Re: [PATCH] drm/amd/display: Use vline2 interrupt on DCN instead of vstartup

2026-06-01 Thread Mary Guillemard
Hi Leo,

The patch appears to work perfectly for me on my RX 9070 XT.
I used to have a timeout on a daily basis but haven't got any since I
applied your patch 3 weeks ago.

Mary

On Mon, May 04, 2026 at 02:36:49PM -0400, [email protected] wrote:
> From: Leo Li 
> 
> [Why]
> 
> VStartup is an OTG event that fires when the pixel pipeline prepares for
> pixel scanout of the next frame. It was previously used to deliver
> vblank events for commits that do not trigger a fb address update, and
> hence a pflip interrupt (hw cursor updates, for example).
> 
> The issue with vstartup is that HW can mask the interrupt in cases where
> idle optimizations are enabled or when a HW lock is active. This could
> the explain the range of flip_done timeouts frequently seen in the wild.
> 
> DCN hardware provides 3 generic OTG interrupts that can be programmed to
> fire on a specific line. Vline 0 and 1 are currently reserved, with
> vline2 available to use for event delivery. These interrupts cannot
> be masked, as long as the OTG is active.
> 
> [How]
> 
> Switch to vline2 for vblank handling. Today, DC will program the
> vline2 position to at vupdate -- the point at which HW latches to
> double-buffered registers.
> 
> Since all the vline interrupt types share the same interrupt src_id,
> refactor the existing vline0 infrastructure to allow for all the vline0,
> 1, and 2 types.
> 
> Since this is intended to replace vstartup for DCN, use the same handler
> logic, but be careful to leave DCE on vstartup.
> 
> Signed-off-by: Leo Li 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h   |   2 +-
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 165 --
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   9 +
>  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c|  20 ++-
>  .../drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c |  99 +--
>  .../drm/amd/display/amdgpu_dm/amdgpu_dm_irq.h |   7 +
>  .../display/dc/irq/dcn10/irq_service_dcn10.c  |  44 +++--
>  .../display/dc/irq/dcn20/irq_service_dcn20.c  |  43 +++--
>  .../dc/irq/dcn201/irq_service_dcn201.c|  24 ++-
>  .../display/dc/irq/dcn21/irq_service_dcn21.c  |  44 +++--
>  .../display/dc/irq/dcn30/irq_service_dcn30.c  |  44 +++--
>  .../dc/irq/dcn302/irq_service_dcn302.c|  43 +++--
>  .../dc/irq/dcn303/irq_service_dcn303.c|  24 ++-
>  .../display/dc/irq/dcn31/irq_service_dcn31.c  |  44 +++--
>  .../dc/irq/dcn314/irq_service_dcn314.c|  44 +++--
>  .../dc/irq/dcn315/irq_service_dcn315.c|  44 +++--
>  .../display/dc/irq/dcn32/irq_service_dcn32.c  |  26 +--
>  .../display/dc/irq/dcn35/irq_service_dcn35.c  |  41 +++--
>  .../dc/irq/dcn351/irq_service_dcn351.c|  43 +++--
>  .../display/dc/irq/dcn36/irq_service_dcn36.c  |  41 +++--
>  .../dc/irq/dcn401/irq_service_dcn401.c|  25 +--
>  .../display/dc/irq/dcn42/irq_service_dcn42.c  |  26 +--
>  .../gpu/drm/amd/display/dc/irq/irq_service.h  |  23 +++
>  23 files changed, 673 insertions(+), 252 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 39894e38fee45..0d84293705107 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -947,7 +947,7 @@ struct amdgpu_device {
>   /* For pre-DCE11. DCE11 and later are in "struct amdgpu_device->dm" */
>   struct delayed_work hotplug_work;
>   struct amdgpu_irq_src   crtc_irq;
> - struct amdgpu_irq_src   vline0_irq;
> + struct amdgpu_irq_src   vline_irq;
>   struct amdgpu_irq_src   vupdate_irq;
>   struct amdgpu_irq_src   pageflip_irq;
>   struct amdgpu_irq_src   hpd_irq;
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 3fa4dbda4517c..429f8df17c5d1 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -646,7 +646,8 @@ static void dm_vupdate_high_irq(void *interrupt_params)
>   * Handles the CRTC/VSYNC interrupt by notfying DRM's VBLANK
>   * event handler.
>   */
> -static void dm_crtc_high_irq(void *interrupt_params)
> +static void __dm_crtc_high_irq(void *interrupt_params,
> +  int otg_inst)
>  {
>   struct common_irq_params *irq_params = interrupt_params;
>   struct amdgpu_device *adev = irq_params->adev;
> @@ -655,7 +656,7 @@ static void dm_crtc_high_irq(void *interrupt_params)
>   unsigned long flags;
>   int vrr_active;
>  
> - acrtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - 
> IRQ_TYPE_VBLANK);
> + acrtc = get_crtc_by_otg_inst(adev, otg_inst);
>   if (!acrtc)
>   return;
>  
> @@ -755,6 +756,13 @@ static void dm_crtc_high_irq(void *interrupt_params)
>   spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags);
>  }
>  
> +static void dm_crtc_high_irq(void *interrupt_params)
> +{
> + struct 

Re: [PATCH] drm/amd/display: Use vline2 interrupt on DCN instead of vstartup

2026-05-18 Thread Shengyu Qu

Hi,

Still no issues after longer testing:
https://gitlab.freedesktop.org/drm/amd/-/work_items/2950#note_3477114

Also what's your test result, Michele?

Best regards,
Shengyu

在 2026/5/10 14:06, Shengyu Qu 写道:

Hi Leo,

Seems this patch is working:

https://gitlab.freedesktop.org/drm/amd/-/work_items/2950#note_3465004

Best regards,

Shengyu


在 2026/5/5 02:36, [email protected] 写道:

From: Leo Li 

[Why]

VStartup is an OTG event that fires when the pixel pipeline prepares for
pixel scanout of the next frame. It was previously used to deliver
vblank events for commits that do not trigger a fb address update, and
hence a pflip interrupt (hw cursor updates, for example).

The issue with vstartup is that HW can mask the interrupt in cases where
idle optimizations are enabled or when a HW lock is active. This could
the explain the range of flip_done timeouts frequently seen in the wild.

DCN hardware provides 3 generic OTG interrupts that can be programmed to
fire on a specific line. Vline 0 and 1 are currently reserved, with
vline2 available to use for event delivery. These interrupts cannot
be masked, as long as the OTG is active.

[How]

Switch to vline2 for vblank handling. Today, DC will program the
vline2 position to at vupdate -- the point at which HW latches to
double-buffered registers.

Since all the vline interrupt types share the same interrupt src_id,
refactor the existing vline0 infrastructure to allow for all the vline0,
1, and 2 types.

Since this is intended to replace vstartup for DCN, use the same handler
logic, but be careful to leave DCE on vstartup.

Signed-off-by: Leo Li 
---
  drivers/gpu/drm/amd/amdgpu/amdgpu.h   |   2 +-
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 165 --
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   9 +
  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    |  20 ++-
  .../drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c |  99 +--
  .../drm/amd/display/amdgpu_dm/amdgpu_dm_irq.h |   7 +
  .../display/dc/irq/dcn10/irq_service_dcn10.c  |  44 +++--
  .../display/dc/irq/dcn20/irq_service_dcn20.c  |  43 +++--
  .../dc/irq/dcn201/irq_service_dcn201.c    |  24 ++-
  .../display/dc/irq/dcn21/irq_service_dcn21.c  |  44 +++--
  .../display/dc/irq/dcn30/irq_service_dcn30.c  |  44 +++--
  .../dc/irq/dcn302/irq_service_dcn302.c    |  43 +++--
  .../dc/irq/dcn303/irq_service_dcn303.c    |  24 ++-
  .../display/dc/irq/dcn31/irq_service_dcn31.c  |  44 +++--
  .../dc/irq/dcn314/irq_service_dcn314.c    |  44 +++--
  .../dc/irq/dcn315/irq_service_dcn315.c    |  44 +++--
  .../display/dc/irq/dcn32/irq_service_dcn32.c  |  26 +--
  .../display/dc/irq/dcn35/irq_service_dcn35.c  |  41 +++--
  .../dc/irq/dcn351/irq_service_dcn351.c    |  43 +++--
  .../display/dc/irq/dcn36/irq_service_dcn36.c  |  41 +++--
  .../dc/irq/dcn401/irq_service_dcn401.c    |  25 +--
  .../display/dc/irq/dcn42/irq_service_dcn42.c  |  26 +--
  .../gpu/drm/amd/display/dc/irq/irq_service.h  |  23 +++
  23 files changed, 673 insertions(+), 252 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/ 
amd/amdgpu/amdgpu.h

index 39894e38fee45..0d84293705107 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -947,7 +947,7 @@ struct amdgpu_device {
  /* For pre-DCE11. DCE11 and later are in "struct amdgpu_device- 
>dm" */

  struct delayed_work hotplug_work;
  struct amdgpu_irq_src    crtc_irq;
-    struct amdgpu_irq_src    vline0_irq;
+    struct amdgpu_irq_src    vline_irq;
  struct amdgpu_irq_src    vupdate_irq;
  struct amdgpu_irq_src    pageflip_irq;
  struct amdgpu_irq_src    hpd_irq;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/ 
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c

index 3fa4dbda4517c..429f8df17c5d1 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -646,7 +646,8 @@ static void dm_vupdate_high_irq(void 
*interrupt_params)

   * Handles the CRTC/VSYNC interrupt by notfying DRM's VBLANK
   * event handler.
   */
-static void dm_crtc_high_irq(void *interrupt_params)
+static void __dm_crtc_high_irq(void *interrupt_params,
+ int otg_inst)
  {
  struct common_irq_params *irq_params = interrupt_params;
  struct amdgpu_device *adev = irq_params->adev;
@@ -655,7 +656,7 @@ static void dm_crtc_high_irq(void *interrupt_params)
  unsigned long flags;
  int vrr_active;
-    acrtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - 
IRQ_TYPE_VBLANK);

+    acrtc = get_crtc_by_otg_inst(adev, otg_inst);
  if (!acrtc)
  return;
@@ -755,6 +756,13 @@ static void dm_crtc_high_irq(void *interrupt_params)
  spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags);
  }
