summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorTimur Kristóf <timur.kristof@gmail.com>2025-08-28 17:11:06 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-10-15 11:56:31 +0200
commit82963fb4eca9d4858f5c2fda77741575aa504903 (patch)
tree352e877ac1245dba38bf2e32ea58a9d6efe2219f /drivers/gpu
parent85324b1f5f708e89c73b7fb1a35f5a74279b70c7 (diff)
downloadlinux-82963fb4eca9d4858f5c2fda77741575aa504903.tar.gz
linux-82963fb4eca9d4858f5c2fda77741575aa504903.tar.bz2
linux-82963fb4eca9d4858f5c2fda77741575aa504903.zip
drm/amd/pm: Fix si_upload_smc_data (v3)
[ Upstream commit a43b2cec04b02743338aa78f837ee0bdf066a6d5 ] The si_upload_smc_data function uses si_write_smc_soft_register to set some register values in the SMC, and expects the result to be PPSMC_Result_OK which is 1. The PPSMC_Result_OK / PPSMC_Result_Failed values are used for checking the result of a command sent to the SMC. However, the si_write_smc_soft_register actually doesn't send any commands to the SMC and returns zero on success, so this check was incorrect. Fix that by not checking the return value, just like other calls to si_write_smc_soft_register. v3: Additionally, when no display is plugged in, there is no need to restrict MCLK switching, so program the registers to zero. Fixes: 841686df9f7d ("drm/amdgpu: add SI DPM support (v4)") Reviewed-by: Alex Deucher <alexander.deucher@amd.com> 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>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c43
1 files changed, 24 insertions, 19 deletions
diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c
index c17d567cf8bc..85ab0d87eb33 100644
--- a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c
+++ b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c
@@ -5793,9 +5793,9 @@ static int si_upload_smc_data(struct amdgpu_device *adev)
{
struct amdgpu_crtc *amdgpu_crtc = NULL;
int i;
-
- if (adev->pm.dpm.new_active_crtc_count == 0)
- return 0;
+ u32 crtc_index = 0;
+ u32 mclk_change_block_cp_min = 0;
+ u32 mclk_change_block_cp_max = 0;
for (i = 0; i < adev->mode_info.num_crtc; i++) {
if (adev->pm.dpm.new_active_crtcs & (1 << i)) {
@@ -5804,26 +5804,31 @@ static int si_upload_smc_data(struct amdgpu_device *adev)
}
}
- if (amdgpu_crtc == NULL)
- return 0;
+ /* When a display is plugged in, program these so that the SMC
+ * performs MCLK switching when it doesn't cause flickering.
+ * When no display is plugged in, there is no need to restrict
+ * MCLK switching, so program them to zero.
+ */
+ if (adev->pm.dpm.new_active_crtc_count && amdgpu_crtc) {
+ crtc_index = amdgpu_crtc->crtc_id;
- if (amdgpu_crtc->line_time <= 0)
- return 0;
+ if (amdgpu_crtc->line_time) {
+ mclk_change_block_cp_min = amdgpu_crtc->wm_high / amdgpu_crtc->line_time;
+ mclk_change_block_cp_max = amdgpu_crtc->wm_low / amdgpu_crtc->line_time;
+ }
+ }
- if (si_write_smc_soft_register(adev,
- SI_SMC_SOFT_REGISTER_crtc_index,
- amdgpu_crtc->crtc_id) != PPSMC_Result_OK)
- return 0;
+ si_write_smc_soft_register(adev,
+ SI_SMC_SOFT_REGISTER_crtc_index,
+ crtc_index);
- if (si_write_smc_soft_register(adev,
- SI_SMC_SOFT_REGISTER_mclk_change_block_cp_min,
- amdgpu_crtc->wm_high / amdgpu_crtc->line_time) != PPSMC_Result_OK)
- return 0;
+ si_write_smc_soft_register(adev,
+ SI_SMC_SOFT_REGISTER_mclk_change_block_cp_min,
+ mclk_change_block_cp_min);
- if (si_write_smc_soft_register(adev,
- SI_SMC_SOFT_REGISTER_mclk_change_block_cp_max,
- amdgpu_crtc->wm_low / amdgpu_crtc->line_time) != PPSMC_Result_OK)
- return 0;
+ si_write_smc_soft_register(adev,
+ SI_SMC_SOFT_REGISTER_mclk_change_block_cp_max,
+ mclk_change_block_cp_max);
return 0;
}