Trigger the loading of FECS/GPCCS using secure boot if required, and start managed falcons using the CPUCTL_ALIAS register since CPUCTL is protected in that case.
Signed-off-by: Alexandre Courbot <acour...@nvidia.com> --- drm/nouveau/nvkm/engine/gr/gf100.c | 56 +++++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/drm/nouveau/nvkm/engine/gr/gf100.c b/drm/nouveau/nvkm/engine/gr/gf100.c index dda7a7d224c9..67691941d7ba 100644 --- a/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drm/nouveau/nvkm/engine/gr/gf100.c @@ -27,6 +27,7 @@ #include <core/client.h> #include <core/option.h> +#include <core/secure_boot.h> #include <subdev/fb.h> #include <subdev/mc.h> #include <subdev/pmu.h> @@ -1342,16 +1343,40 @@ gf100_gr_init_ctxctl(struct gf100_gr *gr) if (gr->firmware) { /* load fuc microcode */ nvkm_mc_unk260(device->mc, 0); - gf100_gr_init_fw(gr, 0x409000, &gr->fuc409c, &gr->fuc409d); - gf100_gr_init_fw(gr, 0x41a000, &gr->fuc41ac, &gr->fuc41ad); + + if (nvkm_is_secure(device, LSF_FALCON_ID_FECS) || + nvkm_is_secure(device, LSF_FALCON_ID_GPCCS)) { + int err = nvkm_secure_boot(subdev->device); + + if (err) + return err; + } + + if (!nvkm_is_secure(device, LSF_FALCON_ID_FECS)) + gf100_gr_init_fw(gr, 0x409000, &gr->fuc409c, + &gr->fuc409d); + + if (!nvkm_is_secure(device, LSF_FALCON_ID_GPCCS)) + gf100_gr_init_fw(gr, 0x41a000, &gr->fuc41ac, + &gr->fuc41ad); + nvkm_mc_unk260(device->mc, 1); /* start both of them running */ nvkm_wr32(device, 0x409840, 0xffffffff); nvkm_wr32(device, 0x41a10c, 0x00000000); nvkm_wr32(device, 0x40910c, 0x00000000); - nvkm_wr32(device, 0x41a100, 0x00000002); - nvkm_wr32(device, 0x409100, 0x00000002); + /* Use FALCON_CPUCTL_ALIAS if falcon is in secure mode */ + if (nvkm_rd32(device, 0x41a100) & 0x40) + nvkm_wr32(device, 0x41a130, 0x00000002); + else + nvkm_wr32(device, 0x41a100, 0x00000002); + + /* Use FALCON_CPUCTL_ALIAS if falcon is in secure mode */ + if (nvkm_rd32(device, 0x409100) & 0x40) + nvkm_wr32(device, 0x409130, 0x00000002); + else + nvkm_wr32(device, 0x409100, 0x00000002); if (nvkm_msec(device, 2000, if (nvkm_rd32(device, 0x409800) & 0x00000001) break; @@ -1659,6 +1684,7 @@ int gf100_gr_ctor(const struct gf100_gr_func *func, struct nvkm_device *device, int index, struct gf100_gr *gr) { + struct nvkm_subdev *subdev = &gr->base.engine.subdev; int ret; gr->func = func; @@ -1672,12 +1698,22 @@ gf100_gr_ctor(const struct gf100_gr_func *func, struct nvkm_device *device, return ret; if (gr->firmware) { - nvkm_info(&gr->base.engine.subdev, "using external firmware\n"); - if (gf100_gr_ctor_fw(gr, "fecs_inst", &gr->fuc409c) || - gf100_gr_ctor_fw(gr, "fecs_data", &gr->fuc409d) || - gf100_gr_ctor_fw(gr, "gpccs_inst", &gr->fuc41ac) || - gf100_gr_ctor_fw(gr, "gpccs_data", &gr->fuc41ad)) - return -ENODEV; + nvkm_info(subdev, "using external firmware\n"); + if (!nvkm_is_secure(device, LSF_FALCON_ID_FECS)) { + if (gf100_gr_ctor_fw(gr, "fecs_inst", &gr->fuc409c) || + gf100_gr_ctor_fw(gr, "fecs_data", &gr->fuc409d)) + return -ENODEV; + } else { + nvkm_info(subdev, "FECS firmware securely managed\n"); + } + + if (!nvkm_is_secure(device, LSF_FALCON_ID_GPCCS)) { + if (gf100_gr_ctor_fw(gr, "gpccs_inst", &gr->fuc41ac) || + gf100_gr_ctor_fw(gr, "gpccs_data", &gr->fuc41ad)) + return -ENODEV; + } else { + nvkm_info(subdev, "GPCCS firmware securely managed\n"); + } } return 0; -- 2.6.1 -- To unsubscribe from this list: send the line "unsubscribe linux-tegra" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html