Commit 0636e0d6 authored by Rex Zhu's avatar Rex Zhu Committed by Alex Deucher

drm/amd/powerplay: fix issue uvd dpm can't enabled on Polaris11.

1. Populate correct value of VDDCI voltage for SMC SAMU, VCE,
   and UVD levels depending on whether VDDCi control is SVI2 or GPIO.
2. Populate SMC ACPI minimum voltage using VBIOS boot SCLK and MCLK

When static voltage is configured as VDDCI, driver still tries to program
a voltage for MM minVoltage using VDDC-VDDCI delta requirement.
minVoltage should be set as boot up voltage.
Signed-off-by: default avatarRex Zhu <Rex.Zhu@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 3a8bd717
...@@ -1423,22 +1423,19 @@ static int polaris10_populate_smc_acpi_level(struct pp_hwmgr *hwmgr, ...@@ -1423,22 +1423,19 @@ static int polaris10_populate_smc_acpi_level(struct pp_hwmgr *hwmgr,
table->ACPILevel.Flags &= ~PPSMC_SWSTATE_FLAG_DC; table->ACPILevel.Flags &= ~PPSMC_SWSTATE_FLAG_DC;
if (!data->sclk_dpm_key_disabled) {
/* Get MinVoltage and Frequency from DPM0, /* Get MinVoltage and Frequency from DPM0,
* already converted to SMC_UL */ * already converted to SMC_UL */
sclk_frequency = data->dpm_table.sclk_table.dpm_levels[0].value; sclk_frequency = data->dpm_table.sclk_table.dpm_levels[0].value;
result = polaris10_get_dependency_volt_by_clk(hwmgr, result = polaris10_get_dependency_volt_by_clk(hwmgr,
table_info->vdd_dep_on_sclk, table_info->vdd_dep_on_sclk,
table->ACPILevel.SclkFrequency, sclk_frequency,
&table->ACPILevel.MinVoltage, &mvdd); &table->ACPILevel.MinVoltage, &mvdd);
PP_ASSERT_WITH_CODE((0 == result), PP_ASSERT_WITH_CODE((0 == result),
"Cannot find ACPI VDDC voltage value " "Cannot find ACPI VDDC voltage value "
"in Clock Dependency Table", ); "in Clock Dependency Table",
} else { );
sclk_frequency = data->vbios_boot_state.sclk_bootup_value;
table->ACPILevel.MinVoltage =
data->vbios_boot_state.vddc_bootup_value * VOLTAGE_SCALE;
}
result = polaris10_calculate_sclk_params(hwmgr, sclk_frequency, &(table->ACPILevel.SclkSetting)); result = polaris10_calculate_sclk_params(hwmgr, sclk_frequency, &(table->ACPILevel.SclkSetting));
PP_ASSERT_WITH_CODE(result == 0, "Error retrieving Engine Clock dividers from VBIOS.", return result); PP_ASSERT_WITH_CODE(result == 0, "Error retrieving Engine Clock dividers from VBIOS.", return result);
...@@ -1463,7 +1460,7 @@ static int polaris10_populate_smc_acpi_level(struct pp_hwmgr *hwmgr, ...@@ -1463,7 +1460,7 @@ static int polaris10_populate_smc_acpi_level(struct pp_hwmgr *hwmgr,
CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Fcw1_frac); CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Fcw1_frac);
CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Sclk_ss_slew_rate); CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Sclk_ss_slew_rate);
if (!data->mclk_dpm_key_disabled) {
/* Get MinVoltage and Frequency from DPM0, already converted to SMC_UL */ /* Get MinVoltage and Frequency from DPM0, already converted to SMC_UL */
table->MemoryACPILevel.MclkFrequency = table->MemoryACPILevel.MclkFrequency =
data->dpm_table.mclk_table.dpm_levels[0].value; data->dpm_table.mclk_table.dpm_levels[0].value;
...@@ -1475,12 +1472,6 @@ static int polaris10_populate_smc_acpi_level(struct pp_hwmgr *hwmgr, ...@@ -1475,12 +1472,6 @@ static int polaris10_populate_smc_acpi_level(struct pp_hwmgr *hwmgr,
"Cannot find ACPI VDDCI voltage value " "Cannot find ACPI VDDCI voltage value "
"in Clock Dependency Table", "in Clock Dependency Table",
); );
} else {
table->MemoryACPILevel.MclkFrequency =
data->vbios_boot_state.mclk_bootup_value;
table->MemoryACPILevel.MinVoltage =
data->vbios_boot_state.vddci_bootup_value * VOLTAGE_SCALE;
}
us_mvdd = 0; us_mvdd = 0;
if ((POLARIS10_VOLTAGE_CONTROL_NONE == data->mvdd_control) || if ((POLARIS10_VOLTAGE_CONTROL_NONE == data->mvdd_control) ||
...@@ -1525,6 +1516,7 @@ static int polaris10_populate_smc_vce_level(struct pp_hwmgr *hwmgr, ...@@ -1525,6 +1516,7 @@ static int polaris10_populate_smc_vce_level(struct pp_hwmgr *hwmgr,
struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table =
table_info->mm_dep_table; table_info->mm_dep_table;
struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend);
uint32_t vddci;
table->VceLevelCount = (uint8_t)(mm_table->count); table->VceLevelCount = (uint8_t)(mm_table->count);
table->VceBootLevel = 0; table->VceBootLevel = 0;
...@@ -1534,9 +1526,18 @@ static int polaris10_populate_smc_vce_level(struct pp_hwmgr *hwmgr, ...@@ -1534,9 +1526,18 @@ static int polaris10_populate_smc_vce_level(struct pp_hwmgr *hwmgr,
table->VceLevel[count].MinVoltage = 0; table->VceLevel[count].MinVoltage = 0;
table->VceLevel[count].MinVoltage |= table->VceLevel[count].MinVoltage |=
(mm_table->entries[count].vddc * VOLTAGE_SCALE) << VDDC_SHIFT; (mm_table->entries[count].vddc * VOLTAGE_SCALE) << VDDC_SHIFT;
if (POLARIS10_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control)
vddci = (uint32_t)phm_find_closest_vddci(&(data->vddci_voltage_table),
mm_table->entries[count].vddc - VDDC_VDDCI_DELTA);
else if (POLARIS10_VOLTAGE_CONTROL_BY_SVID2 == data->vddci_control)
vddci = mm_table->entries[count].vddc - VDDC_VDDCI_DELTA;
else
vddci = (data->vbios_boot_state.vddci_bootup_value * VOLTAGE_SCALE) << VDDCI_SHIFT;
table->VceLevel[count].MinVoltage |= table->VceLevel[count].MinVoltage |=
((mm_table->entries[count].vddc - data->vddc_vddci_delta) * (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT;
VOLTAGE_SCALE) << VDDCI_SHIFT;
table->VceLevel[count].MinVoltage |= 1 << PHASES_SHIFT; table->VceLevel[count].MinVoltage |= 1 << PHASES_SHIFT;
/*retrieve divider value for VBIOS */ /*retrieve divider value for VBIOS */
...@@ -1565,6 +1566,7 @@ static int polaris10_populate_smc_samu_level(struct pp_hwmgr *hwmgr, ...@@ -1565,6 +1566,7 @@ static int polaris10_populate_smc_samu_level(struct pp_hwmgr *hwmgr,
struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table =
table_info->mm_dep_table; table_info->mm_dep_table;
struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend);
uint32_t vddci;
table->SamuBootLevel = 0; table->SamuBootLevel = 0;
table->SamuLevelCount = (uint8_t)(mm_table->count); table->SamuLevelCount = (uint8_t)(mm_table->count);
...@@ -1575,8 +1577,16 @@ static int polaris10_populate_smc_samu_level(struct pp_hwmgr *hwmgr, ...@@ -1575,8 +1577,16 @@ static int polaris10_populate_smc_samu_level(struct pp_hwmgr *hwmgr,
table->SamuLevel[count].Frequency = mm_table->entries[count].samclock; table->SamuLevel[count].Frequency = mm_table->entries[count].samclock;
table->SamuLevel[count].MinVoltage |= (mm_table->entries[count].vddc * table->SamuLevel[count].MinVoltage |= (mm_table->entries[count].vddc *
VOLTAGE_SCALE) << VDDC_SHIFT; VOLTAGE_SCALE) << VDDC_SHIFT;
table->SamuLevel[count].MinVoltage |= ((mm_table->entries[count].vddc -
data->vddc_vddci_delta) * VOLTAGE_SCALE) << VDDCI_SHIFT; if (POLARIS10_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control)
vddci = (uint32_t)phm_find_closest_vddci(&(data->vddci_voltage_table),
mm_table->entries[count].vddc - VDDC_VDDCI_DELTA);
else if (POLARIS10_VOLTAGE_CONTROL_BY_SVID2 == data->vddci_control)
vddci = mm_table->entries[count].vddc - VDDC_VDDCI_DELTA;
else
vddci = (data->vbios_boot_state.vddci_bootup_value * VOLTAGE_SCALE) << VDDCI_SHIFT;
table->SamuLevel[count].MinVoltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT;
table->SamuLevel[count].MinVoltage |= 1 << PHASES_SHIFT; table->SamuLevel[count].MinVoltage |= 1 << PHASES_SHIFT;
/* retrieve divider value for VBIOS */ /* retrieve divider value for VBIOS */
...@@ -1659,6 +1669,7 @@ static int polaris10_populate_smc_uvd_level(struct pp_hwmgr *hwmgr, ...@@ -1659,6 +1669,7 @@ static int polaris10_populate_smc_uvd_level(struct pp_hwmgr *hwmgr,
struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table =
table_info->mm_dep_table; table_info->mm_dep_table;
struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend);
uint32_t vddci;
table->UvdLevelCount = (uint8_t)(mm_table->count); table->UvdLevelCount = (uint8_t)(mm_table->count);
table->UvdBootLevel = 0; table->UvdBootLevel = 0;
...@@ -1669,8 +1680,16 @@ static int polaris10_populate_smc_uvd_level(struct pp_hwmgr *hwmgr, ...@@ -1669,8 +1680,16 @@ static int polaris10_populate_smc_uvd_level(struct pp_hwmgr *hwmgr,
table->UvdLevel[count].DclkFrequency = mm_table->entries[count].dclk; table->UvdLevel[count].DclkFrequency = mm_table->entries[count].dclk;
table->UvdLevel[count].MinVoltage |= (mm_table->entries[count].vddc * table->UvdLevel[count].MinVoltage |= (mm_table->entries[count].vddc *
VOLTAGE_SCALE) << VDDC_SHIFT; VOLTAGE_SCALE) << VDDC_SHIFT;
table->UvdLevel[count].MinVoltage |= ((mm_table->entries[count].vddc -
data->vddc_vddci_delta) * VOLTAGE_SCALE) << VDDCI_SHIFT; if (POLARIS10_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control)
vddci = (uint32_t)phm_find_closest_vddci(&(data->vddci_voltage_table),
mm_table->entries[count].vddc - VDDC_VDDCI_DELTA);
else if (POLARIS10_VOLTAGE_CONTROL_BY_SVID2 == data->vddci_control)
vddci = mm_table->entries[count].vddc - VDDC_VDDCI_DELTA;
else
vddci = (data->vbios_boot_state.vddci_bootup_value * VOLTAGE_SCALE) << VDDCI_SHIFT;
table->UvdLevel[count].MinVoltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT;
table->UvdLevel[count].MinVoltage |= 1 << PHASES_SHIFT; table->UvdLevel[count].MinVoltage |= 1 << PHASES_SHIFT;
/* retrieve divider value for VBIOS */ /* retrieve divider value for VBIOS */
...@@ -1691,8 +1710,8 @@ static int polaris10_populate_smc_uvd_level(struct pp_hwmgr *hwmgr, ...@@ -1691,8 +1710,8 @@ static int polaris10_populate_smc_uvd_level(struct pp_hwmgr *hwmgr,
CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].VclkFrequency); CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].VclkFrequency);
CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].DclkFrequency); CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].DclkFrequency);
CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].MinVoltage); CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].MinVoltage);
} }
return result; return result;
} }
......
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