drm/amd/powerplay: retrieve all clock ranges on startup
authorEvan Quan <evan.quan@amd.com>
Mon, 11 Jun 2018 07:41:44 +0000 (15:41 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 5 Jul 2018 21:38:53 +0000 (16:38 -0500)
So that we do not need to use PPSMC_MSG_GetMin/MaxDpmFreq to
get the clock ranges on runtime. Since that causes some problems.

Signed-off-by: Evan Quan <evan.quan@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c
drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h

index bc976e1d22c50cc460825b82ee0065adbf59fd0f..d3e898306ced3a8fb710094fcbde123f3ebdb197 100644 (file)
@@ -856,6 +856,48 @@ static int vega12_power_control_set_level(struct pp_hwmgr *hwmgr)
        return result;
 }
 
+static int vega12_get_all_clock_ranges_helper(struct pp_hwmgr *hwmgr,
+               PPCLK_e clkid, struct vega12_clock_range *clock)
+{
+       /* AC Max */
+       PP_ASSERT_WITH_CODE(
+               smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetMaxDpmFreq, (clkid << 16)) == 0,
+               "[GetClockRanges] Failed to get max ac clock from SMC!",
+               return -EINVAL);
+       vega12_read_arg_from_smc(hwmgr, &(clock->ACMax));
+
+       /* AC Min */
+       PP_ASSERT_WITH_CODE(
+               smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetMinDpmFreq, (clkid << 16)) == 0,
+               "[GetClockRanges] Failed to get min ac clock from SMC!",
+               return -EINVAL);
+       vega12_read_arg_from_smc(hwmgr, &(clock->ACMin));
+
+       /* DC Max */
+       PP_ASSERT_WITH_CODE(
+               smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetDcModeMaxDpmFreq, (clkid << 16)) == 0,
+               "[GetClockRanges] Failed to get max dc clock from SMC!",
+               return -EINVAL);
+       vega12_read_arg_from_smc(hwmgr, &(clock->DCMax));
+
+       return 0;
+}
+
+static int vega12_get_all_clock_ranges(struct pp_hwmgr *hwmgr)
+{
+       struct vega12_hwmgr *data =
+                       (struct vega12_hwmgr *)(hwmgr->backend);
+       uint32_t i;
+
+       for (i = 0; i < PPCLK_COUNT; i++)
+               PP_ASSERT_WITH_CODE(!vega12_get_all_clock_ranges_helper(hwmgr,
+                                       i, &(data->clk_range[i])),
+                               "Failed to get clk range from SMC!",
+                               return -EINVAL);
+
+       return 0;
+}
+
 static int vega12_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
 {
        int tmp_result, result = 0;
@@ -883,6 +925,11 @@ static int vega12_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
                        "Failed to power control set level!",
                        result = tmp_result);
 
+       result = vega12_get_all_clock_ranges(hwmgr);
+       PP_ASSERT_WITH_CODE(!result,
+                       "Failed to get all clock ranges!",
+                       return result);
+
        result = vega12_odn_initialize_default_settings(hwmgr);
        PP_ASSERT_WITH_CODE(!result,
                        "Failed to power control set level!",
@@ -1472,24 +1519,14 @@ static int vega12_get_clock_ranges(struct pp_hwmgr *hwmgr,
                PPCLK_e clock_select,
                bool max)
 {
-       int result;
-       *clock = 0;
+       struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
 
-       if (max) {
-                PP_ASSERT_WITH_CODE(
-                       smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetMaxDpmFreq, (clock_select << 16)) == 0,
-                       "[GetClockRanges] Failed to get max clock from SMC!",
-                       return -1);
-               result = vega12_read_arg_from_smc(hwmgr, clock);
-       } else {
-               PP_ASSERT_WITH_CODE(
-                       smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetMinDpmFreq, (clock_select << 16)) == 0,
-                       "[GetClockRanges] Failed to get min clock from SMC!",
-                       return -1);
-               result = vega12_read_arg_from_smc(hwmgr, clock);
-       }
+       if (max)
+               *clock = data->clk_range[clock_select].ACMax;
+       else
+               *clock = data->clk_range[clock_select].ACMin;
 
-       return result;
+       return 0;
 }
 
 static int vega12_get_sclks(struct pp_hwmgr *hwmgr,
index 49b38df8c7f2702553b7aa49e27e77069d55adef..e18c083086028c647c5b8b86cc0e2c1a1c315c0a 100644 (file)
@@ -304,6 +304,12 @@ struct vega12_odn_fan_table {
        bool            force_fan_pwm;
 };
 
+struct vega12_clock_range {
+       uint32_t        ACMax;
+       uint32_t        ACMin;
+       uint32_t        DCMax;
+};
+
 struct vega12_hwmgr {
        struct vega12_dpm_table          dpm_table;
        struct vega12_dpm_table          golden_dpm_table;
@@ -385,6 +391,8 @@ struct vega12_hwmgr {
        uint32_t                       smu_version;
        struct smu_features            smu_features[GNLD_FEATURES_MAX];
        struct vega12_smc_state_table  smc_state_table;
+
+       struct vega12_clock_range      clk_range[PPCLK_COUNT];
 };
 
 #define VEGA12_DPM2_NEAR_TDP_DEC                      10