+static void dm_crtc_high_irq(void *interrupt_params)
+{
+    struct common_irq_params *irq_params = interrupt_params;
+    

Re: [PATCH] drm/amd/display: Use vline2 interrupt on DCN instead of vstartup

2026-05-18 Thread Michele Palazzi

On 5/18/26 08:34, Shengyu Qu wrote:

Hi,

Still no issues after longer testing:
https://gitlab.freedesktop.org/drm/amd/-/work_items/2950#note_3477114

Also what's your test result, Michele?

Best regards,
Shengyu


no issues for me too, patch seems to work.

Michele


Re: [PATCH] drm/amd/display: Use vline2 interrupt on DCN instead of vstartup

2026-05-11 Thread Shengyu Qu

Hi Leo,

Seems this patch is working:

https://gitlab.freedesktop.org/drm/amd/-/work_items/2950#note_3465004

Best regards,

Shengyu


在 2026/5/5 02:36, [email protected] 写道:

From: Leo Li 

[Why]

VStartup is an OTG event that fires when the pixel pipeline prepares for
pixel scanout of the next frame. It was previously used to deliver
vblank events for commits that do not trigger a fb address update, and
hence a pflip interrupt (hw cursor updates, for example).

The issue with vstartup is that HW can mask the interrupt in cases where
idle optimizations are enabled or when a HW lock is active. This could
the explain the range of flip_done timeouts frequently seen in the wild.

DCN hardware provides 3 generic OTG interrupts that can be programmed to
fire on a specific line. Vline 0 and 1 are currently reserved, with
vline2 available to use for event delivery. These interrupts cannot
be masked, as long as the OTG is active.

[How]

Switch to vline2 for vblank handling. Today, DC will program the
vline2 position to at vupdate -- the point at which HW latches to
double-buffered registers.

Since all the vline interrupt types share the same interrupt src_id,
refactor the existing vline0 infrastructure to allow for all the vline0,
1, and 2 types.

Since this is intended to replace vstartup for DCN, use the same handler
logic, but be careful to leave DCE on vstartup.

Signed-off-by: Leo Li 
---
  drivers/gpu/drm/amd/amdgpu/amdgpu.h   |   2 +-
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 165 --
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   9 +
  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c|  20 ++-
  .../drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c |  99 +--
  .../drm/amd/display/amdgpu_dm/amdgpu_dm_irq.h |   7 +
  .../display/dc/irq/dcn10/irq_service_dcn10.c  |  44 +++--
  .../display/dc/irq/dcn20/irq_service_dcn20.c  |  43 +++--
  .../dc/irq/dcn201/irq_service_dcn201.c|  24 ++-
  .../display/dc/irq/dcn21/irq_service_dcn21.c  |  44 +++--
  .../display/dc/irq/dcn30/irq_service_dcn30.c  |  44 +++--
  .../dc/irq/dcn302/irq_service_dcn302.c|  43 +++--
  .../dc/irq/dcn303/irq_service_dcn303.c|  24 ++-
  .../display/dc/irq/dcn31/irq_service_dcn31.c  |  44 +++--
  .../dc/irq/dcn314/irq_service_dcn314.c|  44 +++--
  .../dc/irq/dcn315/irq_service_dcn315.c|  44 +++--
  .../display/dc/irq/dcn32/irq_service_dcn32.c  |  26 +--
  .../display/dc/irq/dcn35/irq_service_dcn35.c  |  41 +++--
  .../dc/irq/dcn351/irq_service_dcn351.c|  43 +++--
  .../display/dc/irq/dcn36/irq_service_dcn36.c  |  41 +++--
  .../dc/irq/dcn401/irq_service_dcn401.c|  25 +--
  .../display/dc/irq/dcn42/irq_service_dcn42.c  |  26 +--
  .../gpu/drm/amd/display/dc/irq/irq_service.h  |  23 +++
  23 files changed, 673 insertions(+), 252 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 39894e38fee45..0d84293705107 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -947,7 +947,7 @@ struct amdgpu_device {
/* For pre-DCE11. DCE11 and later are in "struct amdgpu_device->dm" */
struct delayed_work hotplug_work;
struct amdgpu_irq_src   crtc_irq;
-   struct amdgpu_irq_src   vline0_irq;
+   struct amdgpu_irq_src   vline_irq;
struct amdgpu_irq_src   vupdate_irq;
struct amdgpu_irq_src   pageflip_irq;
struct amdgpu_irq_src   hpd_irq;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 3fa4dbda4517c..429f8df17c5d1 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -646,7 +646,8 @@ static void dm_vupdate_high_irq(void *interrupt_params)
   * Handles the CRTC/VSYNC interrupt by notfying DRM's VBLANK
   * event handler.
   */
-static void dm_crtc_high_irq(void *interrupt_params)
+static void __dm_crtc_high_irq(void *interrupt_params,
+int otg_inst)
  {
struct common_irq_params *irq_params = interrupt_params;
struct amdgpu_device *adev = irq_params->adev;
@@ -655,7 +656,7 @@ static void dm_crtc_high_irq(void *interrupt_params)
unsigned long flags;
int vrr_active;
  
-	acrtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_VBLANK);

+   acrtc = get_crtc_by_otg_inst(adev, otg_inst);
if (!acrtc)
return;
  
@@ -755,6 +756,13 @@ static void dm_crtc_high_irq(void *interrupt_params)

spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags);
  }
  
