mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-02 09:21:19 -04:00
drm/nouveau/gsp: move booter handling to GPU-specific code
GH100/GBxxx have significant changes to the GSP-RM boot process. Signed-off-by: Ben Skeggs <bskeggs@nvidia.com> Reviewed-by: Dave Airlie <airlied@redhat.com> Reviewed-by: Timur Tabi <ttabi@nvidia.com> Tested-by: Timur Tabi <ttabi@nvidia.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 **);
|
||||
|
||||
@@ -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);
|
||||
nvkm_falcon_wr32(&gsp->falcon, 0x080, gsp->boot.app_version);
|
||||
|
||||
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 = 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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user