Loading drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h +2 −0 Original line number Diff line number Diff line Loading @@ -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 drivers/gpu/drm/nouveau/nvkm/engine/sec2/gp102.c +41 −1 Original line number Diff line number Diff line Loading @@ -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 = { Loading @@ -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, Loading drivers/gpu/drm/nouveau/nvkm/engine/sec2/tu102.c +1 −1 Original line number Diff line number Diff line Loading @@ -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, Loading drivers/gpu/drm/nouveau/nvkm/falcon/v1.c +0 −36 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gv100.c +1 −1 Original line number Diff line number Diff line Loading @@ -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, Loading Loading
drivers/gpu/drm/nouveau/include/nvkm/core/falcon.h +2 −0 Original line number Diff line number Diff line Loading @@ -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
drivers/gpu/drm/nouveau/nvkm/engine/sec2/gp102.c +41 −1 Original line number Diff line number Diff line Loading @@ -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 = { Loading @@ -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, Loading
drivers/gpu/drm/nouveau/nvkm/engine/sec2/tu102.c +1 −1 Original line number Diff line number Diff line Loading @@ -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, Loading
drivers/gpu/drm/nouveau/nvkm/falcon/v1.c +0 −36 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gv100.c +1 −1 Original line number Diff line number Diff line Loading @@ -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, Loading