+static void dm_crtc_high_irq(void *interrupt_params)

+{
+   struct common_irq_params *irq_params = interrupt_params;
+   __dm_crtc_high_irq(interrupt_params,
+  irq_params->irq_src - DC_IRQ_SOURCE_VBLANK1);
+}
+
  #if 

Re: [PATCH] drm/amd/display: Use vline2 interrupt on DCN instead of vstartup

2026-05-07 Thread Leo Li



On 2026-05-06 18:03, Timur Kristóf wrote:
> Thanks for the explanation.
> Just one more question: does DCN always mask the VSTARTUP interrupt under 
> those conditions or is that configurable?

AFAIK, yes. The masking is part of HW operation and not something we can
toggle (short of disabling the features that cause the masking conditions)

- Leo


Re: [PATCH] drm/amd/display: Use vline2 interrupt on DCN instead of vstartup

2026-05-07 Thread Shengyu Qu


在 2026/5/7 06:03, Timur Kristóf 写道:

On Wednesday, May 6, 2026 10:00:12 PM Central European Summer Time Leo Li
wrote:

On 2026-05-04 16:54, Timur Kristóf wrote:

On Monday, May 4, 2026 8:36:49 PM Central European Summer Time

[email protected] wrote:

From: Leo Li

[Why]

VStartup is an OTG event that fires when the pixel pipeline prepares for
pixel scanout of the next frame. It was previously used to deliver
vblank events for commits that do not trigger a fb address update, and
hence a pflip interrupt (hw cursor updates, for example).

