Commit b841ce7b authored by Alex Deucher's avatar Alex Deucher

drm/radeon/dpm: fix spread spectrum setup (v2)

Need to check for engine and memory clock ss separately
and only enable dynamic ss if either of them are found.

This should fix systems which have a ss table, but do
not have entries for engine or memory.  On those systems
we may enable dynamic spread spectrum without enabling
it on the engine or memory clocks which can lead to a
hang in some cases.

fixes some systems reported here:
https://bugs.freedesktop.org/show_bug.cgi?id=66963

v2: fix typo
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent fda83724
...@@ -2548,9 +2548,6 @@ int btc_dpm_init(struct radeon_device *rdev) ...@@ -2548,9 +2548,6 @@ int btc_dpm_init(struct radeon_device *rdev)
{ {
struct rv7xx_power_info *pi; struct rv7xx_power_info *pi;
struct evergreen_power_info *eg_pi; struct evergreen_power_info *eg_pi;
int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info);
u16 data_offset, size;
u8 frev, crev;
struct atom_clock_dividers dividers; struct atom_clock_dividers dividers;
int ret; int ret;
...@@ -2633,16 +2630,7 @@ int btc_dpm_init(struct radeon_device *rdev) ...@@ -2633,16 +2630,7 @@ int btc_dpm_init(struct radeon_device *rdev)
eg_pi->vddci_control = eg_pi->vddci_control =
radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0); radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0);
if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, rv770_get_engine_memory_ss(rdev);
&frev, &crev, &data_offset)) {
pi->sclk_ss = true;
pi->mclk_ss = true;
pi->dynamic_ss = true;
} else {
pi->sclk_ss = false;
pi->mclk_ss = false;
pi->dynamic_ss = true;
}
pi->asi = RV770_ASI_DFLT; pi->asi = RV770_ASI_DFLT;
pi->pasi = CYPRESS_HASI_DFLT; pi->pasi = CYPRESS_HASI_DFLT;
......
...@@ -2038,9 +2038,6 @@ int cypress_dpm_init(struct radeon_device *rdev) ...@@ -2038,9 +2038,6 @@ int cypress_dpm_init(struct radeon_device *rdev)
{ {
struct rv7xx_power_info *pi; struct rv7xx_power_info *pi;
struct evergreen_power_info *eg_pi; struct evergreen_power_info *eg_pi;
int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info);
uint16_t data_offset, size;
uint8_t frev, crev;
struct atom_clock_dividers dividers; struct atom_clock_dividers dividers;
int ret; int ret;
...@@ -2092,16 +2089,7 @@ int cypress_dpm_init(struct radeon_device *rdev) ...@@ -2092,16 +2089,7 @@ int cypress_dpm_init(struct radeon_device *rdev)
eg_pi->vddci_control = eg_pi->vddci_control =
radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0); radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0);
if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, rv770_get_engine_memory_ss(rdev);
&frev, &crev, &data_offset)) {
pi->sclk_ss = true;
pi->mclk_ss = true;
pi->dynamic_ss = true;
} else {
pi->sclk_ss = false;
pi->mclk_ss = false;
pi->dynamic_ss = true;
}
pi->asi = RV770_ASI_DFLT; pi->asi = RV770_ASI_DFLT;
pi->pasi = CYPRESS_HASI_DFLT; pi->pasi = CYPRESS_HASI_DFLT;
......
...@@ -4067,9 +4067,6 @@ int ni_dpm_init(struct radeon_device *rdev) ...@@ -4067,9 +4067,6 @@ int ni_dpm_init(struct radeon_device *rdev)
struct rv7xx_power_info *pi; struct rv7xx_power_info *pi;
struct evergreen_power_info *eg_pi; struct evergreen_power_info *eg_pi;
struct ni_power_info *ni_pi; struct ni_power_info *ni_pi;
int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info);
u16 data_offset, size;
u8 frev, crev;
struct atom_clock_dividers dividers; struct atom_clock_dividers dividers;
int ret; int ret;
...@@ -4162,16 +4159,7 @@ int ni_dpm_init(struct radeon_device *rdev) ...@@ -4162,16 +4159,7 @@ int ni_dpm_init(struct radeon_device *rdev)
eg_pi->vddci_control = eg_pi->vddci_control =
radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0); radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0);
if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, rv770_get_engine_memory_ss(rdev);
&frev, &crev, &data_offset)) {
pi->sclk_ss = true;
pi->mclk_ss = true;
pi->dynamic_ss = true;
} else {
pi->sclk_ss = false;
pi->mclk_ss = false;
pi->dynamic_ss = true;
}
pi->asi = RV770_ASI_DFLT; pi->asi = RV770_ASI_DFLT;
pi->pasi = CYPRESS_HASI_DFLT; pi->pasi = CYPRESS_HASI_DFLT;
......
...@@ -1944,9 +1944,7 @@ static int rv6xx_parse_power_table(struct radeon_device *rdev) ...@@ -1944,9 +1944,7 @@ static int rv6xx_parse_power_table(struct radeon_device *rdev)
int rv6xx_dpm_init(struct radeon_device *rdev) int rv6xx_dpm_init(struct radeon_device *rdev)
{ {
int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info); struct radeon_atom_ss ss;
uint16_t data_offset, size;
uint8_t frev, crev;
struct atom_clock_dividers dividers; struct atom_clock_dividers dividers;
struct rv6xx_power_info *pi; struct rv6xx_power_info *pi;
int ret; int ret;
...@@ -1989,16 +1987,15 @@ int rv6xx_dpm_init(struct radeon_device *rdev) ...@@ -1989,16 +1987,15 @@ int rv6xx_dpm_init(struct radeon_device *rdev)
pi->gfx_clock_gating = true; pi->gfx_clock_gating = true;
if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, pi->sclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss,
&frev, &crev, &data_offset)) { ASIC_INTERNAL_ENGINE_SS, 0);
pi->sclk_ss = true; pi->mclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss,
pi->mclk_ss = true; ASIC_INTERNAL_MEMORY_SS, 0);
if (pi->sclk_ss || pi->mclk_ss)
pi->dynamic_ss = true; pi->dynamic_ss = true;
} else { else
pi->sclk_ss = false;
pi->mclk_ss = false;
pi->dynamic_ss = false; pi->dynamic_ss = false;
}
pi->dynamic_pcie_gen2 = true; pi->dynamic_pcie_gen2 = true;
......
...@@ -2319,12 +2319,25 @@ int rv7xx_parse_power_table(struct radeon_device *rdev) ...@@ -2319,12 +2319,25 @@ int rv7xx_parse_power_table(struct radeon_device *rdev)
return 0; return 0;
} }
void rv770_get_engine_memory_ss(struct radeon_device *rdev)
{
struct rv7xx_power_info *pi = rv770_get_pi(rdev);
struct radeon_atom_ss ss;
pi->sclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss,
ASIC_INTERNAL_ENGINE_SS, 0);
pi->mclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss,
ASIC_INTERNAL_MEMORY_SS, 0);
if (pi->sclk_ss || pi->mclk_ss)
pi->dynamic_ss = true;
else
pi->dynamic_ss = false;
}
int rv770_dpm_init(struct radeon_device *rdev) int rv770_dpm_init(struct radeon_device *rdev)
{ {
struct rv7xx_power_info *pi; struct rv7xx_power_info *pi;
int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info);
uint16_t data_offset, size;
uint8_t frev, crev;
struct atom_clock_dividers dividers; struct atom_clock_dividers dividers;
int ret; int ret;
...@@ -2369,16 +2382,7 @@ int rv770_dpm_init(struct radeon_device *rdev) ...@@ -2369,16 +2382,7 @@ int rv770_dpm_init(struct radeon_device *rdev)
pi->mvdd_control = pi->mvdd_control =
radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, 0); radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, 0);
if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, rv770_get_engine_memory_ss(rdev);
&frev, &crev, &data_offset)) {
pi->sclk_ss = true;
pi->mclk_ss = true;
pi->dynamic_ss = true;
} else {
pi->sclk_ss = false;
pi->mclk_ss = false;
pi->dynamic_ss = false;
}
pi->asi = RV770_ASI_DFLT; pi->asi = RV770_ASI_DFLT;
pi->pasi = RV770_HASI_DFLT; pi->pasi = RV770_HASI_DFLT;
......
...@@ -275,6 +275,7 @@ void rv770_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev, ...@@ -275,6 +275,7 @@ void rv770_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev,
void rv770_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev, void rv770_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev,
struct radeon_ps *new_ps, struct radeon_ps *new_ps,
struct radeon_ps *old_ps); struct radeon_ps *old_ps);
void rv770_get_engine_memory_ss(struct radeon_device *rdev);
/* smc */ /* smc */
int rv770_read_smc_soft_register(struct radeon_device *rdev, int rv770_read_smc_soft_register(struct radeon_device *rdev,
......
...@@ -6253,9 +6253,6 @@ int si_dpm_init(struct radeon_device *rdev) ...@@ -6253,9 +6253,6 @@ int si_dpm_init(struct radeon_device *rdev)
struct evergreen_power_info *eg_pi; struct evergreen_power_info *eg_pi;
struct ni_power_info *ni_pi; struct ni_power_info *ni_pi;
struct si_power_info *si_pi; struct si_power_info *si_pi;
int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info);
u16 data_offset, size;
u8 frev, crev;
struct atom_clock_dividers dividers; struct atom_clock_dividers dividers;
int ret; int ret;
u32 mask; u32 mask;
...@@ -6346,16 +6343,7 @@ int si_dpm_init(struct radeon_device *rdev) ...@@ -6346,16 +6343,7 @@ int si_dpm_init(struct radeon_device *rdev)
si_pi->vddc_phase_shed_control = si_pi->vddc_phase_shed_control =
radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, VOLTAGE_OBJ_PHASE_LUT); radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, VOLTAGE_OBJ_PHASE_LUT);
if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, rv770_get_engine_memory_ss(rdev);
&frev, &crev, &data_offset)) {
pi->sclk_ss = true;
pi->mclk_ss = true;
pi->dynamic_ss = true;
} else {
pi->sclk_ss = false;
pi->mclk_ss = false;
pi->dynamic_ss = true;
}
pi->asi = RV770_ASI_DFLT; pi->asi = RV770_ASI_DFLT;
pi->pasi = CYPRESS_HASI_DFLT; pi->pasi = CYPRESS_HASI_DFLT;
......
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