diff mbox series

[2/3] drm/i915/dsb: Fix DSB vblank waits when using VRR

Message ID 20240306040806.21697-3-ville.syrjala@linux.intel.com (mailing list archive)
State New, archived
Headers show
Series drm/i915: Fix DSB vblank waits with VRR | expand

Commit Message

Ville Syrjälä March 6, 2024, 4:08 a.m. UTC
From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Looks like the undelayed vblank gets signalled exactly when
the active period ends. That is a problem for DSB+VRR when
we are already in vblank and expect DSB to start executing
as soon as we send the push. Instead of starting the DSB
just keeps on waiting for the undelayed vblank which won't
signal until the end of the next frame's active period,
which is far too late.

The end result is that DSB won't have even started
executing by the time the flips/etc. have completed.
We then wait for an extra 1ms, after which we terminate
the DSB and report a timeout:
[drm] *ERROR* [CRTC:80:pipe A] DSB 0 timed out waiting for idle (current head=0xfedf4000, head=0x0, tail=0x1080)

To fix this let's configure DSB to use the so called VRR
"safe window" instead of the undelayed vblank to trigger
the DSB vblank logic, when VRR is enabled.

Cc: stable@vger.kernel.org
Fixes: 34d8311f4a1c ("drm/i915/dsb: Re-instate DSB for LUT updates")
Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/9927
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_dsb.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

Comments

Animesh Manna March 6, 2024, 12:26 p.m. UTC | #1
> -----Original Message-----
> From: Intel-gfx <intel-gfx-bounces@lists.freedesktop.org> On Behalf Of Ville
> Syrjala
> Sent: Wednesday, March 6, 2024 9:38 AM
> To: intel-gfx@lists.freedesktop.org
> Cc: stable@vger.kernel.org
> Subject: [PATCH 2/3] drm/i915/dsb: Fix DSB vblank waits when using VRR
> 
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Looks like the undelayed vblank gets signalled exactly when the active period
> ends. That is a problem for DSB+VRR when we are already in vblank and
> expect DSB to start executing as soon as we send the push. Instead of
> starting the DSB just keeps on waiting for the undelayed vblank which won't
> signal until the end of the next frame's active period, which is far too late.
> 
> The end result is that DSB won't have even started executing by the time the
> flips/etc. have completed.
> We then wait for an extra 1ms, after which we terminate the DSB and report
> a timeout:
> [drm] *ERROR* [CRTC:80:pipe A] DSB 0 timed out waiting for idle (current
> head=0xfedf4000, head=0x0, tail=0x1080)
> 
> To fix this let's configure DSB to use the so called VRR "safe window" instead
> of the undelayed vblank to trigger the DSB vblank logic, when VRR is enabled.
> 
> Cc: stable@vger.kernel.org
> Fixes: 34d8311f4a1c ("drm/i915/dsb: Re-instate DSB for LUT updates")
> Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/9927
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

LGTM.
Reviewed-by: Animesh Manna <animesh.manna@intel.com>

> ---
>  drivers/gpu/drm/i915/display/intel_dsb.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c
> b/drivers/gpu/drm/i915/display/intel_dsb.c
> index d62e050185e7..e4515bf92038 100644
> --- a/drivers/gpu/drm/i915/display/intel_dsb.c
> +++ b/drivers/gpu/drm/i915/display/intel_dsb.c
> @@ -340,6 +340,17 @@ static int intel_dsb_dewake_scanline(const struct
> intel_crtc_state *crtc_state)
>  	return max(0, vblank_start -
> intel_usecs_to_scanlines(adjusted_mode, latency));  }
> 
> +static u32 dsb_chicken(struct intel_crtc *crtc) {
> +	if (crtc->mode_flags & I915_MODE_FLAG_VRR)
> +		return DSB_CTRL_WAIT_SAFE_WINDOW |
> +			DSB_CTRL_NO_WAIT_VBLANK |
> +			DSB_INST_WAIT_SAFE_WINDOW |
> +			DSB_INST_NO_WAIT_VBLANK;
> +	else
> +		return 0;
> +}
> +
>  static void _intel_dsb_commit(struct intel_dsb *dsb, u32 ctrl,
>  			      int dewake_scanline)
>  {
> @@ -361,6 +372,9 @@ static void _intel_dsb_commit(struct intel_dsb *dsb,
> u32 ctrl,
>  	intel_de_write_fw(dev_priv, DSB_CTRL(pipe, dsb->id),
>  			  ctrl | DSB_ENABLE);
> 
> +	intel_de_write_fw(dev_priv, DSB_CHICKEN(pipe, dsb->id),
> +			  dsb_chicken(crtc));
> +
>  	intel_de_write_fw(dev_priv, DSB_HEAD(pipe, dsb->id),
>  			  intel_dsb_buffer_ggtt_offset(&dsb->dsb_buf));
> 
> --
> 2.43.0
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c
index d62e050185e7..e4515bf92038 100644
--- a/drivers/gpu/drm/i915/display/intel_dsb.c
+++ b/drivers/gpu/drm/i915/display/intel_dsb.c
@@ -340,6 +340,17 @@  static int intel_dsb_dewake_scanline(const struct intel_crtc_state *crtc_state)
 	return max(0, vblank_start - intel_usecs_to_scanlines(adjusted_mode, latency));
 }
 
+static u32 dsb_chicken(struct intel_crtc *crtc)
+{
+	if (crtc->mode_flags & I915_MODE_FLAG_VRR)
+		return DSB_CTRL_WAIT_SAFE_WINDOW |
+			DSB_CTRL_NO_WAIT_VBLANK |
+			DSB_INST_WAIT_SAFE_WINDOW |
+			DSB_INST_NO_WAIT_VBLANK;
+	else
+		return 0;
+}
+
 static void _intel_dsb_commit(struct intel_dsb *dsb, u32 ctrl,
 			      int dewake_scanline)
 {
@@ -361,6 +372,9 @@  static void _intel_dsb_commit(struct intel_dsb *dsb, u32 ctrl,
 	intel_de_write_fw(dev_priv, DSB_CTRL(pipe, dsb->id),
 			  ctrl | DSB_ENABLE);
 
+	intel_de_write_fw(dev_priv, DSB_CHICKEN(pipe, dsb->id),
+			  dsb_chicken(crtc));
+
 	intel_de_write_fw(dev_priv, DSB_HEAD(pipe, dsb->id),
 			  intel_dsb_buffer_ggtt_offset(&dsb->dsb_buf));