The issue with vstartup is that HW can mask the interrupt in cases where
idle optimizations are enabled or when a HW lock is active. This could
the explain the range of flip_done timeouts frequently seen in the wild.

Can you help me understand how that could happen with vstartup?
Specifically, what is a "HW lock" and when is it active?

Hi Timur,

I should've prefaced this patch to say that this is a theoretical fix. I
haven't been able to reproduce the timeout issues myself, and this patch
came out of internal discussions with folks more familiar with the HW. I
don't think this will fix *all* cases of flip_done timeouts, but it may
address some of them.

I see.
Yeah, I've only very rarely seen that issue myself. Seems that the bug avoids
driver devs, but it's very popular among end users.


Btw according to Michele's test result, such issue would be hidden by

debug options due to code running slower:

https://lore.kernel.org/amd-gfx/[email protected]/



(But timeouts aside, we *should* transition to vline since it's more
reliable than vstartup.)

I agree.


To answer your questions: depending on the DCN generation, there can be a
few things that affects vstartup firing:

* 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 thru drm_vblank_off) Once gated, even though the
OTG (output timing generator) is still enabled, vstartup is masked. vline
is unaffected.

* 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, but vline is
unaffected. 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, vline is unaffected.

Thanks for the explanation.
Just one more question: does DCN always mask the VSTARTUP interrupt under
those conditions or is that configurable?


Many users have experienced flip_done timeouts while playing games.
In that scenario, would any idle optimization be enabled or is there a "HW
lock"?

If the game stops submitting frames for ~15 refresh cycles, it's possible
that PSR kicks in. Though I know there are plenty of reporters running on
external without PSR support. If it's DGPUs, it's very likely due to MALL.
A reporter I was debugging with said disabling MALL showed good results[1].
If it's an APU with an external monitor, then that's less clear.

A lot of the reporters seem to be running Phoenix (DCN314), with a common
symptom of DMUB timing out[2]. If a self-refresh panel is involved, then I'm
curious if this vline2 patch would help. Hamza's recent patch[3] that
enables various levels of reset may help to mitigate, but it doesn't fix
the root-cause. I'm planning a branch with this patch and [3], along with
debug dumps on flip_done timeouts for reporters to try.


That's very nice to hear. I'm crossing my fingers that it works out.


[1]https://lore.kernel.org/amd-gfx/e415c38b-4102-40e4-a195-0256caf34802@m1k.
cloud/ [2]https://gitlab.freedesktop.org/drm/amd/-/work_items/4831
[3]https://lore.kernel.org/lkml/20260505182105.420525-2-someguy@effective-li
ght.com/

DCN hardware provides 3 generic OTG interrupts that can be programmed
to>> fire on a specific line. Vline 0 and 1 are currently reserved, with
vline2 available to use for event delivery. These interrupts cannot be
masked, as long as the OTG is active.

[How]

Switch to vline2 for vblank handling. Today, DC will program the
vline2 position to at vupdate -- the point at which HW latches to
double-buffered registers.

Since all the vline interrupt types share the same interrupt src_id,
refactor the existing vline0 infrastructure to allow for all the vline0,
1, and 2 types.

Since this is intended to replace vstartup for DCN, use the same handler
logic, but be careful to leave DCE on vstartup.

Why not also switch DCE?
Does DCE not have the vline interrupts or does it not have the same issue
with the vstartup interrupt?

I didn't want to touch DCE since I don't have information on how these
interrupts behave on them, and I didn't want to regress anything. Would need
to do some digging to find out.


Do we have any reports of these page flip timeouts on DCE?

Re: [PATCH] drm/amd/display: Use vline2 interrupt on DCN instead of vstartup

2026-05-06 Thread Timur Kristóf
On Wednesday, May 6, 2026 10:00:12 PM Central European Summer Time Leo Li 
wrote:
> On 2026-05-04 16:54, Timur Kristóf wrote:
> > On Monday, May 4, 2026 8:36:49 PM Central European Summer Time
> > 
> > [email protected] wrote:
> >> From: Leo Li 
> >> 
> >> [Why]
> >> 
> >> VStartup is an OTG event that fires when the pixel pipeline prepares for
> >> pixel scanout of the next frame. It was previously used to deliver
> >> vblank events for commits that do not trigger a fb address update, and
> >> hence a pflip interrupt (hw cursor updates, for example).
> >> 
> >> The issue with vstartup is that HW can mask the interrupt in cases where
> >> idle optimizations are enabled or when a HW lock is active. This could
> >> the explain the range of flip_done timeouts frequently seen in the wild.
> > 
> > Can you help me understand how that could happen with vstartup?
> > Specifically, what is a "HW lock" and when is it active?
> 
> Hi Timur,
> 
> I should've prefaced this patch to say that this is a theoretical fix. I
> haven't been able to reproduce the timeout issues myself, and this patch
> came out of internal discussions with folks more familiar with the HW. I
> don't think this will fix *all* cases of flip_done timeouts, but it may
> address some of them.

