GH100/GBxxx have significant changes to the GSP-RM boot process. Signed-off-by: Ben Skeggs <bske...@nvidia.com> --- .../gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c | 4 +- .../gpu/drm/nouveau/nvkm/subdev/gsp/base.c | 2 +- .../gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c | 4 +- .../gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c | 4 +- .../gpu/drm/nouveau/nvkm/subdev/gsp/priv.h | 3 + .../gpu/drm/nouveau/nvkm/subdev/gsp/r535.c | 94 +-------------- .../gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c | 113 +++++++++++++++++- .../gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c | 4 +- 8 files changed, 125 insertions(+), 103 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c index 221ea0fd8a51..ea2821e7a54e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c @@ -36,8 +36,8 @@ ad102_gsp_r535_113_01 = { .dtor = r535_gsp_dtor, .oneinit = tu102_gsp_oneinit, - .init = r535_gsp_init, - .fini = r535_gsp_fini, + .init = tu102_gsp_init, + .fini = tu102_gsp_fini, .reset = ga102_gsp_reset, .rm = &r535_gsp_rm, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c index fe1cef1b6324..78f2a15f0d42 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c @@ -52,7 +52,7 @@ nvkm_gsp_fini(struct nvkm_subdev *subdev, bool suspend) { struct nvkm_gsp *gsp = nvkm_gsp(subdev); - if (!gsp->func->fini) + if (!gsp->func->fini || !gsp->running) return 0; return gsp->func->fini(gsp, suspend); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c index c3be72d3390a..d9cdec4810b4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c @@ -52,8 +52,8 @@ ga100_gsp_r535_113_01 = { .dtor = r535_gsp_dtor, .oneinit = tu102_gsp_oneinit, - .init = r535_gsp_init, - .fini = r535_gsp_fini, + .init = tu102_gsp_init, + .fini = tu102_gsp_fini, .reset = tu102_gsp_reset, .rm = &r535_gsp_rm, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c index d7385d3989f1..7b8db70f3cb3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c @@ -164,8 +164,8 @@ ga102_gsp_r535_113_01 = { .dtor = r535_gsp_dtor, .oneinit = tu102_gsp_oneinit, - .init = r535_gsp_init, - .fini = r535_gsp_fini, + .init = tu102_gsp_init, + .fini = tu102_gsp_fini, .reset = ga102_gsp_reset, .rm = &r535_gsp_rm, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h index 601dd5d503bb..e6f0e865848a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h @@ -59,6 +59,8 @@ extern const struct nvkm_falcon_fw_func tu102_gsp_fwsec; int tu102_gsp_booter_ctor(struct nvkm_gsp *, const char *, const struct firmware *, struct nvkm_falcon *, struct nvkm_falcon_fw *); int tu102_gsp_oneinit(struct nvkm_gsp *); +int tu102_gsp_init(struct nvkm_gsp *); +int tu102_gsp_fini(struct nvkm_gsp *, bool suspend); int tu102_gsp_reset(struct nvkm_gsp *); extern const struct nvkm_falcon_func ga102_gsp_flcn; @@ -72,6 +74,7 @@ int r535_gsp_oneinit(struct nvkm_gsp *); int r535_gsp_init(struct nvkm_gsp *); int r535_gsp_fini(struct nvkm_gsp *, bool suspend); extern const struct nvkm_gsp_rm r535_gsp_rm; +int r535_gsp_rmargs_init(struct nvkm_gsp *gsp, bool resume); int nvkm_gsp_new_(const struct nvkm_gsp_fwif *, struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c index 45e3fcbabe4f..ff5ab2635003 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c @@ -1145,48 +1145,6 @@ r535_gsp_msg_run_cpu_sequencer(void *priv, u32 fn, void *repv, u32 repc) return 0; } -static int -r535_gsp_booter_unload(struct nvkm_gsp *gsp, u32 mbox0, u32 mbox1) -{ - struct nvkm_subdev *subdev = &gsp->subdev; - struct nvkm_device *device = subdev->device; - u32 wpr2_hi; - int ret; - - wpr2_hi = nvkm_rd32(device, 0x1fa828); - if (!wpr2_hi) { - nvkm_debug(subdev, "WPR2 not set - skipping booter unload\n"); - return 0; - } - - ret = nvkm_falcon_fw_boot(&gsp->booter.unload, &gsp->subdev, true, &mbox0, &mbox1, 0, 0); - if (WARN_ON(ret)) - return ret; - - wpr2_hi = nvkm_rd32(device, 0x1fa828); - if (WARN_ON(wpr2_hi)) - return -EIO; - - return 0; -} - -static int -r535_gsp_booter_load(struct nvkm_gsp *gsp, u32 mbox0, u32 mbox1) -{ - int ret; - - ret = nvkm_falcon_fw_boot(&gsp->booter.load, &gsp->subdev, true, &mbox0, &mbox1, 0, 0); - if (ret) - return ret; - - nvkm_falcon_wr32(&gsp->falcon, 0x080, gsp->boot.app_version); - - if (WARN_ON(!nvkm_falcon_riscv_active(&gsp->falcon))) - return -EIO; - - return 0; -} - static int r535_gsp_wpr_meta_init(struct nvkm_gsp *gsp) { @@ -1287,7 +1245,7 @@ r535_gsp_shared_init(struct nvkm_gsp *gsp) return 0; } -static int +int r535_gsp_rmargs_init(struct nvkm_gsp *gsp, bool resume) { GSP_ARGUMENTS_CACHED *args; @@ -1816,12 +1774,8 @@ nvkm_gsp_radix3_sg(struct nvkm_gsp *gsp, struct sg_table *sgt, u64 size, int r535_gsp_fini(struct nvkm_gsp *gsp, bool suspend) { - u32 mbox0 = 0xff, mbox1 = 0xff; int ret; - if (!gsp->running) - return 0; - if (suspend) { GspFwWprMeta *meta = gsp->wpr_meta.data; u64 len = meta->gspFwWprEnd - meta->gspFwWprStart; @@ -1844,9 +1798,6 @@ r535_gsp_fini(struct nvkm_gsp *gsp, bool suspend) sr->revision = GSP_FW_SR_META_REVISION; sr->sysmemAddrOfSuspendResumeData = gsp->sr.radix3.lvl0.addr; sr->sizeOfSuspendResumeData = len; - - mbox0 = lower_32_bits(gsp->sr.meta.addr); - mbox1 = upper_32_bits(gsp->sr.meta.addr); } ret = r535_gsp_rpc_unloading_guest_driver(gsp, suspend); @@ -1858,14 +1809,6 @@ r535_gsp_fini(struct nvkm_gsp *gsp, bool suspend) break; ); - nvkm_falcon_reset(&gsp->falcon); - - ret = nvkm_gsp_fwsec_sb(gsp); - WARN_ON(ret); - - ret = r535_gsp_booter_unload(gsp, mbox0, mbox1); - WARN_ON(ret); - gsp->running = false; return 0; } @@ -1873,23 +1816,12 @@ r535_gsp_fini(struct nvkm_gsp *gsp, bool suspend) int r535_gsp_init(struct nvkm_gsp *gsp) { - u32 mbox0, mbox1; int ret; - if (!gsp->sr.meta.data) { - mbox0 = lower_32_bits(gsp->wpr_meta.addr); - mbox1 = upper_32_bits(gsp->wpr_meta.addr); - } else { - r535_gsp_rmargs_init(gsp, true); - - mbox0 = lower_32_bits(gsp->sr.meta.addr); - mbox1 = upper_32_bits(gsp->sr.meta.addr); - } + nvkm_falcon_wr32(&gsp->falcon, 0x080, gsp->boot.app_version); - /* Execute booter to handle (eventually...) booting GSP-RM. */ - ret = r535_gsp_booter_load(gsp, mbox0, mbox1); - if (WARN_ON(ret)) - goto done; + if (WARN_ON(!nvkm_falcon_riscv_active(&gsp->falcon))) + return -EIO; ret = r535_gsp_rpc_poll(gsp, NV_VGPU_MSG_EVENT_GSP_INIT_DONE); if (ret) @@ -2220,16 +2152,6 @@ r535_gsp_oneinit(struct nvkm_gsp *gsp) mutex_init(&gsp->cmdq.mutex); mutex_init(&gsp->msgq.mutex); - ret = gsp->func->booter.ctor(gsp, "booter-load", gsp->fws.booter.load, - &device->sec2->falcon, &gsp->booter.load); - if (ret) - return ret; - - ret = gsp->func->booter.ctor(gsp, "booter-unload", gsp->fws.booter.unload, - &device->sec2->falcon, &gsp->booter.unload); - if (ret) - return ret; - /* Load GSP firmware from ELF image into DMA-accessible memory. */ ret = r535_gsp_elf_section(gsp, ".fwimage", &data, &size); if (ret) @@ -2324,14 +2246,6 @@ r535_gsp_oneinit(struct nvkm_gsp *gsp) if (WARN_ON(ret)) return ret; - /* Reset GSP into RISC-V mode. */ - ret = gsp->func->reset(gsp); - if (WARN_ON(ret)) - return ret; - - nvkm_falcon_wr32(&gsp->falcon, 0x040, lower_32_bits(gsp->libos.addr)); - nvkm_falcon_wr32(&gsp->falcon, 0x044, upper_32_bits(gsp->libos.addr)); - mutex_init(&gsp->client_id.mutex); idr_init(&gsp->client_id.idr); return 0; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c index e7396344cfdf..451d3e588d26 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c @@ -22,11 +22,43 @@ #include "priv.h" #include <subdev/fb.h> +#include <engine/sec2.h> #include <nvfw/flcn.h> #include <nvfw/fw.h> #include <nvfw/hs.h> +static int +tu102_gsp_booter_unload(struct nvkm_gsp *gsp, u32 mbox0, u32 mbox1) +{ + struct nvkm_subdev *subdev = &gsp->subdev; + struct nvkm_device *device = subdev->device; + u32 wpr2_hi; + int ret; + + wpr2_hi = nvkm_rd32(device, 0x1fa828); + if (!wpr2_hi) { + nvkm_debug(subdev, "WPR2 not set - skipping booter unload\n"); + return 0; + } + + ret = nvkm_falcon_fw_boot(&gsp->booter.unload, &gsp->subdev, true, &mbox0, &mbox1, 0, 0); + if (WARN_ON(ret)) + return ret; + + wpr2_hi = nvkm_rd32(device, 0x1fa828); + if (WARN_ON(wpr2_hi)) + return -EIO; + + return 0; +} + +static int +tu102_gsp_booter_load(struct nvkm_gsp *gsp, u32 mbox0, u32 mbox1) +{ + return nvkm_falcon_fw_boot(&gsp->booter.load, &gsp->subdev, true, &mbox0, &mbox1, 0, 0); +} + int tu102_gsp_booter_ctor(struct nvkm_gsp *gsp, const char *name, const struct firmware *blob, struct nvkm_falcon *falcon, struct nvkm_falcon_fw *fw) @@ -114,6 +146,55 @@ tu102_gsp_reset(struct nvkm_gsp *gsp) return gsp->falcon.func->reset_eng(&gsp->falcon); } +int +tu102_gsp_fini(struct nvkm_gsp *gsp, bool suspend) +{ + u32 mbox0 = 0xff, mbox1 = 0xff; + int ret; + + ret = r535_gsp_fini(gsp, suspend); + if (ret && suspend) + return ret; + + nvkm_falcon_reset(&gsp->falcon); + + ret = nvkm_gsp_fwsec_sb(gsp); + WARN_ON(ret); + + if (suspend) { + mbox0 = lower_32_bits(gsp->sr.meta.addr); + mbox1 = upper_32_bits(gsp->sr.meta.addr); + } + + ret = tu102_gsp_booter_unload(gsp, mbox0, mbox1); + WARN_ON(ret); + return 0; +} + +int +tu102_gsp_init(struct nvkm_gsp *gsp) +{ + u32 mbox0, mbox1; + int ret; + + if (!gsp->sr.meta.data) { + mbox0 = lower_32_bits(gsp->wpr_meta.addr); + mbox1 = upper_32_bits(gsp->wpr_meta.addr); + } else { + r535_gsp_rmargs_init(gsp, true); + + mbox0 = lower_32_bits(gsp->sr.meta.addr); + mbox1 = upper_32_bits(gsp->sr.meta.addr); + } + + /* Execute booter to handle (eventually...) booting GSP-RM. */ + ret = tu102_gsp_booter_load(gsp, mbox0, mbox1); + if (WARN_ON(ret)) + return ret; + + return r535_gsp_init(gsp); +} + static u64 tu102_gsp_vga_workspace_addr(struct nvkm_gsp *gsp, u64 fb_size) { @@ -136,14 +217,38 @@ tu102_gsp_vga_workspace_addr(struct nvkm_gsp *gsp, u64 fb_size) int tu102_gsp_oneinit(struct nvkm_gsp *gsp) { - gsp->fb.size = nvkm_fb_vidmem_size(gsp->subdev.device); + struct nvkm_device *device = gsp->subdev.device; + int ret; + + gsp->fb.size = nvkm_fb_vidmem_size(device); gsp->fb.bios.vga_workspace.addr = tu102_gsp_vga_workspace_addr(gsp, gsp->fb.size); gsp->fb.bios.vga_workspace.size = gsp->fb.size - gsp->fb.bios.vga_workspace.addr; gsp->fb.bios.addr = gsp->fb.bios.vga_workspace.addr; gsp->fb.bios.size = gsp->fb.bios.vga_workspace.size; - return r535_gsp_oneinit(gsp); + ret = gsp->func->booter.ctor(gsp, "booter-load", gsp->fws.booter.load, + &device->sec2->falcon, &gsp->booter.load); + if (ret) + return ret; + + ret = gsp->func->booter.ctor(gsp, "booter-unload", gsp->fws.booter.unload, + &device->sec2->falcon, &gsp->booter.unload); + if (ret) + return ret; + + ret = r535_gsp_oneinit(gsp); + if (ret) + return ret; + + /* Reset GSP into RISC-V mode. */ + ret = gsp->func->reset(gsp); + if (ret) + return ret; + + nvkm_falcon_wr32(&gsp->falcon, 0x040, lower_32_bits(gsp->libos.addr)); + nvkm_falcon_wr32(&gsp->falcon, 0x044, upper_32_bits(gsp->libos.addr)); + return 0; } const struct nvkm_falcon_func @@ -176,8 +281,8 @@ tu102_gsp_r535_113_01 = { .dtor = r535_gsp_dtor, .oneinit = tu102_gsp_oneinit, - .init = r535_gsp_init, - .fini = r535_gsp_fini, + .init = tu102_gsp_init, + .fini = tu102_gsp_fini, .reset = tu102_gsp_reset, .rm = &r535_gsp_rm, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c index a8c9480b8024..1bc806a18010 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c @@ -35,8 +35,8 @@ tu116_gsp_r535_113_01 = { .dtor = r535_gsp_dtor, .oneinit = tu102_gsp_oneinit, - .init = r535_gsp_init, - .fini = r535_gsp_fini, + .init = tu102_gsp_init, + .fini = tu102_gsp_fini, .reset = tu102_gsp_reset, .rm = &r535_gsp_rm, -- 2.49.0