]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
drm/amd/pm: Fix si_upload_smc_data (v3)
authorTimur Kristóf <timur.kristof@gmail.com>
Thu, 28 Aug 2025 15:11:06 +0000 (17:11 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 15 Oct 2025 09:56:31 +0000 (11:56 +0200)
[ 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>
drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c

index c17d567cf8bc5f1b14b266fb6ada59f908b93752..85ab0d87eb337516513477712007f31e5d0594bd 100644 (file)
@@ -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;
 }