I see.
Yeah, I've only very rarely seen that issue myself. Seems that the bug avoids 
driver devs, but it's very popular among end users.

> 
> (But timeouts aside, we *should* transition to vline since it's more
> reliable than vstartup.)

I agree.

> 
> To answer your questions: depending on the DCN generation, there can be a
> few things that affects vstartup firing:
> 
> * 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 thru drm_vblank_off) Once gated, even though the
> OTG (output timing generator) is still enabled, vstartup is masked. vline
> is unaffected.
> 
> * 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, but vline is
> unaffected. 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, vline is unaffected.

Thanks for the explanation.
Just one more question: does DCN always mask the VSTARTUP interrupt under 
those conditions or is that configurable?

> 
> > Many users have experienced flip_done timeouts while playing games.
> > In that scenario, would any idle optimization be enabled or is there a "HW
> > lock"?
> 
> If the game stops submitting frames for ~15 refresh cycles, it's possible
> that PSR kicks in. Though I know there are plenty of reporters running on
> external without PSR support. If it's DGPUs, it's very likely due to MALL.
> A reporter I was debugging with said disabling MALL showed good results[1].
> If it's an APU with an external monitor, then that's less clear.
> 
> A lot of the reporters seem to be running Phoenix (DCN314), with a common
> symptom of DMUB timing out[2]. If a self-refresh panel is involved, then I'm
> curious if this vline2 patch would help. Hamza's recent patch[3] that
> enables various levels of reset may help to mitigate, but it doesn't fix
> the root-cause. I'm planning a branch with this patch and [3], along with
> debug dumps on flip_done timeouts for reporters to try.
> 

That's very nice to hear. I'm crossing my fingers that it works out.

> [1]https://lore.kernel.org/amd-gfx/e415c38b-4102-40e4-a195-0256caf34802@m1k.
> cloud/ [2]https://gitlab.freedesktop.org/drm/amd/-/work_items/4831
> [3]https://lore.kernel.org/lkml/20260505182105.420525-2-someguy@effective-li
> ght.com/
> >> DCN hardware provides 3 generic OTG interrupts that can be programmed
> >> to>> fire on a specific line. Vline 0 and 1 are currently reserved, with
> >> vline2 available to use for event delivery. These interrupts cannot be
> >> masked, as long as the OTG is active.
> >> 
> >> [How]
> >> 
> >> Switch to vline2 for vblank handling. Today, DC will program the
> >> vline2 position to at vupdate -- the point at which HW latches to
> >> double-buffered registers.
> >> 
> >> Since all the vline interrupt types share the same interrupt src_id,
> >> refactor the existing vline0 infrastructure to allow for all the vline0,
> >> 1, and 2 types.
> >> 
> >> Since this is intended to replace vstartup for DCN, use the same handler
> >> logic, but be careful to leave DCE on vstartup.
> > 
> > Why not also switch DCE?
> > Does DCE not have the vline interrupts or does it not have the same issue
> > with the vstartup interrupt?
> 
> I didn't want to touch DCE since I don't have information on how these
> interrupts behave on them, and I didn't want to regress anything. Would need
> to do some digging to find out.

Re: [PATCH] drm/amd/display: Use vline2 interrupt on DCN instead of vstartup

