[Intel-gfx] [PATCH v12 1/8] drm/i915: migrate skl planes code new file (v5)

Ville Syrjälä ville.syrjala at linux.intel.com
Fri Feb 5 15:01:51 UTC 2021


On Fri, Feb 05, 2021 at 04:48:36PM +0200, Jani Nikula wrote:
> From: Dave Airlie <airlied at redhat.com>
> 
> Rework the plane init calls to do the gen test one level higher.
> 
> Rework some of the plane helpers so they can live in new file,
> there is still some scope to clean up the plane/fb interactions
> later.
> 
> v2: drop atomic code back, rename file to Ville suggestions,
> add header file.
> v3: move scaler bits back
> v4: drop wrong new includes (Ville)
> v5: integrate the ccs gen12 changes
> v6: fix unrelated code movement (Ville)
> 
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> [Jani: fixed up sparse warnings.]
> Signed-off-by: Jani Nikula <jani.nikula at intel.com>
> Reported-by: kernel test robot <lkp at intel.com>
> Reported-by: Dan Carpenter <dan.carpenter at oracle.com>

Reviewed-by: Ville Syrjälä <ville.syrjala at linux.intel.com>

> ---
>  drivers/gpu/drm/i915/Makefile                 |    3 +-
>  drivers/gpu/drm/i915/display/i9xx_plane.c     |    4 -
>  drivers/gpu/drm/i915/display/icl_dsi.c        |    1 +
>  drivers/gpu/drm/i915/display/intel_crtc.c     |   13 +-
>  drivers/gpu/drm/i915/display/intel_ddi.c      |    1 +
>  drivers/gpu/drm/i915/display/intel_display.c  |  948 +------
>  drivers/gpu/drm/i915/display/intel_display.h  |   27 +-
>  .../drm/i915/display/intel_display_types.h    |   27 +
>  drivers/gpu/drm/i915/display/intel_psr.c      |    1 +
>  drivers/gpu/drm/i915/display/intel_sprite.c   | 1343 +---------
>  drivers/gpu/drm/i915/display/intel_sprite.h   |    6 +-
>  .../drm/i915/display/skl_universal_plane.c    | 2265 +++++++++++++++++
>  .../drm/i915/display/skl_universal_plane.h    |   33 +
>  drivers/gpu/drm/i915/intel_pm.c               |    1 +
>  14 files changed, 2380 insertions(+), 2293 deletions(-)
>  create mode 100644 drivers/gpu/drm/i915/display/skl_universal_plane.c
>  create mode 100644 drivers/gpu/drm/i915/display/skl_universal_plane.h
> 
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index d571e87416dc..9388e09184fe 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -225,7 +225,8 @@ i915-y += \
>  	display/intel_sprite.o \
>  	display/intel_tc.o \
>  	display/intel_vga.o \
> -	display/i9xx_plane.o
> +	display/i9xx_plane.o \
> +	display/skl_universal_plane.o
>  i915-$(CONFIG_ACPI) += \
>  	display/intel_acpi.o \
>  	display/intel_opregion.o
> diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c
> index d30374df67f0..d116dee201aa 100644
> --- a/drivers/gpu/drm/i915/display/i9xx_plane.c
> +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c
> @@ -743,10 +743,6 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
>  	int num_formats;
>  	int ret, zpos;
>  
> -	if (INTEL_GEN(dev_priv) >= 9)
> -		return skl_universal_plane_create(dev_priv, pipe,
> -						  PLANE_PRIMARY);
> -
>  	plane = intel_plane_alloc();
>  	if (IS_ERR(plane))
>  		return plane;
> diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
> index 9d245a689323..9eeec6fadec7 100644
> --- a/drivers/gpu/drm/i915/display/icl_dsi.c
> +++ b/drivers/gpu/drm/i915/display/icl_dsi.c
> @@ -35,6 +35,7 @@
>  #include "intel_dsi.h"
>  #include "intel_panel.h"
>  #include "intel_vdsc.h"
> +#include "skl_universal_plane.h"
>  
>  static int header_credits_available(struct drm_i915_private *dev_priv,
>  				    enum transcoder dsi_trans)
> diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c
> index 57b0a3ebe908..eb478712c381 100644
> --- a/drivers/gpu/drm/i915/display/intel_crtc.c
> +++ b/drivers/gpu/drm/i915/display/intel_crtc.c
> @@ -20,6 +20,7 @@
>  #include "intel_pipe_crc.h"
>  #include "intel_sprite.h"
>  #include "i9xx_plane.h"
> +#include "skl_universal_plane.h"
>  
>  static void assert_vblank_disabled(struct drm_crtc *crtc)
>  {
> @@ -243,7 +244,11 @@ int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
>  	crtc->pipe = pipe;
>  	crtc->num_scalers = RUNTIME_INFO(dev_priv)->num_scalers[pipe];
>  
> -	primary = intel_primary_plane_create(dev_priv, pipe);
> +	if (INTEL_GEN(dev_priv) >= 9)
> +		primary = skl_universal_plane_create(dev_priv, pipe,
> +						     PLANE_PRIMARY);
> +	else
> +		primary = intel_primary_plane_create(dev_priv, pipe);
>  	if (IS_ERR(primary)) {
>  		ret = PTR_ERR(primary);
>  		goto fail;
> @@ -253,7 +258,11 @@ int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
>  	for_each_sprite(dev_priv, pipe, sprite) {
>  		struct intel_plane *plane;
>  
> -		plane = intel_sprite_plane_create(dev_priv, pipe, sprite);
> +		if (INTEL_GEN(dev_priv) >= 9)
> +			plane = skl_universal_plane_create(dev_priv, pipe,
> +							   PLANE_SPRITE0 + sprite);
> +		else
> +			plane = intel_sprite_plane_create(dev_priv, pipe, sprite);
>  		if (IS_ERR(plane)) {
>  			ret = PTR_ERR(plane);
>  			goto fail;
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 28877a31adc0..f4746c1edabe 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -54,6 +54,7 @@
>  #include "intel_tc.h"
>  #include "intel_vdsc.h"
>  #include "intel_vrr.h"
> +#include "skl_universal_plane.h"
>  
>  static const u8 index_to_dp_signal_levels[] = {
>  	[0] = DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0,
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 92c14f3f0abf..a259ca5433f7 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -94,6 +94,7 @@
>  #include "intel_tc.h"
>  #include "intel_vga.h"
>  #include "i9xx_plane.h"
> +#include "skl_universal_plane.h"
>  
>  static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
>  				struct intel_crtc_state *pipe_config);
> @@ -116,7 +117,6 @@ static void vlv_prepare_pll(struct intel_crtc *crtc,
>  			    const struct intel_crtc_state *pipe_config);
>  static void chv_prepare_pll(struct intel_crtc *crtc,
>  			    const struct intel_crtc_state *pipe_config);
> -static void skl_pfit_enable(const struct intel_crtc_state *crtc_state);
>  static void ilk_pfit_enable(const struct intel_crtc_state *crtc_state);
>  static void intel_modeset_setup_hw_state(struct drm_device *dev,
>  					 struct drm_modeset_acquire_ctx *ctx);
> @@ -1082,32 +1082,6 @@ static unsigned int intel_tile_size(const struct drm_i915_private *dev_priv)
>  	return IS_GEN(dev_priv, 2) ? 2048 : 4096;
>  }
>  
> -static bool is_ccs_plane(const struct drm_framebuffer *fb, int plane)
> -{
> -	if (!is_ccs_modifier(fb->modifier))
> -		return false;
> -
> -	return plane >= fb->format->num_planes / 2;
> -}
> -
> -static bool is_gen12_ccs_modifier(u64 modifier)
> -{
> -	return modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS ||
> -	       modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC ||
> -	       modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS;
> -}
> -
> -static bool is_gen12_ccs_plane(const struct drm_framebuffer *fb, int plane)
> -{
> -	return is_gen12_ccs_modifier(fb->modifier) && is_ccs_plane(fb, plane);
> -}
> -
> -static bool is_gen12_ccs_cc_plane(const struct drm_framebuffer *fb, int plane)
> -{
> -	return fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC &&
> -	       plane == 2;
> -}
> -
>  static bool is_aux_plane(const struct drm_framebuffer *fb, int plane)
>  {
>  	if (is_ccs_modifier(fb->modifier))
> @@ -1116,38 +1090,6 @@ static bool is_aux_plane(const struct drm_framebuffer *fb, int plane)
>  	return plane == 1;
>  }
>  
> -static int main_to_ccs_plane(const struct drm_framebuffer *fb, int main_plane)
> -{
> -	drm_WARN_ON(fb->dev, !is_ccs_modifier(fb->modifier) ||
> -		    (main_plane && main_plane >= fb->format->num_planes / 2));
> -
> -	return fb->format->num_planes / 2 + main_plane;
> -}
> -
> -static int ccs_to_main_plane(const struct drm_framebuffer *fb, int ccs_plane)
> -{
> -	drm_WARN_ON(fb->dev, !is_ccs_modifier(fb->modifier) ||
> -		    ccs_plane < fb->format->num_planes / 2);
> -
> -	if (is_gen12_ccs_cc_plane(fb, ccs_plane))
> -		return 0;
> -
> -	return ccs_plane - fb->format->num_planes / 2;
> -}
> -
> -int intel_main_to_aux_plane(const struct drm_framebuffer *fb, int main_plane)
> -{
> -	struct drm_i915_private *i915 = to_i915(fb->dev);
> -
> -	if (is_ccs_modifier(fb->modifier))
> -		return main_to_ccs_plane(fb, main_plane);
> -	else if (INTEL_GEN(i915) < 11 &&
> -		 intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
> -		return 1;
> -	else
> -		return 0;
> -}
> -
>  bool
>  intel_format_info_is_yuv_semiplanar(const struct drm_format_info *info,
>  				    u64 modifier)
> @@ -1163,7 +1105,7 @@ static bool is_semiplanar_uv_plane(const struct drm_framebuffer *fb,
>  	       color_plane == 1;
>  }
>  
> -static unsigned int
> +unsigned int
>  intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(fb->dev);
> @@ -1217,7 +1159,7 @@ intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane)
>  	}
>  }
>  
> -static unsigned int
> +unsigned int
>  intel_tile_height(const struct drm_framebuffer *fb, int color_plane)
>  {
>  	if (is_gen12_ccs_plane(fb, color_plane))
> @@ -1322,8 +1264,8 @@ static bool has_async_flips(struct drm_i915_private *i915)
>  	return INTEL_GEN(i915) >= 5;
>  }
>  
> -static unsigned int intel_surf_alignment(const struct drm_framebuffer *fb,
> -					 int color_plane)
> +unsigned int intel_surf_alignment(const struct drm_framebuffer *fb,
> +				  int color_plane)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(fb->dev);
>  
> @@ -1590,10 +1532,10 @@ static u32 intel_adjust_aligned_offset(int *x, int *y,
>   * Adjust the tile offset by moving the difference into
>   * the x/y offsets.
>   */
> -static u32 intel_plane_adjust_aligned_offset(int *x, int *y,
> -					     const struct intel_plane_state *state,
> -					     int color_plane,
> -					     u32 old_offset, u32 new_offset)
> +u32 intel_plane_adjust_aligned_offset(int *x, int *y,
> +				      const struct intel_plane_state *state,
> +				      int color_plane,
> +				      u32 old_offset, u32 new_offset)
>  {
>  	return intel_adjust_aligned_offset(x, y, state->hw.fb, color_plane,
>  					   state->hw.rotation,
> @@ -1892,7 +1834,7 @@ bool is_ccs_modifier(u64 modifier)
>  
>  static int gen12_ccs_aux_stride(struct drm_framebuffer *fb, int ccs_plane)
>  {
> -	return DIV_ROUND_UP(fb->pitches[ccs_to_main_plane(fb, ccs_plane)],
> +	return DIV_ROUND_UP(fb->pitches[skl_ccs_to_main_plane(fb, ccs_plane)],
>  			    512) * 64;
>  }
>  
> @@ -2050,7 +1992,7 @@ static bool intel_plane_needs_remap(const struct intel_plane_state *plane_state)
>  	return stride > max_stride;
>  }
>  
> -static void
> +void
>  intel_fb_plane_get_subsampling(int *hsub, int *vsub,
>  			       const struct drm_framebuffer *fb,
>  			       int color_plane)
> @@ -2075,7 +2017,7 @@ intel_fb_plane_get_subsampling(int *hsub, int *vsub,
>  		return;
>  	}
>  
> -	main_plane = ccs_to_main_plane(fb, color_plane);
> +	main_plane = skl_ccs_to_main_plane(fb, color_plane);
>  	*hsub = drm_format_info_block_width(fb->format, color_plane) /
>  		drm_format_info_block_width(fb->format, main_plane);
>  
> @@ -2115,7 +2057,7 @@ intel_fb_check_ccs_xy(struct drm_framebuffer *fb, int ccs_plane, int x, int y)
>  	ccs_x = (x * hsub) % tile_width;
>  	ccs_y = (y * vsub) % tile_height;
>  
> -	main_plane = ccs_to_main_plane(fb, ccs_plane);
> +	main_plane = skl_ccs_to_main_plane(fb, ccs_plane);
>  	main_x = intel_fb->normal[main_plane].x % tile_width;
>  	main_y = intel_fb->normal[main_plane].y % tile_height;
>  
> @@ -2141,7 +2083,7 @@ static void
>  intel_fb_plane_dims(int *w, int *h, struct drm_framebuffer *fb, int color_plane)
>  {
>  	int main_plane = is_ccs_plane(fb, color_plane) ?
> -			 ccs_to_main_plane(fb, color_plane) : 0;
> +			 skl_ccs_to_main_plane(fb, color_plane) : 0;
>  	int main_hsub, main_vsub;
>  	int hsub, vsub;
>  
> @@ -2528,73 +2470,6 @@ static int i9xx_format_to_fourcc(int format)
>  	}
>  }
>  
> -int skl_format_to_fourcc(int format, bool rgb_order, bool alpha)
> -{
> -	switch (format) {
> -	case PLANE_CTL_FORMAT_RGB_565:
> -		return DRM_FORMAT_RGB565;
> -	case PLANE_CTL_FORMAT_NV12:
> -		return DRM_FORMAT_NV12;
> -	case PLANE_CTL_FORMAT_XYUV:
> -		return DRM_FORMAT_XYUV8888;
> -	case PLANE_CTL_FORMAT_P010:
> -		return DRM_FORMAT_P010;
> -	case PLANE_CTL_FORMAT_P012:
> -		return DRM_FORMAT_P012;
> -	case PLANE_CTL_FORMAT_P016:
> -		return DRM_FORMAT_P016;
> -	case PLANE_CTL_FORMAT_Y210:
> -		return DRM_FORMAT_Y210;
> -	case PLANE_CTL_FORMAT_Y212:
> -		return DRM_FORMAT_Y212;
> -	case PLANE_CTL_FORMAT_Y216:
> -		return DRM_FORMAT_Y216;
> -	case PLANE_CTL_FORMAT_Y410:
> -		return DRM_FORMAT_XVYU2101010;
> -	case PLANE_CTL_FORMAT_Y412:
> -		return DRM_FORMAT_XVYU12_16161616;
> -	case PLANE_CTL_FORMAT_Y416:
> -		return DRM_FORMAT_XVYU16161616;
> -	default:
> -	case PLANE_CTL_FORMAT_XRGB_8888:
> -		if (rgb_order) {
> -			if (alpha)
> -				return DRM_FORMAT_ABGR8888;
> -			else
> -				return DRM_FORMAT_XBGR8888;
> -		} else {
> -			if (alpha)
> -				return DRM_FORMAT_ARGB8888;
> -			else
> -				return DRM_FORMAT_XRGB8888;
> -		}
> -	case PLANE_CTL_FORMAT_XRGB_2101010:
> -		if (rgb_order) {
> -			if (alpha)
> -				return DRM_FORMAT_ABGR2101010;
> -			else
> -				return DRM_FORMAT_XBGR2101010;
> -		} else {
> -			if (alpha)
> -				return DRM_FORMAT_ARGB2101010;
> -			else
> -				return DRM_FORMAT_XRGB2101010;
> -		}
> -	case PLANE_CTL_FORMAT_XRGB_16161616F:
> -		if (rgb_order) {
> -			if (alpha)
> -				return DRM_FORMAT_ABGR16161616F;
> -			else
> -				return DRM_FORMAT_XBGR16161616F;
> -		} else {
> -			if (alpha)
> -				return DRM_FORMAT_ARGB16161616F;
> -			else
> -				return DRM_FORMAT_XRGB16161616F;
> -		}
> -	}
> -}
> -
>  static struct i915_vma *
>  initial_plane_vma(struct drm_i915_private *i915,
>  		  struct intel_initial_plane_config *plane_config)
> @@ -2899,52 +2774,6 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
>  		  &to_intel_frontbuffer(fb)->bits);
>  }
>  
> -
> -static bool
> -skl_check_main_ccs_coordinates(struct intel_plane_state *plane_state,
> -			       int main_x, int main_y, u32 main_offset,
> -			       int ccs_plane)
> -{
> -	const struct drm_framebuffer *fb = plane_state->hw.fb;
> -	int aux_x = plane_state->color_plane[ccs_plane].x;
> -	int aux_y = plane_state->color_plane[ccs_plane].y;
> -	u32 aux_offset = plane_state->color_plane[ccs_plane].offset;
> -	u32 alignment = intel_surf_alignment(fb, ccs_plane);
> -	int hsub;
> -	int vsub;
> -
> -	intel_fb_plane_get_subsampling(&hsub, &vsub, fb, ccs_plane);
> -	while (aux_offset >= main_offset && aux_y <= main_y) {
> -		int x, y;
> -
> -		if (aux_x == main_x && aux_y == main_y)
> -			break;
> -
> -		if (aux_offset == 0)
> -			break;
> -
> -		x = aux_x / hsub;
> -		y = aux_y / vsub;
> -		aux_offset = intel_plane_adjust_aligned_offset(&x, &y,
> -							       plane_state,
> -							       ccs_plane,
> -							       aux_offset,
> -							       aux_offset -
> -								alignment);
> -		aux_x = x * hsub + aux_x % hsub;
> -		aux_y = y * vsub + aux_y % vsub;
> -	}
> -
> -	if (aux_x != main_x || aux_y != main_y)
> -		return false;
> -
> -	plane_state->color_plane[ccs_plane].offset = aux_offset;
> -	plane_state->color_plane[ccs_plane].x = aux_x;
> -	plane_state->color_plane[ccs_plane].y = aux_y;
> -
> -	return true;
> -}
> -
>  unsigned int
>  intel_plane_fence_y_offset(const struct intel_plane_state *plane_state)
>  {
> @@ -2956,310 +2785,6 @@ intel_plane_fence_y_offset(const struct intel_plane_state *plane_state)
>  	return y;
>  }
>  
> -static int intel_plane_min_width(struct intel_plane *plane,
> -				 const struct drm_framebuffer *fb,
> -				 int color_plane,
> -				 unsigned int rotation)
> -{
> -	if (plane->min_width)
> -		return plane->min_width(fb, color_plane, rotation);
> -	else
> -		return 1;
> -}
> -
> -static int intel_plane_max_width(struct intel_plane *plane,
> -				 const struct drm_framebuffer *fb,
> -				 int color_plane,
> -				 unsigned int rotation)
> -{
> -	if (plane->max_width)
> -		return plane->max_width(fb, color_plane, rotation);
> -	else
> -		return INT_MAX;
> -}
> -
> -static int intel_plane_max_height(struct intel_plane *plane,
> -				  const struct drm_framebuffer *fb,
> -				  int color_plane,
> -				  unsigned int rotation)
> -{
> -	if (plane->max_height)
> -		return plane->max_height(fb, color_plane, rotation);
> -	else
> -		return INT_MAX;
> -}
> -
> -int skl_calc_main_surface_offset(const struct intel_plane_state *plane_state,
> -				 int *x, int *y, u32 *offset)
> -{
> -	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
> -	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> -	const struct drm_framebuffer *fb = plane_state->hw.fb;
> -	const int aux_plane = intel_main_to_aux_plane(fb, 0);
> -	const u32 aux_offset = plane_state->color_plane[aux_plane].offset;
> -	const u32 alignment = intel_surf_alignment(fb, 0);
> -	const int w = drm_rect_width(&plane_state->uapi.src) >> 16;
> -
> -	intel_add_fb_offsets(x, y, plane_state, 0);
> -	*offset = intel_plane_compute_aligned_offset(x, y, plane_state, 0);
> -	if (drm_WARN_ON(&dev_priv->drm, alignment && !is_power_of_2(alignment)))
> -		return -EINVAL;
> -
> -	/*
> -	 * AUX surface offset is specified as the distance from the
> -	 * main surface offset, and it must be non-negative. Make
> -	 * sure that is what we will get.
> -	 */
> -	if (aux_plane && *offset > aux_offset)
> -		*offset = intel_plane_adjust_aligned_offset(x, y, plane_state, 0,
> -							    *offset,
> -							    aux_offset & ~(alignment - 1));
> -
> -	/*
> -	 * When using an X-tiled surface, the plane blows up
> -	 * if the x offset + width exceed the stride.
> -	 *
> -	 * TODO: linear and Y-tiled seem fine, Yf untested,
> -	 */
> -	if (fb->modifier == I915_FORMAT_MOD_X_TILED) {
> -		int cpp = fb->format->cpp[0];
> -
> -		while ((*x + w) * cpp > plane_state->color_plane[0].stride) {
> -			if (*offset == 0) {
> -				drm_dbg_kms(&dev_priv->drm,
> -					    "Unable to find suitable display surface offset due to X-tiling\n");
> -				return -EINVAL;
> -			}
> -
> -			*offset = intel_plane_adjust_aligned_offset(x, y, plane_state, 0,
> -								    *offset,
> -								    *offset - alignment);
> -		}
> -	}
> -
> -	return 0;
> -}
> -
> -static int skl_check_main_surface(struct intel_plane_state *plane_state)
> -{
> -	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
> -	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> -	const struct drm_framebuffer *fb = plane_state->hw.fb;
> -	const unsigned int rotation = plane_state->hw.rotation;
> -	int x = plane_state->uapi.src.x1 >> 16;
> -	int y = plane_state->uapi.src.y1 >> 16;
> -	const int w = drm_rect_width(&plane_state->uapi.src) >> 16;
> -	const int h = drm_rect_height(&plane_state->uapi.src) >> 16;
> -	const int min_width = intel_plane_min_width(plane, fb, 0, rotation);
> -	const int max_width = intel_plane_max_width(plane, fb, 0, rotation);
> -	const int max_height = intel_plane_max_height(plane, fb, 0, rotation);
> -	const int aux_plane = intel_main_to_aux_plane(fb, 0);
> -	const u32 alignment = intel_surf_alignment(fb, 0);
> -	u32 offset;
> -	int ret;
> -
> -	if (w > max_width || w < min_width || h > max_height) {
> -		drm_dbg_kms(&dev_priv->drm,
> -			    "requested Y/RGB source size %dx%d outside limits (min: %dx1 max: %dx%d)\n",
> -			    w, h, min_width, max_width, max_height);
> -		return -EINVAL;
> -	}
> -
> -	ret = skl_calc_main_surface_offset(plane_state, &x, &y, &offset);
> -	if (ret)
> -		return ret;
> -
> -	/*
> -	 * CCS AUX surface doesn't have its own x/y offsets, we must make sure
> -	 * they match with the main surface x/y offsets.
> -	 */
> -	if (is_ccs_modifier(fb->modifier)) {
> -		while (!skl_check_main_ccs_coordinates(plane_state, x, y,
> -						       offset, aux_plane)) {
> -			if (offset == 0)
> -				break;
> -
> -			offset = intel_plane_adjust_aligned_offset(&x, &y, plane_state, 0,
> -								   offset, offset - alignment);
> -		}
> -
> -		if (x != plane_state->color_plane[aux_plane].x ||
> -		    y != plane_state->color_plane[aux_plane].y) {
> -			drm_dbg_kms(&dev_priv->drm,
> -				    "Unable to find suitable display surface offset due to CCS\n");
> -			return -EINVAL;
> -		}
> -	}
> -
> -	drm_WARN_ON(&dev_priv->drm, x > 8191 || y > 8191);
> -
> -	plane_state->color_plane[0].offset = offset;
> -	plane_state->color_plane[0].x = x;
> -	plane_state->color_plane[0].y = y;
> -
> -	/*
> -	 * Put the final coordinates back so that the src
> -	 * coordinate checks will see the right values.
> -	 */
> -	drm_rect_translate_to(&plane_state->uapi.src,
> -			      x << 16, y << 16);
> -
> -	return 0;
> -}
> -
> -static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state)
> -{
> -	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
> -	struct drm_i915_private *i915 = to_i915(plane->base.dev);
> -	const struct drm_framebuffer *fb = plane_state->hw.fb;
> -	unsigned int rotation = plane_state->hw.rotation;
> -	int uv_plane = 1;
> -	int max_width = intel_plane_max_width(plane, fb, uv_plane, rotation);
> -	int max_height = intel_plane_max_height(plane, fb, uv_plane, rotation);
> -	int x = plane_state->uapi.src.x1 >> 17;
> -	int y = plane_state->uapi.src.y1 >> 17;
> -	int w = drm_rect_width(&plane_state->uapi.src) >> 17;
> -	int h = drm_rect_height(&plane_state->uapi.src) >> 17;
> -	u32 offset;
> -
> -	/* FIXME not quite sure how/if these apply to the chroma plane */
> -	if (w > max_width || h > max_height) {
> -		drm_dbg_kms(&i915->drm,
> -			    "CbCr source size %dx%d too big (limit %dx%d)\n",
> -			    w, h, max_width, max_height);
> -		return -EINVAL;
> -	}
> -
> -	intel_add_fb_offsets(&x, &y, plane_state, uv_plane);
> -	offset = intel_plane_compute_aligned_offset(&x, &y,
> -						    plane_state, uv_plane);
> -
> -	if (is_ccs_modifier(fb->modifier)) {
> -		int ccs_plane = main_to_ccs_plane(fb, uv_plane);
> -		u32 aux_offset = plane_state->color_plane[ccs_plane].offset;
> -		u32 alignment = intel_surf_alignment(fb, uv_plane);
> -
> -		if (offset > aux_offset)
> -			offset = intel_plane_adjust_aligned_offset(&x, &y,
> -								   plane_state,
> -								   uv_plane,
> -								   offset,
> -								   aux_offset & ~(alignment - 1));
> -
> -		while (!skl_check_main_ccs_coordinates(plane_state, x, y,
> -						       offset, ccs_plane)) {
> -			if (offset == 0)
> -				break;
> -
> -			offset = intel_plane_adjust_aligned_offset(&x, &y,
> -								   plane_state,
> -								   uv_plane,
> -								   offset, offset - alignment);
> -		}
> -
> -		if (x != plane_state->color_plane[ccs_plane].x ||
> -		    y != plane_state->color_plane[ccs_plane].y) {
> -			drm_dbg_kms(&i915->drm,
> -				    "Unable to find suitable display surface offset due to CCS\n");
> -			return -EINVAL;
> -		}
> -	}
> -
> -	drm_WARN_ON(&i915->drm, x > 8191 || y > 8191);
> -
> -	plane_state->color_plane[uv_plane].offset = offset;
> -	plane_state->color_plane[uv_plane].x = x;
> -	plane_state->color_plane[uv_plane].y = y;
> -
> -	return 0;
> -}
> -
> -static int skl_check_ccs_aux_surface(struct intel_plane_state *plane_state)
> -{
> -	const struct drm_framebuffer *fb = plane_state->hw.fb;
> -	int src_x = plane_state->uapi.src.x1 >> 16;
> -	int src_y = plane_state->uapi.src.y1 >> 16;
> -	u32 offset;
> -	int ccs_plane;
> -
> -	for (ccs_plane = 0; ccs_plane < fb->format->num_planes; ccs_plane++) {
> -		int main_hsub, main_vsub;
> -		int hsub, vsub;
> -		int x, y;
> -
> -		if (!is_ccs_plane(fb, ccs_plane) ||
> -		    is_gen12_ccs_cc_plane(fb, ccs_plane))
> -			continue;
> -
> -		intel_fb_plane_get_subsampling(&main_hsub, &main_vsub, fb,
> -					       ccs_to_main_plane(fb, ccs_plane));
> -		intel_fb_plane_get_subsampling(&hsub, &vsub, fb, ccs_plane);
> -
> -		hsub *= main_hsub;
> -		vsub *= main_vsub;
> -		x = src_x / hsub;
> -		y = src_y / vsub;
> -
> -		intel_add_fb_offsets(&x, &y, plane_state, ccs_plane);
> -
> -		offset = intel_plane_compute_aligned_offset(&x, &y,
> -							    plane_state,
> -							    ccs_plane);
> -
> -		plane_state->color_plane[ccs_plane].offset = offset;
> -		plane_state->color_plane[ccs_plane].x = (x * hsub +
> -							 src_x % hsub) /
> -							main_hsub;
> -		plane_state->color_plane[ccs_plane].y = (y * vsub +
> -							 src_y % vsub) /
> -							main_vsub;
> -	}
> -
> -	return 0;
> -}
> -
> -int skl_check_plane_surface(struct intel_plane_state *plane_state)
> -{
> -	const struct drm_framebuffer *fb = plane_state->hw.fb;
> -	int ret, i;
> -
> -	ret = intel_plane_compute_gtt(plane_state);
> -	if (ret)
> -		return ret;
> -
> -	if (!plane_state->uapi.visible)
> -		return 0;
> -
> -	/*
> -	 * Handle the AUX surface first since the main surface setup depends on
> -	 * it.
> -	 */
> -	if (is_ccs_modifier(fb->modifier)) {
> -		ret = skl_check_ccs_aux_surface(plane_state);
> -		if (ret)
> -			return ret;
> -	}
> -
> -	if (intel_format_info_is_yuv_semiplanar(fb->format,
> -						fb->modifier)) {
> -		ret = skl_check_nv12_aux_surface(plane_state);
> -		if (ret)
> -			return ret;
> -	}
> -
> -	for (i = fb->format->num_planes; i < ARRAY_SIZE(plane_state->color_plane); i++) {
> -		plane_state->color_plane[i].offset = 0;
> -		plane_state->color_plane[i].x = 0;
> -		plane_state->color_plane[i].y = 0;
> -	}
> -
> -	ret = skl_check_main_surface(plane_state);
> -	if (ret)
> -		return ret;
> -
> -	return 0;
> -}
> -
>  static void skl_detach_scaler(struct intel_crtc *intel_crtc, int id)
>  {
>  	struct drm_device *dev = intel_crtc->base.dev;
> @@ -3292,307 +2817,6 @@ static void skl_detach_scalers(const struct intel_crtc_state *crtc_state)
>  	}
>  }
>  
> -static unsigned int skl_plane_stride_mult(const struct drm_framebuffer *fb,
> -					  int color_plane, unsigned int rotation)
> -{
> -	/*
> -	 * The stride is either expressed as a multiple of 64 bytes chunks for
> -	 * linear buffers or in number of tiles for tiled buffers.
> -	 */
> -	if (is_surface_linear(fb, color_plane))
> -		return 64;
> -	else if (drm_rotation_90_or_270(rotation))
> -		return intel_tile_height(fb, color_plane);
> -	else
> -		return intel_tile_width_bytes(fb, color_plane);
> -}
> -
> -u32 skl_plane_stride(const struct intel_plane_state *plane_state,
> -		     int color_plane)
> -{
> -	const struct drm_framebuffer *fb = plane_state->hw.fb;
> -	unsigned int rotation = plane_state->hw.rotation;
> -	u32 stride = plane_state->color_plane[color_plane].stride;
> -
> -	if (color_plane >= fb->format->num_planes)
> -		return 0;
> -
> -	return stride / skl_plane_stride_mult(fb, color_plane, rotation);
> -}
> -
> -static u32 skl_plane_ctl_format(u32 pixel_format)
> -{
> -	switch (pixel_format) {
> -	case DRM_FORMAT_C8:
> -		return PLANE_CTL_FORMAT_INDEXED;
> -	case DRM_FORMAT_RGB565:
> -		return PLANE_CTL_FORMAT_RGB_565;
> -	case DRM_FORMAT_XBGR8888:
> -	case DRM_FORMAT_ABGR8888:
> -		return PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX;
> -	case DRM_FORMAT_XRGB8888:
> -	case DRM_FORMAT_ARGB8888:
> -		return PLANE_CTL_FORMAT_XRGB_8888;
> -	case DRM_FORMAT_XBGR2101010:
> -	case DRM_FORMAT_ABGR2101010:
> -		return PLANE_CTL_FORMAT_XRGB_2101010 | PLANE_CTL_ORDER_RGBX;
> -	case DRM_FORMAT_XRGB2101010:
> -	case DRM_FORMAT_ARGB2101010:
> -		return PLANE_CTL_FORMAT_XRGB_2101010;
> -	case DRM_FORMAT_XBGR16161616F:
> -	case DRM_FORMAT_ABGR16161616F:
> -		return PLANE_CTL_FORMAT_XRGB_16161616F | PLANE_CTL_ORDER_RGBX;
> -	case DRM_FORMAT_XRGB16161616F:
> -	case DRM_FORMAT_ARGB16161616F:
> -		return PLANE_CTL_FORMAT_XRGB_16161616F;
> -	case DRM_FORMAT_XYUV8888:
> -		return PLANE_CTL_FORMAT_XYUV;
> -	case DRM_FORMAT_YUYV:
> -		return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YUYV;
> -	case DRM_FORMAT_YVYU:
> -		return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YVYU;
> -	case DRM_FORMAT_UYVY:
> -		return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY;
> -	case DRM_FORMAT_VYUY:
> -		return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY;
> -	case DRM_FORMAT_NV12:
> -		return PLANE_CTL_FORMAT_NV12;
> -	case DRM_FORMAT_P010:
> -		return PLANE_CTL_FORMAT_P010;
> -	case DRM_FORMAT_P012:
> -		return PLANE_CTL_FORMAT_P012;
> -	case DRM_FORMAT_P016:
> -		return PLANE_CTL_FORMAT_P016;
> -	case DRM_FORMAT_Y210:
> -		return PLANE_CTL_FORMAT_Y210;
> -	case DRM_FORMAT_Y212:
> -		return PLANE_CTL_FORMAT_Y212;
> -	case DRM_FORMAT_Y216:
> -		return PLANE_CTL_FORMAT_Y216;
> -	case DRM_FORMAT_XVYU2101010:
> -		return PLANE_CTL_FORMAT_Y410;
> -	case DRM_FORMAT_XVYU12_16161616:
> -		return PLANE_CTL_FORMAT_Y412;
> -	case DRM_FORMAT_XVYU16161616:
> -		return PLANE_CTL_FORMAT_Y416;
> -	default:
> -		MISSING_CASE(pixel_format);
> -	}
> -
> -	return 0;
> -}
> -
> -static u32 skl_plane_ctl_alpha(const struct intel_plane_state *plane_state)
> -{
> -	if (!plane_state->hw.fb->format->has_alpha)
> -		return PLANE_CTL_ALPHA_DISABLE;
> -
> -	switch (plane_state->hw.pixel_blend_mode) {
> -	case DRM_MODE_BLEND_PIXEL_NONE:
> -		return PLANE_CTL_ALPHA_DISABLE;
> -	case DRM_MODE_BLEND_PREMULTI:
> -		return PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> -	case DRM_MODE_BLEND_COVERAGE:
> -		return PLANE_CTL_ALPHA_HW_PREMULTIPLY;
> -	default:
> -		MISSING_CASE(plane_state->hw.pixel_blend_mode);
> -		return PLANE_CTL_ALPHA_DISABLE;
> -	}
> -}
> -
> -static u32 glk_plane_color_ctl_alpha(const struct intel_plane_state *plane_state)
> -{
> -	if (!plane_state->hw.fb->format->has_alpha)
> -		return PLANE_COLOR_ALPHA_DISABLE;
> -
> -	switch (plane_state->hw.pixel_blend_mode) {
> -	case DRM_MODE_BLEND_PIXEL_NONE:
> -		return PLANE_COLOR_ALPHA_DISABLE;
> -	case DRM_MODE_BLEND_PREMULTI:
> -		return PLANE_COLOR_ALPHA_SW_PREMULTIPLY;
> -	case DRM_MODE_BLEND_COVERAGE:
> -		return PLANE_COLOR_ALPHA_HW_PREMULTIPLY;
> -	default:
> -		MISSING_CASE(plane_state->hw.pixel_blend_mode);
> -		return PLANE_COLOR_ALPHA_DISABLE;
> -	}
> -}
> -
> -static u32 skl_plane_ctl_tiling(u64 fb_modifier)
> -{
> -	switch (fb_modifier) {
> -	case DRM_FORMAT_MOD_LINEAR:
> -		break;
> -	case I915_FORMAT_MOD_X_TILED:
> -		return PLANE_CTL_TILED_X;
> -	case I915_FORMAT_MOD_Y_TILED:
> -		return PLANE_CTL_TILED_Y;
> -	case I915_FORMAT_MOD_Y_TILED_CCS:
> -	case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC:
> -		return PLANE_CTL_TILED_Y | PLANE_CTL_RENDER_DECOMPRESSION_ENABLE;
> -	case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
> -		return PLANE_CTL_TILED_Y |
> -		       PLANE_CTL_RENDER_DECOMPRESSION_ENABLE |
> -		       PLANE_CTL_CLEAR_COLOR_DISABLE;
> -	case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
> -		return PLANE_CTL_TILED_Y | PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE;
> -	case I915_FORMAT_MOD_Yf_TILED:
> -		return PLANE_CTL_TILED_YF;
> -	case I915_FORMAT_MOD_Yf_TILED_CCS:
> -		return PLANE_CTL_TILED_YF | PLANE_CTL_RENDER_DECOMPRESSION_ENABLE;
> -	default:
> -		MISSING_CASE(fb_modifier);
> -	}
> -
> -	return 0;
> -}
> -
> -static u32 skl_plane_ctl_rotate(unsigned int rotate)
> -{
> -	switch (rotate) {
> -	case DRM_MODE_ROTATE_0:
> -		break;
> -	/*
> -	 * DRM_MODE_ROTATE_ is counter clockwise to stay compatible with Xrandr
> -	 * while i915 HW rotation is clockwise, thats why this swapping.
> -	 */
> -	case DRM_MODE_ROTATE_90:
> -		return PLANE_CTL_ROTATE_270;
> -	case DRM_MODE_ROTATE_180:
> -		return PLANE_CTL_ROTATE_180;
> -	case DRM_MODE_ROTATE_270:
> -		return PLANE_CTL_ROTATE_90;
> -	default:
> -		MISSING_CASE(rotate);
> -	}
> -
> -	return 0;
> -}
> -
> -static u32 cnl_plane_ctl_flip(unsigned int reflect)
> -{
> -	switch (reflect) {
> -	case 0:
> -		break;
> -	case DRM_MODE_REFLECT_X:
> -		return PLANE_CTL_FLIP_HORIZONTAL;
> -	case DRM_MODE_REFLECT_Y:
> -	default:
> -		MISSING_CASE(reflect);
> -	}
> -
> -	return 0;
> -}
> -
> -u32 skl_plane_ctl_crtc(const struct intel_crtc_state *crtc_state)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
> -	u32 plane_ctl = 0;
> -
> -	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> -		return plane_ctl;
> -
> -	if (crtc_state->gamma_enable)
> -		plane_ctl |= PLANE_CTL_PIPE_GAMMA_ENABLE;
> -
> -	if (crtc_state->csc_enable)
> -		plane_ctl |= PLANE_CTL_PIPE_CSC_ENABLE;
> -
> -	return plane_ctl;
> -}
> -
> -u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state,
> -		  const struct intel_plane_state *plane_state)
> -{
> -	struct drm_i915_private *dev_priv =
> -		to_i915(plane_state->uapi.plane->dev);
> -	const struct drm_framebuffer *fb = plane_state->hw.fb;
> -	unsigned int rotation = plane_state->hw.rotation;
> -	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
> -	u32 plane_ctl;
> -
> -	plane_ctl = PLANE_CTL_ENABLE;
> -
> -	if (INTEL_GEN(dev_priv) < 10 && !IS_GEMINILAKE(dev_priv)) {
> -		plane_ctl |= skl_plane_ctl_alpha(plane_state);
> -		plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
> -
> -		if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709)
> -			plane_ctl |= PLANE_CTL_YUV_TO_RGB_CSC_FORMAT_BT709;
> -
> -		if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
> -			plane_ctl |= PLANE_CTL_YUV_RANGE_CORRECTION_DISABLE;
> -	}
> -
> -	plane_ctl |= skl_plane_ctl_format(fb->format->format);
> -	plane_ctl |= skl_plane_ctl_tiling(fb->modifier);
> -	plane_ctl |= skl_plane_ctl_rotate(rotation & DRM_MODE_ROTATE_MASK);
> -
> -	if (INTEL_GEN(dev_priv) >= 10)
> -		plane_ctl |= cnl_plane_ctl_flip(rotation &
> -						DRM_MODE_REFLECT_MASK);
> -
> -	if (key->flags & I915_SET_COLORKEY_DESTINATION)
> -		plane_ctl |= PLANE_CTL_KEY_ENABLE_DESTINATION;
> -	else if (key->flags & I915_SET_COLORKEY_SOURCE)
> -		plane_ctl |= PLANE_CTL_KEY_ENABLE_SOURCE;
> -
> -	return plane_ctl;
> -}
> -
> -u32 glk_plane_color_ctl_crtc(const struct intel_crtc_state *crtc_state)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
> -	u32 plane_color_ctl = 0;
> -
> -	if (INTEL_GEN(dev_priv) >= 11)
> -		return plane_color_ctl;
> -
> -	if (crtc_state->gamma_enable)
> -		plane_color_ctl |= PLANE_COLOR_PIPE_GAMMA_ENABLE;
> -
> -	if (crtc_state->csc_enable)
> -		plane_color_ctl |= PLANE_COLOR_PIPE_CSC_ENABLE;
> -
> -	return plane_color_ctl;
> -}
> -
> -u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state,
> -			const struct intel_plane_state *plane_state)
> -{
> -	struct drm_i915_private *dev_priv =
> -		to_i915(plane_state->uapi.plane->dev);
> -	const struct drm_framebuffer *fb = plane_state->hw.fb;
> -	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
> -	u32 plane_color_ctl = 0;
> -
> -	plane_color_ctl |= PLANE_COLOR_PLANE_GAMMA_DISABLE;
> -	plane_color_ctl |= glk_plane_color_ctl_alpha(plane_state);
> -
> -	if (fb->format->is_yuv && !icl_is_hdr_plane(dev_priv, plane->id)) {
> -		switch (plane_state->hw.color_encoding) {
> -		case DRM_COLOR_YCBCR_BT709:
> -			plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709;
> -			break;
> -		case DRM_COLOR_YCBCR_BT2020:
> -			plane_color_ctl |=
> -				PLANE_COLOR_CSC_MODE_YUV2020_TO_RGB2020;
> -			break;
> -		default:
> -			plane_color_ctl |=
> -				PLANE_COLOR_CSC_MODE_YUV601_TO_RGB601;
> -		}
> -		if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
> -			plane_color_ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
> -	} else if (fb->format->is_yuv) {
> -		plane_color_ctl |= PLANE_COLOR_INPUT_CSC_ENABLE;
> -		if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
> -			plane_color_ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
> -	}
> -
> -	return plane_color_ctl;
> -}
> -
>  static int
>  __intel_display_resume(struct drm_device *dev,
>  		       struct drm_atomic_state *state,
> @@ -8276,150 +7500,6 @@ static void skl_get_pfit_config(struct intel_crtc_state *crtc_state)
>  		scaler_state->scaler_users &= ~(1 << SKL_CRTC_INDEX);
>  }
>  
> -static void
> -skl_get_initial_plane_config(struct intel_crtc *crtc,
> -			     struct intel_initial_plane_config *plane_config)
> -{
> -	struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state);
> -	struct drm_device *dev = crtc->base.dev;
> -	struct drm_i915_private *dev_priv = to_i915(dev);
> -	struct intel_plane *plane = to_intel_plane(crtc->base.primary);
> -	enum plane_id plane_id = plane->id;
> -	enum pipe pipe;
> -	u32 val, base, offset, stride_mult, tiling, alpha;
> -	int fourcc, pixel_format;
> -	unsigned int aligned_height;
> -	struct drm_framebuffer *fb;
> -	struct intel_framebuffer *intel_fb;
> -
> -	if (!plane->get_hw_state(plane, &pipe))
> -		return;
> -
> -	drm_WARN_ON(dev, pipe != crtc->pipe);
> -
> -	if (crtc_state->bigjoiner) {
> -		drm_dbg_kms(&dev_priv->drm,
> -			    "Unsupported bigjoiner configuration for initial FB\n");
> -		return;
> -	}
> -
> -	intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
> -	if (!intel_fb) {
> -		drm_dbg_kms(&dev_priv->drm, "failed to alloc fb\n");
> -		return;
> -	}
> -
> -	fb = &intel_fb->base;
> -
> -	fb->dev = dev;
> -
> -	val = intel_de_read(dev_priv, PLANE_CTL(pipe, plane_id));
> -
> -	if (INTEL_GEN(dev_priv) >= 11)
> -		pixel_format = val & ICL_PLANE_CTL_FORMAT_MASK;
> -	else
> -		pixel_format = val & PLANE_CTL_FORMAT_MASK;
> -
> -	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) {
> -		alpha = intel_de_read(dev_priv,
> -				      PLANE_COLOR_CTL(pipe, plane_id));
> -		alpha &= PLANE_COLOR_ALPHA_MASK;
> -	} else {
> -		alpha = val & PLANE_CTL_ALPHA_MASK;
> -	}
> -
> -	fourcc = skl_format_to_fourcc(pixel_format,
> -				      val & PLANE_CTL_ORDER_RGBX, alpha);
> -	fb->format = drm_format_info(fourcc);
> -
> -	tiling = val & PLANE_CTL_TILED_MASK;
> -	switch (tiling) {
> -	case PLANE_CTL_TILED_LINEAR:
> -		fb->modifier = DRM_FORMAT_MOD_LINEAR;
> -		break;
> -	case PLANE_CTL_TILED_X:
> -		plane_config->tiling = I915_TILING_X;
> -		fb->modifier = I915_FORMAT_MOD_X_TILED;
> -		break;
> -	case PLANE_CTL_TILED_Y:
> -		plane_config->tiling = I915_TILING_Y;
> -		if (val & PLANE_CTL_RENDER_DECOMPRESSION_ENABLE)
> -			fb->modifier = INTEL_GEN(dev_priv) >= 12 ?
> -				I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS :
> -				I915_FORMAT_MOD_Y_TILED_CCS;
> -		else if (val & PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE)
> -			fb->modifier = I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS;
> -		else
> -			fb->modifier = I915_FORMAT_MOD_Y_TILED;
> -		break;
> -	case PLANE_CTL_TILED_YF:
> -		if (val & PLANE_CTL_RENDER_DECOMPRESSION_ENABLE)
> -			fb->modifier = I915_FORMAT_MOD_Yf_TILED_CCS;
> -		else
> -			fb->modifier = I915_FORMAT_MOD_Yf_TILED;
> -		break;
> -	default:
> -		MISSING_CASE(tiling);
> -		goto error;
> -	}
> -
> -	/*
> -	 * DRM_MODE_ROTATE_ is counter clockwise to stay compatible with Xrandr
> -	 * while i915 HW rotation is clockwise, thats why this swapping.
> -	 */
> -	switch (val & PLANE_CTL_ROTATE_MASK) {
> -	case PLANE_CTL_ROTATE_0:
> -		plane_config->rotation = DRM_MODE_ROTATE_0;
> -		break;
> -	case PLANE_CTL_ROTATE_90:
> -		plane_config->rotation = DRM_MODE_ROTATE_270;
> -		break;
> -	case PLANE_CTL_ROTATE_180:
> -		plane_config->rotation = DRM_MODE_ROTATE_180;
> -		break;
> -	case PLANE_CTL_ROTATE_270:
> -		plane_config->rotation = DRM_MODE_ROTATE_90;
> -		break;
> -	}
> -
> -	if (INTEL_GEN(dev_priv) >= 10 &&
> -	    val & PLANE_CTL_FLIP_HORIZONTAL)
> -		plane_config->rotation |= DRM_MODE_REFLECT_X;
> -
> -	/* 90/270 degree rotation would require extra work */
> -	if (drm_rotation_90_or_270(plane_config->rotation))
> -		goto error;
> -
> -	base = intel_de_read(dev_priv, PLANE_SURF(pipe, plane_id)) & 0xfffff000;
> -	plane_config->base = base;
> -
> -	offset = intel_de_read(dev_priv, PLANE_OFFSET(pipe, plane_id));
> -
> -	val = intel_de_read(dev_priv, PLANE_SIZE(pipe, plane_id));
> -	fb->height = ((val >> 16) & 0xffff) + 1;
> -	fb->width = ((val >> 0) & 0xffff) + 1;
> -
> -	val = intel_de_read(dev_priv, PLANE_STRIDE(pipe, plane_id));
> -	stride_mult = skl_plane_stride_mult(fb, 0, DRM_MODE_ROTATE_0);
> -	fb->pitches[0] = (val & 0x3ff) * stride_mult;
> -
> -	aligned_height = intel_fb_align_height(fb, 0, fb->height);
> -
> -	plane_config->size = fb->pitches[0] * aligned_height;
> -
> -	drm_dbg_kms(&dev_priv->drm,
> -		    "%s/%s with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
> -		    crtc->base.name, plane->base.name, fb->width, fb->height,
> -		    fb->format->cpp[0] * 8, base, fb->pitches[0],
> -		    plane_config->size);
> -
> -	plane_config->fb = intel_fb;
> -	return;
> -
> -error:
> -	kfree(intel_fb);
> -}
> -
>  static void ilk_get_pfit_config(struct intel_crtc_state *crtc_state)
>  {
>  	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
> index c72e41b61349..3c153eb78092 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.h
> +++ b/drivers/gpu/drm/i915/display/intel_display.h
> @@ -52,6 +52,7 @@ struct intel_crtc_state;
>  struct intel_digital_port;
>  struct intel_dp;
>  struct intel_encoder;
> +struct intel_initial_plane_config;
>  struct intel_load_detect_pipe;
>  struct intel_plane;
>  struct intel_plane_state;
> @@ -517,7 +518,6 @@ void intel_link_compute_m_n(u16 bpp, int nlanes,
>  			    struct intel_link_m_n *m_n,
>  			    bool constant_n, bool fec_enable);
>  bool is_ccs_modifier(u64 modifier);
> -int intel_main_to_aux_plane(const struct drm_framebuffer *fb, int main_plane);
>  void lpt_disable_clkout_dp(struct drm_i915_private *dev_priv);
>  u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv,
>  			      u32 pixel_format, u64 modifier);
> @@ -629,18 +629,7 @@ u32 skl_scaler_get_filter_select(enum drm_scaling_filter filter, int set);
>  void skl_scaler_setup_filter(struct drm_i915_private *dev_priv, enum pipe pipe,
>  			     int id, int set, enum drm_scaling_filter filter);
>  void ilk_pfit_disable(const struct intel_crtc_state *old_crtc_state);
> -u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state,
> -			const struct intel_plane_state *plane_state);
> -u32 glk_plane_color_ctl_crtc(const struct intel_crtc_state *crtc_state);
> -u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state,
> -		  const struct intel_plane_state *plane_state);
> -u32 skl_plane_ctl_crtc(const struct intel_crtc_state *crtc_state);
> -u32 skl_plane_stride(const struct intel_plane_state *plane_state,
> -		     int plane);
> -int skl_check_plane_surface(struct intel_plane_state *plane_state);
> -int skl_calc_main_surface_offset(const struct intel_plane_state *plane_state,
> -				 int *x, int *y, u32 *offset);
> -int skl_format_to_fourcc(int format, bool rgb_order, bool alpha);
> +
>  int bdw_get_pipemisc_bpp(struct intel_crtc *crtc);
>  unsigned int intel_plane_fence_y_offset(const struct intel_plane_state *plane_state);
>  
> @@ -663,6 +652,18 @@ struct intel_encoder *
>  intel_get_crtc_new_encoder(const struct intel_atomic_state *state,
>  			   const struct intel_crtc_state *crtc_state);
>  
> +unsigned int intel_surf_alignment(const struct drm_framebuffer *fb,
> +				  int color_plane);
> +void intel_fb_plane_get_subsampling(int *hsub, int *vsub,
> +				    const struct drm_framebuffer *fb,
> +				    int color_plane);
> +u32 intel_plane_adjust_aligned_offset(int *x, int *y,
> +				      const struct intel_plane_state *state,
> +				      int color_plane,
> +				      u32 old_offset, u32 new_offset);
> +unsigned int intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane);
> +unsigned int intel_tile_height(const struct drm_framebuffer *fb, int color_plane);
> +
>  /* modesetting */
>  void intel_modeset_init_hw(struct drm_i915_private *i915);
>  int intel_modeset_init_noirq(struct drm_i915_private *i915);
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 307ff4b771f4..6183f2f0424b 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -37,6 +37,7 @@
>  #include <drm/drm_dp_mst_helper.h>
>  #include <drm/drm_encoder.h>
>  #include <drm/drm_fb_helper.h>
> +#include <drm/drm_fourcc.h>
>  #include <drm/drm_probe_helper.h>
>  #include <drm/drm_rect.h>
>  #include <drm/drm_vblank.h>
> @@ -1945,4 +1946,30 @@ static inline u32 intel_fdi_link_freq(struct drm_i915_private *dev_priv,
>  		return dev_priv->fdi_pll_freq;
>  }
>  
> +static inline bool is_ccs_plane(const struct drm_framebuffer *fb, int plane)
> +{
> +	if (!is_ccs_modifier(fb->modifier))
> +		return false;
> +
> +	return plane >= fb->format->num_planes / 2;
> +}
> +
> +static inline bool is_gen12_ccs_modifier(u64 modifier)
> +{
> +	return modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS ||
> +	       modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC ||
> +	       modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS;
> +}
> +
> +static inline bool is_gen12_ccs_plane(const struct drm_framebuffer *fb, int plane)
> +{
> +	return is_gen12_ccs_modifier(fb->modifier) && is_ccs_plane(fb, plane);
> +}
> +
> +static inline bool is_gen12_ccs_cc_plane(const struct drm_framebuffer *fb, int plane)
> +{
> +	return fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC &&
> +	       plane == 2;
> +}
> +
>  #endif /*  __INTEL_DISPLAY_TYPES_H__ */
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
> index 28423356d53b..bf214d0e2dec 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -32,6 +32,7 @@
>  #include "intel_hdmi.h"
>  #include "intel_psr.h"
>  #include "intel_sprite.h"
> +#include "skl_universal_plane.h"
>  
>  /**
>   * DOC: Panel Self Refresh (PSR/SRD)
> diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
> index 26025251b038..93f3afc245b9 100644
> --- a/drivers/gpu/drm/i915/display/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/display/intel_sprite.c
> @@ -376,212 +376,7 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
>  	return 0;
>  }
>  
> -static u8 icl_nv12_y_plane_mask(struct drm_i915_private *i915)
> -{
> -	if (HAS_D12_PLANE_MINIMIZATION(i915))
> -		return BIT(PLANE_SPRITE2) | BIT(PLANE_SPRITE3);
> -	else
> -		return BIT(PLANE_SPRITE4) | BIT(PLANE_SPRITE5);
> -}
> -
> -bool icl_is_nv12_y_plane(struct drm_i915_private *dev_priv,
> -			 enum plane_id plane_id)
> -{
> -	return INTEL_GEN(dev_priv) >= 11 &&
> -		icl_nv12_y_plane_mask(dev_priv) & BIT(plane_id);
> -}
> -
> -bool icl_is_hdr_plane(struct drm_i915_private *dev_priv, enum plane_id plane_id)
> -{
> -	return INTEL_GEN(dev_priv) >= 11 &&
> -		icl_hdr_plane_mask() & BIT(plane_id);
> -}
> -
> -static void
> -skl_plane_ratio(const struct intel_crtc_state *crtc_state,
> -		const struct intel_plane_state *plane_state,
> -		unsigned int *num, unsigned int *den)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(plane_state->uapi.plane->dev);
> -	const struct drm_framebuffer *fb = plane_state->hw.fb;
> -
> -	if (fb->format->cpp[0] == 8) {
> -		if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) {
> -			*num = 10;
> -			*den = 8;
> -		} else {
> -			*num = 9;
> -			*den = 8;
> -		}
> -	} else {
> -		*num = 1;
> -		*den = 1;
> -	}
> -}
> -
> -static int skl_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
> -			       const struct intel_plane_state *plane_state)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(plane_state->uapi.plane->dev);
> -	unsigned int num, den;
> -	unsigned int pixel_rate = intel_plane_pixel_rate(crtc_state, plane_state);
> -
> -	skl_plane_ratio(crtc_state, plane_state, &num, &den);
> -
> -	/* two pixels per clock on glk+ */
> -	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> -		den *= 2;
> -
> -	return DIV_ROUND_UP(pixel_rate * num, den);
> -}
> -
> -static int skl_plane_max_width(const struct drm_framebuffer *fb,
> -			       int color_plane,
> -			       unsigned int rotation)
> -{
> -	int cpp = fb->format->cpp[color_plane];
> -
> -	switch (fb->modifier) {
> -	case DRM_FORMAT_MOD_LINEAR:
> -	case I915_FORMAT_MOD_X_TILED:
> -		/*
> -		 * Validated limit is 4k, but has 5k should
> -		 * work apart from the following features:
> -		 * - Ytile (already limited to 4k)
> -		 * - FP16 (already limited to 4k)
> -		 * - render compression (already limited to 4k)
> -		 * - KVMR sprite and cursor (don't care)
> -		 * - horizontal panning (TODO verify this)
> -		 * - pipe and plane scaling (TODO verify this)
> -		 */
> -		if (cpp == 8)
> -			return 4096;
> -		else
> -			return 5120;
> -	case I915_FORMAT_MOD_Y_TILED_CCS:
> -	case I915_FORMAT_MOD_Yf_TILED_CCS:
> -	case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
> -		/* FIXME AUX plane? */
> -	case I915_FORMAT_MOD_Y_TILED:
> -	case I915_FORMAT_MOD_Yf_TILED:
> -		if (cpp == 8)
> -			return 2048;
> -		else
> -			return 4096;
> -	default:
> -		MISSING_CASE(fb->modifier);
> -		return 2048;
> -	}
> -}
> -
> -static int glk_plane_max_width(const struct drm_framebuffer *fb,
> -			       int color_plane,
> -			       unsigned int rotation)
> -{
> -	int cpp = fb->format->cpp[color_plane];
> -
> -	switch (fb->modifier) {
> -	case DRM_FORMAT_MOD_LINEAR:
> -	case I915_FORMAT_MOD_X_TILED:
> -		if (cpp == 8)
> -			return 4096;
> -		else
> -			return 5120;
> -	case I915_FORMAT_MOD_Y_TILED_CCS:
> -	case I915_FORMAT_MOD_Yf_TILED_CCS:
> -		/* FIXME AUX plane? */
> -	case I915_FORMAT_MOD_Y_TILED:
> -	case I915_FORMAT_MOD_Yf_TILED:
> -		if (cpp == 8)
> -			return 2048;
> -		else
> -			return 5120;
> -	default:
> -		MISSING_CASE(fb->modifier);
> -		return 2048;
> -	}
> -}
> -
> -static int icl_plane_min_width(const struct drm_framebuffer *fb,
> -			       int color_plane,
> -			       unsigned int rotation)
> -{
> -	/* Wa_14011264657, Wa_14011050563: gen11+ */
> -	switch (fb->format->format) {
> -	case DRM_FORMAT_C8:
> -		return 18;
> -	case DRM_FORMAT_RGB565:
> -		return 10;
> -	case DRM_FORMAT_XRGB8888:
> -	case DRM_FORMAT_XBGR8888:
> -	case DRM_FORMAT_ARGB8888:
> -	case DRM_FORMAT_ABGR8888:
> -	case DRM_FORMAT_XRGB2101010:
> -	case DRM_FORMAT_XBGR2101010:
> -	case DRM_FORMAT_ARGB2101010:
> -	case DRM_FORMAT_ABGR2101010:
> -	case DRM_FORMAT_XVYU2101010:
> -	case DRM_FORMAT_Y212:
> -	case DRM_FORMAT_Y216:
> -		return 6;
> -	case DRM_FORMAT_NV12:
> -		return 20;
> -	case DRM_FORMAT_P010:
> -	case DRM_FORMAT_P012:
> -	case DRM_FORMAT_P016:
> -		return 12;
> -	case DRM_FORMAT_XRGB16161616F:
> -	case DRM_FORMAT_XBGR16161616F:
> -	case DRM_FORMAT_ARGB16161616F:
> -	case DRM_FORMAT_ABGR16161616F:
> -	case DRM_FORMAT_XVYU12_16161616:
> -	case DRM_FORMAT_XVYU16161616:
> -		return 4;
> -	default:
> -		return 1;
> -	}
> -}
> -
> -static int icl_plane_max_width(const struct drm_framebuffer *fb,
> -			       int color_plane,
> -			       unsigned int rotation)
> -{
> -	return 5120;
> -}
> -
> -static int skl_plane_max_height(const struct drm_framebuffer *fb,
> -				int color_plane,
> -				unsigned int rotation)
> -{
> -	return 4096;
> -}
> -
> -static int icl_plane_max_height(const struct drm_framebuffer *fb,
> -				int color_plane,
> -				unsigned int rotation)
> -{
> -	return 4320;
> -}
> -
> -static unsigned int
> -skl_plane_max_stride(struct intel_plane *plane,
> -		     u32 pixel_format, u64 modifier,
> -		     unsigned int rotation)
> -{
> -	const struct drm_format_info *info = drm_format_info(pixel_format);
> -	int cpp = info->cpp[0];
> -
> -	/*
> -	 * "The stride in bytes must not exceed the
> -	 * of the size of 8K pixels and 32K bytes."
> -	 */
> -	if (drm_rotation_90_or_270(rotation))
> -		return min(8192, 32768 / cpp);
> -	else
> -		return min(8192 * cpp, 32768);
> -}
> -
> -static void
> +void
>  skl_program_scaler(struct intel_plane *plane,
>  		   const struct intel_crtc_state *crtc_state,
>  		   const struct intel_plane_state *plane_state)
> @@ -643,317 +438,6 @@ skl_program_scaler(struct intel_plane *plane,
>  			  (crtc_w << 16) | crtc_h);
>  }
>  
> -/* Preoffset values for YUV to RGB Conversion */
> -#define PREOFF_YUV_TO_RGB_HI		0x1800
> -#define PREOFF_YUV_TO_RGB_ME		0x0000
> -#define PREOFF_YUV_TO_RGB_LO		0x1800
> -
> -#define  ROFF(x)          (((x) & 0xffff) << 16)
> -#define  GOFF(x)          (((x) & 0xffff) << 0)
> -#define  BOFF(x)          (((x) & 0xffff) << 16)
> -
> -/*
> - * Programs the input color space conversion stage for ICL HDR planes.
> - * Note that it is assumed that this stage always happens after YUV
> - * range correction. Thus, the input to this stage is assumed to be
> - * in full-range YCbCr.
> - */
> -static void
> -icl_program_input_csc(struct intel_plane *plane,
> -		      const struct intel_crtc_state *crtc_state,
> -		      const struct intel_plane_state *plane_state)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> -	enum pipe pipe = plane->pipe;
> -	enum plane_id plane_id = plane->id;
> -
> -	static const u16 input_csc_matrix[][9] = {
> -		/*
> -		 * BT.601 full range YCbCr -> full range RGB
> -		 * The matrix required is :
> -		 * [1.000, 0.000, 1.371,
> -		 *  1.000, -0.336, -0.698,
> -		 *  1.000, 1.732, 0.0000]
> -		 */
> -		[DRM_COLOR_YCBCR_BT601] = {
> -			0x7AF8, 0x7800, 0x0,
> -			0x8B28, 0x7800, 0x9AC0,
> -			0x0, 0x7800, 0x7DD8,
> -		},
> -		/*
> -		 * BT.709 full range YCbCr -> full range RGB
> -		 * The matrix required is :
> -		 * [1.000, 0.000, 1.574,
> -		 *  1.000, -0.187, -0.468,
> -		 *  1.000, 1.855, 0.0000]
> -		 */
> -		[DRM_COLOR_YCBCR_BT709] = {
> -			0x7C98, 0x7800, 0x0,
> -			0x9EF8, 0x7800, 0xAC00,
> -			0x0, 0x7800,  0x7ED8,
> -		},
> -		/*
> -		 * BT.2020 full range YCbCr -> full range RGB
> -		 * The matrix required is :
> -		 * [1.000, 0.000, 1.474,
> -		 *  1.000, -0.1645, -0.5713,
> -		 *  1.000, 1.8814, 0.0000]
> -		 */
> -		[DRM_COLOR_YCBCR_BT2020] = {
> -			0x7BC8, 0x7800, 0x0,
> -			0x8928, 0x7800, 0xAA88,
> -			0x0, 0x7800, 0x7F10,
> -		},
> -	};
> -	const u16 *csc = input_csc_matrix[plane_state->hw.color_encoding];
> -
> -	intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 0),
> -			  ROFF(csc[0]) | GOFF(csc[1]));
> -	intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 1),
> -			  BOFF(csc[2]));
> -	intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 2),
> -			  ROFF(csc[3]) | GOFF(csc[4]));
> -	intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 3),
> -			  BOFF(csc[5]));
> -	intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 4),
> -			  ROFF(csc[6]) | GOFF(csc[7]));
> -	intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 5),
> -			  BOFF(csc[8]));
> -
> -	intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 0),
> -			  PREOFF_YUV_TO_RGB_HI);
> -	intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1),
> -			  PREOFF_YUV_TO_RGB_ME);
> -	intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 2),
> -			  PREOFF_YUV_TO_RGB_LO);
> -	intel_de_write_fw(dev_priv,
> -			  PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 0), 0x0);
> -	intel_de_write_fw(dev_priv,
> -			  PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 1), 0x0);
> -	intel_de_write_fw(dev_priv,
> -			  PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 2), 0x0);
> -}
> -
> -static void
> -skl_plane_async_flip(struct intel_plane *plane,
> -		     const struct intel_crtc_state *crtc_state,
> -		     const struct intel_plane_state *plane_state,
> -		     bool async_flip)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> -	unsigned long irqflags;
> -	enum plane_id plane_id = plane->id;
> -	enum pipe pipe = plane->pipe;
> -	u32 surf_addr = plane_state->color_plane[0].offset;
> -	u32 plane_ctl = plane_state->ctl;
> -
> -	plane_ctl |= skl_plane_ctl_crtc(crtc_state);
> -
> -	if (async_flip)
> -		plane_ctl |= PLANE_CTL_ASYNC_FLIP;
> -
> -	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> -
> -	intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
> -	intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id),
> -			  intel_plane_ggtt_offset(plane_state) + surf_addr);
> -
> -	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
> -}
> -
> -static void
> -skl_program_plane(struct intel_plane *plane,
> -		  const struct intel_crtc_state *crtc_state,
> -		  const struct intel_plane_state *plane_state,
> -		  int color_plane)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> -	enum plane_id plane_id = plane->id;
> -	enum pipe pipe = plane->pipe;
> -	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
> -	u32 surf_addr = plane_state->color_plane[color_plane].offset;
> -	u32 stride = skl_plane_stride(plane_state, color_plane);
> -	const struct drm_framebuffer *fb = plane_state->hw.fb;
> -	int aux_plane = intel_main_to_aux_plane(fb, color_plane);
> -	int crtc_x = plane_state->uapi.dst.x1;
> -	int crtc_y = plane_state->uapi.dst.y1;
> -	u32 x = plane_state->color_plane[color_plane].x;
> -	u32 y = plane_state->color_plane[color_plane].y;
> -	u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
> -	u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
> -	u8 alpha = plane_state->hw.alpha >> 8;
> -	u32 plane_color_ctl = 0, aux_dist = 0;
> -	unsigned long irqflags;
> -	u32 keymsk, keymax;
> -	u32 plane_ctl = plane_state->ctl;
> -
> -	plane_ctl |= skl_plane_ctl_crtc(crtc_state);
> -
> -	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> -		plane_color_ctl = plane_state->color_ctl |
> -			glk_plane_color_ctl_crtc(crtc_state);
> -
> -	/* Sizes are 0 based */
> -	src_w--;
> -	src_h--;
> -
> -	keymax = (key->max_value & 0xffffff) | PLANE_KEYMAX_ALPHA(alpha);
> -
> -	keymsk = key->channel_mask & 0x7ffffff;
> -	if (alpha < 0xff)
> -		keymsk |= PLANE_KEYMSK_ALPHA_ENABLE;
> -
> -	/* The scaler will handle the output position */
> -	if (plane_state->scaler_id >= 0) {
> -		crtc_x = 0;
> -		crtc_y = 0;
> -	}
> -
> -	if (aux_plane) {
> -		aux_dist = plane_state->color_plane[aux_plane].offset - surf_addr;
> -
> -		if (INTEL_GEN(dev_priv) < 12)
> -			aux_dist |= skl_plane_stride(plane_state, aux_plane);
> -	}
> -
> -	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> -
> -	intel_de_write_fw(dev_priv, PLANE_STRIDE(pipe, plane_id), stride);
> -	intel_de_write_fw(dev_priv, PLANE_POS(pipe, plane_id),
> -			  (crtc_y << 16) | crtc_x);
> -	intel_de_write_fw(dev_priv, PLANE_SIZE(pipe, plane_id),
> -			  (src_h << 16) | src_w);
> -
> -	intel_de_write_fw(dev_priv, PLANE_AUX_DIST(pipe, plane_id), aux_dist);
> -
> -	if (icl_is_hdr_plane(dev_priv, plane_id))
> -		intel_de_write_fw(dev_priv, PLANE_CUS_CTL(pipe, plane_id),
> -				  plane_state->cus_ctl);
> -
> -	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> -		intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id),
> -				  plane_color_ctl);
> -
> -	if (fb->format->is_yuv && icl_is_hdr_plane(dev_priv, plane_id))
> -		icl_program_input_csc(plane, crtc_state, plane_state);
> -
> -	if (fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC)
> -		intel_uncore_write64_fw(&dev_priv->uncore,
> -					PLANE_CC_VAL(pipe, plane_id), plane_state->ccval);
> -
> -	skl_write_plane_wm(plane, crtc_state);
> -
> -	intel_de_write_fw(dev_priv, PLANE_KEYVAL(pipe, plane_id),
> -			  key->min_value);
> -	intel_de_write_fw(dev_priv, PLANE_KEYMSK(pipe, plane_id), keymsk);
> -	intel_de_write_fw(dev_priv, PLANE_KEYMAX(pipe, plane_id), keymax);
> -
> -	intel_de_write_fw(dev_priv, PLANE_OFFSET(pipe, plane_id),
> -			  (y << 16) | x);
> -
> -	if (INTEL_GEN(dev_priv) < 11)
> -		intel_de_write_fw(dev_priv, PLANE_AUX_OFFSET(pipe, plane_id),
> -				  (plane_state->color_plane[1].y << 16) | plane_state->color_plane[1].x);
> -
> -	if (!drm_atomic_crtc_needs_modeset(&crtc_state->uapi))
> -		intel_psr2_program_plane_sel_fetch(plane, crtc_state, plane_state, color_plane);
> -
> -	/*
> -	 * The control register self-arms if the plane was previously
> -	 * disabled. Try to make the plane enable atomic by writing
> -	 * the control register just before the surface register.
> -	 */
> -	intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
> -	intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id),
> -			  intel_plane_ggtt_offset(plane_state) + surf_addr);
> -
> -	if (plane_state->scaler_id >= 0)
> -		skl_program_scaler(plane, crtc_state, plane_state);
> -
> -	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
> -}
> -
> -static void
> -skl_update_plane(struct intel_plane *plane,
> -		 const struct intel_crtc_state *crtc_state,
> -		 const struct intel_plane_state *plane_state)
> -{
> -	int color_plane = 0;
> -
> -	if (plane_state->planar_linked_plane && !plane_state->planar_slave)
> -		/* Program the UV plane on planar master */
> -		color_plane = 1;
> -
> -	skl_program_plane(plane, crtc_state, plane_state, color_plane);
> -}
> -static void
> -skl_disable_plane(struct intel_plane *plane,
> -		  const struct intel_crtc_state *crtc_state)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> -	enum plane_id plane_id = plane->id;
> -	enum pipe pipe = plane->pipe;
> -	unsigned long irqflags;
> -
> -	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> -
> -	if (icl_is_hdr_plane(dev_priv, plane_id))
> -		intel_de_write_fw(dev_priv, PLANE_CUS_CTL(pipe, plane_id), 0);
> -
> -	skl_write_plane_wm(plane, crtc_state);
> -
> -	intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0);
> -	intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0);
> -
> -	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
> -}
> -
> -static bool
> -skl_plane_get_hw_state(struct intel_plane *plane,
> -		       enum pipe *pipe)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> -	enum intel_display_power_domain power_domain;
> -	enum plane_id plane_id = plane->id;
> -	intel_wakeref_t wakeref;
> -	bool ret;
> -
> -	power_domain = POWER_DOMAIN_PIPE(plane->pipe);
> -	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
> -	if (!wakeref)
> -		return false;
> -
> -	ret = intel_de_read(dev_priv, PLANE_CTL(plane->pipe, plane_id)) & PLANE_CTL_ENABLE;
> -
> -	*pipe = plane->pipe;
> -
> -	intel_display_power_put(dev_priv, power_domain, wakeref);
> -
> -	return ret;
> -}
> -
> -static void
> -skl_plane_enable_flip_done(struct intel_plane *plane)
> -{
> -	struct drm_i915_private *i915 = to_i915(plane->base.dev);
> -	enum pipe pipe = plane->pipe;
> -
> -	spin_lock_irq(&i915->irq_lock);
> -	bdw_enable_pipe_irq(i915, pipe, GEN9_PIPE_PLANE_FLIP_DONE(plane->id));
> -	spin_unlock_irq(&i915->irq_lock);
> -}
> -
> -static void
> -skl_plane_disable_flip_done(struct intel_plane *plane)
> -{
> -	struct drm_i915_private *i915 = to_i915(plane->base.dev);
> -	enum pipe pipe = plane->pipe;
> -
> -	spin_lock_irq(&i915->irq_lock);
> -	bdw_disable_pipe_irq(i915, pipe, GEN9_PIPE_PLANE_FLIP_DONE(plane->id));
> -	spin_unlock_irq(&i915->irq_lock);
> -}
> -
>  static void i9xx_plane_linear_gamma(u16 gamma[8])
>  {
>  	/* The points are not evenly spaced. */
> @@ -2297,253 +1781,19 @@ vlv_sprite_check(struct intel_crtc_state *crtc_state,
>  	return 0;
>  }
>  
> -static bool intel_format_is_p01x(u32 format)
> +static bool has_dst_key_in_primary_plane(struct drm_i915_private *dev_priv)
>  {
> -	switch (format) {
> -	case DRM_FORMAT_P010:
> -	case DRM_FORMAT_P012:
> -	case DRM_FORMAT_P016:
> -		return true;
> -	default:
> -		return false;
> -	}
> +	return INTEL_GEN(dev_priv) >= 9;
>  }
>  
> -static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
> -			      const struct intel_plane_state *plane_state)
> +static void intel_plane_set_ckey(struct intel_plane_state *plane_state,
> +				 const struct drm_intel_sprite_colorkey *set)
>  {
>  	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
>  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> -	const struct drm_framebuffer *fb = plane_state->hw.fb;
> -	unsigned int rotation = plane_state->hw.rotation;
> -	struct drm_format_name_buf format_name;
> +	struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
>  
> -	if (!fb)
> -		return 0;
> -
> -	if (rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180) &&
> -	    is_ccs_modifier(fb->modifier)) {
> -		drm_dbg_kms(&dev_priv->drm,
> -			    "RC support only with 0/180 degree rotation (%x)\n",
> -			    rotation);
> -		return -EINVAL;
> -	}
> -
> -	if (rotation & DRM_MODE_REFLECT_X &&
> -	    fb->modifier == DRM_FORMAT_MOD_LINEAR) {
> -		drm_dbg_kms(&dev_priv->drm,
> -			    "horizontal flip is not supported with linear surface formats\n");
> -		return -EINVAL;
> -	}
> -
> -	if (drm_rotation_90_or_270(rotation)) {
> -		if (fb->modifier != I915_FORMAT_MOD_Y_TILED &&
> -		    fb->modifier != I915_FORMAT_MOD_Yf_TILED) {
> -			drm_dbg_kms(&dev_priv->drm,
> -				    "Y/Yf tiling required for 90/270!\n");
> -			return -EINVAL;
> -		}
> -
> -		/*
> -		 * 90/270 is not allowed with RGB64 16:16:16:16 and
> -		 * Indexed 8-bit. RGB 16-bit 5:6:5 is allowed gen11 onwards.
> -		 */
> -		switch (fb->format->format) {
> -		case DRM_FORMAT_RGB565:
> -			if (INTEL_GEN(dev_priv) >= 11)
> -				break;
> -			fallthrough;
> -		case DRM_FORMAT_C8:
> -		case DRM_FORMAT_XRGB16161616F:
> -		case DRM_FORMAT_XBGR16161616F:
> -		case DRM_FORMAT_ARGB16161616F:
> -		case DRM_FORMAT_ABGR16161616F:
> -		case DRM_FORMAT_Y210:
> -		case DRM_FORMAT_Y212:
> -		case DRM_FORMAT_Y216:
> -		case DRM_FORMAT_XVYU12_16161616:
> -		case DRM_FORMAT_XVYU16161616:
> -			drm_dbg_kms(&dev_priv->drm,
> -				    "Unsupported pixel format %s for 90/270!\n",
> -				    drm_get_format_name(fb->format->format,
> -							&format_name));
> -			return -EINVAL;
> -		default:
> -			break;
> -		}
> -	}
> -
> -	/* Y-tiling is not supported in IF-ID Interlace mode */
> -	if (crtc_state->hw.enable &&
> -	    crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE &&
> -	    (fb->modifier == I915_FORMAT_MOD_Y_TILED ||
> -	     fb->modifier == I915_FORMAT_MOD_Yf_TILED ||
> -	     fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
> -	     fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS ||
> -	     fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS ||
> -	     fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS ||
> -	     fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC)) {
> -		drm_dbg_kms(&dev_priv->drm,
> -			    "Y/Yf tiling not supported in IF-ID mode\n");
> -		return -EINVAL;
> -	}
> -
> -	/* Wa_1606054188:tgl,adl-s */
> -	if ((IS_ALDERLAKE_S(dev_priv) || IS_TIGERLAKE(dev_priv)) &&
> -	    plane_state->ckey.flags & I915_SET_COLORKEY_SOURCE &&
> -	    intel_format_is_p01x(fb->format->format)) {
> -		drm_dbg_kms(&dev_priv->drm,
> -			    "Source color keying not supported with P01x formats\n");
> -		return -EINVAL;
> -	}
> -
> -	return 0;
> -}
> -
> -static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_state,
> -					   const struct intel_plane_state *plane_state)
> -{
> -	struct drm_i915_private *dev_priv =
> -		to_i915(plane_state->uapi.plane->dev);
> -	int crtc_x = plane_state->uapi.dst.x1;
> -	int crtc_w = drm_rect_width(&plane_state->uapi.dst);
> -	int pipe_src_w = crtc_state->pipe_src_w;
> -
> -	/*
> -	 * Display WA #1175: cnl,glk
> -	 * Planes other than the cursor may cause FIFO underflow and display
> -	 * corruption if starting less than 4 pixels from the right edge of
> -	 * the screen.
> -	 * Besides the above WA fix the similar problem, where planes other
> -	 * than the cursor ending less than 4 pixels from the left edge of the
> -	 * screen may cause FIFO underflow and display corruption.
> -	 */
> -	if ((IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) &&
> -	    (crtc_x + crtc_w < 4 || crtc_x > pipe_src_w - 4)) {
> -		drm_dbg_kms(&dev_priv->drm,
> -			    "requested plane X %s position %d invalid (valid range %d-%d)\n",
> -			    crtc_x + crtc_w < 4 ? "end" : "start",
> -			    crtc_x + crtc_w < 4 ? crtc_x + crtc_w : crtc_x,
> -			    4, pipe_src_w - 4);
> -		return -ERANGE;
> -	}
> -
> -	return 0;
> -}
> -
> -static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_state)
> -{
> -	const struct drm_framebuffer *fb = plane_state->hw.fb;
> -	unsigned int rotation = plane_state->hw.rotation;
> -	int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
> -
> -	/* Display WA #1106 */
> -	if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) &&
> -	    src_w & 3 &&
> -	    (rotation == DRM_MODE_ROTATE_270 ||
> -	     rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) {
> -		DRM_DEBUG_KMS("src width must be multiple of 4 for rotated planar YUV\n");
> -		return -EINVAL;
> -	}
> -
> -	return 0;
> -}
> -
> -static int skl_plane_max_scale(struct drm_i915_private *dev_priv,
> -			       const struct drm_framebuffer *fb)
> -{
> -	/*
> -	 * We don't yet know the final source width nor
> -	 * whether we can use the HQ scaler mode. Assume
> -	 * the best case.
> -	 * FIXME need to properly check this later.
> -	 */
> -	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv) ||
> -	    !intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
> -		return 0x30000 - 1;
> -	else
> -		return 0x20000 - 1;
> -}
> -
> -static int skl_plane_check(struct intel_crtc_state *crtc_state,
> -			   struct intel_plane_state *plane_state)
> -{
> -	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
> -	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> -	const struct drm_framebuffer *fb = plane_state->hw.fb;
> -	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
> -	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
> -	int ret;
> -
> -	ret = skl_plane_check_fb(crtc_state, plane_state);
> -	if (ret)
> -		return ret;
> -
> -	/* use scaler when colorkey is not required */
> -	if (!plane_state->ckey.flags && intel_fb_scalable(fb)) {
> -		min_scale = 1;
> -		max_scale = skl_plane_max_scale(dev_priv, fb);
> -	}
> -
> -	ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
> -						min_scale, max_scale, true);
> -	if (ret)
> -		return ret;
> -
> -	ret = skl_check_plane_surface(plane_state);
> -	if (ret)
> -		return ret;
> -
> -	if (!plane_state->uapi.visible)
> -		return 0;
> -
> -	ret = skl_plane_check_dst_coordinates(crtc_state, plane_state);
> -	if (ret)
> -		return ret;
> -
> -	ret = intel_plane_check_src_coordinates(plane_state);
> -	if (ret)
> -		return ret;
> -
> -	ret = skl_plane_check_nv12_rotation(plane_state);
> -	if (ret)
> -		return ret;
> -
> -	/* HW only has 8 bits pixel precision, disable plane if invisible */
> -	if (!(plane_state->hw.alpha >> 8))
> -		plane_state->uapi.visible = false;
> -
> -	plane_state->ctl = skl_plane_ctl(crtc_state, plane_state);
> -
> -	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> -		plane_state->color_ctl = glk_plane_color_ctl(crtc_state,
> -							     plane_state);
> -
> -	if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) &&
> -	    icl_is_hdr_plane(dev_priv, plane->id))
> -		/* Enable and use MPEG-2 chroma siting */
> -		plane_state->cus_ctl = PLANE_CUS_ENABLE |
> -			PLANE_CUS_HPHASE_0 |
> -			PLANE_CUS_VPHASE_SIGN_NEGATIVE | PLANE_CUS_VPHASE_0_25;
> -	else
> -		plane_state->cus_ctl = 0;
> -
> -	return 0;
> -}
> -
> -static bool has_dst_key_in_primary_plane(struct drm_i915_private *dev_priv)
> -{
> -	return INTEL_GEN(dev_priv) >= 9;
> -}
> -
> -static void intel_plane_set_ckey(struct intel_plane_state *plane_state,
> -				 const struct drm_intel_sprite_colorkey *set)
> -{
> -	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
> -	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> -	struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
> -
> -	*key = *set;
> +	*key = *set;
>  
>  	/*
>  	 * We want src key enabled on the
> @@ -2708,186 +1958,6 @@ static const u32 chv_pipe_b_sprite_formats[] = {
>  	DRM_FORMAT_VYUY,
>  };
>  
> -static const u32 skl_plane_formats[] = {
> -	DRM_FORMAT_C8,
> -	DRM_FORMAT_RGB565,
> -	DRM_FORMAT_XRGB8888,
> -	DRM_FORMAT_XBGR8888,
> -	DRM_FORMAT_ARGB8888,
> -	DRM_FORMAT_ABGR8888,
> -	DRM_FORMAT_XRGB2101010,
> -	DRM_FORMAT_XBGR2101010,
> -	DRM_FORMAT_XRGB16161616F,
> -	DRM_FORMAT_XBGR16161616F,
> -	DRM_FORMAT_YUYV,
> -	DRM_FORMAT_YVYU,
> -	DRM_FORMAT_UYVY,
> -	DRM_FORMAT_VYUY,
> -	DRM_FORMAT_XYUV8888,
> -};
> -
> -static const u32 skl_planar_formats[] = {
> -	DRM_FORMAT_C8,
> -	DRM_FORMAT_RGB565,
> -	DRM_FORMAT_XRGB8888,
> -	DRM_FORMAT_XBGR8888,
> -	DRM_FORMAT_ARGB8888,
> -	DRM_FORMAT_ABGR8888,
> -	DRM_FORMAT_XRGB2101010,
> -	DRM_FORMAT_XBGR2101010,
> -	DRM_FORMAT_XRGB16161616F,
> -	DRM_FORMAT_XBGR16161616F,
> -	DRM_FORMAT_YUYV,
> -	DRM_FORMAT_YVYU,
> -	DRM_FORMAT_UYVY,
> -	DRM_FORMAT_VYUY,
> -	DRM_FORMAT_NV12,
> -	DRM_FORMAT_XYUV8888,
> -};
> -
> -static const u32 glk_planar_formats[] = {
> -	DRM_FORMAT_C8,
> -	DRM_FORMAT_RGB565,
> -	DRM_FORMAT_XRGB8888,
> -	DRM_FORMAT_XBGR8888,
> -	DRM_FORMAT_ARGB8888,
> -	DRM_FORMAT_ABGR8888,
> -	DRM_FORMAT_XRGB2101010,
> -	DRM_FORMAT_XBGR2101010,
> -	DRM_FORMAT_XRGB16161616F,
> -	DRM_FORMAT_XBGR16161616F,
> -	DRM_FORMAT_YUYV,
> -	DRM_FORMAT_YVYU,
> -	DRM_FORMAT_UYVY,
> -	DRM_FORMAT_VYUY,
> -	DRM_FORMAT_NV12,
> -	DRM_FORMAT_XYUV8888,
> -	DRM_FORMAT_P010,
> -	DRM_FORMAT_P012,
> -	DRM_FORMAT_P016,
> -};
> -
> -static const u32 icl_sdr_y_plane_formats[] = {
> -	DRM_FORMAT_C8,
> -	DRM_FORMAT_RGB565,
> -	DRM_FORMAT_XRGB8888,
> -	DRM_FORMAT_XBGR8888,
> -	DRM_FORMAT_ARGB8888,
> -	DRM_FORMAT_ABGR8888,
> -	DRM_FORMAT_XRGB2101010,
> -	DRM_FORMAT_XBGR2101010,
> -	DRM_FORMAT_ARGB2101010,
> -	DRM_FORMAT_ABGR2101010,
> -	DRM_FORMAT_YUYV,
> -	DRM_FORMAT_YVYU,
> -	DRM_FORMAT_UYVY,
> -	DRM_FORMAT_VYUY,
> -	DRM_FORMAT_Y210,
> -	DRM_FORMAT_Y212,
> -	DRM_FORMAT_Y216,
> -	DRM_FORMAT_XYUV8888,
> -	DRM_FORMAT_XVYU2101010,
> -	DRM_FORMAT_XVYU12_16161616,
> -	DRM_FORMAT_XVYU16161616,
> -};
> -
> -static const u32 icl_sdr_uv_plane_formats[] = {
> -	DRM_FORMAT_C8,
> -	DRM_FORMAT_RGB565,
> -	DRM_FORMAT_XRGB8888,
> -	DRM_FORMAT_XBGR8888,
> -	DRM_FORMAT_ARGB8888,
> -	DRM_FORMAT_ABGR8888,
> -	DRM_FORMAT_XRGB2101010,
> -	DRM_FORMAT_XBGR2101010,
> -	DRM_FORMAT_ARGB2101010,
> -	DRM_FORMAT_ABGR2101010,
> -	DRM_FORMAT_YUYV,
> -	DRM_FORMAT_YVYU,
> -	DRM_FORMAT_UYVY,
> -	DRM_FORMAT_VYUY,
> -	DRM_FORMAT_NV12,
> -	DRM_FORMAT_P010,
> -	DRM_FORMAT_P012,
> -	DRM_FORMAT_P016,
> -	DRM_FORMAT_Y210,
> -	DRM_FORMAT_Y212,
> -	DRM_FORMAT_Y216,
> -	DRM_FORMAT_XYUV8888,
> -	DRM_FORMAT_XVYU2101010,
> -	DRM_FORMAT_XVYU12_16161616,
> -	DRM_FORMAT_XVYU16161616,
> -};
> -
> -static const u32 icl_hdr_plane_formats[] = {
> -	DRM_FORMAT_C8,
> -	DRM_FORMAT_RGB565,
> -	DRM_FORMAT_XRGB8888,
> -	DRM_FORMAT_XBGR8888,
> -	DRM_FORMAT_ARGB8888,
> -	DRM_FORMAT_ABGR8888,
> -	DRM_FORMAT_XRGB2101010,
> -	DRM_FORMAT_XBGR2101010,
> -	DRM_FORMAT_ARGB2101010,
> -	DRM_FORMAT_ABGR2101010,
> -	DRM_FORMAT_XRGB16161616F,
> -	DRM_FORMAT_XBGR16161616F,
> -	DRM_FORMAT_ARGB16161616F,
> -	DRM_FORMAT_ABGR16161616F,
> -	DRM_FORMAT_YUYV,
> -	DRM_FORMAT_YVYU,
> -	DRM_FORMAT_UYVY,
> -	DRM_FORMAT_VYUY,
> -	DRM_FORMAT_NV12,
> -	DRM_FORMAT_P010,
> -	DRM_FORMAT_P012,
> -	DRM_FORMAT_P016,
> -	DRM_FORMAT_Y210,
> -	DRM_FORMAT_Y212,
> -	DRM_FORMAT_Y216,
> -	DRM_FORMAT_XYUV8888,
> -	DRM_FORMAT_XVYU2101010,
> -	DRM_FORMAT_XVYU12_16161616,
> -	DRM_FORMAT_XVYU16161616,
> -};
> -
> -static const u64 skl_plane_format_modifiers_noccs[] = {
> -	I915_FORMAT_MOD_Yf_TILED,
> -	I915_FORMAT_MOD_Y_TILED,
> -	I915_FORMAT_MOD_X_TILED,
> -	DRM_FORMAT_MOD_LINEAR,
> -	DRM_FORMAT_MOD_INVALID
> -};
> -
> -static const u64 skl_plane_format_modifiers_ccs[] = {
> -	I915_FORMAT_MOD_Yf_TILED_CCS,
> -	I915_FORMAT_MOD_Y_TILED_CCS,
> -	I915_FORMAT_MOD_Yf_TILED,
> -	I915_FORMAT_MOD_Y_TILED,
> -	I915_FORMAT_MOD_X_TILED,
> -	DRM_FORMAT_MOD_LINEAR,
> -	DRM_FORMAT_MOD_INVALID
> -};
> -
> -static const u64 gen12_plane_format_modifiers_mc_ccs[] = {
> -	I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS,
> -	I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS,
> -	I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC,
> -	I915_FORMAT_MOD_Y_TILED,
> -	I915_FORMAT_MOD_X_TILED,
> -	DRM_FORMAT_MOD_LINEAR,
> -	DRM_FORMAT_MOD_INVALID
> -};
> -
> -static const u64 gen12_plane_format_modifiers_rc_ccs[] = {
> -	I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS,
> -	I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC,
> -	I915_FORMAT_MOD_Y_TILED,
> -	I915_FORMAT_MOD_X_TILED,
> -	DRM_FORMAT_MOD_LINEAR,
> -	DRM_FORMAT_MOD_INVALID
> -};
> -
>  static bool g4x_sprite_format_mod_supported(struct drm_plane *_plane,
>  					    u32 format, u64 modifier)
>  {
> @@ -2980,150 +2050,6 @@ static bool vlv_sprite_format_mod_supported(struct drm_plane *_plane,
>  	}
>  }
>  
> -static bool skl_plane_format_mod_supported(struct drm_plane *_plane,
> -					   u32 format, u64 modifier)
> -{
> -	struct intel_plane *plane = to_intel_plane(_plane);
> -
> -	switch (modifier) {
> -	case DRM_FORMAT_MOD_LINEAR:
> -	case I915_FORMAT_MOD_X_TILED:
> -	case I915_FORMAT_MOD_Y_TILED:
> -	case I915_FORMAT_MOD_Yf_TILED:
> -		break;
> -	case I915_FORMAT_MOD_Y_TILED_CCS:
> -	case I915_FORMAT_MOD_Yf_TILED_CCS:
> -		if (!plane->has_ccs)
> -			return false;
> -		break;
> -	default:
> -		return false;
> -	}
> -
> -	switch (format) {
> -	case DRM_FORMAT_XRGB8888:
> -	case DRM_FORMAT_XBGR8888:
> -	case DRM_FORMAT_ARGB8888:
> -	case DRM_FORMAT_ABGR8888:
> -		if (is_ccs_modifier(modifier))
> -			return true;
> -		fallthrough;
> -	case DRM_FORMAT_RGB565:
> -	case DRM_FORMAT_XRGB2101010:
> -	case DRM_FORMAT_XBGR2101010:
> -	case DRM_FORMAT_ARGB2101010:
> -	case DRM_FORMAT_ABGR2101010:
> -	case DRM_FORMAT_YUYV:
> -	case DRM_FORMAT_YVYU:
> -	case DRM_FORMAT_UYVY:
> -	case DRM_FORMAT_VYUY:
> -	case DRM_FORMAT_NV12:
> -	case DRM_FORMAT_XYUV8888:
> -	case DRM_FORMAT_P010:
> -	case DRM_FORMAT_P012:
> -	case DRM_FORMAT_P016:
> -	case DRM_FORMAT_XVYU2101010:
> -		if (modifier == I915_FORMAT_MOD_Yf_TILED)
> -			return true;
> -		fallthrough;
> -	case DRM_FORMAT_C8:
> -	case DRM_FORMAT_XBGR16161616F:
> -	case DRM_FORMAT_ABGR16161616F:
> -	case DRM_FORMAT_XRGB16161616F:
> -	case DRM_FORMAT_ARGB16161616F:
> -	case DRM_FORMAT_Y210:
> -	case DRM_FORMAT_Y212:
> -	case DRM_FORMAT_Y216:
> -	case DRM_FORMAT_XVYU12_16161616:
> -	case DRM_FORMAT_XVYU16161616:
> -		if (modifier == DRM_FORMAT_MOD_LINEAR ||
> -		    modifier == I915_FORMAT_MOD_X_TILED ||
> -		    modifier == I915_FORMAT_MOD_Y_TILED)
> -			return true;
> -		fallthrough;
> -	default:
> -		return false;
> -	}
> -}
> -
> -static bool gen12_plane_supports_mc_ccs(struct drm_i915_private *dev_priv,
> -					enum plane_id plane_id)
> -{
> -	/* Wa_14010477008:tgl[a0..c0],rkl[all],dg1[all] */
> -	if (IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv) ||
> -	    IS_TGL_DISP_STEPPING(dev_priv, STEP_A0, STEP_C0))
> -		return false;
> -
> -	return plane_id < PLANE_SPRITE4;
> -}
> -
> -static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,
> -					     u32 format, u64 modifier)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(_plane->dev);
> -	struct intel_plane *plane = to_intel_plane(_plane);
> -
> -	switch (modifier) {
> -	case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
> -		if (!gen12_plane_supports_mc_ccs(dev_priv, plane->id))
> -			return false;
> -		fallthrough;
> -	case DRM_FORMAT_MOD_LINEAR:
> -	case I915_FORMAT_MOD_X_TILED:
> -	case I915_FORMAT_MOD_Y_TILED:
> -	case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
> -	case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC:
> -		break;
> -	default:
> -		return false;
> -	}
> -
> -	switch (format) {
> -	case DRM_FORMAT_XRGB8888:
> -	case DRM_FORMAT_XBGR8888:
> -	case DRM_FORMAT_ARGB8888:
> -	case DRM_FORMAT_ABGR8888:
> -		if (is_ccs_modifier(modifier))
> -			return true;
> -		fallthrough;
> -	case DRM_FORMAT_YUYV:
> -	case DRM_FORMAT_YVYU:
> -	case DRM_FORMAT_UYVY:
> -	case DRM_FORMAT_VYUY:
> -	case DRM_FORMAT_NV12:
> -	case DRM_FORMAT_XYUV8888:
> -	case DRM_FORMAT_P010:
> -	case DRM_FORMAT_P012:
> -	case DRM_FORMAT_P016:
> -		if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS)
> -			return true;
> -		fallthrough;
> -	case DRM_FORMAT_RGB565:
> -	case DRM_FORMAT_XRGB2101010:
> -	case DRM_FORMAT_XBGR2101010:
> -	case DRM_FORMAT_ARGB2101010:
> -	case DRM_FORMAT_ABGR2101010:
> -	case DRM_FORMAT_XVYU2101010:
> -	case DRM_FORMAT_C8:
> -	case DRM_FORMAT_XBGR16161616F:
> -	case DRM_FORMAT_ABGR16161616F:
> -	case DRM_FORMAT_XRGB16161616F:
> -	case DRM_FORMAT_ARGB16161616F:
> -	case DRM_FORMAT_Y210:
> -	case DRM_FORMAT_Y212:
> -	case DRM_FORMAT_Y216:
> -	case DRM_FORMAT_XVYU12_16161616:
> -	case DRM_FORMAT_XVYU16161616:
> -		if (modifier == DRM_FORMAT_MOD_LINEAR ||
> -		    modifier == I915_FORMAT_MOD_X_TILED ||
> -		    modifier == I915_FORMAT_MOD_Y_TILED)
> -			return true;
> -		fallthrough;
> -	default:
> -		return false;
> -	}
> -}
> -
>  static const struct drm_plane_funcs g4x_sprite_funcs = {
>  	.update_plane = drm_atomic_helper_update_plane,
>  	.disable_plane = drm_atomic_helper_disable_plane,
> @@ -3151,257 +2077,6 @@ static const struct drm_plane_funcs vlv_sprite_funcs = {
>  	.format_mod_supported = vlv_sprite_format_mod_supported,
>  };
>  
> -static const struct drm_plane_funcs skl_plane_funcs = {
> -	.update_plane = drm_atomic_helper_update_plane,
> -	.disable_plane = drm_atomic_helper_disable_plane,
> -	.destroy = intel_plane_destroy,
> -	.atomic_duplicate_state = intel_plane_duplicate_state,
> -	.atomic_destroy_state = intel_plane_destroy_state,
> -	.format_mod_supported = skl_plane_format_mod_supported,
> -};
> -
> -static const struct drm_plane_funcs gen12_plane_funcs = {
> -	.update_plane = drm_atomic_helper_update_plane,
> -	.disable_plane = drm_atomic_helper_disable_plane,
> -	.destroy = intel_plane_destroy,
> -	.atomic_duplicate_state = intel_plane_duplicate_state,
> -	.atomic_destroy_state = intel_plane_destroy_state,
> -	.format_mod_supported = gen12_plane_format_mod_supported,
> -};
> -
> -static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv,
> -			      enum pipe pipe, enum plane_id plane_id)
> -{
> -	if (!HAS_FBC(dev_priv))
> -		return false;
> -
> -	return pipe == PIPE_A && plane_id == PLANE_PRIMARY;
> -}
> -
> -static bool skl_plane_has_planar(struct drm_i915_private *dev_priv,
> -				 enum pipe pipe, enum plane_id plane_id)
> -{
> -	/* Display WA #0870: skl, bxt */
> -	if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv))
> -		return false;
> -
> -	if (IS_GEN(dev_priv, 9) && !IS_GEMINILAKE(dev_priv) && pipe == PIPE_C)
> -		return false;
> -
> -	if (plane_id != PLANE_PRIMARY && plane_id != PLANE_SPRITE0)
> -		return false;
> -
> -	return true;
> -}
> -
> -static const u32 *skl_get_plane_formats(struct drm_i915_private *dev_priv,
> -					enum pipe pipe, enum plane_id plane_id,
> -					int *num_formats)
> -{
> -	if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
> -		*num_formats = ARRAY_SIZE(skl_planar_formats);
> -		return skl_planar_formats;
> -	} else {
> -		*num_formats = ARRAY_SIZE(skl_plane_formats);
> -		return skl_plane_formats;
> -	}
> -}
> -
> -static const u32 *glk_get_plane_formats(struct drm_i915_private *dev_priv,
> -					enum pipe pipe, enum plane_id plane_id,
> -					int *num_formats)
> -{
> -	if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
> -		*num_formats = ARRAY_SIZE(glk_planar_formats);
> -		return glk_planar_formats;
> -	} else {
> -		*num_formats = ARRAY_SIZE(skl_plane_formats);
> -		return skl_plane_formats;
> -	}
> -}
> -
> -static const u32 *icl_get_plane_formats(struct drm_i915_private *dev_priv,
> -					enum pipe pipe, enum plane_id plane_id,
> -					int *num_formats)
> -{
> -	if (icl_is_hdr_plane(dev_priv, plane_id)) {
> -		*num_formats = ARRAY_SIZE(icl_hdr_plane_formats);
> -		return icl_hdr_plane_formats;
> -	} else if (icl_is_nv12_y_plane(dev_priv, plane_id)) {
> -		*num_formats = ARRAY_SIZE(icl_sdr_y_plane_formats);
> -		return icl_sdr_y_plane_formats;
> -	} else {
> -		*num_formats = ARRAY_SIZE(icl_sdr_uv_plane_formats);
> -		return icl_sdr_uv_plane_formats;
> -	}
> -}
> -
> -static const u64 *gen12_get_plane_modifiers(struct drm_i915_private *dev_priv,
> -					    enum plane_id plane_id)
> -{
> -	if (gen12_plane_supports_mc_ccs(dev_priv, plane_id))
> -		return gen12_plane_format_modifiers_mc_ccs;
> -	else
> -		return gen12_plane_format_modifiers_rc_ccs;
> -}
> -
> -static bool skl_plane_has_ccs(struct drm_i915_private *dev_priv,
> -			      enum pipe pipe, enum plane_id plane_id)
> -{
> -	if (plane_id == PLANE_CURSOR)
> -		return false;
> -
> -	if (INTEL_GEN(dev_priv) >= 10)
> -		return true;
> -
> -	if (IS_GEMINILAKE(dev_priv))
> -		return pipe != PIPE_C;
> -
> -	return pipe != PIPE_C &&
> -		(plane_id == PLANE_PRIMARY ||
> -		 plane_id == PLANE_SPRITE0);
> -}
> -
> -struct intel_plane *
> -skl_universal_plane_create(struct drm_i915_private *dev_priv,
> -			   enum pipe pipe, enum plane_id plane_id)
> -{
> -	const struct drm_plane_funcs *plane_funcs;
> -	struct intel_plane *plane;
> -	enum drm_plane_type plane_type;
> -	unsigned int supported_rotations;
> -	unsigned int supported_csc;
> -	const u64 *modifiers;
> -	const u32 *formats;
> -	int num_formats;
> -	int ret;
> -
> -	plane = intel_plane_alloc();
> -	if (IS_ERR(plane))
> -		return plane;
> -
> -	plane->pipe = pipe;
> -	plane->id = plane_id;
> -	plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane_id);
> -
> -	plane->has_fbc = skl_plane_has_fbc(dev_priv, pipe, plane_id);
> -	if (plane->has_fbc) {
> -		struct intel_fbc *fbc = &dev_priv->fbc;
> -
> -		fbc->possible_framebuffer_bits |= plane->frontbuffer_bit;
> -	}
> -
> -	if (INTEL_GEN(dev_priv) >= 11) {
> -		plane->min_width = icl_plane_min_width;
> -		plane->max_width = icl_plane_max_width;
> -		plane->max_height = icl_plane_max_height;
> -	} else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) {
> -		plane->max_width = glk_plane_max_width;
> -		plane->max_height = skl_plane_max_height;
> -	} else {
> -		plane->max_width = skl_plane_max_width;
> -		plane->max_height = skl_plane_max_height;
> -	}
> -
> -	plane->max_stride = skl_plane_max_stride;
> -	plane->update_plane = skl_update_plane;
> -	plane->disable_plane = skl_disable_plane;
> -	plane->get_hw_state = skl_plane_get_hw_state;
> -	plane->check_plane = skl_plane_check;
> -	plane->min_cdclk = skl_plane_min_cdclk;
> -
> -	if (plane_id == PLANE_PRIMARY) {
> -		plane->need_async_flip_disable_wa = IS_GEN_RANGE(dev_priv, 9, 10);
> -		plane->async_flip = skl_plane_async_flip;
> -		plane->enable_flip_done = skl_plane_enable_flip_done;
> -		plane->disable_flip_done = skl_plane_disable_flip_done;
> -	}
> -
> -	if (INTEL_GEN(dev_priv) >= 11)
> -		formats = icl_get_plane_formats(dev_priv, pipe,
> -						plane_id, &num_formats);
> -	else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> -		formats = glk_get_plane_formats(dev_priv, pipe,
> -						plane_id, &num_formats);
> -	else
> -		formats = skl_get_plane_formats(dev_priv, pipe,
> -						plane_id, &num_formats);
> -
> -	plane->has_ccs = skl_plane_has_ccs(dev_priv, pipe, plane_id);
> -	if (INTEL_GEN(dev_priv) >= 12) {
> -		modifiers = gen12_get_plane_modifiers(dev_priv, plane_id);
> -		plane_funcs = &gen12_plane_funcs;
> -	} else {
> -		if (plane->has_ccs)
> -			modifiers = skl_plane_format_modifiers_ccs;
> -		else
> -			modifiers = skl_plane_format_modifiers_noccs;
> -		plane_funcs = &skl_plane_funcs;
> -	}
> -
> -	if (plane_id == PLANE_PRIMARY)
> -		plane_type = DRM_PLANE_TYPE_PRIMARY;
> -	else
> -		plane_type = DRM_PLANE_TYPE_OVERLAY;
> -
> -	ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
> -				       0, plane_funcs,
> -				       formats, num_formats, modifiers,
> -				       plane_type,
> -				       "plane %d%c", plane_id + 1,
> -				       pipe_name(pipe));
> -	if (ret)
> -		goto fail;
> -
> -	supported_rotations =
> -		DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 |
> -		DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270;
> -
> -	if (INTEL_GEN(dev_priv) >= 10)
> -		supported_rotations |= DRM_MODE_REFLECT_X;
> -
> -	drm_plane_create_rotation_property(&plane->base,
> -					   DRM_MODE_ROTATE_0,
> -					   supported_rotations);
> -
> -	supported_csc = BIT(DRM_COLOR_YCBCR_BT601) | BIT(DRM_COLOR_YCBCR_BT709);
> -
> -	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> -		supported_csc |= BIT(DRM_COLOR_YCBCR_BT2020);
> -
> -	drm_plane_create_color_properties(&plane->base,
> -					  supported_csc,
> -					  BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
> -					  BIT(DRM_COLOR_YCBCR_FULL_RANGE),
> -					  DRM_COLOR_YCBCR_BT709,
> -					  DRM_COLOR_YCBCR_LIMITED_RANGE);
> -
> -	drm_plane_create_alpha_property(&plane->base);
> -	drm_plane_create_blend_mode_property(&plane->base,
> -					     BIT(DRM_MODE_BLEND_PIXEL_NONE) |
> -					     BIT(DRM_MODE_BLEND_PREMULTI) |
> -					     BIT(DRM_MODE_BLEND_COVERAGE));
> -
> -	drm_plane_create_zpos_immutable_property(&plane->base, plane_id);
> -
> -	if (INTEL_GEN(dev_priv) >= 12)
> -		drm_plane_enable_fb_damage_clips(&plane->base);
> -
> -	if (INTEL_GEN(dev_priv) >= 10)
> -		drm_plane_create_scaling_filter_property(&plane->base,
> -						BIT(DRM_SCALING_FILTER_DEFAULT) |
> -						BIT(DRM_SCALING_FILTER_NEAREST_NEIGHBOR));
> -
> -	drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
> -
> -	return plane;
> -
> -fail:
> -	intel_plane_free(plane);
> -
> -	return ERR_PTR(ret);
> -}
> -
>  struct intel_plane *
>  intel_sprite_plane_create(struct drm_i915_private *dev_priv,
>  			  enum pipe pipe, int sprite)
> @@ -3414,10 +2089,6 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
>  	int num_formats;
>  	int ret, zpos;
>  
> -	if (INTEL_GEN(dev_priv) >= 9)
> -		return skl_universal_plane_create(dev_priv, pipe,
> -						  PLANE_SPRITE0 + sprite);
> -
>  	plane = intel_plane_alloc();
>  	if (IS_ERR(plane))
>  		return plane;
> diff --git a/drivers/gpu/drm/i915/display/intel_sprite.h b/drivers/gpu/drm/i915/display/intel_sprite.h
> index 76126dd8d584..418897f953fc 100644
> --- a/drivers/gpu/drm/i915/display/intel_sprite.h
> +++ b/drivers/gpu/drm/i915/display/intel_sprite.h
> @@ -38,9 +38,6 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state);
>  int intel_plane_check_stride(const struct intel_plane_state *plane_state);
>  int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state);
>  int chv_plane_check_rotation(const struct intel_plane_state *plane_state);
> -struct intel_plane *
> -skl_universal_plane_create(struct drm_i915_private *dev_priv,
> -			   enum pipe pipe, enum plane_id plane_id);
>  
>  static inline u8 icl_hdr_plane_mask(void)
>  {
> @@ -59,4 +56,7 @@ int hsw_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
>  int vlv_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
>  			const struct intel_plane_state *plane_state);
>  
> +void skl_program_scaler(struct intel_plane *plane,
> +			const struct intel_crtc_state *crtc_state,
> +			const struct intel_plane_state *plane_state);
>  #endif /* __INTEL_SPRITE_H__ */
> diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
> new file mode 100644
> index 000000000000..29c2e3693e8b
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
> @@ -0,0 +1,2265 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright © 2020 Intel Corporation
> + */
> +
> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_damage_helper.h>
> +#include <drm/drm_fourcc.h>
> +#include <drm/drm_plane_helper.h>
> +
> +#include "i915_drv.h"
> +#include "intel_atomic_plane.h"
> +#include "intel_display_types.h"
> +#include "intel_pm.h"
> +#include "intel_psr.h"
> +#include "intel_sprite.h"
> +#include "skl_universal_plane.h"
> +
> +static const u32 skl_plane_formats[] = {
> +	DRM_FORMAT_C8,
> +	DRM_FORMAT_RGB565,
> +	DRM_FORMAT_XRGB8888,
> +	DRM_FORMAT_XBGR8888,
> +	DRM_FORMAT_ARGB8888,
> +	DRM_FORMAT_ABGR8888,
> +	DRM_FORMAT_XRGB2101010,
> +	DRM_FORMAT_XBGR2101010,
> +	DRM_FORMAT_XRGB16161616F,
> +	DRM_FORMAT_XBGR16161616F,
> +	DRM_FORMAT_YUYV,
> +	DRM_FORMAT_YVYU,
> +	DRM_FORMAT_UYVY,
> +	DRM_FORMAT_VYUY,
> +	DRM_FORMAT_XYUV8888,
> +};
> +
> +static const u32 skl_planar_formats[] = {
> +	DRM_FORMAT_C8,
> +	DRM_FORMAT_RGB565,
> +	DRM_FORMAT_XRGB8888,
> +	DRM_FORMAT_XBGR8888,
> +	DRM_FORMAT_ARGB8888,
> +	DRM_FORMAT_ABGR8888,
> +	DRM_FORMAT_XRGB2101010,
> +	DRM_FORMAT_XBGR2101010,
> +	DRM_FORMAT_XRGB16161616F,
> +	DRM_FORMAT_XBGR16161616F,
> +	DRM_FORMAT_YUYV,
> +	DRM_FORMAT_YVYU,
> +	DRM_FORMAT_UYVY,
> +	DRM_FORMAT_VYUY,
> +	DRM_FORMAT_NV12,
> +	DRM_FORMAT_XYUV8888,
> +};
> +
> +static const u32 glk_planar_formats[] = {
> +	DRM_FORMAT_C8,
> +	DRM_FORMAT_RGB565,
> +	DRM_FORMAT_XRGB8888,
> +	DRM_FORMAT_XBGR8888,
> +	DRM_FORMAT_ARGB8888,
> +	DRM_FORMAT_ABGR8888,
> +	DRM_FORMAT_XRGB2101010,
> +	DRM_FORMAT_XBGR2101010,
> +	DRM_FORMAT_XRGB16161616F,
> +	DRM_FORMAT_XBGR16161616F,
> +	DRM_FORMAT_YUYV,
> +	DRM_FORMAT_YVYU,
> +	DRM_FORMAT_UYVY,
> +	DRM_FORMAT_VYUY,
> +	DRM_FORMAT_NV12,
> +	DRM_FORMAT_XYUV8888,
> +	DRM_FORMAT_P010,
> +	DRM_FORMAT_P012,
> +	DRM_FORMAT_P016,
> +};
> +
> +static const u32 icl_sdr_y_plane_formats[] = {
> +	DRM_FORMAT_C8,
> +	DRM_FORMAT_RGB565,
> +	DRM_FORMAT_XRGB8888,
> +	DRM_FORMAT_XBGR8888,
> +	DRM_FORMAT_ARGB8888,
> +	DRM_FORMAT_ABGR8888,
> +	DRM_FORMAT_XRGB2101010,
> +	DRM_FORMAT_XBGR2101010,
> +	DRM_FORMAT_ARGB2101010,
> +	DRM_FORMAT_ABGR2101010,
> +	DRM_FORMAT_YUYV,
> +	DRM_FORMAT_YVYU,
> +	DRM_FORMAT_UYVY,
> +	DRM_FORMAT_VYUY,
> +	DRM_FORMAT_Y210,
> +	DRM_FORMAT_Y212,
> +	DRM_FORMAT_Y216,
> +	DRM_FORMAT_XYUV8888,
> +	DRM_FORMAT_XVYU2101010,
> +	DRM_FORMAT_XVYU12_16161616,
> +	DRM_FORMAT_XVYU16161616,
> +};
> +
> +static const u32 icl_sdr_uv_plane_formats[] = {
> +	DRM_FORMAT_C8,
> +	DRM_FORMAT_RGB565,
> +	DRM_FORMAT_XRGB8888,
> +	DRM_FORMAT_XBGR8888,
> +	DRM_FORMAT_ARGB8888,
> +	DRM_FORMAT_ABGR8888,
> +	DRM_FORMAT_XRGB2101010,
> +	DRM_FORMAT_XBGR2101010,
> +	DRM_FORMAT_ARGB2101010,
> +	DRM_FORMAT_ABGR2101010,
> +	DRM_FORMAT_YUYV,
> +	DRM_FORMAT_YVYU,
> +	DRM_FORMAT_UYVY,
> +	DRM_FORMAT_VYUY,
> +	DRM_FORMAT_NV12,
> +	DRM_FORMAT_P010,
> +	DRM_FORMAT_P012,
> +	DRM_FORMAT_P016,
> +	DRM_FORMAT_Y210,
> +	DRM_FORMAT_Y212,
> +	DRM_FORMAT_Y216,
> +	DRM_FORMAT_XYUV8888,
> +	DRM_FORMAT_XVYU2101010,
> +	DRM_FORMAT_XVYU12_16161616,
> +	DRM_FORMAT_XVYU16161616,
> +};
> +
> +static const u32 icl_hdr_plane_formats[] = {
> +	DRM_FORMAT_C8,
> +	DRM_FORMAT_RGB565,
> +	DRM_FORMAT_XRGB8888,
> +	DRM_FORMAT_XBGR8888,
> +	DRM_FORMAT_ARGB8888,
> +	DRM_FORMAT_ABGR8888,
> +	DRM_FORMAT_XRGB2101010,
> +	DRM_FORMAT_XBGR2101010,
> +	DRM_FORMAT_ARGB2101010,
> +	DRM_FORMAT_ABGR2101010,
> +	DRM_FORMAT_XRGB16161616F,
> +	DRM_FORMAT_XBGR16161616F,
> +	DRM_FORMAT_ARGB16161616F,
> +	DRM_FORMAT_ABGR16161616F,
> +	DRM_FORMAT_YUYV,
> +	DRM_FORMAT_YVYU,
> +	DRM_FORMAT_UYVY,
> +	DRM_FORMAT_VYUY,
> +	DRM_FORMAT_NV12,
> +	DRM_FORMAT_P010,
> +	DRM_FORMAT_P012,
> +	DRM_FORMAT_P016,
> +	DRM_FORMAT_Y210,
> +	DRM_FORMAT_Y212,
> +	DRM_FORMAT_Y216,
> +	DRM_FORMAT_XYUV8888,
> +	DRM_FORMAT_XVYU2101010,
> +	DRM_FORMAT_XVYU12_16161616,
> +	DRM_FORMAT_XVYU16161616,
> +};
> +
> +static const u64 skl_plane_format_modifiers_noccs[] = {
> +	I915_FORMAT_MOD_Yf_TILED,
> +	I915_FORMAT_MOD_Y_TILED,
> +	I915_FORMAT_MOD_X_TILED,
> +	DRM_FORMAT_MOD_LINEAR,
> +	DRM_FORMAT_MOD_INVALID
> +};
> +
> +static const u64 skl_plane_format_modifiers_ccs[] = {
> +	I915_FORMAT_MOD_Yf_TILED_CCS,
> +	I915_FORMAT_MOD_Y_TILED_CCS,
> +	I915_FORMAT_MOD_Yf_TILED,
> +	I915_FORMAT_MOD_Y_TILED,
> +	I915_FORMAT_MOD_X_TILED,
> +	DRM_FORMAT_MOD_LINEAR,
> +	DRM_FORMAT_MOD_INVALID
> +};
> +
> +static const u64 gen12_plane_format_modifiers_mc_ccs[] = {
> +	I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS,
> +	I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS,
> +	I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC,
> +	I915_FORMAT_MOD_Y_TILED,
> +	I915_FORMAT_MOD_X_TILED,
> +	DRM_FORMAT_MOD_LINEAR,
> +	DRM_FORMAT_MOD_INVALID
> +};
> +
> +static const u64 gen12_plane_format_modifiers_rc_ccs[] = {
> +	I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS,
> +	I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC,
> +	I915_FORMAT_MOD_Y_TILED,
> +	I915_FORMAT_MOD_X_TILED,
> +	DRM_FORMAT_MOD_LINEAR,
> +	DRM_FORMAT_MOD_INVALID
> +};
> +
> +int skl_format_to_fourcc(int format, bool rgb_order, bool alpha)
> +{
> +	switch (format) {
> +	case PLANE_CTL_FORMAT_RGB_565:
> +		return DRM_FORMAT_RGB565;
> +	case PLANE_CTL_FORMAT_NV12:
> +		return DRM_FORMAT_NV12;
> +	case PLANE_CTL_FORMAT_XYUV:
> +		return DRM_FORMAT_XYUV8888;
> +	case PLANE_CTL_FORMAT_P010:
> +		return DRM_FORMAT_P010;
> +	case PLANE_CTL_FORMAT_P012:
> +		return DRM_FORMAT_P012;
> +	case PLANE_CTL_FORMAT_P016:
> +		return DRM_FORMAT_P016;
> +	case PLANE_CTL_FORMAT_Y210:
> +		return DRM_FORMAT_Y210;
> +	case PLANE_CTL_FORMAT_Y212:
> +		return DRM_FORMAT_Y212;
> +	case PLANE_CTL_FORMAT_Y216:
> +		return DRM_FORMAT_Y216;
> +	case PLANE_CTL_FORMAT_Y410:
> +		return DRM_FORMAT_XVYU2101010;
> +	case PLANE_CTL_FORMAT_Y412:
> +		return DRM_FORMAT_XVYU12_16161616;
> +	case PLANE_CTL_FORMAT_Y416:
> +		return DRM_FORMAT_XVYU16161616;
> +	default:
> +	case PLANE_CTL_FORMAT_XRGB_8888:
> +		if (rgb_order) {
> +			if (alpha)
> +				return DRM_FORMAT_ABGR8888;
> +			else
> +				return DRM_FORMAT_XBGR8888;
> +		} else {
> +			if (alpha)
> +				return DRM_FORMAT_ARGB8888;
> +			else
> +				return DRM_FORMAT_XRGB8888;
> +		}
> +	case PLANE_CTL_FORMAT_XRGB_2101010:
> +		if (rgb_order) {
> +			if (alpha)
> +				return DRM_FORMAT_ABGR2101010;
> +			else
> +				return DRM_FORMAT_XBGR2101010;
> +		} else {
> +			if (alpha)
> +				return DRM_FORMAT_ARGB2101010;
> +			else
> +				return DRM_FORMAT_XRGB2101010;
> +		}
> +	case PLANE_CTL_FORMAT_XRGB_16161616F:
> +		if (rgb_order) {
> +			if (alpha)
> +				return DRM_FORMAT_ABGR16161616F;
> +			else
> +				return DRM_FORMAT_XBGR16161616F;
> +		} else {
> +			if (alpha)
> +				return DRM_FORMAT_ARGB16161616F;
> +			else
> +				return DRM_FORMAT_XRGB16161616F;
> +		}
> +	}
> +}
> +
> +static u8 icl_nv12_y_plane_mask(struct drm_i915_private *i915)
> +{
> +	if (HAS_D12_PLANE_MINIMIZATION(i915))
> +		return BIT(PLANE_SPRITE2) | BIT(PLANE_SPRITE3);
> +	else
> +		return BIT(PLANE_SPRITE4) | BIT(PLANE_SPRITE5);
> +}
> +
> +bool icl_is_nv12_y_plane(struct drm_i915_private *dev_priv,
> +			 enum plane_id plane_id)
> +{
> +	return INTEL_GEN(dev_priv) >= 11 &&
> +		icl_nv12_y_plane_mask(dev_priv) & BIT(plane_id);
> +}
> +
> +bool icl_is_hdr_plane(struct drm_i915_private *dev_priv, enum plane_id plane_id)
> +{
> +	return INTEL_GEN(dev_priv) >= 11 &&
> +		icl_hdr_plane_mask() & BIT(plane_id);
> +}
> +
> +static void
> +skl_plane_ratio(const struct intel_crtc_state *crtc_state,
> +		const struct intel_plane_state *plane_state,
> +		unsigned int *num, unsigned int *den)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(plane_state->uapi.plane->dev);
> +	const struct drm_framebuffer *fb = plane_state->hw.fb;
> +
> +	if (fb->format->cpp[0] == 8) {
> +		if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) {
> +			*num = 10;
> +			*den = 8;
> +		} else {
> +			*num = 9;
> +			*den = 8;
> +		}
> +	} else {
> +		*num = 1;
> +		*den = 1;
> +	}
> +}
> +
> +static int skl_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
> +			       const struct intel_plane_state *plane_state)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(plane_state->uapi.plane->dev);
> +	unsigned int num, den;
> +	unsigned int pixel_rate = intel_plane_pixel_rate(crtc_state, plane_state);
> +
> +	skl_plane_ratio(crtc_state, plane_state, &num, &den);
> +
> +	/* two pixels per clock on glk+ */
> +	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> +		den *= 2;
> +
> +	return DIV_ROUND_UP(pixel_rate * num, den);
> +}
> +
> +static int skl_plane_max_width(const struct drm_framebuffer *fb,
> +			       int color_plane,
> +			       unsigned int rotation)
> +{
> +	int cpp = fb->format->cpp[color_plane];
> +
> +	switch (fb->modifier) {
> +	case DRM_FORMAT_MOD_LINEAR:
> +	case I915_FORMAT_MOD_X_TILED:
> +		/*
> +		 * Validated limit is 4k, but has 5k should
> +		 * work apart from the following features:
> +		 * - Ytile (already limited to 4k)
> +		 * - FP16 (already limited to 4k)
> +		 * - render compression (already limited to 4k)
> +		 * - KVMR sprite and cursor (don't care)
> +		 * - horizontal panning (TODO verify this)
> +		 * - pipe and plane scaling (TODO verify this)
> +		 */
> +		if (cpp == 8)
> +			return 4096;
> +		else
> +			return 5120;
> +	case I915_FORMAT_MOD_Y_TILED_CCS:
> +	case I915_FORMAT_MOD_Yf_TILED_CCS:
> +	case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
> +		/* FIXME AUX plane? */
> +	case I915_FORMAT_MOD_Y_TILED:
> +	case I915_FORMAT_MOD_Yf_TILED:
> +		if (cpp == 8)
> +			return 2048;
> +		else
> +			return 4096;
> +	default:
> +		MISSING_CASE(fb->modifier);
> +		return 2048;
> +	}
> +}
> +
> +static int glk_plane_max_width(const struct drm_framebuffer *fb,
> +			       int color_plane,
> +			       unsigned int rotation)
> +{
> +	int cpp = fb->format->cpp[color_plane];
> +
> +	switch (fb->modifier) {
> +	case DRM_FORMAT_MOD_LINEAR:
> +	case I915_FORMAT_MOD_X_TILED:
> +		if (cpp == 8)
> +			return 4096;
> +		else
> +			return 5120;
> +	case I915_FORMAT_MOD_Y_TILED_CCS:
> +	case I915_FORMAT_MOD_Yf_TILED_CCS:
> +		/* FIXME AUX plane? */
> +	case I915_FORMAT_MOD_Y_TILED:
> +	case I915_FORMAT_MOD_Yf_TILED:
> +		if (cpp == 8)
> +			return 2048;
> +		else
> +			return 5120;
> +	default:
> +		MISSING_CASE(fb->modifier);
> +		return 2048;
> +	}
> +}
> +
> +static int icl_plane_min_width(const struct drm_framebuffer *fb,
> +			       int color_plane,
> +			       unsigned int rotation)
> +{
> +	/* Wa_14011264657, Wa_14011050563: gen11+ */
> +	switch (fb->format->format) {
> +	case DRM_FORMAT_C8:
> +		return 18;
> +	case DRM_FORMAT_RGB565:
> +		return 10;
> +	case DRM_FORMAT_XRGB8888:
> +	case DRM_FORMAT_XBGR8888:
> +	case DRM_FORMAT_ARGB8888:
> +	case DRM_FORMAT_ABGR8888:
> +	case DRM_FORMAT_XRGB2101010:
> +	case DRM_FORMAT_XBGR2101010:
> +	case DRM_FORMAT_ARGB2101010:
> +	case DRM_FORMAT_ABGR2101010:
> +	case DRM_FORMAT_XVYU2101010:
> +	case DRM_FORMAT_Y212:
> +	case DRM_FORMAT_Y216:
> +		return 6;
> +	case DRM_FORMAT_NV12:
> +		return 20;
> +	case DRM_FORMAT_P010:
> +	case DRM_FORMAT_P012:
> +	case DRM_FORMAT_P016:
> +		return 12;
> +	case DRM_FORMAT_XRGB16161616F:
> +	case DRM_FORMAT_XBGR16161616F:
> +	case DRM_FORMAT_ARGB16161616F:
> +	case DRM_FORMAT_ABGR16161616F:
> +	case DRM_FORMAT_XVYU12_16161616:
> +	case DRM_FORMAT_XVYU16161616:
> +		return 4;
> +	default:
> +		return 1;
> +	}
> +}
> +
> +static int icl_plane_max_width(const struct drm_framebuffer *fb,
> +			       int color_plane,
> +			       unsigned int rotation)
> +{
> +	return 5120;
> +}
> +
> +static int skl_plane_max_height(const struct drm_framebuffer *fb,
> +				int color_plane,
> +				unsigned int rotation)
> +{
> +	return 4096;
> +}
> +
> +static int icl_plane_max_height(const struct drm_framebuffer *fb,
> +				int color_plane,
> +				unsigned int rotation)
> +{
> +	return 4320;
> +}
> +
> +static unsigned int
> +skl_plane_max_stride(struct intel_plane *plane,
> +		     u32 pixel_format, u64 modifier,
> +		     unsigned int rotation)
> +{
> +	const struct drm_format_info *info = drm_format_info(pixel_format);
> +	int cpp = info->cpp[0];
> +
> +	/*
> +	 * "The stride in bytes must not exceed the
> +	 * of the size of 8K pixels and 32K bytes."
> +	 */
> +	if (drm_rotation_90_or_270(rotation))
> +		return min(8192, 32768 / cpp);
> +	else
> +		return min(8192 * cpp, 32768);
> +}
> +
> +
> +/* Preoffset values for YUV to RGB Conversion */
> +#define PREOFF_YUV_TO_RGB_HI		0x1800
> +#define PREOFF_YUV_TO_RGB_ME		0x0000
> +#define PREOFF_YUV_TO_RGB_LO		0x1800
> +
> +#define  ROFF(x)          (((x) & 0xffff) << 16)
> +#define  GOFF(x)          (((x) & 0xffff) << 0)
> +#define  BOFF(x)          (((x) & 0xffff) << 16)
> +
> +/*
> + * Programs the input color space conversion stage for ICL HDR planes.
> + * Note that it is assumed that this stage always happens after YUV
> + * range correction. Thus, the input to this stage is assumed to be
> + * in full-range YCbCr.
> + */
> +static void
> +icl_program_input_csc(struct intel_plane *plane,
> +		      const struct intel_crtc_state *crtc_state,
> +		      const struct intel_plane_state *plane_state)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> +	enum pipe pipe = plane->pipe;
> +	enum plane_id plane_id = plane->id;
> +
> +	static const u16 input_csc_matrix[][9] = {
> +		/*
> +		 * BT.601 full range YCbCr -> full range RGB
> +		 * The matrix required is :
> +		 * [1.000, 0.000, 1.371,
> +		 *  1.000, -0.336, -0.698,
> +		 *  1.000, 1.732, 0.0000]
> +		 */
> +		[DRM_COLOR_YCBCR_BT601] = {
> +			0x7AF8, 0x7800, 0x0,
> +			0x8B28, 0x7800, 0x9AC0,
> +			0x0, 0x7800, 0x7DD8,
> +		},
> +		/*
> +		 * BT.709 full range YCbCr -> full range RGB
> +		 * The matrix required is :
> +		 * [1.000, 0.000, 1.574,
> +		 *  1.000, -0.187, -0.468,
> +		 *  1.000, 1.855, 0.0000]
> +		 */
> +		[DRM_COLOR_YCBCR_BT709] = {
> +			0x7C98, 0x7800, 0x0,
> +			0x9EF8, 0x7800, 0xAC00,
> +			0x0, 0x7800,  0x7ED8,
> +		},
> +		/*
> +		 * BT.2020 full range YCbCr -> full range RGB
> +		 * The matrix required is :
> +		 * [1.000, 0.000, 1.474,
> +		 *  1.000, -0.1645, -0.5713,
> +		 *  1.000, 1.8814, 0.0000]
> +		 */
> +		[DRM_COLOR_YCBCR_BT2020] = {
> +			0x7BC8, 0x7800, 0x0,
> +			0x8928, 0x7800, 0xAA88,
> +			0x0, 0x7800, 0x7F10,
> +		},
> +	};
> +	const u16 *csc = input_csc_matrix[plane_state->hw.color_encoding];
> +
> +	intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 0),
> +			  ROFF(csc[0]) | GOFF(csc[1]));
> +	intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 1),
> +			  BOFF(csc[2]));
> +	intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 2),
> +			  ROFF(csc[3]) | GOFF(csc[4]));
> +	intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 3),
> +			  BOFF(csc[5]));
> +	intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 4),
> +			  ROFF(csc[6]) | GOFF(csc[7]));
> +	intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 5),
> +			  BOFF(csc[8]));
> +
> +	intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 0),
> +			  PREOFF_YUV_TO_RGB_HI);
> +	intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1),
> +			  PREOFF_YUV_TO_RGB_ME);
> +	intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 2),
> +			  PREOFF_YUV_TO_RGB_LO);
> +	intel_de_write_fw(dev_priv,
> +			  PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 0), 0x0);
> +	intel_de_write_fw(dev_priv,
> +			  PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 1), 0x0);
> +	intel_de_write_fw(dev_priv,
> +			  PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 2), 0x0);
> +}
> +
> +static bool is_surface_linear(const struct drm_framebuffer *fb, int color_plane)
> +{
> +	return fb->modifier == DRM_FORMAT_MOD_LINEAR ||
> +	       is_gen12_ccs_plane(fb, color_plane);
> +}
> +
> +static unsigned int skl_plane_stride_mult(const struct drm_framebuffer *fb,
> +					  int color_plane, unsigned int rotation)
> +{
> +	/*
> +	 * The stride is either expressed as a multiple of 64 bytes chunks for
> +	 * linear buffers or in number of tiles for tiled buffers.
> +	 */
> +	if (is_surface_linear(fb, color_plane))
> +		return 64;
> +	else if (drm_rotation_90_or_270(rotation))
> +		return intel_tile_height(fb, color_plane);
> +	else
> +		return intel_tile_width_bytes(fb, color_plane);
> +}
> +
> +static u32 skl_plane_stride(const struct intel_plane_state *plane_state,
> +			    int color_plane)
> +{
> +	const struct drm_framebuffer *fb = plane_state->hw.fb;
> +	unsigned int rotation = plane_state->hw.rotation;
> +	u32 stride = plane_state->color_plane[color_plane].stride;
> +
> +	if (color_plane >= fb->format->num_planes)
> +		return 0;
> +
> +	return stride / skl_plane_stride_mult(fb, color_plane, rotation);
> +}
> +
> +static void
> +skl_disable_plane(struct intel_plane *plane,
> +		  const struct intel_crtc_state *crtc_state)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> +	enum plane_id plane_id = plane->id;
> +	enum pipe pipe = plane->pipe;
> +	unsigned long irqflags;
> +
> +	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> +
> +	if (icl_is_hdr_plane(dev_priv, plane_id))
> +		intel_de_write_fw(dev_priv, PLANE_CUS_CTL(pipe, plane_id), 0);
> +
> +	skl_write_plane_wm(plane, crtc_state);
> +
> +	intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0);
> +	intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0);
> +
> +	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
> +}
> +
> +static bool
> +skl_plane_get_hw_state(struct intel_plane *plane,
> +		       enum pipe *pipe)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> +	enum intel_display_power_domain power_domain;
> +	enum plane_id plane_id = plane->id;
> +	intel_wakeref_t wakeref;
> +	bool ret;
> +
> +	power_domain = POWER_DOMAIN_PIPE(plane->pipe);
> +	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
> +	if (!wakeref)
> +		return false;
> +
> +	ret = intel_de_read(dev_priv, PLANE_CTL(plane->pipe, plane_id)) & PLANE_CTL_ENABLE;
> +
> +	*pipe = plane->pipe;
> +
> +	intel_display_power_put(dev_priv, power_domain, wakeref);
> +
> +	return ret;
> +}
> +
> +static u32 skl_plane_ctl_format(u32 pixel_format)
> +{
> +	switch (pixel_format) {
> +	case DRM_FORMAT_C8:
> +		return PLANE_CTL_FORMAT_INDEXED;
> +	case DRM_FORMAT_RGB565:
> +		return PLANE_CTL_FORMAT_RGB_565;
> +	case DRM_FORMAT_XBGR8888:
> +	case DRM_FORMAT_ABGR8888:
> +		return PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX;
> +	case DRM_FORMAT_XRGB8888:
> +	case DRM_FORMAT_ARGB8888:
> +		return PLANE_CTL_FORMAT_XRGB_8888;
> +	case DRM_FORMAT_XBGR2101010:
> +	case DRM_FORMAT_ABGR2101010:
> +		return PLANE_CTL_FORMAT_XRGB_2101010 | PLANE_CTL_ORDER_RGBX;
> +	case DRM_FORMAT_XRGB2101010:
> +	case DRM_FORMAT_ARGB2101010:
> +		return PLANE_CTL_FORMAT_XRGB_2101010;
> +	case DRM_FORMAT_XBGR16161616F:
> +	case DRM_FORMAT_ABGR16161616F:
> +		return PLANE_CTL_FORMAT_XRGB_16161616F | PLANE_CTL_ORDER_RGBX;
> +	case DRM_FORMAT_XRGB16161616F:
> +	case DRM_FORMAT_ARGB16161616F:
> +		return PLANE_CTL_FORMAT_XRGB_16161616F;
> +	case DRM_FORMAT_XYUV8888:
> +		return PLANE_CTL_FORMAT_XYUV;
> +	case DRM_FORMAT_YUYV:
> +		return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YUYV;
> +	case DRM_FORMAT_YVYU:
> +		return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YVYU;
> +	case DRM_FORMAT_UYVY:
> +		return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY;
> +	case DRM_FORMAT_VYUY:
> +		return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY;
> +	case DRM_FORMAT_NV12:
> +		return PLANE_CTL_FORMAT_NV12;
> +	case DRM_FORMAT_P010:
> +		return PLANE_CTL_FORMAT_P010;
> +	case DRM_FORMAT_P012:
> +		return PLANE_CTL_FORMAT_P012;
> +	case DRM_FORMAT_P016:
> +		return PLANE_CTL_FORMAT_P016;
> +	case DRM_FORMAT_Y210:
> +		return PLANE_CTL_FORMAT_Y210;
> +	case DRM_FORMAT_Y212:
> +		return PLANE_CTL_FORMAT_Y212;
> +	case DRM_FORMAT_Y216:
> +		return PLANE_CTL_FORMAT_Y216;
> +	case DRM_FORMAT_XVYU2101010:
> +		return PLANE_CTL_FORMAT_Y410;
> +	case DRM_FORMAT_XVYU12_16161616:
> +		return PLANE_CTL_FORMAT_Y412;
> +	case DRM_FORMAT_XVYU16161616:
> +		return PLANE_CTL_FORMAT_Y416;
> +	default:
> +		MISSING_CASE(pixel_format);
> +	}
> +
> +	return 0;
> +}
> +
> +static u32 skl_plane_ctl_alpha(const struct intel_plane_state *plane_state)
> +{
> +	if (!plane_state->hw.fb->format->has_alpha)
> +		return PLANE_CTL_ALPHA_DISABLE;
> +
> +	switch (plane_state->hw.pixel_blend_mode) {
> +	case DRM_MODE_BLEND_PIXEL_NONE:
> +		return PLANE_CTL_ALPHA_DISABLE;
> +	case DRM_MODE_BLEND_PREMULTI:
> +		return PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> +	case DRM_MODE_BLEND_COVERAGE:
> +		return PLANE_CTL_ALPHA_HW_PREMULTIPLY;
> +	default:
> +		MISSING_CASE(plane_state->hw.pixel_blend_mode);
> +		return PLANE_CTL_ALPHA_DISABLE;
> +	}
> +}
> +
> +static u32 glk_plane_color_ctl_alpha(const struct intel_plane_state *plane_state)
> +{
> +	if (!plane_state->hw.fb->format->has_alpha)
> +		return PLANE_COLOR_ALPHA_DISABLE;
> +
> +	switch (plane_state->hw.pixel_blend_mode) {
> +	case DRM_MODE_BLEND_PIXEL_NONE:
> +		return PLANE_COLOR_ALPHA_DISABLE;
> +	case DRM_MODE_BLEND_PREMULTI:
> +		return PLANE_COLOR_ALPHA_SW_PREMULTIPLY;
> +	case DRM_MODE_BLEND_COVERAGE:
> +		return PLANE_COLOR_ALPHA_HW_PREMULTIPLY;
> +	default:
> +		MISSING_CASE(plane_state->hw.pixel_blend_mode);
> +		return PLANE_COLOR_ALPHA_DISABLE;
> +	}
> +}
> +
> +static u32 skl_plane_ctl_tiling(u64 fb_modifier)
> +{
> +	switch (fb_modifier) {
> +	case DRM_FORMAT_MOD_LINEAR:
> +		break;
> +	case I915_FORMAT_MOD_X_TILED:
> +		return PLANE_CTL_TILED_X;
> +	case I915_FORMAT_MOD_Y_TILED:
> +		return PLANE_CTL_TILED_Y;
> +	case I915_FORMAT_MOD_Y_TILED_CCS:
> +	case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC:
> +		return PLANE_CTL_TILED_Y | PLANE_CTL_RENDER_DECOMPRESSION_ENABLE;
> +	case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
> +		return PLANE_CTL_TILED_Y |
> +		       PLANE_CTL_RENDER_DECOMPRESSION_ENABLE |
> +		       PLANE_CTL_CLEAR_COLOR_DISABLE;
> +	case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
> +		return PLANE_CTL_TILED_Y | PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE;
> +	case I915_FORMAT_MOD_Yf_TILED:
> +		return PLANE_CTL_TILED_YF;
> +	case I915_FORMAT_MOD_Yf_TILED_CCS:
> +		return PLANE_CTL_TILED_YF | PLANE_CTL_RENDER_DECOMPRESSION_ENABLE;
> +	default:
> +		MISSING_CASE(fb_modifier);
> +	}
> +
> +	return 0;
> +}
> +
> +static u32 skl_plane_ctl_rotate(unsigned int rotate)
> +{
> +	switch (rotate) {
> +	case DRM_MODE_ROTATE_0:
> +		break;
> +	/*
> +	 * DRM_MODE_ROTATE_ is counter clockwise to stay compatible with Xrandr
> +	 * while i915 HW rotation is clockwise, thats why this swapping.
> +	 */
> +	case DRM_MODE_ROTATE_90:
> +		return PLANE_CTL_ROTATE_270;
> +	case DRM_MODE_ROTATE_180:
> +		return PLANE_CTL_ROTATE_180;
> +	case DRM_MODE_ROTATE_270:
> +		return PLANE_CTL_ROTATE_90;
> +	default:
> +		MISSING_CASE(rotate);
> +	}
> +
> +	return 0;
> +}
> +
> +static u32 cnl_plane_ctl_flip(unsigned int reflect)
> +{
> +	switch (reflect) {
> +	case 0:
> +		break;
> +	case DRM_MODE_REFLECT_X:
> +		return PLANE_CTL_FLIP_HORIZONTAL;
> +	case DRM_MODE_REFLECT_Y:
> +	default:
> +		MISSING_CASE(reflect);
> +	}
> +
> +	return 0;
> +}
> +
> +static u32 skl_plane_ctl_crtc(const struct intel_crtc_state *crtc_state)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
> +	u32 plane_ctl = 0;
> +
> +	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> +		return plane_ctl;
> +
> +	if (crtc_state->gamma_enable)
> +		plane_ctl |= PLANE_CTL_PIPE_GAMMA_ENABLE;
> +
> +	if (crtc_state->csc_enable)
> +		plane_ctl |= PLANE_CTL_PIPE_CSC_ENABLE;
> +
> +	return plane_ctl;
> +}
> +
> +static u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state,
> +			 const struct intel_plane_state *plane_state)
> +{
> +	struct drm_i915_private *dev_priv =
> +		to_i915(plane_state->uapi.plane->dev);
> +	const struct drm_framebuffer *fb = plane_state->hw.fb;
> +	unsigned int rotation = plane_state->hw.rotation;
> +	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
> +	u32 plane_ctl;
> +
> +	plane_ctl = PLANE_CTL_ENABLE;
> +
> +	if (INTEL_GEN(dev_priv) < 10 && !IS_GEMINILAKE(dev_priv)) {
> +		plane_ctl |= skl_plane_ctl_alpha(plane_state);
> +		plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
> +
> +		if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709)
> +			plane_ctl |= PLANE_CTL_YUV_TO_RGB_CSC_FORMAT_BT709;
> +
> +		if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
> +			plane_ctl |= PLANE_CTL_YUV_RANGE_CORRECTION_DISABLE;
> +	}
> +
> +	plane_ctl |= skl_plane_ctl_format(fb->format->format);
> +	plane_ctl |= skl_plane_ctl_tiling(fb->modifier);
> +	plane_ctl |= skl_plane_ctl_rotate(rotation & DRM_MODE_ROTATE_MASK);
> +
> +	if (INTEL_GEN(dev_priv) >= 10)
> +		plane_ctl |= cnl_plane_ctl_flip(rotation &
> +						DRM_MODE_REFLECT_MASK);
> +
> +	if (key->flags & I915_SET_COLORKEY_DESTINATION)
> +		plane_ctl |= PLANE_CTL_KEY_ENABLE_DESTINATION;
> +	else if (key->flags & I915_SET_COLORKEY_SOURCE)
> +		plane_ctl |= PLANE_CTL_KEY_ENABLE_SOURCE;
> +
> +	return plane_ctl;
> +}
> +
> +static u32 glk_plane_color_ctl_crtc(const struct intel_crtc_state *crtc_state)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
> +	u32 plane_color_ctl = 0;
> +
> +	if (INTEL_GEN(dev_priv) >= 11)
> +		return plane_color_ctl;
> +
> +	if (crtc_state->gamma_enable)
> +		plane_color_ctl |= PLANE_COLOR_PIPE_GAMMA_ENABLE;
> +
> +	if (crtc_state->csc_enable)
> +		plane_color_ctl |= PLANE_COLOR_PIPE_CSC_ENABLE;
> +
> +	return plane_color_ctl;
> +}
> +
> +static u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state,
> +			       const struct intel_plane_state *plane_state)
> +{
> +	struct drm_i915_private *dev_priv =
> +		to_i915(plane_state->uapi.plane->dev);
> +	const struct drm_framebuffer *fb = plane_state->hw.fb;
> +	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
> +	u32 plane_color_ctl = 0;
> +
> +	plane_color_ctl |= PLANE_COLOR_PLANE_GAMMA_DISABLE;
> +	plane_color_ctl |= glk_plane_color_ctl_alpha(plane_state);
> +
> +	if (fb->format->is_yuv && !icl_is_hdr_plane(dev_priv, plane->id)) {
> +		switch (plane_state->hw.color_encoding) {
> +		case DRM_COLOR_YCBCR_BT709:
> +			plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709;
> +			break;
> +		case DRM_COLOR_YCBCR_BT2020:
> +			plane_color_ctl |=
> +				PLANE_COLOR_CSC_MODE_YUV2020_TO_RGB2020;
> +			break;
> +		default:
> +			plane_color_ctl |=
> +				PLANE_COLOR_CSC_MODE_YUV601_TO_RGB601;
> +		}
> +		if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
> +			plane_color_ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
> +	} else if (fb->format->is_yuv) {
> +		plane_color_ctl |= PLANE_COLOR_INPUT_CSC_ENABLE;
> +		if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
> +			plane_color_ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
> +	}
> +
> +	return plane_color_ctl;
> +}
> +
> +static int
> +main_to_ccs_plane(const struct drm_framebuffer *fb, int main_plane)
> +{
> +	drm_WARN_ON(fb->dev, !is_ccs_modifier(fb->modifier) ||
> +		    (main_plane && main_plane >= fb->format->num_planes / 2));
> +
> +	return fb->format->num_planes / 2 + main_plane;
> +}
> +
> +int skl_ccs_to_main_plane(const struct drm_framebuffer *fb, int ccs_plane)
> +{
> +	drm_WARN_ON(fb->dev, !is_ccs_modifier(fb->modifier) ||
> +		    ccs_plane < fb->format->num_planes / 2);
> +
> +	if (is_gen12_ccs_cc_plane(fb, ccs_plane))
> +		return 0;
> +
> +	return ccs_plane - fb->format->num_planes / 2;
> +}
> +
> +static int
> +skl_main_to_aux_plane(const struct drm_framebuffer *fb, int main_plane)
> +{
> +	struct drm_i915_private *i915 = to_i915(fb->dev);
> +
> +	if (is_ccs_modifier(fb->modifier))
> +		return main_to_ccs_plane(fb, main_plane);
> +	else if (INTEL_GEN(i915) < 11 &&
> +		 intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
> +		return 1;
> +	else
> +		return 0;
> +}
> +
> +static void
> +skl_program_plane(struct intel_plane *plane,
> +		  const struct intel_crtc_state *crtc_state,
> +		  const struct intel_plane_state *plane_state,
> +		  int color_plane)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> +	enum plane_id plane_id = plane->id;
> +	enum pipe pipe = plane->pipe;
> +	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
> +	u32 surf_addr = plane_state->color_plane[color_plane].offset;
> +	u32 stride = skl_plane_stride(plane_state, color_plane);
> +	const struct drm_framebuffer *fb = plane_state->hw.fb;
> +	int aux_plane = skl_main_to_aux_plane(fb, color_plane);
> +	int crtc_x = plane_state->uapi.dst.x1;
> +	int crtc_y = plane_state->uapi.dst.y1;
> +	u32 x = plane_state->color_plane[color_plane].x;
> +	u32 y = plane_state->color_plane[color_plane].y;
> +	u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
> +	u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
> +	u8 alpha = plane_state->hw.alpha >> 8;
> +	u32 plane_color_ctl = 0, aux_dist = 0;
> +	unsigned long irqflags;
> +	u32 keymsk, keymax;
> +	u32 plane_ctl = plane_state->ctl;
> +
> +	plane_ctl |= skl_plane_ctl_crtc(crtc_state);
> +
> +	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> +		plane_color_ctl = plane_state->color_ctl |
> +			glk_plane_color_ctl_crtc(crtc_state);
> +
> +	/* Sizes are 0 based */
> +	src_w--;
> +	src_h--;
> +
> +	keymax = (key->max_value & 0xffffff) | PLANE_KEYMAX_ALPHA(alpha);
> +
> +	keymsk = key->channel_mask & 0x7ffffff;
> +	if (alpha < 0xff)
> +		keymsk |= PLANE_KEYMSK_ALPHA_ENABLE;
> +
> +	/* The scaler will handle the output position */
> +	if (plane_state->scaler_id >= 0) {
> +		crtc_x = 0;
> +		crtc_y = 0;
> +	}
> +
> +	if (aux_plane) {
> +		aux_dist = plane_state->color_plane[aux_plane].offset - surf_addr;
> +
> +		if (INTEL_GEN(dev_priv) < 12)
> +			aux_dist |= skl_plane_stride(plane_state, aux_plane);
> +	}
> +
> +	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> +
> +	intel_de_write_fw(dev_priv, PLANE_STRIDE(pipe, plane_id), stride);
> +	intel_de_write_fw(dev_priv, PLANE_POS(pipe, plane_id),
> +			  (crtc_y << 16) | crtc_x);
> +	intel_de_write_fw(dev_priv, PLANE_SIZE(pipe, plane_id),
> +			  (src_h << 16) | src_w);
> +
> +	intel_de_write_fw(dev_priv, PLANE_AUX_DIST(pipe, plane_id), aux_dist);
> +
> +	if (icl_is_hdr_plane(dev_priv, plane_id))
> +		intel_de_write_fw(dev_priv, PLANE_CUS_CTL(pipe, plane_id),
> +				  plane_state->cus_ctl);
> +
> +	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> +		intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id),
> +				  plane_color_ctl);
> +
> +	if (fb->format->is_yuv && icl_is_hdr_plane(dev_priv, plane_id))
> +		icl_program_input_csc(plane, crtc_state, plane_state);
> +
> +	if (fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC)
> +		intel_uncore_write64_fw(&dev_priv->uncore,
> +					PLANE_CC_VAL(pipe, plane_id), plane_state->ccval);
> +
> +	skl_write_plane_wm(plane, crtc_state);
> +
> +	intel_de_write_fw(dev_priv, PLANE_KEYVAL(pipe, plane_id),
> +			  key->min_value);
> +	intel_de_write_fw(dev_priv, PLANE_KEYMSK(pipe, plane_id), keymsk);
> +	intel_de_write_fw(dev_priv, PLANE_KEYMAX(pipe, plane_id), keymax);
> +
> +	intel_de_write_fw(dev_priv, PLANE_OFFSET(pipe, plane_id),
> +			  (y << 16) | x);
> +
> +	if (INTEL_GEN(dev_priv) < 11)
> +		intel_de_write_fw(dev_priv, PLANE_AUX_OFFSET(pipe, plane_id),
> +				  (plane_state->color_plane[1].y << 16) | plane_state->color_plane[1].x);
> +
> +	if (!drm_atomic_crtc_needs_modeset(&crtc_state->uapi))
> +		intel_psr2_program_plane_sel_fetch(plane, crtc_state, plane_state, color_plane);
> +
> +	/*
> +	 * The control register self-arms if the plane was previously
> +	 * disabled. Try to make the plane enable atomic by writing
> +	 * the control register just before the surface register.
> +	 */
> +	intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
> +	intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id),
> +			  intel_plane_ggtt_offset(plane_state) + surf_addr);
> +
> +	if (plane_state->scaler_id >= 0)
> +		skl_program_scaler(plane, crtc_state, plane_state);
> +
> +	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
> +}
> +
> +static void
> +skl_plane_async_flip(struct intel_plane *plane,
> +		     const struct intel_crtc_state *crtc_state,
> +		     const struct intel_plane_state *plane_state,
> +		     bool async_flip)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> +	unsigned long irqflags;
> +	enum plane_id plane_id = plane->id;
> +	enum pipe pipe = plane->pipe;
> +	u32 surf_addr = plane_state->color_plane[0].offset;
> +	u32 plane_ctl = plane_state->ctl;
> +
> +	plane_ctl |= skl_plane_ctl_crtc(crtc_state);
> +
> +	if (async_flip)
> +		plane_ctl |= PLANE_CTL_ASYNC_FLIP;
> +
> +	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> +
> +	intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
> +	intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id),
> +			  intel_plane_ggtt_offset(plane_state) + surf_addr);
> +
> +	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
> +}
> +
> +static void
> +skl_update_plane(struct intel_plane *plane,
> +		 const struct intel_crtc_state *crtc_state,
> +		 const struct intel_plane_state *plane_state)
> +{
> +	int color_plane = 0;
> +
> +	if (plane_state->planar_linked_plane && !plane_state->planar_slave)
> +		/* Program the UV plane on planar master */
> +		color_plane = 1;
> +
> +	skl_program_plane(plane, crtc_state, plane_state, color_plane);
> +}
> +
> +static bool intel_format_is_p01x(u32 format)
> +{
> +	switch (format) {
> +	case DRM_FORMAT_P010:
> +	case DRM_FORMAT_P012:
> +	case DRM_FORMAT_P016:
> +		return true;
> +	default:
> +		return false;
> +	}
> +}
> +
> +static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
> +			      const struct intel_plane_state *plane_state)
> +{
> +	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
> +	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> +	const struct drm_framebuffer *fb = plane_state->hw.fb;
> +	unsigned int rotation = plane_state->hw.rotation;
> +	struct drm_format_name_buf format_name;
> +
> +	if (!fb)
> +		return 0;
> +
> +	if (rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180) &&
> +	    is_ccs_modifier(fb->modifier)) {
> +		drm_dbg_kms(&dev_priv->drm,
> +			    "RC support only with 0/180 degree rotation (%x)\n",
> +			    rotation);
> +		return -EINVAL;
> +	}
> +
> +	if (rotation & DRM_MODE_REFLECT_X &&
> +	    fb->modifier == DRM_FORMAT_MOD_LINEAR) {
> +		drm_dbg_kms(&dev_priv->drm,
> +			    "horizontal flip is not supported with linear surface formats\n");
> +		return -EINVAL;
> +	}
> +
> +	if (drm_rotation_90_or_270(rotation)) {
> +		if (fb->modifier != I915_FORMAT_MOD_Y_TILED &&
> +		    fb->modifier != I915_FORMAT_MOD_Yf_TILED) {
> +			drm_dbg_kms(&dev_priv->drm,
> +				    "Y/Yf tiling required for 90/270!\n");
> +			return -EINVAL;
> +		}
> +
> +		/*
> +		 * 90/270 is not allowed with RGB64 16:16:16:16 and
> +		 * Indexed 8-bit. RGB 16-bit 5:6:5 is allowed gen11 onwards.
> +		 */
> +		switch (fb->format->format) {
> +		case DRM_FORMAT_RGB565:
> +			if (INTEL_GEN(dev_priv) >= 11)
> +				break;
> +			fallthrough;
> +		case DRM_FORMAT_C8:
> +		case DRM_FORMAT_XRGB16161616F:
> +		case DRM_FORMAT_XBGR16161616F:
> +		case DRM_FORMAT_ARGB16161616F:
> +		case DRM_FORMAT_ABGR16161616F:
> +		case DRM_FORMAT_Y210:
> +		case DRM_FORMAT_Y212:
> +		case DRM_FORMAT_Y216:
> +		case DRM_FORMAT_XVYU12_16161616:
> +		case DRM_FORMAT_XVYU16161616:
> +			drm_dbg_kms(&dev_priv->drm,
> +				    "Unsupported pixel format %s for 90/270!\n",
> +				    drm_get_format_name(fb->format->format,
> +							&format_name));
> +			return -EINVAL;
> +		default:
> +			break;
> +		}
> +	}
> +
> +	/* Y-tiling is not supported in IF-ID Interlace mode */
> +	if (crtc_state->hw.enable &&
> +	    crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE &&
> +	    (fb->modifier == I915_FORMAT_MOD_Y_TILED ||
> +	     fb->modifier == I915_FORMAT_MOD_Yf_TILED ||
> +	     fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
> +	     fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS ||
> +	     fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS ||
> +	     fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS ||
> +	     fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC)) {
> +		drm_dbg_kms(&dev_priv->drm,
> +			    "Y/Yf tiling not supported in IF-ID mode\n");
> +		return -EINVAL;
> +	}
> +
> +	/* Wa_1606054188:tgl,adl-s */
> +	if ((IS_ALDERLAKE_S(dev_priv) || IS_TIGERLAKE(dev_priv)) &&
> +	    plane_state->ckey.flags & I915_SET_COLORKEY_SOURCE &&
> +	    intel_format_is_p01x(fb->format->format)) {
> +		drm_dbg_kms(&dev_priv->drm,
> +			    "Source color keying not supported with P01x formats\n");
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_state,
> +					   const struct intel_plane_state *plane_state)
> +{
> +	struct drm_i915_private *dev_priv =
> +		to_i915(plane_state->uapi.plane->dev);
> +	int crtc_x = plane_state->uapi.dst.x1;
> +	int crtc_w = drm_rect_width(&plane_state->uapi.dst);
> +	int pipe_src_w = crtc_state->pipe_src_w;
> +
> +	/*
> +	 * Display WA #1175: cnl,glk
> +	 * Planes other than the cursor may cause FIFO underflow and display
> +	 * corruption if starting less than 4 pixels from the right edge of
> +	 * the screen.
> +	 * Besides the above WA fix the similar problem, where planes other
> +	 * than the cursor ending less than 4 pixels from the left edge of the
> +	 * screen may cause FIFO underflow and display corruption.
> +	 */
> +	if ((IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) &&
> +	    (crtc_x + crtc_w < 4 || crtc_x > pipe_src_w - 4)) {
> +		drm_dbg_kms(&dev_priv->drm,
> +			    "requested plane X %s position %d invalid (valid range %d-%d)\n",
> +			    crtc_x + crtc_w < 4 ? "end" : "start",
> +			    crtc_x + crtc_w < 4 ? crtc_x + crtc_w : crtc_x,
> +			    4, pipe_src_w - 4);
> +		return -ERANGE;
> +	}
> +
> +	return 0;
> +}
> +
> +static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_state)
> +{
> +	const struct drm_framebuffer *fb = plane_state->hw.fb;
> +	unsigned int rotation = plane_state->hw.rotation;
> +	int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
> +
> +	/* Display WA #1106 */
> +	if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) &&
> +	    src_w & 3 &&
> +	    (rotation == DRM_MODE_ROTATE_270 ||
> +	     rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) {
> +		DRM_DEBUG_KMS("src width must be multiple of 4 for rotated planar YUV\n");
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int skl_plane_max_scale(struct drm_i915_private *dev_priv,
> +			       const struct drm_framebuffer *fb)
> +{
> +	/*
> +	 * We don't yet know the final source width nor
> +	 * whether we can use the HQ scaler mode. Assume
> +	 * the best case.
> +	 * FIXME need to properly check this later.
> +	 */
> +	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv) ||
> +	    !intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
> +		return 0x30000 - 1;
> +	else
> +		return 0x20000 - 1;
> +}
> +
> +static int intel_plane_min_width(struct intel_plane *plane,
> +				 const struct drm_framebuffer *fb,
> +				 int color_plane,
> +				 unsigned int rotation)
> +{
> +	if (plane->min_width)
> +		return plane->min_width(fb, color_plane, rotation);
> +	else
> +		return 1;
> +}
> +
> +static int intel_plane_max_width(struct intel_plane *plane,
> +				 const struct drm_framebuffer *fb,
> +				 int color_plane,
> +				 unsigned int rotation)
> +{
> +	if (plane->max_width)
> +		return plane->max_width(fb, color_plane, rotation);
> +	else
> +		return INT_MAX;
> +}
> +
> +static int intel_plane_max_height(struct intel_plane *plane,
> +				  const struct drm_framebuffer *fb,
> +				  int color_plane,
> +				  unsigned int rotation)
> +{
> +	if (plane->max_height)
> +		return plane->max_height(fb, color_plane, rotation);
> +	else
> +		return INT_MAX;
> +}
> +
> +static bool
> +skl_check_main_ccs_coordinates(struct intel_plane_state *plane_state,
> +			       int main_x, int main_y, u32 main_offset,
> +			       int ccs_plane)
> +{
> +	const struct drm_framebuffer *fb = plane_state->hw.fb;
> +	int aux_x = plane_state->color_plane[ccs_plane].x;
> +	int aux_y = plane_state->color_plane[ccs_plane].y;
> +	u32 aux_offset = plane_state->color_plane[ccs_plane].offset;
> +	u32 alignment = intel_surf_alignment(fb, ccs_plane);
> +	int hsub;
> +	int vsub;
> +
> +	intel_fb_plane_get_subsampling(&hsub, &vsub, fb, ccs_plane);
> +	while (aux_offset >= main_offset && aux_y <= main_y) {
> +		int x, y;
> +
> +		if (aux_x == main_x && aux_y == main_y)
> +			break;
> +
> +		if (aux_offset == 0)
> +			break;
> +
> +		x = aux_x / hsub;
> +		y = aux_y / vsub;
> +		aux_offset = intel_plane_adjust_aligned_offset(&x, &y,
> +							       plane_state,
> +							       ccs_plane,
> +							       aux_offset,
> +							       aux_offset -
> +								alignment);
> +		aux_x = x * hsub + aux_x % hsub;
> +		aux_y = y * vsub + aux_y % vsub;
> +	}
> +
> +	if (aux_x != main_x || aux_y != main_y)
> +		return false;
> +
> +	plane_state->color_plane[ccs_plane].offset = aux_offset;
> +	plane_state->color_plane[ccs_plane].x = aux_x;
> +	plane_state->color_plane[ccs_plane].y = aux_y;
> +
> +	return true;
> +}
> +
> +
> +int skl_calc_main_surface_offset(const struct intel_plane_state *plane_state,
> +				 int *x, int *y, u32 *offset)
> +{
> +	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
> +	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> +	const struct drm_framebuffer *fb = plane_state->hw.fb;
> +	const int aux_plane = skl_main_to_aux_plane(fb, 0);
> +	const u32 aux_offset = plane_state->color_plane[aux_plane].offset;
> +	const u32 alignment = intel_surf_alignment(fb, 0);
> +	const int w = drm_rect_width(&plane_state->uapi.src) >> 16;
> +
> +	intel_add_fb_offsets(x, y, plane_state, 0);
> +	*offset = intel_plane_compute_aligned_offset(x, y, plane_state, 0);
> +	if (drm_WARN_ON(&dev_priv->drm, alignment && !is_power_of_2(alignment)))
> +		return -EINVAL;
> +
> +	/*
> +	 * AUX surface offset is specified as the distance from the
> +	 * main surface offset, and it must be non-negative. Make
> +	 * sure that is what we will get.
> +	 */
> +	if (aux_plane && *offset > aux_offset)
> +		*offset = intel_plane_adjust_aligned_offset(x, y, plane_state, 0,
> +							    *offset,
> +							    aux_offset & ~(alignment - 1));
> +
> +	/*
> +	 * When using an X-tiled surface, the plane blows up
> +	 * if the x offset + width exceed the stride.
> +	 *
> +	 * TODO: linear and Y-tiled seem fine, Yf untested,
> +	 */
> +	if (fb->modifier == I915_FORMAT_MOD_X_TILED) {
> +		int cpp = fb->format->cpp[0];
> +
> +		while ((*x + w) * cpp > plane_state->color_plane[0].stride) {
> +			if (*offset == 0) {
> +				drm_dbg_kms(&dev_priv->drm,
> +					    "Unable to find suitable display surface offset due to X-tiling\n");
> +				return -EINVAL;
> +			}
> +
> +			*offset = intel_plane_adjust_aligned_offset(x, y, plane_state, 0,
> +								    *offset,
> +								    *offset - alignment);
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static int skl_check_main_surface(struct intel_plane_state *plane_state)
> +{
> +	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
> +	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> +	const struct drm_framebuffer *fb = plane_state->hw.fb;
> +	const unsigned int rotation = plane_state->hw.rotation;
> +	int x = plane_state->uapi.src.x1 >> 16;
> +	int y = plane_state->uapi.src.y1 >> 16;
> +	const int w = drm_rect_width(&plane_state->uapi.src) >> 16;
> +	const int h = drm_rect_height(&plane_state->uapi.src) >> 16;
> +	const int min_width = intel_plane_min_width(plane, fb, 0, rotation);
> +	const int max_width = intel_plane_max_width(plane, fb, 0, rotation);
> +	const int max_height = intel_plane_max_height(plane, fb, 0, rotation);
> +	const int aux_plane = skl_main_to_aux_plane(fb, 0);
> +	const u32 alignment = intel_surf_alignment(fb, 0);
> +	u32 offset;
> +	int ret;
> +
> +	if (w > max_width || w < min_width || h > max_height) {
> +		drm_dbg_kms(&dev_priv->drm,
> +			    "requested Y/RGB source size %dx%d outside limits (min: %dx1 max: %dx%d)\n",
> +			    w, h, min_width, max_width, max_height);
> +		return -EINVAL;
> +	}
> +
> +	ret = skl_calc_main_surface_offset(plane_state, &x, &y, &offset);
> +	if (ret)
> +		return ret;
> +
> +	/*
> +	 * CCS AUX surface doesn't have its own x/y offsets, we must make sure
> +	 * they match with the main surface x/y offsets.
> +	 */
> +	if (is_ccs_modifier(fb->modifier)) {
> +		while (!skl_check_main_ccs_coordinates(plane_state, x, y,
> +						       offset, aux_plane)) {
> +			if (offset == 0)
> +				break;
> +
> +			offset = intel_plane_adjust_aligned_offset(&x, &y, plane_state, 0,
> +								   offset, offset - alignment);
> +		}
> +
> +		if (x != plane_state->color_plane[aux_plane].x ||
> +		    y != plane_state->color_plane[aux_plane].y) {
> +			drm_dbg_kms(&dev_priv->drm,
> +				    "Unable to find suitable display surface offset due to CCS\n");
> +			return -EINVAL;
> +		}
> +	}
> +
> +	drm_WARN_ON(&dev_priv->drm, x > 8191 || y > 8191);
> +
> +	plane_state->color_plane[0].offset = offset;
> +	plane_state->color_plane[0].x = x;
> +	plane_state->color_plane[0].y = y;
> +
> +	/*
> +	 * Put the final coordinates back so that the src
> +	 * coordinate checks will see the right values.
> +	 */
> +	drm_rect_translate_to(&plane_state->uapi.src,
> +			      x << 16, y << 16);
> +
> +	return 0;
> +}
> +
> +static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state)
> +{
> +	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
> +	struct drm_i915_private *i915 = to_i915(plane->base.dev);
> +	const struct drm_framebuffer *fb = plane_state->hw.fb;
> +	unsigned int rotation = plane_state->hw.rotation;
> +	int uv_plane = 1;
> +	int max_width = intel_plane_max_width(plane, fb, uv_plane, rotation);
> +	int max_height = intel_plane_max_height(plane, fb, uv_plane, rotation);
> +	int x = plane_state->uapi.src.x1 >> 17;
> +	int y = plane_state->uapi.src.y1 >> 17;
> +	int w = drm_rect_width(&plane_state->uapi.src) >> 17;
> +	int h = drm_rect_height(&plane_state->uapi.src) >> 17;
> +	u32 offset;
> +
> +	/* FIXME not quite sure how/if these apply to the chroma plane */
> +	if (w > max_width || h > max_height) {
> +		drm_dbg_kms(&i915->drm,
> +			    "CbCr source size %dx%d too big (limit %dx%d)\n",
> +			    w, h, max_width, max_height);
> +		return -EINVAL;
> +	}
> +
> +	intel_add_fb_offsets(&x, &y, plane_state, uv_plane);
> +	offset = intel_plane_compute_aligned_offset(&x, &y,
> +						    plane_state, uv_plane);
> +
> +	if (is_ccs_modifier(fb->modifier)) {
> +		int ccs_plane = main_to_ccs_plane(fb, uv_plane);
> +		u32 aux_offset = plane_state->color_plane[ccs_plane].offset;
> +		u32 alignment = intel_surf_alignment(fb, uv_plane);
> +
> +		if (offset > aux_offset)
> +			offset = intel_plane_adjust_aligned_offset(&x, &y,
> +								   plane_state,
> +								   uv_plane,
> +								   offset,
> +								   aux_offset & ~(alignment - 1));
> +
> +		while (!skl_check_main_ccs_coordinates(plane_state, x, y,
> +						       offset, ccs_plane)) {
> +			if (offset == 0)
> +				break;
> +
> +			offset = intel_plane_adjust_aligned_offset(&x, &y,
> +								   plane_state,
> +								   uv_plane,
> +								   offset, offset - alignment);
> +		}
> +
> +		if (x != plane_state->color_plane[ccs_plane].x ||
> +		    y != plane_state->color_plane[ccs_plane].y) {
> +			drm_dbg_kms(&i915->drm,
> +				    "Unable to find suitable display surface offset due to CCS\n");
> +			return -EINVAL;
> +		}
> +	}
> +
> +	drm_WARN_ON(&i915->drm, x > 8191 || y > 8191);
> +
> +	plane_state->color_plane[uv_plane].offset = offset;
> +	plane_state->color_plane[uv_plane].x = x;
> +	plane_state->color_plane[uv_plane].y = y;
> +
> +	return 0;
> +}
> +
> +static int skl_check_ccs_aux_surface(struct intel_plane_state *plane_state)
> +{
> +	const struct drm_framebuffer *fb = plane_state->hw.fb;
> +	int src_x = plane_state->uapi.src.x1 >> 16;
> +	int src_y = plane_state->uapi.src.y1 >> 16;
> +	u32 offset;
> +	int ccs_plane;
> +
> +	for (ccs_plane = 0; ccs_plane < fb->format->num_planes; ccs_plane++) {
> +		int main_hsub, main_vsub;
> +		int hsub, vsub;
> +		int x, y;
> +
> +		if (!is_ccs_plane(fb, ccs_plane) ||
> +		    is_gen12_ccs_cc_plane(fb, ccs_plane))
> +			continue;
> +
> +		intel_fb_plane_get_subsampling(&main_hsub, &main_vsub, fb,
> +					       skl_ccs_to_main_plane(fb, ccs_plane));
> +		intel_fb_plane_get_subsampling(&hsub, &vsub, fb, ccs_plane);
> +
> +		hsub *= main_hsub;
> +		vsub *= main_vsub;
> +		x = src_x / hsub;
> +		y = src_y / vsub;
> +
> +		intel_add_fb_offsets(&x, &y, plane_state, ccs_plane);
> +
> +		offset = intel_plane_compute_aligned_offset(&x, &y,
> +							    plane_state,
> +							    ccs_plane);
> +
> +		plane_state->color_plane[ccs_plane].offset = offset;
> +		plane_state->color_plane[ccs_plane].x = (x * hsub +
> +							 src_x % hsub) /
> +							main_hsub;
> +		plane_state->color_plane[ccs_plane].y = (y * vsub +
> +							 src_y % vsub) /
> +							main_vsub;
> +	}
> +
> +	return 0;
> +}
> +
> +static int skl_check_plane_surface(struct intel_plane_state *plane_state)
> +{
> +	const struct drm_framebuffer *fb = plane_state->hw.fb;
> +	int ret, i;
> +
> +	ret = intel_plane_compute_gtt(plane_state);
> +	if (ret)
> +		return ret;
> +
> +	if (!plane_state->uapi.visible)
> +		return 0;
> +
> +	/*
> +	 * Handle the AUX surface first since the main surface setup depends on
> +	 * it.
> +	 */
> +	if (is_ccs_modifier(fb->modifier)) {
> +		ret = skl_check_ccs_aux_surface(plane_state);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	if (intel_format_info_is_yuv_semiplanar(fb->format,
> +						fb->modifier)) {
> +		ret = skl_check_nv12_aux_surface(plane_state);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	for (i = fb->format->num_planes; i < ARRAY_SIZE(plane_state->color_plane); i++) {
> +		plane_state->color_plane[i].offset = 0;
> +		plane_state->color_plane[i].x = 0;
> +		plane_state->color_plane[i].y = 0;
> +	}
> +
> +	ret = skl_check_main_surface(plane_state);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static bool intel_fb_scalable(const struct drm_framebuffer *fb)
> +{
> +	if (!fb)
> +		return false;
> +
> +	switch (fb->format->format) {
> +	case DRM_FORMAT_C8:
> +		return false;
> +	case DRM_FORMAT_XRGB16161616F:
> +	case DRM_FORMAT_ARGB16161616F:
> +	case DRM_FORMAT_XBGR16161616F:
> +	case DRM_FORMAT_ABGR16161616F:
> +		return INTEL_GEN(to_i915(fb->dev)) >= 11;
> +	default:
> +		return true;
> +	}
> +}
> +
> +static int skl_plane_check(struct intel_crtc_state *crtc_state,
> +			   struct intel_plane_state *plane_state)
> +{
> +	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
> +	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> +	const struct drm_framebuffer *fb = plane_state->hw.fb;
> +	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
> +	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
> +	int ret;
> +
> +	ret = skl_plane_check_fb(crtc_state, plane_state);
> +	if (ret)
> +		return ret;
> +
> +	/* use scaler when colorkey is not required */
> +	if (!plane_state->ckey.flags && intel_fb_scalable(fb)) {
> +		min_scale = 1;
> +		max_scale = skl_plane_max_scale(dev_priv, fb);
> +	}
> +
> +	ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
> +						min_scale, max_scale, true);
> +	if (ret)
> +		return ret;
> +
> +	ret = skl_check_plane_surface(plane_state);
> +	if (ret)
> +		return ret;
> +
> +	if (!plane_state->uapi.visible)
> +		return 0;
> +
> +	ret = skl_plane_check_dst_coordinates(crtc_state, plane_state);
> +	if (ret)
> +		return ret;
> +
> +	ret = intel_plane_check_src_coordinates(plane_state);
> +	if (ret)
> +		return ret;
> +
> +	ret = skl_plane_check_nv12_rotation(plane_state);
> +	if (ret)
> +		return ret;
> +
> +	/* HW only has 8 bits pixel precision, disable plane if invisible */
> +	if (!(plane_state->hw.alpha >> 8))
> +		plane_state->uapi.visible = false;
> +
> +	plane_state->ctl = skl_plane_ctl(crtc_state, plane_state);
> +
> +	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> +		plane_state->color_ctl = glk_plane_color_ctl(crtc_state,
> +							     plane_state);
> +
> +	if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) &&
> +	    icl_is_hdr_plane(dev_priv, plane->id))
> +		/* Enable and use MPEG-2 chroma siting */
> +		plane_state->cus_ctl = PLANE_CUS_ENABLE |
> +			PLANE_CUS_HPHASE_0 |
> +			PLANE_CUS_VPHASE_SIGN_NEGATIVE | PLANE_CUS_VPHASE_0_25;
> +	else
> +		plane_state->cus_ctl = 0;
> +
> +	return 0;
> +}
> +
> +static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv,
> +			      enum pipe pipe, enum plane_id plane_id)
> +{
> +	if (!HAS_FBC(dev_priv))
> +		return false;
> +
> +	return pipe == PIPE_A && plane_id == PLANE_PRIMARY;
> +}
> +
> +static bool skl_plane_has_planar(struct drm_i915_private *dev_priv,
> +				 enum pipe pipe, enum plane_id plane_id)
> +{
> +	/* Display WA #0870: skl, bxt */
> +	if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv))
> +		return false;
> +
> +	if (IS_GEN(dev_priv, 9) && !IS_GEMINILAKE(dev_priv) && pipe == PIPE_C)
> +		return false;
> +
> +	if (plane_id != PLANE_PRIMARY && plane_id != PLANE_SPRITE0)
> +		return false;
> +
> +	return true;
> +}
> +
> +static const u32 *skl_get_plane_formats(struct drm_i915_private *dev_priv,
> +					enum pipe pipe, enum plane_id plane_id,
> +					int *num_formats)
> +{
> +	if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
> +		*num_formats = ARRAY_SIZE(skl_planar_formats);
> +		return skl_planar_formats;
> +	} else {
> +		*num_formats = ARRAY_SIZE(skl_plane_formats);
> +		return skl_plane_formats;
> +	}
> +}
> +
> +static const u32 *glk_get_plane_formats(struct drm_i915_private *dev_priv,
> +					enum pipe pipe, enum plane_id plane_id,
> +					int *num_formats)
> +{
> +	if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
> +		*num_formats = ARRAY_SIZE(glk_planar_formats);
> +		return glk_planar_formats;
> +	} else {
> +		*num_formats = ARRAY_SIZE(skl_plane_formats);
> +		return skl_plane_formats;
> +	}
> +}
> +
> +static const u32 *icl_get_plane_formats(struct drm_i915_private *dev_priv,
> +					enum pipe pipe, enum plane_id plane_id,
> +					int *num_formats)
> +{
> +	if (icl_is_hdr_plane(dev_priv, plane_id)) {
> +		*num_formats = ARRAY_SIZE(icl_hdr_plane_formats);
> +		return icl_hdr_plane_formats;
> +	} else if (icl_is_nv12_y_plane(dev_priv, plane_id)) {
> +		*num_formats = ARRAY_SIZE(icl_sdr_y_plane_formats);
> +		return icl_sdr_y_plane_formats;
> +	} else {
> +		*num_formats = ARRAY_SIZE(icl_sdr_uv_plane_formats);
> +		return icl_sdr_uv_plane_formats;
> +	}
> +}
> +
> +static bool skl_plane_has_ccs(struct drm_i915_private *dev_priv,
> +			      enum pipe pipe, enum plane_id plane_id)
> +{
> +	if (plane_id == PLANE_CURSOR)
> +		return false;
> +
> +	if (INTEL_GEN(dev_priv) >= 10)
> +		return true;
> +
> +	if (IS_GEMINILAKE(dev_priv))
> +		return pipe != PIPE_C;
> +
> +	return pipe != PIPE_C &&
> +		(plane_id == PLANE_PRIMARY ||
> +		 plane_id == PLANE_SPRITE0);
> +}
> +
> +static bool skl_plane_format_mod_supported(struct drm_plane *_plane,
> +					   u32 format, u64 modifier)
> +{
> +	struct intel_plane *plane = to_intel_plane(_plane);
> +
> +	switch (modifier) {
> +	case DRM_FORMAT_MOD_LINEAR:
> +	case I915_FORMAT_MOD_X_TILED:
> +	case I915_FORMAT_MOD_Y_TILED:
> +	case I915_FORMAT_MOD_Yf_TILED:
> +		break;
> +	case I915_FORMAT_MOD_Y_TILED_CCS:
> +	case I915_FORMAT_MOD_Yf_TILED_CCS:
> +		if (!plane->has_ccs)
> +			return false;
> +		break;
> +	default:
> +		return false;
> +	}
> +
> +	switch (format) {
> +	case DRM_FORMAT_XRGB8888:
> +	case DRM_FORMAT_XBGR8888:
> +	case DRM_FORMAT_ARGB8888:
> +	case DRM_FORMAT_ABGR8888:
> +		if (is_ccs_modifier(modifier))
> +			return true;
> +		fallthrough;
> +	case DRM_FORMAT_RGB565:
> +	case DRM_FORMAT_XRGB2101010:
> +	case DRM_FORMAT_XBGR2101010:
> +	case DRM_FORMAT_ARGB2101010:
> +	case DRM_FORMAT_ABGR2101010:
> +	case DRM_FORMAT_YUYV:
> +	case DRM_FORMAT_YVYU:
> +	case DRM_FORMAT_UYVY:
> +	case DRM_FORMAT_VYUY:
> +	case DRM_FORMAT_NV12:
> +	case DRM_FORMAT_XYUV8888:
> +	case DRM_FORMAT_P010:
> +	case DRM_FORMAT_P012:
> +	case DRM_FORMAT_P016:
> +	case DRM_FORMAT_XVYU2101010:
> +		if (modifier == I915_FORMAT_MOD_Yf_TILED)
> +			return true;
> +		fallthrough;
> +	case DRM_FORMAT_C8:
> +	case DRM_FORMAT_XBGR16161616F:
> +	case DRM_FORMAT_ABGR16161616F:
> +	case DRM_FORMAT_XRGB16161616F:
> +	case DRM_FORMAT_ARGB16161616F:
> +	case DRM_FORMAT_Y210:
> +	case DRM_FORMAT_Y212:
> +	case DRM_FORMAT_Y216:
> +	case DRM_FORMAT_XVYU12_16161616:
> +	case DRM_FORMAT_XVYU16161616:
> +		if (modifier == DRM_FORMAT_MOD_LINEAR ||
> +		    modifier == I915_FORMAT_MOD_X_TILED ||
> +		    modifier == I915_FORMAT_MOD_Y_TILED)
> +			return true;
> +		fallthrough;
> +	default:
> +		return false;
> +	}
> +}
> +
> +static bool gen12_plane_supports_mc_ccs(struct drm_i915_private *dev_priv,
> +					enum plane_id plane_id)
> +{
> +	/* Wa_14010477008:tgl[a0..c0],rkl[all],dg1[all] */
> +	if (IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv) ||
> +	    IS_TGL_DISP_STEPPING(dev_priv, STEP_A0, STEP_C0))
> +		return false;
> +
> +	return plane_id < PLANE_SPRITE4;
> +}
> +
> +static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,
> +					     u32 format, u64 modifier)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(_plane->dev);
> +	struct intel_plane *plane = to_intel_plane(_plane);
> +
> +	switch (modifier) {
> +	case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
> +		if (!gen12_plane_supports_mc_ccs(dev_priv, plane->id))
> +			return false;
> +		fallthrough;
> +	case DRM_FORMAT_MOD_LINEAR:
> +	case I915_FORMAT_MOD_X_TILED:
> +	case I915_FORMAT_MOD_Y_TILED:
> +	case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
> +	case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC:
> +		break;
> +	default:
> +		return false;
> +	}
> +
> +	switch (format) {
> +	case DRM_FORMAT_XRGB8888:
> +	case DRM_FORMAT_XBGR8888:
> +	case DRM_FORMAT_ARGB8888:
> +	case DRM_FORMAT_ABGR8888:
> +		if (is_ccs_modifier(modifier))
> +			return true;
> +		fallthrough;
> +	case DRM_FORMAT_YUYV:
> +	case DRM_FORMAT_YVYU:
> +	case DRM_FORMAT_UYVY:
> +	case DRM_FORMAT_VYUY:
> +	case DRM_FORMAT_NV12:
> +	case DRM_FORMAT_XYUV8888:
> +	case DRM_FORMAT_P010:
> +	case DRM_FORMAT_P012:
> +	case DRM_FORMAT_P016:
> +		if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS)
> +			return true;
> +		fallthrough;
> +	case DRM_FORMAT_RGB565:
> +	case DRM_FORMAT_XRGB2101010:
> +	case DRM_FORMAT_XBGR2101010:
> +	case DRM_FORMAT_ARGB2101010:
> +	case DRM_FORMAT_ABGR2101010:
> +	case DRM_FORMAT_XVYU2101010:
> +	case DRM_FORMAT_C8:
> +	case DRM_FORMAT_XBGR16161616F:
> +	case DRM_FORMAT_ABGR16161616F:
> +	case DRM_FORMAT_XRGB16161616F:
> +	case DRM_FORMAT_ARGB16161616F:
> +	case DRM_FORMAT_Y210:
> +	case DRM_FORMAT_Y212:
> +	case DRM_FORMAT_Y216:
> +	case DRM_FORMAT_XVYU12_16161616:
> +	case DRM_FORMAT_XVYU16161616:
> +		if (modifier == DRM_FORMAT_MOD_LINEAR ||
> +		    modifier == I915_FORMAT_MOD_X_TILED ||
> +		    modifier == I915_FORMAT_MOD_Y_TILED)
> +			return true;
> +		fallthrough;
> +	default:
> +		return false;
> +	}
> +}
> +
> +static const u64 *gen12_get_plane_modifiers(struct drm_i915_private *dev_priv,
> +					    enum plane_id plane_id)
> +{
> +	if (gen12_plane_supports_mc_ccs(dev_priv, plane_id))
> +		return gen12_plane_format_modifiers_mc_ccs;
> +	else
> +		return gen12_plane_format_modifiers_rc_ccs;
> +}
> +
> +static const struct drm_plane_funcs skl_plane_funcs = {
> +	.update_plane = drm_atomic_helper_update_plane,
> +	.disable_plane = drm_atomic_helper_disable_plane,
> +	.destroy = intel_plane_destroy,
> +	.atomic_duplicate_state = intel_plane_duplicate_state,
> +	.atomic_destroy_state = intel_plane_destroy_state,
> +	.format_mod_supported = skl_plane_format_mod_supported,
> +};
> +
> +static const struct drm_plane_funcs gen12_plane_funcs = {
> +	.update_plane = drm_atomic_helper_update_plane,
> +	.disable_plane = drm_atomic_helper_disable_plane,
> +	.destroy = intel_plane_destroy,
> +	.atomic_duplicate_state = intel_plane_duplicate_state,
> +	.atomic_destroy_state = intel_plane_destroy_state,
> +	.format_mod_supported = gen12_plane_format_mod_supported,
> +};
> +
> +static void
> +skl_plane_enable_flip_done(struct intel_plane *plane)
> +{
> +	struct drm_i915_private *i915 = to_i915(plane->base.dev);
> +	enum pipe pipe = plane->pipe;
> +
> +	spin_lock_irq(&i915->irq_lock);
> +	bdw_enable_pipe_irq(i915, pipe, GEN9_PIPE_PLANE_FLIP_DONE(plane->id));
> +	spin_unlock_irq(&i915->irq_lock);
> +}
> +
> +static void
> +skl_plane_disable_flip_done(struct intel_plane *plane)
> +{
> +	struct drm_i915_private *i915 = to_i915(plane->base.dev);
> +	enum pipe pipe = plane->pipe;
> +
> +	spin_lock_irq(&i915->irq_lock);
> +	bdw_disable_pipe_irq(i915, pipe, GEN9_PIPE_PLANE_FLIP_DONE(plane->id));
> +	spin_unlock_irq(&i915->irq_lock);
> +}
> +
> +struct intel_plane *
> +skl_universal_plane_create(struct drm_i915_private *dev_priv,
> +			   enum pipe pipe, enum plane_id plane_id)
> +{
> +	const struct drm_plane_funcs *plane_funcs;
> +	struct intel_plane *plane;
> +	enum drm_plane_type plane_type;
> +	unsigned int supported_rotations;
> +	unsigned int supported_csc;
> +	const u64 *modifiers;
> +	const u32 *formats;
> +	int num_formats;
> +	int ret;
> +
> +	plane = intel_plane_alloc();
> +	if (IS_ERR(plane))
> +		return plane;
> +
> +	plane->pipe = pipe;
> +	plane->id = plane_id;
> +	plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane_id);
> +
> +	plane->has_fbc = skl_plane_has_fbc(dev_priv, pipe, plane_id);
> +	if (plane->has_fbc) {
> +		struct intel_fbc *fbc = &dev_priv->fbc;
> +
> +		fbc->possible_framebuffer_bits |= plane->frontbuffer_bit;
> +	}
> +
> +	if (INTEL_GEN(dev_priv) >= 11) {
> +		plane->min_width = icl_plane_min_width;
> +		plane->max_width = icl_plane_max_width;
> +		plane->max_height = icl_plane_max_height;
> +	} else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) {
> +		plane->max_width = glk_plane_max_width;
> +		plane->max_height = skl_plane_max_height;
> +	} else {
> +		plane->max_width = skl_plane_max_width;
> +		plane->max_height = skl_plane_max_height;
> +	}
> +
> +	plane->max_stride = skl_plane_max_stride;
> +	plane->update_plane = skl_update_plane;
> +	plane->disable_plane = skl_disable_plane;
> +	plane->get_hw_state = skl_plane_get_hw_state;
> +	plane->check_plane = skl_plane_check;
> +	plane->min_cdclk = skl_plane_min_cdclk;
> +
> +	if (plane_id == PLANE_PRIMARY) {
> +		plane->need_async_flip_disable_wa = IS_GEN_RANGE(dev_priv, 9, 10);
> +		plane->async_flip = skl_plane_async_flip;
> +		plane->enable_flip_done = skl_plane_enable_flip_done;
> +		plane->disable_flip_done = skl_plane_disable_flip_done;
> +	}
> +
> +	if (INTEL_GEN(dev_priv) >= 11)
> +		formats = icl_get_plane_formats(dev_priv, pipe,
> +						plane_id, &num_formats);
> +	else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> +		formats = glk_get_plane_formats(dev_priv, pipe,
> +						plane_id, &num_formats);
> +	else
> +		formats = skl_get_plane_formats(dev_priv, pipe,
> +						plane_id, &num_formats);
> +
> +	plane->has_ccs = skl_plane_has_ccs(dev_priv, pipe, plane_id);
> +	if (INTEL_GEN(dev_priv) >= 12) {
> +		modifiers = gen12_get_plane_modifiers(dev_priv, plane_id);
> +		plane_funcs = &gen12_plane_funcs;
> +	} else {
> +		if (plane->has_ccs)
> +			modifiers = skl_plane_format_modifiers_ccs;
> +		else
> +			modifiers = skl_plane_format_modifiers_noccs;
> +		plane_funcs = &skl_plane_funcs;
> +	}
> +
> +	if (plane_id == PLANE_PRIMARY)
> +		plane_type = DRM_PLANE_TYPE_PRIMARY;
> +	else
> +		plane_type = DRM_PLANE_TYPE_OVERLAY;
> +
> +	ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
> +				       0, plane_funcs,
> +				       formats, num_formats, modifiers,
> +				       plane_type,
> +				       "plane %d%c", plane_id + 1,
> +				       pipe_name(pipe));
> +	if (ret)
> +		goto fail;
> +
> +	supported_rotations =
> +		DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 |
> +		DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270;
> +
> +	if (INTEL_GEN(dev_priv) >= 10)
> +		supported_rotations |= DRM_MODE_REFLECT_X;
> +
> +	drm_plane_create_rotation_property(&plane->base,
> +					   DRM_MODE_ROTATE_0,
> +					   supported_rotations);
> +
> +	supported_csc = BIT(DRM_COLOR_YCBCR_BT601) | BIT(DRM_COLOR_YCBCR_BT709);
> +
> +	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> +		supported_csc |= BIT(DRM_COLOR_YCBCR_BT2020);
> +
> +	drm_plane_create_color_properties(&plane->base,
> +					  supported_csc,
> +					  BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
> +					  BIT(DRM_COLOR_YCBCR_FULL_RANGE),
> +					  DRM_COLOR_YCBCR_BT709,
> +					  DRM_COLOR_YCBCR_LIMITED_RANGE);
> +
> +	drm_plane_create_alpha_property(&plane->base);
> +	drm_plane_create_blend_mode_property(&plane->base,
> +					     BIT(DRM_MODE_BLEND_PIXEL_NONE) |
> +					     BIT(DRM_MODE_BLEND_PREMULTI) |
> +					     BIT(DRM_MODE_BLEND_COVERAGE));
> +
> +	drm_plane_create_zpos_immutable_property(&plane->base, plane_id);
> +
> +	if (INTEL_GEN(dev_priv) >= 12)
> +		drm_plane_enable_fb_damage_clips(&plane->base);
> +
> +	if (INTEL_GEN(dev_priv) >= 10)
> +		drm_plane_create_scaling_filter_property(&plane->base,
> +						BIT(DRM_SCALING_FILTER_DEFAULT) |
> +						BIT(DRM_SCALING_FILTER_NEAREST_NEIGHBOR));
> +
> +	drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
> +
> +	return plane;
> +
> +fail:
> +	intel_plane_free(plane);
> +
> +	return ERR_PTR(ret);
> +}
> +
> +void
> +skl_get_initial_plane_config(struct intel_crtc *crtc,
> +			     struct intel_initial_plane_config *plane_config)
> +{
> +	struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state);
> +	struct drm_device *dev = crtc->base.dev;
> +	struct drm_i915_private *dev_priv = to_i915(dev);
> +	struct intel_plane *plane = to_intel_plane(crtc->base.primary);
> +	enum plane_id plane_id = plane->id;
> +	enum pipe pipe;
> +	u32 val, base, offset, stride_mult, tiling, alpha;
> +	int fourcc, pixel_format;
> +	unsigned int aligned_height;
> +	struct drm_framebuffer *fb;
> +	struct intel_framebuffer *intel_fb;
> +
> +	if (!plane->get_hw_state(plane, &pipe))
> +		return;
> +
> +	drm_WARN_ON(dev, pipe != crtc->pipe);
> +
> +	if (crtc_state->bigjoiner) {
> +		drm_dbg_kms(&dev_priv->drm,
> +			    "Unsupported bigjoiner configuration for initial FB\n");
> +		return;
> +	}
> +
> +	intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
> +	if (!intel_fb) {
> +		drm_dbg_kms(&dev_priv->drm, "failed to alloc fb\n");
> +		return;
> +	}
> +
> +	fb = &intel_fb->base;
> +
> +	fb->dev = dev;
> +
> +	val = intel_de_read(dev_priv, PLANE_CTL(pipe, plane_id));
> +
> +	if (INTEL_GEN(dev_priv) >= 11)
> +		pixel_format = val & ICL_PLANE_CTL_FORMAT_MASK;
> +	else
> +		pixel_format = val & PLANE_CTL_FORMAT_MASK;
> +
> +	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) {
> +		alpha = intel_de_read(dev_priv,
> +				      PLANE_COLOR_CTL(pipe, plane_id));
> +		alpha &= PLANE_COLOR_ALPHA_MASK;
> +	} else {
> +		alpha = val & PLANE_CTL_ALPHA_MASK;
> +	}
> +
> +	fourcc = skl_format_to_fourcc(pixel_format,
> +				      val & PLANE_CTL_ORDER_RGBX, alpha);
> +	fb->format = drm_format_info(fourcc);
> +
> +	tiling = val & PLANE_CTL_TILED_MASK;
> +	switch (tiling) {
> +	case PLANE_CTL_TILED_LINEAR:
> +		fb->modifier = DRM_FORMAT_MOD_LINEAR;
> +		break;
> +	case PLANE_CTL_TILED_X:
> +		plane_config->tiling = I915_TILING_X;
> +		fb->modifier = I915_FORMAT_MOD_X_TILED;
> +		break;
> +	case PLANE_CTL_TILED_Y:
> +		plane_config->tiling = I915_TILING_Y;
> +		if (val & PLANE_CTL_RENDER_DECOMPRESSION_ENABLE)
> +			fb->modifier = INTEL_GEN(dev_priv) >= 12 ?
> +				I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS :
> +				I915_FORMAT_MOD_Y_TILED_CCS;
> +		else if (val & PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE)
> +			fb->modifier = I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS;
> +		else
> +			fb->modifier = I915_FORMAT_MOD_Y_TILED;
> +		break;
> +	case PLANE_CTL_TILED_YF:
> +		if (val & PLANE_CTL_RENDER_DECOMPRESSION_ENABLE)
> +			fb->modifier = I915_FORMAT_MOD_Yf_TILED_CCS;
> +		else
> +			fb->modifier = I915_FORMAT_MOD_Yf_TILED;
> +		break;
> +	default:
> +		MISSING_CASE(tiling);
> +		goto error;
> +	}
> +
> +	/*
> +	 * DRM_MODE_ROTATE_ is counter clockwise to stay compatible with Xrandr
> +	 * while i915 HW rotation is clockwise, thats why this swapping.
> +	 */
> +	switch (val & PLANE_CTL_ROTATE_MASK) {
> +	case PLANE_CTL_ROTATE_0:
> +		plane_config->rotation = DRM_MODE_ROTATE_0;
> +		break;
> +	case PLANE_CTL_ROTATE_90:
> +		plane_config->rotation = DRM_MODE_ROTATE_270;
> +		break;
> +	case PLANE_CTL_ROTATE_180:
> +		plane_config->rotation = DRM_MODE_ROTATE_180;
> +		break;
> +	case PLANE_CTL_ROTATE_270:
> +		plane_config->rotation = DRM_MODE_ROTATE_90;
> +		break;
> +	}
> +
> +	if (INTEL_GEN(dev_priv) >= 10 &&
> +	    val & PLANE_CTL_FLIP_HORIZONTAL)
> +		plane_config->rotation |= DRM_MODE_REFLECT_X;
> +
> +	/* 90/270 degree rotation would require extra work */
> +	if (drm_rotation_90_or_270(plane_config->rotation))
> +		goto error;
> +
> +	base = intel_de_read(dev_priv, PLANE_SURF(pipe, plane_id)) & 0xfffff000;
> +	plane_config->base = base;
> +
> +	offset = intel_de_read(dev_priv, PLANE_OFFSET(pipe, plane_id));
> +
> +	val = intel_de_read(dev_priv, PLANE_SIZE(pipe, plane_id));
> +	fb->height = ((val >> 16) & 0xffff) + 1;
> +	fb->width = ((val >> 0) & 0xffff) + 1;
> +
> +	val = intel_de_read(dev_priv, PLANE_STRIDE(pipe, plane_id));
> +	stride_mult = skl_plane_stride_mult(fb, 0, DRM_MODE_ROTATE_0);
> +	fb->pitches[0] = (val & 0x3ff) * stride_mult;
> +
> +	aligned_height = intel_fb_align_height(fb, 0, fb->height);
> +
> +	plane_config->size = fb->pitches[0] * aligned_height;
> +
> +	drm_dbg_kms(&dev_priv->drm,
> +		    "%s/%s with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
> +		    crtc->base.name, plane->base.name, fb->width, fb->height,
> +		    fb->format->cpp[0] * 8, base, fb->pitches[0],
> +		    plane_config->size);
> +
> +	plane_config->fb = intel_fb;
> +	return;
> +
> +error:
> +	kfree(intel_fb);
> +}
> +
> diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.h b/drivers/gpu/drm/i915/display/skl_universal_plane.h
> new file mode 100644
> index 000000000000..70eb5010cd28
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.h
> @@ -0,0 +1,33 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright © 2020 Intel Corporation
> + */
> +
> +#ifndef _SKL_UNIVERSAL_PLANE_H_
> +#define _SKL_UNIVERSAL_PLANE_H_
> +
> +#include <linux/types.h>
> +
> +struct drm_framebuffer;
> +struct drm_i915_private;
> +struct intel_crtc;
> +struct intel_initial_plane_config;
> +struct intel_plane_state;
> +
> +enum pipe;
> +enum plane_id;
> +
> +struct intel_plane *
> +skl_universal_plane_create(struct drm_i915_private *dev_priv,
> +			   enum pipe pipe, enum plane_id plane_id);
> +
> +void skl_get_initial_plane_config(struct intel_crtc *crtc,
> +				  struct intel_initial_plane_config *plane_config);
> +
> +int skl_format_to_fourcc(int format, bool rgb_order, bool alpha);
> +
> +int skl_ccs_to_main_plane(const struct drm_framebuffer *fb, int ccs_plane);
> +int skl_calc_main_surface_offset(const struct intel_plane_state *plane_state,
> +				 int *x, int *y, u32 *offset);
> +
> +#endif
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index c58e5077590d..8c42fa51c0f6 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -38,6 +38,7 @@
>  #include "display/intel_display_types.h"
>  #include "display/intel_fbc.h"
>  #include "display/intel_sprite.h"
> +#include "display/skl_universal_plane.h"
>  
>  #include "gt/intel_llc.h"
>  
> -- 
> 2.20.1

-- 
Ville Syrjälä
Intel


More information about the Intel-gfx mailing list