diff options
author | David Francis <David.Francis@amd.com> | 2018-09-11 13:41:01 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2018-09-12 17:29:09 -0400 |
commit | 01fcfc83fe07ae42af707c3217f533fb350d4c19 (patch) | |
tree | 7ebe0342d2fdddbb5b07b45cb1d8952c0d42e88c /drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | |
parent | 240cd9a64226e013ac1a608ebf720a1813790196 (diff) |
drm/amd: Add ucode DMCU support
DMCU (Display Microcontroller Unit) is a GPU chip involved in
eDP features like Adaptive Backlight Modulation and Panel Self
Refresh.
DMCU has two pieces of firmware: the ERAM and the interrupt
vectors, which must be loaded seperately.
To this end, the DMCU firmware has a custom header and parsing
logic similar to MEC, to extract the two ucodes from a single
struct firmware.
Signed-off-by: David Francis <David.Francis@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c index a942fd28dae8..1fa8bc337859 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | |||
@@ -322,6 +322,7 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev, | |||
322 | { | 322 | { |
323 | const struct common_firmware_header *header = NULL; | 323 | const struct common_firmware_header *header = NULL; |
324 | const struct gfx_firmware_header_v1_0 *cp_hdr = NULL; | 324 | const struct gfx_firmware_header_v1_0 *cp_hdr = NULL; |
325 | const struct dmcu_firmware_header_v1_0 *dmcu_hdr = NULL; | ||
325 | 326 | ||
326 | if (NULL == ucode->fw) | 327 | if (NULL == ucode->fw) |
327 | return 0; | 328 | return 0; |
@@ -333,8 +334,8 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev, | |||
333 | return 0; | 334 | return 0; |
334 | 335 | ||
335 | header = (const struct common_firmware_header *)ucode->fw->data; | 336 | header = (const struct common_firmware_header *)ucode->fw->data; |
336 | |||
337 | cp_hdr = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data; | 337 | cp_hdr = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data; |
338 | dmcu_hdr = (const struct dmcu_firmware_header_v1_0 *)ucode->fw->data; | ||
338 | 339 | ||
339 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP || | 340 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP || |
340 | (ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC1 && | 341 | (ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC1 && |
@@ -343,7 +344,9 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev, | |||
343 | ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC2_JT && | 344 | ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC2_JT && |
344 | ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL && | 345 | ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL && |
345 | ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM && | 346 | ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM && |
346 | ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM)) { | 347 | ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM && |
348 | ucode->ucode_id != AMDGPU_UCODE_ID_DMCU_ERAM && | ||
349 | ucode->ucode_id != AMDGPU_UCODE_ID_DMCU_INTV)) { | ||
347 | ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes); | 350 | ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes); |
348 | 351 | ||
349 | memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data + | 352 | memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data + |
@@ -365,6 +368,20 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev, | |||
365 | le32_to_cpu(header->ucode_array_offset_bytes) + | 368 | le32_to_cpu(header->ucode_array_offset_bytes) + |
366 | le32_to_cpu(cp_hdr->jt_offset) * 4), | 369 | le32_to_cpu(cp_hdr->jt_offset) * 4), |
367 | ucode->ucode_size); | 370 | ucode->ucode_size); |
371 | } else if (ucode->ucode_id == AMDGPU_UCODE_ID_DMCU_ERAM) { | ||
372 | ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes) - | ||
373 | le32_to_cpu(dmcu_hdr->intv_size_bytes); | ||
374 | |||
375 | memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data + | ||
376 | le32_to_cpu(header->ucode_array_offset_bytes)), | ||
377 | ucode->ucode_size); | ||
378 | } else if (ucode->ucode_id == AMDGPU_UCODE_ID_DMCU_INTV) { | ||
379 | ucode->ucode_size = le32_to_cpu(dmcu_hdr->intv_size_bytes); | ||
380 | |||
381 | memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data + | ||
382 | le32_to_cpu(header->ucode_array_offset_bytes) + | ||
383 | le32_to_cpu(dmcu_hdr->intv_offset_bytes)), | ||
384 | ucode->ucode_size); | ||
368 | } else if (ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL) { | 385 | } else if (ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL) { |
369 | ucode->ucode_size = adev->gfx.rlc.save_restore_list_cntl_size_bytes; | 386 | ucode->ucode_size = adev->gfx.rlc.save_restore_list_cntl_size_bytes; |
370 | memcpy(ucode->kaddr, adev->gfx.rlc.save_restore_list_cntl, | 387 | memcpy(ucode->kaddr, adev->gfx.rlc.save_restore_list_cntl, |