drm/amd/powerplay: enable df cstate control on swSMU routine
authorEvan Quan <evan.quan@amd.com>
Thu, 10 Oct 2019 03:40:37 +0000 (11:40 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 15 Oct 2019 19:48:29 +0000 (15:48 -0400)
Currently this is only supported on Vega20 with 40.50 and later
SMC firmware.

Signed-off-by: Evan Quan <evan.quan@amd.com>
Reviewed-by: Kenneth Feng <kenneth.feng@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/inc/smu_types.h
drivers/gpu/drm/amd/powerplay/vega20_ppt.c

index c9266ea..8bb5287 100644 (file)
@@ -1834,6 +1834,29 @@ int smu_set_mp1_state(struct smu_context *smu,
        return ret;
 }
 
+int smu_set_df_cstate(struct smu_context *smu,
+                     enum pp_df_cstate state)
+{
+       int ret = 0;
+
+       /*
+        * The SMC is not fully ready. That may be
+        * expected as the IP may be masked.
+        * So, just return without error.
+        */
+       if (!smu->pm_enabled)
+               return 0;
+
+       if (!smu->ppt_funcs || !smu->ppt_funcs->set_df_cstate)
+               return 0;
+
+       ret = smu->ppt_funcs->set_df_cstate(smu, state);
+       if (ret)
+               pr_err("[SetDfCstate] failed!\n");
+
+       return ret;
+}
+
 const struct amd_ip_funcs smu_ip_funcs = {
        .name = "smu",
        .early_init = smu_early_init,
index ccf711c..401affd 100644 (file)
@@ -468,6 +468,7 @@ struct pptable_funcs {
        int (*get_power_limit)(struct smu_context *smu, uint32_t *limit, bool asic_default);
        int (*get_dpm_clk_limited)(struct smu_context *smu, enum smu_clk_type clk_type,
                                   uint32_t dpm_level, uint32_t *freq);
+       int (*set_df_cstate)(struct smu_context *smu, enum pp_df_cstate state);
 };
 
 struct smu_funcs
@@ -852,5 +853,7 @@ int smu_force_clk_levels(struct smu_context *smu,
                         uint32_t mask);
 int smu_set_mp1_state(struct smu_context *smu,
                      enum pp_mp1_state mp1_state);
+int smu_set_df_cstate(struct smu_context *smu,
+                     enum pp_df_cstate state);
 
 #endif
index 12a1de5..d8c9b7f 100644 (file)
        __SMU_DUMMY_MAP(PowerGateAtHub),              \
        __SMU_DUMMY_MAP(SetSoftMinJpeg),              \
        __SMU_DUMMY_MAP(SetHardMinFclkByFreq),        \
+       __SMU_DUMMY_MAP(DFCstateControl), \
 
 #undef __SMU_DUMMY_MAP
 #define __SMU_DUMMY_MAP(type)  SMU_MSG_##type
index f655ebd..3fc6ad0 100644 (file)
@@ -143,6 +143,7 @@ static struct smu_11_0_cmn2aisc_mapping vega20_message_map[SMU_MSG_MAX_COUNT] =
        MSG_MAP(PrepareMp1ForShutdown),
        MSG_MAP(SetMGpuFanBoostLimitRpm),
        MSG_MAP(GetAVFSVoltageByDpm),
+       MSG_MAP(DFCstateControl),
 };
 
 static struct smu_11_0_cmn2aisc_mapping vega20_clk_map[SMU_CLK_COUNT] = {
@@ -3135,6 +3136,27 @@ static int vega20_get_thermal_temperature_range(struct smu_context *smu,
        return 0;
 }
 
+static int vega20_set_df_cstate(struct smu_context *smu,
+                               enum pp_df_cstate state)
+{
+       uint32_t smu_version;
+       int ret;
+
+       ret = smu_get_smc_version(smu, NULL, &smu_version);
+       if (ret) {
+               pr_err("Failed to get smu version!\n");
+               return ret;
+       }
+
+       /* PPSMC_MSG_DFCstateControl is supported with 40.50 and later fws */
+       if (smu_version < 0x283200) {
+               pr_err("Df cstate control is supported with 40.50 and later SMC fw!\n");
+               return -EINVAL;
+       }
+
+       return smu_send_smc_msg_with_param(smu, SMU_MSG_DFCstateControl, state);
+}
+
 static const struct pptable_funcs vega20_ppt_funcs = {
        .tables_init = vega20_tables_init,
        .alloc_dpm_context = vega20_allocate_dpm_context,
@@ -3177,7 +3199,8 @@ static const struct pptable_funcs vega20_ppt_funcs = {
        .get_fan_speed_percent = vega20_get_fan_speed_percent,
        .get_fan_speed_rpm = vega20_get_fan_speed_rpm,
        .set_watermarks_table = vega20_set_watermarks_table,
-       .get_thermal_temperature_range = vega20_get_thermal_temperature_range
+       .get_thermal_temperature_range = vega20_get_thermal_temperature_range,
+       .set_df_cstate = vega20_set_df_cstate,
 };
 
 void vega20_set_ppt_funcs(struct smu_context *smu)