2026-05-06 Thread Timur Kristóf
On Wednesday, May 6, 2026 10:32:16 PM Central European Summer Time Harry 
Wentland wrote:
> On 2026-05-06 16:00, Leo Li wrote:
> > On 2026-05-04 16:54, Timur Kristóf wrote:
> >> On Monday, May 4, 2026 8:36:49 PM Central European Summer Time
> >> 
> >> [email protected] wrote:
> >>> From: Leo Li 
> >>> 
> >>> [Why]
> >>> 
> >>> VStartup is an OTG event that fires when the pixel pipeline prepares for
> >>> pixel scanout of the next frame. It was previously used to deliver
> >>> vblank events for commits that do not trigger a fb address update, and
> >>> hence a pflip interrupt (hw cursor updates, for example).
> >>> 
> >>> The issue with vstartup is that HW can mask the interrupt in cases where
> >>> idle optimizations are enabled or when a HW lock is active. This could
> >>> the explain the range of flip_done timeouts frequently seen in the wild.
> >> 
> >> Can you help me understand how that could happen with vstartup?
> >> Specifically, what is a "HW lock" and when is it active?
> > 
> > Hi Timur,
> > 
> > I should've prefaced this patch to say that this is a theoretical fix. I
> > haven't been able to reproduce the timeout issues myself, and this patch
> > came out of internal discussions with folks more familiar with the HW. I
> > don't think this will fix *all* cases of flip_done timeouts, but it may
> > address some of them.
> > 
> > (But timeouts aside, we *should* transition to vline since it's more
> > reliable than vstartup.)
> > 
> > To answer your questions: depending on the DCN generation, there can be a
> > few things that affects vstartup firing:
> > 
> > * 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 thru drm_vblank_off) Once gated, even though the
> >   OTG (output timing generator) is still enabled, vstartup is masked.
> >   vline is unaffected.
> > 
> > * 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,
> >   but vline is unaffected. 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, vline is unaffected.
> >> 
> >> Many users have experienced flip_done timeouts while playing games.
> >> In that scenario, would any idle optimization be enabled or is there a
> >> "HW
> >> lock"?
> > 
> > If the game stops submitting frames for ~15 refresh cycles, it's possible
> > that PSR kicks in. Though I know there are plenty of reporters running on
> > external without PSR support. If it's DGPUs, it's very likely due to
> > MALL. A reporter I was debugging with said disabling MALL showed good
> > results[1]. If it's an APU with an external monitor, then that's less
> > clear.
> > 
> > A lot of the reporters seem to be running Phoenix (DCN314), with a common
> > symptom of DMUB timing out[2]. If a self-refresh panel is involved, then
> > I'm curious if this vline2 patch would help. Hamza's recent patch[3] that
> > enables various levels of reset may help to mitigate, but it doesn't fix
> > the root-cause. I'm planning a branch with this patch and [3], along with
> > debug dumps on flip_done timeouts for reporters to try.
> > 
> > [1]https://lore.kernel.org/amd-gfx/e415c38b-4102-40e4-a195-0256caf34802@m1
> > k.cloud/ [2]https://gitlab.freedesktop.org/drm/amd/-/work_items/4831
> > [3]https://lore.kernel.org/lkml/20260505182105.420525-2-someguy@effective-> 
> > > light.com/> 
> >>> DCN hardware provides 3 generic OTG interrupts that can be programmed
> >>> to>> fire on a specific line. Vline 0 and 1 are currently reserved,
> >>> with vline2 available to use for event delivery. These interrupts
> >>> cannot be masked, as long as the OTG is active.
> >>> 
> >>> [How]
> >>> 
> >>> Switch to vline2 for vblank handling. Today, DC will program the
> >>> vline2 position to at vupdate -- the point at which HW latches to
> >>> double-buffered registers.
> >>> 
> >>> Since all the vline interrupt types share the same interrupt src_id,
> >>> refactor the existing vline0 infrastructure to allow for all the vline0,
> >>> 1, and 2 types.
> >>> 
> >>> Since this is intended to replace vstartup for DCN, use the same handler
> >>> logic, but be careful to leave DCE on vstartup.
> >> 
> >> Why not also switch DCE?
> >> Does DCE not have the vline interrupts or does it not have the same issue
> >> with the vstartup interrupt?
> > 
> > I didn't want to touch DCE since I don't have information on how these
> > interrupts behave on them, and I didn't want to regress anything. Would
> > need to do some digging to find out.
> 
> DCE's architecture is quite different in this regard. No VSTARTUP, VUPDATE
> signals and interrupts on DCE.
> 

Hi 

Re: [PATCH] drm/amd/display: Use vline2 interrupt on DCN instead of vstartup

2026-05-06 Thread Harry Wentland



On 2026-05-06 16:00, Leo Li wrote:
> 
> 
> On 2026-05-04 16:54, Timur Kristóf wrote:
>> On Monday, May 4, 2026 8:36:49 PM Central European Summer Time 
>> [email protected] wrote:
>>> From: Leo Li 
>>>
>>> [Why]
>>>
>>> VStartup is an OTG event that fires when the pixel pipeline prepares for
>>> pixel scanout of the next frame. It was previously used to deliver
>>> vblank events for commits that do not trigger a fb address update, and
>>> hence a pflip interrupt (hw cursor updates, for example).
>>>
>>> The issue with vstartup is that HW can mask the interrupt in cases where
>>> idle optimizations are enabled or when a HW lock is active. This could
>>> the explain the range of flip_done timeouts frequently seen in the wild.
>> Can you help me understand how that could happen with vstartup?
>> Specifically, what is a "HW lock" and when is it active?
> 
> Hi Timur,
> 
> I should've prefaced this patch to say that this is a theoretical fix. I 
> haven't
> been able to reproduce the timeout issues myself, and this patch came out of
> internal discussions with folks more familiar with the HW. I don't think this
> will fix *all* cases of flip_done timeouts, but it may address some of them.
> 
> (But timeouts aside, we *should* transition to vline since it's more reliable
> than vstartup.)
> 
> To answer your questions: depending on the DCN generation, there can be a few
> things that affects vstartup firing:
> 
> * 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 thru drm_vblank_off) Once gated, even though the OTG
>   (output timing generator) is still enabled, vstartup is masked. vline is
>   unaffected.
> 
> * 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, but vline is
>   unaffected. 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, vline is unaffected.
> 
>>
>> Many users have experienced flip_done timeouts while playing games.
>> In that scenario, would any idle optimization be enabled or is there a "HW 
>> lock"?
> 
> If the game stops submitting frames for ~15 refresh cycles, it's possible that
> PSR kicks in. Though I know there are plenty of reporters running on external
> without PSR support. If it's DGPUs, it's very likely due to MALL. A reporter I
> was debugging with said disabling MALL showed good results[1]. If it's an APU
> with an external monitor, then that's less clear.
> 
> A lot of the reporters seem to be running Phoenix (DCN314), with a common
> symptom of DMUB timing out[2]. If a self-refresh panel is involved, then I'm
> curious if this vline2 patch would help. Hamza's recent patch[3] that enables
> various levels of reset may help to mitigate, but it doesn't fix the 
> root-cause.
> I'm planning a branch with this patch and [3], along with debug dumps on
> flip_done timeouts for reporters to try.
> 
> [1]https://lore.kernel.org/amd-gfx/[email protected]/
> [2]https://gitlab.freedesktop.org/drm/amd/-/work_items/4831
> [3]https://lore.kernel.org/lkml/[email protected]/
> 
>>
>>> DCN hardware provides 3 generic OTG interrupts that can be programmed to>> 
>>> fire on a specific line. Vline 0 and 1 are currently reserved, with
>>> vline2 available to use for event delivery. These interrupts cannot
>>> be masked, as long as the OTG is active.
>>>
>>> [How]
>>>
>>> Switch to vline2 for vblank handling. Today, DC will program the
>>> vline2 position to at vupdate -- the point at which HW latches to
>>> double-buffered registers.
>>>
>>> Since all the vline interrupt types share the same interrupt src_id,
>>> refactor the existing vline0 infrastructure to allow for all the vline0,
>>> 1, and 2 types.
>>>
>>> Since this is intended to replace vstartup for DCN, use the same handler
>>> logic, but be careful to leave DCE on vstartup.
>> Why not also switch DCE?
>> Does DCE not have the vline interrupts or does it not have the same issue 
>> with 
>> the vstartup interrupt?
> 
> I didn't want to touch DCE since I don't have information on how these
> interrupts behave on them, and I didn't want to regress anything. Would need 
> to
> do some digging to find out.
> 

