Commit 32f2a0d1 authored by Evan Quan's avatar Evan Quan Committed by Alex Deucher

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: default avatarEvan Quan <evan.quan@amd.com>
Acked-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent b1f82cb2
...@@ -514,6 +514,47 @@ static int vega20_setup_single_dpm_table(struct pp_hwmgr *hwmgr, ...@@ -514,6 +514,47 @@ static int vega20_setup_single_dpm_table(struct pp_hwmgr *hwmgr,
return ret; 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 * This function is to initialize all DPM state tables
...@@ -547,28 +588,16 @@ static int vega20_setup_default_dpm_tables(struct pp_hwmgr *hwmgr) ...@@ -547,28 +588,16 @@ static int vega20_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
/* gfxclk */ /* gfxclk */
dpm_table = &(data->dpm_table.gfx_table); dpm_table = &(data->dpm_table.gfx_table);
if (data->smu_features[GNLD_DPM_GFXCLK].enabled) { ret = vega20_setup_gfxclk_dpm_table(hwmgr);
ret = vega20_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_GFXCLK); if (ret)
PP_ASSERT_WITH_CODE(!ret, return 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;
}
vega20_init_dpm_state(&(dpm_table->dpm_state)); vega20_init_dpm_state(&(dpm_table->dpm_state));
/* memclk */ /* memclk */
dpm_table = &(data->dpm_table.mem_table); dpm_table = &(data->dpm_table.mem_table);
if (data->smu_features[GNLD_DPM_UCLK].enabled) { ret = vega20_setup_memclk_dpm_table(hwmgr);
ret = vega20_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_UCLK); if (ret)
PP_ASSERT_WITH_CODE(!ret, return 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;
}
vega20_init_dpm_state(&(dpm_table->dpm_state)); vega20_init_dpm_state(&(dpm_table->dpm_state));
/* eclk */ /* eclk */
...@@ -1181,6 +1210,9 @@ static int vega20_od8_set_settings( ...@@ -1181,6 +1210,9 @@ static int vega20_od8_set_settings(
{ {
OverDriveTable_t od_table; OverDriveTable_t od_table;
int ret = 0; 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); ret = vega20_copy_table_from_smc(hwmgr, (uint8_t *)(&od_table), TABLE_OVERDRIVE);
PP_ASSERT_WITH_CODE(!ret, PP_ASSERT_WITH_CODE(!ret,
...@@ -1192,6 +1224,10 @@ static int vega20_od8_set_settings( ...@@ -1192,6 +1224,10 @@ static int vega20_od8_set_settings(
od_table.GfxclkFmin = (uint16_t)value; od_table.GfxclkFmin = (uint16_t)value;
break; break;
case OD8_SETTING_GFXCLK_FMAX: 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; od_table.GfxclkFmax = (uint16_t)value;
break; break;
case OD8_SETTING_GFXCLK_FREQ1: case OD8_SETTING_GFXCLK_FREQ1:
...@@ -1213,6 +1249,9 @@ static int vega20_od8_set_settings( ...@@ -1213,6 +1249,9 @@ static int vega20_od8_set_settings(
od_table.GfxclkVolt3 = (uint16_t)value; od_table.GfxclkVolt3 = (uint16_t)value;
break; break;
case OD8_SETTING_UCLK_FMAX: 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; od_table.UclkFmax = (uint16_t)value;
break; break;
case OD8_SETTING_POWER_PERCENTAGE: case OD8_SETTING_POWER_PERCENTAGE:
...@@ -1262,8 +1301,6 @@ static int vega20_set_sclk_od( ...@@ -1262,8 +1301,6 @@ static int vega20_set_sclk_od(
struct pp_hwmgr *hwmgr, uint32_t value) struct pp_hwmgr *hwmgr, uint32_t value)
{ {
struct vega20_hwmgr *data = hwmgr->backend; 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 = struct vega20_single_dpm_table *golden_sclk_table =
&(data->golden_dpm_table.gfx_table); &(data->golden_dpm_table.gfx_table);
uint32_t od_sclk; uint32_t od_sclk;
...@@ -1278,8 +1315,8 @@ static int vega20_set_sclk_od( ...@@ -1278,8 +1315,8 @@ static int vega20_set_sclk_od(
"[SetSclkOD] failed to set od gfxclk!", "[SetSclkOD] failed to set od gfxclk!",
return ret); return ret);
/* refresh gfxclk table */ /* retrieve updated gfxclk table */
ret = vega20_setup_single_dpm_table(hwmgr, sclk_table, PPCLK_GFXCLK); ret = vega20_setup_gfxclk_dpm_table(hwmgr);
PP_ASSERT_WITH_CODE(!ret, PP_ASSERT_WITH_CODE(!ret,
"[SetSclkOD] failed to refresh gfxclk table!", "[SetSclkOD] failed to refresh gfxclk table!",
return ret); return ret);
...@@ -1309,8 +1346,6 @@ static int vega20_set_mclk_od( ...@@ -1309,8 +1346,6 @@ static int vega20_set_mclk_od(
struct pp_hwmgr *hwmgr, uint32_t value) struct pp_hwmgr *hwmgr, uint32_t value)
{ {
struct vega20_hwmgr *data = hwmgr->backend; 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 = struct vega20_single_dpm_table *golden_mclk_table =
&(data->golden_dpm_table.mem_table); &(data->golden_dpm_table.mem_table);
uint32_t od_mclk; uint32_t od_mclk;
...@@ -1325,8 +1360,8 @@ static int vega20_set_mclk_od( ...@@ -1325,8 +1360,8 @@ static int vega20_set_mclk_od(
"[SetMclkOD] failed to set od memclk!", "[SetMclkOD] failed to set od memclk!",
return ret); return ret);
/* refresh memclk table */ /* retrieve updated memclk table */
ret = vega20_setup_single_dpm_table(hwmgr, mclk_table, PPCLK_UCLK); ret = vega20_setup_memclk_dpm_table(hwmgr);
PP_ASSERT_WITH_CODE(!ret, PP_ASSERT_WITH_CODE(!ret,
"[SetMclkOD] failed to refresh memclk table!", "[SetMclkOD] failed to refresh memclk table!",
return ret); return ret);
...@@ -2451,6 +2486,10 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr, ...@@ -2451,6 +2486,10 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
return -EINVAL; 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) if (input_index == 0)
od_table->GfxclkFmin = input_clk; od_table->GfxclkFmin = input_clk;
else else
...@@ -2495,6 +2534,9 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr, ...@@ -2495,6 +2534,9 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
return -EINVAL; return -EINVAL;
} }
if (input_index == 1 && od_table->UclkFmax != input_clk)
data->memclk_overdrive = true;
od_table->UclkFmax = input_clk; od_table->UclkFmax = input_clk;
} }
...@@ -2567,6 +2609,9 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr, ...@@ -2567,6 +2609,9 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
break; break;
case PP_OD_RESTORE_DEFAULT_TABLE: case PP_OD_RESTORE_DEFAULT_TABLE:
data->gfxclk_overdrive = false;
data->memclk_overdrive = false;
ret = vega20_copy_table_from_smc(hwmgr, ret = vega20_copy_table_from_smc(hwmgr,
(uint8_t *)od_table, (uint8_t *)od_table,
TABLE_OVERDRIVE); TABLE_OVERDRIVE);
...@@ -2583,6 +2628,23 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr, ...@@ -2583,6 +2628,23 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
"Failed to import overdrive table!", "Failed to import overdrive table!",
return ret); 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; break;
default: default:
......
...@@ -502,6 +502,8 @@ struct vega20_hwmgr { ...@@ -502,6 +502,8 @@ struct vega20_hwmgr {
/* ---- Overdrive next setting ---- */ /* ---- Overdrive next setting ---- */
struct vega20_odn_data odn_data; struct vega20_odn_data odn_data;
bool gfxclk_overdrive;
bool memclk_overdrive;
/* ---- Overdrive8 Setting ---- */ /* ---- Overdrive8 Setting ---- */
struct vega20_od8_settings od8_settings; struct vega20_od8_settings od8_settings;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment