diff options
author | Alexandre Courbot <acourbot@nvidia.com> | 2017-03-29 05:31:12 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2017-04-06 00:39:04 -0400 |
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 @@ | |||
26 | #include <core/gpuobj.h> | 26 | #include <core/gpuobj.h> |
27 | #include <core/firmware.h> | 27 | #include <core/firmware.h> |
28 | #include <engine/falcon.h> | 28 | #include <engine/falcon.h> |
29 | #include <subdev/mc.h> | ||
30 | #include <subdev/timer.h> | ||
31 | #include <subdev/pmu.h> | 29 | #include <subdev/pmu.h> |
32 | #include <core/msgqueue.h> | 30 | #include <core/msgqueue.h> |
33 | #include <engine/sec2.h> | 31 | #include <engine/sec2.h> |
@@ -885,7 +883,6 @@ acr_r352_bootstrap(struct acr_r352 *acr, struct nvkm_secboot *sb) | |||
885 | { | 883 | { |
886 | const struct nvkm_subdev *subdev = &sb->subdev; | 884 | const struct nvkm_subdev *subdev = &sb->subdev; |
887 | unsigned long managed_falcons = acr->base.managed_falcons; | 885 | unsigned long managed_falcons = acr->base.managed_falcons; |
888 | u32 reg; | ||
889 | int falcon_id; | 886 | int falcon_id; |
890 | int ret; | 887 | int ret; |
891 | 888 | ||
@@ -927,50 +924,6 @@ acr_r352_bootstrap(struct acr_r352 *acr, struct nvkm_secboot *sb) | |||
927 | } | 924 | } |
928 | } | 925 | } |
929 | 926 | ||
930 | /* Re-start ourselves if we are managed */ | ||
931 | if (!nvkm_secboot_is_managed(sb, acr->base.boot_falcon)) | ||
932 | return 0; | ||
933 | |||
934 | /* Enable interrupts */ | ||
935 | nvkm_falcon_wr32(sb->boot_falcon, 0x10, 0xff); | ||
936 | nvkm_mc_intr_mask(subdev->device, sb->boot_falcon->owner->index, true); | ||
937 | |||
938 | /* Start LS firmware on boot falcon */ | ||
939 | nvkm_falcon_start(sb->boot_falcon); | ||
940 | |||
941 | /* | ||
942 | * There is a bug where the LS firmware sometimes require to be started | ||
943 | * twice (this happens only on SEC). Detect and workaround that | ||
944 | * condition. | ||
945 | * | ||
946 | * Once started, the falcon will end up in STOPPED condition (bit 5) | ||
947 | * if successful, or in HALT condition (bit 4) if not. | ||
948 | */ | ||
949 | nvkm_msec(subdev->device, 1, | ||
950 | if ((reg = nvkm_rd32(subdev->device, | ||
951 | sb->boot_falcon->addr + 0x100) | ||
952 | & 0x30) != 0) | ||
953 | break; | ||
954 | ); | ||
955 | if (reg & BIT(4)) { | ||
956 | nvkm_debug(subdev, "applying workaround for start bug..."); | ||
957 | nvkm_falcon_start(sb->boot_falcon); | ||
958 | nvkm_msec(subdev->device, 1, | ||
959 | if ((reg = nvkm_rd32(subdev->device, | ||
960 | sb->boot_falcon->addr + 0x100) | ||
961 | & 0x30) != 0) | ||
962 | break; | ||
963 | ); | ||
964 | if (reg & BIT(4)) { | ||
965 | nvkm_error(subdev, "%s failed to start\n", | ||
966 | nvkm_secboot_falcon_name[acr->base.boot_falcon]); | ||
967 | return -EINVAL; | ||
968 | } | ||
969 | } | ||
970 | |||
971 | nvkm_debug(subdev, "%s started\n", | ||
972 | nvkm_secboot_falcon_name[acr->base.boot_falcon]); | ||
973 | |||
974 | return 0; | 927 | return 0; |
975 | } | 928 | } |
976 | 929 | ||
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 @@ | |||
28 | #include <core/msgqueue.h> | 28 | #include <core/msgqueue.h> |
29 | #include <subdev/pmu.h> | 29 | #include <subdev/pmu.h> |
30 | #include <engine/sec2.h> | 30 | #include <engine/sec2.h> |
31 | #include <subdev/mc.h> | ||
32 | #include <subdev/timer.h> | ||
31 | 33 | ||
32 | /** | 34 | /** |
33 | * acr_ls_ucode_load_msgqueue - load and prepare a ucode img for a msgqueue fw | 35 | * acr_ls_ucode_load_msgqueue - load and prepare a ucode img for a msgqueue fw |
@@ -77,6 +79,7 @@ static int | |||
77 | acr_ls_msgqueue_post_run(struct nvkm_msgqueue *queue, | 79 | acr_ls_msgqueue_post_run(struct nvkm_msgqueue *queue, |
78 | struct nvkm_falcon *falcon, u32 addr_args) | 80 | struct nvkm_falcon *falcon, u32 addr_args) |
79 | { | 81 | { |
82 | struct nvkm_device *device = falcon->owner->device; | ||
80 | u32 cmdline_size = NVKM_MSGQUEUE_CMDLINE_SIZE; | 83 | u32 cmdline_size = NVKM_MSGQUEUE_CMDLINE_SIZE; |
81 | u8 buf[cmdline_size]; | 84 | u8 buf[cmdline_size]; |
82 | 85 | ||
@@ -86,6 +89,13 @@ acr_ls_msgqueue_post_run(struct nvkm_msgqueue *queue, | |||
86 | /* rearm the queue so it will wait for the init message */ | 89 | /* rearm the queue so it will wait for the init message */ |
87 | nvkm_msgqueue_reinit(queue); | 90 | nvkm_msgqueue_reinit(queue); |
88 | 91 | ||
92 | /* Enable interrupts */ | ||
93 | nvkm_falcon_wr32(falcon, 0x10, 0xff); | ||
94 | nvkm_mc_intr_mask(device, falcon->owner->index, true); | ||
95 | |||
96 | /* Start LS firmware on boot falcon */ | ||
97 | nvkm_falcon_start(falcon); | ||
98 | |||
89 | return 0; | 99 | return 0; |
90 | } | 100 | } |
91 | 101 | ||
@@ -120,6 +130,9 @@ acr_ls_pmu_post_run(const struct nvkm_acr *acr, const struct nvkm_secboot *sb) | |||
120 | if (ret) | 130 | if (ret) |
121 | return ret; | 131 | return ret; |
122 | 132 | ||
133 | nvkm_debug(&sb->subdev, "%s started\n", | ||
134 | nvkm_secboot_falcon_name[acr->boot_falcon]); | ||
135 | |||
123 | return 0; | 136 | return 0; |
124 | } | 137 | } |
125 | 138 | ||
@@ -145,16 +158,48 @@ acr_ls_ucode_load_sec2(const struct nvkm_secboot *sb, struct ls_ucode_img *img) | |||
145 | int | 158 | int |
146 | acr_ls_sec2_post_run(const struct nvkm_acr *acr, const struct nvkm_secboot *sb) | 159 | acr_ls_sec2_post_run(const struct nvkm_acr *acr, const struct nvkm_secboot *sb) |
147 | { | 160 | { |
148 | struct nvkm_device *device = sb->subdev.device; | 161 | const struct nvkm_subdev *subdev = &sb->subdev; |
162 | struct nvkm_device *device = subdev->device; | ||
149 | struct nvkm_sec2 *sec = device->sec2; | 163 | struct nvkm_sec2 *sec = device->sec2; |
150 | /* on SEC arguments are always at the beginning of EMEM */ | 164 | /* on SEC arguments are always at the beginning of EMEM */ |
151 | u32 addr_args = 0x01000000; | 165 | const u32 addr_args = 0x01000000; |
166 | u32 reg; | ||
152 | int ret; | 167 | int ret; |
153 | 168 | ||
154 | ret = acr_ls_msgqueue_post_run(sec->queue, sec->falcon, addr_args); | 169 | ret = acr_ls_msgqueue_post_run(sec->queue, sec->falcon, addr_args); |
155 | if (ret) | 170 | if (ret) |
156 | return ret; | 171 | return ret; |
157 | 172 | ||
173 | /* | ||
174 | * There is a bug where the LS firmware sometimes require to be started | ||
175 | * twice (this happens only on SEC). Detect and workaround that | ||
176 | * condition. | ||
177 | * | ||
178 | * Once started, the falcon will end up in STOPPED condition (bit 5) | ||
179 | * if successful, or in HALT condition (bit 4) if not. | ||
180 | */ | ||
181 | nvkm_msec(device, 1, | ||
182 | if ((reg = nvkm_falcon_rd32(sb->boot_falcon, 0x100) & 0x30) != 0) | ||
183 | break; | ||
184 | ); | ||
185 | if (reg & BIT(4)) { | ||
186 | nvkm_debug(subdev, "applying workaround for start bug..."); | ||
187 | nvkm_falcon_start(sb->boot_falcon); | ||
188 | nvkm_msec(subdev->device, 1, | ||
189 | if ((reg = nvkm_rd32(subdev->device, | ||
190 | sb->boot_falcon->addr + 0x100) | ||
191 | & 0x30) != 0) | ||
192 | break; | ||
193 | ); | ||
194 | if (reg & BIT(4)) { | ||
195 | nvkm_error(subdev, "%s failed to start\n", | ||
196 | nvkm_secboot_falcon_name[acr->boot_falcon]); | ||
197 | return -EINVAL; | ||
198 | } | ||
199 | } | ||
200 | |||
201 | nvkm_debug(&sb->subdev, "%s started\n", | ||
202 | nvkm_secboot_falcon_name[acr->boot_falcon]); | ||
158 | 203 | ||
159 | return 0; | 204 | return 0; |
160 | } | 205 | } |