DCE's architecture is quite different in this regard. No VSTARTUP, VUPDATE
signals and interrupts on DCE.

Harry

> - Leo
> 
>>
>>> Signed-off-by: Leo Li 
>> I think this patch should have a "Fixes:" tag or another way to indicate 
>> that 
>> it should be backported to stable kernels.
>>
>> Thanks,
>> Timur
> 



Re: [PATCH] drm/amd/display: Use vline2 interrupt on DCN instead of vstartup

2026-05-06 Thread Leo Li



On 2026-05-04 16:54, Timur Kristóf wrote:
> On Monday, May 4, 2026 8:36:49 PM Central European Summer Time 
> [email protected] wrote:
>> From: Leo Li 
>>
>> [Why]
>>
>> VStartup is an OTG event that fires when the pixel pipeline prepares for
>> pixel scanout of the next frame. It was previously used to deliver
>> vblank events for commits that do not trigger a fb address update, and
>> hence a pflip interrupt (hw cursor updates, for example).
>>
>> The issue with vstartup is that HW can mask the interrupt in cases where
>> idle optimizations are enabled or when a HW lock is active. This could
>> the explain the range of flip_done timeouts frequently seen in the wild.
> Can you help me understand how that could happen with vstartup?
> Specifically, what is a "HW lock" and when is it active?

Hi Timur,

I should've prefaced this patch to say that this is a theoretical fix. I haven't
been able to reproduce the timeout issues myself, and this patch came out of
internal discussions with folks more familiar with the HW. I don't think this
will fix *all* cases of flip_done timeouts, but it may address some of them.

(But timeouts aside, we *should* transition to vline since it's more reliable
than vstartup.)

To answer your questions: depending on the DCN generation, there can be a few
things that affects vstartup firing:

* 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 thru drm_vblank_off) Once gated, even though the OTG
  (output timing generator) is still enabled, vstartup is masked. vline is
  unaffected.

* 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, but vline is
  unaffected. 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, vline is unaffected.

> 
> Many users have experienced flip_done timeouts while playing games.
> In that scenario, would any idle optimization be enabled or is there a "HW 
> lock"?

If the game stops submitting frames for ~15 refresh cycles, it's possible that
PSR kicks in. Though I know there are plenty of reporters running on external
without PSR support. If it's DGPUs, it's very likely due to MALL. A reporter I
was debugging with said disabling MALL showed good results[1]. If it's an APU
with an external monitor, then that's less clear.

A lot of the reporters seem to be running Phoenix (DCN314), with a common
symptom of DMUB timing out[2]. If a self-refresh panel is involved, then I'm
curious if this vline2 patch would help. Hamza's recent patch[3] that enables
various levels of reset may help to mitigate, but it doesn't fix the root-cause.
I'm planning a branch with this patch and [3], along with debug dumps on
flip_done timeouts for reporters to try.

[1]https://lore.kernel.org/amd-gfx/[email protected]/
[2]https://gitlab.freedesktop.org/drm/amd/-/work_items/4831
[3]https://lore.kernel.org/lkml/[email protected]/

> 
>> DCN hardware provides 3 generic OTG interrupts that can be programmed to>> 
>> fire on a specific line. Vline 0 and 1 are currently reserved, with
>> vline2 available to use for event delivery. These interrupts cannot
>> be masked, as long as the OTG is active.
>>
>> [How]
>>
>> Switch to vline2 for vblank handling. Today, DC will program the
>> vline2 position to at vupdate -- the point at which HW latches to
>> double-buffered registers.
>>
>> Since all the vline interrupt types share the same interrupt src_id,
>> refactor the existing vline0 infrastructure to allow for all the vline0,
>> 1, and 2 types.
>>
>> Since this is intended to replace vstartup for DCN, use the same handler
>> logic, but be careful to leave DCE on vstartup.
> Why not also switch DCE?
> Does DCE not have the vline interrupts or does it not have the same issue 
> with 
> the vstartup interrupt?

