diff mbox series

[v9,3/3] drm/i915/display: Add i915 hook for format_mod_supported_async

Message ID 20250319-asyn-v9-3-629d1ece63e7@intel.com (mailing list archive)
State New
Headers show
Series Expose modifiers/formats supported by async flips | expand

Commit Message

Arun R Murthy March 19, 2025, 10:32 a.m. UTC
Hook up the newly added plane function pointer
format_mod_supported_async to populate the modifiers/formats supported
by asynchronous flips.

v5: Correct the if condition for modifier support check (Chaitanya)
v6: Replace uint32_t/uint64_t with u32/u64 (Jani)
v7: Move plannar check from intel_async_flip_check_hw() to
intel_plane_format_mod_supported_async() (Ville)
v8: In case of error print format/modifier (Chaitanya)
v9: Exclude C8 format as its not supported by hardware

Signed-off-by: Arun R Murthy <arun.r.murthy@intel.com>
---
 drivers/gpu/drm/i915/display/i9xx_plane.c          |  6 ++--
 drivers/gpu/drm/i915/display/intel_atomic_plane.c  | 32 +++++++++++++++++++++-
 drivers/gpu/drm/i915/display/intel_atomic_plane.h  |  6 +++-
 drivers/gpu/drm/i915/display/intel_display.c       | 14 +++-------
 drivers/gpu/drm/i915/display/skl_universal_plane.c |  5 +++-
 5 files changed, 48 insertions(+), 15 deletions(-)

Comments

