Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amd/pm: restore SCLK settings after S0ix resume

User-configured SCLK(GPU core clock)frequencies were not persisting
across S0ix suspend/resume cycles on smu v14 hardware.
The issue occurred because of the code resetting clock frequency
to zero during resume.

This patch addresses the problem by:
- Preserving user-configured values in driver and sets the
clock frequency across resume
- Preserved settings are sent to the hardware during resume

Signed-off-by: mythilam <mythilam@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Yang Wang <kevinyang.wang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 20ba98326f4c69e6bf8d1f42942ece485a675b27)

authored by

mythilam and committed by
Alex Deucher
7a372e21 77f73253

+37 -5
+5
drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c
··· 1939 1939 dev_err(smu->adev->dev, "Set soft max sclk failed!"); 1940 1940 return ret; 1941 1941 } 1942 + if (smu->gfx_actual_hard_min_freq != smu->gfx_default_hard_min_freq || 1943 + smu->gfx_actual_soft_max_freq != smu->gfx_default_soft_max_freq) 1944 + smu->user_dpm_profile.user_od = true; 1945 + else 1946 + smu->user_dpm_profile.user_od = false; 1942 1947 break; 1943 1948 default: 1944 1949 return -ENOSYS;
+32 -5
drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c
··· 1514 1514 1515 1515 smu->gfx_default_hard_min_freq = clk_table->MinGfxClk; 1516 1516 smu->gfx_default_soft_max_freq = clk_table->MaxGfxClk; 1517 - smu->gfx_actual_hard_min_freq = 0; 1518 - smu->gfx_actual_soft_max_freq = 0; 1519 - 1517 + if (smu->gfx_actual_hard_min_freq == 0) 1518 + smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq; 1519 + if (smu->gfx_actual_soft_max_freq == 0) 1520 + smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq; 1520 1521 return 0; 1521 1522 } 1522 1523 ··· 1527 1526 1528 1527 smu->gfx_default_hard_min_freq = clk_table->MinGfxClk; 1529 1528 smu->gfx_default_soft_max_freq = clk_table->MaxGfxClk; 1530 - smu->gfx_actual_hard_min_freq = 0; 1531 - smu->gfx_actual_soft_max_freq = 0; 1529 + if (smu->gfx_actual_hard_min_freq == 0) 1530 + smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq; 1531 + if (smu->gfx_actual_soft_max_freq == 0) 1532 + smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq; 1532 1533 1533 1534 return 0; 1534 1535 } ··· 1668 1665 return ret; 1669 1666 } 1670 1667 1668 + static int smu_v14_0_0_restore_user_od_settings(struct smu_context *smu) 1669 + { 1670 + int ret; 1671 + 1672 + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinGfxClk, 1673 + smu->gfx_actual_hard_min_freq, 1674 + NULL); 1675 + if (ret) { 1676 + dev_err(smu->adev->dev, "Failed to restore hard min sclk!\n"); 1677 + return ret; 1678 + } 1679 + 1680 + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk, 1681 + smu->gfx_actual_soft_max_freq, 1682 + NULL); 1683 + if (ret) { 1684 + dev_err(smu->adev->dev, "Failed to restore soft max sclk!\n"); 1685 + return ret; 1686 + } 1687 + 1688 + return 0; 1689 + } 1690 + 1671 1691 static const struct pptable_funcs smu_v14_0_0_ppt_funcs = { 1672 1692 .check_fw_status = smu_v14_0_check_fw_status, 1673 1693 .check_fw_version = smu_v14_0_check_fw_version, ··· 1714 1688 .mode2_reset = smu_v14_0_0_mode2_reset, 1715 1689 .get_dpm_ultimate_freq = smu_v14_0_common_get_dpm_ultimate_freq, 1716 1690 .set_soft_freq_limited_range = smu_v14_0_0_set_soft_freq_limited_range, 1691 + .restore_user_od_settings = smu_v14_0_0_restore_user_od_settings, 1717 1692 .od_edit_dpm_table = smu_v14_0_od_edit_dpm_table, 1718 1693 .print_clk_levels = smu_v14_0_0_print_clk_levels, 1719 1694 .force_clk_levels = smu_v14_0_0_force_clk_levels,