diff options
author | Alexandre Courbot <acourbot@nvidia.com> | 2017-03-29 18:31:12 +0900 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2017-04-06 14:39:04 +1000 |
commit | 008796d9a35f217d7f3672acd1d97ef77a5e05ff (patch) | |
tree | e8aab857478f6a1c5798460ee8fc87f97595ed3a /drivers | |
parent | d424d278b2e5c73040e476e3d854eea4d2063023 (diff) |
drm/nouveau/secboot: start LS firmware in post-run hook
The LS firmware post-run hook is the right place to start said LS
firmware. Moving it here also allows to remove special handling in the
ACR code.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c | 47 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_msgqueue.c | 49 |
2 files changed, 47 insertions, 49 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 ac7022912973..a721354249ce 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c @@ -26,8 +26,6 @@ #include <core/gpuobj.h> #include <core/firmware.h> #include <engine/falcon.h> -#include <subdev/mc.h> -#include <subdev/timer.h> #include <subdev/pmu.h> #include <core/msgqueue.h> #include <engine/sec2.h> @@ -885,7 +883,6 @@ acr_r352_bootstrap(struct acr_r352 *acr, struct nvkm_secboot *sb) { const struct nvkm_subdev *subdev = &sb->subdev; unsigned long managed_falcons = acr->base.managed_falcons; - u32 reg; int falcon_id; int ret; @@ -927,50 +924,6 @@ acr_r352_bootstrap(struct acr_r352 *acr, struct nvkm_secboot *sb) } } - /* Re-start ourselves if we are managed */ - if (!nvkm_secboot_is_managed(sb, acr->base.boot_falcon)) - return 0; - - /* Enable interrupts */ - nvkm_falcon_wr32(sb->boot_falcon, 0x10, 0xff); - nvkm_mc_intr_mask(subdev->device, sb->boot_falcon->owner->index, true); - - /* Start LS firmware on boot falcon */ - nvkm_falcon_start(sb->boot_falcon); - - /* - * There is a bug where the LS firmware sometimes require to be started - * twice (this happens only on SEC). Detect and workaround that - * condition. - * - * Once started, the falcon will end up in STOPPED condition (bit 5) - * if successful, or in HALT condition (bit 4) if not. - */ - nvkm_msec(subdev->device, 1, - if ((reg = nvkm_rd32(subdev->device, - sb->boot_falcon->addr + 0x100) - & 0x30) != 0) - break; - ); - if (reg & BIT(4)) { - nvkm_debug(subdev, "applying workaround for start bug..."); - nvkm_falcon_start(sb->boot_falcon); - nvkm_msec(subdev->device, 1, - if ((reg = nvkm_rd32(subdev->device, - sb->boot_falcon->addr + 0x100) - & 0x30) != 0) - break; - ); - if (reg & BIT(4)) { - nvkm_error(subdev, "%s failed to start\n", - nvkm_secboot_falcon_name[acr->base.boot_falcon]); - return -EINVAL; - } - } - - nvkm_debug(subdev, "%s started\n", - nvkm_secboot_falcon_name[acr->base.boot_falcon]); - return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_msgqueue.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_msgqueue.c index a4dd5f198d55..ee989210725e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_msgqueue.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_msgqueue.c @@ -28,6 +28,8 @@ #include <core/msgqueue.h> #include <subdev/pmu.h> #include <engine/sec2.h> +#include <subdev/mc.h> +#include <subdev/timer.h> /** * acr_ls_ucode_load_msgqueue - load and prepare a ucode img for a msgqueue fw @@ -77,6 +79,7 @@ static int acr_ls_msgqueue_post_run(struct nvkm_msgqueue *queue, struct nvkm_falcon *falcon, u32 addr_args) { + struct nvkm_device *device = falcon->owner->device; u32 cmdline_size = NVKM_MSGQUEUE_CMDLINE_SIZE; u8 buf[cmdline_size]; @@ -86,6 +89,13 @@ acr_ls_msgqueue_post_run(struct nvkm_msgqueue *queue, /* rearm the queue so it will wait for the init message */ nvkm_msgqueue_reinit(queue); + /* Enable interrupts */ + nvkm_falcon_wr32(falcon, 0x10, 0xff); + nvkm_mc_intr_mask(device, falcon->owner->index, true); + + /* Start LS firmware on boot falcon */ + nvkm_falcon_start(falcon); + return 0; } @@ -120,6 +130,9 @@ acr_ls_pmu_post_run(const struct nvkm_acr *acr, const struct nvkm_secboot *sb) if (ret) return ret; + nvkm_debug(&sb->subdev, "%s started\n", + nvkm_secboot_falcon_name[acr->boot_falcon]); + return 0; } @@ -145,16 +158,48 @@ acr_ls_ucode_load_sec2(const struct nvkm_secboot *sb, struct ls_ucode_img *img) int acr_ls_sec2_post_run(const struct nvkm_acr *acr, const struct nvkm_secboot *sb) { - struct nvkm_device *device = sb->subdev.device; + const struct nvkm_subdev *subdev = &sb->subdev; + struct nvkm_device *device = subdev->device; struct nvkm_sec2 *sec = device->sec2; /* on SEC arguments are always at the beginning of EMEM */ - u32 addr_args = 0x01000000; + const u32 addr_args = 0x01000000; + u32 reg; int ret; ret = acr_ls_msgqueue_post_run(sec->queue, sec->falcon, addr_args); if (ret) return ret; + /* + * There is a bug where the LS firmware sometimes require to be started + * twice (this happens only on SEC). Detect and workaround that + * condition. + * + * Once started, the falcon will end up in STOPPED condition (bit 5) + * if successful, or in HALT condition (bit 4) if not. + */ + nvkm_msec(device, 1, + if ((reg = nvkm_falcon_rd32(sb->boot_falcon, 0x100) & 0x30) != 0) + break; + ); + if (reg & BIT(4)) { + nvkm_debug(subdev, "applying workaround for start bug..."); + nvkm_falcon_start(sb->boot_falcon); + nvkm_msec(subdev->device, 1, + if ((reg = nvkm_rd32(subdev->device, + sb->boot_falcon->addr + 0x100) + & 0x30) != 0) + break; + ); + if (reg & BIT(4)) { + nvkm_error(subdev, "%s failed to start\n", + nvkm_secboot_falcon_name[acr->boot_falcon]); + return -EINVAL; + } + } + + nvkm_debug(&sb->subdev, "%s started\n", + nvkm_secboot_falcon_name[acr->boot_falcon]); return 0; } |