Skip to content

Commit 86b16f3

Browse files
Timur Kristófgregkh
authored andcommitted
drm/amd/pm/smu7: Add SCLK cap for quirky Hawaii board
[ Upstream commit 4724bc5 ] On a specific Radeon R9 390X board, the GPU can "randomly" hang while gaming. Initially I thought this was a RADV bug and tried to work around this in Mesa: commit 8ea08747b86b ("radv: Mitigate GPU hang on Hawaii in Dota 2 and RotTR") However, I got some feedback from other users who are reporting that the above mitigation causes a significant performance regression for them, and they didn't experience the hang on their GPU in the first place. After some further investigation, it turns out that the problem is that the highest SCLK DPM level on this board isn't stable. Lowering SCLK to 1040 MHz (from 1070 MHz) works around the issue, and has a negligible impact on performance compared to the Mesa patch. (Note that increasing the voltage can also work around it, but we felt that lowering the SCLK is the safer option.) To solve the above issue, add an "sclk_cap" field to smu7_hwmgr and set this field for the affected board. The capped SCLK value correctly appears on the sysfs interface and shows up in GUI tools such as LACT. Fixes: 9f4b354 ("drm/amd/powerplay: add CI asics support to smumgr (v3)") Signed-off-by: Timur Kristóf <timur.kristof@gmail.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 834be5c commit 86b16f3

2 files changed

Lines changed: 27 additions & 4 deletions

File tree

drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -787,7 +787,7 @@ static int smu7_setup_dpm_tables_v0(struct pp_hwmgr *hwmgr)
787787
hwmgr->dyn_state.vddc_dependency_on_mclk;
788788
struct phm_cac_leakage_table *std_voltage_table =
789789
hwmgr->dyn_state.cac_leakage_table;
790-
uint32_t i;
790+
uint32_t i, clk;
791791

792792
PP_ASSERT_WITH_CODE(allowed_vdd_sclk_table != NULL,
793793
"SCLK dependency table is missing. This table is mandatory", return -EINVAL);
@@ -804,10 +804,12 @@ static int smu7_setup_dpm_tables_v0(struct pp_hwmgr *hwmgr)
804804
data->dpm_table.sclk_table.count = 0;
805805

806806
for (i = 0; i < allowed_vdd_sclk_table->count; i++) {
807+
clk = min(allowed_vdd_sclk_table->entries[i].clk, data->sclk_cap);
808+
807809
if (i == 0 || data->dpm_table.sclk_table.dpm_levels[data->dpm_table.sclk_table.count-1].value !=
808-
allowed_vdd_sclk_table->entries[i].clk) {
810+
clk) {
809811
data->dpm_table.sclk_table.dpm_levels[data->dpm_table.sclk_table.count].value =
810-
allowed_vdd_sclk_table->entries[i].clk;
812+
clk;
811813
data->dpm_table.sclk_table.dpm_levels[data->dpm_table.sclk_table.count].enabled = (i == 0) ? 1 : 0;
812814
data->dpm_table.sclk_table.count++;
813815
}
@@ -3006,6 +3008,25 @@ static int smu7_init_voltage_dependency_on_display_clock_table(struct pp_hwmgr *
30063008
return 0;
30073009
}
30083010

3011+
static void smu7_set_sclk_cap(struct pp_hwmgr *hwmgr)
3012+
{
3013+
struct amdgpu_device *adev = hwmgr->adev;
3014+
struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
3015+
3016+
data->sclk_cap = 0xffffffff;
3017+
3018+
if (hwmgr->od_enabled)
3019+
return;
3020+
3021+
/* R9 390X board: last sclk dpm level is unstable, use lower sclk */
3022+
if (adev->pdev->device == 0x67B0 &&
3023+
adev->pdev->subsystem_vendor == 0x1043)
3024+
data->sclk_cap = 104000; /* 1040 MHz */
3025+
3026+
if (data->sclk_cap != 0xffffffff)
3027+
dev_info(adev->dev, "sclk cap: %u kHz on quirky ASIC\n", data->sclk_cap * 10);
3028+
}
3029+
30093030
static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
30103031
{
30113032
struct amdgpu_device *adev = hwmgr->adev;
@@ -3017,6 +3038,7 @@ static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
30173038
return -ENOMEM;
30183039

30193040
hwmgr->backend = data;
3041+
smu7_set_sclk_cap(hwmgr);
30203042
smu7_patch_voltage_workaround(hwmgr);
30213043
smu7_init_dpm_defaults(hwmgr);
30223044

@@ -3903,7 +3925,7 @@ static int smu7_get_pp_table_entry_callback_func_v0(struct pp_hwmgr *hwmgr,
39033925

39043926
/* Performance levels are arranged from low to high. */
39053927
performance_level->memory_clock = memory_clock;
3906-
performance_level->engine_clock = engine_clock;
3928+
performance_level->engine_clock = min(engine_clock, data->sclk_cap);
39073929

39083930
pcie_gen_from_bios = visland_clk_info->ucPCIEGen;
39093931

drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ struct smu7_hwmgr {
234234
uint32_t pcie_gen_cap;
235235
uint32_t pcie_lane_cap;
236236
uint32_t pcie_spc_cap;
237+
uint32_t sclk_cap;
237238
struct smu7_leakage_voltage vddc_leakage;
238239
struct smu7_leakage_voltage vddci_leakage;
239240
struct smu7_leakage_voltage vddcgfx_leakage;

0 commit comments

Comments
 (0)