aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nvkm/subdev
diff options
context:
space:
mode:
authorAlexandre Courbot <acourbot@nvidia.com>2017-03-29 18:31:09 +0900
committerBen Skeggs <bskeggs@redhat.com>2017-04-06 14:39:03 +1000
commit598a8148e7208aae64f3c3d33f0ad1a65425965f (patch)
tree0e0676cf919cedf30008d4db11fbe63aaee226d1 /drivers/gpu/drm/nouveau/nvkm/subdev
parente5ffa727e5330478d9f074521dbf195c8593ed9f (diff)
downloadlinux-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.h3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c25
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/secboot/base.c6
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);
}
/**