mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-06 00:39:48 +00:00
drm/amd/pp: Change voltage/clk range for OD feature on VI
read vddc range from vbios. Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Rex Zhu <Rex.Zhu@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
ca6e0c5bdc
commit
d389d607e6
4 changed files with 73 additions and 20 deletions
|
@ -1505,3 +1505,31 @@ int atomctrl_get_leakage_vddc_base_on_leakage(struct pp_hwmgr *hwmgr,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void atomctrl_get_voltage_range(struct pp_hwmgr *hwmgr, uint32_t *max_vddc,
|
||||||
|
uint32_t *min_vddc)
|
||||||
|
{
|
||||||
|
void *profile;
|
||||||
|
|
||||||
|
profile = smu_atom_get_data_table(hwmgr->adev,
|
||||||
|
GetIndexIntoMasterTable(DATA, ASIC_ProfilingInfo),
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
|
||||||
|
if (profile) {
|
||||||
|
switch (hwmgr->chip_id) {
|
||||||
|
case CHIP_TONGA:
|
||||||
|
case CHIP_FIJI:
|
||||||
|
*max_vddc = le32_to_cpu(((ATOM_ASIC_PROFILING_INFO_V3_3 *)profile)->ulMaxVddc/4);
|
||||||
|
*min_vddc = le32_to_cpu(((ATOM_ASIC_PROFILING_INFO_V3_3 *)profile)->ulMinVddc/4);
|
||||||
|
break;
|
||||||
|
case CHIP_POLARIS11:
|
||||||
|
case CHIP_POLARIS10:
|
||||||
|
case CHIP_POLARIS12:
|
||||||
|
*max_vddc = le32_to_cpu(((ATOM_ASIC_PROFILING_INFO_V3_6 *)profile)->ulMaxVddc/100);
|
||||||
|
*min_vddc = le32_to_cpu(((ATOM_ASIC_PROFILING_INFO_V3_6 *)profile)->ulMinVddc/100);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -320,5 +320,8 @@ extern int atomctrl_get_leakage_vddc_base_on_leakage(struct pp_hwmgr *hwmgr,
|
||||||
uint16_t virtual_voltage_id,
|
uint16_t virtual_voltage_id,
|
||||||
uint16_t efuse_voltage_id);
|
uint16_t efuse_voltage_id);
|
||||||
extern int atomctrl_get_leakage_id_from_efuse(struct pp_hwmgr *hwmgr, uint16_t *virtual_voltage_id);
|
extern int atomctrl_get_leakage_id_from_efuse(struct pp_hwmgr *hwmgr, uint16_t *virtual_voltage_id);
|
||||||
|
|
||||||
|
extern void atomctrl_get_voltage_range(struct pp_hwmgr *hwmgr, uint32_t *max_vddc,
|
||||||
|
uint32_t *min_vddc);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -838,6 +838,33 @@ static int smu7_odn_initial_default_setting(struct pp_hwmgr *hwmgr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void smu7_setup_voltage_range_from_vbios(struct pp_hwmgr *hwmgr)
|
||||||
|
{
|
||||||
|
struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
|
||||||
|
struct phm_ppt_v1_clock_voltage_dependency_table *dep_sclk_table;
|
||||||
|
struct phm_ppt_v1_information *table_info =
|
||||||
|
(struct phm_ppt_v1_information *)(hwmgr->pptable);
|
||||||
|
uint32_t min_vddc, max_vddc;
|
||||||
|
|
||||||
|
if (!table_info)
|
||||||
|
return;
|
||||||
|
|
||||||
|
dep_sclk_table = table_info->vdd_dep_on_sclk;
|
||||||
|
|
||||||
|
atomctrl_get_voltage_range(hwmgr, &max_vddc, &min_vddc);
|
||||||
|
|
||||||
|
if (min_vddc == 0 || min_vddc > 2000
|
||||||
|
|| min_vddc > dep_sclk_table->entries[0].vddc)
|
||||||
|
min_vddc = dep_sclk_table->entries[0].vddc;
|
||||||
|
|
||||||
|
if (max_vddc == 0 || max_vddc > 2000
|
||||||
|
|| max_vddc < dep_sclk_table->entries[dep_sclk_table->count-1].vddc)
|
||||||
|
max_vddc = dep_sclk_table->entries[dep_sclk_table->count-1].vddc;
|
||||||
|
|
||||||
|
data->odn_dpm_table.min_vddc = min_vddc;
|
||||||
|
data->odn_dpm_table.max_vddc = max_vddc;
|
||||||
|
}
|
||||||
|
|
||||||
static int smu7_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
|
static int smu7_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
|
||||||
{
|
{
|
||||||
struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
|
struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
|
||||||
|
@ -856,8 +883,10 @@ static int smu7_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
|
||||||
sizeof(struct smu7_dpm_table));
|
sizeof(struct smu7_dpm_table));
|
||||||
|
|
||||||
/* initialize ODN table */
|
/* initialize ODN table */
|
||||||
if (hwmgr->od_enabled)
|
if (hwmgr->od_enabled) {
|
||||||
|
smu7_setup_voltage_range_from_vbios(hwmgr);
|
||||||
smu7_odn_initial_default_setting(hwmgr);
|
smu7_odn_initial_default_setting(hwmgr);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -4605,36 +4634,27 @@ static bool smu7_check_clk_voltage_valid(struct pp_hwmgr *hwmgr,
|
||||||
{
|
{
|
||||||
struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
|
struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
|
||||||
|
|
||||||
struct phm_ppt_v1_information *table_info =
|
if (voltage < data->odn_dpm_table.min_vddc || voltage > data->odn_dpm_table.max_vddc) {
|
||||||
(struct phm_ppt_v1_information *)(hwmgr->pptable);
|
pr_info("OD voltage is out of range [%d - %d] mV\n",
|
||||||
uint32_t min_vddc;
|
data->odn_dpm_table.min_vddc,
|
||||||
struct phm_ppt_v1_clock_voltage_dependency_table *dep_sclk_table;
|
data->odn_dpm_table.max_vddc);
|
||||||
|
|
||||||
if (table_info == NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
dep_sclk_table = table_info->vdd_dep_on_sclk;
|
|
||||||
min_vddc = dep_sclk_table->entries[0].vddc;
|
|
||||||
|
|
||||||
if (voltage < min_vddc || voltage > 2000) {
|
|
||||||
pr_info("OD voltage is out of range [%d - 2000] mV\n", min_vddc);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == PP_OD_EDIT_SCLK_VDDC_TABLE) {
|
if (type == PP_OD_EDIT_SCLK_VDDC_TABLE) {
|
||||||
if (data->vbios_boot_state.sclk_bootup_value > clk ||
|
if (data->golden_dpm_table.sclk_table.dpm_levels[0].value > clk ||
|
||||||
hwmgr->platform_descriptor.overdriveLimit.engineClock < clk) {
|
hwmgr->platform_descriptor.overdriveLimit.engineClock < clk) {
|
||||||
pr_info("OD engine clock is out of range [%d - %d] MHz\n",
|
pr_info("OD engine clock is out of range [%d - %d] MHz\n",
|
||||||
data->vbios_boot_state.sclk_bootup_value,
|
data->golden_dpm_table.sclk_table.dpm_levels[0].value/100,
|
||||||
hwmgr->platform_descriptor.overdriveLimit.engineClock / 100);
|
hwmgr->platform_descriptor.overdriveLimit.engineClock/100);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (type == PP_OD_EDIT_MCLK_VDDC_TABLE) {
|
} else if (type == PP_OD_EDIT_MCLK_VDDC_TABLE) {
|
||||||
if (data->vbios_boot_state.mclk_bootup_value > clk ||
|
if (data->golden_dpm_table.mclk_table.dpm_levels[0].value > clk ||
|
||||||
hwmgr->platform_descriptor.overdriveLimit.memoryClock < clk) {
|
hwmgr->platform_descriptor.overdriveLimit.memoryClock < clk) {
|
||||||
pr_info("OD memory clock is out of range [%d - %d] MHz\n",
|
pr_info("OD memory clock is out of range [%d - %d] MHz\n",
|
||||||
data->vbios_boot_state.mclk_bootup_value/100,
|
data->golden_dpm_table.mclk_table.dpm_levels[0].value/100,
|
||||||
hwmgr->platform_descriptor.overdriveLimit.memoryClock / 100);
|
hwmgr->platform_descriptor.overdriveLimit.memoryClock/100);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -184,6 +184,8 @@ struct smu7_odn_dpm_table {
|
||||||
struct smu7_odn_clock_voltage_dependency_table vdd_dependency_on_sclk;
|
struct smu7_odn_clock_voltage_dependency_table vdd_dependency_on_sclk;
|
||||||
struct smu7_odn_clock_voltage_dependency_table vdd_dependency_on_mclk;
|
struct smu7_odn_clock_voltage_dependency_table vdd_dependency_on_mclk;
|
||||||
uint32_t odn_mclk_min_limit;
|
uint32_t odn_mclk_min_limit;
|
||||||
|
uint32_t min_vddc;
|
||||||
|
uint32_t max_vddc;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct profile_mode_setting {
|
struct profile_mode_setting {
|
||||||
|
|
Loading…
Reference in a new issue