Skip to content

Commit f21e6d1

Browse files
leo-sunli1alexdeucher
authored andcommitted
drm/amd/display: Increase vblank offdelay for PSR panels
[Why] Depending on when the HW latching event (vupdate) of double-buffered registers happen relative to the PSR SDP (signals panel psr enter/exit) deadline, and how bad the Panel clock has drifted since the last ALPM off event, there can be up to 3 frames of delay between sending the PSR exit cmd to DMUB fw, and when the panel starts displaying live frames. This can manifest as micro-stuttering when userspace commit patterns cause rapid toggling of the DRM vblank counter, since PSR enter/exit is hooked up to DRM vblank disable/enable respectively. In the ideal world, the panel should present the live frame immediately on PSR exit cmd. But due to HW design and PSR limitations, immediate exit can only happen by chance, when: 1. PSR exit cmd is ack'd by FW before HW latching (vupdate) event, and 2. Panel's SDP deadline -- determined by it's PSR Start Delay in DPCD 71h -- is after the vupdate event. The PSR exit SDP can then be sent immediately after HW latches. Otherwise, we have to wait 1 frame. And 3. There is negligible drift between the panel's clock and source clock. Otherwise, there can be up to 1 frame of drift. Note that this delay is not expected with Panel Replay. [How] Since PSR power savings can be quite substantial, and there are a lot of systems in the wild with PSR panels, It'll be nice to have a middle ground that balances user experience with power savings. A simple way to achieve this is by extending the vblank offdelay, such that additional PSR exit delays will be less perceivable. We can set: 20/100 * offdelay_ms = 3_frames_ms => offdelay_ms = 5 * 3_frames_ms This ensures that `3_frames_ms` will only be experienced as a 20% delay on top how long the panel has been static, and thus make the delay less perceivable. If this ends up being too high of a percentage, it can be dropped further in a future change. Fixes: 537ef0f ("drm/amd/display: use new vblank enable policy for DCN35+") Reviewed-by: Harry Wentland <harry.wentland@amd.com> Signed-off-by: Leo Li <sunpeng.li@amd.com> Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Cc: stable@vger.kernel.org
1 parent 5f054dd commit f21e6d1

File tree

1 file changed

+33
-8
lines changed

1 file changed

+33
-8
lines changed

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8707,14 +8707,39 @@ static void manage_dm_interrupts(struct amdgpu_device *adev,
87078707
int offdelay;
87088708

87098709
if (acrtc_state) {
8710-
if (amdgpu_ip_version(adev, DCE_HWIP, 0) <
8711-
IP_VERSION(3, 5, 0) ||
8712-
acrtc_state->stream->link->psr_settings.psr_version <
8713-
DC_PSR_VERSION_UNSUPPORTED ||
8714-
!(adev->flags & AMD_IS_APU)) {
8715-
timing = &acrtc_state->stream->timing;
8716-
8717-
/* at least 2 frames */
8710+
timing = &acrtc_state->stream->timing;
8711+
8712+
/*
8713+
* Depending on when the HW latching event of double-buffered
8714+
* registers happen relative to the PSR SDP deadline, and how
8715+
* bad the Panel clock has drifted since the last ALPM off
8716+
* event, there can be up to 3 frames of delay between sending
8717+
* the PSR exit cmd to DMUB fw, and when the panel starts
8718+
* displaying live frames.
8719+
*
8720+
* We can set:
8721+
*
8722+
* 20/100 * offdelay_ms = 3_frames_ms
8723+
* => offdelay_ms = 5 * 3_frames_ms
8724+
*
8725+
* This ensures that `3_frames_ms` will only be experienced as a
8726+
* 20% delay on top how long the display has been static, and
8727+
* thus make the delay less perceivable.
8728+
*/
8729+
if (acrtc_state->stream->link->psr_settings.psr_version <
8730+
DC_PSR_VERSION_UNSUPPORTED) {
8731+
offdelay = DIV64_U64_ROUND_UP((u64)5 * 3 * 10 *
8732+
timing->v_total *
8733+
timing->h_total,
8734+
timing->pix_clk_100hz);
8735+
config.offdelay_ms = offdelay ?: 30;
8736+
} else if (amdgpu_ip_version(adev, DCE_HWIP, 0) <
8737+
IP_VERSION(3, 5, 0) ||
8738+
!(adev->flags & AMD_IS_APU)) {
8739+
/*
8740+
* Older HW and DGPU have issues with instant off;
8741+
* use a 2 frame offdelay.
8742+
*/
87188743
offdelay = DIV64_U64_ROUND_UP((u64)20 *
87198744
timing->v_total *
87208745
timing->h_total,

0 commit comments

Comments
 (0)