summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Courbot <acourbot@nvidia.com>2016-11-15 16:28:37 +0900
committerBen Skeggs <bskeggs@redhat.com>2017-03-07 17:05:13 +1000
commite9462417f1fedec381dd148cbc1d29d21bec4500 (patch)
tree9ee3a840472ef28832ccbe1ba7e627c335be9c36
parent9706d8f9d1ebc499192f8974abba03acdcf1094a (diff)
drm/nouveau/secboot: add shadow blob argument
ACR firmware from r364 on need a shadow region for the ACR to copy the WPR region into. Add a flag to indicate that a shadow region is required and manage memory allocations accordingly. Signed-off-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c16
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.h1
2 files changed, 15 insertions, 2 deletions
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 9e64b7c8b0b2..814f9f2a17ef 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c
@@ -491,7 +491,7 @@ acr_r352_prepare_ls_blob(struct acr_r352 *acr, u64 wpr_addr, u32 wpr_size)
struct ls_ucode_img *img, *t;
unsigned long managed_falcons = acr->base.managed_falcons;
int managed_count = 0;
- u32 image_wpr_size;
+ u32 image_wpr_size, ls_blob_size;
int falcon_id;
int ret;
@@ -542,8 +542,17 @@ acr_r352_prepare_ls_blob(struct acr_r352 *acr, u64 wpr_addr, u32 wpr_size)
image_wpr_size = acr->func->ls_fill_headers(acr, &imgs);
image_wpr_size = ALIGN(image_wpr_size, WPR_ALIGNMENT);
+ ls_blob_size = image_wpr_size;
+
+ /*
+ * If we need a shadow area, allocate twice the size and use the
+ * upper half as WPR
+ */
+ if (wpr_size == 0 && acr->func->shadow_blob)
+ ls_blob_size *= 2;
+
/* Allocate GPU object that will contain the WPR region */
- ret = nvkm_gpuobj_new(subdev->device, image_wpr_size, WPR_ALIGNMENT,
+ ret = nvkm_gpuobj_new(subdev->device, ls_blob_size, WPR_ALIGNMENT,
false, NULL, &acr->ls_blob);
if (ret)
goto cleanup;
@@ -554,6 +563,9 @@ acr_r352_prepare_ls_blob(struct acr_r352 *acr, u64 wpr_addr, u32 wpr_size)
/* If WPR address and size are not fixed, set them to fit the LS blob */
if (wpr_size == 0) {
wpr_addr = acr->ls_blob->addr;
+ if (acr->func->shadow_blob)
+ wpr_addr += acr->ls_blob->size / 2;
+
wpr_size = image_wpr_size;
/*
* But if the WPR region is set by the bootloader, it is illegal for
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.h b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.h
index 9ca23c1e3aa9..1b9f5c825c8a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.h
@@ -104,6 +104,7 @@ struct acr_r352_func {
u64);
void (*fixup_hs_desc)(struct acr_r352 *, struct nvkm_secboot *, void *);
u32 hs_bl_desc_size;
+ bool shadow_blob;
struct ls_ucode_img *(*ls_ucode_img_load)(const struct acr_r352 *,
enum nvkm_secboot_falcon);