diff options
author | Sean Paul <seanpaul@chromium.org> | 2017-05-18 09:24:30 -0400 |
---|---|---|
committer | Sean Paul <seanpaul@chromium.org> | 2017-05-18 09:24:30 -0400 |
commit | 6b7781b42dc9bc9bcd1523b6c24b876cdda0bef3 (patch) | |
tree | ee55c67e4ea30b9eb44f301ba0bde2e631a26162 /drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | |
parent | 52d9d38c183bf0e09601d875ea31bb53c05dd8cf (diff) | |
parent | e98c58e55f68f8785aebfab1f8c9a03d8de0afe1 (diff) |
Merge remote-tracking branch 'airlied/drm-next' into drm-misc-next
Picking up drm-next @ 4.12-rc1 in order to apply Michal Hocko's vmalloc patch set
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 229 |
1 files changed, 146 insertions, 83 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index e6cf91ca5761..596e3957bdd9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | |||
@@ -55,6 +55,8 @@ static int psp_sw_init(void *handle) | |||
55 | psp->bootloader_load_sos = psp_v3_1_bootloader_load_sos; | 55 | psp->bootloader_load_sos = psp_v3_1_bootloader_load_sos; |
56 | psp->prep_cmd_buf = psp_v3_1_prep_cmd_buf; | 56 | psp->prep_cmd_buf = psp_v3_1_prep_cmd_buf; |
57 | psp->ring_init = psp_v3_1_ring_init; | 57 | psp->ring_init = psp_v3_1_ring_init; |
58 | psp->ring_create = psp_v3_1_ring_create; | ||
59 | psp->ring_destroy = psp_v3_1_ring_destroy; | ||
58 | psp->cmd_submit = psp_v3_1_cmd_submit; | 60 | psp->cmd_submit = psp_v3_1_cmd_submit; |
59 | psp->compare_sram_data = psp_v3_1_compare_sram_data; | 61 | psp->compare_sram_data = psp_v3_1_compare_sram_data; |
60 | psp->smu_reload_quirk = psp_v3_1_smu_reload_quirk; | 62 | psp->smu_reload_quirk = psp_v3_1_smu_reload_quirk; |
@@ -152,11 +154,6 @@ static void psp_prep_tmr_cmd_buf(struct psp_gfx_cmd_resp *cmd, | |||
152 | static int psp_tmr_init(struct psp_context *psp) | 154 | static int psp_tmr_init(struct psp_context *psp) |
153 | { | 155 | { |
154 | int ret; | 156 | int ret; |
155 | struct psp_gfx_cmd_resp *cmd; | ||
156 | |||
157 | cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); | ||
158 | if (!cmd) | ||
159 | return -ENOMEM; | ||
160 | 157 | ||
161 | /* | 158 | /* |
162 | * Allocate 3M memory aligned to 1M from Frame Buffer (local | 159 | * Allocate 3M memory aligned to 1M from Frame Buffer (local |
@@ -168,22 +165,30 @@ static int psp_tmr_init(struct psp_context *psp) | |||
168 | ret = amdgpu_bo_create_kernel(psp->adev, 0x300000, 0x100000, | 165 | ret = amdgpu_bo_create_kernel(psp->adev, 0x300000, 0x100000, |
169 | AMDGPU_GEM_DOMAIN_VRAM, | 166 | AMDGPU_GEM_DOMAIN_VRAM, |
170 | &psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf); | 167 | &psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf); |
171 | if (ret) | 168 | |
172 | goto failed; | 169 | return ret; |
170 | } | ||
171 | |||
172 | static int psp_tmr_load(struct psp_context *psp) | ||
173 | { | ||
174 | int ret; | ||
175 | struct psp_gfx_cmd_resp *cmd; | ||
176 | |||
177 | cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); | ||
178 | if (!cmd) | ||
179 | return -ENOMEM; | ||
173 | 180 | ||
174 | psp_prep_tmr_cmd_buf(cmd, psp->tmr_mc_addr, 0x300000); | 181 | psp_prep_tmr_cmd_buf(cmd, psp->tmr_mc_addr, 0x300000); |
175 | 182 | ||
176 | ret = psp_cmd_submit_buf(psp, NULL, cmd, | 183 | ret = psp_cmd_submit_buf(psp, NULL, cmd, |
177 | psp->fence_buf_mc_addr, 1); | 184 | psp->fence_buf_mc_addr, 1); |
178 | if (ret) | 185 | if (ret) |
179 | goto failed_mem; | 186 | goto failed; |
180 | 187 | ||
181 | kfree(cmd); | 188 | kfree(cmd); |
182 | 189 | ||
183 | return 0; | 190 | return 0; |
184 | 191 | ||
185 | failed_mem: | ||
186 | amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf); | ||
187 | failed: | 192 | failed: |
188 | kfree(cmd); | 193 | kfree(cmd); |
189 | return ret; | 194 | return ret; |
@@ -203,104 +208,78 @@ static void psp_prep_asd_cmd_buf(struct psp_gfx_cmd_resp *cmd, | |||
203 | cmd->cmd.cmd_load_ta.cmd_buf_len = shared_size; | 208 | cmd->cmd.cmd_load_ta.cmd_buf_len = shared_size; |
204 | } | 209 | } |
205 | 210 | ||
206 | static int psp_asd_load(struct psp_context *psp) | 211 | static int psp_asd_init(struct psp_context *psp) |
207 | { | 212 | { |
208 | int ret; | 213 | int ret; |
209 | struct amdgpu_bo *asd_bo, *asd_shared_bo; | ||
210 | uint64_t asd_mc_addr, asd_shared_mc_addr; | ||
211 | void *asd_buf, *asd_shared_buf; | ||
212 | struct psp_gfx_cmd_resp *cmd; | ||
213 | |||
214 | cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); | ||
215 | if (!cmd) | ||
216 | return -ENOMEM; | ||
217 | 214 | ||
218 | /* | 215 | /* |
219 | * Allocate 16k memory aligned to 4k from Frame Buffer (local | 216 | * Allocate 16k memory aligned to 4k from Frame Buffer (local |
220 | * physical) for shared ASD <-> Driver | 217 | * physical) for shared ASD <-> Driver |
221 | */ | 218 | */ |
222 | ret = amdgpu_bo_create_kernel(psp->adev, PSP_ASD_SHARED_MEM_SIZE, PAGE_SIZE, | 219 | ret = amdgpu_bo_create_kernel(psp->adev, PSP_ASD_SHARED_MEM_SIZE, |
223 | AMDGPU_GEM_DOMAIN_VRAM, | 220 | PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM, |
224 | &asd_shared_bo, &asd_shared_mc_addr, &asd_buf); | 221 | &psp->asd_shared_bo, |
225 | if (ret) | 222 | &psp->asd_shared_mc_addr, |
226 | goto failed; | 223 | &psp->asd_shared_buf); |
227 | 224 | ||
228 | /* | 225 | return ret; |
229 | * Allocate 256k memory aligned to 4k from Frame Buffer (local | 226 | } |
230 | * physical) for ASD firmware | 227 | |
231 | */ | 228 | static int psp_asd_load(struct psp_context *psp) |
232 | ret = amdgpu_bo_create_kernel(psp->adev, PSP_ASD_BIN_SIZE, PAGE_SIZE, | 229 | { |
233 | AMDGPU_GEM_DOMAIN_VRAM, | 230 | int ret; |
234 | &asd_bo, &asd_mc_addr, &asd_buf); | 231 | struct psp_gfx_cmd_resp *cmd; |
235 | if (ret) | 232 | |
236 | goto failed_mem; | 233 | cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); |
234 | if (!cmd) | ||
235 | return -ENOMEM; | ||
237 | 236 | ||
238 | memcpy(asd_buf, psp->asd_start_addr, psp->asd_ucode_size); | 237 | memset(psp->fw_pri_buf, 0, PSP_1_MEG); |
238 | memcpy(psp->fw_pri_buf, psp->asd_start_addr, psp->asd_ucode_size); | ||
239 | 239 | ||
240 | psp_prep_asd_cmd_buf(cmd, asd_mc_addr, asd_shared_mc_addr, | 240 | psp_prep_asd_cmd_buf(cmd, psp->fw_pri_mc_addr, psp->asd_shared_mc_addr, |
241 | psp->asd_ucode_size, PSP_ASD_SHARED_MEM_SIZE); | 241 | psp->asd_ucode_size, PSP_ASD_SHARED_MEM_SIZE); |
242 | 242 | ||
243 | ret = psp_cmd_submit_buf(psp, NULL, cmd, | 243 | ret = psp_cmd_submit_buf(psp, NULL, cmd, |
244 | psp->fence_buf_mc_addr, 2); | 244 | psp->fence_buf_mc_addr, 2); |
245 | if (ret) | ||
246 | goto failed_mem1; | ||
247 | 245 | ||
248 | amdgpu_bo_free_kernel(&asd_bo, &asd_mc_addr, &asd_buf); | ||
249 | amdgpu_bo_free_kernel(&asd_shared_bo, &asd_shared_mc_addr, &asd_shared_buf); | ||
250 | kfree(cmd); | 246 | kfree(cmd); |
251 | 247 | ||
252 | return 0; | ||
253 | |||
254 | failed_mem1: | ||
255 | amdgpu_bo_free_kernel(&asd_bo, &asd_mc_addr, &asd_buf); | ||
256 | failed_mem: | ||
257 | amdgpu_bo_free_kernel(&asd_shared_bo, &asd_shared_mc_addr, &asd_shared_buf); | ||
258 | failed: | ||
259 | kfree(cmd); | ||
260 | return ret; | 248 | return ret; |
261 | } | 249 | } |
262 | 250 | ||
263 | static int psp_load_fw(struct amdgpu_device *adev) | 251 | static int psp_hw_start(struct psp_context *psp) |
264 | { | 252 | { |
265 | int ret; | 253 | int ret; |
266 | struct psp_gfx_cmd_resp *cmd; | ||
267 | int i; | ||
268 | struct amdgpu_firmware_info *ucode; | ||
269 | struct psp_context *psp = &adev->psp; | ||
270 | |||
271 | cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); | ||
272 | if (!cmd) | ||
273 | return -ENOMEM; | ||
274 | 254 | ||
275 | ret = psp_bootloader_load_sysdrv(psp); | 255 | ret = psp_bootloader_load_sysdrv(psp); |
276 | if (ret) | 256 | if (ret) |
277 | goto failed; | 257 | return ret; |
278 | 258 | ||
279 | ret = psp_bootloader_load_sos(psp); | 259 | ret = psp_bootloader_load_sos(psp); |
280 | if (ret) | 260 | if (ret) |
281 | goto failed; | 261 | return ret; |
282 | |||
283 | ret = psp_ring_init(psp, PSP_RING_TYPE__KM); | ||
284 | if (ret) | ||
285 | goto failed; | ||
286 | 262 | ||
287 | ret = amdgpu_bo_create_kernel(adev, PSP_FENCE_BUFFER_SIZE, PAGE_SIZE, | 263 | ret = psp_ring_create(psp, PSP_RING_TYPE__KM); |
288 | AMDGPU_GEM_DOMAIN_VRAM, | ||
289 | &psp->fence_buf_bo, | ||
290 | &psp->fence_buf_mc_addr, | ||
291 | &psp->fence_buf); | ||
292 | if (ret) | 264 | if (ret) |
293 | goto failed; | 265 | return ret; |
294 | |||
295 | memset(psp->fence_buf, 0, PSP_FENCE_BUFFER_SIZE); | ||
296 | 266 | ||
297 | ret = psp_tmr_init(psp); | 267 | ret = psp_tmr_load(psp); |
298 | if (ret) | 268 | if (ret) |
299 | goto failed_mem; | 269 | return ret; |
300 | 270 | ||
301 | ret = psp_asd_load(psp); | 271 | ret = psp_asd_load(psp); |
302 | if (ret) | 272 | if (ret) |
303 | goto failed_mem; | 273 | return ret; |
274 | |||
275 | return 0; | ||
276 | } | ||
277 | |||
278 | static int psp_np_fw_load(struct psp_context *psp) | ||
279 | { | ||
280 | int i, ret; | ||
281 | struct amdgpu_firmware_info *ucode; | ||
282 | struct amdgpu_device* adev = psp->adev; | ||
304 | 283 | ||
305 | for (i = 0; i < adev->firmware.max_ucodes; i++) { | 284 | for (i = 0; i < adev->firmware.max_ucodes; i++) { |
306 | ucode = &adev->firmware.ucode[i]; | 285 | ucode = &adev->firmware.ucode[i]; |
@@ -310,15 +289,21 @@ static int psp_load_fw(struct amdgpu_device *adev) | |||
310 | if (ucode->ucode_id == AMDGPU_UCODE_ID_SMC && | 289 | if (ucode->ucode_id == AMDGPU_UCODE_ID_SMC && |
311 | psp_smu_reload_quirk(psp)) | 290 | psp_smu_reload_quirk(psp)) |
312 | continue; | 291 | continue; |
292 | if (amdgpu_sriov_vf(adev) && | ||
293 | (ucode->ucode_id == AMDGPU_UCODE_ID_SDMA0 | ||
294 | || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA1 | ||
295 | || ucode->ucode_id == AMDGPU_UCODE_ID_RLC_G)) | ||
296 | /*skip ucode loading in SRIOV VF */ | ||
297 | continue; | ||
313 | 298 | ||
314 | ret = psp_prep_cmd_buf(ucode, cmd); | 299 | ret = psp_prep_cmd_buf(ucode, psp->cmd); |
315 | if (ret) | 300 | if (ret) |
316 | goto failed_mem; | 301 | return ret; |
317 | 302 | ||
318 | ret = psp_cmd_submit_buf(psp, ucode, cmd, | 303 | ret = psp_cmd_submit_buf(psp, ucode, psp->cmd, |
319 | psp->fence_buf_mc_addr, i + 3); | 304 | psp->fence_buf_mc_addr, i + 3); |
320 | if (ret) | 305 | if (ret) |
321 | goto failed_mem; | 306 | return ret; |
322 | 307 | ||
323 | #if 0 | 308 | #if 0 |
324 | /* check if firmware loaded sucessfully */ | 309 | /* check if firmware loaded sucessfully */ |
@@ -327,8 +312,59 @@ static int psp_load_fw(struct amdgpu_device *adev) | |||
327 | #endif | 312 | #endif |
328 | } | 313 | } |
329 | 314 | ||
330 | amdgpu_bo_free_kernel(&psp->fence_buf_bo, | 315 | return 0; |
331 | &psp->fence_buf_mc_addr, &psp->fence_buf); | 316 | } |
317 | |||
318 | static int psp_load_fw(struct amdgpu_device *adev) | ||
319 | { | ||
320 | int ret; | ||
321 | struct psp_context *psp = &adev->psp; | ||
322 | struct psp_gfx_cmd_resp *cmd; | ||
323 | |||
324 | cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); | ||
325 | if (!cmd) | ||
326 | return -ENOMEM; | ||
327 | |||
328 | psp->cmd = cmd; | ||
329 | |||
330 | ret = amdgpu_bo_create_kernel(adev, PSP_1_MEG, PSP_1_MEG, | ||
331 | AMDGPU_GEM_DOMAIN_GTT, | ||
332 | &psp->fw_pri_bo, | ||
333 | &psp->fw_pri_mc_addr, | ||
334 | &psp->fw_pri_buf); | ||
335 | if (ret) | ||
336 | goto failed; | ||
337 | |||
338 | ret = amdgpu_bo_create_kernel(adev, PSP_FENCE_BUFFER_SIZE, PAGE_SIZE, | ||
339 | AMDGPU_GEM_DOMAIN_VRAM, | ||
340 | &psp->fence_buf_bo, | ||
341 | &psp->fence_buf_mc_addr, | ||
342 | &psp->fence_buf); | ||
343 | if (ret) | ||
344 | goto failed_mem1; | ||
345 | |||
346 | memset(psp->fence_buf, 0, PSP_FENCE_BUFFER_SIZE); | ||
347 | |||
348 | ret = psp_ring_init(psp, PSP_RING_TYPE__KM); | ||
349 | if (ret) | ||
350 | goto failed_mem1; | ||
351 | |||
352 | ret = psp_tmr_init(psp); | ||
353 | if (ret) | ||
354 | goto failed_mem; | ||
355 | |||
356 | ret = psp_asd_init(psp); | ||
357 | if (ret) | ||
358 | goto failed_mem; | ||
359 | |||
360 | ret = psp_hw_start(psp); | ||
361 | if (ret) | ||
362 | goto failed_mem; | ||
363 | |||
364 | ret = psp_np_fw_load(psp); | ||
365 | if (ret) | ||
366 | goto failed_mem; | ||
367 | |||
332 | kfree(cmd); | 368 | kfree(cmd); |
333 | 369 | ||
334 | return 0; | 370 | return 0; |
@@ -336,6 +372,9 @@ static int psp_load_fw(struct amdgpu_device *adev) | |||
336 | failed_mem: | 372 | failed_mem: |
337 | amdgpu_bo_free_kernel(&psp->fence_buf_bo, | 373 | amdgpu_bo_free_kernel(&psp->fence_buf_bo, |
338 | &psp->fence_buf_mc_addr, &psp->fence_buf); | 374 | &psp->fence_buf_mc_addr, &psp->fence_buf); |
375 | failed_mem1: | ||
376 | amdgpu_bo_free_kernel(&psp->fw_pri_bo, | ||
377 | &psp->fw_pri_mc_addr, &psp->fw_pri_buf); | ||
339 | failed: | 378 | failed: |
340 | kfree(cmd); | 379 | kfree(cmd); |
341 | return ret; | 380 | return ret; |
@@ -379,12 +418,24 @@ static int psp_hw_fini(void *handle) | |||
379 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 418 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
380 | struct psp_context *psp = &adev->psp; | 419 | struct psp_context *psp = &adev->psp; |
381 | 420 | ||
382 | if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) | 421 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) |
383 | amdgpu_ucode_fini_bo(adev); | 422 | return 0; |
423 | |||
424 | amdgpu_ucode_fini_bo(adev); | ||
425 | |||
426 | psp_ring_destroy(psp, PSP_RING_TYPE__KM); | ||
384 | 427 | ||
385 | if (psp->tmr_buf) | 428 | if (psp->tmr_buf) |
386 | amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf); | 429 | amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf); |
387 | 430 | ||
431 | if (psp->fw_pri_buf) | ||
432 | amdgpu_bo_free_kernel(&psp->fw_pri_bo, | ||
433 | &psp->fw_pri_mc_addr, &psp->fw_pri_buf); | ||
434 | |||
435 | if (psp->fence_buf_bo) | ||
436 | amdgpu_bo_free_kernel(&psp->fence_buf_bo, | ||
437 | &psp->fence_buf_mc_addr, &psp->fence_buf); | ||
438 | |||
388 | return 0; | 439 | return 0; |
389 | } | 440 | } |
390 | 441 | ||
@@ -397,18 +448,30 @@ static int psp_resume(void *handle) | |||
397 | { | 448 | { |
398 | int ret; | 449 | int ret; |
399 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 450 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
451 | struct psp_context *psp = &adev->psp; | ||
400 | 452 | ||
401 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) | 453 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) |
402 | return 0; | 454 | return 0; |
403 | 455 | ||
456 | DRM_INFO("PSP is resuming...\n"); | ||
457 | |||
404 | mutex_lock(&adev->firmware.mutex); | 458 | mutex_lock(&adev->firmware.mutex); |
405 | 459 | ||
406 | ret = psp_load_fw(adev); | 460 | ret = psp_hw_start(psp); |
407 | if (ret) | 461 | if (ret) |
408 | DRM_ERROR("PSP resume failed\n"); | 462 | goto failed; |
463 | |||
464 | ret = psp_np_fw_load(psp); | ||
465 | if (ret) | ||
466 | goto failed; | ||
409 | 467 | ||
410 | mutex_unlock(&adev->firmware.mutex); | 468 | mutex_unlock(&adev->firmware.mutex); |
411 | 469 | ||
470 | return 0; | ||
471 | |||
472 | failed: | ||
473 | DRM_ERROR("PSP resume failed\n"); | ||
474 | mutex_unlock(&adev->firmware.mutex); | ||
412 | return ret; | 475 | return ret; |
413 | } | 476 | } |
414 | 477 | ||