drm/amd/powerplay: implement get_clk_info_from_vbios function for smu11 (v2)
authorHuang Rui <ray.huang@amd.com>
Mon, 17 Dec 2018 06:56:40 +0000 (14:56 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 19 Mar 2019 20:03:56 +0000 (15:03 -0500)
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.huang@amd.com>
Reviewed-by: Kevin Wang <Kevin1.Wang@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
drivers/gpu/drm/amd/powerplay/smu_v11_0.c

index ef377ef0e3896d48dec481931567ba20355f211a..f31b6281325603df9e932d5904ae2c51fbb73690 100644 (file)
@@ -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;
index 6d0db61179db764caddc3cf68084e546d10ebe6e..57572ff4d49654a0a4a72c79d35a16ed4c499b6a 100644 (file)
@@ -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) \
index f036313153ae20d054cf6585f4bc5c5b955e0e92..adae5a70368e33bb74d4b85044be7091ae213094 100644 (file)
@@ -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)