diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 115 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/psp_v3_1.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/psp_v3_1.h | 2 |
4 files changed, 87 insertions, 44 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index ea5616036bf6..0d20dc3ea84e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | |||
@@ -55,6 +55,7 @@ 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; | ||
58 | psp->cmd_submit = psp_v3_1_cmd_submit; | 59 | psp->cmd_submit = psp_v3_1_cmd_submit; |
59 | psp->compare_sram_data = psp_v3_1_compare_sram_data; | 60 | psp->compare_sram_data = psp_v3_1_compare_sram_data; |
60 | psp->smu_reload_quirk = psp_v3_1_smu_reload_quirk; | 61 | psp->smu_reload_quirk = psp_v3_1_smu_reload_quirk; |
@@ -246,18 +247,79 @@ static int psp_asd_load(struct psp_context *psp) | |||
246 | return ret; | 247 | return ret; |
247 | } | 248 | } |
248 | 249 | ||
249 | static int psp_load_fw(struct amdgpu_device *adev) | 250 | static int psp_hw_start(struct psp_context *psp) |
250 | { | 251 | { |
251 | int ret; | 252 | int ret; |
252 | struct psp_gfx_cmd_resp *cmd; | 253 | |
253 | int i; | 254 | ret = psp_bootloader_load_sysdrv(psp); |
255 | if (ret) | ||
256 | return ret; | ||
257 | |||
258 | ret = psp_bootloader_load_sos(psp); | ||
259 | if (ret) | ||
260 | return ret; | ||
261 | |||
262 | ret = psp_ring_create(psp, PSP_RING_TYPE__KM); | ||
263 | if (ret) | ||
264 | return ret; | ||
265 | |||
266 | ret = psp_tmr_load(psp); | ||
267 | if (ret) | ||
268 | return ret; | ||
269 | |||
270 | ret = psp_asd_load(psp); | ||
271 | if (ret) | ||
272 | return ret; | ||
273 | |||
274 | return 0; | ||
275 | } | ||
276 | |||
277 | static int psp_np_fw_load(struct psp_context *psp) | ||
278 | { | ||
279 | int i, ret; | ||
254 | struct amdgpu_firmware_info *ucode; | 280 | struct amdgpu_firmware_info *ucode; |
281 | struct amdgpu_device* adev = psp->adev; | ||
282 | |||
283 | for (i = 0; i < adev->firmware.max_ucodes; i++) { | ||
284 | ucode = &adev->firmware.ucode[i]; | ||
285 | if (!ucode->fw) | ||
286 | continue; | ||
287 | |||
288 | if (ucode->ucode_id == AMDGPU_UCODE_ID_SMC && | ||
289 | psp_smu_reload_quirk(psp)) | ||
290 | continue; | ||
291 | |||
292 | ret = psp_prep_cmd_buf(ucode, psp->cmd); | ||
293 | if (ret) | ||
294 | return ret; | ||
295 | |||
296 | ret = psp_cmd_submit_buf(psp, ucode, psp->cmd, | ||
297 | psp->fence_buf_mc_addr, i + 3); | ||
298 | if (ret) | ||
299 | return ret; | ||
300 | |||
301 | #if 0 | ||
302 | /* check if firmware loaded sucessfully */ | ||
303 | if (!amdgpu_psp_check_fw_loading_status(adev, i)) | ||
304 | return -EINVAL; | ||
305 | #endif | ||
306 | } | ||
307 | |||
308 | return 0; | ||
309 | } | ||
310 | |||
311 | static int psp_load_fw(struct amdgpu_device *adev) | ||
312 | { | ||
313 | int ret; | ||
255 | struct psp_context *psp = &adev->psp; | 314 | struct psp_context *psp = &adev->psp; |
315 | struct psp_gfx_cmd_resp *cmd; | ||
256 | 316 | ||
257 | cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); | 317 | cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); |
258 | if (!cmd) | 318 | if (!cmd) |
259 | return -ENOMEM; | 319 | return -ENOMEM; |
260 | 320 | ||
321 | psp->cmd = cmd; | ||
322 | |||
261 | ret = amdgpu_bo_create_kernel(adev, PSP_1_MEG, PSP_1_MEG, | 323 | ret = amdgpu_bo_create_kernel(adev, PSP_1_MEG, PSP_1_MEG, |
262 | AMDGPU_GEM_DOMAIN_GTT, | 324 | AMDGPU_GEM_DOMAIN_GTT, |
263 | &psp->fw_pri_bo, | 325 | &psp->fw_pri_bo, |
@@ -266,18 +328,6 @@ static int psp_load_fw(struct amdgpu_device *adev) | |||
266 | if (ret) | 328 | if (ret) |
267 | goto failed; | 329 | goto failed; |
268 | 330 | ||
269 | ret = psp_bootloader_load_sysdrv(psp); | ||
270 | if (ret) | ||
271 | goto failed_mem1; | ||
272 | |||
273 | ret = psp_bootloader_load_sos(psp); | ||
274 | if (ret) | ||
275 | goto failed_mem1; | ||
276 | |||
277 | ret = psp_ring_init(psp, PSP_RING_TYPE__KM); | ||
278 | if (ret) | ||
279 | goto failed_mem1; | ||
280 | |||
281 | ret = amdgpu_bo_create_kernel(adev, PSP_FENCE_BUFFER_SIZE, PAGE_SIZE, | 331 | ret = amdgpu_bo_create_kernel(adev, PSP_FENCE_BUFFER_SIZE, PAGE_SIZE, |
282 | AMDGPU_GEM_DOMAIN_VRAM, | 332 | AMDGPU_GEM_DOMAIN_VRAM, |
283 | &psp->fence_buf_bo, | 333 | &psp->fence_buf_bo, |
@@ -288,11 +338,11 @@ static int psp_load_fw(struct amdgpu_device *adev) | |||
288 | 338 | ||
289 | memset(psp->fence_buf, 0, PSP_FENCE_BUFFER_SIZE); | 339 | memset(psp->fence_buf, 0, PSP_FENCE_BUFFER_SIZE); |
290 | 340 | ||
291 | ret = psp_tmr_init(psp); | 341 | ret = psp_ring_init(psp, PSP_RING_TYPE__KM); |
292 | if (ret) | 342 | if (ret) |
293 | goto failed_mem; | 343 | goto failed_mem1; |
294 | 344 | ||
295 | ret = psp_tmr_load(psp); | 345 | ret = psp_tmr_init(psp); |
296 | if (ret) | 346 | if (ret) |
297 | goto failed_mem; | 347 | goto failed_mem; |
298 | 348 | ||
@@ -300,34 +350,13 @@ static int psp_load_fw(struct amdgpu_device *adev) | |||
300 | if (ret) | 350 | if (ret) |
301 | goto failed_mem; | 351 | goto failed_mem; |
302 | 352 | ||
303 | ret = psp_asd_load(psp); | 353 | ret = psp_hw_start(psp); |
304 | if (ret) | 354 | if (ret) |
305 | goto failed_mem; | 355 | goto failed_mem; |
306 | 356 | ||
307 | for (i = 0; i < adev->firmware.max_ucodes; i++) { | 357 | ret = psp_np_fw_load(psp); |
308 | ucode = &adev->firmware.ucode[i]; | 358 | if (ret) |
309 | if (!ucode->fw) | 359 | goto failed_mem; |
310 | continue; | ||
311 | |||
312 | if (ucode->ucode_id == AMDGPU_UCODE_ID_SMC && | ||
313 | psp_smu_reload_quirk(psp)) | ||
314 | continue; | ||
315 | |||
316 | ret = psp_prep_cmd_buf(ucode, cmd); | ||
317 | if (ret) | ||
318 | goto failed_mem; | ||
319 | |||
320 | ret = psp_cmd_submit_buf(psp, ucode, cmd, | ||
321 | psp->fence_buf_mc_addr, i + 3); | ||
322 | if (ret) | ||
323 | goto failed_mem; | ||
324 | |||
325 | #if 0 | ||
326 | /* check if firmware loaded sucessfully */ | ||
327 | if (!amdgpu_psp_check_fw_loading_status(adev, i)) | ||
328 | return -EINVAL; | ||
329 | #endif | ||
330 | } | ||
331 | 360 | ||
332 | amdgpu_bo_free_kernel(&psp->fence_buf_bo, | 361 | amdgpu_bo_free_kernel(&psp->fence_buf_bo, |
333 | &psp->fence_buf_mc_addr, &psp->fence_buf); | 362 | &psp->fence_buf_mc_addr, &psp->fence_buf); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h index 1f1f057c7c42..28faba5b7dd6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h | |||
@@ -57,6 +57,7 @@ struct psp_context | |||
57 | { | 57 | { |
58 | struct amdgpu_device *adev; | 58 | struct amdgpu_device *adev; |
59 | struct psp_ring km_ring; | 59 | struct psp_ring km_ring; |
60 | struct psp_gfx_cmd_resp *cmd; | ||
60 | 61 | ||
61 | int (*init_microcode)(struct psp_context *psp); | 62 | int (*init_microcode)(struct psp_context *psp); |
62 | int (*bootloader_load_sysdrv)(struct psp_context *psp); | 63 | int (*bootloader_load_sysdrv)(struct psp_context *psp); |
@@ -64,6 +65,7 @@ struct psp_context | |||
64 | int (*prep_cmd_buf)(struct amdgpu_firmware_info *ucode, | 65 | int (*prep_cmd_buf)(struct amdgpu_firmware_info *ucode, |
65 | struct psp_gfx_cmd_resp *cmd); | 66 | struct psp_gfx_cmd_resp *cmd); |
66 | int (*ring_init)(struct psp_context *psp, enum psp_ring_type ring_type); | 67 | int (*ring_init)(struct psp_context *psp, enum psp_ring_type ring_type); |
68 | int (*ring_create)(struct psp_context *psp, enum psp_ring_type ring_type); | ||
67 | int (*cmd_submit)(struct psp_context *psp, struct amdgpu_firmware_info *ucode, | 69 | int (*cmd_submit)(struct psp_context *psp, struct amdgpu_firmware_info *ucode, |
68 | uint64_t cmd_buf_mc_addr, uint64_t fence_mc_addr, int index); | 70 | uint64_t cmd_buf_mc_addr, uint64_t fence_mc_addr, int index); |
69 | bool (*compare_sram_data)(struct psp_context *psp, | 71 | bool (*compare_sram_data)(struct psp_context *psp, |
@@ -113,6 +115,7 @@ struct amdgpu_psp_funcs { | |||
113 | 115 | ||
114 | #define psp_prep_cmd_buf(ucode, type) (psp)->prep_cmd_buf((ucode), (type)) | 116 | #define psp_prep_cmd_buf(ucode, type) (psp)->prep_cmd_buf((ucode), (type)) |
115 | #define psp_ring_init(psp, type) (psp)->ring_init((psp), (type)) | 117 | #define psp_ring_init(psp, type) (psp)->ring_init((psp), (type)) |
118 | #define psp_ring_create(psp, type) (psp)->ring_create((psp), (type)) | ||
116 | #define psp_cmd_submit(psp, ucode, cmd_mc, fence_mc, index) \ | 119 | #define psp_cmd_submit(psp, ucode, cmd_mc, fence_mc, index) \ |
117 | (psp)->cmd_submit((psp), (ucode), (cmd_mc), (fence_mc), (index)) | 120 | (psp)->cmd_submit((psp), (ucode), (cmd_mc), (fence_mc), (index)) |
118 | #define psp_compare_sram_data(psp, ucode, type) \ | 121 | #define psp_compare_sram_data(psp, ucode, type) \ |
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c index aae6b6540161..d351583785e5 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c | |||
@@ -268,7 +268,6 @@ int psp_v3_1_prep_cmd_buf(struct amdgpu_firmware_info *ucode, struct psp_gfx_cmd | |||
268 | int psp_v3_1_ring_init(struct psp_context *psp, enum psp_ring_type ring_type) | 268 | int psp_v3_1_ring_init(struct psp_context *psp, enum psp_ring_type ring_type) |
269 | { | 269 | { |
270 | int ret = 0; | 270 | int ret = 0; |
271 | unsigned int psp_ring_reg = 0; | ||
272 | struct psp_ring *ring; | 271 | struct psp_ring *ring; |
273 | struct amdgpu_device *adev = psp->adev; | 272 | struct amdgpu_device *adev = psp->adev; |
274 | 273 | ||
@@ -288,6 +287,16 @@ int psp_v3_1_ring_init(struct psp_context *psp, enum psp_ring_type ring_type) | |||
288 | return ret; | 287 | return ret; |
289 | } | 288 | } |
290 | 289 | ||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | int psp_v3_1_ring_create(struct psp_context *psp, enum psp_ring_type ring_type) | ||
294 | { | ||
295 | int ret = 0; | ||
296 | unsigned int psp_ring_reg = 0; | ||
297 | struct psp_ring *ring = &psp->km_ring; | ||
298 | struct amdgpu_device *adev = psp->adev; | ||
299 | |||
291 | /* Write low address of the ring to C2PMSG_69 */ | 300 | /* Write low address of the ring to C2PMSG_69 */ |
292 | psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr); | 301 | psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr); |
293 | WREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_69), psp_ring_reg); | 302 | WREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_69), psp_ring_reg); |
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.h b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.h index e82eff741a08..5230d27867c9 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.h +++ b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.h | |||
@@ -39,6 +39,8 @@ extern int psp_v3_1_prep_cmd_buf(struct amdgpu_firmware_info *ucode, | |||
39 | struct psp_gfx_cmd_resp *cmd); | 39 | struct psp_gfx_cmd_resp *cmd); |
40 | extern int psp_v3_1_ring_init(struct psp_context *psp, | 40 | extern int psp_v3_1_ring_init(struct psp_context *psp, |
41 | enum psp_ring_type ring_type); | 41 | enum psp_ring_type ring_type); |
42 | extern int psp_v3_1_ring_create(struct psp_context *psp, | ||
43 | enum psp_ring_type ring_type); | ||
42 | extern int psp_v3_1_cmd_submit(struct psp_context *psp, | 44 | extern int psp_v3_1_cmd_submit(struct psp_context *psp, |
43 | struct amdgpu_firmware_info *ucode, | 45 | struct amdgpu_firmware_info *ucode, |
44 | uint64_t cmd_buf_mc_addr, uint64_t fence_mc_addr, | 46 | uint64_t cmd_buf_mc_addr, uint64_t fence_mc_addr, |