diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/2278-drm-amd-powerplay-implement-smc-firmware-v2.1-for-sm.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.19.8/2278-drm-amd-powerplay-implement-smc-firmware-v2.1-for-sm.patch | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/2278-drm-amd-powerplay-implement-smc-firmware-v2.1-for-sm.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/2278-drm-amd-powerplay-implement-smc-firmware-v2.1-for-sm.patch new file mode 100644 index 00000000..0be6d535 --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/2278-drm-amd-powerplay-implement-smc-firmware-v2.1-for-sm.patch @@ -0,0 +1,226 @@ +From 8f6c8519a8c4e12c639d27bcfe92493c40124ac1 Mon Sep 17 00:00:00 2001 +From: Kevin Wang <kevin1.wang@amd.com> +Date: Mon, 11 Mar 2019 20:09:35 +0800 +Subject: [PATCH 2278/2940] drm/amd/powerplay: implement smc firmware v2.1 for + smu11 + +1.add smc_firmware_header_v2_1 hfirmware support, support more pptable in smc firmware. +2.optimization current pptable load framework. +3.rename read_pptable_from_vbios with setup_pptable. + +Signed-off-by: Kevin Wang <kevin1.wang@amd.com> +Reviewed-by: Huang Rui <ray.huang@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h | 13 +++ + drivers/gpu/drm/amd/powerplay/amdgpu_smu.c | 2 +- + .../gpu/drm/amd/powerplay/inc/amdgpu_smu.h | 6 +- + drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 94 ++++++++++++++----- + 4 files changed, 85 insertions(+), 30 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h +index 9b096228a02f..eaafea87aa3a 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h +@@ -56,6 +56,19 @@ struct smc_firmware_header_v2_0 { + uint32_t ppt_size_bytes; /* soft pptable size */ + }; + ++struct smc_soft_pptable_entry { ++ uint32_t id; ++ uint32_t ppt_offset_bytes; ++ uint32_t ppt_size_bytes; ++}; ++ ++/* version_major=2, version_minor=1 */ ++struct smc_firmware_header_v2_1 { ++ struct smc_firmware_header_v1_0 v1_0; ++ uint32_t pptable_count; ++ uint32_t pptable_entry_offset; ++}; ++ + /* version_major=1, version_minor=0 */ + struct psp_firmware_header_v1_0 { + struct common_firmware_header header; +diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c +index b9b56ec1aacf..2de67e16e5e3 100644 +--- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c ++++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c +@@ -633,7 +633,7 @@ static int smu_smc_table_hw_init(struct smu_context *smu, + if (ret) + return ret; + +- ret = smu_read_pptable_from_vbios(smu); ++ ret = smu_setup_pptable(smu); + if (ret) + return ret; + +diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +index 7b31054b3e5e..4ec643417b68 100644 +--- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h ++++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +@@ -486,7 +486,7 @@ struct smu_funcs + int (*fini_power)(struct smu_context *smu); + int (*load_microcode)(struct smu_context *smu); + int (*check_fw_status)(struct smu_context *smu); +- int (*read_pptable_from_vbios)(struct smu_context *smu); ++ int (*setup_pptable)(struct smu_context *smu); + int (*get_vbios_bootup_values)(struct smu_context *smu); + int (*get_clk_info_from_vbios)(struct smu_context *smu); + int (*check_pptable)(struct smu_context *smu); +@@ -570,8 +570,8 @@ struct smu_funcs + ((smu)->funcs->load_microcode ? (smu)->funcs->load_microcode((smu)) : 0) + #define smu_check_fw_status(smu) \ + ((smu)->funcs->check_fw_status ? (smu)->funcs->check_fw_status((smu)) : 0) +-#define smu_read_pptable_from_vbios(smu) \ +- ((smu)->funcs->read_pptable_from_vbios ? (smu)->funcs->read_pptable_from_vbios((smu)) : 0) ++#define smu_setup_pptable(smu) \ ++ ((smu)->funcs->setup_pptable ? (smu)->funcs->setup_pptable((smu)) : 0) + #define smu_get_vbios_bootup_values(smu) \ + ((smu)->funcs->get_vbios_bootup_values ? (smu)->funcs->get_vbios_bootup_values((smu)) : 0) + #define smu_get_clk_info_from_vbios(smu) \ +diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c +index 8f2272a420b6..a952d2a297f7 100644 +--- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c ++++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c +@@ -143,18 +143,6 @@ smu_v11_0_send_msg_with_param(struct smu_context *smu, uint16_t msg, + return ret; + } + +-static void smu_v11_0_init_smu_ext_microcode(struct smu_context *smu) +-{ +- struct amdgpu_device *adev = smu->adev; +- const struct smc_firmware_header_v2_0 *v2; +- +- v2 = (const struct smc_firmware_header_v2_0 *) adev->pm.fw->data; +- +- smu->ppt_offset_bytes = le32_to_cpu(v2->ppt_offset_bytes); +- smu->ppt_size_bytes = le32_to_cpu(v2->ppt_size_bytes); +- smu->ppt_start_addr = (uint8_t *)v2 + smu->ppt_offset_bytes; +-} +- + static int smu_v11_0_init_microcode(struct smu_context *smu) + { + struct amdgpu_device *adev = smu->adev; +@@ -164,7 +152,6 @@ static int smu_v11_0_init_microcode(struct smu_context *smu) + const struct smc_firmware_header_v1_0 *hdr; + const struct common_firmware_header *header; + struct amdgpu_firmware_info *ucode = NULL; +- uint32_t version_major, version_minor; + + switch (adev->asic_type) { + case CHIP_VEGA20: +@@ -190,11 +177,6 @@ static int smu_v11_0_init_microcode(struct smu_context *smu) + amdgpu_ucode_print_smc_hdr(&hdr->header); + adev->pm.fw_version = le32_to_cpu(hdr->header.ucode_version); + +- version_major = le16_to_cpu(hdr->header.header_version_major); +- version_minor = le16_to_cpu(hdr->header.header_version_minor); +- if (version_major == 2 && version_minor == 0) +- smu_v11_0_init_smu_ext_microcode(smu); /* with soft pptable */ +- + if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { + ucode = &adev->firmware.ucode[AMDGPU_UCODE_ID_SMC]; + ucode->ucode_id = AMDGPU_UCODE_ID_SMC; +@@ -293,22 +275,82 @@ static int smu_v11_0_check_fw_version(struct smu_context *smu) + return ret; + } + +-static int smu_v11_0_read_pptable_from_vbios(struct smu_context *smu) ++static int smu_v11_0_set_pptable_v2_0(struct smu_context *smu, void **table, uint32_t *size) ++{ ++ struct amdgpu_device *adev = smu->adev; ++ uint32_t ppt_offset_bytes; ++ const struct smc_firmware_header_v2_0 *v2; ++ ++ v2 = (const struct smc_firmware_header_v2_0 *) adev->pm.fw->data; ++ ++ ppt_offset_bytes = le32_to_cpu(v2->ppt_offset_bytes); ++ *size = le32_to_cpu(v2->ppt_size_bytes); ++ *table = (uint8_t *)v2 + ppt_offset_bytes; ++ ++ return 0; ++} ++ ++static int smu_v11_0_set_pptable_v2_1(struct smu_context *smu, void **table, uint32_t *size, uint32_t pptable_id) ++{ ++ struct amdgpu_device *adev = smu->adev; ++ const struct smc_firmware_header_v2_1 *v2_1; ++ struct smc_soft_pptable_entry *entries; ++ uint32_t pptable_count = 0; ++ int i = 0; ++ ++ v2_1 = (const struct smc_firmware_header_v2_1 *) adev->pm.fw->data; ++ entries = (struct smc_soft_pptable_entry *) ++ ((uint8_t *)v2_1 + le32_to_cpu(v2_1->pptable_entry_offset)); ++ pptable_count = le32_to_cpu(v2_1->pptable_count); ++ for (i = 0; i < pptable_count; i++) { ++ if (le32_to_cpu(entries[i].id) == pptable_id) { ++ *table = ((uint8_t *)v2_1 + le32_to_cpu(entries[i].ppt_offset_bytes)); ++ *size = le32_to_cpu(entries[i].ppt_size_bytes); ++ break; ++ } ++ } ++ ++ if (i == pptable_count) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++static int smu_v11_0_setup_pptable(struct smu_context *smu) + { ++ struct amdgpu_device *adev = smu->adev; ++ const struct smc_firmware_header_v1_0 *hdr; + int ret, index; +- uint16_t size; ++ uint32_t size; + uint8_t frev, crev; + void *table; ++ uint16_t version_major, version_minor; ++ ++ hdr = (const struct smc_firmware_header_v1_0 *) adev->pm.fw->data; ++ version_major = le16_to_cpu(hdr->header.header_version_major); ++ version_minor = le16_to_cpu(hdr->header.header_version_minor); ++ ++ if (version_major == 2 && smu->smu_table.boot_values.pp_table_id > 0) { ++ switch (version_minor) { ++ case 0: ++ ret = smu_v11_0_set_pptable_v2_0(smu, &table, &size); ++ break; ++ case 1: ++ ret = smu_v11_0_set_pptable_v2_1(smu, &table, &size, ++ smu->smu_table.boot_values.pp_table_id); ++ break; ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ if (ret) ++ return ret; + +- if (smu->smu_table.boot_values.pp_table_id > 0 && smu->ppt_start_addr) { +- /* load soft pptable */ +- table = (void *)smu->ppt_start_addr; +- size= smu->ppt_size_bytes; + } else { + index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, + powerplayinfo); + +- ret = smu_get_atom_data_table(smu, index, &size, &frev, &crev, ++ ret = smu_get_atom_data_table(smu, index, (uint16_t *)&size, &frev, &crev, + (uint8_t **)&table); + if (ret) + return ret; +@@ -1836,7 +1878,7 @@ static const struct smu_funcs smu_v11_0_funcs = { + .send_smc_msg = smu_v11_0_send_msg, + .send_smc_msg_with_param = smu_v11_0_send_msg_with_param, + .read_smc_arg = smu_v11_0_read_arg, +- .read_pptable_from_vbios = smu_v11_0_read_pptable_from_vbios, ++ .setup_pptable= smu_v11_0_setup_pptable, + .init_smc_tables = smu_v11_0_init_smc_tables, + .fini_smc_tables = smu_v11_0_fini_smc_tables, + .init_power = smu_v11_0_init_power, +-- +2.17.1 + |