I didn't want to touch DCE since I don't have information on how these
interrupts behave on them, and I didn't want to regress anything. Would need to
do some digging to find out.

- Leo

> 
>> Signed-off-by: Leo Li 
> I think this patch should have a "Fixes:" tag or another way to indicate that 
> it should be backported to stable kernels.
> 
> Thanks,
> Timur



Re: [PATCH] drm/amd/display: Use vline2 interrupt on DCN instead of vstartup

2026-05-04 Thread Timur Kristóf
On Monday, May 4, 2026 8:36:49 PM Central European Summer Time 
[email protected] wrote:
> From: Leo Li 
> 
> [Why]
> 
> VStartup is an OTG event that fires when the pixel pipeline prepares for
> pixel scanout of the next frame. It was previously used to deliver
> vblank events for commits that do not trigger a fb address update, and
> hence a pflip interrupt (hw cursor updates, for example).
> 
> The issue with vstartup is that HW can mask the interrupt in cases where
> idle optimizations are enabled or when a HW lock is active. This could
> the explain the range of flip_done timeouts frequently seen in the wild.

Can you help me understand how that could happen with vstartup?
Specifically, what is a "HW lock" and when is it active?

Many users have experienced flip_done timeouts while playing games.
In that scenario, would any idle optimization be enabled or is there a "HW 
lock"?

> DCN hardware provides 3 generic OTG interrupts that can be programmed to
> fire on a specific line. Vline 0 and 1 are currently reserved, with
> vline2 available to use for event delivery. These interrupts cannot
> be masked, as long as the OTG is active.
> 
> [How]
> 
> Switch to vline2 for vblank handling. Today, DC will program the
> vline2 position to at vupdate -- the point at which HW latches to
> double-buffered registers.
> 
> Since all the vline interrupt types share the same interrupt src_id,
> refactor the existing vline0 infrastructure to allow for all the vline0,
> 1, and 2 types.
> 
> Since this is intended to replace vstartup for DCN, use the same handler
> logic, but be careful to leave DCE on vstartup.

Why not also switch DCE?
Does DCE not have the vline interrupts or does it not have the same issue with 
the vstartup interrupt?

> 
> Signed-off-by: Leo Li 

I think this patch should have a "Fixes:" tag or another way to indicate that 
it should be backported to stable kernels.

Thanks,
Timur

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h   |   2 +-
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 165 --
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   9 +
>  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c|  20 ++-
>  .../drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c |  99 +--
>  .../drm/amd/display/amdgpu_dm/amdgpu_dm_irq.h |   7 +
>  .../display/dc/irq/dcn10/irq_service_dcn10.c  |  44 +++--
>  .../display/dc/irq/dcn20/irq_service_dcn20.c  |  43 +++--
>  .../dc/irq/dcn201/irq_service_dcn201.c|  24 ++-
>  .../display/dc/irq/dcn21/irq_service_dcn21.c  |  44 +++--
>  .../display/dc/irq/dcn30/irq_service_dcn30.c  |  44 +++--
>  .../dc/irq/dcn302/irq_service_dcn302.c|  43 +++--
>  .../dc/irq/dcn303/irq_service_dcn303.c|  24 ++-
>  .../display/dc/irq/dcn31/irq_service_dcn31.c  |  44 +++--
>  .../dc/irq/dcn314/irq_service_dcn314.c|  44 +++--
>  .../dc/irq/dcn315/irq_service_dcn315.c|  44 +++--
>  .../display/dc/irq/dcn32/irq_service_dcn32.c  |  26 +--
>  .../display/dc/irq/dcn35/irq_service_dcn35.c  |  41 +++--
>  .../dc/irq/dcn351/irq_service_dcn351.c|  43 +++--
>  .../display/dc/irq/dcn36/irq_service_dcn36.c  |  41 +++--
>  .../dc/irq/dcn401/irq_service_dcn401.c|  25 +--
>  .../display/dc/irq/dcn42/irq_service_dcn42.c  |  26 +--
>  .../gpu/drm/amd/display/dc/irq/irq_service.h  |  23 +++
>  23 files changed, 673 insertions(+), 252 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 39894e38fee45..0d84293705107
> 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -947,7 +947,7 @@ struct amdgpu_device {
>   /* For pre-DCE11. DCE11 and later are in "struct amdgpu_device-
>dm" */
>   struct delayed_work hotplug_work;
>   struct amdgpu_irq_src   crtc_irq;
> - struct amdgpu_irq_src   vline0_irq;
> + struct amdgpu_irq_src   vline_irq;
>   struct amdgpu_irq_src   vupdate_irq;
>   struct amdgpu_irq_src   pageflip_irq;
>   struct amdgpu_irq_src   hpd_irq;
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index
> 3fa4dbda4517c..429f8df17c5d1 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -646,7 +646,8 @@ static void dm_vupdate_high_irq(void *interrupt_params)
>   * Handles the CRTC/VSYNC interrupt by notfying DRM's VBLANK
>   * event handler.
>   */
> -static void dm_crtc_high_irq(void *interrupt_params)
> +static void __dm_crtc_high_irq(void *interrupt_params,
> +  int otg_inst)
>  {
>   struct common_irq_params *irq_params = interrupt_params;
>   struct amdgpu_device *adev = irq_params->adev;
> @@ -655,7 +656,7 @@ static void dm_crtc_high_irq(void *interrupt_params)
>   unsigned long flags;
>   int vrr_active;
> 
> - acrtc =