mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
b1f82cb212
commit
32f2a0d117
|
@ -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)
|
||||||
|
|
||||||
/* 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(
|
||||||
{
|
{
|
||||||
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(
|
||||||
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(
|
||||||
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(
|
||||||
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(
|
||||||
"[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(
|
||||||
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(
|
||||||
"[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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
"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 {
|
||||||
|
|
||||||
/* ---- 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;
|
||||||
|
|
Loading…
Reference in New Issue