Commit 3c2a536b authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/mc: expose device enable/disable separately, as well as reset

There are cases where subdevs need to perform additonal actions around
the master reset, so we want to expost the operations separately.

This commit also adds a flag to the NV_PMC_ENABLE bitfield definitions
which allow skipping the automatic reset() called from core/subdev.c.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent d3981190
......@@ -7,10 +7,12 @@ struct nvkm_mc {
struct nvkm_subdev subdev;
};
void nvkm_mc_enable(struct nvkm_device *, enum nvkm_devidx);
void nvkm_mc_disable(struct nvkm_device *, enum nvkm_devidx);
void nvkm_mc_reset(struct nvkm_device *, enum nvkm_devidx);
void nvkm_mc_intr(struct nvkm_device *, bool *handled);
void nvkm_mc_intr_unarm(struct nvkm_device *);
void nvkm_mc_intr_rearm(struct nvkm_device *);
void nvkm_mc_reset(struct nvkm_device *, enum nvkm_devidx);
void nvkm_mc_unk260(struct nvkm_device *, u32 data);
int nv04_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
......
......@@ -95,22 +95,32 @@ nvkm_mc_intr(struct nvkm_device *device, bool *handled)
*handled = intr != 0;
}
static void
nvkm_mc_reset_(struct nvkm_mc *mc, enum nvkm_devidx devidx)
static u32
nvkm_mc_reset_mask(struct nvkm_device *device, bool isauto,
enum nvkm_devidx devidx)
{
struct nvkm_device *device = mc->subdev.device;
struct nvkm_mc *mc = device->mc;
const struct nvkm_mc_map *map;
u64 pmc_enable;
if (!(pmc_enable = nvkm_top_reset(device, devidx))) {
for (map = mc->func->reset; map && map->stat; map++) {
if (map->unit == devidx) {
pmc_enable = map->stat;
break;
u64 pmc_enable = 0;
if (likely(mc)) {
if (!(pmc_enable = nvkm_top_reset(device, devidx))) {
for (map = mc->func->reset; map && map->stat; map++) {
if (!isauto || !map->noauto) {
if (map->unit == devidx) {
pmc_enable = map->stat;
break;
}
}
}
}
}
return pmc_enable;
}
void
nvkm_mc_reset(struct nvkm_device *device, enum nvkm_devidx devidx)
{
u64 pmc_enable = nvkm_mc_reset_mask(device, true, devidx);
if (pmc_enable) {
nvkm_mask(device, 0x000200, pmc_enable, 0x00000000);
nvkm_mask(device, 0x000200, pmc_enable, pmc_enable);
......@@ -119,11 +129,21 @@ nvkm_mc_reset_(struct nvkm_mc *mc, enum nvkm_devidx devidx)
}
void
nvkm_mc_reset(struct nvkm_device *device, enum nvkm_devidx devidx)
nvkm_mc_disable(struct nvkm_device *device, enum nvkm_devidx devidx)
{
struct nvkm_mc *mc = device->mc;
if (likely(mc))
nvkm_mc_reset_(mc, devidx);
u64 pmc_enable = nvkm_mc_reset_mask(device, false, devidx);
if (pmc_enable)
nvkm_mask(device, 0x000200, pmc_enable, 0x00000000);
}
void
nvkm_mc_enable(struct nvkm_device *device, enum nvkm_devidx devidx)
{
u64 pmc_enable = nvkm_mc_reset_mask(device, false, devidx);
if (pmc_enable) {
nvkm_mask(device, 0x000200, pmc_enable, pmc_enable);
nvkm_rd32(device, 0x000200);
}
}
static int
......
......@@ -11,6 +11,7 @@ int nvkm_mc_new_(const struct nvkm_mc_func *, struct nvkm_device *,
struct nvkm_mc_map {
u32 stat;
u32 unit;
bool noauto;
};
struct nvkm_mc_func {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment