xref: /openbmc/linux/drivers/gpu/drm/i915/display/skl_universal_plane.c (revision 360823a09426347ea8f232b0b0b5156d0aed0302)
146d12f91SDave Airlie // SPDX-License-Identifier: MIT
246d12f91SDave Airlie /*
346d12f91SDave Airlie  * Copyright © 2020 Intel Corporation
446d12f91SDave Airlie  */
546d12f91SDave Airlie 
646d12f91SDave Airlie #include <drm/drm_atomic_helper.h>
790bb087fSVille Syrjälä #include <drm/drm_blend.h>
846d12f91SDave Airlie #include <drm/drm_damage_helper.h>
946d12f91SDave Airlie #include <drm/drm_fourcc.h>
1046d12f91SDave Airlie 
1146d12f91SDave Airlie #include "i915_drv.h"
12801543b2SJani Nikula #include "i915_reg.h"
1346d12f91SDave Airlie #include "intel_atomic_plane.h"
147785ae0bSVille Syrjälä #include "intel_de.h"
152b874a02SJani Nikula #include "intel_display_irq.h"
1646d12f91SDave Airlie #include "intel_display_types.h"
17f837a61fSImre Deak #include "intel_fb.h"
18825bd833SVille Syrjälä #include "intel_fbc.h"
1946d12f91SDave Airlie #include "intel_psr.h"
20714b1cdbSDave Airlie #include "skl_scaler.h"
2146d12f91SDave Airlie #include "skl_universal_plane.h"
2242a0d256SVille Syrjälä #include "skl_watermark.h"
23*b3749611SMatt Roper #include "gt/intel_gt.h"
24ef6ba31dSAnshuman Gupta #include "pxp/intel_pxp.h"
2546d12f91SDave Airlie 
2646d12f91SDave Airlie static const u32 skl_plane_formats[] = {
2746d12f91SDave Airlie 	DRM_FORMAT_C8,
2846d12f91SDave Airlie 	DRM_FORMAT_RGB565,
2946d12f91SDave Airlie 	DRM_FORMAT_XRGB8888,
3046d12f91SDave Airlie 	DRM_FORMAT_XBGR8888,
3146d12f91SDave Airlie 	DRM_FORMAT_ARGB8888,
3246d12f91SDave Airlie 	DRM_FORMAT_ABGR8888,
3346d12f91SDave Airlie 	DRM_FORMAT_XRGB2101010,
3446d12f91SDave Airlie 	DRM_FORMAT_XBGR2101010,
3546d12f91SDave Airlie 	DRM_FORMAT_XRGB16161616F,
3646d12f91SDave Airlie 	DRM_FORMAT_XBGR16161616F,
3746d12f91SDave Airlie 	DRM_FORMAT_YUYV,
3846d12f91SDave Airlie 	DRM_FORMAT_YVYU,
3946d12f91SDave Airlie 	DRM_FORMAT_UYVY,
4046d12f91SDave Airlie 	DRM_FORMAT_VYUY,
4146d12f91SDave Airlie 	DRM_FORMAT_XYUV8888,
4246d12f91SDave Airlie };
4346d12f91SDave Airlie 
4446d12f91SDave Airlie static const u32 skl_planar_formats[] = {
4546d12f91SDave Airlie 	DRM_FORMAT_C8,
4646d12f91SDave Airlie 	DRM_FORMAT_RGB565,
4746d12f91SDave Airlie 	DRM_FORMAT_XRGB8888,
4846d12f91SDave Airlie 	DRM_FORMAT_XBGR8888,
4946d12f91SDave Airlie 	DRM_FORMAT_ARGB8888,
5046d12f91SDave Airlie 	DRM_FORMAT_ABGR8888,
5146d12f91SDave Airlie 	DRM_FORMAT_XRGB2101010,
5246d12f91SDave Airlie 	DRM_FORMAT_XBGR2101010,
5346d12f91SDave Airlie 	DRM_FORMAT_XRGB16161616F,
5446d12f91SDave Airlie 	DRM_FORMAT_XBGR16161616F,
5546d12f91SDave Airlie 	DRM_FORMAT_YUYV,
5646d12f91SDave Airlie 	DRM_FORMAT_YVYU,
5746d12f91SDave Airlie 	DRM_FORMAT_UYVY,
5846d12f91SDave Airlie 	DRM_FORMAT_VYUY,
5946d12f91SDave Airlie 	DRM_FORMAT_NV12,
6046d12f91SDave Airlie 	DRM_FORMAT_XYUV8888,
6146d12f91SDave Airlie };
6246d12f91SDave Airlie 
6346d12f91SDave Airlie static const u32 glk_planar_formats[] = {
6446d12f91SDave Airlie 	DRM_FORMAT_C8,
6546d12f91SDave Airlie 	DRM_FORMAT_RGB565,
6646d12f91SDave Airlie 	DRM_FORMAT_XRGB8888,
6746d12f91SDave Airlie 	DRM_FORMAT_XBGR8888,
6846d12f91SDave Airlie 	DRM_FORMAT_ARGB8888,
6946d12f91SDave Airlie 	DRM_FORMAT_ABGR8888,
7046d12f91SDave Airlie 	DRM_FORMAT_XRGB2101010,
7146d12f91SDave Airlie 	DRM_FORMAT_XBGR2101010,
7246d12f91SDave Airlie 	DRM_FORMAT_XRGB16161616F,
7346d12f91SDave Airlie 	DRM_FORMAT_XBGR16161616F,
7446d12f91SDave Airlie 	DRM_FORMAT_YUYV,
7546d12f91SDave Airlie 	DRM_FORMAT_YVYU,
7646d12f91SDave Airlie 	DRM_FORMAT_UYVY,
7746d12f91SDave Airlie 	DRM_FORMAT_VYUY,
7846d12f91SDave Airlie 	DRM_FORMAT_NV12,
7946d12f91SDave Airlie 	DRM_FORMAT_XYUV8888,
8046d12f91SDave Airlie 	DRM_FORMAT_P010,
8146d12f91SDave Airlie 	DRM_FORMAT_P012,
8246d12f91SDave Airlie 	DRM_FORMAT_P016,
8346d12f91SDave Airlie };
8446d12f91SDave Airlie 
8546d12f91SDave Airlie static const u32 icl_sdr_y_plane_formats[] = {
8646d12f91SDave Airlie 	DRM_FORMAT_C8,
8746d12f91SDave Airlie 	DRM_FORMAT_RGB565,
8846d12f91SDave Airlie 	DRM_FORMAT_XRGB8888,
8946d12f91SDave Airlie 	DRM_FORMAT_XBGR8888,
9046d12f91SDave Airlie 	DRM_FORMAT_ARGB8888,
9146d12f91SDave Airlie 	DRM_FORMAT_ABGR8888,
9246d12f91SDave Airlie 	DRM_FORMAT_XRGB2101010,
9346d12f91SDave Airlie 	DRM_FORMAT_XBGR2101010,
9446d12f91SDave Airlie 	DRM_FORMAT_ARGB2101010,
9546d12f91SDave Airlie 	DRM_FORMAT_ABGR2101010,
9646d12f91SDave Airlie 	DRM_FORMAT_YUYV,
9746d12f91SDave Airlie 	DRM_FORMAT_YVYU,
9846d12f91SDave Airlie 	DRM_FORMAT_UYVY,
9946d12f91SDave Airlie 	DRM_FORMAT_VYUY,
10046d12f91SDave Airlie 	DRM_FORMAT_Y210,
10146d12f91SDave Airlie 	DRM_FORMAT_Y212,
10246d12f91SDave Airlie 	DRM_FORMAT_Y216,
10346d12f91SDave Airlie 	DRM_FORMAT_XYUV8888,
10446d12f91SDave Airlie 	DRM_FORMAT_XVYU2101010,
10546d12f91SDave Airlie };
10646d12f91SDave Airlie 
10746d12f91SDave Airlie static const u32 icl_sdr_uv_plane_formats[] = {
10846d12f91SDave Airlie 	DRM_FORMAT_C8,
10946d12f91SDave Airlie 	DRM_FORMAT_RGB565,
11046d12f91SDave Airlie 	DRM_FORMAT_XRGB8888,
11146d12f91SDave Airlie 	DRM_FORMAT_XBGR8888,
11246d12f91SDave Airlie 	DRM_FORMAT_ARGB8888,
11346d12f91SDave Airlie 	DRM_FORMAT_ABGR8888,
11446d12f91SDave Airlie 	DRM_FORMAT_XRGB2101010,
11546d12f91SDave Airlie 	DRM_FORMAT_XBGR2101010,
11646d12f91SDave Airlie 	DRM_FORMAT_ARGB2101010,
11746d12f91SDave Airlie 	DRM_FORMAT_ABGR2101010,
11846d12f91SDave Airlie 	DRM_FORMAT_YUYV,
11946d12f91SDave Airlie 	DRM_FORMAT_YVYU,
12046d12f91SDave Airlie 	DRM_FORMAT_UYVY,
12146d12f91SDave Airlie 	DRM_FORMAT_VYUY,
12246d12f91SDave Airlie 	DRM_FORMAT_NV12,
12346d12f91SDave Airlie 	DRM_FORMAT_P010,
12446d12f91SDave Airlie 	DRM_FORMAT_P012,
12546d12f91SDave Airlie 	DRM_FORMAT_P016,
12646d12f91SDave Airlie 	DRM_FORMAT_Y210,
12746d12f91SDave Airlie 	DRM_FORMAT_Y212,
12846d12f91SDave Airlie 	DRM_FORMAT_Y216,
12946d12f91SDave Airlie 	DRM_FORMAT_XYUV8888,
13046d12f91SDave Airlie 	DRM_FORMAT_XVYU2101010,
13146d12f91SDave Airlie };
13246d12f91SDave Airlie 
13346d12f91SDave Airlie static const u32 icl_hdr_plane_formats[] = {
13446d12f91SDave Airlie 	DRM_FORMAT_C8,
13546d12f91SDave Airlie 	DRM_FORMAT_RGB565,
13646d12f91SDave Airlie 	DRM_FORMAT_XRGB8888,
13746d12f91SDave Airlie 	DRM_FORMAT_XBGR8888,
13846d12f91SDave Airlie 	DRM_FORMAT_ARGB8888,
13946d12f91SDave Airlie 	DRM_FORMAT_ABGR8888,
14046d12f91SDave Airlie 	DRM_FORMAT_XRGB2101010,
14146d12f91SDave Airlie 	DRM_FORMAT_XBGR2101010,
14246d12f91SDave Airlie 	DRM_FORMAT_ARGB2101010,
14346d12f91SDave Airlie 	DRM_FORMAT_ABGR2101010,
14446d12f91SDave Airlie 	DRM_FORMAT_XRGB16161616F,
14546d12f91SDave Airlie 	DRM_FORMAT_XBGR16161616F,
14646d12f91SDave Airlie 	DRM_FORMAT_ARGB16161616F,
14746d12f91SDave Airlie 	DRM_FORMAT_ABGR16161616F,
14846d12f91SDave Airlie 	DRM_FORMAT_YUYV,
14946d12f91SDave Airlie 	DRM_FORMAT_YVYU,
15046d12f91SDave Airlie 	DRM_FORMAT_UYVY,
15146d12f91SDave Airlie 	DRM_FORMAT_VYUY,
15246d12f91SDave Airlie 	DRM_FORMAT_NV12,
15346d12f91SDave Airlie 	DRM_FORMAT_P010,
15446d12f91SDave Airlie 	DRM_FORMAT_P012,
15546d12f91SDave Airlie 	DRM_FORMAT_P016,
15646d12f91SDave Airlie 	DRM_FORMAT_Y210,
15746d12f91SDave Airlie 	DRM_FORMAT_Y212,
15846d12f91SDave Airlie 	DRM_FORMAT_Y216,
15946d12f91SDave Airlie 	DRM_FORMAT_XYUV8888,
16046d12f91SDave Airlie 	DRM_FORMAT_XVYU2101010,
16146d12f91SDave Airlie 	DRM_FORMAT_XVYU12_16161616,
16246d12f91SDave Airlie 	DRM_FORMAT_XVYU16161616,
16346d12f91SDave Airlie };
16446d12f91SDave Airlie 
skl_format_to_fourcc(int format,bool rgb_order,bool alpha)16546d12f91SDave Airlie int skl_format_to_fourcc(int format, bool rgb_order, bool alpha)
16646d12f91SDave Airlie {
16746d12f91SDave Airlie 	switch (format) {
16846d12f91SDave Airlie 	case PLANE_CTL_FORMAT_RGB_565:
16946d12f91SDave Airlie 		return DRM_FORMAT_RGB565;
17046d12f91SDave Airlie 	case PLANE_CTL_FORMAT_NV12:
17146d12f91SDave Airlie 		return DRM_FORMAT_NV12;
17246d12f91SDave Airlie 	case PLANE_CTL_FORMAT_XYUV:
17346d12f91SDave Airlie 		return DRM_FORMAT_XYUV8888;
17446d12f91SDave Airlie 	case PLANE_CTL_FORMAT_P010:
17546d12f91SDave Airlie 		return DRM_FORMAT_P010;
17646d12f91SDave Airlie 	case PLANE_CTL_FORMAT_P012:
17746d12f91SDave Airlie 		return DRM_FORMAT_P012;
17846d12f91SDave Airlie 	case PLANE_CTL_FORMAT_P016:
17946d12f91SDave Airlie 		return DRM_FORMAT_P016;
18046d12f91SDave Airlie 	case PLANE_CTL_FORMAT_Y210:
18146d12f91SDave Airlie 		return DRM_FORMAT_Y210;
18246d12f91SDave Airlie 	case PLANE_CTL_FORMAT_Y212:
18346d12f91SDave Airlie 		return DRM_FORMAT_Y212;
18446d12f91SDave Airlie 	case PLANE_CTL_FORMAT_Y216:
18546d12f91SDave Airlie 		return DRM_FORMAT_Y216;
18646d12f91SDave Airlie 	case PLANE_CTL_FORMAT_Y410:
18746d12f91SDave Airlie 		return DRM_FORMAT_XVYU2101010;
18846d12f91SDave Airlie 	case PLANE_CTL_FORMAT_Y412:
18946d12f91SDave Airlie 		return DRM_FORMAT_XVYU12_16161616;
19046d12f91SDave Airlie 	case PLANE_CTL_FORMAT_Y416:
19146d12f91SDave Airlie 		return DRM_FORMAT_XVYU16161616;
19246d12f91SDave Airlie 	default:
19346d12f91SDave Airlie 	case PLANE_CTL_FORMAT_XRGB_8888:
19446d12f91SDave Airlie 		if (rgb_order) {
19546d12f91SDave Airlie 			if (alpha)
19646d12f91SDave Airlie 				return DRM_FORMAT_ABGR8888;
19746d12f91SDave Airlie 			else
19846d12f91SDave Airlie 				return DRM_FORMAT_XBGR8888;
19946d12f91SDave Airlie 		} else {
20046d12f91SDave Airlie 			if (alpha)
20146d12f91SDave Airlie 				return DRM_FORMAT_ARGB8888;
20246d12f91SDave Airlie 			else
20346d12f91SDave Airlie 				return DRM_FORMAT_XRGB8888;
20446d12f91SDave Airlie 		}
20546d12f91SDave Airlie 	case PLANE_CTL_FORMAT_XRGB_2101010:
20646d12f91SDave Airlie 		if (rgb_order) {
20746d12f91SDave Airlie 			if (alpha)
20846d12f91SDave Airlie 				return DRM_FORMAT_ABGR2101010;
20946d12f91SDave Airlie 			else
21046d12f91SDave Airlie 				return DRM_FORMAT_XBGR2101010;
21146d12f91SDave Airlie 		} else {
21246d12f91SDave Airlie 			if (alpha)
21346d12f91SDave Airlie 				return DRM_FORMAT_ARGB2101010;
21446d12f91SDave Airlie 			else
21546d12f91SDave Airlie 				return DRM_FORMAT_XRGB2101010;
21646d12f91SDave Airlie 		}
21746d12f91SDave Airlie 	case PLANE_CTL_FORMAT_XRGB_16161616F:
21846d12f91SDave Airlie 		if (rgb_order) {
21946d12f91SDave Airlie 			if (alpha)
22046d12f91SDave Airlie 				return DRM_FORMAT_ABGR16161616F;
22146d12f91SDave Airlie 			else
22246d12f91SDave Airlie 				return DRM_FORMAT_XBGR16161616F;
22346d12f91SDave Airlie 		} else {
22446d12f91SDave Airlie 			if (alpha)
22546d12f91SDave Airlie 				return DRM_FORMAT_ARGB16161616F;
22646d12f91SDave Airlie 			else
22746d12f91SDave Airlie 				return DRM_FORMAT_XRGB16161616F;
22846d12f91SDave Airlie 		}
22946d12f91SDave Airlie 	}
23046d12f91SDave Airlie }
23146d12f91SDave Airlie 
icl_nv12_y_plane_mask(struct drm_i915_private * i915)23246d12f91SDave Airlie static u8 icl_nv12_y_plane_mask(struct drm_i915_private *i915)
23346d12f91SDave Airlie {
2341649a4ccSMatt Roper 	if (DISPLAY_VER(i915) >= 13 || HAS_D12_PLANE_MINIMIZATION(i915))
23546d12f91SDave Airlie 		return BIT(PLANE_SPRITE2) | BIT(PLANE_SPRITE3);
23646d12f91SDave Airlie 	else
23746d12f91SDave Airlie 		return BIT(PLANE_SPRITE4) | BIT(PLANE_SPRITE5);
23846d12f91SDave Airlie }
23946d12f91SDave Airlie 
icl_is_nv12_y_plane(struct drm_i915_private * dev_priv,enum plane_id plane_id)24046d12f91SDave Airlie bool icl_is_nv12_y_plane(struct drm_i915_private *dev_priv,
24146d12f91SDave Airlie 			 enum plane_id plane_id)
24246d12f91SDave Airlie {
243005e9537SMatt Roper 	return DISPLAY_VER(dev_priv) >= 11 &&
24446d12f91SDave Airlie 		icl_nv12_y_plane_mask(dev_priv) & BIT(plane_id);
24546d12f91SDave Airlie }
24646d12f91SDave Airlie 
icl_hdr_plane_mask(void)247d29c410fSJani Nikula u8 icl_hdr_plane_mask(void)
248d29c410fSJani Nikula {
249d29c410fSJani Nikula 	return BIT(PLANE_PRIMARY) | BIT(PLANE_SPRITE0) | BIT(PLANE_SPRITE1);
250d29c410fSJani Nikula }
251d29c410fSJani Nikula 
icl_is_hdr_plane(struct drm_i915_private * dev_priv,enum plane_id plane_id)25246d12f91SDave Airlie bool icl_is_hdr_plane(struct drm_i915_private *dev_priv, enum plane_id plane_id)
25346d12f91SDave Airlie {
254005e9537SMatt Roper 	return DISPLAY_VER(dev_priv) >= 11 &&
25546d12f91SDave Airlie 		icl_hdr_plane_mask() & BIT(plane_id);
25646d12f91SDave Airlie }
25746d12f91SDave Airlie 
icl_plane_min_cdclk(const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)2586195f850SVille Syrjälä static int icl_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
2596195f850SVille Syrjälä 			       const struct intel_plane_state *plane_state)
2606195f850SVille Syrjälä {
2616195f850SVille Syrjälä 	unsigned int pixel_rate = intel_plane_pixel_rate(crtc_state, plane_state);
2626195f850SVille Syrjälä 
2636195f850SVille Syrjälä 	/* two pixels per clock */
2646195f850SVille Syrjälä 	return DIV_ROUND_UP(pixel_rate, 2);
2656195f850SVille Syrjälä }
2666195f850SVille Syrjälä 
26746d12f91SDave Airlie static void
glk_plane_ratio(const struct intel_plane_state * plane_state,unsigned int * num,unsigned int * den)268efc52308SVille Syrjälä glk_plane_ratio(const struct intel_plane_state *plane_state,
26946d12f91SDave Airlie 		unsigned int *num, unsigned int *den)
27046d12f91SDave Airlie {
27146d12f91SDave Airlie 	const struct drm_framebuffer *fb = plane_state->hw.fb;
27246d12f91SDave Airlie 
27346d12f91SDave Airlie 	if (fb->format->cpp[0] == 8) {
27446d12f91SDave Airlie 		*num = 10;
27546d12f91SDave Airlie 		*den = 8;
27646d12f91SDave Airlie 	} else {
277efc52308SVille Syrjälä 		*num = 1;
278efc52308SVille Syrjälä 		*den = 1;
279efc52308SVille Syrjälä 	}
280efc52308SVille Syrjälä }
281efc52308SVille Syrjälä 
glk_plane_min_cdclk(const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)282efc52308SVille Syrjälä static int glk_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
283efc52308SVille Syrjälä 			       const struct intel_plane_state *plane_state)
284efc52308SVille Syrjälä {
285efc52308SVille Syrjälä 	unsigned int pixel_rate = intel_plane_pixel_rate(crtc_state, plane_state);
286efc52308SVille Syrjälä 	unsigned int num, den;
287efc52308SVille Syrjälä 
288efc52308SVille Syrjälä 	glk_plane_ratio(plane_state, &num, &den);
289efc52308SVille Syrjälä 
290efc52308SVille Syrjälä 	/* two pixels per clock */
291efc52308SVille Syrjälä 	return DIV_ROUND_UP(pixel_rate * num, 2 * den);
292efc52308SVille Syrjälä }
293efc52308SVille Syrjälä 
294efc52308SVille Syrjälä static void
skl_plane_ratio(const struct intel_plane_state * plane_state,unsigned int * num,unsigned int * den)295efc52308SVille Syrjälä skl_plane_ratio(const struct intel_plane_state *plane_state,
296efc52308SVille Syrjälä 		unsigned int *num, unsigned int *den)
297efc52308SVille Syrjälä {
298efc52308SVille Syrjälä 	const struct drm_framebuffer *fb = plane_state->hw.fb;
299efc52308SVille Syrjälä 
300efc52308SVille Syrjälä 	if (fb->format->cpp[0] == 8) {
30146d12f91SDave Airlie 		*num = 9;
30246d12f91SDave Airlie 		*den = 8;
30346d12f91SDave Airlie 	} else {
30446d12f91SDave Airlie 		*num = 1;
30546d12f91SDave Airlie 		*den = 1;
30646d12f91SDave Airlie 	}
30746d12f91SDave Airlie }
30846d12f91SDave Airlie 
skl_plane_min_cdclk(const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)30946d12f91SDave Airlie static int skl_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
31046d12f91SDave Airlie 			       const struct intel_plane_state *plane_state)
31146d12f91SDave Airlie {
31246d12f91SDave Airlie 	unsigned int pixel_rate = intel_plane_pixel_rate(crtc_state, plane_state);
313efc52308SVille Syrjälä 	unsigned int num, den;
31446d12f91SDave Airlie 
315efc52308SVille Syrjälä 	skl_plane_ratio(plane_state, &num, &den);
31646d12f91SDave Airlie 
31746d12f91SDave Airlie 	return DIV_ROUND_UP(pixel_rate * num, den);
31846d12f91SDave Airlie }
31946d12f91SDave Airlie 
skl_plane_max_width(const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)32046d12f91SDave Airlie static int skl_plane_max_width(const struct drm_framebuffer *fb,
32146d12f91SDave Airlie 			       int color_plane,
32246d12f91SDave Airlie 			       unsigned int rotation)
32346d12f91SDave Airlie {
32446d12f91SDave Airlie 	int cpp = fb->format->cpp[color_plane];
32546d12f91SDave Airlie 
32646d12f91SDave Airlie 	switch (fb->modifier) {
32746d12f91SDave Airlie 	case DRM_FORMAT_MOD_LINEAR:
32846d12f91SDave Airlie 	case I915_FORMAT_MOD_X_TILED:
32946d12f91SDave Airlie 		/*
33046d12f91SDave Airlie 		 * Validated limit is 4k, but has 5k should
33146d12f91SDave Airlie 		 * work apart from the following features:
33246d12f91SDave Airlie 		 * - Ytile (already limited to 4k)
33346d12f91SDave Airlie 		 * - FP16 (already limited to 4k)
33446d12f91SDave Airlie 		 * - render compression (already limited to 4k)
33546d12f91SDave Airlie 		 * - KVMR sprite and cursor (don't care)
33646d12f91SDave Airlie 		 * - horizontal panning (TODO verify this)
33746d12f91SDave Airlie 		 * - pipe and plane scaling (TODO verify this)
33846d12f91SDave Airlie 		 */
33946d12f91SDave Airlie 		if (cpp == 8)
34046d12f91SDave Airlie 			return 4096;
34146d12f91SDave Airlie 		else
34246d12f91SDave Airlie 			return 5120;
34346d12f91SDave Airlie 	case I915_FORMAT_MOD_Y_TILED_CCS:
34446d12f91SDave Airlie 	case I915_FORMAT_MOD_Yf_TILED_CCS:
34546d12f91SDave Airlie 	case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
34646d12f91SDave Airlie 		/* FIXME AUX plane? */
34746d12f91SDave Airlie 	case I915_FORMAT_MOD_Y_TILED:
34846d12f91SDave Airlie 	case I915_FORMAT_MOD_Yf_TILED:
34946d12f91SDave Airlie 		if (cpp == 8)
35046d12f91SDave Airlie 			return 2048;
35146d12f91SDave Airlie 		else
35246d12f91SDave Airlie 			return 4096;
35346d12f91SDave Airlie 	default:
35446d12f91SDave Airlie 		MISSING_CASE(fb->modifier);
35546d12f91SDave Airlie 		return 2048;
35646d12f91SDave Airlie 	}
35746d12f91SDave Airlie }
35846d12f91SDave Airlie 
glk_plane_max_width(const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)35946d12f91SDave Airlie static int glk_plane_max_width(const struct drm_framebuffer *fb,
36046d12f91SDave Airlie 			       int color_plane,
36146d12f91SDave Airlie 			       unsigned int rotation)
36246d12f91SDave Airlie {
36346d12f91SDave Airlie 	int cpp = fb->format->cpp[color_plane];
36446d12f91SDave Airlie 
36546d12f91SDave Airlie 	switch (fb->modifier) {
36646d12f91SDave Airlie 	case DRM_FORMAT_MOD_LINEAR:
36746d12f91SDave Airlie 	case I915_FORMAT_MOD_X_TILED:
36846d12f91SDave Airlie 		if (cpp == 8)
36946d12f91SDave Airlie 			return 4096;
37046d12f91SDave Airlie 		else
37146d12f91SDave Airlie 			return 5120;
37246d12f91SDave Airlie 	case I915_FORMAT_MOD_Y_TILED_CCS:
37346d12f91SDave Airlie 	case I915_FORMAT_MOD_Yf_TILED_CCS:
37446d12f91SDave Airlie 		/* FIXME AUX plane? */
37546d12f91SDave Airlie 	case I915_FORMAT_MOD_Y_TILED:
37646d12f91SDave Airlie 	case I915_FORMAT_MOD_Yf_TILED:
37746d12f91SDave Airlie 		if (cpp == 8)
37846d12f91SDave Airlie 			return 2048;
37946d12f91SDave Airlie 		else
38046d12f91SDave Airlie 			return 5120;
38146d12f91SDave Airlie 	default:
38246d12f91SDave Airlie 		MISSING_CASE(fb->modifier);
38346d12f91SDave Airlie 		return 2048;
38446d12f91SDave Airlie 	}
38546d12f91SDave Airlie }
38646d12f91SDave Airlie 
icl_plane_min_width(const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)38746d12f91SDave Airlie static int icl_plane_min_width(const struct drm_framebuffer *fb,
38846d12f91SDave Airlie 			       int color_plane,
38946d12f91SDave Airlie 			       unsigned int rotation)
39046d12f91SDave Airlie {
39146d12f91SDave Airlie 	/* Wa_14011264657, Wa_14011050563: gen11+ */
39246d12f91SDave Airlie 	switch (fb->format->format) {
39346d12f91SDave Airlie 	case DRM_FORMAT_C8:
39446d12f91SDave Airlie 		return 18;
39546d12f91SDave Airlie 	case DRM_FORMAT_RGB565:
39646d12f91SDave Airlie 		return 10;
39746d12f91SDave Airlie 	case DRM_FORMAT_XRGB8888:
39846d12f91SDave Airlie 	case DRM_FORMAT_XBGR8888:
39946d12f91SDave Airlie 	case DRM_FORMAT_ARGB8888:
40046d12f91SDave Airlie 	case DRM_FORMAT_ABGR8888:
40146d12f91SDave Airlie 	case DRM_FORMAT_XRGB2101010:
40246d12f91SDave Airlie 	case DRM_FORMAT_XBGR2101010:
40346d12f91SDave Airlie 	case DRM_FORMAT_ARGB2101010:
40446d12f91SDave Airlie 	case DRM_FORMAT_ABGR2101010:
40546d12f91SDave Airlie 	case DRM_FORMAT_XVYU2101010:
40646d12f91SDave Airlie 	case DRM_FORMAT_Y212:
40746d12f91SDave Airlie 	case DRM_FORMAT_Y216:
40846d12f91SDave Airlie 		return 6;
40946d12f91SDave Airlie 	case DRM_FORMAT_NV12:
41046d12f91SDave Airlie 		return 20;
41146d12f91SDave Airlie 	case DRM_FORMAT_P010:
41246d12f91SDave Airlie 	case DRM_FORMAT_P012:
41346d12f91SDave Airlie 	case DRM_FORMAT_P016:
41446d12f91SDave Airlie 		return 12;
41546d12f91SDave Airlie 	case DRM_FORMAT_XRGB16161616F:
41646d12f91SDave Airlie 	case DRM_FORMAT_XBGR16161616F:
41746d12f91SDave Airlie 	case DRM_FORMAT_ARGB16161616F:
41846d12f91SDave Airlie 	case DRM_FORMAT_ABGR16161616F:
41946d12f91SDave Airlie 	case DRM_FORMAT_XVYU12_16161616:
42046d12f91SDave Airlie 	case DRM_FORMAT_XVYU16161616:
42146d12f91SDave Airlie 		return 4;
42246d12f91SDave Airlie 	default:
42346d12f91SDave Airlie 		return 1;
42446d12f91SDave Airlie 	}
42546d12f91SDave Airlie }
42646d12f91SDave Airlie 
icl_hdr_plane_max_width(const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)4270e959b4eSVidya Srinivas static int icl_hdr_plane_max_width(const struct drm_framebuffer *fb,
4280e959b4eSVidya Srinivas 				   int color_plane,
4290e959b4eSVidya Srinivas 				   unsigned int rotation)
4300e959b4eSVidya Srinivas {
4310e959b4eSVidya Srinivas 	if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
4320e959b4eSVidya Srinivas 		return 4096;
4330e959b4eSVidya Srinivas 	else
4340e959b4eSVidya Srinivas 		return 5120;
4350e959b4eSVidya Srinivas }
4360e959b4eSVidya Srinivas 
icl_sdr_plane_max_width(const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)4370e959b4eSVidya Srinivas static int icl_sdr_plane_max_width(const struct drm_framebuffer *fb,
43846d12f91SDave Airlie 				   int color_plane,
43946d12f91SDave Airlie 				   unsigned int rotation)
44046d12f91SDave Airlie {
44146d12f91SDave Airlie 	return 5120;
44246d12f91SDave Airlie }
44346d12f91SDave Airlie 
skl_plane_max_height(const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)44446d12f91SDave Airlie static int skl_plane_max_height(const struct drm_framebuffer *fb,
44546d12f91SDave Airlie 				int color_plane,
44646d12f91SDave Airlie 				unsigned int rotation)
44746d12f91SDave Airlie {
44846d12f91SDave Airlie 	return 4096;
44946d12f91SDave Airlie }
45046d12f91SDave Airlie 
icl_plane_max_height(const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)45146d12f91SDave Airlie static int icl_plane_max_height(const struct drm_framebuffer *fb,
45246d12f91SDave Airlie 				int color_plane,
45346d12f91SDave Airlie 				unsigned int rotation)
45446d12f91SDave Airlie {
45546d12f91SDave Airlie 	return 4320;
45646d12f91SDave Airlie }
45746d12f91SDave Airlie 
45846d12f91SDave Airlie static unsigned int
skl_plane_max_stride(struct intel_plane * plane,u32 pixel_format,u64 modifier,unsigned int rotation)45946d12f91SDave Airlie skl_plane_max_stride(struct intel_plane *plane,
46046d12f91SDave Airlie 		     u32 pixel_format, u64 modifier,
46146d12f91SDave Airlie 		     unsigned int rotation)
46246d12f91SDave Airlie {
463e7367af1SJuha-Pekka Heikkilä 	struct drm_i915_private *i915 = to_i915(plane->base.dev);
46446d12f91SDave Airlie 	const struct drm_format_info *info = drm_format_info(pixel_format);
46546d12f91SDave Airlie 	int cpp = info->cpp[0];
466e7367af1SJuha-Pekka Heikkilä 	int max_horizontal_pixels = 8192;
467e7367af1SJuha-Pekka Heikkilä 	int max_stride_bytes;
46846d12f91SDave Airlie 
469e7367af1SJuha-Pekka Heikkilä 	if (DISPLAY_VER(i915) >= 13) {
470e7367af1SJuha-Pekka Heikkilä 		/*
471e7367af1SJuha-Pekka Heikkilä 		 * The stride in bytes must not exceed of the size
472e7367af1SJuha-Pekka Heikkilä 		 * of 128K bytes. For pixel formats of 64bpp will allow
473e7367af1SJuha-Pekka Heikkilä 		 * for a 16K pixel surface.
474e7367af1SJuha-Pekka Heikkilä 		 */
475e7367af1SJuha-Pekka Heikkilä 		max_stride_bytes = 131072;
476e7367af1SJuha-Pekka Heikkilä 		if (cpp == 8)
477e7367af1SJuha-Pekka Heikkilä 			max_horizontal_pixels = 16384;
478e7367af1SJuha-Pekka Heikkilä 		else
479e7367af1SJuha-Pekka Heikkilä 			max_horizontal_pixels = 65536;
480e7367af1SJuha-Pekka Heikkilä 	} else {
48146d12f91SDave Airlie 		/*
48246d12f91SDave Airlie 		 * "The stride in bytes must not exceed the
48346d12f91SDave Airlie 		 * of the size of 8K pixels and 32K bytes."
48446d12f91SDave Airlie 		 */
485e7367af1SJuha-Pekka Heikkilä 		max_stride_bytes = 32768;
486e7367af1SJuha-Pekka Heikkilä 	}
487e7367af1SJuha-Pekka Heikkilä 
48846d12f91SDave Airlie 	if (drm_rotation_90_or_270(rotation))
489e7367af1SJuha-Pekka Heikkilä 		return min(max_horizontal_pixels, max_stride_bytes / cpp);
49046d12f91SDave Airlie 	else
491e7367af1SJuha-Pekka Heikkilä 		return min(max_horizontal_pixels * cpp, max_stride_bytes);
49246d12f91SDave Airlie }
49346d12f91SDave Airlie 
49446d12f91SDave Airlie 
49546d12f91SDave Airlie /* Preoffset values for YUV to RGB Conversion */
49646d12f91SDave Airlie #define PREOFF_YUV_TO_RGB_HI		0x1800
49746d12f91SDave Airlie #define PREOFF_YUV_TO_RGB_ME		0x0000
49846d12f91SDave Airlie #define PREOFF_YUV_TO_RGB_LO		0x1800
49946d12f91SDave Airlie 
50046d12f91SDave Airlie #define  ROFF(x)          (((x) & 0xffff) << 16)
50146d12f91SDave Airlie #define  GOFF(x)          (((x) & 0xffff) << 0)
50246d12f91SDave Airlie #define  BOFF(x)          (((x) & 0xffff) << 16)
50346d12f91SDave Airlie 
50446d12f91SDave Airlie /*
50546d12f91SDave Airlie  * Programs the input color space conversion stage for ICL HDR planes.
50646d12f91SDave Airlie  * Note that it is assumed that this stage always happens after YUV
50746d12f91SDave Airlie  * range correction. Thus, the input to this stage is assumed to be
50846d12f91SDave Airlie  * in full-range YCbCr.
50946d12f91SDave Airlie  */
51046d12f91SDave Airlie static void
icl_program_input_csc(struct intel_plane * plane,const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)51146d12f91SDave Airlie icl_program_input_csc(struct intel_plane *plane,
51246d12f91SDave Airlie 		      const struct intel_crtc_state *crtc_state,
51346d12f91SDave Airlie 		      const struct intel_plane_state *plane_state)
51446d12f91SDave Airlie {
51546d12f91SDave Airlie 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
51646d12f91SDave Airlie 	enum pipe pipe = plane->pipe;
51746d12f91SDave Airlie 	enum plane_id plane_id = plane->id;
51846d12f91SDave Airlie 
51946d12f91SDave Airlie 	static const u16 input_csc_matrix[][9] = {
52046d12f91SDave Airlie 		/*
52146d12f91SDave Airlie 		 * BT.601 full range YCbCr -> full range RGB
52246d12f91SDave Airlie 		 * The matrix required is :
52346d12f91SDave Airlie 		 * [1.000, 0.000, 1.371,
52446d12f91SDave Airlie 		 *  1.000, -0.336, -0.698,
52546d12f91SDave Airlie 		 *  1.000, 1.732, 0.0000]
52646d12f91SDave Airlie 		 */
52746d12f91SDave Airlie 		[DRM_COLOR_YCBCR_BT601] = {
52846d12f91SDave Airlie 			0x7AF8, 0x7800, 0x0,
52946d12f91SDave Airlie 			0x8B28, 0x7800, 0x9AC0,
53046d12f91SDave Airlie 			0x0, 0x7800, 0x7DD8,
53146d12f91SDave Airlie 		},
53246d12f91SDave Airlie 		/*
53346d12f91SDave Airlie 		 * BT.709 full range YCbCr -> full range RGB
53446d12f91SDave Airlie 		 * The matrix required is :
53546d12f91SDave Airlie 		 * [1.000, 0.000, 1.574,
53646d12f91SDave Airlie 		 *  1.000, -0.187, -0.468,
53746d12f91SDave Airlie 		 *  1.000, 1.855, 0.0000]
53846d12f91SDave Airlie 		 */
53946d12f91SDave Airlie 		[DRM_COLOR_YCBCR_BT709] = {
54046d12f91SDave Airlie 			0x7C98, 0x7800, 0x0,
54146d12f91SDave Airlie 			0x9EF8, 0x7800, 0xAC00,
54246d12f91SDave Airlie 			0x0, 0x7800,  0x7ED8,
54346d12f91SDave Airlie 		},
54446d12f91SDave Airlie 		/*
54546d12f91SDave Airlie 		 * BT.2020 full range YCbCr -> full range RGB
54646d12f91SDave Airlie 		 * The matrix required is :
54746d12f91SDave Airlie 		 * [1.000, 0.000, 1.474,
54846d12f91SDave Airlie 		 *  1.000, -0.1645, -0.5713,
54946d12f91SDave Airlie 		 *  1.000, 1.8814, 0.0000]
55046d12f91SDave Airlie 		 */
55146d12f91SDave Airlie 		[DRM_COLOR_YCBCR_BT2020] = {
55246d12f91SDave Airlie 			0x7BC8, 0x7800, 0x0,
55346d12f91SDave Airlie 			0x8928, 0x7800, 0xAA88,
55446d12f91SDave Airlie 			0x0, 0x7800, 0x7F10,
55546d12f91SDave Airlie 		},
55646d12f91SDave Airlie 	};
55746d12f91SDave Airlie 	const u16 *csc = input_csc_matrix[plane_state->hw.color_encoding];
55846d12f91SDave Airlie 
55946d12f91SDave Airlie 	intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 0),
56046d12f91SDave Airlie 			  ROFF(csc[0]) | GOFF(csc[1]));
56146d12f91SDave Airlie 	intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 1),
56246d12f91SDave Airlie 			  BOFF(csc[2]));
56346d12f91SDave Airlie 	intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 2),
56446d12f91SDave Airlie 			  ROFF(csc[3]) | GOFF(csc[4]));
56546d12f91SDave Airlie 	intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 3),
56646d12f91SDave Airlie 			  BOFF(csc[5]));
56746d12f91SDave Airlie 	intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 4),
56846d12f91SDave Airlie 			  ROFF(csc[6]) | GOFF(csc[7]));
56946d12f91SDave Airlie 	intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 5),
57046d12f91SDave Airlie 			  BOFF(csc[8]));
57146d12f91SDave Airlie 
57246d12f91SDave Airlie 	intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 0),
57346d12f91SDave Airlie 			  PREOFF_YUV_TO_RGB_HI);
57446d12f91SDave Airlie 	intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1),
57546d12f91SDave Airlie 			  PREOFF_YUV_TO_RGB_ME);
57646d12f91SDave Airlie 	intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 2),
57746d12f91SDave Airlie 			  PREOFF_YUV_TO_RGB_LO);
57846d12f91SDave Airlie 	intel_de_write_fw(dev_priv,
57946d12f91SDave Airlie 			  PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 0), 0x0);
58046d12f91SDave Airlie 	intel_de_write_fw(dev_priv,
58146d12f91SDave Airlie 			  PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 1), 0x0);
58246d12f91SDave Airlie 	intel_de_write_fw(dev_priv,
58346d12f91SDave Airlie 			  PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 2), 0x0);
58446d12f91SDave Airlie }
58546d12f91SDave Airlie 
skl_plane_stride_mult(const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)58646d12f91SDave Airlie static unsigned int skl_plane_stride_mult(const struct drm_framebuffer *fb,
58746d12f91SDave Airlie 					  int color_plane, unsigned int rotation)
58846d12f91SDave Airlie {
58946d12f91SDave Airlie 	/*
59046d12f91SDave Airlie 	 * The stride is either expressed as a multiple of 64 bytes chunks for
59146d12f91SDave Airlie 	 * linear buffers or in number of tiles for tiled buffers.
59246d12f91SDave Airlie 	 */
59346d12f91SDave Airlie 	if (is_surface_linear(fb, color_plane))
59446d12f91SDave Airlie 		return 64;
59546d12f91SDave Airlie 	else if (drm_rotation_90_or_270(rotation))
59646d12f91SDave Airlie 		return intel_tile_height(fb, color_plane);
59746d12f91SDave Airlie 	else
59846d12f91SDave Airlie 		return intel_tile_width_bytes(fb, color_plane);
59946d12f91SDave Airlie }
60046d12f91SDave Airlie 
skl_plane_stride(const struct intel_plane_state * plane_state,int color_plane)60146d12f91SDave Airlie static u32 skl_plane_stride(const struct intel_plane_state *plane_state,
60246d12f91SDave Airlie 			    int color_plane)
60346d12f91SDave Airlie {
60446d12f91SDave Airlie 	const struct drm_framebuffer *fb = plane_state->hw.fb;
60546d12f91SDave Airlie 	unsigned int rotation = plane_state->hw.rotation;
606e6d6f689SImre Deak 	u32 stride = plane_state->view.color_plane[color_plane].scanout_stride;
60746d12f91SDave Airlie 
60846d12f91SDave Airlie 	if (color_plane >= fb->format->num_planes)
60946d12f91SDave Airlie 		return 0;
61046d12f91SDave Airlie 
61146d12f91SDave Airlie 	return stride / skl_plane_stride_mult(fb, color_plane, rotation);
61246d12f91SDave Airlie }
61346d12f91SDave Airlie 
61446d12f91SDave Airlie static void
skl_plane_disable_arm(struct intel_plane * plane,const struct intel_crtc_state * crtc_state)6158ac80733SVille Syrjälä skl_plane_disable_arm(struct intel_plane *plane,
61646d12f91SDave Airlie 		      const struct intel_crtc_state *crtc_state)
61746d12f91SDave Airlie {
61846d12f91SDave Airlie 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
61946d12f91SDave Airlie 	enum plane_id plane_id = plane->id;
62046d12f91SDave Airlie 	enum pipe pipe = plane->pipe;
62146d12f91SDave Airlie 
622f8a005ebSVille Syrjälä 	skl_write_plane_wm(plane, crtc_state);
623f8a005ebSVille Syrjälä 
624f8a005ebSVille Syrjälä 	intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0);
625f8a005ebSVille Syrjälä 	intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0);
626f8a005ebSVille Syrjälä }
627f8a005ebSVille Syrjälä 
628f8a005ebSVille Syrjälä static void
icl_plane_disable_arm(struct intel_plane * plane,const struct intel_crtc_state * crtc_state)629f8a005ebSVille Syrjälä icl_plane_disable_arm(struct intel_plane *plane,
630f8a005ebSVille Syrjälä 		      const struct intel_crtc_state *crtc_state)
631f8a005ebSVille Syrjälä {
632f8a005ebSVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
633f8a005ebSVille Syrjälä 	enum plane_id plane_id = plane->id;
634f8a005ebSVille Syrjälä 	enum pipe pipe = plane->pipe;
635f8a005ebSVille Syrjälä 
63646d12f91SDave Airlie 	if (icl_is_hdr_plane(dev_priv, plane_id))
63746d12f91SDave Airlie 		intel_de_write_fw(dev_priv, PLANE_CUS_CTL(pipe, plane_id), 0);
63846d12f91SDave Airlie 
63946d12f91SDave Airlie 	skl_write_plane_wm(plane, crtc_state);
64046d12f91SDave Airlie 
641c22cf04cSJouni Högander 	intel_psr2_disable_plane_sel_fetch_arm(plane, crtc_state);
64246d12f91SDave Airlie 	intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0);
64346d12f91SDave Airlie 	intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0);
64446d12f91SDave Airlie }
64546d12f91SDave Airlie 
64646d12f91SDave Airlie static bool
skl_plane_get_hw_state(struct intel_plane * plane,enum pipe * pipe)64746d12f91SDave Airlie skl_plane_get_hw_state(struct intel_plane *plane,
64846d12f91SDave Airlie 		       enum pipe *pipe)
64946d12f91SDave Airlie {
65046d12f91SDave Airlie 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
65146d12f91SDave Airlie 	enum intel_display_power_domain power_domain;
65246d12f91SDave Airlie 	enum plane_id plane_id = plane->id;
65346d12f91SDave Airlie 	intel_wakeref_t wakeref;
65446d12f91SDave Airlie 	bool ret;
65546d12f91SDave Airlie 
65646d12f91SDave Airlie 	power_domain = POWER_DOMAIN_PIPE(plane->pipe);
65746d12f91SDave Airlie 	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
65846d12f91SDave Airlie 	if (!wakeref)
65946d12f91SDave Airlie 		return false;
66046d12f91SDave Airlie 
66146d12f91SDave Airlie 	ret = intel_de_read(dev_priv, PLANE_CTL(plane->pipe, plane_id)) & PLANE_CTL_ENABLE;
66246d12f91SDave Airlie 
66346d12f91SDave Airlie 	*pipe = plane->pipe;
66446d12f91SDave Airlie 
66546d12f91SDave Airlie 	intel_display_power_put(dev_priv, power_domain, wakeref);
66646d12f91SDave Airlie 
66746d12f91SDave Airlie 	return ret;
66846d12f91SDave Airlie }
66946d12f91SDave Airlie 
skl_plane_ctl_format(u32 pixel_format)67046d12f91SDave Airlie static u32 skl_plane_ctl_format(u32 pixel_format)
67146d12f91SDave Airlie {
67246d12f91SDave Airlie 	switch (pixel_format) {
67346d12f91SDave Airlie 	case DRM_FORMAT_C8:
67446d12f91SDave Airlie 		return PLANE_CTL_FORMAT_INDEXED;
67546d12f91SDave Airlie 	case DRM_FORMAT_RGB565:
67646d12f91SDave Airlie 		return PLANE_CTL_FORMAT_RGB_565;
67746d12f91SDave Airlie 	case DRM_FORMAT_XBGR8888:
67846d12f91SDave Airlie 	case DRM_FORMAT_ABGR8888:
67946d12f91SDave Airlie 		return PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX;
68046d12f91SDave Airlie 	case DRM_FORMAT_XRGB8888:
68146d12f91SDave Airlie 	case DRM_FORMAT_ARGB8888:
68246d12f91SDave Airlie 		return PLANE_CTL_FORMAT_XRGB_8888;
68346d12f91SDave Airlie 	case DRM_FORMAT_XBGR2101010:
68446d12f91SDave Airlie 	case DRM_FORMAT_ABGR2101010:
68546d12f91SDave Airlie 		return PLANE_CTL_FORMAT_XRGB_2101010 | PLANE_CTL_ORDER_RGBX;
68646d12f91SDave Airlie 	case DRM_FORMAT_XRGB2101010:
68746d12f91SDave Airlie 	case DRM_FORMAT_ARGB2101010:
68846d12f91SDave Airlie 		return PLANE_CTL_FORMAT_XRGB_2101010;
68946d12f91SDave Airlie 	case DRM_FORMAT_XBGR16161616F:
69046d12f91SDave Airlie 	case DRM_FORMAT_ABGR16161616F:
69146d12f91SDave Airlie 		return PLANE_CTL_FORMAT_XRGB_16161616F | PLANE_CTL_ORDER_RGBX;
69246d12f91SDave Airlie 	case DRM_FORMAT_XRGB16161616F:
69346d12f91SDave Airlie 	case DRM_FORMAT_ARGB16161616F:
69446d12f91SDave Airlie 		return PLANE_CTL_FORMAT_XRGB_16161616F;
69546d12f91SDave Airlie 	case DRM_FORMAT_XYUV8888:
69646d12f91SDave Airlie 		return PLANE_CTL_FORMAT_XYUV;
69746d12f91SDave Airlie 	case DRM_FORMAT_YUYV:
69862f887aeSVille Syrjälä 		return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_ORDER_YUYV;
69946d12f91SDave Airlie 	case DRM_FORMAT_YVYU:
70062f887aeSVille Syrjälä 		return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_ORDER_YVYU;
70146d12f91SDave Airlie 	case DRM_FORMAT_UYVY:
70262f887aeSVille Syrjälä 		return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_ORDER_UYVY;
70346d12f91SDave Airlie 	case DRM_FORMAT_VYUY:
70462f887aeSVille Syrjälä 		return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_ORDER_VYUY;
70546d12f91SDave Airlie 	case DRM_FORMAT_NV12:
70646d12f91SDave Airlie 		return PLANE_CTL_FORMAT_NV12;
70746d12f91SDave Airlie 	case DRM_FORMAT_P010:
70846d12f91SDave Airlie 		return PLANE_CTL_FORMAT_P010;
70946d12f91SDave Airlie 	case DRM_FORMAT_P012:
71046d12f91SDave Airlie 		return PLANE_CTL_FORMAT_P012;
71146d12f91SDave Airlie 	case DRM_FORMAT_P016:
71246d12f91SDave Airlie 		return PLANE_CTL_FORMAT_P016;
71346d12f91SDave Airlie 	case DRM_FORMAT_Y210:
71446d12f91SDave Airlie 		return PLANE_CTL_FORMAT_Y210;
71546d12f91SDave Airlie 	case DRM_FORMAT_Y212:
71646d12f91SDave Airlie 		return PLANE_CTL_FORMAT_Y212;
71746d12f91SDave Airlie 	case DRM_FORMAT_Y216:
71846d12f91SDave Airlie 		return PLANE_CTL_FORMAT_Y216;
71946d12f91SDave Airlie 	case DRM_FORMAT_XVYU2101010:
72046d12f91SDave Airlie 		return PLANE_CTL_FORMAT_Y410;
72146d12f91SDave Airlie 	case DRM_FORMAT_XVYU12_16161616:
72246d12f91SDave Airlie 		return PLANE_CTL_FORMAT_Y412;
72346d12f91SDave Airlie 	case DRM_FORMAT_XVYU16161616:
72446d12f91SDave Airlie 		return PLANE_CTL_FORMAT_Y416;
72546d12f91SDave Airlie 	default:
72646d12f91SDave Airlie 		MISSING_CASE(pixel_format);
72746d12f91SDave Airlie 	}
72846d12f91SDave Airlie 
72946d12f91SDave Airlie 	return 0;
73046d12f91SDave Airlie }
73146d12f91SDave Airlie 
skl_plane_ctl_alpha(const struct intel_plane_state * plane_state)73246d12f91SDave Airlie static u32 skl_plane_ctl_alpha(const struct intel_plane_state *plane_state)
73346d12f91SDave Airlie {
73446d12f91SDave Airlie 	if (!plane_state->hw.fb->format->has_alpha)
73546d12f91SDave Airlie 		return PLANE_CTL_ALPHA_DISABLE;
73646d12f91SDave Airlie 
73746d12f91SDave Airlie 	switch (plane_state->hw.pixel_blend_mode) {
73846d12f91SDave Airlie 	case DRM_MODE_BLEND_PIXEL_NONE:
73946d12f91SDave Airlie 		return PLANE_CTL_ALPHA_DISABLE;
74046d12f91SDave Airlie 	case DRM_MODE_BLEND_PREMULTI:
74146d12f91SDave Airlie 		return PLANE_CTL_ALPHA_SW_PREMULTIPLY;
74246d12f91SDave Airlie 	case DRM_MODE_BLEND_COVERAGE:
74346d12f91SDave Airlie 		return PLANE_CTL_ALPHA_HW_PREMULTIPLY;
74446d12f91SDave Airlie 	default:
74546d12f91SDave Airlie 		MISSING_CASE(plane_state->hw.pixel_blend_mode);
74646d12f91SDave Airlie 		return PLANE_CTL_ALPHA_DISABLE;
74746d12f91SDave Airlie 	}
74846d12f91SDave Airlie }
74946d12f91SDave Airlie 
glk_plane_color_ctl_alpha(const struct intel_plane_state * plane_state)75046d12f91SDave Airlie static u32 glk_plane_color_ctl_alpha(const struct intel_plane_state *plane_state)
75146d12f91SDave Airlie {
75246d12f91SDave Airlie 	if (!plane_state->hw.fb->format->has_alpha)
75346d12f91SDave Airlie 		return PLANE_COLOR_ALPHA_DISABLE;
75446d12f91SDave Airlie 
75546d12f91SDave Airlie 	switch (plane_state->hw.pixel_blend_mode) {
75646d12f91SDave Airlie 	case DRM_MODE_BLEND_PIXEL_NONE:
75746d12f91SDave Airlie 		return PLANE_COLOR_ALPHA_DISABLE;
75846d12f91SDave Airlie 	case DRM_MODE_BLEND_PREMULTI:
75946d12f91SDave Airlie 		return PLANE_COLOR_ALPHA_SW_PREMULTIPLY;
76046d12f91SDave Airlie 	case DRM_MODE_BLEND_COVERAGE:
76146d12f91SDave Airlie 		return PLANE_COLOR_ALPHA_HW_PREMULTIPLY;
76246d12f91SDave Airlie 	default:
76346d12f91SDave Airlie 		MISSING_CASE(plane_state->hw.pixel_blend_mode);
76446d12f91SDave Airlie 		return PLANE_COLOR_ALPHA_DISABLE;
76546d12f91SDave Airlie 	}
76646d12f91SDave Airlie }
76746d12f91SDave Airlie 
skl_plane_ctl_tiling(u64 fb_modifier)76846d12f91SDave Airlie static u32 skl_plane_ctl_tiling(u64 fb_modifier)
76946d12f91SDave Airlie {
77046d12f91SDave Airlie 	switch (fb_modifier) {
77146d12f91SDave Airlie 	case DRM_FORMAT_MOD_LINEAR:
77246d12f91SDave Airlie 		break;
77346d12f91SDave Airlie 	case I915_FORMAT_MOD_X_TILED:
77446d12f91SDave Airlie 		return PLANE_CTL_TILED_X;
77546d12f91SDave Airlie 	case I915_FORMAT_MOD_Y_TILED:
77646d12f91SDave Airlie 		return PLANE_CTL_TILED_Y;
777072ce416SStanislav Lisovskiy 	case I915_FORMAT_MOD_4_TILED:
778072ce416SStanislav Lisovskiy 		return PLANE_CTL_TILED_4;
7794c3afa72SMatt Roper 	case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS:
7804c3afa72SMatt Roper 		return PLANE_CTL_TILED_4 |
7814c3afa72SMatt Roper 			PLANE_CTL_RENDER_DECOMPRESSION_ENABLE |
7824c3afa72SMatt Roper 			PLANE_CTL_CLEAR_COLOR_DISABLE;
7834c3afa72SMatt Roper 	case I915_FORMAT_MOD_4_TILED_DG2_MC_CCS:
7844c3afa72SMatt Roper 		return PLANE_CTL_TILED_4 |
7854c3afa72SMatt Roper 			PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE |
7864c3afa72SMatt Roper 			PLANE_CTL_CLEAR_COLOR_DISABLE;
787680025dcSJuha-Pekka Heikkilä 	case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC:
788680025dcSJuha-Pekka Heikkilä 		return PLANE_CTL_TILED_4 | PLANE_CTL_RENDER_DECOMPRESSION_ENABLE;
789f2eb43f0SJuha-Pekka Heikkila 	case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS:
790f2eb43f0SJuha-Pekka Heikkila 		return PLANE_CTL_TILED_4 |
791f2eb43f0SJuha-Pekka Heikkila 			PLANE_CTL_RENDER_DECOMPRESSION_ENABLE |
792f2eb43f0SJuha-Pekka Heikkila 			PLANE_CTL_CLEAR_COLOR_DISABLE;
793f2eb43f0SJuha-Pekka Heikkila 	case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC:
794f2eb43f0SJuha-Pekka Heikkila 		return PLANE_CTL_TILED_4 | PLANE_CTL_RENDER_DECOMPRESSION_ENABLE;
795f2eb43f0SJuha-Pekka Heikkila 	case I915_FORMAT_MOD_4_TILED_MTL_MC_CCS:
796f2eb43f0SJuha-Pekka Heikkila 		return PLANE_CTL_TILED_4 | PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE;
79746d12f91SDave Airlie 	case I915_FORMAT_MOD_Y_TILED_CCS:
79846d12f91SDave Airlie 	case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC:
79946d12f91SDave Airlie 		return PLANE_CTL_TILED_Y | PLANE_CTL_RENDER_DECOMPRESSION_ENABLE;
80046d12f91SDave Airlie 	case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
80146d12f91SDave Airlie 		return PLANE_CTL_TILED_Y |
80246d12f91SDave Airlie 		       PLANE_CTL_RENDER_DECOMPRESSION_ENABLE |
80346d12f91SDave Airlie 		       PLANE_CTL_CLEAR_COLOR_DISABLE;
80446d12f91SDave Airlie 	case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
80546d12f91SDave Airlie 		return PLANE_CTL_TILED_Y | PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE;
80646d12f91SDave Airlie 	case I915_FORMAT_MOD_Yf_TILED:
80746d12f91SDave Airlie 		return PLANE_CTL_TILED_YF;
80846d12f91SDave Airlie 	case I915_FORMAT_MOD_Yf_TILED_CCS:
80946d12f91SDave Airlie 		return PLANE_CTL_TILED_YF | PLANE_CTL_RENDER_DECOMPRESSION_ENABLE;
81046d12f91SDave Airlie 	default:
81146d12f91SDave Airlie 		MISSING_CASE(fb_modifier);
81246d12f91SDave Airlie 	}
81346d12f91SDave Airlie 
81446d12f91SDave Airlie 	return 0;
81546d12f91SDave Airlie }
81646d12f91SDave Airlie 
skl_plane_ctl_rotate(unsigned int rotate)81746d12f91SDave Airlie static u32 skl_plane_ctl_rotate(unsigned int rotate)
81846d12f91SDave Airlie {
81946d12f91SDave Airlie 	switch (rotate) {
82046d12f91SDave Airlie 	case DRM_MODE_ROTATE_0:
82146d12f91SDave Airlie 		break;
82246d12f91SDave Airlie 	/*
82346d12f91SDave Airlie 	 * DRM_MODE_ROTATE_ is counter clockwise to stay compatible with Xrandr
82446d12f91SDave Airlie 	 * while i915 HW rotation is clockwise, thats why this swapping.
82546d12f91SDave Airlie 	 */
82646d12f91SDave Airlie 	case DRM_MODE_ROTATE_90:
82746d12f91SDave Airlie 		return PLANE_CTL_ROTATE_270;
82846d12f91SDave Airlie 	case DRM_MODE_ROTATE_180:
82946d12f91SDave Airlie 		return PLANE_CTL_ROTATE_180;
83046d12f91SDave Airlie 	case DRM_MODE_ROTATE_270:
83146d12f91SDave Airlie 		return PLANE_CTL_ROTATE_90;
83246d12f91SDave Airlie 	default:
83346d12f91SDave Airlie 		MISSING_CASE(rotate);
83446d12f91SDave Airlie 	}
83546d12f91SDave Airlie 
83646d12f91SDave Airlie 	return 0;
83746d12f91SDave Airlie }
83846d12f91SDave Airlie 
icl_plane_ctl_flip(unsigned int reflect)839c988d2dcSLucas De Marchi static u32 icl_plane_ctl_flip(unsigned int reflect)
84046d12f91SDave Airlie {
84146d12f91SDave Airlie 	switch (reflect) {
84246d12f91SDave Airlie 	case 0:
84346d12f91SDave Airlie 		break;
84446d12f91SDave Airlie 	case DRM_MODE_REFLECT_X:
84546d12f91SDave Airlie 		return PLANE_CTL_FLIP_HORIZONTAL;
84646d12f91SDave Airlie 	case DRM_MODE_REFLECT_Y:
84746d12f91SDave Airlie 	default:
84846d12f91SDave Airlie 		MISSING_CASE(reflect);
84946d12f91SDave Airlie 	}
85046d12f91SDave Airlie 
85146d12f91SDave Airlie 	return 0;
85246d12f91SDave Airlie }
85346d12f91SDave Airlie 
adlp_plane_ctl_arb_slots(const struct intel_plane_state * plane_state)8540b86952dSVille Syrjälä static u32 adlp_plane_ctl_arb_slots(const struct intel_plane_state *plane_state)
8550b86952dSVille Syrjälä {
8560b86952dSVille Syrjälä 	const struct drm_framebuffer *fb = plane_state->hw.fb;
8570b86952dSVille Syrjälä 
8580b86952dSVille Syrjälä 	if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier)) {
8590b86952dSVille Syrjälä 		switch (fb->format->cpp[0]) {
8600b86952dSVille Syrjälä 		case 2:
8610b86952dSVille Syrjälä 			return PLANE_CTL_ARB_SLOTS(1);
8620b86952dSVille Syrjälä 		default:
8630b86952dSVille Syrjälä 			return PLANE_CTL_ARB_SLOTS(0);
8640b86952dSVille Syrjälä 		}
8650b86952dSVille Syrjälä 	} else {
8660b86952dSVille Syrjälä 		switch (fb->format->cpp[0]) {
8670b86952dSVille Syrjälä 		case 8:
8680b86952dSVille Syrjälä 			return PLANE_CTL_ARB_SLOTS(3);
8690b86952dSVille Syrjälä 		case 4:
8700b86952dSVille Syrjälä 			return PLANE_CTL_ARB_SLOTS(1);
8710b86952dSVille Syrjälä 		default:
8720b86952dSVille Syrjälä 			return PLANE_CTL_ARB_SLOTS(0);
8730b86952dSVille Syrjälä 		}
8740b86952dSVille Syrjälä 	}
8750b86952dSVille Syrjälä }
8760b86952dSVille Syrjälä 
skl_plane_ctl_crtc(const struct intel_crtc_state * crtc_state)87746d12f91SDave Airlie static u32 skl_plane_ctl_crtc(const struct intel_crtc_state *crtc_state)
87846d12f91SDave Airlie {
87946d12f91SDave Airlie 	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
88046d12f91SDave Airlie 	u32 plane_ctl = 0;
88146d12f91SDave Airlie 
8822b5a4562SMatt Roper 	if (DISPLAY_VER(dev_priv) >= 10)
88346d12f91SDave Airlie 		return plane_ctl;
88446d12f91SDave Airlie 
88546d12f91SDave Airlie 	if (crtc_state->gamma_enable)
88646d12f91SDave Airlie 		plane_ctl |= PLANE_CTL_PIPE_GAMMA_ENABLE;
88746d12f91SDave Airlie 
88846d12f91SDave Airlie 	if (crtc_state->csc_enable)
88946d12f91SDave Airlie 		plane_ctl |= PLANE_CTL_PIPE_CSC_ENABLE;
89046d12f91SDave Airlie 
89146d12f91SDave Airlie 	return plane_ctl;
89246d12f91SDave Airlie }
89346d12f91SDave Airlie 
skl_plane_ctl(const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)89446d12f91SDave Airlie static u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state,
89546d12f91SDave Airlie 			 const struct intel_plane_state *plane_state)
89646d12f91SDave Airlie {
89746d12f91SDave Airlie 	struct drm_i915_private *dev_priv =
89846d12f91SDave Airlie 		to_i915(plane_state->uapi.plane->dev);
89946d12f91SDave Airlie 	const struct drm_framebuffer *fb = plane_state->hw.fb;
90046d12f91SDave Airlie 	unsigned int rotation = plane_state->hw.rotation;
90146d12f91SDave Airlie 	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
90246d12f91SDave Airlie 	u32 plane_ctl;
90346d12f91SDave Airlie 
90446d12f91SDave Airlie 	plane_ctl = PLANE_CTL_ENABLE;
90546d12f91SDave Airlie 
906ad314fecSVille Syrjälä 	if (DISPLAY_VER(dev_priv) < 10) {
90746d12f91SDave Airlie 		plane_ctl |= skl_plane_ctl_alpha(plane_state);
90846d12f91SDave Airlie 		plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
90946d12f91SDave Airlie 
91046d12f91SDave Airlie 		if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709)
91146d12f91SDave Airlie 			plane_ctl |= PLANE_CTL_YUV_TO_RGB_CSC_FORMAT_BT709;
91246d12f91SDave Airlie 
91346d12f91SDave Airlie 		if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
91446d12f91SDave Airlie 			plane_ctl |= PLANE_CTL_YUV_RANGE_CORRECTION_DISABLE;
91546d12f91SDave Airlie 	}
91646d12f91SDave Airlie 
91746d12f91SDave Airlie 	plane_ctl |= skl_plane_ctl_format(fb->format->format);
91846d12f91SDave Airlie 	plane_ctl |= skl_plane_ctl_tiling(fb->modifier);
91946d12f91SDave Airlie 	plane_ctl |= skl_plane_ctl_rotate(rotation & DRM_MODE_ROTATE_MASK);
92046d12f91SDave Airlie 
921c988d2dcSLucas De Marchi 	if (DISPLAY_VER(dev_priv) >= 11)
922c988d2dcSLucas De Marchi 		plane_ctl |= icl_plane_ctl_flip(rotation &
92346d12f91SDave Airlie 						DRM_MODE_REFLECT_MASK);
92446d12f91SDave Airlie 
92546d12f91SDave Airlie 	if (key->flags & I915_SET_COLORKEY_DESTINATION)
92646d12f91SDave Airlie 		plane_ctl |= PLANE_CTL_KEY_ENABLE_DESTINATION;
92746d12f91SDave Airlie 	else if (key->flags & I915_SET_COLORKEY_SOURCE)
92846d12f91SDave Airlie 		plane_ctl |= PLANE_CTL_KEY_ENABLE_SOURCE;
92946d12f91SDave Airlie 
9301d2b8fd9SJosé Roberto de Souza 	/* Wa_22012358565:adl-p */
9310b86952dSVille Syrjälä 	if (DISPLAY_VER(dev_priv) == 13)
9320b86952dSVille Syrjälä 		plane_ctl |= adlp_plane_ctl_arb_slots(plane_state);
9330b86952dSVille Syrjälä 
93446d12f91SDave Airlie 	return plane_ctl;
93546d12f91SDave Airlie }
93646d12f91SDave Airlie 
glk_plane_color_ctl_crtc(const struct intel_crtc_state * crtc_state)93746d12f91SDave Airlie static u32 glk_plane_color_ctl_crtc(const struct intel_crtc_state *crtc_state)
93846d12f91SDave Airlie {
93946d12f91SDave Airlie 	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
94046d12f91SDave Airlie 	u32 plane_color_ctl = 0;
94146d12f91SDave Airlie 
942005e9537SMatt Roper 	if (DISPLAY_VER(dev_priv) >= 11)
94346d12f91SDave Airlie 		return plane_color_ctl;
94446d12f91SDave Airlie 
94546d12f91SDave Airlie 	if (crtc_state->gamma_enable)
94646d12f91SDave Airlie 		plane_color_ctl |= PLANE_COLOR_PIPE_GAMMA_ENABLE;
94746d12f91SDave Airlie 
94846d12f91SDave Airlie 	if (crtc_state->csc_enable)
94946d12f91SDave Airlie 		plane_color_ctl |= PLANE_COLOR_PIPE_CSC_ENABLE;
95046d12f91SDave Airlie 
95146d12f91SDave Airlie 	return plane_color_ctl;
95246d12f91SDave Airlie }
95346d12f91SDave Airlie 
glk_plane_color_ctl(const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)95446d12f91SDave Airlie static u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state,
95546d12f91SDave Airlie 			       const struct intel_plane_state *plane_state)
95646d12f91SDave Airlie {
95746d12f91SDave Airlie 	struct drm_i915_private *dev_priv =
95846d12f91SDave Airlie 		to_i915(plane_state->uapi.plane->dev);
95946d12f91SDave Airlie 	const struct drm_framebuffer *fb = plane_state->hw.fb;
96046d12f91SDave Airlie 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
96146d12f91SDave Airlie 	u32 plane_color_ctl = 0;
96246d12f91SDave Airlie 
96346d12f91SDave Airlie 	plane_color_ctl |= PLANE_COLOR_PLANE_GAMMA_DISABLE;
96446d12f91SDave Airlie 	plane_color_ctl |= glk_plane_color_ctl_alpha(plane_state);
96546d12f91SDave Airlie 
96646d12f91SDave Airlie 	if (fb->format->is_yuv && !icl_is_hdr_plane(dev_priv, plane->id)) {
96746d12f91SDave Airlie 		switch (plane_state->hw.color_encoding) {
96846d12f91SDave Airlie 		case DRM_COLOR_YCBCR_BT709:
96946d12f91SDave Airlie 			plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709;
97046d12f91SDave Airlie 			break;
97146d12f91SDave Airlie 		case DRM_COLOR_YCBCR_BT2020:
97246d12f91SDave Airlie 			plane_color_ctl |=
97346d12f91SDave Airlie 				PLANE_COLOR_CSC_MODE_YUV2020_TO_RGB2020;
97446d12f91SDave Airlie 			break;
97546d12f91SDave Airlie 		default:
97646d12f91SDave Airlie 			plane_color_ctl |=
97746d12f91SDave Airlie 				PLANE_COLOR_CSC_MODE_YUV601_TO_RGB601;
97846d12f91SDave Airlie 		}
97946d12f91SDave Airlie 		if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
98046d12f91SDave Airlie 			plane_color_ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
98146d12f91SDave Airlie 	} else if (fb->format->is_yuv) {
98246d12f91SDave Airlie 		plane_color_ctl |= PLANE_COLOR_INPUT_CSC_ENABLE;
98346d12f91SDave Airlie 		if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
98446d12f91SDave Airlie 			plane_color_ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
98546d12f91SDave Airlie 	}
98646d12f91SDave Airlie 
987841f262eSVille Syrjälä 	if (plane_state->force_black)
988841f262eSVille Syrjälä 		plane_color_ctl |= PLANE_COLOR_PLANE_CSC_ENABLE;
989841f262eSVille Syrjälä 
99046d12f91SDave Airlie 	return plane_color_ctl;
99146d12f91SDave Airlie }
99246d12f91SDave Airlie 
skl_surf_address(const struct intel_plane_state * plane_state,int color_plane)99333e7a975SVille Syrjälä static u32 skl_surf_address(const struct intel_plane_state *plane_state,
99433e7a975SVille Syrjälä 			    int color_plane)
99533e7a975SVille Syrjälä {
9965acbdcd1SJani Nikula 	struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
99733e7a975SVille Syrjälä 	const struct drm_framebuffer *fb = plane_state->hw.fb;
99833e7a975SVille Syrjälä 	u32 offset = plane_state->view.color_plane[color_plane].offset;
99933e7a975SVille Syrjälä 
100033e7a975SVille Syrjälä 	if (intel_fb_uses_dpt(fb)) {
100192dff6c7SImre Deak 		/*
100292dff6c7SImre Deak 		 * The DPT object contains only one vma, so the VMA's offset
100392dff6c7SImre Deak 		 * within the DPT is always 0.
100492dff6c7SImre Deak 		 */
10055acbdcd1SJani Nikula 		drm_WARN_ON(&i915->drm, plane_state->dpt_vma->node.start);
10065acbdcd1SJani Nikula 		drm_WARN_ON(&i915->drm, offset & 0x1fffff);
100733e7a975SVille Syrjälä 		return offset >> 9;
100833e7a975SVille Syrjälä 	} else {
10095acbdcd1SJani Nikula 		drm_WARN_ON(&i915->drm, offset & 0xfff);
101033e7a975SVille Syrjälä 		return offset;
101133e7a975SVille Syrjälä 	}
101233e7a975SVille Syrjälä }
101333e7a975SVille Syrjälä 
skl_plane_surf(const struct intel_plane_state * plane_state,int color_plane)101450faf7a1SVille Syrjälä static u32 skl_plane_surf(const struct intel_plane_state *plane_state,
101550faf7a1SVille Syrjälä 			  int color_plane)
101650faf7a1SVille Syrjälä {
101750faf7a1SVille Syrjälä 	u32 plane_surf;
101850faf7a1SVille Syrjälä 
101950faf7a1SVille Syrjälä 	plane_surf = intel_plane_ggtt_offset(plane_state) +
102050faf7a1SVille Syrjälä 		skl_surf_address(plane_state, color_plane);
102150faf7a1SVille Syrjälä 
102250faf7a1SVille Syrjälä 	if (plane_state->decrypt)
102350faf7a1SVille Syrjälä 		plane_surf |= PLANE_SURF_DECRYPT;
102450faf7a1SVille Syrjälä 
102550faf7a1SVille Syrjälä 	return plane_surf;
102650faf7a1SVille Syrjälä }
102750faf7a1SVille Syrjälä 
skl_plane_aux_dist(const struct intel_plane_state * plane_state,int color_plane)1028366714b0SVille Syrjälä static u32 skl_plane_aux_dist(const struct intel_plane_state *plane_state,
1029366714b0SVille Syrjälä 			      int color_plane)
1030366714b0SVille Syrjälä {
1031366714b0SVille Syrjälä 	struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
1032366714b0SVille Syrjälä 	const struct drm_framebuffer *fb = plane_state->hw.fb;
1033366714b0SVille Syrjälä 	int aux_plane = skl_main_to_aux_plane(fb, color_plane);
1034366714b0SVille Syrjälä 	u32 aux_dist;
1035366714b0SVille Syrjälä 
1036366714b0SVille Syrjälä 	if (!aux_plane)
1037366714b0SVille Syrjälä 		return 0;
1038366714b0SVille Syrjälä 
1039366714b0SVille Syrjälä 	aux_dist = skl_surf_address(plane_state, aux_plane) -
1040366714b0SVille Syrjälä 		skl_surf_address(plane_state, color_plane);
1041366714b0SVille Syrjälä 
1042366714b0SVille Syrjälä 	if (DISPLAY_VER(i915) < 12)
1043366714b0SVille Syrjälä 		aux_dist |= PLANE_AUX_STRIDE(skl_plane_stride(plane_state, aux_plane));
1044366714b0SVille Syrjälä 
1045366714b0SVille Syrjälä 	return aux_dist;
1046366714b0SVille Syrjälä }
1047366714b0SVille Syrjälä 
skl_plane_keyval(const struct intel_plane_state * plane_state)10484682a6d9SVille Syrjälä static u32 skl_plane_keyval(const struct intel_plane_state *plane_state)
10494682a6d9SVille Syrjälä {
10504682a6d9SVille Syrjälä 	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
10514682a6d9SVille Syrjälä 
10524682a6d9SVille Syrjälä 	return key->min_value;
10534682a6d9SVille Syrjälä }
10544682a6d9SVille Syrjälä 
skl_plane_keymax(const struct intel_plane_state * plane_state)10554682a6d9SVille Syrjälä static u32 skl_plane_keymax(const struct intel_plane_state *plane_state)
10564682a6d9SVille Syrjälä {
10574682a6d9SVille Syrjälä 	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
10584682a6d9SVille Syrjälä 	u8 alpha = plane_state->hw.alpha >> 8;
10594682a6d9SVille Syrjälä 
10604682a6d9SVille Syrjälä 	return (key->max_value & 0xffffff) | PLANE_KEYMAX_ALPHA(alpha);
10614682a6d9SVille Syrjälä }
10624682a6d9SVille Syrjälä 
skl_plane_keymsk(const struct intel_plane_state * plane_state)10634682a6d9SVille Syrjälä static u32 skl_plane_keymsk(const struct intel_plane_state *plane_state)
10644682a6d9SVille Syrjälä {
10654682a6d9SVille Syrjälä 	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
10664682a6d9SVille Syrjälä 	u8 alpha = plane_state->hw.alpha >> 8;
10674682a6d9SVille Syrjälä 	u32 keymsk;
10684682a6d9SVille Syrjälä 
10694682a6d9SVille Syrjälä 	keymsk = key->channel_mask & 0x7ffffff;
10704682a6d9SVille Syrjälä 	if (alpha < 0xff)
10714682a6d9SVille Syrjälä 		keymsk |= PLANE_KEYMSK_ALPHA_ENABLE;
10724682a6d9SVille Syrjälä 
10734682a6d9SVille Syrjälä 	return keymsk;
10744682a6d9SVille Syrjälä }
10754682a6d9SVille Syrjälä 
icl_plane_csc_load_black(struct intel_plane * plane)107617dbbe7bSVille Syrjälä static void icl_plane_csc_load_black(struct intel_plane *plane)
10776eba56f6SAnshuman Gupta {
107817dbbe7bSVille Syrjälä 	struct drm_i915_private *i915 = to_i915(plane->base.dev);
107917dbbe7bSVille Syrjälä 	enum plane_id plane_id = plane->id;
108017dbbe7bSVille Syrjälä 	enum pipe pipe = plane->pipe;
10816eba56f6SAnshuman Gupta 
108217dbbe7bSVille Syrjälä 	intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 0), 0);
108317dbbe7bSVille Syrjälä 	intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 1), 0);
10846eba56f6SAnshuman Gupta 
108517dbbe7bSVille Syrjälä 	intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 2), 0);
108617dbbe7bSVille Syrjälä 	intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 3), 0);
10876eba56f6SAnshuman Gupta 
108817dbbe7bSVille Syrjälä 	intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 4), 0);
108917dbbe7bSVille Syrjälä 	intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 5), 0);
10906eba56f6SAnshuman Gupta 
109117dbbe7bSVille Syrjälä 	intel_de_write_fw(i915, PLANE_CSC_PREOFF(pipe, plane_id, 0), 0);
109217dbbe7bSVille Syrjälä 	intel_de_write_fw(i915, PLANE_CSC_PREOFF(pipe, plane_id, 1), 0);
109317dbbe7bSVille Syrjälä 	intel_de_write_fw(i915, PLANE_CSC_PREOFF(pipe, plane_id, 2), 0);
10946eba56f6SAnshuman Gupta 
109517dbbe7bSVille Syrjälä 	intel_de_write_fw(i915, PLANE_CSC_POSTOFF(pipe, plane_id, 0), 0);
109617dbbe7bSVille Syrjälä 	intel_de_write_fw(i915, PLANE_CSC_POSTOFF(pipe, plane_id, 1), 0);
109717dbbe7bSVille Syrjälä 	intel_de_write_fw(i915, PLANE_CSC_POSTOFF(pipe, plane_id, 2), 0);
10986eba56f6SAnshuman Gupta }
10996eba56f6SAnshuman Gupta 
icl_plane_color_plane(const struct intel_plane_state * plane_state)1100f8a005ebSVille Syrjälä static int icl_plane_color_plane(const struct intel_plane_state *plane_state)
1101fee07601SVille Syrjälä {
1102fee07601SVille Syrjälä 	/* Program the UV plane on planar master */
1103fee07601SVille Syrjälä 	if (plane_state->planar_linked_plane && !plane_state->planar_slave)
1104fee07601SVille Syrjälä 		return 1;
1105fee07601SVille Syrjälä 	else
1106fee07601SVille Syrjälä 		return 0;
1107fee07601SVille Syrjälä }
1108fee07601SVille Syrjälä 
110946d12f91SDave Airlie static void
skl_plane_update_noarm(struct intel_plane * plane,const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)1110fee07601SVille Syrjälä skl_plane_update_noarm(struct intel_plane *plane,
111146d12f91SDave Airlie 		       const struct intel_crtc_state *crtc_state,
1112fee07601SVille Syrjälä 		       const struct intel_plane_state *plane_state)
111346d12f91SDave Airlie {
111446d12f91SDave Airlie 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
111546d12f91SDave Airlie 	enum plane_id plane_id = plane->id;
111646d12f91SDave Airlie 	enum pipe pipe = plane->pipe;
1117f8a005ebSVille Syrjälä 	u32 stride = skl_plane_stride(plane_state, 0);
111846d12f91SDave Airlie 	int crtc_x = plane_state->uapi.dst.x1;
111946d12f91SDave Airlie 	int crtc_y = plane_state->uapi.dst.y1;
112046d12f91SDave Airlie 	u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
112146d12f91SDave Airlie 	u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
112246d12f91SDave Airlie 
112346d12f91SDave Airlie 	/* The scaler will handle the output position */
112446d12f91SDave Airlie 	if (plane_state->scaler_id >= 0) {
112546d12f91SDave Airlie 		crtc_x = 0;
112646d12f91SDave Airlie 		crtc_y = 0;
112746d12f91SDave Airlie 	}
112846d12f91SDave Airlie 
112912d7d858SVille Syrjälä 	intel_de_write_fw(dev_priv, PLANE_STRIDE(pipe, plane_id),
113012d7d858SVille Syrjälä 			  PLANE_STRIDE_(stride));
113146d12f91SDave Airlie 	intel_de_write_fw(dev_priv, PLANE_POS(pipe, plane_id),
113212d7d858SVille Syrjälä 			  PLANE_POS_Y(crtc_y) | PLANE_POS_X(crtc_x));
113346d12f91SDave Airlie 	intel_de_write_fw(dev_priv, PLANE_SIZE(pipe, plane_id),
113412d7d858SVille Syrjälä 			  PLANE_HEIGHT(src_h - 1) | PLANE_WIDTH(src_w - 1));
113546d12f91SDave Airlie 
113646d12f91SDave Airlie 	skl_write_plane_wm(plane, crtc_state);
1137890b6ec4SVille Syrjälä }
1138890b6ec4SVille Syrjälä 
1139890b6ec4SVille Syrjälä static void
skl_plane_update_arm(struct intel_plane * plane,const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)1140fee07601SVille Syrjälä skl_plane_update_arm(struct intel_plane *plane,
1141890b6ec4SVille Syrjälä 		     const struct intel_crtc_state *crtc_state,
1142fee07601SVille Syrjälä 		     const struct intel_plane_state *plane_state)
1143890b6ec4SVille Syrjälä {
1144890b6ec4SVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1145890b6ec4SVille Syrjälä 	enum plane_id plane_id = plane->id;
1146890b6ec4SVille Syrjälä 	enum pipe pipe = plane->pipe;
1147f8a005ebSVille Syrjälä 	u32 x = plane_state->view.color_plane[0].x;
1148f8a005ebSVille Syrjälä 	u32 y = plane_state->view.color_plane[0].y;
1149f8a005ebSVille Syrjälä 	u32 plane_ctl, plane_color_ctl = 0;
1150890b6ec4SVille Syrjälä 
1151f8a005ebSVille Syrjälä 	plane_ctl = plane_state->ctl |
1152f8a005ebSVille Syrjälä 		skl_plane_ctl_crtc(crtc_state);
1153890b6ec4SVille Syrjälä 
1154890b6ec4SVille Syrjälä 	if (DISPLAY_VER(dev_priv) >= 10)
1155890b6ec4SVille Syrjälä 		plane_color_ctl = plane_state->color_ctl |
1156890b6ec4SVille Syrjälä 			glk_plane_color_ctl_crtc(crtc_state);
1157890b6ec4SVille Syrjälä 
11584682a6d9SVille Syrjälä 	intel_de_write_fw(dev_priv, PLANE_KEYVAL(pipe, plane_id), skl_plane_keyval(plane_state));
11594682a6d9SVille Syrjälä 	intel_de_write_fw(dev_priv, PLANE_KEYMSK(pipe, plane_id), skl_plane_keymsk(plane_state));
11604682a6d9SVille Syrjälä 	intel_de_write_fw(dev_priv, PLANE_KEYMAX(pipe, plane_id), skl_plane_keymax(plane_state));
116146d12f91SDave Airlie 
116246d12f91SDave Airlie 	intel_de_write_fw(dev_priv, PLANE_OFFSET(pipe, plane_id),
116312d7d858SVille Syrjälä 			  PLANE_OFFSET_Y(y) | PLANE_OFFSET_X(x));
116446d12f91SDave Airlie 
1165366714b0SVille Syrjälä 	intel_de_write_fw(dev_priv, PLANE_AUX_DIST(pipe, plane_id),
1166f8a005ebSVille Syrjälä 			  skl_plane_aux_dist(plane_state, 0));
1167890b6ec4SVille Syrjälä 
116846d12f91SDave Airlie 	intel_de_write_fw(dev_priv, PLANE_AUX_OFFSET(pipe, plane_id),
116912d7d858SVille Syrjälä 			  PLANE_OFFSET_Y(plane_state->view.color_plane[1].y) |
117012d7d858SVille Syrjälä 			  PLANE_OFFSET_X(plane_state->view.color_plane[1].x));
117146d12f91SDave Airlie 
1172890b6ec4SVille Syrjälä 	if (DISPLAY_VER(dev_priv) >= 10)
1173890b6ec4SVille Syrjälä 		intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id), plane_color_ctl);
117446d12f91SDave Airlie 
117546d12f91SDave Airlie 	/*
11767c653e15SVille Syrjälä 	 * Enable the scaler before the plane so that we don't
11777c653e15SVille Syrjälä 	 * get a catastrophic underrun even if the two operations
11787c653e15SVille Syrjälä 	 * end up happening in two different frames.
1179890b6ec4SVille Syrjälä 	 *
1180890b6ec4SVille Syrjälä 	 * TODO: split into noarm+arm pair
11817c653e15SVille Syrjälä 	 */
11827c653e15SVille Syrjälä 	if (plane_state->scaler_id >= 0)
11837c653e15SVille Syrjälä 		skl_program_plane_scaler(plane, crtc_state, plane_state);
11847c653e15SVille Syrjälä 
11857c653e15SVille Syrjälä 	/*
118646d12f91SDave Airlie 	 * The control register self-arms if the plane was previously
118746d12f91SDave Airlie 	 * disabled. Try to make the plane enable atomic by writing
118846d12f91SDave Airlie 	 * the control register just before the surface register.
118946d12f91SDave Airlie 	 */
119046d12f91SDave Airlie 	intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
119150faf7a1SVille Syrjälä 	intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id),
1192f8a005ebSVille Syrjälä 			  skl_plane_surf(plane_state, 0));
1193f8a005ebSVille Syrjälä }
1194f8a005ebSVille Syrjälä 
1195f8a005ebSVille Syrjälä static void
icl_plane_update_noarm(struct intel_plane * plane,const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)1196f8a005ebSVille Syrjälä icl_plane_update_noarm(struct intel_plane *plane,
1197f8a005ebSVille Syrjälä 		       const struct intel_crtc_state *crtc_state,
1198f8a005ebSVille Syrjälä 		       const struct intel_plane_state *plane_state)
1199f8a005ebSVille Syrjälä {
1200f8a005ebSVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1201f8a005ebSVille Syrjälä 	enum plane_id plane_id = plane->id;
1202f8a005ebSVille Syrjälä 	enum pipe pipe = plane->pipe;
1203f8a005ebSVille Syrjälä 	int color_plane = icl_plane_color_plane(plane_state);
1204f8a005ebSVille Syrjälä 	u32 stride = skl_plane_stride(plane_state, color_plane);
1205f8a005ebSVille Syrjälä 	const struct drm_framebuffer *fb = plane_state->hw.fb;
1206f8a005ebSVille Syrjälä 	int crtc_x = plane_state->uapi.dst.x1;
1207f8a005ebSVille Syrjälä 	int crtc_y = plane_state->uapi.dst.y1;
1208f8a005ebSVille Syrjälä 	int x = plane_state->view.color_plane[color_plane].x;
1209f8a005ebSVille Syrjälä 	int y = plane_state->view.color_plane[color_plane].y;
1210f8a005ebSVille Syrjälä 	int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
1211f8a005ebSVille Syrjälä 	int src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
1212f8a005ebSVille Syrjälä 	u32 plane_color_ctl;
1213f8a005ebSVille Syrjälä 
1214f8a005ebSVille Syrjälä 	plane_color_ctl = plane_state->color_ctl |
1215f8a005ebSVille Syrjälä 		glk_plane_color_ctl_crtc(crtc_state);
1216f8a005ebSVille Syrjälä 
1217f8a005ebSVille Syrjälä 	/* The scaler will handle the output position */
1218f8a005ebSVille Syrjälä 	if (plane_state->scaler_id >= 0) {
1219f8a005ebSVille Syrjälä 		crtc_x = 0;
1220f8a005ebSVille Syrjälä 		crtc_y = 0;
1221f8a005ebSVille Syrjälä 	}
1222f8a005ebSVille Syrjälä 
1223f8a005ebSVille Syrjälä 	intel_de_write_fw(dev_priv, PLANE_STRIDE(pipe, plane_id),
1224f8a005ebSVille Syrjälä 			  PLANE_STRIDE_(stride));
1225f8a005ebSVille Syrjälä 	intel_de_write_fw(dev_priv, PLANE_POS(pipe, plane_id),
1226f8a005ebSVille Syrjälä 			  PLANE_POS_Y(crtc_y) | PLANE_POS_X(crtc_x));
1227f8a005ebSVille Syrjälä 	intel_de_write_fw(dev_priv, PLANE_SIZE(pipe, plane_id),
1228f8a005ebSVille Syrjälä 			  PLANE_HEIGHT(src_h - 1) | PLANE_WIDTH(src_w - 1));
1229f8a005ebSVille Syrjälä 
1230f8a005ebSVille Syrjälä 	intel_de_write_fw(dev_priv, PLANE_KEYVAL(pipe, plane_id), skl_plane_keyval(plane_state));
1231f8a005ebSVille Syrjälä 	intel_de_write_fw(dev_priv, PLANE_KEYMSK(pipe, plane_id), skl_plane_keymsk(plane_state));
1232f8a005ebSVille Syrjälä 	intel_de_write_fw(dev_priv, PLANE_KEYMAX(pipe, plane_id), skl_plane_keymax(plane_state));
1233f8a005ebSVille Syrjälä 
1234f8a005ebSVille Syrjälä 	intel_de_write_fw(dev_priv, PLANE_OFFSET(pipe, plane_id),
1235f8a005ebSVille Syrjälä 			  PLANE_OFFSET_Y(y) | PLANE_OFFSET_X(x));
1236f8a005ebSVille Syrjälä 
1237f8a005ebSVille Syrjälä 	if (intel_fb_is_rc_ccs_cc_modifier(fb->modifier)) {
1238f8a005ebSVille Syrjälä 		intel_de_write_fw(dev_priv, PLANE_CC_VAL(pipe, plane_id, 0),
1239f8a005ebSVille Syrjälä 				  lower_32_bits(plane_state->ccval));
1240f8a005ebSVille Syrjälä 		intel_de_write_fw(dev_priv, PLANE_CC_VAL(pipe, plane_id, 1),
1241f8a005ebSVille Syrjälä 				  upper_32_bits(plane_state->ccval));
1242f8a005ebSVille Syrjälä 	}
1243f8a005ebSVille Syrjälä 
1244680025dcSJuha-Pekka Heikkilä 	/* FLAT CCS doesn't need to program AUX_DIST */
1245680025dcSJuha-Pekka Heikkilä 	if (!HAS_FLAT_CCS(dev_priv))
1246f8a005ebSVille Syrjälä 		intel_de_write_fw(dev_priv, PLANE_AUX_DIST(pipe, plane_id),
1247f8a005ebSVille Syrjälä 				  skl_plane_aux_dist(plane_state, color_plane));
1248f8a005ebSVille Syrjälä 
1249f8a005ebSVille Syrjälä 	if (icl_is_hdr_plane(dev_priv, plane_id))
1250f8a005ebSVille Syrjälä 		intel_de_write_fw(dev_priv, PLANE_CUS_CTL(pipe, plane_id),
1251f8a005ebSVille Syrjälä 				  plane_state->cus_ctl);
1252f8a005ebSVille Syrjälä 
1253f8a005ebSVille Syrjälä 	intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id), plane_color_ctl);
1254f8a005ebSVille Syrjälä 
1255f8a005ebSVille Syrjälä 	if (fb->format->is_yuv && icl_is_hdr_plane(dev_priv, plane_id))
1256f8a005ebSVille Syrjälä 		icl_program_input_csc(plane, crtc_state, plane_state);
1257f8a005ebSVille Syrjälä 
1258f8a005ebSVille Syrjälä 	skl_write_plane_wm(plane, crtc_state);
1259f8a005ebSVille Syrjälä 
1260f8a005ebSVille Syrjälä 	/*
1261f8a005ebSVille Syrjälä 	 * FIXME: pxp session invalidation can hit any time even at time of commit
1262f8a005ebSVille Syrjälä 	 * or after the commit, display content will be garbage.
1263f8a005ebSVille Syrjälä 	 */
1264f8a005ebSVille Syrjälä 	if (plane_state->force_black)
1265f8a005ebSVille Syrjälä 		icl_plane_csc_load_black(plane);
1266f8a005ebSVille Syrjälä 
1267c22cf04cSJouni Högander 	intel_psr2_program_plane_sel_fetch_noarm(plane, crtc_state, plane_state, color_plane);
1268f8a005ebSVille Syrjälä }
1269f8a005ebSVille Syrjälä 
1270f8a005ebSVille Syrjälä static void
icl_plane_update_arm(struct intel_plane * plane,const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)1271f8a005ebSVille Syrjälä icl_plane_update_arm(struct intel_plane *plane,
1272f8a005ebSVille Syrjälä 		     const struct intel_crtc_state *crtc_state,
1273f8a005ebSVille Syrjälä 		     const struct intel_plane_state *plane_state)
1274f8a005ebSVille Syrjälä {
1275f8a005ebSVille Syrjälä 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1276f8a005ebSVille Syrjälä 	enum plane_id plane_id = plane->id;
1277f8a005ebSVille Syrjälä 	enum pipe pipe = plane->pipe;
1278f8a005ebSVille Syrjälä 	int color_plane = icl_plane_color_plane(plane_state);
1279f8a005ebSVille Syrjälä 	u32 plane_ctl;
1280f8a005ebSVille Syrjälä 
1281f8a005ebSVille Syrjälä 	plane_ctl = plane_state->ctl |
1282f8a005ebSVille Syrjälä 		skl_plane_ctl_crtc(crtc_state);
1283f8a005ebSVille Syrjälä 
1284f8a005ebSVille Syrjälä 	/*
1285f8a005ebSVille Syrjälä 	 * Enable the scaler before the plane so that we don't
1286f8a005ebSVille Syrjälä 	 * get a catastrophic underrun even if the two operations
1287f8a005ebSVille Syrjälä 	 * end up happening in two different frames.
1288f8a005ebSVille Syrjälä 	 *
1289f8a005ebSVille Syrjälä 	 * TODO: split into noarm+arm pair
1290f8a005ebSVille Syrjälä 	 */
1291f8a005ebSVille Syrjälä 	if (plane_state->scaler_id >= 0)
1292f8a005ebSVille Syrjälä 		skl_program_plane_scaler(plane, crtc_state, plane_state);
1293f8a005ebSVille Syrjälä 
1294c22cf04cSJouni Högander 	intel_psr2_program_plane_sel_fetch_arm(plane, crtc_state, plane_state);
1295c22cf04cSJouni Högander 
1296f8a005ebSVille Syrjälä 	/*
1297f8a005ebSVille Syrjälä 	 * The control register self-arms if the plane was previously
1298f8a005ebSVille Syrjälä 	 * disabled. Try to make the plane enable atomic by writing
1299f8a005ebSVille Syrjälä 	 * the control register just before the surface register.
1300f8a005ebSVille Syrjälä 	 */
1301f8a005ebSVille Syrjälä 	intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
1302f8a005ebSVille Syrjälä 	intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id),
130350faf7a1SVille Syrjälä 			  skl_plane_surf(plane_state, color_plane));
130446d12f91SDave Airlie }
130546d12f91SDave Airlie 
130646d12f91SDave Airlie 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)130746d12f91SDave Airlie skl_plane_async_flip(struct intel_plane *plane,
130846d12f91SDave Airlie 		     const struct intel_crtc_state *crtc_state,
130946d12f91SDave Airlie 		     const struct intel_plane_state *plane_state,
131046d12f91SDave Airlie 		     bool async_flip)
131146d12f91SDave Airlie {
131246d12f91SDave Airlie 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
131346d12f91SDave Airlie 	enum plane_id plane_id = plane->id;
131446d12f91SDave Airlie 	enum pipe pipe = plane->pipe;
131546d12f91SDave Airlie 	u32 plane_ctl = plane_state->ctl;
131646d12f91SDave Airlie 
131746d12f91SDave Airlie 	plane_ctl |= skl_plane_ctl_crtc(crtc_state);
131846d12f91SDave Airlie 
131946d12f91SDave Airlie 	if (async_flip)
132046d12f91SDave Airlie 		plane_ctl |= PLANE_CTL_ASYNC_FLIP;
132146d12f91SDave Airlie 
132246d12f91SDave Airlie 	intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
132346d12f91SDave Airlie 	intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id),
132450faf7a1SVille Syrjälä 			  skl_plane_surf(plane_state, 0));
132546d12f91SDave Airlie }
132646d12f91SDave Airlie 
intel_format_is_p01x(u32 format)132746d12f91SDave Airlie static bool intel_format_is_p01x(u32 format)
132846d12f91SDave Airlie {
132946d12f91SDave Airlie 	switch (format) {
133046d12f91SDave Airlie 	case DRM_FORMAT_P010:
133146d12f91SDave Airlie 	case DRM_FORMAT_P012:
133246d12f91SDave Airlie 	case DRM_FORMAT_P016:
133346d12f91SDave Airlie 		return true;
133446d12f91SDave Airlie 	default:
133546d12f91SDave Airlie 		return false;
133646d12f91SDave Airlie 	}
133746d12f91SDave Airlie }
133846d12f91SDave Airlie 
skl_plane_check_fb(const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)133946d12f91SDave Airlie static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
134046d12f91SDave Airlie 			      const struct intel_plane_state *plane_state)
134146d12f91SDave Airlie {
134246d12f91SDave Airlie 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
134346d12f91SDave Airlie 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
134446d12f91SDave Airlie 	const struct drm_framebuffer *fb = plane_state->hw.fb;
134546d12f91SDave Airlie 	unsigned int rotation = plane_state->hw.rotation;
134646d12f91SDave Airlie 
134746d12f91SDave Airlie 	if (!fb)
134846d12f91SDave Airlie 		return 0;
134946d12f91SDave Airlie 
135046d12f91SDave Airlie 	if (rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180) &&
1351e359c47bSImre Deak 	    intel_fb_is_ccs_modifier(fb->modifier)) {
135246d12f91SDave Airlie 		drm_dbg_kms(&dev_priv->drm,
135346d12f91SDave Airlie 			    "RC support only with 0/180 degree rotation (%x)\n",
135446d12f91SDave Airlie 			    rotation);
135546d12f91SDave Airlie 		return -EINVAL;
135646d12f91SDave Airlie 	}
135746d12f91SDave Airlie 
135846d12f91SDave Airlie 	if (rotation & DRM_MODE_REFLECT_X &&
135946d12f91SDave Airlie 	    fb->modifier == DRM_FORMAT_MOD_LINEAR) {
136046d12f91SDave Airlie 		drm_dbg_kms(&dev_priv->drm,
136146d12f91SDave Airlie 			    "horizontal flip is not supported with linear surface formats\n");
136246d12f91SDave Airlie 		return -EINVAL;
136346d12f91SDave Airlie 	}
136446d12f91SDave Airlie 
136546d12f91SDave Airlie 	if (drm_rotation_90_or_270(rotation)) {
1366d3b4aa43SImre Deak 		if (!intel_fb_supports_90_270_rotation(to_intel_framebuffer(fb))) {
136746d12f91SDave Airlie 			drm_dbg_kms(&dev_priv->drm,
136846d12f91SDave Airlie 				    "Y/Yf tiling required for 90/270!\n");
136946d12f91SDave Airlie 			return -EINVAL;
137046d12f91SDave Airlie 		}
137146d12f91SDave Airlie 
137246d12f91SDave Airlie 		/*
137346d12f91SDave Airlie 		 * 90/270 is not allowed with RGB64 16:16:16:16 and
137446d12f91SDave Airlie 		 * Indexed 8-bit. RGB 16-bit 5:6:5 is allowed gen11 onwards.
137546d12f91SDave Airlie 		 */
137646d12f91SDave Airlie 		switch (fb->format->format) {
137746d12f91SDave Airlie 		case DRM_FORMAT_RGB565:
1378005e9537SMatt Roper 			if (DISPLAY_VER(dev_priv) >= 11)
137946d12f91SDave Airlie 				break;
138046d12f91SDave Airlie 			fallthrough;
138146d12f91SDave Airlie 		case DRM_FORMAT_C8:
138246d12f91SDave Airlie 		case DRM_FORMAT_XRGB16161616F:
138346d12f91SDave Airlie 		case DRM_FORMAT_XBGR16161616F:
138446d12f91SDave Airlie 		case DRM_FORMAT_ARGB16161616F:
138546d12f91SDave Airlie 		case DRM_FORMAT_ABGR16161616F:
138646d12f91SDave Airlie 		case DRM_FORMAT_Y210:
138746d12f91SDave Airlie 		case DRM_FORMAT_Y212:
138846d12f91SDave Airlie 		case DRM_FORMAT_Y216:
138946d12f91SDave Airlie 		case DRM_FORMAT_XVYU12_16161616:
139046d12f91SDave Airlie 		case DRM_FORMAT_XVYU16161616:
139146d12f91SDave Airlie 			drm_dbg_kms(&dev_priv->drm,
1392e3c2f187SStephen Rothwell 				    "Unsupported pixel format %p4cc for 90/270!\n",
1393e3c2f187SStephen Rothwell 				    &fb->format->format);
139446d12f91SDave Airlie 			return -EINVAL;
139546d12f91SDave Airlie 		default:
139646d12f91SDave Airlie 			break;
139746d12f91SDave Airlie 		}
139846d12f91SDave Airlie 	}
139946d12f91SDave Airlie 
140046d12f91SDave Airlie 	/* Y-tiling is not supported in IF-ID Interlace mode */
140146d12f91SDave Airlie 	if (crtc_state->hw.enable &&
140246d12f91SDave Airlie 	    crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE &&
1403d89357deSImre Deak 	    fb->modifier != DRM_FORMAT_MOD_LINEAR &&
1404d89357deSImre Deak 	    fb->modifier != I915_FORMAT_MOD_X_TILED) {
140546d12f91SDave Airlie 		drm_dbg_kms(&dev_priv->drm,
140646d12f91SDave Airlie 			    "Y/Yf tiling not supported in IF-ID mode\n");
140746d12f91SDave Airlie 		return -EINVAL;
140846d12f91SDave Airlie 	}
140946d12f91SDave Airlie 
141046d12f91SDave Airlie 	/* Wa_1606054188:tgl,adl-s */
141146d12f91SDave Airlie 	if ((IS_ALDERLAKE_S(dev_priv) || IS_TIGERLAKE(dev_priv)) &&
141246d12f91SDave Airlie 	    plane_state->ckey.flags & I915_SET_COLORKEY_SOURCE &&
141346d12f91SDave Airlie 	    intel_format_is_p01x(fb->format->format)) {
141446d12f91SDave Airlie 		drm_dbg_kms(&dev_priv->drm,
141546d12f91SDave Airlie 			    "Source color keying not supported with P01x formats\n");
141646d12f91SDave Airlie 		return -EINVAL;
141746d12f91SDave Airlie 	}
141846d12f91SDave Airlie 
141946d12f91SDave Airlie 	return 0;
142046d12f91SDave Airlie }
142146d12f91SDave Airlie 
skl_plane_check_dst_coordinates(const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)142246d12f91SDave Airlie static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_state,
142346d12f91SDave Airlie 					   const struct intel_plane_state *plane_state)
142446d12f91SDave Airlie {
142546d12f91SDave Airlie 	struct drm_i915_private *dev_priv =
142646d12f91SDave Airlie 		to_i915(plane_state->uapi.plane->dev);
142746d12f91SDave Airlie 	int crtc_x = plane_state->uapi.dst.x1;
142846d12f91SDave Airlie 	int crtc_w = drm_rect_width(&plane_state->uapi.dst);
142926111a16SVille Syrjälä 	int pipe_src_w = drm_rect_width(&crtc_state->pipe_src);
143046d12f91SDave Airlie 
143146d12f91SDave Airlie 	/*
1432244dba4cSLucas De Marchi 	 * Display WA #1175: glk
143346d12f91SDave Airlie 	 * Planes other than the cursor may cause FIFO underflow and display
143446d12f91SDave Airlie 	 * corruption if starting less than 4 pixels from the right edge of
143546d12f91SDave Airlie 	 * the screen.
143646d12f91SDave Airlie 	 * Besides the above WA fix the similar problem, where planes other
143746d12f91SDave Airlie 	 * than the cursor ending less than 4 pixels from the left edge of the
143846d12f91SDave Airlie 	 * screen may cause FIFO underflow and display corruption.
143946d12f91SDave Airlie 	 */
144093e7e61eSLucas De Marchi 	if (DISPLAY_VER(dev_priv) == 10 &&
144146d12f91SDave Airlie 	    (crtc_x + crtc_w < 4 || crtc_x > pipe_src_w - 4)) {
144246d12f91SDave Airlie 		drm_dbg_kms(&dev_priv->drm,
144346d12f91SDave Airlie 			    "requested plane X %s position %d invalid (valid range %d-%d)\n",
144446d12f91SDave Airlie 			    crtc_x + crtc_w < 4 ? "end" : "start",
144546d12f91SDave Airlie 			    crtc_x + crtc_w < 4 ? crtc_x + crtc_w : crtc_x,
144646d12f91SDave Airlie 			    4, pipe_src_w - 4);
144746d12f91SDave Airlie 		return -ERANGE;
144846d12f91SDave Airlie 	}
144946d12f91SDave Airlie 
145046d12f91SDave Airlie 	return 0;
145146d12f91SDave Airlie }
145246d12f91SDave Airlie 
skl_plane_check_nv12_rotation(const struct intel_plane_state * plane_state)145346d12f91SDave Airlie static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_state)
145446d12f91SDave Airlie {
14555acbdcd1SJani Nikula 	struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
145646d12f91SDave Airlie 	const struct drm_framebuffer *fb = plane_state->hw.fb;
145746d12f91SDave Airlie 	unsigned int rotation = plane_state->hw.rotation;
145846d12f91SDave Airlie 	int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
145946d12f91SDave Airlie 
146046d12f91SDave Airlie 	/* Display WA #1106 */
146146d12f91SDave Airlie 	if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) &&
146246d12f91SDave Airlie 	    src_w & 3 &&
146346d12f91SDave Airlie 	    (rotation == DRM_MODE_ROTATE_270 ||
146446d12f91SDave Airlie 	     rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) {
14655acbdcd1SJani Nikula 		drm_dbg_kms(&i915->drm, "src width must be multiple of 4 for rotated planar YUV\n");
146646d12f91SDave Airlie 		return -EINVAL;
146746d12f91SDave Airlie 	}
146846d12f91SDave Airlie 
146946d12f91SDave Airlie 	return 0;
147046d12f91SDave Airlie }
147146d12f91SDave Airlie 
skl_plane_max_scale(struct drm_i915_private * dev_priv,const struct drm_framebuffer * fb)147246d12f91SDave Airlie static int skl_plane_max_scale(struct drm_i915_private *dev_priv,
147346d12f91SDave Airlie 			       const struct drm_framebuffer *fb)
147446d12f91SDave Airlie {
147546d12f91SDave Airlie 	/*
147646d12f91SDave Airlie 	 * We don't yet know the final source width nor
147746d12f91SDave Airlie 	 * whether we can use the HQ scaler mode. Assume
147846d12f91SDave Airlie 	 * the best case.
147946d12f91SDave Airlie 	 * FIXME need to properly check this later.
148046d12f91SDave Airlie 	 */
14812b5a4562SMatt Roper 	if (DISPLAY_VER(dev_priv) >= 10 ||
148246d12f91SDave Airlie 	    !intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
148346d12f91SDave Airlie 		return 0x30000 - 1;
148446d12f91SDave Airlie 	else
148546d12f91SDave Airlie 		return 0x20000 - 1;
148646d12f91SDave Airlie }
148746d12f91SDave Airlie 
intel_plane_min_width(struct intel_plane * plane,const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)148846d12f91SDave Airlie static int intel_plane_min_width(struct intel_plane *plane,
148946d12f91SDave Airlie 				 const struct drm_framebuffer *fb,
149046d12f91SDave Airlie 				 int color_plane,
149146d12f91SDave Airlie 				 unsigned int rotation)
149246d12f91SDave Airlie {
149346d12f91SDave Airlie 	if (plane->min_width)
149446d12f91SDave Airlie 		return plane->min_width(fb, color_plane, rotation);
149546d12f91SDave Airlie 	else
149646d12f91SDave Airlie 		return 1;
149746d12f91SDave Airlie }
149846d12f91SDave Airlie 
intel_plane_max_width(struct intel_plane * plane,const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)149946d12f91SDave Airlie static int intel_plane_max_width(struct intel_plane *plane,
150046d12f91SDave Airlie 				 const struct drm_framebuffer *fb,
150146d12f91SDave Airlie 				 int color_plane,
150246d12f91SDave Airlie 				 unsigned int rotation)
150346d12f91SDave Airlie {
150446d12f91SDave Airlie 	if (plane->max_width)
150546d12f91SDave Airlie 		return plane->max_width(fb, color_plane, rotation);
150646d12f91SDave Airlie 	else
150746d12f91SDave Airlie 		return INT_MAX;
150846d12f91SDave Airlie }
150946d12f91SDave Airlie 
intel_plane_max_height(struct intel_plane * plane,const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)151046d12f91SDave Airlie static int intel_plane_max_height(struct intel_plane *plane,
151146d12f91SDave Airlie 				  const struct drm_framebuffer *fb,
151246d12f91SDave Airlie 				  int color_plane,
151346d12f91SDave Airlie 				  unsigned int rotation)
151446d12f91SDave Airlie {
151546d12f91SDave Airlie 	if (plane->max_height)
151646d12f91SDave Airlie 		return plane->max_height(fb, color_plane, rotation);
151746d12f91SDave Airlie 	else
151846d12f91SDave Airlie 		return INT_MAX;
151946d12f91SDave Airlie }
152046d12f91SDave Airlie 
152146d12f91SDave Airlie 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)152246d12f91SDave Airlie skl_check_main_ccs_coordinates(struct intel_plane_state *plane_state,
152346d12f91SDave Airlie 			       int main_x, int main_y, u32 main_offset,
152446d12f91SDave Airlie 			       int ccs_plane)
152546d12f91SDave Airlie {
152646d12f91SDave Airlie 	const struct drm_framebuffer *fb = plane_state->hw.fb;
152761169987SImre Deak 	int aux_x = plane_state->view.color_plane[ccs_plane].x;
152861169987SImre Deak 	int aux_y = plane_state->view.color_plane[ccs_plane].y;
152961169987SImre Deak 	u32 aux_offset = plane_state->view.color_plane[ccs_plane].offset;
153046d12f91SDave Airlie 	u32 alignment = intel_surf_alignment(fb, ccs_plane);
153146d12f91SDave Airlie 	int hsub;
153246d12f91SDave Airlie 	int vsub;
153346d12f91SDave Airlie 
153446d12f91SDave Airlie 	intel_fb_plane_get_subsampling(&hsub, &vsub, fb, ccs_plane);
153546d12f91SDave Airlie 	while (aux_offset >= main_offset && aux_y <= main_y) {
153646d12f91SDave Airlie 		int x, y;
153746d12f91SDave Airlie 
153846d12f91SDave Airlie 		if (aux_x == main_x && aux_y == main_y)
153946d12f91SDave Airlie 			break;
154046d12f91SDave Airlie 
154146d12f91SDave Airlie 		if (aux_offset == 0)
154246d12f91SDave Airlie 			break;
154346d12f91SDave Airlie 
154446d12f91SDave Airlie 		x = aux_x / hsub;
154546d12f91SDave Airlie 		y = aux_y / vsub;
154646d12f91SDave Airlie 		aux_offset = intel_plane_adjust_aligned_offset(&x, &y,
154746d12f91SDave Airlie 							       plane_state,
154846d12f91SDave Airlie 							       ccs_plane,
154946d12f91SDave Airlie 							       aux_offset,
155046d12f91SDave Airlie 							       aux_offset -
155146d12f91SDave Airlie 								alignment);
155246d12f91SDave Airlie 		aux_x = x * hsub + aux_x % hsub;
155346d12f91SDave Airlie 		aux_y = y * vsub + aux_y % vsub;
155446d12f91SDave Airlie 	}
155546d12f91SDave Airlie 
155646d12f91SDave Airlie 	if (aux_x != main_x || aux_y != main_y)
155746d12f91SDave Airlie 		return false;
155846d12f91SDave Airlie 
155961169987SImre Deak 	plane_state->view.color_plane[ccs_plane].offset = aux_offset;
156061169987SImre Deak 	plane_state->view.color_plane[ccs_plane].x = aux_x;
156161169987SImre Deak 	plane_state->view.color_plane[ccs_plane].y = aux_y;
156246d12f91SDave Airlie 
156346d12f91SDave Airlie 	return true;
156446d12f91SDave Airlie }
156546d12f91SDave Airlie 
156646d12f91SDave Airlie 
skl_calc_main_surface_offset(const struct intel_plane_state * plane_state,int * x,int * y,u32 * offset)156746d12f91SDave Airlie int skl_calc_main_surface_offset(const struct intel_plane_state *plane_state,
156846d12f91SDave Airlie 				 int *x, int *y, u32 *offset)
156946d12f91SDave Airlie {
157046d12f91SDave Airlie 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
157146d12f91SDave Airlie 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
157246d12f91SDave Airlie 	const struct drm_framebuffer *fb = plane_state->hw.fb;
157346d12f91SDave Airlie 	const int aux_plane = skl_main_to_aux_plane(fb, 0);
157461169987SImre Deak 	const u32 aux_offset = plane_state->view.color_plane[aux_plane].offset;
157546d12f91SDave Airlie 	const u32 alignment = intel_surf_alignment(fb, 0);
157646d12f91SDave Airlie 	const int w = drm_rect_width(&plane_state->uapi.src) >> 16;
157746d12f91SDave Airlie 
157846d12f91SDave Airlie 	intel_add_fb_offsets(x, y, plane_state, 0);
157946d12f91SDave Airlie 	*offset = intel_plane_compute_aligned_offset(x, y, plane_state, 0);
158046d12f91SDave Airlie 	if (drm_WARN_ON(&dev_priv->drm, alignment && !is_power_of_2(alignment)))
158146d12f91SDave Airlie 		return -EINVAL;
158246d12f91SDave Airlie 
158346d12f91SDave Airlie 	/*
158446d12f91SDave Airlie 	 * AUX surface offset is specified as the distance from the
158546d12f91SDave Airlie 	 * main surface offset, and it must be non-negative. Make
158646d12f91SDave Airlie 	 * sure that is what we will get.
158746d12f91SDave Airlie 	 */
158846d12f91SDave Airlie 	if (aux_plane && *offset > aux_offset)
158946d12f91SDave Airlie 		*offset = intel_plane_adjust_aligned_offset(x, y, plane_state, 0,
159046d12f91SDave Airlie 							    *offset,
159146d12f91SDave Airlie 							    aux_offset & ~(alignment - 1));
159246d12f91SDave Airlie 
159346d12f91SDave Airlie 	/*
159446d12f91SDave Airlie 	 * When using an X-tiled surface, the plane blows up
159546d12f91SDave Airlie 	 * if the x offset + width exceed the stride.
159646d12f91SDave Airlie 	 *
159746d12f91SDave Airlie 	 * TODO: linear and Y-tiled seem fine, Yf untested,
159846d12f91SDave Airlie 	 */
159946d12f91SDave Airlie 	if (fb->modifier == I915_FORMAT_MOD_X_TILED) {
160046d12f91SDave Airlie 		int cpp = fb->format->cpp[0];
160146d12f91SDave Airlie 
1602be6c1dd5SImre Deak 		while ((*x + w) * cpp > plane_state->view.color_plane[0].mapping_stride) {
160346d12f91SDave Airlie 			if (*offset == 0) {
160446d12f91SDave Airlie 				drm_dbg_kms(&dev_priv->drm,
160546d12f91SDave Airlie 					    "Unable to find suitable display surface offset due to X-tiling\n");
160646d12f91SDave Airlie 				return -EINVAL;
160746d12f91SDave Airlie 			}
160846d12f91SDave Airlie 
160946d12f91SDave Airlie 			*offset = intel_plane_adjust_aligned_offset(x, y, plane_state, 0,
161046d12f91SDave Airlie 								    *offset,
161146d12f91SDave Airlie 								    *offset - alignment);
161246d12f91SDave Airlie 		}
161346d12f91SDave Airlie 	}
161446d12f91SDave Airlie 
161546d12f91SDave Airlie 	return 0;
161646d12f91SDave Airlie }
161746d12f91SDave Airlie 
skl_check_main_surface(struct intel_plane_state * plane_state)161846d12f91SDave Airlie static int skl_check_main_surface(struct intel_plane_state *plane_state)
161946d12f91SDave Airlie {
162046d12f91SDave Airlie 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
162146d12f91SDave Airlie 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
162246d12f91SDave Airlie 	const struct drm_framebuffer *fb = plane_state->hw.fb;
162346d12f91SDave Airlie 	const unsigned int rotation = plane_state->hw.rotation;
162446d12f91SDave Airlie 	int x = plane_state->uapi.src.x1 >> 16;
162546d12f91SDave Airlie 	int y = plane_state->uapi.src.y1 >> 16;
162646d12f91SDave Airlie 	const int w = drm_rect_width(&plane_state->uapi.src) >> 16;
162746d12f91SDave Airlie 	const int h = drm_rect_height(&plane_state->uapi.src) >> 16;
162846d12f91SDave Airlie 	const int min_width = intel_plane_min_width(plane, fb, 0, rotation);
162946d12f91SDave Airlie 	const int max_width = intel_plane_max_width(plane, fb, 0, rotation);
163046d12f91SDave Airlie 	const int max_height = intel_plane_max_height(plane, fb, 0, rotation);
163146d12f91SDave Airlie 	const int aux_plane = skl_main_to_aux_plane(fb, 0);
163246d12f91SDave Airlie 	const u32 alignment = intel_surf_alignment(fb, 0);
163346d12f91SDave Airlie 	u32 offset;
163446d12f91SDave Airlie 	int ret;
163546d12f91SDave Airlie 
16360fe76b19SDrew Davenport 	if (w > max_width || w < min_width || h > max_height || h < 1) {
163746d12f91SDave Airlie 		drm_dbg_kms(&dev_priv->drm,
163846d12f91SDave Airlie 			    "requested Y/RGB source size %dx%d outside limits (min: %dx1 max: %dx%d)\n",
163946d12f91SDave Airlie 			    w, h, min_width, max_width, max_height);
164046d12f91SDave Airlie 		return -EINVAL;
164146d12f91SDave Airlie 	}
164246d12f91SDave Airlie 
164346d12f91SDave Airlie 	ret = skl_calc_main_surface_offset(plane_state, &x, &y, &offset);
164446d12f91SDave Airlie 	if (ret)
164546d12f91SDave Airlie 		return ret;
164646d12f91SDave Airlie 
164746d12f91SDave Airlie 	/*
164846d12f91SDave Airlie 	 * CCS AUX surface doesn't have its own x/y offsets, we must make sure
1649680025dcSJuha-Pekka Heikkilä 	 * they match with the main surface x/y offsets. On DG2
1650680025dcSJuha-Pekka Heikkilä 	 * there's no aux plane on fb so skip this checking.
165146d12f91SDave Airlie 	 */
1652680025dcSJuha-Pekka Heikkilä 	if (intel_fb_is_ccs_modifier(fb->modifier) && aux_plane) {
165346d12f91SDave Airlie 		while (!skl_check_main_ccs_coordinates(plane_state, x, y,
165446d12f91SDave Airlie 						       offset, aux_plane)) {
165546d12f91SDave Airlie 			if (offset == 0)
165646d12f91SDave Airlie 				break;
165746d12f91SDave Airlie 
165846d12f91SDave Airlie 			offset = intel_plane_adjust_aligned_offset(&x, &y, plane_state, 0,
165946d12f91SDave Airlie 								   offset, offset - alignment);
166046d12f91SDave Airlie 		}
166146d12f91SDave Airlie 
166261169987SImre Deak 		if (x != plane_state->view.color_plane[aux_plane].x ||
166361169987SImre Deak 		    y != plane_state->view.color_plane[aux_plane].y) {
166446d12f91SDave Airlie 			drm_dbg_kms(&dev_priv->drm,
166546d12f91SDave Airlie 				    "Unable to find suitable display surface offset due to CCS\n");
166646d12f91SDave Airlie 			return -EINVAL;
166746d12f91SDave Airlie 		}
166846d12f91SDave Airlie 	}
166946d12f91SDave Airlie 
1670e7367af1SJuha-Pekka Heikkilä 	if (DISPLAY_VER(dev_priv) >= 13)
1671e7367af1SJuha-Pekka Heikkilä 		drm_WARN_ON(&dev_priv->drm, x > 65535 || y > 65535);
1672e7367af1SJuha-Pekka Heikkilä 	else
167346d12f91SDave Airlie 		drm_WARN_ON(&dev_priv->drm, x > 8191 || y > 8191);
167446d12f91SDave Airlie 
167561169987SImre Deak 	plane_state->view.color_plane[0].offset = offset;
167661169987SImre Deak 	plane_state->view.color_plane[0].x = x;
167761169987SImre Deak 	plane_state->view.color_plane[0].y = y;
167846d12f91SDave Airlie 
167946d12f91SDave Airlie 	/*
168046d12f91SDave Airlie 	 * Put the final coordinates back so that the src
168146d12f91SDave Airlie 	 * coordinate checks will see the right values.
168246d12f91SDave Airlie 	 */
168346d12f91SDave Airlie 	drm_rect_translate_to(&plane_state->uapi.src,
168446d12f91SDave Airlie 			      x << 16, y << 16);
168546d12f91SDave Airlie 
168646d12f91SDave Airlie 	return 0;
168746d12f91SDave Airlie }
168846d12f91SDave Airlie 
skl_check_nv12_aux_surface(struct intel_plane_state * plane_state)168946d12f91SDave Airlie static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state)
169046d12f91SDave Airlie {
169146d12f91SDave Airlie 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
169246d12f91SDave Airlie 	struct drm_i915_private *i915 = to_i915(plane->base.dev);
169346d12f91SDave Airlie 	const struct drm_framebuffer *fb = plane_state->hw.fb;
169446d12f91SDave Airlie 	unsigned int rotation = plane_state->hw.rotation;
169546d12f91SDave Airlie 	int uv_plane = 1;
1696680025dcSJuha-Pekka Heikkilä 	int ccs_plane = intel_fb_is_ccs_modifier(fb->modifier) ?
1697680025dcSJuha-Pekka Heikkilä 			skl_main_to_aux_plane(fb, uv_plane) : 0;
169846d12f91SDave Airlie 	int max_width = intel_plane_max_width(plane, fb, uv_plane, rotation);
169946d12f91SDave Airlie 	int max_height = intel_plane_max_height(plane, fb, uv_plane, rotation);
170046d12f91SDave Airlie 	int x = plane_state->uapi.src.x1 >> 17;
170146d12f91SDave Airlie 	int y = plane_state->uapi.src.y1 >> 17;
170246d12f91SDave Airlie 	int w = drm_rect_width(&plane_state->uapi.src) >> 17;
170346d12f91SDave Airlie 	int h = drm_rect_height(&plane_state->uapi.src) >> 17;
170446d12f91SDave Airlie 	u32 offset;
170546d12f91SDave Airlie 
170646d12f91SDave Airlie 	/* FIXME not quite sure how/if these apply to the chroma plane */
170746d12f91SDave Airlie 	if (w > max_width || h > max_height) {
170846d12f91SDave Airlie 		drm_dbg_kms(&i915->drm,
170946d12f91SDave Airlie 			    "CbCr source size %dx%d too big (limit %dx%d)\n",
171046d12f91SDave Airlie 			    w, h, max_width, max_height);
171146d12f91SDave Airlie 		return -EINVAL;
171246d12f91SDave Airlie 	}
171346d12f91SDave Airlie 
171446d12f91SDave Airlie 	intel_add_fb_offsets(&x, &y, plane_state, uv_plane);
171546d12f91SDave Airlie 	offset = intel_plane_compute_aligned_offset(&x, &y,
171646d12f91SDave Airlie 						    plane_state, uv_plane);
171746d12f91SDave Airlie 
1718680025dcSJuha-Pekka Heikkilä 	if (ccs_plane) {
171961169987SImre Deak 		u32 aux_offset = plane_state->view.color_plane[ccs_plane].offset;
172046d12f91SDave Airlie 		u32 alignment = intel_surf_alignment(fb, uv_plane);
172146d12f91SDave Airlie 
172246d12f91SDave Airlie 		if (offset > aux_offset)
172346d12f91SDave Airlie 			offset = intel_plane_adjust_aligned_offset(&x, &y,
172446d12f91SDave Airlie 								   plane_state,
172546d12f91SDave Airlie 								   uv_plane,
172646d12f91SDave Airlie 								   offset,
172746d12f91SDave Airlie 								   aux_offset & ~(alignment - 1));
172846d12f91SDave Airlie 
172946d12f91SDave Airlie 		while (!skl_check_main_ccs_coordinates(plane_state, x, y,
173046d12f91SDave Airlie 						       offset, ccs_plane)) {
173146d12f91SDave Airlie 			if (offset == 0)
173246d12f91SDave Airlie 				break;
173346d12f91SDave Airlie 
173446d12f91SDave Airlie 			offset = intel_plane_adjust_aligned_offset(&x, &y,
173546d12f91SDave Airlie 								   plane_state,
173646d12f91SDave Airlie 								   uv_plane,
173746d12f91SDave Airlie 								   offset, offset - alignment);
173846d12f91SDave Airlie 		}
173946d12f91SDave Airlie 
174061169987SImre Deak 		if (x != plane_state->view.color_plane[ccs_plane].x ||
174161169987SImre Deak 		    y != plane_state->view.color_plane[ccs_plane].y) {
174246d12f91SDave Airlie 			drm_dbg_kms(&i915->drm,
174346d12f91SDave Airlie 				    "Unable to find suitable display surface offset due to CCS\n");
174446d12f91SDave Airlie 			return -EINVAL;
174546d12f91SDave Airlie 		}
174646d12f91SDave Airlie 	}
174746d12f91SDave Airlie 
1748e7367af1SJuha-Pekka Heikkilä 	if (DISPLAY_VER(i915) >= 13)
1749e7367af1SJuha-Pekka Heikkilä 		drm_WARN_ON(&i915->drm, x > 65535 || y > 65535);
1750e7367af1SJuha-Pekka Heikkilä 	else
175146d12f91SDave Airlie 		drm_WARN_ON(&i915->drm, x > 8191 || y > 8191);
175246d12f91SDave Airlie 
175361169987SImre Deak 	plane_state->view.color_plane[uv_plane].offset = offset;
175461169987SImre Deak 	plane_state->view.color_plane[uv_plane].x = x;
175561169987SImre Deak 	plane_state->view.color_plane[uv_plane].y = y;
175646d12f91SDave Airlie 
175746d12f91SDave Airlie 	return 0;
175846d12f91SDave Airlie }
175946d12f91SDave Airlie 
skl_check_ccs_aux_surface(struct intel_plane_state * plane_state)176046d12f91SDave Airlie static int skl_check_ccs_aux_surface(struct intel_plane_state *plane_state)
176146d12f91SDave Airlie {
176246d12f91SDave Airlie 	const struct drm_framebuffer *fb = plane_state->hw.fb;
176346d12f91SDave Airlie 	int src_x = plane_state->uapi.src.x1 >> 16;
176446d12f91SDave Airlie 	int src_y = plane_state->uapi.src.y1 >> 16;
176546d12f91SDave Airlie 	u32 offset;
176646d12f91SDave Airlie 	int ccs_plane;
176746d12f91SDave Airlie 
176846d12f91SDave Airlie 	for (ccs_plane = 0; ccs_plane < fb->format->num_planes; ccs_plane++) {
176946d12f91SDave Airlie 		int main_hsub, main_vsub;
177046d12f91SDave Airlie 		int hsub, vsub;
177146d12f91SDave Airlie 		int x, y;
177246d12f91SDave Airlie 
1773f5042343SImre Deak 		if (!intel_fb_is_ccs_aux_plane(fb, ccs_plane))
177446d12f91SDave Airlie 			continue;
177546d12f91SDave Airlie 
177646d12f91SDave Airlie 		intel_fb_plane_get_subsampling(&main_hsub, &main_vsub, fb,
177746d12f91SDave Airlie 					       skl_ccs_to_main_plane(fb, ccs_plane));
177846d12f91SDave Airlie 		intel_fb_plane_get_subsampling(&hsub, &vsub, fb, ccs_plane);
177946d12f91SDave Airlie 
178046d12f91SDave Airlie 		hsub *= main_hsub;
178146d12f91SDave Airlie 		vsub *= main_vsub;
178246d12f91SDave Airlie 		x = src_x / hsub;
178346d12f91SDave Airlie 		y = src_y / vsub;
178446d12f91SDave Airlie 
178546d12f91SDave Airlie 		intel_add_fb_offsets(&x, &y, plane_state, ccs_plane);
178646d12f91SDave Airlie 
178746d12f91SDave Airlie 		offset = intel_plane_compute_aligned_offset(&x, &y,
178846d12f91SDave Airlie 							    plane_state,
178946d12f91SDave Airlie 							    ccs_plane);
179046d12f91SDave Airlie 
179161169987SImre Deak 		plane_state->view.color_plane[ccs_plane].offset = offset;
179261169987SImre Deak 		plane_state->view.color_plane[ccs_plane].x = (x * hsub + src_x % hsub) / main_hsub;
179361169987SImre Deak 		plane_state->view.color_plane[ccs_plane].y = (y * vsub + src_y % vsub) / main_vsub;
179446d12f91SDave Airlie 	}
179546d12f91SDave Airlie 
179646d12f91SDave Airlie 	return 0;
179746d12f91SDave Airlie }
179846d12f91SDave Airlie 
skl_check_plane_surface(struct intel_plane_state * plane_state)179946d12f91SDave Airlie static int skl_check_plane_surface(struct intel_plane_state *plane_state)
180046d12f91SDave Airlie {
180146d12f91SDave Airlie 	const struct drm_framebuffer *fb = plane_state->hw.fb;
1802ee456a4cSImre Deak 	int ret;
180346d12f91SDave Airlie 
180446d12f91SDave Airlie 	ret = intel_plane_compute_gtt(plane_state);
180546d12f91SDave Airlie 	if (ret)
180646d12f91SDave Airlie 		return ret;
180746d12f91SDave Airlie 
180846d12f91SDave Airlie 	if (!plane_state->uapi.visible)
180946d12f91SDave Airlie 		return 0;
181046d12f91SDave Airlie 
181146d12f91SDave Airlie 	/*
181246d12f91SDave Airlie 	 * Handle the AUX surface first since the main surface setup depends on
181346d12f91SDave Airlie 	 * it.
181446d12f91SDave Airlie 	 */
1815e359c47bSImre Deak 	if (intel_fb_is_ccs_modifier(fb->modifier)) {
181646d12f91SDave Airlie 		ret = skl_check_ccs_aux_surface(plane_state);
181746d12f91SDave Airlie 		if (ret)
181846d12f91SDave Airlie 			return ret;
181946d12f91SDave Airlie 	}
182046d12f91SDave Airlie 
182146d12f91SDave Airlie 	if (intel_format_info_is_yuv_semiplanar(fb->format,
182246d12f91SDave Airlie 						fb->modifier)) {
182346d12f91SDave Airlie 		ret = skl_check_nv12_aux_surface(plane_state);
182446d12f91SDave Airlie 		if (ret)
182546d12f91SDave Airlie 			return ret;
182646d12f91SDave Airlie 	}
182746d12f91SDave Airlie 
182846d12f91SDave Airlie 	ret = skl_check_main_surface(plane_state);
182946d12f91SDave Airlie 	if (ret)
183046d12f91SDave Airlie 		return ret;
183146d12f91SDave Airlie 
183246d12f91SDave Airlie 	return 0;
183346d12f91SDave Airlie }
183446d12f91SDave Airlie 
skl_fb_scalable(const struct drm_framebuffer * fb)183514cebc1fSDave Airlie static bool skl_fb_scalable(const struct drm_framebuffer *fb)
183646d12f91SDave Airlie {
183746d12f91SDave Airlie 	if (!fb)
183846d12f91SDave Airlie 		return false;
183946d12f91SDave Airlie 
184046d12f91SDave Airlie 	switch (fb->format->format) {
184146d12f91SDave Airlie 	case DRM_FORMAT_C8:
184246d12f91SDave Airlie 		return false;
184346d12f91SDave Airlie 	case DRM_FORMAT_XRGB16161616F:
184446d12f91SDave Airlie 	case DRM_FORMAT_ARGB16161616F:
184546d12f91SDave Airlie 	case DRM_FORMAT_XBGR16161616F:
184646d12f91SDave Airlie 	case DRM_FORMAT_ABGR16161616F:
1847005e9537SMatt Roper 		return DISPLAY_VER(to_i915(fb->dev)) >= 11;
184846d12f91SDave Airlie 	default:
184946d12f91SDave Airlie 		return true;
185046d12f91SDave Airlie 	}
185146d12f91SDave Airlie }
185246d12f91SDave Airlie 
bo_has_valid_encryption(struct drm_i915_gem_object * obj)1853f9a7b19cSVille Syrjälä static bool bo_has_valid_encryption(struct drm_i915_gem_object *obj)
1854f9a7b19cSVille Syrjälä {
1855f9a7b19cSVille Syrjälä 	struct drm_i915_private *i915 = to_i915(obj->base.dev);
1856f9a7b19cSVille Syrjälä 
1857f67986b0SAlan Previn 	return intel_pxp_key_check(i915->pxp, obj, false) == 0;
1858f9a7b19cSVille Syrjälä }
1859f9a7b19cSVille Syrjälä 
pxp_is_borked(struct drm_i915_gem_object * obj)1860f9a7b19cSVille Syrjälä static bool pxp_is_borked(struct drm_i915_gem_object *obj)
1861f9a7b19cSVille Syrjälä {
1862f9a7b19cSVille Syrjälä 	return i915_gem_object_is_protected(obj) && !bo_has_valid_encryption(obj);
1863f9a7b19cSVille Syrjälä }
1864f9a7b19cSVille Syrjälä 
skl_plane_check(struct intel_crtc_state * crtc_state,struct intel_plane_state * plane_state)186546d12f91SDave Airlie static int skl_plane_check(struct intel_crtc_state *crtc_state,
186646d12f91SDave Airlie 			   struct intel_plane_state *plane_state)
186746d12f91SDave Airlie {
186846d12f91SDave Airlie 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
186946d12f91SDave Airlie 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
187046d12f91SDave Airlie 	const struct drm_framebuffer *fb = plane_state->hw.fb;
1871cce32e4eSThomas Zimmermann 	int min_scale = DRM_PLANE_NO_SCALING;
1872cce32e4eSThomas Zimmermann 	int max_scale = DRM_PLANE_NO_SCALING;
187346d12f91SDave Airlie 	int ret;
187446d12f91SDave Airlie 
187546d12f91SDave Airlie 	ret = skl_plane_check_fb(crtc_state, plane_state);
187646d12f91SDave Airlie 	if (ret)
187746d12f91SDave Airlie 		return ret;
187846d12f91SDave Airlie 
187946d12f91SDave Airlie 	/* use scaler when colorkey is not required */
188014cebc1fSDave Airlie 	if (!plane_state->ckey.flags && skl_fb_scalable(fb)) {
188146d12f91SDave Airlie 		min_scale = 1;
188246d12f91SDave Airlie 		max_scale = skl_plane_max_scale(dev_priv, fb);
188346d12f91SDave Airlie 	}
188446d12f91SDave Airlie 
188546d12f91SDave Airlie 	ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
188646d12f91SDave Airlie 						min_scale, max_scale, true);
188746d12f91SDave Airlie 	if (ret)
188846d12f91SDave Airlie 		return ret;
188946d12f91SDave Airlie 
189046d12f91SDave Airlie 	ret = skl_check_plane_surface(plane_state);
189146d12f91SDave Airlie 	if (ret)
189246d12f91SDave Airlie 		return ret;
189346d12f91SDave Airlie 
189446d12f91SDave Airlie 	if (!plane_state->uapi.visible)
189546d12f91SDave Airlie 		return 0;
189646d12f91SDave Airlie 
189746d12f91SDave Airlie 	ret = skl_plane_check_dst_coordinates(crtc_state, plane_state);
189846d12f91SDave Airlie 	if (ret)
189946d12f91SDave Airlie 		return ret;
190046d12f91SDave Airlie 
190146d12f91SDave Airlie 	ret = intel_plane_check_src_coordinates(plane_state);
190246d12f91SDave Airlie 	if (ret)
190346d12f91SDave Airlie 		return ret;
190446d12f91SDave Airlie 
190546d12f91SDave Airlie 	ret = skl_plane_check_nv12_rotation(plane_state);
190646d12f91SDave Airlie 	if (ret)
190746d12f91SDave Airlie 		return ret;
190846d12f91SDave Airlie 
1909f9a7b19cSVille Syrjälä 	if (DISPLAY_VER(dev_priv) >= 11) {
1910f9a7b19cSVille Syrjälä 		plane_state->decrypt = bo_has_valid_encryption(intel_fb_obj(fb));
1911f9a7b19cSVille Syrjälä 		plane_state->force_black = pxp_is_borked(intel_fb_obj(fb));
1912f9a7b19cSVille Syrjälä 	}
1913f9a7b19cSVille Syrjälä 
191446d12f91SDave Airlie 	/* HW only has 8 bits pixel precision, disable plane if invisible */
191546d12f91SDave Airlie 	if (!(plane_state->hw.alpha >> 8))
191646d12f91SDave Airlie 		plane_state->uapi.visible = false;
191746d12f91SDave Airlie 
191846d12f91SDave Airlie 	plane_state->ctl = skl_plane_ctl(crtc_state, plane_state);
191946d12f91SDave Airlie 
19202b5a4562SMatt Roper 	if (DISPLAY_VER(dev_priv) >= 10)
192146d12f91SDave Airlie 		plane_state->color_ctl = glk_plane_color_ctl(crtc_state,
192246d12f91SDave Airlie 							     plane_state);
192346d12f91SDave Airlie 
192446d12f91SDave Airlie 	if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) &&
192546d12f91SDave Airlie 	    icl_is_hdr_plane(dev_priv, plane->id))
192646d12f91SDave Airlie 		/* Enable and use MPEG-2 chroma siting */
192746d12f91SDave Airlie 		plane_state->cus_ctl = PLANE_CUS_ENABLE |
192846d12f91SDave Airlie 			PLANE_CUS_HPHASE_0 |
192946d12f91SDave Airlie 			PLANE_CUS_VPHASE_SIGN_NEGATIVE | PLANE_CUS_VPHASE_0_25;
193046d12f91SDave Airlie 	else
193146d12f91SDave Airlie 		plane_state->cus_ctl = 0;
193246d12f91SDave Airlie 
193346d12f91SDave Airlie 	return 0;
193446d12f91SDave Airlie }
193546d12f91SDave Airlie 
skl_fbc_id_for_pipe(enum pipe pipe)1936b8ca477eSVille Syrjälä static enum intel_fbc_id skl_fbc_id_for_pipe(enum pipe pipe)
193746d12f91SDave Airlie {
1938b8ca477eSVille Syrjälä 	return pipe - PIPE_A + INTEL_FBC_A;
1939b8ca477eSVille Syrjälä }
1940b8ca477eSVille Syrjälä 
skl_plane_has_fbc(struct drm_i915_private * dev_priv,enum intel_fbc_id fbc_id,enum plane_id plane_id)1941b8ca477eSVille Syrjälä static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv,
1942b8ca477eSVille Syrjälä 			      enum intel_fbc_id fbc_id, enum plane_id plane_id)
1943b8ca477eSVille Syrjälä {
194418e0deeeSMatt Roper 	if ((DISPLAY_RUNTIME_INFO(dev_priv)->fbc_mask & BIT(fbc_id)) == 0)
194546d12f91SDave Airlie 		return false;
194646d12f91SDave Airlie 
1947b8ca477eSVille Syrjälä 	return plane_id == PLANE_PRIMARY;
194846d12f91SDave Airlie }
194946d12f91SDave Airlie 
skl_plane_fbc(struct drm_i915_private * dev_priv,enum pipe pipe,enum plane_id plane_id)1950825bd833SVille Syrjälä static struct intel_fbc *skl_plane_fbc(struct drm_i915_private *dev_priv,
1951825bd833SVille Syrjälä 				       enum pipe pipe, enum plane_id plane_id)
1952825bd833SVille Syrjälä {
1953b8ca477eSVille Syrjälä 	enum intel_fbc_id fbc_id = skl_fbc_id_for_pipe(pipe);
1954b8ca477eSVille Syrjälä 
1955b8ca477eSVille Syrjälä 	if (skl_plane_has_fbc(dev_priv, fbc_id, plane_id))
195680b3842fSJani Nikula 		return dev_priv->display.fbc[fbc_id];
1957825bd833SVille Syrjälä 	else
1958825bd833SVille Syrjälä 		return NULL;
1959825bd833SVille Syrjälä }
1960825bd833SVille Syrjälä 
skl_plane_has_planar(struct drm_i915_private * dev_priv,enum pipe pipe,enum plane_id plane_id)196146d12f91SDave Airlie static bool skl_plane_has_planar(struct drm_i915_private *dev_priv,
196246d12f91SDave Airlie 				 enum pipe pipe, enum plane_id plane_id)
196346d12f91SDave Airlie {
196446d12f91SDave Airlie 	/* Display WA #0870: skl, bxt */
196546d12f91SDave Airlie 	if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv))
196646d12f91SDave Airlie 		return false;
196746d12f91SDave Airlie 
196893e7e61eSLucas De Marchi 	if (DISPLAY_VER(dev_priv) == 9 && pipe == PIPE_C)
196946d12f91SDave Airlie 		return false;
197046d12f91SDave Airlie 
197146d12f91SDave Airlie 	if (plane_id != PLANE_PRIMARY && plane_id != PLANE_SPRITE0)
197246d12f91SDave Airlie 		return false;
197346d12f91SDave Airlie 
197446d12f91SDave Airlie 	return true;
197546d12f91SDave Airlie }
197646d12f91SDave Airlie 
skl_get_plane_formats(struct drm_i915_private * dev_priv,enum pipe pipe,enum plane_id plane_id,int * num_formats)197746d12f91SDave Airlie static const u32 *skl_get_plane_formats(struct drm_i915_private *dev_priv,
197846d12f91SDave Airlie 					enum pipe pipe, enum plane_id plane_id,
197946d12f91SDave Airlie 					int *num_formats)
198046d12f91SDave Airlie {
198146d12f91SDave Airlie 	if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
198246d12f91SDave Airlie 		*num_formats = ARRAY_SIZE(skl_planar_formats);
198346d12f91SDave Airlie 		return skl_planar_formats;
198446d12f91SDave Airlie 	} else {
198546d12f91SDave Airlie 		*num_formats = ARRAY_SIZE(skl_plane_formats);
198646d12f91SDave Airlie 		return skl_plane_formats;
198746d12f91SDave Airlie 	}
198846d12f91SDave Airlie }
198946d12f91SDave Airlie 
glk_get_plane_formats(struct drm_i915_private * dev_priv,enum pipe pipe,enum plane_id plane_id,int * num_formats)199046d12f91SDave Airlie static const u32 *glk_get_plane_formats(struct drm_i915_private *dev_priv,
199146d12f91SDave Airlie 					enum pipe pipe, enum plane_id plane_id,
199246d12f91SDave Airlie 					int *num_formats)
199346d12f91SDave Airlie {
199446d12f91SDave Airlie 	if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
199546d12f91SDave Airlie 		*num_formats = ARRAY_SIZE(glk_planar_formats);
199646d12f91SDave Airlie 		return glk_planar_formats;
199746d12f91SDave Airlie 	} else {
199846d12f91SDave Airlie 		*num_formats = ARRAY_SIZE(skl_plane_formats);
199946d12f91SDave Airlie 		return skl_plane_formats;
200046d12f91SDave Airlie 	}
200146d12f91SDave Airlie }
200246d12f91SDave Airlie 
icl_get_plane_formats(struct drm_i915_private * dev_priv,enum pipe pipe,enum plane_id plane_id,int * num_formats)200346d12f91SDave Airlie static const u32 *icl_get_plane_formats(struct drm_i915_private *dev_priv,
200446d12f91SDave Airlie 					enum pipe pipe, enum plane_id plane_id,
200546d12f91SDave Airlie 					int *num_formats)
200646d12f91SDave Airlie {
200746d12f91SDave Airlie 	if (icl_is_hdr_plane(dev_priv, plane_id)) {
200846d12f91SDave Airlie 		*num_formats = ARRAY_SIZE(icl_hdr_plane_formats);
200946d12f91SDave Airlie 		return icl_hdr_plane_formats;
201046d12f91SDave Airlie 	} else if (icl_is_nv12_y_plane(dev_priv, plane_id)) {
201146d12f91SDave Airlie 		*num_formats = ARRAY_SIZE(icl_sdr_y_plane_formats);
201246d12f91SDave Airlie 		return icl_sdr_y_plane_formats;
201346d12f91SDave Airlie 	} else {
201446d12f91SDave Airlie 		*num_formats = ARRAY_SIZE(icl_sdr_uv_plane_formats);
201546d12f91SDave Airlie 		return icl_sdr_uv_plane_formats;
201646d12f91SDave Airlie 	}
201746d12f91SDave Airlie }
201846d12f91SDave Airlie 
skl_plane_format_mod_supported(struct drm_plane * _plane,u32 format,u64 modifier)201946d12f91SDave Airlie static bool skl_plane_format_mod_supported(struct drm_plane *_plane,
202046d12f91SDave Airlie 					   u32 format, u64 modifier)
202146d12f91SDave Airlie {
202246d12f91SDave Airlie 	struct intel_plane *plane = to_intel_plane(_plane);
202346d12f91SDave Airlie 
2024e2b83294SImre Deak 	if (!intel_fb_plane_supports_modifier(plane, modifier))
202546d12f91SDave Airlie 		return false;
202646d12f91SDave Airlie 
202746d12f91SDave Airlie 	switch (format) {
202846d12f91SDave Airlie 	case DRM_FORMAT_XRGB8888:
202946d12f91SDave Airlie 	case DRM_FORMAT_XBGR8888:
203046d12f91SDave Airlie 	case DRM_FORMAT_ARGB8888:
203146d12f91SDave Airlie 	case DRM_FORMAT_ABGR8888:
2032e359c47bSImre Deak 		if (intel_fb_is_ccs_modifier(modifier))
203346d12f91SDave Airlie 			return true;
203446d12f91SDave Airlie 		fallthrough;
203546d12f91SDave Airlie 	case DRM_FORMAT_RGB565:
203646d12f91SDave Airlie 	case DRM_FORMAT_XRGB2101010:
203746d12f91SDave Airlie 	case DRM_FORMAT_XBGR2101010:
203846d12f91SDave Airlie 	case DRM_FORMAT_ARGB2101010:
203946d12f91SDave Airlie 	case DRM_FORMAT_ABGR2101010:
204046d12f91SDave Airlie 	case DRM_FORMAT_YUYV:
204146d12f91SDave Airlie 	case DRM_FORMAT_YVYU:
204246d12f91SDave Airlie 	case DRM_FORMAT_UYVY:
204346d12f91SDave Airlie 	case DRM_FORMAT_VYUY:
204446d12f91SDave Airlie 	case DRM_FORMAT_NV12:
204546d12f91SDave Airlie 	case DRM_FORMAT_XYUV8888:
204646d12f91SDave Airlie 	case DRM_FORMAT_P010:
204746d12f91SDave Airlie 	case DRM_FORMAT_P012:
204846d12f91SDave Airlie 	case DRM_FORMAT_P016:
204946d12f91SDave Airlie 	case DRM_FORMAT_XVYU2101010:
205046d12f91SDave Airlie 		if (modifier == I915_FORMAT_MOD_Yf_TILED)
205146d12f91SDave Airlie 			return true;
205246d12f91SDave Airlie 		fallthrough;
205346d12f91SDave Airlie 	case DRM_FORMAT_C8:
205446d12f91SDave Airlie 	case DRM_FORMAT_XBGR16161616F:
205546d12f91SDave Airlie 	case DRM_FORMAT_ABGR16161616F:
205646d12f91SDave Airlie 	case DRM_FORMAT_XRGB16161616F:
205746d12f91SDave Airlie 	case DRM_FORMAT_ARGB16161616F:
205846d12f91SDave Airlie 	case DRM_FORMAT_Y210:
205946d12f91SDave Airlie 	case DRM_FORMAT_Y212:
206046d12f91SDave Airlie 	case DRM_FORMAT_Y216:
206146d12f91SDave Airlie 	case DRM_FORMAT_XVYU12_16161616:
206246d12f91SDave Airlie 	case DRM_FORMAT_XVYU16161616:
206346d12f91SDave Airlie 		if (modifier == DRM_FORMAT_MOD_LINEAR ||
206446d12f91SDave Airlie 		    modifier == I915_FORMAT_MOD_X_TILED ||
206546d12f91SDave Airlie 		    modifier == I915_FORMAT_MOD_Y_TILED)
206646d12f91SDave Airlie 			return true;
206746d12f91SDave Airlie 		fallthrough;
206846d12f91SDave Airlie 	default:
206946d12f91SDave Airlie 		return false;
207046d12f91SDave Airlie 	}
207146d12f91SDave Airlie }
207246d12f91SDave Airlie 
gen12_plane_format_mod_supported(struct drm_plane * _plane,u32 format,u64 modifier)207346d12f91SDave Airlie static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,
207446d12f91SDave Airlie 					     u32 format, u64 modifier)
207546d12f91SDave Airlie {
207646d12f91SDave Airlie 	struct intel_plane *plane = to_intel_plane(_plane);
207746d12f91SDave Airlie 
2078e2b83294SImre Deak 	if (!intel_fb_plane_supports_modifier(plane, modifier))
207946d12f91SDave Airlie 		return false;
208046d12f91SDave Airlie 
208146d12f91SDave Airlie 	switch (format) {
208246d12f91SDave Airlie 	case DRM_FORMAT_XRGB8888:
208346d12f91SDave Airlie 	case DRM_FORMAT_XBGR8888:
208446d12f91SDave Airlie 	case DRM_FORMAT_ARGB8888:
208546d12f91SDave Airlie 	case DRM_FORMAT_ABGR8888:
2086e359c47bSImre Deak 		if (intel_fb_is_ccs_modifier(modifier))
208746d12f91SDave Airlie 			return true;
208846d12f91SDave Airlie 		fallthrough;
208946d12f91SDave Airlie 	case DRM_FORMAT_YUYV:
209046d12f91SDave Airlie 	case DRM_FORMAT_YVYU:
209146d12f91SDave Airlie 	case DRM_FORMAT_UYVY:
209246d12f91SDave Airlie 	case DRM_FORMAT_VYUY:
209346d12f91SDave Airlie 	case DRM_FORMAT_NV12:
209446d12f91SDave Airlie 	case DRM_FORMAT_XYUV8888:
209546d12f91SDave Airlie 	case DRM_FORMAT_P010:
209646d12f91SDave Airlie 	case DRM_FORMAT_P012:
209746d12f91SDave Airlie 	case DRM_FORMAT_P016:
20980b2c31ddSImre Deak 		if (intel_fb_is_mc_ccs_modifier(modifier))
209946d12f91SDave Airlie 			return true;
210046d12f91SDave Airlie 		fallthrough;
210146d12f91SDave Airlie 	case DRM_FORMAT_RGB565:
210246d12f91SDave Airlie 	case DRM_FORMAT_XRGB2101010:
210346d12f91SDave Airlie 	case DRM_FORMAT_XBGR2101010:
210446d12f91SDave Airlie 	case DRM_FORMAT_ARGB2101010:
210546d12f91SDave Airlie 	case DRM_FORMAT_ABGR2101010:
210646d12f91SDave Airlie 	case DRM_FORMAT_XVYU2101010:
210746d12f91SDave Airlie 	case DRM_FORMAT_C8:
210846d12f91SDave Airlie 	case DRM_FORMAT_XBGR16161616F:
210946d12f91SDave Airlie 	case DRM_FORMAT_ABGR16161616F:
211046d12f91SDave Airlie 	case DRM_FORMAT_XRGB16161616F:
211146d12f91SDave Airlie 	case DRM_FORMAT_ARGB16161616F:
211246d12f91SDave Airlie 	case DRM_FORMAT_Y210:
211346d12f91SDave Airlie 	case DRM_FORMAT_Y212:
211446d12f91SDave Airlie 	case DRM_FORMAT_Y216:
211546d12f91SDave Airlie 	case DRM_FORMAT_XVYU12_16161616:
211646d12f91SDave Airlie 	case DRM_FORMAT_XVYU16161616:
2117072ce416SStanislav Lisovskiy 		if (!intel_fb_is_ccs_modifier(modifier))
211846d12f91SDave Airlie 			return true;
211946d12f91SDave Airlie 		fallthrough;
212046d12f91SDave Airlie 	default:
212146d12f91SDave Airlie 		return false;
212246d12f91SDave Airlie 	}
212346d12f91SDave Airlie }
212446d12f91SDave Airlie 
212546d12f91SDave Airlie static const struct drm_plane_funcs skl_plane_funcs = {
212646d12f91SDave Airlie 	.update_plane = drm_atomic_helper_update_plane,
212746d12f91SDave Airlie 	.disable_plane = drm_atomic_helper_disable_plane,
212846d12f91SDave Airlie 	.destroy = intel_plane_destroy,
212946d12f91SDave Airlie 	.atomic_duplicate_state = intel_plane_duplicate_state,
213046d12f91SDave Airlie 	.atomic_destroy_state = intel_plane_destroy_state,
213146d12f91SDave Airlie 	.format_mod_supported = skl_plane_format_mod_supported,
213246d12f91SDave Airlie };
213346d12f91SDave Airlie 
213446d12f91SDave Airlie static const struct drm_plane_funcs gen12_plane_funcs = {
213546d12f91SDave Airlie 	.update_plane = drm_atomic_helper_update_plane,
213646d12f91SDave Airlie 	.disable_plane = drm_atomic_helper_disable_plane,
213746d12f91SDave Airlie 	.destroy = intel_plane_destroy,
213846d12f91SDave Airlie 	.atomic_duplicate_state = intel_plane_duplicate_state,
213946d12f91SDave Airlie 	.atomic_destroy_state = intel_plane_destroy_state,
214046d12f91SDave Airlie 	.format_mod_supported = gen12_plane_format_mod_supported,
214146d12f91SDave Airlie };
214246d12f91SDave Airlie 
214346d12f91SDave Airlie static void
skl_plane_enable_flip_done(struct intel_plane * plane)214446d12f91SDave Airlie skl_plane_enable_flip_done(struct intel_plane *plane)
214546d12f91SDave Airlie {
214646d12f91SDave Airlie 	struct drm_i915_private *i915 = to_i915(plane->base.dev);
214746d12f91SDave Airlie 	enum pipe pipe = plane->pipe;
214846d12f91SDave Airlie 
214946d12f91SDave Airlie 	spin_lock_irq(&i915->irq_lock);
215046d12f91SDave Airlie 	bdw_enable_pipe_irq(i915, pipe, GEN9_PIPE_PLANE_FLIP_DONE(plane->id));
215146d12f91SDave Airlie 	spin_unlock_irq(&i915->irq_lock);
215246d12f91SDave Airlie }
215346d12f91SDave Airlie 
215446d12f91SDave Airlie static void
skl_plane_disable_flip_done(struct intel_plane * plane)215546d12f91SDave Airlie skl_plane_disable_flip_done(struct intel_plane *plane)
215646d12f91SDave Airlie {
215746d12f91SDave Airlie 	struct drm_i915_private *i915 = to_i915(plane->base.dev);
215846d12f91SDave Airlie 	enum pipe pipe = plane->pipe;
215946d12f91SDave Airlie 
216046d12f91SDave Airlie 	spin_lock_irq(&i915->irq_lock);
216146d12f91SDave Airlie 	bdw_disable_pipe_irq(i915, pipe, GEN9_PIPE_PLANE_FLIP_DONE(plane->id));
216246d12f91SDave Airlie 	spin_unlock_irq(&i915->irq_lock);
216346d12f91SDave Airlie }
216446d12f91SDave Airlie 
skl_plane_has_rc_ccs(struct drm_i915_private * i915,enum pipe pipe,enum plane_id plane_id)2165e2b83294SImre Deak static bool skl_plane_has_rc_ccs(struct drm_i915_private *i915,
2166e2b83294SImre Deak 				 enum pipe pipe, enum plane_id plane_id)
2167e2b83294SImre Deak {
2168f2eb43f0SJuha-Pekka Heikkila 	/* Wa_14017240301 */
2169*b3749611SMatt Roper 	if (IS_GFX_GT_IP_STEP(to_gt(i915), IP_VER(12, 70), STEP_A0, STEP_B0) ||
2170*b3749611SMatt Roper 	    IS_GFX_GT_IP_STEP(to_gt(i915), IP_VER(12, 71), STEP_A0, STEP_B0))
2171f2eb43f0SJuha-Pekka Heikkila 		return false;
2172f2eb43f0SJuha-Pekka Heikkila 
2173e2b83294SImre Deak 	/* Wa_22011186057 */
2174cc0c986aSDnyaneshwar Bhadane 	if (IS_ALDERLAKE_P(i915) && IS_DISPLAY_STEP(i915, STEP_A0, STEP_B0))
2175e2b83294SImre Deak 		return false;
2176e2b83294SImre Deak 
2177e2b83294SImre Deak 	if (DISPLAY_VER(i915) >= 11)
2178e2b83294SImre Deak 		return true;
2179e2b83294SImre Deak 
2180e2b83294SImre Deak 	if (IS_GEMINILAKE(i915))
2181e2b83294SImre Deak 		return pipe != PIPE_C;
2182e2b83294SImre Deak 
2183e2b83294SImre Deak 	return pipe != PIPE_C &&
2184e2b83294SImre Deak 		(plane_id == PLANE_PRIMARY ||
2185e2b83294SImre Deak 		 plane_id == PLANE_SPRITE0);
2186e2b83294SImre Deak }
2187e2b83294SImre Deak 
gen12_plane_has_mc_ccs(struct drm_i915_private * i915,enum plane_id plane_id)2188e2b83294SImre Deak static bool gen12_plane_has_mc_ccs(struct drm_i915_private *i915,
2189e2b83294SImre Deak 				   enum plane_id plane_id)
2190e2b83294SImre Deak {
2191da0c3e2cSImre Deak 	if (DISPLAY_VER(i915) < 12)
2192da0c3e2cSImre Deak 		return false;
2193da0c3e2cSImre Deak 
2194d1702963SMatt Roper 	/* Wa_14010477008 */
2195e2b83294SImre Deak 	if (IS_DG1(i915) || IS_ROCKETLAKE(i915) ||
219648077b0bSDnyaneshwar Bhadane 		(IS_TIGERLAKE(i915) && IS_DISPLAY_STEP(i915, STEP_A0, STEP_D0)))
2197e2b83294SImre Deak 		return false;
2198e2b83294SImre Deak 
2199e2b83294SImre Deak 	/* Wa_22011186057 */
2200cc0c986aSDnyaneshwar Bhadane 	if (IS_ALDERLAKE_P(i915) && IS_DISPLAY_STEP(i915, STEP_A0, STEP_B0))
2201e2b83294SImre Deak 		return false;
2202e2b83294SImre Deak 
22034c3afa72SMatt Roper 	/* Wa_14013215631 */
22044c3afa72SMatt Roper 	if (IS_DG2_DISPLAY_STEP(i915, STEP_A0, STEP_C0))
22054c3afa72SMatt Roper 		return false;
22064c3afa72SMatt Roper 
2207e2b83294SImre Deak 	return plane_id < PLANE_SPRITE4;
2208e2b83294SImre Deak }
2209e2b83294SImre Deak 
skl_get_plane_caps(struct drm_i915_private * i915,enum pipe pipe,enum plane_id plane_id)221010a657ddSImre Deak static u8 skl_get_plane_caps(struct drm_i915_private *i915,
221110a657ddSImre Deak 			     enum pipe pipe, enum plane_id plane_id)
221210a657ddSImre Deak {
221310a657ddSImre Deak 	u8 caps = INTEL_PLANE_CAP_TILING_X;
221410a657ddSImre Deak 
221510a657ddSImre Deak 	if (DISPLAY_VER(i915) < 13 || IS_ALDERLAKE_P(i915))
221610a657ddSImre Deak 		caps |= INTEL_PLANE_CAP_TILING_Y;
221710a657ddSImre Deak 	if (DISPLAY_VER(i915) < 12)
221810a657ddSImre Deak 		caps |= INTEL_PLANE_CAP_TILING_Yf;
2219072ce416SStanislav Lisovskiy 	if (HAS_4TILE(i915))
2220072ce416SStanislav Lisovskiy 		caps |= INTEL_PLANE_CAP_TILING_4;
222110a657ddSImre Deak 
222210a657ddSImre Deak 	if (skl_plane_has_rc_ccs(i915, pipe, plane_id)) {
222310a657ddSImre Deak 		caps |= INTEL_PLANE_CAP_CCS_RC;
222410a657ddSImre Deak 		if (DISPLAY_VER(i915) >= 12)
222510a657ddSImre Deak 			caps |= INTEL_PLANE_CAP_CCS_RC_CC;
222610a657ddSImre Deak 	}
222710a657ddSImre Deak 
222810a657ddSImre Deak 	if (gen12_plane_has_mc_ccs(i915, plane_id))
222910a657ddSImre Deak 		caps |= INTEL_PLANE_CAP_CCS_MC;
223010a657ddSImre Deak 
223110a657ddSImre Deak 	return caps;
223210a657ddSImre Deak }
223310a657ddSImre Deak 
223446d12f91SDave Airlie struct intel_plane *
skl_universal_plane_create(struct drm_i915_private * dev_priv,enum pipe pipe,enum plane_id plane_id)223546d12f91SDave Airlie skl_universal_plane_create(struct drm_i915_private *dev_priv,
223646d12f91SDave Airlie 			   enum pipe pipe, enum plane_id plane_id)
223746d12f91SDave Airlie {
223846d12f91SDave Airlie 	const struct drm_plane_funcs *plane_funcs;
223946d12f91SDave Airlie 	struct intel_plane *plane;
224046d12f91SDave Airlie 	enum drm_plane_type plane_type;
224146d12f91SDave Airlie 	unsigned int supported_rotations;
224246d12f91SDave Airlie 	unsigned int supported_csc;
224346d12f91SDave Airlie 	const u64 *modifiers;
224446d12f91SDave Airlie 	const u32 *formats;
224546d12f91SDave Airlie 	int num_formats;
224646d12f91SDave Airlie 	int ret;
224746d12f91SDave Airlie 
224846d12f91SDave Airlie 	plane = intel_plane_alloc();
224946d12f91SDave Airlie 	if (IS_ERR(plane))
225046d12f91SDave Airlie 		return plane;
225146d12f91SDave Airlie 
225246d12f91SDave Airlie 	plane->pipe = pipe;
225346d12f91SDave Airlie 	plane->id = plane_id;
225446d12f91SDave Airlie 	plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane_id);
225546d12f91SDave Airlie 
2256825bd833SVille Syrjälä 	intel_fbc_add_plane(skl_plane_fbc(dev_priv, pipe, plane_id), plane);
225746d12f91SDave Airlie 
2258005e9537SMatt Roper 	if (DISPLAY_VER(dev_priv) >= 11) {
225946d12f91SDave Airlie 		plane->min_width = icl_plane_min_width;
22600e959b4eSVidya Srinivas 		if (icl_is_hdr_plane(dev_priv, plane_id))
22610e959b4eSVidya Srinivas 			plane->max_width = icl_hdr_plane_max_width;
22620e959b4eSVidya Srinivas 		else
22630e959b4eSVidya Srinivas 			plane->max_width = icl_sdr_plane_max_width;
226446d12f91SDave Airlie 		plane->max_height = icl_plane_max_height;
22656195f850SVille Syrjälä 		plane->min_cdclk = icl_plane_min_cdclk;
22662b5a4562SMatt Roper 	} else if (DISPLAY_VER(dev_priv) >= 10) {
226746d12f91SDave Airlie 		plane->max_width = glk_plane_max_width;
226846d12f91SDave Airlie 		plane->max_height = skl_plane_max_height;
2269efc52308SVille Syrjälä 		plane->min_cdclk = glk_plane_min_cdclk;
227046d12f91SDave Airlie 	} else {
227146d12f91SDave Airlie 		plane->max_width = skl_plane_max_width;
227246d12f91SDave Airlie 		plane->max_height = skl_plane_max_height;
2273efc52308SVille Syrjälä 		plane->min_cdclk = skl_plane_min_cdclk;
227446d12f91SDave Airlie 	}
227546d12f91SDave Airlie 
227646d12f91SDave Airlie 	plane->max_stride = skl_plane_max_stride;
2277f8a005ebSVille Syrjälä 	if (DISPLAY_VER(dev_priv) >= 11) {
2278f8a005ebSVille Syrjälä 		plane->update_noarm = icl_plane_update_noarm;
2279f8a005ebSVille Syrjälä 		plane->update_arm = icl_plane_update_arm;
2280f8a005ebSVille Syrjälä 		plane->disable_arm = icl_plane_disable_arm;
2281f8a005ebSVille Syrjälä 	} else {
2282890b6ec4SVille Syrjälä 		plane->update_noarm = skl_plane_update_noarm;
22838ac80733SVille Syrjälä 		plane->update_arm = skl_plane_update_arm;
22848ac80733SVille Syrjälä 		plane->disable_arm = skl_plane_disable_arm;
2285f8a005ebSVille Syrjälä 	}
228646d12f91SDave Airlie 	plane->get_hw_state = skl_plane_get_hw_state;
228746d12f91SDave Airlie 	plane->check_plane = skl_plane_check;
228846d12f91SDave Airlie 
228946d12f91SDave Airlie 	if (plane_id == PLANE_PRIMARY) {
229093e7e61eSLucas De Marchi 		plane->need_async_flip_disable_wa = IS_DISPLAY_VER(dev_priv,
2291005e9537SMatt Roper 								   9, 10);
229246d12f91SDave Airlie 		plane->async_flip = skl_plane_async_flip;
229346d12f91SDave Airlie 		plane->enable_flip_done = skl_plane_enable_flip_done;
229446d12f91SDave Airlie 		plane->disable_flip_done = skl_plane_disable_flip_done;
229546d12f91SDave Airlie 	}
229646d12f91SDave Airlie 
2297005e9537SMatt Roper 	if (DISPLAY_VER(dev_priv) >= 11)
229846d12f91SDave Airlie 		formats = icl_get_plane_formats(dev_priv, pipe,
229946d12f91SDave Airlie 						plane_id, &num_formats);
23002b5a4562SMatt Roper 	else if (DISPLAY_VER(dev_priv) >= 10)
230146d12f91SDave Airlie 		formats = glk_get_plane_formats(dev_priv, pipe,
230246d12f91SDave Airlie 						plane_id, &num_formats);
230346d12f91SDave Airlie 	else
230446d12f91SDave Airlie 		formats = skl_get_plane_formats(dev_priv, pipe,
230546d12f91SDave Airlie 						plane_id, &num_formats);
230646d12f91SDave Airlie 
2307e2b83294SImre Deak 	if (DISPLAY_VER(dev_priv) >= 12)
230846d12f91SDave Airlie 		plane_funcs = &gen12_plane_funcs;
230946d12f91SDave Airlie 	else
231046d12f91SDave Airlie 		plane_funcs = &skl_plane_funcs;
231146d12f91SDave Airlie 
231246d12f91SDave Airlie 	if (plane_id == PLANE_PRIMARY)
231346d12f91SDave Airlie 		plane_type = DRM_PLANE_TYPE_PRIMARY;
231446d12f91SDave Airlie 	else
231546d12f91SDave Airlie 		plane_type = DRM_PLANE_TYPE_OVERLAY;
231646d12f91SDave Airlie 
231710a657ddSImre Deak 	modifiers = intel_fb_plane_get_modifiers(dev_priv,
231810a657ddSImre Deak 						 skl_get_plane_caps(dev_priv, pipe, plane_id));
2319e2b83294SImre Deak 
232046d12f91SDave Airlie 	ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
232146d12f91SDave Airlie 				       0, plane_funcs,
232246d12f91SDave Airlie 				       formats, num_formats, modifiers,
232346d12f91SDave Airlie 				       plane_type,
232446d12f91SDave Airlie 				       "plane %d%c", plane_id + 1,
232546d12f91SDave Airlie 				       pipe_name(pipe));
2326e2b83294SImre Deak 
2327e2b83294SImre Deak 	kfree(modifiers);
2328e2b83294SImre Deak 
232946d12f91SDave Airlie 	if (ret)
233046d12f91SDave Airlie 		goto fail;
233146d12f91SDave Airlie 
23321649a4ccSMatt Roper 	if (DISPLAY_VER(dev_priv) >= 13)
23331649a4ccSMatt Roper 		supported_rotations = DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
23341649a4ccSMatt Roper 	else
233546d12f91SDave Airlie 		supported_rotations =
233646d12f91SDave Airlie 			DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 |
233746d12f91SDave Airlie 			DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270;
233846d12f91SDave Airlie 
2339c988d2dcSLucas De Marchi 	if (DISPLAY_VER(dev_priv) >= 11)
234046d12f91SDave Airlie 		supported_rotations |= DRM_MODE_REFLECT_X;
234146d12f91SDave Airlie 
234246d12f91SDave Airlie 	drm_plane_create_rotation_property(&plane->base,
234346d12f91SDave Airlie 					   DRM_MODE_ROTATE_0,
234446d12f91SDave Airlie 					   supported_rotations);
234546d12f91SDave Airlie 
234646d12f91SDave Airlie 	supported_csc = BIT(DRM_COLOR_YCBCR_BT601) | BIT(DRM_COLOR_YCBCR_BT709);
234746d12f91SDave Airlie 
23482b5a4562SMatt Roper 	if (DISPLAY_VER(dev_priv) >= 10)
234946d12f91SDave Airlie 		supported_csc |= BIT(DRM_COLOR_YCBCR_BT2020);
235046d12f91SDave Airlie 
235146d12f91SDave Airlie 	drm_plane_create_color_properties(&plane->base,
235246d12f91SDave Airlie 					  supported_csc,
235346d12f91SDave Airlie 					  BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
235446d12f91SDave Airlie 					  BIT(DRM_COLOR_YCBCR_FULL_RANGE),
235546d12f91SDave Airlie 					  DRM_COLOR_YCBCR_BT709,
235646d12f91SDave Airlie 					  DRM_COLOR_YCBCR_LIMITED_RANGE);
235746d12f91SDave Airlie 
235846d12f91SDave Airlie 	drm_plane_create_alpha_property(&plane->base);
235946d12f91SDave Airlie 	drm_plane_create_blend_mode_property(&plane->base,
236046d12f91SDave Airlie 					     BIT(DRM_MODE_BLEND_PIXEL_NONE) |
236146d12f91SDave Airlie 					     BIT(DRM_MODE_BLEND_PREMULTI) |
236246d12f91SDave Airlie 					     BIT(DRM_MODE_BLEND_COVERAGE));
236346d12f91SDave Airlie 
236446d12f91SDave Airlie 	drm_plane_create_zpos_immutable_property(&plane->base, plane_id);
236546d12f91SDave Airlie 
2366005e9537SMatt Roper 	if (DISPLAY_VER(dev_priv) >= 12)
236746d12f91SDave Airlie 		drm_plane_enable_fb_damage_clips(&plane->base);
236846d12f91SDave Airlie 
2369c988d2dcSLucas De Marchi 	if (DISPLAY_VER(dev_priv) >= 11)
237046d12f91SDave Airlie 		drm_plane_create_scaling_filter_property(&plane->base,
237146d12f91SDave Airlie 						BIT(DRM_SCALING_FILTER_DEFAULT) |
237246d12f91SDave Airlie 						BIT(DRM_SCALING_FILTER_NEAREST_NEIGHBOR));
237346d12f91SDave Airlie 
2374d372ba42SJani Nikula 	intel_plane_helper_add(plane);
237546d12f91SDave Airlie 
237646d12f91SDave Airlie 	return plane;
237746d12f91SDave Airlie 
237846d12f91SDave Airlie fail:
237946d12f91SDave Airlie 	intel_plane_free(plane);
238046d12f91SDave Airlie 
238146d12f91SDave Airlie 	return ERR_PTR(ret);
238246d12f91SDave Airlie }
238346d12f91SDave Airlie 
238446d12f91SDave Airlie void
skl_get_initial_plane_config(struct intel_crtc * crtc,struct intel_initial_plane_config * plane_config)238546d12f91SDave Airlie skl_get_initial_plane_config(struct intel_crtc *crtc,
238646d12f91SDave Airlie 			     struct intel_initial_plane_config *plane_config)
238746d12f91SDave Airlie {
238846d12f91SDave Airlie 	struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state);
238946d12f91SDave Airlie 	struct drm_device *dev = crtc->base.dev;
239046d12f91SDave Airlie 	struct drm_i915_private *dev_priv = to_i915(dev);
239146d12f91SDave Airlie 	struct intel_plane *plane = to_intel_plane(crtc->base.primary);
239246d12f91SDave Airlie 	enum plane_id plane_id = plane->id;
239346d12f91SDave Airlie 	enum pipe pipe;
239446d12f91SDave Airlie 	u32 val, base, offset, stride_mult, tiling, alpha;
239546d12f91SDave Airlie 	int fourcc, pixel_format;
239646d12f91SDave Airlie 	unsigned int aligned_height;
239746d12f91SDave Airlie 	struct drm_framebuffer *fb;
239846d12f91SDave Airlie 	struct intel_framebuffer *intel_fb;
2399072ce416SStanislav Lisovskiy 	static_assert(PLANE_CTL_TILED_YF == PLANE_CTL_TILED_4);
240046d12f91SDave Airlie 
240146d12f91SDave Airlie 	if (!plane->get_hw_state(plane, &pipe))
240246d12f91SDave Airlie 		return;
240346d12f91SDave Airlie 
240446d12f91SDave Airlie 	drm_WARN_ON(dev, pipe != crtc->pipe);
240546d12f91SDave Airlie 
24064d1b53dfSVille Syrjälä 	if (crtc_state->bigjoiner_pipes) {
240746d12f91SDave Airlie 		drm_dbg_kms(&dev_priv->drm,
240846d12f91SDave Airlie 			    "Unsupported bigjoiner configuration for initial FB\n");
240946d12f91SDave Airlie 		return;
241046d12f91SDave Airlie 	}
241146d12f91SDave Airlie 
241246d12f91SDave Airlie 	intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
241346d12f91SDave Airlie 	if (!intel_fb) {
241446d12f91SDave Airlie 		drm_dbg_kms(&dev_priv->drm, "failed to alloc fb\n");
241546d12f91SDave Airlie 		return;
241646d12f91SDave Airlie 	}
241746d12f91SDave Airlie 
241846d12f91SDave Airlie 	fb = &intel_fb->base;
241946d12f91SDave Airlie 
242046d12f91SDave Airlie 	fb->dev = dev;
242146d12f91SDave Airlie 
242246d12f91SDave Airlie 	val = intel_de_read(dev_priv, PLANE_CTL(pipe, plane_id));
242346d12f91SDave Airlie 
2424005e9537SMatt Roper 	if (DISPLAY_VER(dev_priv) >= 11)
242512d7d858SVille Syrjälä 		pixel_format = val & PLANE_CTL_FORMAT_MASK_ICL;
242646d12f91SDave Airlie 	else
242712d7d858SVille Syrjälä 		pixel_format = val & PLANE_CTL_FORMAT_MASK_SKL;
242846d12f91SDave Airlie 
24292b5a4562SMatt Roper 	if (DISPLAY_VER(dev_priv) >= 10) {
243012d7d858SVille Syrjälä 		u32 color_ctl;
243112d7d858SVille Syrjälä 
243212d7d858SVille Syrjälä 		color_ctl = intel_de_read(dev_priv, PLANE_COLOR_CTL(pipe, plane_id));
243312d7d858SVille Syrjälä 		alpha = REG_FIELD_GET(PLANE_COLOR_ALPHA_MASK, color_ctl);
243446d12f91SDave Airlie 	} else {
243512d7d858SVille Syrjälä 		alpha = REG_FIELD_GET(PLANE_CTL_ALPHA_MASK, val);
243646d12f91SDave Airlie 	}
243746d12f91SDave Airlie 
243846d12f91SDave Airlie 	fourcc = skl_format_to_fourcc(pixel_format,
243946d12f91SDave Airlie 				      val & PLANE_CTL_ORDER_RGBX, alpha);
244046d12f91SDave Airlie 	fb->format = drm_format_info(fourcc);
244146d12f91SDave Airlie 
244246d12f91SDave Airlie 	tiling = val & PLANE_CTL_TILED_MASK;
244346d12f91SDave Airlie 	switch (tiling) {
244446d12f91SDave Airlie 	case PLANE_CTL_TILED_LINEAR:
244546d12f91SDave Airlie 		fb->modifier = DRM_FORMAT_MOD_LINEAR;
244646d12f91SDave Airlie 		break;
244746d12f91SDave Airlie 	case PLANE_CTL_TILED_X:
244846d12f91SDave Airlie 		plane_config->tiling = I915_TILING_X;
244946d12f91SDave Airlie 		fb->modifier = I915_FORMAT_MOD_X_TILED;
245046d12f91SDave Airlie 		break;
245146d12f91SDave Airlie 	case PLANE_CTL_TILED_Y:
245246d12f91SDave Airlie 		plane_config->tiling = I915_TILING_Y;
245346d12f91SDave Airlie 		if (val & PLANE_CTL_RENDER_DECOMPRESSION_ENABLE)
2454f2eb43f0SJuha-Pekka Heikkila 			if (DISPLAY_VER(dev_priv) >= 14)
2455f2eb43f0SJuha-Pekka Heikkila 				fb->modifier = I915_FORMAT_MOD_4_TILED_MTL_RC_CCS;
2456f2eb43f0SJuha-Pekka Heikkila 			else if (DISPLAY_VER(dev_priv) >= 12)
24574c3afa72SMatt Roper 				fb->modifier = I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS;
24584c3afa72SMatt Roper 			else
24594c3afa72SMatt Roper 				fb->modifier = I915_FORMAT_MOD_Y_TILED_CCS;
246046d12f91SDave Airlie 		else if (val & PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE)
2461f2eb43f0SJuha-Pekka Heikkila 			if (DISPLAY_VER(dev_priv) >= 14)
2462f2eb43f0SJuha-Pekka Heikkila 				fb->modifier = I915_FORMAT_MOD_4_TILED_MTL_MC_CCS;
2463f2eb43f0SJuha-Pekka Heikkila 			else
246446d12f91SDave Airlie 				fb->modifier = I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS;
246546d12f91SDave Airlie 		else
246646d12f91SDave Airlie 			fb->modifier = I915_FORMAT_MOD_Y_TILED;
246746d12f91SDave Airlie 		break;
2468072ce416SStanislav Lisovskiy 	case PLANE_CTL_TILED_YF: /* aka PLANE_CTL_TILED_4 on XE_LPD+ */
2469072ce416SStanislav Lisovskiy 		if (HAS_4TILE(dev_priv)) {
2470680025dcSJuha-Pekka Heikkilä 			u32 rc_mask = PLANE_CTL_RENDER_DECOMPRESSION_ENABLE |
2471680025dcSJuha-Pekka Heikkilä 				      PLANE_CTL_CLEAR_COLOR_DISABLE;
2472680025dcSJuha-Pekka Heikkilä 
2473680025dcSJuha-Pekka Heikkilä 			if ((val & rc_mask) == rc_mask)
24744c3afa72SMatt Roper 				fb->modifier = I915_FORMAT_MOD_4_TILED_DG2_RC_CCS;
24754c3afa72SMatt Roper 			else if (val & PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE)
24764c3afa72SMatt Roper 				fb->modifier = I915_FORMAT_MOD_4_TILED_DG2_MC_CCS;
2477680025dcSJuha-Pekka Heikkilä 			else if (val & PLANE_CTL_RENDER_DECOMPRESSION_ENABLE)
2478680025dcSJuha-Pekka Heikkilä 				fb->modifier = I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC;
24794c3afa72SMatt Roper 			else
2480072ce416SStanislav Lisovskiy 				fb->modifier = I915_FORMAT_MOD_4_TILED;
2481072ce416SStanislav Lisovskiy 		} else {
248246d12f91SDave Airlie 			if (val & PLANE_CTL_RENDER_DECOMPRESSION_ENABLE)
248346d12f91SDave Airlie 				fb->modifier = I915_FORMAT_MOD_Yf_TILED_CCS;
248446d12f91SDave Airlie 			else
248546d12f91SDave Airlie 				fb->modifier = I915_FORMAT_MOD_Yf_TILED;
2486072ce416SStanislav Lisovskiy 		}
248746d12f91SDave Airlie 		break;
248846d12f91SDave Airlie 	default:
248946d12f91SDave Airlie 		MISSING_CASE(tiling);
249046d12f91SDave Airlie 		goto error;
249146d12f91SDave Airlie 	}
249246d12f91SDave Airlie 
2493c5de2484SVille Syrjälä 	if (!dev_priv->params.enable_dpt &&
2494c5de2484SVille Syrjälä 	    intel_fb_modifier_uses_dpt(dev_priv, fb->modifier)) {
2495c5de2484SVille Syrjälä 		drm_dbg_kms(&dev_priv->drm, "DPT disabled, skipping initial FB\n");
2496c5de2484SVille Syrjälä 		goto error;
2497c5de2484SVille Syrjälä 	}
2498c5de2484SVille Syrjälä 
249946d12f91SDave Airlie 	/*
250046d12f91SDave Airlie 	 * DRM_MODE_ROTATE_ is counter clockwise to stay compatible with Xrandr
250146d12f91SDave Airlie 	 * while i915 HW rotation is clockwise, thats why this swapping.
250246d12f91SDave Airlie 	 */
250346d12f91SDave Airlie 	switch (val & PLANE_CTL_ROTATE_MASK) {
250446d12f91SDave Airlie 	case PLANE_CTL_ROTATE_0:
250546d12f91SDave Airlie 		plane_config->rotation = DRM_MODE_ROTATE_0;
250646d12f91SDave Airlie 		break;
250746d12f91SDave Airlie 	case PLANE_CTL_ROTATE_90:
250846d12f91SDave Airlie 		plane_config->rotation = DRM_MODE_ROTATE_270;
250946d12f91SDave Airlie 		break;
251046d12f91SDave Airlie 	case PLANE_CTL_ROTATE_180:
251146d12f91SDave Airlie 		plane_config->rotation = DRM_MODE_ROTATE_180;
251246d12f91SDave Airlie 		break;
251346d12f91SDave Airlie 	case PLANE_CTL_ROTATE_270:
251446d12f91SDave Airlie 		plane_config->rotation = DRM_MODE_ROTATE_90;
251546d12f91SDave Airlie 		break;
251646d12f91SDave Airlie 	}
251746d12f91SDave Airlie 
2518c988d2dcSLucas De Marchi 	if (DISPLAY_VER(dev_priv) >= 11 && val & PLANE_CTL_FLIP_HORIZONTAL)
251946d12f91SDave Airlie 		plane_config->rotation |= DRM_MODE_REFLECT_X;
252046d12f91SDave Airlie 
252146d12f91SDave Airlie 	/* 90/270 degree rotation would require extra work */
252246d12f91SDave Airlie 	if (drm_rotation_90_or_270(plane_config->rotation))
252346d12f91SDave Airlie 		goto error;
252446d12f91SDave Airlie 
252512d7d858SVille Syrjälä 	base = intel_de_read(dev_priv, PLANE_SURF(pipe, plane_id)) & PLANE_SURF_ADDR_MASK;
252646d12f91SDave Airlie 	plane_config->base = base;
252746d12f91SDave Airlie 
252846d12f91SDave Airlie 	offset = intel_de_read(dev_priv, PLANE_OFFSET(pipe, plane_id));
252947e157a5SJani Nikula 	drm_WARN_ON(&dev_priv->drm, offset != 0);
253046d12f91SDave Airlie 
253146d12f91SDave Airlie 	val = intel_de_read(dev_priv, PLANE_SIZE(pipe, plane_id));
253212d7d858SVille Syrjälä 	fb->height = REG_FIELD_GET(PLANE_HEIGHT_MASK, val) + 1;
253312d7d858SVille Syrjälä 	fb->width = REG_FIELD_GET(PLANE_WIDTH_MASK, val) + 1;
253446d12f91SDave Airlie 
253546d12f91SDave Airlie 	val = intel_de_read(dev_priv, PLANE_STRIDE(pipe, plane_id));
253646d12f91SDave Airlie 	stride_mult = skl_plane_stride_mult(fb, 0, DRM_MODE_ROTATE_0);
2537e7367af1SJuha-Pekka Heikkilä 
253812d7d858SVille Syrjälä 	fb->pitches[0] = REG_FIELD_GET(PLANE_STRIDE__MASK, val) * stride_mult;
253946d12f91SDave Airlie 
254046d12f91SDave Airlie 	aligned_height = intel_fb_align_height(fb, 0, fb->height);
254146d12f91SDave Airlie 
254246d12f91SDave Airlie 	plane_config->size = fb->pitches[0] * aligned_height;
254346d12f91SDave Airlie 
254446d12f91SDave Airlie 	drm_dbg_kms(&dev_priv->drm,
254546d12f91SDave Airlie 		    "%s/%s with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
254646d12f91SDave Airlie 		    crtc->base.name, plane->base.name, fb->width, fb->height,
254746d12f91SDave Airlie 		    fb->format->cpp[0] * 8, base, fb->pitches[0],
254846d12f91SDave Airlie 		    plane_config->size);
254946d12f91SDave Airlie 
255046d12f91SDave Airlie 	plane_config->fb = intel_fb;
255146d12f91SDave Airlie 	return;
255246d12f91SDave Airlie 
255346d12f91SDave Airlie error:
255446d12f91SDave Airlie 	kfree(intel_fb);
255546d12f91SDave Airlie }
2556