diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mc.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mc.h index 4de05e718f83825a3f67317213716afb1bd45a24..ac6321f1b6e8c562df3ec519d132655d8fdf5595 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mc.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mc.h @@ -10,6 +10,7 @@ struct nvkm_mc { void nvkm_mc_intr(struct nvkm_mc *, bool *handled); void nvkm_mc_intr_unarm(struct nvkm_mc *); void nvkm_mc_intr_rearm(struct nvkm_mc *); +void nvkm_mc_reset(struct nvkm_mc *, enum nvkm_devidx); void nvkm_mc_unk260(struct nvkm_mc *, u32 data); int nv04_mc_new(struct nvkm_device *, int, struct nvkm_mc **); diff --git a/drivers/gpu/drm/nouveau/nvkm/core/subdev.c b/drivers/gpu/drm/nouveau/nvkm/core/subdev.c index eece74d57b51dcda54d940b8b243edc7c3c62d50..68cf6062b96d4fe2230ccd154caa271a63f9fbf4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/subdev.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/subdev.c @@ -24,6 +24,7 @@ #include #include #include +#include static struct lock_class_key nvkm_subdev_lock_class[NVKM_SUBDEV_NR]; @@ -90,7 +91,6 @@ nvkm_subdev_fini(struct nvkm_subdev *subdev, bool suspend) { struct nvkm_device *device = subdev->device; const char *action = suspend ? "suspend" : "fini"; - u32 pmc_enable = subdev->pmc_enable; s64 time; nvkm_trace(subdev, "%s running...\n", action); @@ -105,11 +105,7 @@ nvkm_subdev_fini(struct nvkm_subdev *subdev, bool suspend) } } - if (pmc_enable) { - nvkm_mask(device, 0x000200, pmc_enable, 0x00000000); - nvkm_mask(device, 0x000200, pmc_enable, pmc_enable); - nvkm_rd32(device, 0x000200); - } + nvkm_mc_reset(device->mc, subdev->index); time = ktime_to_us(ktime_get()) - time; nvkm_trace(subdev, "%s completed in %lldus\n", action, time); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c index e6c5bc461ba6adcdde4d8b0625235142993405f6..95183011510e5c9e71453b58067744f29030c53f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c @@ -77,6 +77,26 @@ nvkm_mc_intr(struct nvkm_mc *mc, bool *handled) *handled = intr != 0; } +static void +nvkm_mc_reset_(struct nvkm_mc *mc, enum nvkm_devidx devidx) +{ + struct nvkm_device *device = mc->subdev.device; + struct nvkm_subdev *subdev = nvkm_device_subdev(device, devidx); + u64 pmc_enable = subdev->pmc_enable; + if (pmc_enable) { + nvkm_mask(device, 0x000200, pmc_enable, 0x00000000); + nvkm_mask(device, 0x000200, pmc_enable, pmc_enable); + nvkm_rd32(device, 0x000200); + } +} + +void +nvkm_mc_reset(struct nvkm_mc *mc, enum nvkm_devidx devidx) +{ + if (likely(mc)) + nvkm_mc_reset_(mc, devidx); +} + static int nvkm_mc_fini(struct nvkm_subdev *subdev, bool suspend) {