]> git.ipfire.org Git - thirdparty/linux.git/commit
drm/amd/display: consolidate DCN vblank/flip handling onto vupdate_no_lock
authorLeo Li <sunpeng.li@amd.com>
Fri, 12 Jun 2026 17:29:31 +0000 (13:29 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 17 Jul 2026 21:41:50 +0000 (17:41 -0400)
commit8382cd234981ae36299bb66a10bac2cd8ff1b99d
tree21a4455f44851d3094e3c52962f5a5472f153d24
parent75c8746b9d0a0317d8a58aa0efa2ff2f7359908b
drm/amd/display: consolidate DCN vblank/flip handling onto vupdate_no_lock

[Why]

On DCN, vblank events were delivered from VSTARTUP/VUPDATE
(dm_crtc_high_irq/dm_vupdate_high_irq) and pageflip completion from
GRPH_PFLIP (dm_pflip_high_irq). These signals can be masked by hardware
by a few things:

* DPG - DCN can Dynamically Power Gate parts of the display pipe when a
  self-refresh capable eDP is connected. DPG is engaged when there's
  enough static frames (detected through drm_vblank_off). Once gated,
  even though the OTG (output timing generator) is still enabled,
  VSTARTUP and GRPH_FLIP are masked.

* GSL - Driver can use the Global Sync Lock to block HW from latching
  onto double-buffered registers during programming, to prevent HW from
  latching onto a partially programmed state. This will mask VSTARTUP,
  GRPH_FLIP, and VUPDATE. See dcn20_pipe_control_lock().

* MALL - A DCN accessible cache introduced in DCN32+ DGPUs that can
  store fb data to allow for longer DRAM sleep. When scanning out from
  MALL, VSTARTUP is masked.

When masked, events are never delivered, which can show up as flip_done
timeouts in the wild.

However, there is an interrupt source on DCN that is never masked:
VUPDATE_NO_LOCK. It's simply an unmasked variant of VUPDATE, which fires
while the OTG is active, at the exact point hardware latches
double-buffered registers. It is therefore the natural single signal for
delivering both vblank and flip-completion events on DCN, and the
correct point to timestamp both VRR and non-VRR vblanks.

DCE's interrupt sources are different, it does not have an unmaskable
VUPDATE_NO_LOCK. The only unmaskable DCE interrupt is VLINE0, but it can
only be programmed as a vline offset from vsync_start, making it
unsuitable for VRR. Thus, we keep DCE untouched and use the existing mix
of interrupt sources.

[How]

For DCN1 and newer only:

* Factor the body of dm_crtc_high_irq() into dm_crtc_high_irq_handler()
  and drive it from dm_vupdate_high_irq() (VUPDATE_NO_LOCK). DCE keeps
  using dm_crtc_high_irq() (VSTARTUP) and dm_pflip_high_irq()
  (GRPH_PFLIP) unchanged.

* Stop registering VSTARTUP (crtc_irq) and GRPH_PFLIP (pageflip_irq) on
  DCN, and stop enabling them in amdgpu_dm_crtc_set_vblank() /
  manage_dm_interrupts(). Enable VUPDATE whenever vblank is enabled on
  DCN (previously only in VRR mode). The secure-display vline0 interrupt
  is left untouched.

* VUPDATE_NO_LOCK does not early-fire on an immediate (tearing / async)
  flip, since HW latches the new address right away. Deliver the flip
  completion event immediately after programming such flips in
  amdgpu_dm_commit_planes(), and clear pflip_status so the next vupdate
  handler does not double-send.

v2: Do not gate VUPDATE_NO_LOCK on DCN in dm_handle_vrr_transition()
    Also toggle VUPDATE_NO_LOCK on DCN in dm_gpureset_toggle_interrupts()
    Re-cook vblank event count and timestamp for immediate flips

Fixes: 9b47278cec98 ("drm/amd/display: temp w/a for dGPU to enter idle optimizations")
Link: https://gitlab.freedesktop.org/drm/amd/-/work_items/3787
Link: https://gitlab.freedesktop.org/drm/amd/-/work_items/4141
Assisted-by: Copilot:claude-opus-4.8
Co-developed-by: Matthew Schwartz <matthew.schwartz@linux.dev>
Signed-off-by: Matthew Schwartz <matthew.schwartz@linux.dev>
Tested-by: Mario Limonciello (AMD) <superm1@kernel.org>
Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
Signed-off-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit c87e6635d2db02c88ae8d09529362da672d34770)
Cc: stable@vger.kernel.org
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c