aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.14.71/5322-drm-amd-Add-ucode-DMCU-support.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/5322-drm-amd-Add-ucode-DMCU-support.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.14.71/5322-drm-amd-Add-ucode-DMCU-support.patch115
1 files changed, 115 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/5322-drm-amd-Add-ucode-DMCU-support.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/5322-drm-amd-Add-ucode-DMCU-support.patch
new file mode 100644
index 00000000..75f95a02
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/5322-drm-amd-Add-ucode-DMCU-support.patch
@@ -0,0 +1,115 @@
+From b2d472d71927342b9529a64fd8b92c8c8b0f67bd Mon Sep 17 00:00:00 2001
+From: David Francis <David.Francis@amd.com>
+Date: Tue, 11 Sep 2018 13:41:01 -0400
+Subject: [PATCH 5322/5725] 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>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | 21 +++++++++++++++++++--
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h | 10 ++++++++++
+ 2 files changed, 29 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
+index 8777dad..59fe359 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,
+ {
+ const struct common_firmware_header *header = NULL;
+ const struct gfx_firmware_header_v1_0 *cp_hdr = NULL;
++ const struct dmcu_firmware_header_v1_0 *dmcu_hdr = NULL;
+
+ if (NULL == ucode->fw)
+ return 0;
+@@ -333,8 +334,8 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev,
+ return 0;
+
+ header = (const struct common_firmware_header *)ucode->fw->data;
+-
+ cp_hdr = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data;
++ dmcu_hdr = (const struct dmcu_firmware_header_v1_0 *)ucode->fw->data;
+
+ if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP ||
+ (ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC1 &&
+@@ -343,7 +344,9 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev,
+ ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC2_JT &&
+ ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL &&
+ ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM &&
+- ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM)) {
++ ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM &&
++ ucode->ucode_id != AMDGPU_UCODE_ID_DMCU_ERAM &&
++ ucode->ucode_id != AMDGPU_UCODE_ID_DMCU_INTV)) {
+ ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes);
+
+ memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data +
+@@ -365,6 +368,20 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev,
+ le32_to_cpu(header->ucode_array_offset_bytes) +
+ le32_to_cpu(cp_hdr->jt_offset) * 4),
+ ucode->ucode_size);
++ } else if (ucode->ucode_id == AMDGPU_UCODE_ID_DMCU_ERAM) {
++ ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes) -
++ le32_to_cpu(dmcu_hdr->intv_size_bytes);
++
++ memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data +
++ le32_to_cpu(header->ucode_array_offset_bytes)),
++ ucode->ucode_size);
++ } else if (ucode->ucode_id == AMDGPU_UCODE_ID_DMCU_INTV) {
++ ucode->ucode_size = le32_to_cpu(dmcu_hdr->intv_size_bytes);
++
++ memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data +
++ le32_to_cpu(header->ucode_array_offset_bytes) +
++ le32_to_cpu(dmcu_hdr->intv_offset_bytes)),
++ ucode->ucode_size);
+ } else if (ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL) {
+ ucode->ucode_size = adev->gfx.rlc.save_restore_list_cntl_size_bytes;
+ memcpy(ucode->kaddr, adev->gfx.rlc.save_restore_list_cntl,
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h
+index b2f820c..15791af 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h
+@@ -157,6 +157,13 @@ struct gpu_info_firmware_header_v1_0 {
+ uint16_t version_minor; /* version */
+ };
+
++/* version_major=1, version_minor=0 */
++struct dmcu_firmware_header_v1_0 {
++ struct common_firmware_header header;
++ uint32_t intv_offset_bytes; /* interrupt vectors offset from end of header, in bytes */
++ uint32_t intv_size_bytes; /* size of interrupt vectors, in bytes */
++};
++
+ /* header is fixed size */
+ union amdgpu_firmware_header {
+ struct common_firmware_header common;
+@@ -170,6 +177,7 @@ union amdgpu_firmware_header {
+ struct sdma_firmware_header_v1_0 sdma;
+ struct sdma_firmware_header_v1_1 sdma_v1_1;
+ struct gpu_info_firmware_header_v1_0 gpu_info;
++ struct dmcu_firmware_header_v1_0 dmcu;
+ uint8_t raw[0x100];
+ };
+
+@@ -196,6 +204,8 @@ enum AMDGPU_UCODE_ID {
+ AMDGPU_UCODE_ID_UVD1,
+ AMDGPU_UCODE_ID_VCE,
+ AMDGPU_UCODE_ID_VCN,
++ AMDGPU_UCODE_ID_DMCU_ERAM,
++ AMDGPU_UCODE_ID_DMCU_INTV,
+ AMDGPU_UCODE_ID_MAXIMUM,
+ };
+
+--
+2.7.4
+