aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.19.8/0081-drm-amd-powerplay-new-interfaces-for-overdrive-vega2.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/0081-drm-amd-powerplay-new-interfaces-for-overdrive-vega2.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.19.8/0081-drm-amd-powerplay-new-interfaces-for-overdrive-vega2.patch207
1 files changed, 207 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/0081-drm-amd-powerplay-new-interfaces-for-overdrive-vega2.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/0081-drm-amd-powerplay-new-interfaces-for-overdrive-vega2.patch
new file mode 100644
index 00000000..a5801f24
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/0081-drm-amd-powerplay-new-interfaces-for-overdrive-vega2.patch
@@ -0,0 +1,207 @@
+From 75137d8655bc0000729db855aaa2af782ba2e3f5 Mon Sep 17 00:00:00 2001
+From: Evan Quan <evan.quan@amd.com>
+Date: Mon, 21 May 2018 10:19:06 +0800
+Subject: [PATCH 0081/2940] drm/amd/powerplay: new interfaces for overdrive
+ vega20 sclk and mclk
+
+Add support for the new SMU firmware interface for clock adjustment.
+
+Signed-off-by: Evan Quan <evan.quan@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ .../drm/amd/powerplay/hwmgr/vega20_hwmgr.c | 169 ++++++++++++++++++
+ 1 file changed, 169 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
+index 51bc05dea8e1..1e9426fb1bf9 100644
+--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
+@@ -1101,6 +1101,166 @@ static int vega20_od8_initialize_default_settings(
+ return 0;
+ }
+
++static int vega20_od8_set_settings(
++ struct pp_hwmgr *hwmgr,
++ uint32_t index,
++ uint32_t value)
++{
++ OverDriveTable_t od_table;
++ int ret = 0;
++
++ ret = vega20_copy_table_from_smc(hwmgr, (uint8_t *)(&od_table), TABLE_OVERDRIVE);
++ PP_ASSERT_WITH_CODE(!ret,
++ "Failed to export over drive table!",
++ return ret);
++
++ switch(index) {
++ case OD8_SETTING_GFXCLK_FMIN:
++ od_table.GfxclkFmin = (uint16_t)value;
++ break;
++ case OD8_SETTING_GFXCLK_FMAX:
++ od_table.GfxclkFmax = (uint16_t)value;
++ break;
++ case OD8_SETTING_GFXCLK_FREQ1:
++ od_table.GfxclkFreq1 = (uint16_t)value;
++ break;
++ case OD8_SETTING_GFXCLK_VOLTAGE1:
++ od_table.GfxclkOffsetVolt1 = (uint16_t)value;
++ break;
++ case OD8_SETTING_GFXCLK_FREQ2:
++ od_table.GfxclkFreq2 = (uint16_t)value;
++ break;
++ case OD8_SETTING_GFXCLK_VOLTAGE2:
++ od_table.GfxclkOffsetVolt2 = (uint16_t)value;
++ break;
++ case OD8_SETTING_GFXCLK_FREQ3:
++ od_table.GfxclkFreq3 = (uint16_t)value;
++ break;
++ case OD8_SETTING_GFXCLK_VOLTAGE3:
++ od_table.GfxclkOffsetVolt3 = (uint16_t)value;
++ break;
++ case OD8_SETTING_UCLK_FMAX:
++ od_table.UclkFmax = (uint16_t)value;
++ break;
++ case OD8_SETTING_POWER_PERCENTAGE:
++ od_table.OverDrivePct = (int16_t)value;
++ break;
++ case OD8_SETTING_FAN_ACOUSTIC_LIMIT:
++ od_table.FanMaximumRpm = (uint16_t)value;
++ break;
++ case OD8_SETTING_FAN_MIN_SPEED:
++ od_table.FanMinimumPwm = (uint16_t)value;
++ break;
++ case OD8_SETTING_FAN_TARGET_TEMP:
++ od_table.FanTargetTemperature = (uint16_t)value;
++ break;
++ case OD8_SETTING_OPERATING_TEMP_MAX:
++ od_table.MaxOpTemp = (uint16_t)value;
++ break;
++ }
++
++ ret = vega20_copy_table_to_smc(hwmgr, (uint8_t *)(&od_table), TABLE_OVERDRIVE);
++ PP_ASSERT_WITH_CODE(!ret,
++ "Failed to import over drive table!",
++ return ret);
++
++ return 0;
++}
++
++static int vega20_get_sclk_od(
++ struct pp_hwmgr *hwmgr)
++{
++ struct vega20_hwmgr *data = hwmgr->backend;
++ struct vega20_single_dpm_table *sclk_table =
++ &(data->dpm_table.gfx_table);
++ struct vega20_single_dpm_table *golden_sclk_table =
++ &(data->golden_dpm_table.gfx_table);
++ int value;
++
++ /* od percentage */
++ value = DIV_ROUND_UP((sclk_table->dpm_levels[sclk_table->count - 1].value -
++ golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value) * 100,
++ golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value);
++
++ return value;
++}
++
++static int vega20_set_sclk_od(
++ struct pp_hwmgr *hwmgr, uint32_t value)
++{
++ struct vega20_hwmgr *data = hwmgr->backend;
++ struct vega20_single_dpm_table *sclk_table =
++ &(data->dpm_table.gfx_table);
++ struct vega20_single_dpm_table *golden_sclk_table =
++ &(data->golden_dpm_table.gfx_table);
++ uint32_t od_sclk;
++ int ret = 0;
++
++ od_sclk = golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value * value;
++ do_div(od_sclk, 100);
++ od_sclk += golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value;
++
++ ret = vega20_od8_set_settings(hwmgr, OD8_SETTING_GFXCLK_FMAX, od_sclk);
++ PP_ASSERT_WITH_CODE(!ret,
++ "[SetSclkOD] failed to set od gfxclk!",
++ return ret);
++
++ /* refresh gfxclk table */
++ ret = vega20_setup_single_dpm_table(hwmgr, sclk_table, PPCLK_GFXCLK);
++ PP_ASSERT_WITH_CODE(!ret,
++ "[SetSclkOD] failed to refresh gfxclk table!",
++ return ret);
++
++ return 0;
++}
++
++static int vega20_get_mclk_od(
++ struct pp_hwmgr *hwmgr)
++{
++ struct vega20_hwmgr *data = hwmgr->backend;
++ struct vega20_single_dpm_table *mclk_table =
++ &(data->dpm_table.mem_table);
++ struct vega20_single_dpm_table *golden_mclk_table =
++ &(data->golden_dpm_table.mem_table);
++ int value;
++
++ /* od percentage */
++ value = DIV_ROUND_UP((mclk_table->dpm_levels[mclk_table->count - 1].value -
++ golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value) * 100,
++ golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value);
++
++ return value;
++}
++
++static int vega20_set_mclk_od(
++ struct pp_hwmgr *hwmgr, uint32_t value)
++{
++ struct vega20_hwmgr *data = hwmgr->backend;
++ struct vega20_single_dpm_table *mclk_table =
++ &(data->dpm_table.mem_table);
++ struct vega20_single_dpm_table *golden_mclk_table =
++ &(data->golden_dpm_table.mem_table);
++ uint32_t od_mclk;
++ int ret = 0;
++
++ od_mclk = golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value * value;
++ do_div(od_mclk, 100);
++ od_mclk += golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value;
++
++ ret = vega20_od8_set_settings(hwmgr, OD8_SETTING_UCLK_FMAX, od_mclk);
++ PP_ASSERT_WITH_CODE(!ret,
++ "[SetMclkOD] failed to set od memclk!",
++ return ret);
++
++ /* refresh memclk table */
++ ret = vega20_setup_single_dpm_table(hwmgr, mclk_table, PPCLK_UCLK);
++ PP_ASSERT_WITH_CODE(!ret,
++ "[SetMclkOD] failed to refresh memclk table!",
++ return ret);
++
++ return 0;
++}
++
+ static int vega20_populate_umdpstate_clocks(
+ struct pp_hwmgr *hwmgr)
+ {
+@@ -2604,8 +2764,17 @@ static const struct pp_hwmgr_func vega20_hwmgr_funcs = {
+ vega20_get_power_profile_mode,
+ .set_power_profile_mode =
+ vega20_set_power_profile_mode,
++ /* od related */
+ .set_power_limit =
+ vega20_set_power_limit,
++ .get_sclk_od =
++ vega20_get_sclk_od,
++ .set_sclk_od =
++ vega20_set_sclk_od,
++ .get_mclk_od =
++ vega20_get_mclk_od,
++ .set_mclk_od =
++ vega20_set_mclk_od,
+ /* for sysfs to retrive/set gfxclk/memclk */
+ .force_clock_level =
+ vega20_force_clock_level,
+--
+2.17.1
+