All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Andrzej Hajda <andrzej.hajda@intel.com>
Cc: intel-gfx@lists.freedesktop.org, Rodrigo Vivi <rodrigo.vivi@intel.com>
Subject: Re: [Intel-gfx] [PATCH] drm/i915: implement async_flip mode per plane tracking
Date: Mon, 12 Sep 2022 13:33:54 +0300	[thread overview]
Message-ID: <Yx8LEn86GrAe330+@intel.com> (raw)
In-Reply-To: <20220909140552.110327-1-andrzej.hajda@intel.com>

On Fri, Sep 09, 2022 at 04:05:52PM +0200, Andrzej Hajda wrote:
> Current implementation of async flip w/a relies on assumption that
> previous atomic commit contains valid information if async_flip is still
> enabled on the plane. It is incorrect. If previous commit did not modify
> the plane its state->uapi.async_flip can be false. As a result DMAR/PIPE
> errors can be observed:
> i915 0000:00:02.0: [drm] *ERROR* Fault errors on pipe A: 0x00000080
> i915 0000:00:02.0: [drm] *ERROR* Fault errors on pipe A: 0x00000080
> DMAR: DRHD: handling fault status reg 2
> DMAR: [DMA Read NO_PASID] Request device [00:02.0] fault addr 0x0 [fault reason 0x06] PTE Read access is not set
> 
> Signed-off-by: Andrzej Hajda <andrzej.hajda@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_atomic_plane.c  | 6 ++++++
>  drivers/gpu/drm/i915/display/intel_display.c       | 7 ++++---
>  drivers/gpu/drm/i915/display/intel_display_types.h | 3 +++
>  3 files changed, 13 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> index dd876dbbaa394d..4b4d8427b466c0 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> @@ -591,6 +591,12 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
>  	if (new_plane_state->uapi.visible || old_plane_state->uapi.visible)
>  		new_crtc_state->update_planes |= BIT(plane->id);
>  
> +	if (new_crtc_state->uapi.async_flip && plane->async_flip)
> +		new_crtc_state->async_flip_planes |= BIT(plane->id);
> +	else if (new_plane_state->uapi.visible != old_plane_state->uapi.visible ||
> +		 new_plane_state->uapi.fb != old_plane_state->uapi.fb)
> +		new_crtc_state->async_flip_planes &= ~BIT(plane->id);

We should clear it in intel_plane_set_invisible() and calculate properly
otherwise. Seems this also won't catch anything that happens later in the
modeset (eg. intel_modeset_all_pipes() or skl_{wm,ddb}_add_affected_planes()).

I think there are several scenarios we should try to hit:

1. Keep plane in async flip mode during another plane update
  - ask for async flip on plane 1 to switch it to async flip mode
    (this may still do a sync flip internally)
  - ask async flip on plane 1 again and make sure it really happend async this time
  - sync update on another plane 2 (make sure it doesn't affect cdclk/ddb/etc.)
  - another async flip on plane 1 (should still be in async flip mode and thus
    should again happen async)
2. Switch out of async flip mode on wm/ddb change
  - similar as 1. except we want wm/ddb changes to affect both planes
    and thus plane 1 should exit async flip mode
3. Switch out of async flip mode on cdclk change
  - same as 1. except we want cdclk to trigger a modeset
  - should kick plane 1 out of async flip mode
  - not sure if we can do this w/o affecting wm/ddb as well,
    at least without hacks

4. Keep plane in async flip mode during a modeset on another pipe
  - ask for async flip on plane 1 to switch it to async flip mode
    (this may still do a sync flip internally)
  - ask async flip on plane 1 again and make sure it really happend async this time
  - modeset another pipe (make sure it doesn't trigger anything on the
    first pipe)
  - another async flip on plane 1 (should still be in async flip mode and this be fast)
5. Switch out of async flip on modeset+ddb change
  - same as 4. but have the modeset trigger a ddb reconfiguration for
    both pipes
  - should kick plane 1 out of async flip mode
6. Switch out of async flip on cdclk change change
  - same as 4. but have the modeset do a cdclk change that triggers a modeset
  - should kick plane 1 out of async flip mode
  - again not sure how easy it is to avoid the ddb change as well...

> +
>  	if (new_plane_state->uapi.visible &&
>  	    intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier)) {
>  		new_crtc_state->data_rate_y[plane->id] =
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 72e2091d9fcb59..7bab74b2a4ae2e 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -1292,7 +1292,8 @@ static void intel_crtc_async_flip_disable_wa(struct intel_atomic_state *state,
>  		intel_atomic_get_old_crtc_state(state, crtc);
>  	const struct intel_crtc_state *new_crtc_state =
>  		intel_atomic_get_new_crtc_state(state, crtc);
> -	u8 update_planes = new_crtc_state->update_planes;
> +	u8 disable_async_flip_planes = old_crtc_state->async_flip_planes &
> +				       ~new_crtc_state->async_flip_planes;
>  	const struct intel_plane_state *old_plane_state;
>  	struct intel_plane *plane;
>  	bool need_vbl_wait = false;
> @@ -1301,7 +1302,7 @@ static void intel_crtc_async_flip_disable_wa(struct intel_atomic_state *state,
>  	for_each_old_intel_plane_in_state(state, plane, old_plane_state, i) {
>  		if (plane->need_async_flip_disable_wa &&
>  		    plane->pipe == crtc->pipe &&
> -		    update_planes & BIT(plane->id)) {
> +		    disable_async_flip_planes & BIT(plane->id)) {
>  			/*
>  			 * Apart from the async flip bit we want to
>  			 * preserve the old state for the plane.
> @@ -1418,7 +1419,7 @@ static void intel_pre_plane_update(struct intel_atomic_state *state,
>  	 * WA for platforms where async address update enable bit
>  	 * is double buffered and only latched at start of vblank.
>  	 */
> -	if (old_crtc_state->uapi.async_flip && !new_crtc_state->uapi.async_flip)
> +	if (old_crtc_state->async_flip_planes & ~new_crtc_state->async_flip_planes)
>  		intel_crtc_async_flip_disable_wa(state, crtc);
>  }
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 0da9b208d56e8b..b37891a8def780 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1234,6 +1234,9 @@ struct intel_crtc_state {
>  	/* bitmask of planes that will be updated during the commit */
>  	u8 update_planes;
>  
> +	/* bitmask of planes with async flip active */
> +	u8 async_flip_planes;
> +
>  	u8 framestart_delay; /* 1-4 */
>  	u8 msa_timing_delay; /* 0-3 */
>  
> -- 
> 2.34.1

-- 
Ville Syrjälä
Intel

      parent reply	other threads:[~2022-09-12 10:34 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-09 14:05 [Intel-gfx] [PATCH] drm/i915: implement async_flip mode per plane tracking Andrzej Hajda
2022-09-09 17:43 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for " Patchwork
2022-09-09 17:56 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2022-09-10  0:02 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork
2022-09-12 10:33 ` Ville Syrjälä [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Yx8LEn86GrAe330+@intel.com \
    --to=ville.syrjala@linux.intel.com \
    --cc=andrzej.hajda@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=rodrigo.vivi@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.