summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/powerplay
diff options
context:
space:
mode:
authorEvan Quan <evan.quan@amd.com>2018-09-17 09:59:54 +0300
committerAlex Deucher <alexander.deucher@amd.com>2018-09-19 20:38:02 +0300
commit32f2a0d117769bdca7f7ee6224659f2c688ebc85 (patch)
treee8eaeffdd76b415db03428350474a361270cf052 /drivers/gpu/drm/amd/powerplay
parentb1f82cb21231ccfec3c15b628f8deed778cce22b (diff)
downloadlinux-32f2a0d117769bdca7f7ee6224659f2c688ebc85.tar.xz
drm/amd/powerplay: retrieve the updated clock table after OD
With OD settings applied, the clock table will be updated accordingly. We need to retrieve the new clock tables then. 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>
Diffstat (limited to 'drivers/gpu/drm/amd/powerplay')
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c114
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h2
2 files changed, 90 insertions, 26 deletions
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
index 4f9bf6049d1c..d45cbfe8e184 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
@@ -514,6 +514,47 @@ static int vega20_setup_single_dpm_table(struct pp_hwmgr *hwmgr,
return ret;
}
+static int vega20_setup_gfxclk_dpm_table(struct pp_hwmgr *hwmgr)
+{
+ struct vega20_hwmgr *data =
+ (struct vega20_hwmgr *)(hwmgr->backend);
+ struct vega20_single_dpm_table *dpm_table;
+ int ret = 0;
+
+ dpm_table = &(data->dpm_table.gfx_table);
+ if (data->smu_features[GNLD_DPM_GFXCLK].enabled) {
+ ret = vega20_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_GFXCLK);
+ PP_ASSERT_WITH_CODE(!ret,
+ "[SetupDefaultDpmTable] failed to get gfxclk dpm levels!",
+ return ret);
+ } else {
+ dpm_table->count = 1;
+ dpm_table->dpm_levels[0].value = data->vbios_boot_state.gfx_clock / 100;
+ }
+
+ return ret;
+}
+
+static int vega20_setup_memclk_dpm_table(struct pp_hwmgr *hwmgr)
+{
+ struct vega20_hwmgr *data =
+ (struct vega20_hwmgr *)(hwmgr->backend);
+ struct vega20_single_dpm_table *dpm_table;
+ int ret = 0;
+
+ dpm_table = &(data->dpm_table.mem_table);
+ if (data->smu_features[GNLD_DPM_UCLK].enabled) {
+ ret = vega20_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_UCLK);
+ PP_ASSERT_WITH_CODE(!ret,
+ "[SetupDefaultDpmTable] failed to get memclk dpm levels!",
+ return ret);
+ } else {
+ dpm_table->count = 1;
+ dpm_table->dpm_levels[0].value = data->vbios_boot_state.mem_clock / 100;
+ }
+
+ return ret;
+}
/*
* This function is to initialize all DPM state tables
@@ -547,28 +588,16 @@ static int vega20_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
/* gfxclk */
dpm_table = &(data->dpm_table.gfx_table);
- if (data->smu_features[GNLD_DPM_GFXCLK].enabled) {
- ret = vega20_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_GFXCLK);
- PP_ASSERT_WITH_CODE(!ret,
- "[SetupDefaultDpmTable] failed to get gfxclk dpm levels!",
- return ret);
- } else {
- dpm_table->count = 1;
- dpm_table->dpm_levels[0].value = data->vbios_boot_state.gfx_clock / 100;
- }
+ ret = vega20_setup_gfxclk_dpm_table(hwmgr);
+ if (ret)
+ return ret;
vega20_init_dpm_state(&(dpm_table->dpm_state));
/* memclk */
dpm_table = &(data->dpm_table.mem_table);
- if (data->smu_features[GNLD_DPM_UCLK].enabled) {
- ret = vega20_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_UCLK);
- PP_ASSERT_WITH_CODE(!ret,
- "[SetupDefaultDpmTable] failed to get memclk dpm levels!",
- return ret);
- } else {
- dpm_table->count = 1;
- dpm_table->dpm_levels[0].value = data->vbios_boot_state.mem_clock / 100;
- }
+ ret = vega20_setup_memclk_dpm_table(hwmgr);
+ if (ret)
+ return ret;
vega20_init_dpm_state(&(dpm_table->dpm_state));
/* eclk */
@@ -1181,6 +1210,9 @@ static int vega20_od8_set_settings(
{
OverDriveTable_t od_table;
int ret = 0;
+ struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend);
+ struct vega20_od8_single_setting *od8_settings =
+ data->od8_settings.od8_settings_array;
ret = vega20_copy_table_from_smc(hwmgr, (uint8_t *)(&od_table), TABLE_OVERDRIVE);
PP_ASSERT_WITH_CODE(!ret,
@@ -1192,6 +1224,10 @@ static int vega20_od8_set_settings(
od_table.GfxclkFmin = (uint16_t)value;
break;
case OD8_SETTING_GFXCLK_FMAX:
+ if (value < od8_settings[OD8_SETTING_GFXCLK_FMAX].min_value ||
+ value > od8_settings[OD8_SETTING_GFXCLK_FMAX].max_value)
+ return -EINVAL;
+
od_table.GfxclkFmax = (uint16_t)value;
break;
case OD8_SETTING_GFXCLK_FREQ1:
@@ -1213,6 +1249,9 @@ static int vega20_od8_set_settings(
od_table.GfxclkVolt3 = (uint16_t)value;
break;
case OD8_SETTING_UCLK_FMAX:
+ if (value < od8_settings[OD8_SETTING_UCLK_FMAX].min_value ||
+ value > od8_settings[OD8_SETTING_UCLK_FMAX].max_value)
+ return -EINVAL;
od_table.UclkFmax = (uint16_t)value;
break;
case OD8_SETTING_POWER_PERCENTAGE:
@@ -1262,8 +1301,6 @@ 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;
@@ -1278,8 +1315,8 @@ static int vega20_set_sclk_od(
"[SetSclkOD] failed to set od gfxclk!",
return ret);
- /* refresh gfxclk table */
- ret = vega20_setup_single_dpm_table(hwmgr, sclk_table, PPCLK_GFXCLK);
+ /* retrieve updated gfxclk table */
+ ret = vega20_setup_gfxclk_dpm_table(hwmgr);
PP_ASSERT_WITH_CODE(!ret,
"[SetSclkOD] failed to refresh gfxclk table!",
return ret);
@@ -1309,8 +1346,6 @@ 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;
@@ -1325,8 +1360,8 @@ static int vega20_set_mclk_od(
"[SetMclkOD] failed to set od memclk!",
return ret);
- /* refresh memclk table */
- ret = vega20_setup_single_dpm_table(hwmgr, mclk_table, PPCLK_UCLK);
+ /* retrieve updated memclk table */
+ ret = vega20_setup_memclk_dpm_table(hwmgr);
PP_ASSERT_WITH_CODE(!ret,
"[SetMclkOD] failed to refresh memclk table!",
return ret);
@@ -2451,6 +2486,10 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
return -EINVAL;
}
+ if ((input_index == 0 && od_table->GfxclkFmin != input_clk) ||
+ (input_index == 1 && od_table->GfxclkFmax != input_clk))
+ data->gfxclk_overdrive = true;
+
if (input_index == 0)
od_table->GfxclkFmin = input_clk;
else
@@ -2495,6 +2534,9 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
return -EINVAL;
}
+ if (input_index == 1 && od_table->UclkFmax != input_clk)
+ data->memclk_overdrive = true;
+
od_table->UclkFmax = input_clk;
}
@@ -2567,6 +2609,9 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
break;
case PP_OD_RESTORE_DEFAULT_TABLE:
+ data->gfxclk_overdrive = false;
+ data->memclk_overdrive = false;
+
ret = vega20_copy_table_from_smc(hwmgr,
(uint8_t *)od_table,
TABLE_OVERDRIVE);
@@ -2583,6 +2628,23 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
"Failed to import overdrive table!",
return ret);
+ /* retrieve updated gfxclk table */
+ if (data->gfxclk_overdrive) {
+ data->gfxclk_overdrive = false;
+
+ ret = vega20_setup_gfxclk_dpm_table(hwmgr);
+ if (ret)
+ return ret;
+ }
+
+ /* retrieve updated memclk table */
+ if (data->memclk_overdrive) {
+ data->memclk_overdrive = false;
+
+ ret = vega20_setup_memclk_dpm_table(hwmgr);
+ if (ret)
+ return ret;
+ }
break;
default:
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h
index b71a5f25c734..56fe6a0d42e8 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h
@@ -502,6 +502,8 @@ struct vega20_hwmgr {
/* ---- Overdrive next setting ---- */
struct vega20_odn_data odn_data;
+ bool gfxclk_overdrive;
+ bool memclk_overdrive;
/* ---- Overdrive8 Setting ---- */
struct vega20_od8_settings od8_settings;