Borah, Chaitanya Kumar March 22, 2025, 9:29 a.m. UTC | #1
> -----Original Message-----
> From: Murthy, Arun R <arun.r.murthy@intel.com>
> Sent: Wednesday, March 19, 2025 4:02 PM
> To: dri-devel@lists.freedesktop.org; intel-gfx@lists.freedesktop.org; intel-
> xe@lists.freedesktop.org
> Cc: Borah, Chaitanya Kumar <chaitanya.kumar.borah@intel.com>; Murthy,
> Arun R <arun.r.murthy@intel.com>
> Subject: [PATCH v9 3/3] drm/i915/display: Add i915 hook for
> format_mod_supported_async
> 
> Hook up the newly added plane function pointer
> format_mod_supported_async to populate the modifiers/formats supported
> by asynchronous flips.
> 
> v5: Correct the if condition for modifier support check (Chaitanya)
> v6: Replace uint32_t/uint64_t with u32/u64 (Jani)
> v7: Move plannar check from intel_async_flip_check_hw() to
> intel_plane_format_mod_supported_async() (Ville)
> v8: In case of error print format/modifier (Chaitanya)
> v9: Exclude C8 format as its not supported by hardware
> 
> Signed-off-by: Arun R Murthy <arun.r.murthy@intel.com>
> ---
>  drivers/gpu/drm/i915/display/i9xx_plane.c          |  6 ++--
>  drivers/gpu/drm/i915/display/intel_atomic_plane.c  | 32
> +++++++++++++++++++++-
> drivers/gpu/drm/i915/display/intel_atomic_plane.h  |  6 +++-
>  drivers/gpu/drm/i915/display/intel_display.c       | 14 +++-------
>  drivers/gpu/drm/i915/display/skl_universal_plane.c |  5 +++-
>  5 files changed, 48 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c
> b/drivers/gpu/drm/i915/display/i9xx_plane.c
> index
> 013295f66d56ec5e919b3a0c904034bf7985986a..6bd09adb8a30ba002ef3342
> 61d7638f398587a3e 100644
> --- a/drivers/gpu/drm/i915/display/i9xx_plane.c
> +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c
> @@ -820,7 +820,7 @@ unsigned int vlv_plane_min_alignment(struct
> intel_plane *plane,  {
>  	struct intel_display *display = to_intel_display(plane);
> 
> -	if (intel_plane_can_async_flip(plane, fb->modifier))
> +	if (intel_plane_can_async_flip(plane, fb->format->format,
> +fb->modifier))
>  		return 256 * 1024;
> 
>  	/* FIXME undocumented so not sure what's actually needed */ @@ -
> 844,7 +844,7 @@ static unsigned int g4x_primary_min_alignment(struct
> intel_plane *plane,  {
>  	struct intel_display *display = to_intel_display(plane);
> 
> -	if (intel_plane_can_async_flip(plane, fb->modifier))
> +	if (intel_plane_can_async_flip(plane, fb->format->format,
> +fb->modifier))
>  		return 256 * 1024;
> 
>  	if (intel_scanout_needs_vtd_wa(display))
> @@ -889,6 +889,7 @@ static const struct drm_plane_funcs i965_plane_funcs
> = {
>  	.atomic_duplicate_state = intel_plane_duplicate_state,
>  	.atomic_destroy_state = intel_plane_destroy_state,
>  	.format_mod_supported = i965_plane_format_mod_supported,
> +	.format_mod_supported_async =
> intel_plane_format_mod_supported_async,
>  };
> 
>  static const struct drm_plane_funcs i8xx_plane_funcs = { @@ -898,6 +899,7
> @@ static const struct drm_plane_funcs i8xx_plane_funcs = {
>  	.atomic_duplicate_state = intel_plane_duplicate_state,
>  	.atomic_destroy_state = intel_plane_destroy_state,
>  	.format_mod_supported = i8xx_plane_format_mod_supported,
> +	.format_mod_supported_async =
> intel_plane_format_mod_supported_async,
>  };
> 
>  struct intel_plane *
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> index
> 7276179df878658b7053fe6d8dc37b69f19625e3..ce6bf6fe8f241a9517e8f74fb0
> 02b835c3f0853a 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> @@ -174,11 +174,41 @@ bool intel_plane_needs_physical(struct intel_plane
> *plane)
>  		DISPLAY_INFO(display)->cursor_needs_physical;
>  }
> 
> -bool intel_plane_can_async_flip(struct intel_plane *plane, u64 modifier)
> +bool intel_plane_can_async_flip(struct intel_plane *plane, u32 format,
> +				u64 modifier)
>  {
> +	struct intel_display *display = to_intel_display(plane);
> +
> +	if ((DISPLAY_VER(display) <= 14 ?
> +	    drm_format_info(format)->is_yuv :
> +	    intel_format_info_is_yuv_semiplanar(drm_format_info(format),
> +						modifier)) ||
> +	    format == DRM_FORMAT_C8) {
> +		drm_dbg_kms(plane->base.dev,
> +			    "[PLANE:%d:%s] Planar formats do not support
> async flips\n",
> +			    plane->base.base.id, plane->base.name);

Planar/indexed formats do not support async flips

With this LGTM


Reviewed-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>

> +		return false;
> +	}
> +
>  	return plane->can_async_flip && plane->can_async_flip(modifier);  }
> 
> +bool intel_plane_format_mod_supported_async(struct drm_plane *plane,
> +					    u32 format,
> +					    u64 modifier)
> +{
> +	if (plane->funcs->format_mod_supported &&
> +	    !plane->funcs->format_mod_supported(plane, format, modifier)) {
> +		drm_dbg_kms(plane->dev,
> +			    "[PLANE:%d:%s](format %p4cc) modifier 0x%llx not
> in universal list\n",
> +			    plane->base.id, plane->name, &format, modifier);
> +		return false;
> +	}
> +
> +	return intel_plane_can_async_flip(to_intel_plane(plane),
> +					format, modifier);
> +}
> +
>  unsigned int intel_adjusted_rate(const struct drm_rect *src,
>  				 const struct drm_rect *dst,
>  				 unsigned int rate)
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> index
> 6efac923dcbc757e6f68564cbef2919c920f13cb..512c251cc153753a4808cf177c
> 8bcce2178bb862 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> @@ -21,7 +21,8 @@ enum plane_id;
> 
>  struct intel_plane *
>  intel_crtc_get_plane(struct intel_crtc *crtc, enum plane_id plane_id); -bool
> intel_plane_can_async_flip(struct intel_plane *plane, u64 modifier);
> +bool intel_plane_can_async_flip(struct intel_plane *plane, u32 format,
> +				u64 modifier);
>  unsigned int intel_adjusted_rate(const struct drm_rect *src,
>  				 const struct drm_rect *dst,
>  				 unsigned int rate);
> @@ -87,6 +88,9 @@ void intel_plane_init_cursor_vblank_work(struct
> intel_plane_state *old_plane_sta  int
> intel_atomic_add_affected_planes(struct intel_atomic_state *state,
>  				     struct intel_crtc *crtc);
>  int intel_atomic_check_planes(struct intel_atomic_state *state);
> +bool intel_plane_format_mod_supported_async(struct drm_plane *plane,
> +					    u32 format,
> +					    u64 modifier);
> 
>  u32 intel_plane_ggtt_offset(const struct intel_plane_state *plane_state);
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> b/drivers/gpu/drm/i915/display/intel_display.c
> index
> 3afb85fe8536dfffd55dbaa07f6727112cc876b7..5d0bab1f8ff8294716ca5843c8
> 56032d2b9ccd5b 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -6005,22 +6005,16 @@ static int intel_async_flip_check_hw(struct
> intel_atomic_state *state, struct in
>  		if (!plane->async_flip)
>  			continue;
> 
> -		if (!intel_plane_can_async_flip(plane, new_plane_state-
> >hw.fb->modifier)) {
> +		if (!intel_plane_can_async_flip(plane, new_plane_state-
> >hw.fb->format->format,
> +						new_plane_state->hw.fb-
> >modifier)) {
>  			drm_dbg_kms(display->drm,
> -				    "[PLANE:%d:%s] Modifier 0x%llx does not
> support async flip\n",
> +				    "[PLANE:%d:%s] Format %p4cc Modifier
> 0x%llx does not support
> +async flip\n",
>  				    plane->base.base.id, plane->base.name,
> +				    &new_plane_state->hw.fb->format-
> >format,
>  				    new_plane_state->hw.fb->modifier);
>  			return -EINVAL;
>  		}
> 
> -		if (intel_format_info_is_yuv_semiplanar(new_plane_state-
> >hw.fb->format,
> -							new_plane_state-
> >hw.fb->modifier)) {
> -			drm_dbg_kms(display->drm,
> -				    "[PLANE:%d:%s] Planar formats do not
> support async flips\n",
> -				    plane->base.base.id, plane->base.name);
> -			return -EINVAL;
> -		}
> -
>  		/*
>  		 * We turn the first async flip request into a sync flip
>  		 * so that we can reconfigure the plane (eg. change modifier).
> diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c
> b/drivers/gpu/drm/i915/display/skl_universal_plane.c
> index
> 70e550539bb21393c7173c7b3904e7790eab25f4..f61e1eff30bb4820ccb17daa
> 5d4b2b073a5d4078 100644
> --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
> +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
> @@ -601,7 +601,7 @@ static u32 tgl_plane_min_alignment(struct intel_plane
> *plane,
>  	 * Figure out what's going on here...
>  	 */
>  	if (display->platform.alderlake_p &&
> -	    intel_plane_can_async_flip(plane, fb->modifier))
> +	    intel_plane_can_async_flip(plane, fb->format->format,
> +fb->modifier))
>  		return mult * 16 * 1024;
> 
>  	switch (fb->modifier) {
> @@ -2666,6 +2666,7 @@ static const struct drm_plane_funcs
> skl_plane_funcs = {
>  	.atomic_duplicate_state = intel_plane_duplicate_state,
>  	.atomic_destroy_state = intel_plane_destroy_state,
>  	.format_mod_supported = skl_plane_format_mod_supported,
> +	.format_mod_supported_async =
> intel_plane_format_mod_supported_async,
>  };
> 
>  static const struct drm_plane_funcs icl_plane_funcs = { @@ -2675,6 +2676,7
> @@ static const struct drm_plane_funcs icl_plane_funcs = {
>  	.atomic_duplicate_state = intel_plane_duplicate_state,
>  	.atomic_destroy_state = intel_plane_destroy_state,
>  	.format_mod_supported = icl_plane_format_mod_supported,
> +	.format_mod_supported_async =
> intel_plane_format_mod_supported_async,
>  };
> 
>  static const struct drm_plane_funcs tgl_plane_funcs = { @@ -2684,6 +2686,7
> @@ static const struct drm_plane_funcs tgl_plane_funcs = {
>  	.atomic_duplicate_state = intel_plane_duplicate_state,
>  	.atomic_destroy_state = intel_plane_destroy_state,
>  	.format_mod_supported = tgl_plane_format_mod_supported,
> +	.format_mod_supported_async =
> intel_plane_format_mod_supported_async,
>  };
> 
>  static void
> 
> --
> 2.25.1
Ville Syrjälä March 26, 2025, 5:19 p.m. UTC | #2
On Wed, Mar 19, 2025 at 04:02:17PM +0530, Arun R Murthy wrote:
> Hook up the newly added plane function pointer
> format_mod_supported_async to populate the modifiers/formats supported
> by asynchronous flips.
> 
> v5: Correct the if condition for modifier support check (Chaitanya)
> v6: Replace uint32_t/uint64_t with u32/u64 (Jani)
> v7: Move plannar check from intel_async_flip_check_hw() to
> intel_plane_format_mod_supported_async() (Ville)
> v8: In case of error print format/modifier (Chaitanya)
> v9: Exclude C8 format as its not supported by hardware
> 
> Signed-off-by: Arun R Murthy <arun.r.murthy@intel.com>
> ---
>  drivers/gpu/drm/i915/display/i9xx_plane.c          |  6 ++--
>  drivers/gpu/drm/i915/display/intel_atomic_plane.c  | 32 +++++++++++++++++++++-
>  drivers/gpu/drm/i915/display/intel_atomic_plane.h  |  6 +++-
>  drivers/gpu/drm/i915/display/intel_display.c       | 14 +++-------
>  drivers/gpu/drm/i915/display/skl_universal_plane.c |  5 +++-
>  5 files changed, 48 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c
> index 013295f66d56ec5e919b3a0c904034bf7985986a..6bd09adb8a30ba002ef334261d7638f398587a3e 100644
> --- a/drivers/gpu/drm/i915/display/i9xx_plane.c
> +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c
> @@ -820,7 +820,7 @@ unsigned int vlv_plane_min_alignment(struct intel_plane *plane,
>  {
>  	struct intel_display *display = to_intel_display(plane);
>  
> -	if (intel_plane_can_async_flip(plane, fb->modifier))
> +	if (intel_plane_can_async_flip(plane, fb->format->format, fb->modifier))
>  		return 256 * 1024;
>  
>  	/* FIXME undocumented so not sure what's actually needed */
> @@ -844,7 +844,7 @@ static unsigned int g4x_primary_min_alignment(struct intel_plane *plane,
>  {
>  	struct intel_display *display = to_intel_display(plane);
>  
> -	if (intel_plane_can_async_flip(plane, fb->modifier))
> +	if (intel_plane_can_async_flip(plane, fb->format->format, fb->modifier))
>  		return 256 * 1024;
>  
>  	if (intel_scanout_needs_vtd_wa(display))
> @@ -889,6 +889,7 @@ static const struct drm_plane_funcs i965_plane_funcs = {
>  	.atomic_duplicate_state = intel_plane_duplicate_state,
>  	.atomic_destroy_state = intel_plane_destroy_state,
>  	.format_mod_supported = i965_plane_format_mod_supported,
> +	.format_mod_supported_async = intel_plane_format_mod_supported_async,
>  };
>  
>  static const struct drm_plane_funcs i8xx_plane_funcs = {
> @@ -898,6 +899,7 @@ static const struct drm_plane_funcs i8xx_plane_funcs = {
>  	.atomic_duplicate_state = intel_plane_duplicate_state,
>  	.atomic_destroy_state = intel_plane_destroy_state,
>  	.format_mod_supported = i8xx_plane_format_mod_supported,
> +	.format_mod_supported_async = intel_plane_format_mod_supported_async,
>  };
>  
>  struct intel_plane *
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> index 7276179df878658b7053fe6d8dc37b69f19625e3..ce6bf6fe8f241a9517e8f74fb002b835c3f0853a 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> @@ -174,11 +174,41 @@ bool intel_plane_needs_physical(struct intel_plane *plane)
>  		DISPLAY_INFO(display)->cursor_needs_physical;
>  }
>  
> -bool intel_plane_can_async_flip(struct intel_plane *plane, u64 modifier)
> +bool intel_plane_can_async_flip(struct intel_plane *plane, u32 format,
> +				u64 modifier)

Please split this change into a separate patch.

>  {
> +	struct intel_display *display = to_intel_display(plane);
> +
> +	if ((DISPLAY_VER(display) <= 14 ?
> +	    drm_format_info(format)->is_yuv :
> +	    intel_format_info_is_yuv_semiplanar(drm_format_info(format),
> +						modifier)) ||
> +	    format == DRM_FORMAT_C8) {
> +		drm_dbg_kms(plane->base.dev,
> +			    "[PLANE:%d:%s] Planar formats do not support async flips\n",
> +			    plane->base.base.id, plane->base.name);
> +		return false;

This is introducing functional changes. Those should be separate
patches.

I also don't know what this pre-mtl vs. mtl+ stuff is about. I'm
pretty sure planar formats are the only thing that actually can't do
async flips (in the sense that we can't atomically async flip both
luma and chroma). 

I suppose we may want to reject C8 as well since it depends on
the LUT and we can't update that atomically with an async flip.

> +	}
> +
>  	return plane->can_async_flip && plane->can_async_flip(modifier);
>  }
>  
> +bool intel_plane_format_mod_supported_async(struct drm_plane *plane,
> +					    u32 format,
> +					    u64 modifier)
> +{
> +	if (plane->funcs->format_mod_supported &&
> +	    !plane->funcs->format_mod_supported(plane, format, modifier)) {
> +		drm_dbg_kms(plane->dev,
> +			    "[PLANE:%d:%s](format %p4cc) modifier 0x%llx not in universal list\n",
> +			    plane->base.id, plane->name, &format, modifier);
> +		return false;
> +	}
> +
> +	return intel_plane_can_async_flip(to_intel_plane(plane),
> +					format, modifier);
> +}
> +
>  unsigned int intel_adjusted_rate(const struct drm_rect *src,
>  				 const struct drm_rect *dst,
>  				 unsigned int rate)
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> index 6efac923dcbc757e6f68564cbef2919c920f13cb..512c251cc153753a4808cf177c8bcce2178bb862 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> @@ -21,7 +21,8 @@ enum plane_id;
>  
>  struct intel_plane *
>  intel_crtc_get_plane(struct intel_crtc *crtc, enum plane_id plane_id);
> -bool intel_plane_can_async_flip(struct intel_plane *plane, u64 modifier);
> +bool intel_plane_can_async_flip(struct intel_plane *plane, u32 format,
> +				u64 modifier);
>  unsigned int intel_adjusted_rate(const struct drm_rect *src,
>  				 const struct drm_rect *dst,
>  				 unsigned int rate);
> @@ -87,6 +88,9 @@ void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_sta
>  int intel_atomic_add_affected_planes(struct intel_atomic_state *state,
>  				     struct intel_crtc *crtc);
>  int intel_atomic_check_planes(struct intel_atomic_state *state);
> +bool intel_plane_format_mod_supported_async(struct drm_plane *plane,
> +					    u32 format,
> +					    u64 modifier);
>  
>  u32 intel_plane_ggtt_offset(const struct intel_plane_state *plane_state);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 3afb85fe8536dfffd55dbaa07f6727112cc876b7..5d0bab1f8ff8294716ca5843c856032d2b9ccd5b 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -6005,22 +6005,16 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in
>  		if (!plane->async_flip)
>  			continue;
>  
> -		if (!intel_plane_can_async_flip(plane, new_plane_state->hw.fb->modifier)) {
> +		if (!intel_plane_can_async_flip(plane, new_plane_state->hw.fb->format->format,
> +						new_plane_state->hw.fb->modifier)) {
>  			drm_dbg_kms(display->drm,
> -				    "[PLANE:%d:%s] Modifier 0x%llx does not support async flip\n",
> +				    "[PLANE:%d:%s] Format %p4cc Modifier 0x%llx does not support async flip\n",
>  				    plane->base.base.id, plane->base.name,
> +				    &new_plane_state->hw.fb->format->format,
>  				    new_plane_state->hw.fb->modifier);
>  			return -EINVAL;
>  		}
>  
> -		if (intel_format_info_is_yuv_semiplanar(new_plane_state->hw.fb->format,
> -							new_plane_state->hw.fb->modifier)) {
> -			drm_dbg_kms(display->drm,
> -				    "[PLANE:%d:%s] Planar formats do not support async flips\n",
> -				    plane->base.base.id, plane->base.name);
> -			return -EINVAL;
> -		}
> -
>  		/*
>  		 * We turn the first async flip request into a sync flip
>  		 * so that we can reconfigure the plane (eg. change modifier).
> diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
> index 70e550539bb21393c7173c7b3904e7790eab25f4..f61e1eff30bb4820ccb17daa5d4b2b073a5d4078 100644
> --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
> +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
> @@ -601,7 +601,7 @@ static u32 tgl_plane_min_alignment(struct intel_plane *plane,
>  	 * Figure out what's going on here...
>  	 */
>  	if (display->platform.alderlake_p &&
> -	    intel_plane_can_async_flip(plane, fb->modifier))
> +	    intel_plane_can_async_flip(plane, fb->format->format, fb->modifier))
>  		return mult * 16 * 1024;
>  
>  	switch (fb->modifier) {
> @@ -2666,6 +2666,7 @@ static const struct drm_plane_funcs skl_plane_funcs = {
>  	.atomic_duplicate_state = intel_plane_duplicate_state,
>  	.atomic_destroy_state = intel_plane_destroy_state,
>  	.format_mod_supported = skl_plane_format_mod_supported,
> +	.format_mod_supported_async = intel_plane_format_mod_supported_async,
>  };
>  
>  static const struct drm_plane_funcs icl_plane_funcs = {
> @@ -2675,6 +2676,7 @@ static const struct drm_plane_funcs icl_plane_funcs = {
>  	.atomic_duplicate_state = intel_plane_duplicate_state,
>  	.atomic_destroy_state = intel_plane_destroy_state,
>  	.format_mod_supported = icl_plane_format_mod_supported,
> +	.format_mod_supported_async = intel_plane_format_mod_supported_async,
>  };
>  
>  static const struct drm_plane_funcs tgl_plane_funcs = {
> @@ -2684,6 +2686,7 @@ static const struct drm_plane_funcs tgl_plane_funcs = {
>  	.atomic_duplicate_state = intel_plane_duplicate_state,
>  	.atomic_destroy_state = intel_plane_destroy_state,
>  	.format_mod_supported = tgl_plane_format_mod_supported,
> +	.format_mod_supported_async = intel_plane_format_mod_supported_async,
>  };
>  
>  static void
> 
> -- 
> 2.25.1
Ville Syrjälä March 26, 2025, 5:20 p.m. UTC | #3
On Wed, Mar 19, 2025 at 04:02:17PM +0530, Arun R Murthy wrote:
> Hook up the newly added plane function pointer
> format_mod_supported_async to populate the modifiers/formats supported
> by asynchronous flips.
> 
> v5: Correct the if condition for modifier support check (Chaitanya)
> v6: Replace uint32_t/uint64_t with u32/u64 (Jani)
> v7: Move plannar check from intel_async_flip_check_hw() to
> intel_plane_format_mod_supported_async() (Ville)
> v8: In case of error print format/modifier (Chaitanya)
> v9: Exclude C8 format as its not supported by hardware
> 
> Signed-off-by: Arun R Murthy <arun.r.murthy@intel.com>
> ---
>  drivers/gpu/drm/i915/display/i9xx_plane.c          |  6 ++--
>  drivers/gpu/drm/i915/display/intel_atomic_plane.c  | 32 +++++++++++++++++++++-
>  drivers/gpu/drm/i915/display/intel_atomic_plane.h  |  6 +++-
>  drivers/gpu/drm/i915/display/intel_display.c       | 14 +++-------
>  drivers/gpu/drm/i915/display/skl_universal_plane.c |  5 +++-
>  5 files changed, 48 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c
> index 013295f66d56ec5e919b3a0c904034bf7985986a..6bd09adb8a30ba002ef334261d7638f398587a3e 100644
> --- a/drivers/gpu/drm/i915/display/i9xx_plane.c
> +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c
> @@ -820,7 +820,7 @@ unsigned int vlv_plane_min_alignment(struct intel_plane *plane,
>  {
>  	struct intel_display *display = to_intel_display(plane);
>  
> -	if (intel_plane_can_async_flip(plane, fb->modifier))
> +	if (intel_plane_can_async_flip(plane, fb->format->format, fb->modifier))
>  		return 256 * 1024;
>  
>  	/* FIXME undocumented so not sure what's actually needed */
> @@ -844,7 +844,7 @@ static unsigned int g4x_primary_min_alignment(struct intel_plane *plane,
>  {
>  	struct intel_display *display = to_intel_display(plane);
>  
> -	if (intel_plane_can_async_flip(plane, fb->modifier))
> +	if (intel_plane_can_async_flip(plane, fb->format->format, fb->modifier))
>  		return 256 * 1024;
>  
>  	if (intel_scanout_needs_vtd_wa(display))
> @@ -889,6 +889,7 @@ static const struct drm_plane_funcs i965_plane_funcs = {
>  	.atomic_duplicate_state = intel_plane_duplicate_state,
>  	.atomic_destroy_state = intel_plane_destroy_state,
>  	.format_mod_supported = i965_plane_format_mod_supported,
> +	.format_mod_supported_async = intel_plane_format_mod_supported_async,
>  };
>  
>  static const struct drm_plane_funcs i8xx_plane_funcs = {
> @@ -898,6 +899,7 @@ static const struct drm_plane_funcs i8xx_plane_funcs = {
>  	.atomic_duplicate_state = intel_plane_duplicate_state,
>  	.atomic_destroy_state = intel_plane_destroy_state,
>  	.format_mod_supported = i8xx_plane_format_mod_supported,
> +	.format_mod_supported_async = intel_plane_format_mod_supported_async,
>  };
>  
>  struct intel_plane *
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> index 7276179df878658b7053fe6d8dc37b69f19625e3..ce6bf6fe8f241a9517e8f74fb002b835c3f0853a 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> @@ -174,11 +174,41 @@ bool intel_plane_needs_physical(struct intel_plane *plane)
>  		DISPLAY_INFO(display)->cursor_needs_physical;
>  }
>  
> -bool intel_plane_can_async_flip(struct intel_plane *plane, u64 modifier)
> +bool intel_plane_can_async_flip(struct intel_plane *plane, u32 format,
> +				u64 modifier)
>  {
> +	struct intel_display *display = to_intel_display(plane);
> +
> +	if ((DISPLAY_VER(display) <= 14 ?
> +	    drm_format_info(format)->is_yuv :
> +	    intel_format_info_is_yuv_semiplanar(drm_format_info(format),
> +						modifier)) ||
> +	    format == DRM_FORMAT_C8) {
> +		drm_dbg_kms(plane->base.dev,
> +			    "[PLANE:%d:%s] Planar formats do not support async flips\n",
> +			    plane->base.base.id, plane->base.name);
> +		return false;
> +	}
> +
>  	return plane->can_async_flip && plane->can_async_flip(modifier);
>  }
>  
> +bool intel_plane_format_mod_supported_async(struct drm_plane *plane,
> +					    u32 format,
> +					    u64 modifier)
> +{
> +	if (plane->funcs->format_mod_supported &&

We always have that.

> +	    !plane->funcs->format_mod_supported(plane, format, modifier)) {
> +		drm_dbg_kms(plane->dev,
> +			    "[PLANE:%d:%s](format %p4cc) modifier 0x%llx not in universal list\n",
> +			    plane->base.id, plane->name, &format, modifier);

This is going to create tons of unwanted spam.

> +		return false;
> +	}
> +
> +	return intel_plane_can_async_flip(to_intel_plane(plane),
> +					format, modifier);
> +}
> +
>  unsigned int intel_adjusted_rate(const struct drm_rect *src,
>  				 const struct drm_rect *dst,
>  				 unsigned int rate)
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> index 6efac923dcbc757e6f68564cbef2919c920f13cb..512c251cc153753a4808cf177c8bcce2178bb862 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> @@ -21,7 +21,8 @@ enum plane_id;
>  
>  struct intel_plane *
>  intel_crtc_get_plane(struct intel_crtc *crtc, enum plane_id plane_id);
> -bool intel_plane_can_async_flip(struct intel_plane *plane, u64 modifier);
> +bool intel_plane_can_async_flip(struct intel_plane *plane, u32 format,
> +				u64 modifier);
>  unsigned int intel_adjusted_rate(const struct drm_rect *src,
>  				 const struct drm_rect *dst,
>  				 unsigned int rate);
> @@ -87,6 +88,9 @@ void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_sta
>  int intel_atomic_add_affected_planes(struct intel_atomic_state *state,
>  				     struct intel_crtc *crtc);
>  int intel_atomic_check_planes(struct intel_atomic_state *state);
> +bool intel_plane_format_mod_supported_async(struct drm_plane *plane,
> +					    u32 format,
> +					    u64 modifier);
>  
>  u32 intel_plane_ggtt_offset(const struct intel_plane_state *plane_state);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 3afb85fe8536dfffd55dbaa07f6727112cc876b7..5d0bab1f8ff8294716ca5843c856032d2b9ccd5b 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -6005,22 +6005,16 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in
>  		if (!plane->async_flip)
>  			continue;
>  
> -		if (!intel_plane_can_async_flip(plane, new_plane_state->hw.fb->modifier)) {
> +		if (!intel_plane_can_async_flip(plane, new_plane_state->hw.fb->format->format,
> +						new_plane_state->hw.fb->modifier)) {
>  			drm_dbg_kms(display->drm,
> -				    "[PLANE:%d:%s] Modifier 0x%llx does not support async flip\n",
> +				    "[PLANE:%d:%s] Format %p4cc Modifier 0x%llx does not support async flip\n",
>  				    plane->base.base.id, plane->base.name,
> +				    &new_plane_state->hw.fb->format->format,
>  				    new_plane_state->hw.fb->modifier);
>  			return -EINVAL;
>  		}
>  
> -		if (intel_format_info_is_yuv_semiplanar(new_plane_state->hw.fb->format,
> -							new_plane_state->hw.fb->modifier)) {
> -			drm_dbg_kms(display->drm,
> -				    "[PLANE:%d:%s] Planar formats do not support async flips\n",
> -				    plane->base.base.id, plane->base.name);
> -			return -EINVAL;
> -		}
> -
>  		/*
>  		 * We turn the first async flip request into a sync flip
>  		 * so that we can reconfigure the plane (eg. change modifier).
> diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
> index 70e550539bb21393c7173c7b3904e7790eab25f4..f61e1eff30bb4820ccb17daa5d4b2b073a5d4078 100644
> --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
> +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
> @@ -601,7 +601,7 @@ static u32 tgl_plane_min_alignment(struct intel_plane *plane,
>  	 * Figure out what's going on here...
>  	 */
>  	if (display->platform.alderlake_p &&
> -	    intel_plane_can_async_flip(plane, fb->modifier))
> +	    intel_plane_can_async_flip(plane, fb->format->format, fb->modifier))
>  		return mult * 16 * 1024;
>  
>  	switch (fb->modifier) {
> @@ -2666,6 +2666,7 @@ static const struct drm_plane_funcs skl_plane_funcs = {
>  	.atomic_duplicate_state = intel_plane_duplicate_state,
>  	.atomic_destroy_state = intel_plane_destroy_state,
>  	.format_mod_supported = skl_plane_format_mod_supported,
> +	.format_mod_supported_async = intel_plane_format_mod_supported_async,
>  };
>  
>  static const struct drm_plane_funcs icl_plane_funcs = {
> @@ -2675,6 +2676,7 @@ static const struct drm_plane_funcs icl_plane_funcs = {
>  	.atomic_duplicate_state = intel_plane_duplicate_state,
>  	.atomic_destroy_state = intel_plane_destroy_state,
>  	.format_mod_supported = icl_plane_format_mod_supported,
> +	.format_mod_supported_async = intel_plane_format_mod_supported_async,
>  };
>  
>  static const struct drm_plane_funcs tgl_plane_funcs = {
> @@ -2684,6 +2686,7 @@ static const struct drm_plane_funcs tgl_plane_funcs = {
>  	.atomic_duplicate_state = intel_plane_duplicate_state,
>  	.atomic_destroy_state = intel_plane_destroy_state,
>  	.format_mod_supported = tgl_plane_format_mod_supported,
> +	.format_mod_supported_async = intel_plane_format_mod_supported_async,
>  };
>  
>  static void
> 
> -- 
> 2.25.1
Arun R Murthy March 27, 2025, 5:10 a.m. UTC | #4
> On Wed, Mar 19, 2025 at 04:02:17PM +0530, Arun R Murthy wrote:
> > Hook up the newly added plane function pointer
> > format_mod_supported_async to populate the modifiers/formats supported
> > by asynchronous flips.
> >
> > v5: Correct the if condition for modifier support check (Chaitanya)
> > v6: Replace uint32_t/uint64_t with u32/u64 (Jani)
> > v7: Move plannar check from intel_async_flip_check_hw() to
> > intel_plane_format_mod_supported_async() (Ville)
> > v8: In case of error print format/modifier (Chaitanya)
> > v9: Exclude C8 format as its not supported by hardware
> >
> > Signed-off-by: Arun R Murthy <arun.r.murthy@intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/i9xx_plane.c          |  6 ++--
> >  drivers/gpu/drm/i915/display/intel_atomic_plane.c  | 32
> > +++++++++++++++++++++-
> drivers/gpu/drm/i915/display/intel_atomic_plane.h  |  6 +++-
> >  drivers/gpu/drm/i915/display/intel_display.c       | 14 +++-------
> >  drivers/gpu/drm/i915/display/skl_universal_plane.c |  5 +++-
> >  5 files changed, 48 insertions(+), 15 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c
> > b/drivers/gpu/drm/i915/display/i9xx_plane.c
> > index
> >
> 013295f66d56ec5e919b3a0c904034bf7985986a..6bd09adb8a30ba002ef3342
> 61d76
> > 38f398587a3e 100644
> > --- a/drivers/gpu/drm/i915/display/i9xx_plane.c
> > +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c
> > @@ -820,7 +820,7 @@ unsigned int vlv_plane_min_alignment(struct
> > intel_plane *plane,  {
> >  	struct intel_display *display = to_intel_display(plane);
> >
> > -	if (intel_plane_can_async_flip(plane, fb->modifier))
> > +	if (intel_plane_can_async_flip(plane, fb->format->format,
> > +fb->modifier))
> >  		return 256 * 1024;
> >
> >  	/* FIXME undocumented so not sure what's actually needed */ @@
> > -844,7 +844,7 @@ static unsigned int g4x_primary_min_alignment(struct
> > intel_plane *plane,  {
> >  	struct intel_display *display = to_intel_display(plane);
> >
> > -	if (intel_plane_can_async_flip(plane, fb->modifier))
> > +	if (intel_plane_can_async_flip(plane, fb->format->format,
> > +fb->modifier))
> >  		return 256 * 1024;
> >
> >  	if (intel_scanout_needs_vtd_wa(display))
> > @@ -889,6 +889,7 @@ static const struct drm_plane_funcs
> i965_plane_funcs = {
> >  	.atomic_duplicate_state = intel_plane_duplicate_state,
> >  	.atomic_destroy_state = intel_plane_destroy_state,
> >  	.format_mod_supported = i965_plane_format_mod_supported,
> > +	.format_mod_supported_async =
> > +intel_plane_format_mod_supported_async,
> >  };
> >
> >  static const struct drm_plane_funcs i8xx_plane_funcs = { @@ -898,6
> > +899,7 @@ static const struct drm_plane_funcs i8xx_plane_funcs = {
> >  	.atomic_duplicate_state = intel_plane_duplicate_state,
> >  	.atomic_destroy_state = intel_plane_destroy_state,
> >  	.format_mod_supported = i8xx_plane_format_mod_supported,
> > +	.format_mod_supported_async =
> > +intel_plane_format_mod_supported_async,
> >  };
> >
> >  struct intel_plane *
> > diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > index
> >
> 7276179df878658b7053fe6d8dc37b69f19625e3..ce6bf6fe8f241a9517e8f74fb
> 002
> > b835c3f0853a 100644
> > --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > @@ -174,11 +174,41 @@ bool intel_plane_needs_physical(struct intel_plane
> *plane)
> >  		DISPLAY_INFO(display)->cursor_needs_physical;
> >  }
> >
> > -bool intel_plane_can_async_flip(struct intel_plane *plane, u64
> > modifier)
> > +bool intel_plane_can_async_flip(struct intel_plane *plane, u32 format,
> > +				u64 modifier)
> >  {
> > +	struct intel_display *display = to_intel_display(plane);
> > +
> > +	if ((DISPLAY_VER(display) <= 14 ?
> > +	    drm_format_info(format)->is_yuv :
> > +	    intel_format_info_is_yuv_semiplanar(drm_format_info(format),
> > +						modifier)) ||
> > +	    format == DRM_FORMAT_C8) {
> > +		drm_dbg_kms(plane->base.dev,
> > +			    "[PLANE:%d:%s] Planar formats do not support
> async flips\n",
> > +			    plane->base.base.id, plane->base.name);
> > +		return false;
> > +	}
> > +
> >  	return plane->can_async_flip && plane->can_async_flip(modifier);  }
> >
> > +bool intel_plane_format_mod_supported_async(struct drm_plane *plane,
> > +					    u32 format,
> > +					    u64 modifier)
> > +{
> > +	if (plane->funcs->format_mod_supported &&
> 
> We always have that.
> 
Ok will remove.

> > +	    !plane->funcs->format_mod_supported(plane, format, modifier)) {
> > +		drm_dbg_kms(plane->dev,
> > +			    "[PLANE:%d:%s](format %p4cc) modifier 0x%llx not
> in universal list\n",
> > +			    plane->base.id, plane->name, &format, modifier);
> 
> This is going to create tons of unwanted spam.
Ok will remove this!

Thanks and Regards,
Arun R Murthy
--------------------
> 
> > +		return false;
> > +	}
> > +
> > +	return intel_plane_can_async_flip(to_intel_plane(plane),
> > +					format, modifier);
> > +}
> > +
> >  unsigned int intel_adjusted_rate(const struct drm_rect *src,
> >  				 const struct drm_rect *dst,
> >  				 unsigned int rate)
> > diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> > b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> > index
> >
> 6efac923dcbc757e6f68564cbef2919c920f13cb..512c251cc153753a4808cf177c
> 8b
> > cce2178bb862 100644
> > --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> > +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> > @@ -21,7 +21,8 @@ enum plane_id;
> >
> >  struct intel_plane *
> >  intel_crtc_get_plane(struct intel_crtc *crtc, enum plane_id
> > plane_id); -bool intel_plane_can_async_flip(struct intel_plane *plane,
> > u64 modifier);
> > +bool intel_plane_can_async_flip(struct intel_plane *plane, u32 format,
> > +				u64 modifier);
> >  unsigned int intel_adjusted_rate(const struct drm_rect *src,
> >  				 const struct drm_rect *dst,
> >  				 unsigned int rate);
> > @@ -87,6 +88,9 @@ void intel_plane_init_cursor_vblank_work(struct
> > intel_plane_state *old_plane_sta  int intel_atomic_add_affected_planes(struct
> intel_atomic_state *state,
> >  				     struct intel_crtc *crtc);
> >  int intel_atomic_check_planes(struct intel_atomic_state *state);
> > +bool intel_plane_format_mod_supported_async(struct drm_plane *plane,
> > +					    u32 format,
> > +					    u64 modifier);
> >
> >  u32 intel_plane_ggtt_offset(const struct intel_plane_state
> > *plane_state);
> >
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> > b/drivers/gpu/drm/i915/display/intel_display.c
> > index
> >
> 3afb85fe8536dfffd55dbaa07f6727112cc876b7..5d0bab1f8ff8294716ca5843c8
> 56
> > 032d2b9ccd5b 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -6005,22 +6005,16 @@ static int intel_async_flip_check_hw(struct
> intel_atomic_state *state, struct in
> >  		if (!plane->async_flip)
> >  			continue;
> >
> > -		if (!intel_plane_can_async_flip(plane, new_plane_state->hw.fb-
> >modifier)) {
> > +		if (!intel_plane_can_async_flip(plane, new_plane_state->hw.fb-
> >format->format,
> > +						new_plane_state->hw.fb-
> >modifier)) {
> >  			drm_dbg_kms(display->drm,
> > -				    "[PLANE:%d:%s] Modifier 0x%llx does not
> support async flip\n",
> > +				    "[PLANE:%d:%s] Format %p4cc Modifier
> 0x%llx does not support
> > +async flip\n",
> >  				    plane->base.base.id, plane->base.name,
> > +				    &new_plane_state->hw.fb->format->format,
> >  				    new_plane_state->hw.fb->modifier);
> >  			return -EINVAL;
> >  		}
> >
> > -		if (intel_format_info_is_yuv_semiplanar(new_plane_state-
> >hw.fb->format,
> > -							new_plane_state-
> >hw.fb->modifier)) {
> > -			drm_dbg_kms(display->drm,
> > -				    "[PLANE:%d:%s] Planar formats do not
> support async flips\n",
> > -				    plane->base.base.id, plane->base.name);
> > -			return -EINVAL;
> > -		}
> > -
> >  		/*
> >  		 * We turn the first async flip request into a sync flip
> >  		 * so that we can reconfigure the plane (eg. change modifier).
> > diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c
> > b/drivers/gpu/drm/i915/display/skl_universal_plane.c
> > index
> >
> 70e550539bb21393c7173c7b3904e7790eab25f4..f61e1eff30bb4820ccb17daa
> 5d4b
> > 2b073a5d4078 100644
> > --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
> > +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
> > @@ -601,7 +601,7 @@ static u32 tgl_plane_min_alignment(struct
> intel_plane *plane,
> >  	 * Figure out what's going on here...
> >  	 */
> >  	if (display->platform.alderlake_p &&
> > -	    intel_plane_can_async_flip(plane, fb->modifier))
> > +	    intel_plane_can_async_flip(plane, fb->format->format,
> > +fb->modifier))
> >  		return mult * 16 * 1024;
> >
> >  	switch (fb->modifier) {
> > @@ -2666,6 +2666,7 @@ static const struct drm_plane_funcs
> skl_plane_funcs = {
> >  	.atomic_duplicate_state = intel_plane_duplicate_state,
> >  	.atomic_destroy_state = intel_plane_destroy_state,
> >  	.format_mod_supported = skl_plane_format_mod_supported,
> > +	.format_mod_supported_async =
> > +intel_plane_format_mod_supported_async,
> >  };
> >
> >  static const struct drm_plane_funcs icl_plane_funcs = { @@ -2675,6
> > +2676,7 @@ static const struct drm_plane_funcs icl_plane_funcs = {
> >  	.atomic_duplicate_state = intel_plane_duplicate_state,
> >  	.atomic_destroy_state = intel_plane_destroy_state,
> >  	.format_mod_supported = icl_plane_format_mod_supported,
> > +	.format_mod_supported_async =
> > +intel_plane_format_mod_supported_async,
> >  };
> >
> >  static const struct drm_plane_funcs tgl_plane_funcs = { @@ -2684,6
> > +2686,7 @@ static const struct drm_plane_funcs tgl_plane_funcs = {
> >  	.atomic_duplicate_state = intel_plane_duplicate_state,
> >  	.atomic_destroy_state = intel_plane_destroy_state,
> >  	.format_mod_supported = tgl_plane_format_mod_supported,
> > +	.format_mod_supported_async =
> > +intel_plane_format_mod_supported_async,
> >  };
> >
> >  static void
> >
> > --
> > 2.25.1
> 
> --
> Ville Syrjälä
> Intel
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c
index 013295f66d56ec5e919b3a0c904034bf7985986a..6bd09adb8a30ba002ef334261d7638f398587a3e 100644
--- a/drivers/gpu/drm/i915/display/i9xx_plane.c
+++ b/drivers/gpu/drm/i915/display/i9xx_plane.c
@@ -820,7 +820,7 @@  unsigned int vlv_plane_min_alignment(struct intel_plane *plane,
 {
 	struct intel_display *display = to_intel_display(plane);
 
-	if (intel_plane_can_async_flip(plane, fb->modifier))
+	if (intel_plane_can_async_flip(plane, fb->format->format, fb->modifier))
 		return 256 * 1024;
 
 	/* FIXME undocumented so not sure what's actually needed */
@@ -844,7 +844,7 @@  static unsigned int g4x_primary_min_alignment(struct intel_plane *plane,
 {
 	struct intel_display *display = to_intel_display(plane);
 
-	if (intel_plane_can_async_flip(plane, fb->modifier))
+	if (intel_plane_can_async_flip(plane, fb->format->format, fb->modifier))
 		return 256 * 1024;
 
 	if (intel_scanout_needs_vtd_wa(display))
@@ -889,6 +889,7 @@  static const struct drm_plane_funcs i965_plane_funcs = {
 	.atomic_duplicate_state = intel_plane_duplicate_state,
 	.atomic_destroy_state = intel_plane_destroy_state,
 	.format_mod_supported = i965_plane_format_mod_supported,
+	.format_mod_supported_async = intel_plane_format_mod_supported_async,
 };
 
 static const struct drm_plane_funcs i8xx_plane_funcs = {
@@ -898,6 +899,7 @@  static const struct drm_plane_funcs i8xx_plane_funcs = {
 	.atomic_duplicate_state = intel_plane_duplicate_state,
 	.atomic_destroy_state = intel_plane_destroy_state,
 	.format_mod_supported = i8xx_plane_format_mod_supported,
+	.format_mod_supported_async = intel_plane_format_mod_supported_async,
 };
 
 struct intel_plane *
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index 7276179df878658b7053fe6d8dc37b69f19625e3..ce6bf6fe8f241a9517e8f74fb002b835c3f0853a 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -174,11 +174,41 @@  bool intel_plane_needs_physical(struct intel_plane *plane)
 		DISPLAY_INFO(display)->cursor_needs_physical;
 }
 
-bool intel_plane_can_async_flip(struct intel_plane *plane, u64 modifier)
+bool intel_plane_can_async_flip(struct intel_plane *plane, u32 format,
+				u64 modifier)
 {
+	struct intel_display *display = to_intel_display(plane);
+
+	if ((DISPLAY_VER(display) <= 14 ?
+	    drm_format_info(format)->is_yuv :
+	    intel_format_info_is_yuv_semiplanar(drm_format_info(format),
+						modifier)) ||
+	    format == DRM_FORMAT_C8) {
+		drm_dbg_kms(plane->base.dev,
+			    "[PLANE:%d:%s] Planar formats do not support async flips\n",
+			    plane->base.base.id, plane->base.name);
+		return false;
+	}
+
 	return plane->can_async_flip && plane->can_async_flip(modifier);
 }
 
+bool intel_plane_format_mod_supported_async(struct drm_plane *plane,
+					    u32 format,
+					    u64 modifier)
+{
+	if (plane->funcs->format_mod_supported &&
+	    !plane->funcs->format_mod_supported(plane, format, modifier)) {
+		drm_dbg_kms(plane->dev,
+			    "[PLANE:%d:%s](format %p4cc) modifier 0x%llx not in universal list\n",
+			    plane->base.id, plane->name, &format, modifier);
+		return false;
+	}
+
+	return intel_plane_can_async_flip(to_intel_plane(plane),
+					format, modifier);
+}
+
 unsigned int intel_adjusted_rate(const struct drm_rect *src,
 				 const struct drm_rect *dst,
 				 unsigned int rate)
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
index 6efac923dcbc757e6f68564cbef2919c920f13cb..512c251cc153753a4808cf177c8bcce2178bb862 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
@@ -21,7 +21,8 @@  enum plane_id;
 
 struct intel_plane *
 intel_crtc_get_plane(struct intel_crtc *crtc, enum plane_id plane_id);
-bool intel_plane_can_async_flip(struct intel_plane *plane, u64 modifier);
+bool intel_plane_can_async_flip(struct intel_plane *plane, u32 format,
+				u64 modifier);
 unsigned int intel_adjusted_rate(const struct drm_rect *src,
 				 const struct drm_rect *dst,
 				 unsigned int rate);
@@ -87,6 +88,9 @@  void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_sta
 int intel_atomic_add_affected_planes(struct intel_atomic_state *state,
 				     struct intel_crtc *crtc);
 int intel_atomic_check_planes(struct intel_atomic_state *state);
+bool intel_plane_format_mod_supported_async(struct drm_plane *plane,
+					    u32 format,
+					    u64 modifier);
 
 u32 intel_plane_ggtt_offset(const struct intel_plane_state *plane_state);
 
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 3afb85fe8536dfffd55dbaa07f6727112cc876b7..5d0bab1f8ff8294716ca5843c856032d2b9ccd5b 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -6005,22 +6005,16 @@  static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in
 		if (!plane->async_flip)
 			continue;
 
-		if (!intel_plane_can_async_flip(plane, new_plane_state->hw.fb->modifier)) {
+		if (!intel_plane_can_async_flip(plane, new_plane_state->hw.fb->format->format,
+						new_plane_state->hw.fb->modifier)) {
 			drm_dbg_kms(display->drm,
-				    "[PLANE:%d:%s] Modifier 0x%llx does not support async flip\n",
+				    "[PLANE:%d:%s] Format %p4cc Modifier 0x%llx does not support async flip\n",
 				    plane->base.base.id, plane->base.name,
+				    &new_plane_state->hw.fb->format->format,
 				    new_plane_state->hw.fb->modifier);
 			return -EINVAL;
 		}
 
-		if (intel_format_info_is_yuv_semiplanar(new_plane_state->hw.fb->format,
-							new_plane_state->hw.fb->modifier)) {
-			drm_dbg_kms(display->drm,
-				    "[PLANE:%d:%s] Planar formats do not support async flips\n",
-				    plane->base.base.id, plane->base.name);
-			return -EINVAL;
-		}
-
 		/*
 		 * We turn the first async flip request into a sync flip
 		 * so that we can reconfigure the plane (eg. change modifier).
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 70e550539bb21393c7173c7b3904e7790eab25f4..f61e1eff30bb4820ccb17daa5d4b2b073a5d4078 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -601,7 +601,7 @@  static u32 tgl_plane_min_alignment(struct intel_plane *plane,
 	 * Figure out what's going on here...
 	 */
 	if (display->platform.alderlake_p &&
-	    intel_plane_can_async_flip(plane, fb->modifier))
+	    intel_plane_can_async_flip(plane, fb->format->format, fb->modifier))
 		return mult * 16 * 1024;
 
 	switch (fb->modifier) {
@@ -2666,6 +2666,7 @@  static const struct drm_plane_funcs skl_plane_funcs = {
 	.atomic_duplicate_state = intel_plane_duplicate_state,
 	.atomic_destroy_state = intel_plane_destroy_state,
 	.format_mod_supported = skl_plane_format_mod_supported,
+	.format_mod_supported_async = intel_plane_format_mod_supported_async,
 };
 
 static const struct drm_plane_funcs icl_plane_funcs = {
@@ -2675,6 +2676,7 @@  static const struct drm_plane_funcs icl_plane_funcs = {
 	.atomic_duplicate_state = intel_plane_duplicate_state,
 	.atomic_destroy_state = intel_plane_destroy_state,
 	.format_mod_supported = icl_plane_format_mod_supported,
+	.format_mod_supported_async = intel_plane_format_mod_supported_async,
 };
 
 static const struct drm_plane_funcs tgl_plane_funcs = {
@@ -2684,6 +2686,7 @@  static const struct drm_plane_funcs tgl_plane_funcs = {
 	.atomic_duplicate_state = intel_plane_duplicate_state,
 	.atomic_destroy_state = intel_plane_destroy_state,
 	.format_mod_supported = tgl_plane_format_mod_supported,
+	.format_mod_supported_async = intel_plane_format_mod_supported_async,
 };
 
 static void