Revert "drm/nouveau/pmu/gm200-: avoid touching PMU outside of DEVINIT/PREOS/ACR"
authorKarol Herbst <kherbst@redhat.com>
Mon, 28 Feb 2022 09:12:59 +0000 (10:12 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 2 Mar 2022 10:41:17 +0000 (11:41 +0100)
This reverts commit c9ec3d85c0eef7c71cdc68db758e0f0e378132c0.

This commit causes a regression if 4cdd2450bf739bada353e82d27b00db9af8c3001
is not applied as well. This was fixed for 5.16, 5.15 and 5.10.

On older stable branches backporting this commit is complicated as relevant
code changed quite a bit. Furthermore most of the affected hardware barely
works on those and users would want to use the newer kernels anyway.

Cc: stable@vger.kernel.org # 5.4 4.19 and 4.14
Cc: Ben Skeggs <bskeggs@redhat.com>
Cc: Lyude Paul <lyude@redhat.com>
Link: https://gitlab.freedesktop.org/drm/nouveau/-/issues/149
Signed-off-by: Karol Herbst <kherbst@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c

index 105b4be467a3ed2c0637a6fbeb5631abbef1edf7..ea2e11771bca522e820151b204c098b230a56b22 100644 (file)
@@ -88,13 +88,20 @@ nvkm_pmu_fini(struct nvkm_subdev *subdev, bool suspend)
        return 0;
 }
 
-static void
+static int
 nvkm_pmu_reset(struct nvkm_pmu *pmu)
 {
        struct nvkm_device *device = pmu->subdev.device;
 
        if (!pmu->func->enabled(pmu))
-               return;
+               return 0;
+
+       /* Inhibit interrupts, and wait for idle. */
+       nvkm_wr32(device, 0x10a014, 0x0000ffff);
+       nvkm_msec(device, 2000,
+               if (!nvkm_rd32(device, 0x10a04c))
+                       break;
+       );
 
        /* Reset. */
        if (pmu->func->reset)
@@ -105,37 +112,25 @@ nvkm_pmu_reset(struct nvkm_pmu *pmu)
                if (!(nvkm_rd32(device, 0x10a10c) & 0x00000006))
                        break;
        );
+
+       return 0;
 }
 
 static int
 nvkm_pmu_preinit(struct nvkm_subdev *subdev)
 {
        struct nvkm_pmu *pmu = nvkm_pmu(subdev);
-       nvkm_pmu_reset(pmu);
-       return 0;
+       return nvkm_pmu_reset(pmu);
 }
 
 static int
 nvkm_pmu_init(struct nvkm_subdev *subdev)
 {
        struct nvkm_pmu *pmu = nvkm_pmu(subdev);
-       struct nvkm_device *device = pmu->subdev.device;
-
-       if (!pmu->func->init)
-               return 0;
-
-       if (pmu->func->enabled(pmu)) {
-               /* Inhibit interrupts, and wait for idle. */
-               nvkm_wr32(device, 0x10a014, 0x0000ffff);
-               nvkm_msec(device, 2000,
-                       if (!nvkm_rd32(device, 0x10a04c))
-                               break;
-               );
-
-               nvkm_pmu_reset(pmu);
-       }
-
-       return pmu->func->init(pmu);
+       int ret = nvkm_pmu_reset(pmu);
+       if (ret == 0 && pmu->func->init)
+               ret = pmu->func->init(pmu);
+       return ret;
 }
 
 static int