diff options
author | Alexandre Courbot <acourbot@nvidia.com> | 2017-03-29 18:31:09 +0900 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2017-04-06 14:39:03 +1000 |
commit | 598a8148e7208aae64f3c3d33f0ad1a65425965f (patch) | |
tree | 0e0676cf919cedf30008d4db11fbe63aaee226d1 /drivers/gpu/drm/nouveau/nvkm/subdev | |
parent | e5ffa727e5330478d9f074521dbf195c8593ed9f (diff) | |
download | linux-598a8148e7208aae64f3c3d33f0ad1a65425965f.tar.gz |
drm/nouveau/secboot: allow to boot multiple falcons
Change the secboot and msgqueue interfaces to take a mask of falcons to
reset instead of a single falcon. The GP10B firmware interface requires
FECS and GPCCS to be booted in a single firmware command.
For firmwares that only support single falcon boot, it is trivial to
loop over the mask and boot each falcons individually.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/subdev')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c | 25 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/secboot/base.c | 6 |
3 files changed, 19 insertions, 15 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr.h b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr.h index 93d804652d44..b615fc81aca4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr.h @@ -39,8 +39,7 @@ struct nvkm_acr_func { int (*fini)(struct nvkm_acr *, struct nvkm_secboot *, bool); int (*load)(struct nvkm_acr *, struct nvkm_falcon *, struct nvkm_gpuobj *, u64); - int (*reset)(struct nvkm_acr *, struct nvkm_secboot *, - enum nvkm_secboot_falcon); + int (*reset)(struct nvkm_acr *, struct nvkm_secboot *, unsigned long); }; /** diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c index 993a38eb3ed5..aa4e75f0eb0a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c @@ -976,15 +976,16 @@ acr_r352_bootstrap(struct acr_r352 *acr, struct nvkm_secboot *sb) */ static int acr_r352_reset_nopmu(struct acr_r352 *acr, struct nvkm_secboot *sb, - enum nvkm_secboot_falcon falcon) + unsigned long falcon_mask) { + int falcon; int ret; /* * Perform secure boot each time we are called on FECS. Since only FECS * and GPCCS are managed and started together, this ought to be safe. */ - if (falcon != NVKM_SECBOOT_FALCON_FECS) + if (!(falcon_mask & BIT(NVKM_SECBOOT_FALCON_FECS))) goto end; ret = acr_r352_shutdown(acr, sb); @@ -996,7 +997,9 @@ acr_r352_reset_nopmu(struct acr_r352 *acr, struct nvkm_secboot *sb, return ret; end: - acr->falcon_state[falcon] = RESET; + for_each_set_bit(falcon, &falcon_mask, NVKM_SECBOOT_FALCON_END) { + acr->falcon_state[falcon] = RESET; + } return 0; } @@ -1009,11 +1012,11 @@ end: */ static int acr_r352_reset(struct nvkm_acr *_acr, struct nvkm_secboot *sb, - enum nvkm_secboot_falcon falcon) + unsigned long falcon_mask) { struct acr_r352 *acr = acr_r352(_acr); struct nvkm_msgqueue *queue; - const char *fname = nvkm_secboot_falcon_name[falcon]; + int falcon; bool wpr_already_set = sb->wpr_set; int ret; @@ -1026,7 +1029,7 @@ acr_r352_reset(struct nvkm_acr *_acr, struct nvkm_secboot *sb, if (!nvkm_secboot_is_managed(sb, _acr->boot_falcon)) { /* Redo secure boot entirely if it was already done */ if (wpr_already_set) - return acr_r352_reset_nopmu(acr, sb, falcon); + return acr_r352_reset_nopmu(acr, sb, falcon_mask); /* Else return the result of the initial invokation */ else return ret; @@ -1044,13 +1047,15 @@ acr_r352_reset(struct nvkm_acr *_acr, struct nvkm_secboot *sb, } /* Otherwise just ask the LS firmware to reset the falcon */ - nvkm_debug(&sb->subdev, "resetting %s falcon\n", fname); - ret = nvkm_msgqueue_acr_boot_falcon(queue, falcon); + for_each_set_bit(falcon, &falcon_mask, NVKM_SECBOOT_FALCON_END) + nvkm_debug(&sb->subdev, "resetting %s falcon\n", + nvkm_secboot_falcon_name[falcon]); + ret = nvkm_msgqueue_acr_boot_falcons(queue, falcon_mask); if (ret) { - nvkm_error(&sb->subdev, "cannot boot %s falcon\n", fname); + nvkm_error(&sb->subdev, "error during falcon reset: %d\n", ret); return ret; } - nvkm_debug(&sb->subdev, "falcon %s reset\n", fname); + nvkm_debug(&sb->subdev, "falcon reset done\n"); return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/base.c index 5c11e8c50964..ee29c6c11afd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/base.c @@ -102,15 +102,15 @@ nvkm_secboot_falcon_name[] = { * nvkm_secboot_reset() - reset specified falcon */ int -nvkm_secboot_reset(struct nvkm_secboot *sb, enum nvkm_secboot_falcon falcon) +nvkm_secboot_reset(struct nvkm_secboot *sb, unsigned long falcon_mask) { /* Unmanaged falcon? */ - if (!(BIT(falcon) & sb->acr->managed_falcons)) { + if ((falcon_mask | sb->acr->managed_falcons) != sb->acr->managed_falcons) { nvkm_error(&sb->subdev, "cannot reset unmanaged falcon!\n"); return -EINVAL; } - return sb->acr->func->reset(sb->acr, sb, falcon); + return sb->acr->func->reset(sb->acr, sb, falcon_mask); } /** |