This patch implements the get_clk_info_from_vbios function for smu11. We can do execute_vbios_cmd_table to fetch the clk value from vbios.
v2: use the proper cpu_to_le[32|16]() and le[32|16]_to_cpu() macros to handle endianness. (Alex) Signed-off-by: Huang Rui <ray.hu...@amd.com> Reviewed-by: Kevin Wang <kevin1.w...@amd.com> --- drivers/gpu/drm/amd/powerplay/amdgpu_smu.c | 8 ++++++ drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h | 3 ++ drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 39 ++++++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c index ef377ef..f31b628 100644 --- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c @@ -248,10 +248,18 @@ static int smu_smc_table_hw_init(struct smu_context *smu) if (ret) return ret; + ret = smu_get_clk_info_from_vbios(smu); + if (ret) + return ret; + /* * check if the format_revision in vbios is up to pptable header * version, and the structure size is not 0. */ + ret = smu_get_clk_info_from_vbios(smu); + if (ret) + return ret; + ret = smu_check_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 6d0db61..57572ff4d 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h @@ -98,6 +98,7 @@ struct smu_funcs int (*check_fw_status)(struct smu_context *smu); int (*read_pptable_from_vbios)(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); int (*parse_pptable)(struct smu_context *smu); int (*populate_smc_pptable)(struct smu_context *smu); @@ -132,6 +133,8 @@ struct smu_funcs ((smu)->funcs->read_pptable_from_vbios ? (smu)->funcs->read_pptable_from_vbios((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) \ + ((smu)->funcs->get_clk_info_from_vbios ? (smu)->funcs->get_clk_info_from_vbios((smu)) : 0) #define smu_check_pptable(smu) \ ((smu)->funcs->check_pptable ? (smu)->funcs->check_pptable((smu)) : 0) #define smu_parse_pptable(smu) \ diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c index f036313..adae5a7 100644 --- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c +++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c @@ -30,6 +30,7 @@ #include "smu_v11_0_ppsmc.h" #include "smu11_driver_if.h" #include "soc15_common.h" +#include "atom.h" #include "asic_reg/thm/thm_11_0_2_offset.h" #include "asic_reg/thm/thm_11_0_2_sh_mask.h" @@ -401,6 +402,43 @@ int smu_v11_0_get_vbios_bootup_values(struct smu_context *smu) return 0; } +static int smu_v11_0_get_clk_info_from_vbios(struct smu_context *smu) +{ + int ret, index; + struct amdgpu_device *adev = smu->adev; + struct atom_get_smu_clock_info_parameters_v3_1 input = {0}; + struct atom_get_smu_clock_info_output_parameters_v3_1 *output; + + input.clk_id = SMU11_SYSPLL0_SOCCLK_ID; + input.command = GET_SMU_CLOCK_INFO_V3_1_GET_CLOCK_FREQ; + index = get_index_into_master_table(atom_master_list_of_command_functions_v2_1, + getsmuclockinfo); + + ret = amdgpu_atom_execute_table(adev->mode_info.atom_context, index, + (uint32_t *)&input); + if (ret) + return -EINVAL; + + output = (struct atom_get_smu_clock_info_output_parameters_v3_1 *)&input; + smu->smu_table.boot_values.socclk = le32_to_cpu(output->atom_smu_outputclkfreq.smu_clock_freq_hz) / 10000; + + memset(&input, 0, sizeof(input)); + input.clk_id = SMU11_SYSPLL0_DCEFCLK_ID; + input.command = GET_SMU_CLOCK_INFO_V3_1_GET_CLOCK_FREQ; + index = get_index_into_master_table(atom_master_list_of_command_functions_v2_1, + getsmuclockinfo); + + ret = amdgpu_atom_execute_table(adev->mode_info.atom_context, index, + (uint32_t *)&input); + if (ret) + return -EINVAL; + + output = (struct atom_get_smu_clock_info_output_parameters_v3_1 *)&input; + smu->smu_table.boot_values.dcefclk = le32_to_cpu(output->atom_smu_outputclkfreq.smu_clock_freq_hz) / 10000; + + return 0; +} + static const struct smu_funcs smu_v11_0_funcs = { .init_microcode = smu_v11_0_init_microcode, .load_microcode = smu_v11_0_load_microcode, @@ -414,6 +452,7 @@ static const struct smu_funcs smu_v11_0_funcs = { .init_power = smu_v11_0_init_power, .fini_power = smu_v11_0_fini_power, .get_vbios_bootup_values = smu_v11_0_get_vbios_bootup_values, + .get_clk_info_from_vbios = smu_v11_0_get_clk_info_from_vbios, }; void smu_v11_0_set_smu_funcs(struct smu_context *smu) -- 2.7.4 _______________________________________________ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx