Skip to content

Commit 4724bc5

Browse files
Timur Kristófalexdeucher
authored andcommitted
drm/amd/pm/smu7: Add SCLK cap for quirky Hawaii board
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>
1 parent baf28ec commit 4724bc5

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
}
@@ -3000,6 +3002,25 @@ static int smu7_init_voltage_dependency_on_display_clock_table(struct pp_hwmgr *
30003002
return 0;
30013003
}
30023004

3005+
static void smu7_set_sclk_cap(struct pp_hwmgr *hwmgr)
3006+
{
3007+
struct amdgpu_device *adev = hwmgr->adev;
3008+
struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
3009+
3010+
data->sclk_cap = 0xffffffff;
3011+
3012+
if (hwmgr->od_enabled)
3013+
return;
3014+
3015+
/* R9 390X board: last sclk dpm level is unstable, use lower sclk */
3016+
if (adev->pdev->device == 0x67B0 &&
3017+
adev->pdev->subsystem_vendor == 0x1043)
3018+
data->sclk_cap = 104000; /* 1040 MHz */
3019+
3020+
if (data->sclk_cap != 0xffffffff)
3021+
dev_info(adev->dev, "sclk cap: %u kHz on quirky ASIC\n", data->sclk_cap * 10);
3022+
}
3023+
30033024
static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
30043025
{
30053026
struct amdgpu_device *adev = hwmgr->adev;
@@ -3011,6 +3032,7 @@ static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
30113032
return -ENOMEM;
30123033

30133034
hwmgr->backend = data;
3035+
smu7_set_sclk_cap(hwmgr);
30143036
smu7_patch_voltage_workaround(hwmgr);
30153037
smu7_init_dpm_defaults(hwmgr);
30163038

@@ -3894,7 +3916,7 @@ static int smu7_get_pp_table_entry_callback_func_v0(struct pp_hwmgr *hwmgr,
38943916

38953917
/* Performance levels are arranged from low to high. */
38963918
performance_level->memory_clock = memory_clock;
3897-
performance_level->engine_clock = engine_clock;
3919+
performance_level->engine_clock = min(engine_clock, data->sclk_cap);
38983920

38993921
pcie_gen_from_bios = visland_clk_info->ucPCIEGen;
39003922

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)