drm/nouveau/flcn: move bind_context WAR out of common code
authorBen Skeggs <bskeggs@redhat.com>
Tue, 14 Jan 2020 20:34:21 +0000 (06:34 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 15 Jan 2020 00:50:27 +0000 (10:50 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h
drivers/gpu/drm/nouveau/nvkm/engine/sec2/gp102.c
drivers/gpu/drm/nouveau/nvkm/engine/sec2/tu102.c
drivers/gpu/drm/nouveau/nvkm/falcon/v1.c
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gv100.c

index 0fa6e09..2bfa9ff 100644 (file)
@@ -17,4 +17,6 @@ void nvkm_falcon_v1_set_start_addr(struct nvkm_falcon *, u32 start_addr);
 void nvkm_falcon_v1_start(struct nvkm_falcon *);
 int nvkm_falcon_v1_enable(struct nvkm_falcon *);
 void nvkm_falcon_v1_disable(struct nvkm_falcon *);
+
+void gp102_sec2_flcn_bind_context(struct nvkm_falcon *, struct nvkm_memory *);
 #endif
index 444512e..278eb4d 100644 (file)
@@ -21,6 +21,7 @@
  */
 #include "priv.h"
 #include <subdev/acr.h>
+#include <subdev/timer.h>
 
 static const struct nvkm_acr_lsf_func
 gp102_sec2_acr_0 = {
@@ -46,13 +47,52 @@ gp102_sec2_intr(struct nvkm_sec2 *sec2)
        }
 }
 
+void
+gp102_sec2_flcn_bind_context(struct nvkm_falcon *falcon,
+                            struct nvkm_memory *ctx)
+{
+       struct nvkm_device *device = falcon->owner->device;
+
+       nvkm_falcon_v1_bind_context(falcon, ctx);
+       if (!ctx)
+               return;
+
+       /* Not sure if this is a WAR for a HW issue, or some additional
+        * programming sequence that's needed to properly complete the
+        * context switch we trigger above.
+        *
+        * Fixes unreliability of booting the SEC2 RTOS on Quadro P620,
+        * particularly when resuming from suspend.
+        *
+        * Also removes the need for an odd workaround where we needed
+        * to program SEC2's FALCON_CPUCTL_ALIAS_STARTCPU twice before
+        * the SEC2 RTOS would begin executing.
+        */
+       nvkm_msec(device, 10,
+               u32 irqstat = nvkm_falcon_rd32(falcon, 0x008);
+               u32 flcn0dc = nvkm_falcon_rd32(falcon, 0x0dc);
+               if ((irqstat & 0x00000008) &&
+                   (flcn0dc & 0x00007000) == 0x00005000)
+                       break;
+       );
+
+       nvkm_falcon_mask(falcon, 0x004, 0x00000008, 0x00000008);
+       nvkm_falcon_mask(falcon, 0x058, 0x00000002, 0x00000002);
+
+       nvkm_msec(device, 10,
+               u32 flcn0dc = nvkm_falcon_rd32(falcon, 0x0dc);
+               if ((flcn0dc & 0x00007000) == 0x00000000)
+                       break;
+       );
+}
+
 static const struct nvkm_falcon_func
 gp102_sec2_flcn = {
        .fbif = 0x600,
        .load_imem = nvkm_falcon_v1_load_imem,
        .load_dmem = nvkm_falcon_v1_load_dmem,
        .read_dmem = nvkm_falcon_v1_read_dmem,
-       .bind_context = nvkm_falcon_v1_bind_context,
+       .bind_context = gp102_sec2_flcn_bind_context,
        .wait_for_halt = nvkm_falcon_v1_wait_for_halt,
        .clear_interrupt = nvkm_falcon_v1_clear_interrupt,
        .set_start_addr = nvkm_falcon_v1_set_start_addr,
index f1796f3..cbd89b4 100644 (file)
@@ -27,7 +27,7 @@ tu102_sec2_flcn = {
        .load_imem = nvkm_falcon_v1_load_imem,
        .load_dmem = nvkm_falcon_v1_load_dmem,
        .read_dmem = nvkm_falcon_v1_read_dmem,
-       .bind_context = nvkm_falcon_v1_bind_context,
+       .bind_context = gp102_sec2_flcn_bind_context,
        .wait_for_halt = nvkm_falcon_v1_wait_for_halt,
        .clear_interrupt = nvkm_falcon_v1_clear_interrupt,
        .set_start_addr = nvkm_falcon_v1_set_start_addr,
index 5c49052..93e97c3 100644 (file)
@@ -182,7 +182,6 @@ nvkm_falcon_v1_read_dmem(struct nvkm_falcon *falcon, u32 start, u32 size,
 void
 nvkm_falcon_v1_bind_context(struct nvkm_falcon *falcon, struct nvkm_memory *ctx)
 {
-       struct nvkm_device *device = falcon->owner->device;
        const u32 fbif = falcon->func->fbif;
        u32 inst_loc;
 
@@ -220,41 +219,6 @@ nvkm_falcon_v1_bind_context(struct nvkm_falcon *falcon, struct nvkm_memory *ctx)
 
        nvkm_falcon_mask(falcon, 0x090, 0x10000, 0x10000);
        nvkm_falcon_mask(falcon, 0x0a4, 0x8, 0x8);
-
-       /* Not sure if this is a WAR for a HW issue, or some additional
-        * programming sequence that's needed to properly complete the
-        * context switch we trigger above.
-        *
-        * Fixes unreliability of booting the SEC2 RTOS on Quadro P620,
-        * particularly when resuming from suspend.
-        *
-        * Also removes the need for an odd workaround where we needed
-        * to program SEC2's FALCON_CPUCTL_ALIAS_STARTCPU twice before
-        * the SEC2 RTOS would begin executing.
-        */
-       switch (falcon->owner->index) {
-       case NVKM_SUBDEV_GSP:
-       case NVKM_ENGINE_SEC2:
-               nvkm_msec(device, 10,
-                       u32 irqstat = nvkm_falcon_rd32(falcon, 0x008);
-                       u32 flcn0dc = nvkm_falcon_rd32(falcon, 0x0dc);
-                       if ((irqstat & 0x00000008) &&
-                           (flcn0dc & 0x00007000) == 0x00005000)
-                               break;
-               );
-
-               nvkm_falcon_mask(falcon, 0x004, 0x00000008, 0x00000008);
-               nvkm_falcon_mask(falcon, 0x058, 0x00000002, 0x00000002);
-
-               nvkm_msec(device, 10,
-                       u32 flcn0dc = nvkm_falcon_rd32(falcon, 0x0dc);
-                       if ((flcn0dc & 0x00007000) == 0x00000000)
-                               break;
-               );
-               break;
-       default:
-               break;
-       }
 }
 
 void
index 45fde85..36e640d 100644 (file)
@@ -27,7 +27,7 @@ gv100_gsp_flcn = {
        .load_imem = nvkm_falcon_v1_load_imem,
        .load_dmem = nvkm_falcon_v1_load_dmem,
        .read_dmem = nvkm_falcon_v1_read_dmem,
-       .bind_context = nvkm_falcon_v1_bind_context,
+       .bind_context = gp102_sec2_flcn_bind_context,
        .wait_for_halt = nvkm_falcon_v1_wait_for_halt,
        .clear_interrupt = nvkm_falcon_v1_clear_interrupt,
        .set_start_addr = nvkm_falcon_v1_set_start_addr,