Home | History | Annotate | Line # | Download | only in display
      1 /*	$NetBSD: intel_sprite.c,v 1.6 2021/12/19 12:05:09 riastradh Exp $	*/
      2 
      3 /*
      4  * Copyright  2011 Intel Corporation
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice (including the next
     14  * paragraph) shall be included in all copies or substantial portions of the
     15  * Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     23  * SOFTWARE.
     24  *
     25  * Authors:
     26  *   Jesse Barnes <jbarnes (at) virtuousgeek.org>
     27  *
     28  * New plane/sprite handling.
     29  *
     30  * The older chips had a separate interface for programming plane related
     31  * registers; newer ones are much simpler and we can use the new DRM plane
     32  * support.
     33  */
     34 
     35 #include <sys/cdefs.h>
     36 __KERNEL_RCSID(0, "$NetBSD: intel_sprite.c,v 1.6 2021/12/19 12:05:09 riastradh Exp $");
     37 
     38 #include <drm/drm_atomic.h>
     39 #include <drm/drm_atomic_helper.h>
     40 #include <drm/drm_color_mgmt.h>
     41 #include <drm/drm_crtc.h>
     42 #include <drm/drm_fourcc.h>
     43 #include <drm/drm_plane_helper.h>
     44 #include <drm/drm_rect.h>
     45 #include <drm/i915_drm.h>
     46 
     47 #include "i915_drv.h"
     48 #include "i915_trace.h"
     49 #include "intel_atomic_plane.h"
     50 #include "intel_display_types.h"
     51 #include "intel_frontbuffer.h"
     52 #include "intel_pm.h"
     53 #include "intel_psr.h"
     54 #include "intel_sprite.h"
     55 
     56 int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
     57 			     int usecs)
     58 {
     59 	/* paranoia */
     60 	if (!adjusted_mode->crtc_htotal)
     61 		return 1;
     62 
     63 	return DIV_ROUND_UP(usecs * adjusted_mode->crtc_clock,
     64 			    1000 * adjusted_mode->crtc_htotal);
     65 }
     66 
     67 /* FIXME: We should instead only take spinlocks once for the entire update
     68  * instead of once per mmio. */
     69 #if IS_ENABLED(CONFIG_PROVE_LOCKING)
     70 #define VBLANK_EVASION_TIME_US 250
     71 #else
     72 #define VBLANK_EVASION_TIME_US 100
     73 #endif
     74 
     75 /**
     76  * intel_pipe_update_start() - start update of a set of display registers
     77  * @new_crtc_state: the new crtc state
     78  *
     79  * Mark the start of an update to pipe registers that should be updated
     80  * atomically regarding vblank. If the next vblank will happens within
     81  * the next 100 us, this function waits until the vblank passes.
     82  *
     83  * After a successful call to this function, interrupts will be disabled
     84  * until a subsequent call to intel_pipe_update_end(). That is done to
     85  * avoid random delays.
     86  */
     87 void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state)
     88 {
     89 	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
     90 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
     91 	const struct drm_display_mode *adjusted_mode = &new_crtc_state->hw.adjusted_mode;
     92 	long timeout = msecs_to_jiffies_timeout(1);
     93 	int scanline, min, max, vblank_start;
     94 	drm_waitqueue_t *wq = drm_crtc_vblank_waitqueue(&crtc->base);
     95 	int ret;
     96 	bool need_vlv_dsi_wa = (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
     97 		intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI);
     98 	u32 psr_status;
     99 
    100 	vblank_start = adjusted_mode->crtc_vblank_start;
    101 	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
    102 		vblank_start = DIV_ROUND_UP(vblank_start, 2);
    103 
    104 	/* FIXME needs to be calibrated sensibly */
    105 	min = vblank_start - intel_usecs_to_scanlines(adjusted_mode,
    106 						      VBLANK_EVASION_TIME_US);
    107 	max = vblank_start - 1;
    108 
    109 	if (min <= 0 || max <= 0)
    110 		goto irq_disable;
    111 
    112 	if (WARN_ON(drm_crtc_vblank_get(&crtc->base)))
    113 		goto irq_disable;
    114 
    115 	/*
    116 	 * Wait for psr to idle out after enabling the VBL interrupts
    117 	 * VBL interrupts will start the PSR exit and prevent a PSR
    118 	 * re-entry as well.
    119 	 */
    120 	if (intel_psr_wait_for_idle(new_crtc_state, &psr_status))
    121 		DRM_ERROR("PSR idle timed out 0x%x, atomic update may fail\n",
    122 			  psr_status);
    123 
    124 	spin_lock(&dev_priv->drm.event_lock);
    125 
    126 	crtc->debug.min_vbl = min;
    127 	crtc->debug.max_vbl = max;
    128 	trace_intel_pipe_update_start(crtc);
    129 
    130 	DRM_SPIN_TIMED_WAIT_NOINTR_UNTIL(ret, wq, &dev_priv->drm.event_lock,
    131 	    timeout,
    132 	    (scanline = intel_get_crtc_scanline(crtc),
    133 		scanline < min || scanline > max));
    134 	if (ret <= 0)
    135 		DRM_ERROR("Potential atomic update failure on pipe %c: %d\n",
    136 		    pipe_name(crtc->pipe), ret ? ret : -EWOULDBLOCK);
    137 	drm_crtc_vblank_put_locked(&crtc->base);
    138 
    139 	/*
    140 	 * On VLV/CHV DSI the scanline counter would appear to
    141 	 * increment approx. 1/3 of a scanline before start of vblank.
    142 	 * The registers still get latched at start of vblank however.
    143 	 * This means we must not write any registers on the first
    144 	 * line of vblank (since not the whole line is actually in
    145 	 * vblank). And unfortunately we can't use the interrupt to
    146 	 * wait here since it will fire too soon. We could use the
    147 	 * frame start interrupt instead since it will fire after the
    148 	 * critical scanline, but that would require more changes
    149 	 * in the interrupt code. So for now we'll just do the nasty
    150 	 * thing and poll for the bad scanline to pass us by.
    151 	 *
    152 	 * FIXME figure out if BXT+ DSI suffers from this as well
    153 	 */
    154 	while (need_vlv_dsi_wa && scanline == vblank_start)
    155 		scanline = intel_get_crtc_scanline(crtc);
    156 
    157 	crtc->debug.scanline_start = scanline;
    158 	crtc->debug.start_vbl_time = ktime_get();
    159 	crtc->debug.start_vbl_count = intel_crtc_get_vblank_counter(crtc);
    160 
    161 	trace_intel_pipe_update_vblank_evaded(crtc);
    162 	return;
    163 
    164 irq_disable:
    165 	spin_lock(&dev_priv->drm.event_lock);
    166 }
    167 
    168 /**
    169  * intel_pipe_update_end() - end update of a set of display registers
    170  * @new_crtc_state: the new crtc state
    171  *
    172  * Mark the end of an update started with intel_pipe_update_start(). This
    173  * re-enables interrupts and verifies the update was actually completed
    174  * before a vblank.
    175  */
    176 void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state)
    177 {
    178 	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
    179 	enum pipe pipe = crtc->pipe;
    180 	int scanline_end = intel_get_crtc_scanline(crtc);
    181 	u32 end_vbl_count = intel_crtc_get_vblank_counter(crtc);
    182 	ktime_t end_vbl_time = ktime_get();
    183 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
    184 
    185 	BUG_ON(!spin_is_locked(&dev_priv->drm.event_lock));
    186 
    187 	trace_intel_pipe_update_end(crtc, end_vbl_count, scanline_end);
    188 
    189 	/* We're still in the vblank-evade critical section, this can't race.
    190 	 * Would be slightly nice to just grab the vblank count and arm the
    191 	 * event outside of the critical section - the spinlock might spin for a
    192 	 * while ... */
    193 	if (new_crtc_state->uapi.event) {
    194 		WARN_ON(drm_crtc_vblank_get_locked(&crtc->base) != 0);
    195 
    196 		drm_crtc_arm_vblank_event(&crtc->base,
    197 				          new_crtc_state->uapi.event);
    198 
    199 		new_crtc_state->uapi.event = NULL;
    200 	}
    201 	spin_unlock(&dev_priv->drm.event_lock);
    202 
    203 	if (intel_vgpu_active(dev_priv))
    204 		return;
    205 
    206 	if (crtc->debug.start_vbl_count &&
    207 	    crtc->debug.start_vbl_count != end_vbl_count) {
    208 		DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u) time %"PRIdMAX" us, min %d, max %d, scanline start %d, end %d\n",
    209 			  pipe_name(pipe), crtc->debug.start_vbl_count,
    210 			  end_vbl_count,
    211 			  ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time),
    212 			  crtc->debug.min_vbl, crtc->debug.max_vbl,
    213 			  crtc->debug.scanline_start, scanline_end);
    214 	}
    215 #ifdef CONFIG_DRM_I915_DEBUG_VBLANK_EVADE
    216 	else if (ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time) >
    217 		 VBLANK_EVASION_TIME_US)
    218 		DRM_WARN("Atomic update on pipe (%c) took %lld us, max time under evasion is %u us\n",
    219 			 pipe_name(pipe),
    220 			 ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time),
    221 			 VBLANK_EVASION_TIME_US);
    222 #endif
    223 }
    224 
    225 int intel_plane_check_stride(const struct intel_plane_state *plane_state)
    226 {
    227 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
    228 	const struct drm_framebuffer *fb = plane_state->hw.fb;
    229 	unsigned int rotation = plane_state->hw.rotation;
    230 	u32 stride, max_stride;
    231 
    232 	/*
    233 	 * We ignore stride for all invisible planes that
    234 	 * can be remapped. Otherwise we could end up
    235 	 * with a false positive when the remapping didn't
    236 	 * kick in due the plane being invisible.
    237 	 */
    238 	if (intel_plane_can_remap(plane_state) &&
    239 	    !plane_state->uapi.visible)
    240 		return 0;
    241 
    242 	/* FIXME other color planes? */
    243 	stride = plane_state->color_plane[0].stride;
    244 	max_stride = plane->max_stride(plane, fb->format->format,
    245 				       fb->modifier, rotation);
    246 
    247 	if (stride > max_stride) {
    248 		DRM_DEBUG_KMS("[FB:%d] stride (%d) exceeds [PLANE:%d:%s] max stride (%d)\n",
    249 			      fb->base.id, stride,
    250 			      plane->base.base.id, plane->base.name, max_stride);
    251 		return -EINVAL;
    252 	}
    253 
    254 	return 0;
    255 }
    256 
    257 int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
    258 {
    259 	const struct drm_framebuffer *fb = plane_state->hw.fb;
    260 	struct drm_rect *src = &plane_state->uapi.src;
    261 	u32 src_x, src_y, src_w, src_h, hsub, vsub;
    262 	bool rotated = drm_rotation_90_or_270(plane_state->hw.rotation);
    263 
    264 	/*
    265 	 * Hardware doesn't handle subpixel coordinates.
    266 	 * Adjust to (macro)pixel boundary, but be careful not to
    267 	 * increase the source viewport size, because that could
    268 	 * push the downscaling factor out of bounds.
    269 	 */
    270 	src_x = src->x1 >> 16;
    271 	src_w = drm_rect_width(src) >> 16;
    272 	src_y = src->y1 >> 16;
    273 	src_h = drm_rect_height(src) >> 16;
    274 
    275 	drm_rect_init(src, src_x << 16, src_y << 16,
    276 		      src_w << 16, src_h << 16);
    277 
    278 	if (!fb->format->is_yuv)
    279 		return 0;
    280 
    281 	/* YUV specific checks */
    282 	if (!rotated) {
    283 		hsub = fb->format->hsub;
    284 		vsub = fb->format->vsub;
    285 	} else {
    286 		hsub = vsub = max(fb->format->hsub, fb->format->vsub);
    287 	}
    288 
    289 	if (src_x % hsub || src_w % hsub) {
    290 		DRM_DEBUG_KMS("src x/w (%u, %u) must be a multiple of %u for %sYUV planes\n",
    291 			      src_x, src_w, hsub, rotated ? "rotated " : "");
    292 		return -EINVAL;
    293 	}
    294 
    295 	if (src_y % vsub || src_h % vsub) {
    296 		DRM_DEBUG_KMS("src y/h (%u, %u) must be a multiple of %u for %sYUV planes\n",
    297 			      src_y, src_h, vsub, rotated ? "rotated " : "");
    298 		return -EINVAL;
    299 	}
    300 
    301 	return 0;
    302 }
    303 
    304 bool icl_is_hdr_plane(struct drm_i915_private *dev_priv, enum plane_id plane_id)
    305 {
    306 	return INTEL_GEN(dev_priv) >= 11 &&
    307 		icl_hdr_plane_mask() & BIT(plane_id);
    308 }
    309 
    310 static void
    311 skl_plane_ratio(const struct intel_crtc_state *crtc_state,
    312 		const struct intel_plane_state *plane_state,
    313 		unsigned int *num, unsigned int *den)
    314 {
    315 	struct drm_i915_private *dev_priv = to_i915(plane_state->uapi.plane->dev);
    316 	const struct drm_framebuffer *fb = plane_state->hw.fb;
    317 
    318 	if (fb->format->cpp[0] == 8) {
    319 		if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) {
    320 			*num = 10;
    321 			*den = 8;
    322 		} else {
    323 			*num = 9;
    324 			*den = 8;
    325 		}
    326 	} else {
    327 		*num = 1;
    328 		*den = 1;
    329 	}
    330 }
    331 
    332 static int skl_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
    333 			       const struct intel_plane_state *plane_state)
    334 {
    335 	struct drm_i915_private *dev_priv = to_i915(plane_state->uapi.plane->dev);
    336 	unsigned int pixel_rate = crtc_state->pixel_rate;
    337 	unsigned int src_w, src_h, dst_w, dst_h;
    338 	unsigned int num, den;
    339 
    340 	skl_plane_ratio(crtc_state, plane_state, &num, &den);
    341 
    342 	/* two pixels per clock on glk+ */
    343 	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
    344 		den *= 2;
    345 
    346 	src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
    347 	src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
    348 	dst_w = drm_rect_width(&plane_state->uapi.dst);
    349 	dst_h = drm_rect_height(&plane_state->uapi.dst);
    350 
    351 	/* Downscaling limits the maximum pixel rate */
    352 	dst_w = min(src_w, dst_w);
    353 	dst_h = min(src_h, dst_h);
    354 
    355 	return DIV64_U64_ROUND_UP(mul_u32_u32(pixel_rate * num, src_w * src_h),
    356 				  mul_u32_u32(den, dst_w * dst_h));
    357 }
    358 
    359 static unsigned int
    360 skl_plane_max_stride(struct intel_plane *plane,
    361 		     u32 pixel_format, u64 modifier,
    362 		     unsigned int rotation)
    363 {
    364 	const struct drm_format_info *info = drm_format_info(pixel_format);
    365 	int cpp = info->cpp[0];
    366 
    367 	/*
    368 	 * "The stride in bytes must not exceed the
    369 	 * of the size of 8K pixels and 32K bytes."
    370 	 */
    371 	if (drm_rotation_90_or_270(rotation))
    372 		return min(8192, 32768 / cpp);
    373 	else
    374 		return min(8192 * cpp, 32768);
    375 }
    376 
    377 static void
    378 skl_program_scaler(struct intel_plane *plane,
    379 		   const struct intel_crtc_state *crtc_state,
    380 		   const struct intel_plane_state *plane_state)
    381 {
    382 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
    383 	const struct drm_framebuffer *fb = plane_state->hw.fb;
    384 	enum pipe pipe = plane->pipe;
    385 	int scaler_id = plane_state->scaler_id;
    386 	const struct intel_scaler *scaler =
    387 		&crtc_state->scaler_state.scalers[scaler_id];
    388 	int crtc_x = plane_state->uapi.dst.x1;
    389 	int crtc_y = plane_state->uapi.dst.y1;
    390 	u32 crtc_w = drm_rect_width(&plane_state->uapi.dst);
    391 	u32 crtc_h = drm_rect_height(&plane_state->uapi.dst);
    392 	u16 y_hphase, uv_rgb_hphase;
    393 	u16 y_vphase, uv_rgb_vphase;
    394 	int hscale, vscale;
    395 
    396 	hscale = drm_rect_calc_hscale(&plane_state->uapi.src,
    397 				      &plane_state->uapi.dst,
    398 				      0, INT_MAX);
    399 	vscale = drm_rect_calc_vscale(&plane_state->uapi.src,
    400 				      &plane_state->uapi.dst,
    401 				      0, INT_MAX);
    402 
    403 	/* TODO: handle sub-pixel coordinates */
    404 	if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) &&
    405 	    !icl_is_hdr_plane(dev_priv, plane->id)) {
    406 		y_hphase = skl_scaler_calc_phase(1, hscale, false);
    407 		y_vphase = skl_scaler_calc_phase(1, vscale, false);
    408 
    409 		/* MPEG2 chroma siting convention */
    410 		uv_rgb_hphase = skl_scaler_calc_phase(2, hscale, true);
    411 		uv_rgb_vphase = skl_scaler_calc_phase(2, vscale, false);
    412 	} else {
    413 		/* not used */
    414 		y_hphase = 0;
    415 		y_vphase = 0;
    416 
    417 		uv_rgb_hphase = skl_scaler_calc_phase(1, hscale, false);
    418 		uv_rgb_vphase = skl_scaler_calc_phase(1, vscale, false);
    419 	}
    420 
    421 	I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id),
    422 		      PS_SCALER_EN | PS_PLANE_SEL(plane->id) | scaler->mode);
    423 	I915_WRITE_FW(SKL_PS_VPHASE(pipe, scaler_id),
    424 		      PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase));
    425 	I915_WRITE_FW(SKL_PS_HPHASE(pipe, scaler_id),
    426 		      PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase));
    427 	I915_WRITE_FW(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y);
    428 	I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id), (crtc_w << 16) | crtc_h);
    429 }
    430 
    431 /* Preoffset values for YUV to RGB Conversion */
    432 #define PREOFF_YUV_TO_RGB_HI		0x1800
    433 #define PREOFF_YUV_TO_RGB_ME		0x1F00
    434 #define PREOFF_YUV_TO_RGB_LO		0x1800
    435 
    436 #define  ROFF(x)          (((x) & 0xffff) << 16)
    437 #define  GOFF(x)          (((x) & 0xffff) << 0)
    438 #define  BOFF(x)          (((x) & 0xffff) << 16)
    439 
    440 static void
    441 icl_program_input_csc(struct intel_plane *plane,
    442 		      const struct intel_crtc_state *crtc_state,
    443 		      const struct intel_plane_state *plane_state)
    444 {
    445 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
    446 	enum pipe pipe = plane->pipe;
    447 	enum plane_id plane_id = plane->id;
    448 
    449 	static const u16 input_csc_matrix[][9] = {
    450 		/*
    451 		 * BT.601 full range YCbCr -> full range RGB
    452 		 * The matrix required is :
    453 		 * [1.000, 0.000, 1.371,
    454 		 *  1.000, -0.336, -0.698,
    455 		 *  1.000, 1.732, 0.0000]
    456 		 */
    457 		[DRM_COLOR_YCBCR_BT601] = {
    458 			0x7AF8, 0x7800, 0x0,
    459 			0x8B28, 0x7800, 0x9AC0,
    460 			0x0, 0x7800, 0x7DD8,
    461 		},
    462 		/*
    463 		 * BT.709 full range YCbCr -> full range RGB
    464 		 * The matrix required is :
    465 		 * [1.000, 0.000, 1.574,
    466 		 *  1.000, -0.187, -0.468,
    467 		 *  1.000, 1.855, 0.0000]
    468 		 */
    469 		[DRM_COLOR_YCBCR_BT709] = {
    470 			0x7C98, 0x7800, 0x0,
    471 			0x9EF8, 0x7800, 0xAC00,
    472 			0x0, 0x7800,  0x7ED8,
    473 		},
    474 		/*
    475 		 * BT.2020 full range YCbCr -> full range RGB
    476 		 * The matrix required is :
    477 		 * [1.000, 0.000, 1.474,
    478 		 *  1.000, -0.1645, -0.5713,
    479 		 *  1.000, 1.8814, 0.0000]
    480 		 */
    481 		[DRM_COLOR_YCBCR_BT2020] = {
    482 			0x7BC8, 0x7800, 0x0,
    483 			0x8928, 0x7800, 0xAA88,
    484 			0x0, 0x7800, 0x7F10,
    485 		},
    486 	};
    487 
    488 	/* Matrix for Limited Range to Full Range Conversion */
    489 	static const u16 input_csc_matrix_lr[][9] = {
    490 		/*
    491 		 * BT.601 Limted range YCbCr -> full range RGB
    492 		 * The matrix required is :
    493 		 * [1.164384, 0.000, 1.596027,
    494 		 *  1.164384, -0.39175, -0.812813,
    495 		 *  1.164384, 2.017232, 0.0000]
    496 		 */
    497 		[DRM_COLOR_YCBCR_BT601] = {
    498 			0x7CC8, 0x7950, 0x0,
    499 			0x8D00, 0x7950, 0x9C88,
    500 			0x0, 0x7950, 0x6810,
    501 		},
    502 		/*
    503 		 * BT.709 Limited range YCbCr -> full range RGB
    504 		 * The matrix required is :
    505 		 * [1.164384, 0.000, 1.792741,
    506 		 *  1.164384, -0.213249, -0.532909,
    507 		 *  1.164384, 2.112402, 0.0000]
    508 		 */
    509 		[DRM_COLOR_YCBCR_BT709] = {
    510 			0x7E58, 0x7950, 0x0,
    511 			0x8888, 0x7950, 0xADA8,
    512 			0x0, 0x7950,  0x6870,
    513 		},
    514 		/*
    515 		 * BT.2020 Limited range YCbCr -> full range RGB
    516 		 * The matrix required is :
    517 		 * [1.164, 0.000, 1.678,
    518 		 *  1.164, -0.1873, -0.6504,
    519 		 *  1.164, 2.1417, 0.0000]
    520 		 */
    521 		[DRM_COLOR_YCBCR_BT2020] = {
    522 			0x7D70, 0x7950, 0x0,
    523 			0x8A68, 0x7950, 0xAC00,
    524 			0x0, 0x7950, 0x6890,
    525 		},
    526 	};
    527 	const u16 *csc;
    528 
    529 	if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
    530 		csc = input_csc_matrix[plane_state->hw.color_encoding];
    531 	else
    532 		csc = input_csc_matrix_lr[plane_state->hw.color_encoding];
    533 
    534 	I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 0), ROFF(csc[0]) |
    535 		      GOFF(csc[1]));
    536 	I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 1), BOFF(csc[2]));
    537 	I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 2), ROFF(csc[3]) |
    538 		      GOFF(csc[4]));
    539 	I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 3), BOFF(csc[5]));
    540 	I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 4), ROFF(csc[6]) |
    541 		      GOFF(csc[7]));
    542 	I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 5), BOFF(csc[8]));
    543 
    544 	I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 0),
    545 		      PREOFF_YUV_TO_RGB_HI);
    546 	if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
    547 		I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1), 0);
    548 	else
    549 		I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1),
    550 			      PREOFF_YUV_TO_RGB_ME);
    551 	I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 2),
    552 		      PREOFF_YUV_TO_RGB_LO);
    553 	I915_WRITE_FW(PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 0), 0x0);
    554 	I915_WRITE_FW(PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 1), 0x0);
    555 	I915_WRITE_FW(PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 2), 0x0);
    556 }
    557 
    558 static void
    559 skl_program_plane(struct intel_plane *plane,
    560 		  const struct intel_crtc_state *crtc_state,
    561 		  const struct intel_plane_state *plane_state,
    562 		  int color_plane)
    563 {
    564 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
    565 	enum plane_id plane_id = plane->id;
    566 	enum pipe pipe = plane->pipe;
    567 	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
    568 	u32 surf_addr = plane_state->color_plane[color_plane].offset;
    569 	u32 stride = skl_plane_stride(plane_state, color_plane);
    570 	const struct drm_framebuffer *fb = plane_state->hw.fb;
    571 	int aux_plane = intel_main_to_aux_plane(fb, color_plane);
    572 	u32 aux_dist = plane_state->color_plane[aux_plane].offset - surf_addr;
    573 	u32 aux_stride = skl_plane_stride(plane_state, aux_plane);
    574 	int crtc_x = plane_state->uapi.dst.x1;
    575 	int crtc_y = plane_state->uapi.dst.y1;
    576 	u32 x = plane_state->color_plane[color_plane].x;
    577 	u32 y = plane_state->color_plane[color_plane].y;
    578 	u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
    579 	u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
    580 	u8 alpha = plane_state->hw.alpha >> 8;
    581 	u32 plane_color_ctl = 0;
    582 	unsigned long irqflags;
    583 	u32 keymsk, keymax;
    584 	u32 plane_ctl = plane_state->ctl;
    585 
    586 	plane_ctl |= skl_plane_ctl_crtc(crtc_state);
    587 
    588 	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
    589 		plane_color_ctl = plane_state->color_ctl |
    590 			glk_plane_color_ctl_crtc(crtc_state);
    591 
    592 	/* Sizes are 0 based */
    593 	src_w--;
    594 	src_h--;
    595 
    596 	keymax = (key->max_value & 0xffffff) | PLANE_KEYMAX_ALPHA(alpha);
    597 
    598 	keymsk = key->channel_mask & 0x7ffffff;
    599 	if (alpha < 0xff)
    600 		keymsk |= PLANE_KEYMSK_ALPHA_ENABLE;
    601 
    602 	/* The scaler will handle the output position */
    603 	if (plane_state->scaler_id >= 0) {
    604 		crtc_x = 0;
    605 		crtc_y = 0;
    606 	}
    607 
    608 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
    609 
    610 	I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride);
    611 	I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x);
    612 	I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w);
    613 
    614 	if (INTEL_GEN(dev_priv) < 12)
    615 		aux_dist |= aux_stride;
    616 	I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id), aux_dist);
    617 
    618 	if (icl_is_hdr_plane(dev_priv, plane_id))
    619 		I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), plane_state->cus_ctl);
    620 
    621 	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
    622 		I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id), plane_color_ctl);
    623 
    624 	if (fb->format->is_yuv && icl_is_hdr_plane(dev_priv, plane_id))
    625 		icl_program_input_csc(plane, crtc_state, plane_state);
    626 
    627 	skl_write_plane_wm(plane, crtc_state);
    628 
    629 	I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
    630 	I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk);
    631 	I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax);
    632 
    633 	I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x);
    634 
    635 	if (INTEL_GEN(dev_priv) < 11)
    636 		I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
    637 			      (plane_state->color_plane[1].y << 16) |
    638 			      plane_state->color_plane[1].x);
    639 
    640 	/*
    641 	 * The control register self-arms if the plane was previously
    642 	 * disabled. Try to make the plane enable atomic by writing
    643 	 * the control register just before the surface register.
    644 	 */
    645 	I915_WRITE_FW(PLANE_CTL(pipe, plane_id), plane_ctl);
    646 	I915_WRITE_FW(PLANE_SURF(pipe, plane_id),
    647 		      intel_plane_ggtt_offset(plane_state) + surf_addr);
    648 
    649 	if (plane_state->scaler_id >= 0)
    650 		skl_program_scaler(plane, crtc_state, plane_state);
    651 
    652 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
    653 }
    654 
    655 static void
    656 skl_update_plane(struct intel_plane *plane,
    657 		 const struct intel_crtc_state *crtc_state,
    658 		 const struct intel_plane_state *plane_state)
    659 {
    660 	int color_plane = 0;
    661 
    662 	if (plane_state->planar_linked_plane && !plane_state->planar_slave)
    663 		/* Program the UV plane on planar master */
    664 		color_plane = 1;
    665 
    666 	skl_program_plane(plane, crtc_state, plane_state, color_plane);
    667 }
    668 static void
    669 skl_disable_plane(struct intel_plane *plane,
    670 		  const struct intel_crtc_state *crtc_state)
    671 {
    672 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
    673 	enum plane_id plane_id = plane->id;
    674 	enum pipe pipe = plane->pipe;
    675 	unsigned long irqflags;
    676 
    677 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
    678 
    679 	if (icl_is_hdr_plane(dev_priv, plane_id))
    680 		I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), 0);
    681 
    682 	skl_write_plane_wm(plane, crtc_state);
    683 
    684 	I915_WRITE_FW(PLANE_CTL(pipe, plane_id), 0);
    685 	I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 0);
    686 
    687 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
    688 }
    689 
    690 static bool
    691 skl_plane_get_hw_state(struct intel_plane *plane,
    692 		       enum pipe *pipe)
    693 {
    694 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
    695 	enum intel_display_power_domain power_domain;
    696 	enum plane_id plane_id = plane->id;
    697 	intel_wakeref_t wakeref;
    698 	bool ret;
    699 
    700 	power_domain = POWER_DOMAIN_PIPE(plane->pipe);
    701 	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
    702 	if (!wakeref)
    703 		return false;
    704 
    705 	ret = I915_READ(PLANE_CTL(plane->pipe, plane_id)) & PLANE_CTL_ENABLE;
    706 
    707 	*pipe = plane->pipe;
    708 
    709 	intel_display_power_put(dev_priv, power_domain, wakeref);
    710 
    711 	return ret;
    712 }
    713 
    714 static void i9xx_plane_linear_gamma(u16 gamma[8])
    715 {
    716 	/* The points are not evenly spaced. */
    717 	static const u8 in[8] = { 0, 1, 2, 4, 8, 16, 24, 32 };
    718 	int i;
    719 
    720 	for (i = 0; i < 8; i++)
    721 		gamma[i] = (in[i] << 8) / 32;
    722 }
    723 
    724 static void
    725 chv_update_csc(const struct intel_plane_state *plane_state)
    726 {
    727 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
    728 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
    729 	const struct drm_framebuffer *fb = plane_state->hw.fb;
    730 	enum plane_id plane_id = plane->id;
    731 	/*
    732 	 * |r|   | c0 c1 c2 |   |cr|
    733 	 * |g| = | c3 c4 c5 | x |y |
    734 	 * |b|   | c6 c7 c8 |   |cb|
    735 	 *
    736 	 * Coefficients are s3.12.
    737 	 *
    738 	 * Cb and Cr apparently come in as signed already, and
    739 	 * we always get full range data in on account of CLRC0/1.
    740 	 */
    741 	static const s16 csc_matrix[][9] = {
    742 		/* BT.601 full range YCbCr -> full range RGB */
    743 		[DRM_COLOR_YCBCR_BT601] = {
    744 			 5743, 4096,     0,
    745 			-2925, 4096, -1410,
    746 			    0, 4096,  7258,
    747 		},
    748 		/* BT.709 full range YCbCr -> full range RGB */
    749 		[DRM_COLOR_YCBCR_BT709] = {
    750 			 6450, 4096,     0,
    751 			-1917, 4096,  -767,
    752 			    0, 4096,  7601,
    753 		},
    754 	};
    755 	const s16 *csc = csc_matrix[plane_state->hw.color_encoding];
    756 
    757 	/* Seems RGB data bypasses the CSC always */
    758 	if (!fb->format->is_yuv)
    759 		return;
    760 
    761 	I915_WRITE_FW(SPCSCYGOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
    762 	I915_WRITE_FW(SPCSCCBOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
    763 	I915_WRITE_FW(SPCSCCROFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
    764 
    765 	I915_WRITE_FW(SPCSCC01(plane_id), SPCSC_C1(csc[1]) | SPCSC_C0(csc[0]));
    766 	I915_WRITE_FW(SPCSCC23(plane_id), SPCSC_C1(csc[3]) | SPCSC_C0(csc[2]));
    767 	I915_WRITE_FW(SPCSCC45(plane_id), SPCSC_C1(csc[5]) | SPCSC_C0(csc[4]));
    768 	I915_WRITE_FW(SPCSCC67(plane_id), SPCSC_C1(csc[7]) | SPCSC_C0(csc[6]));
    769 	I915_WRITE_FW(SPCSCC8(plane_id), SPCSC_C0(csc[8]));
    770 
    771 	I915_WRITE_FW(SPCSCYGICLAMP(plane_id), SPCSC_IMAX(1023) | SPCSC_IMIN(0));
    772 	I915_WRITE_FW(SPCSCCBICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512));
    773 	I915_WRITE_FW(SPCSCCRICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512));
    774 
    775 	I915_WRITE_FW(SPCSCYGOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
    776 	I915_WRITE_FW(SPCSCCBOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
    777 	I915_WRITE_FW(SPCSCCROCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
    778 }
    779 
    780 #define SIN_0 0
    781 #define COS_0 1
    782 
    783 static void
    784 vlv_update_clrc(const struct intel_plane_state *plane_state)
    785 {
    786 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
    787 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
    788 	const struct drm_framebuffer *fb = plane_state->hw.fb;
    789 	enum pipe pipe = plane->pipe;
    790 	enum plane_id plane_id = plane->id;
    791 	int contrast, brightness, sh_scale, sh_sin, sh_cos;
    792 
    793 	if (fb->format->is_yuv &&
    794 	    plane_state->hw.color_range == DRM_COLOR_YCBCR_LIMITED_RANGE) {
    795 		/*
    796 		 * Expand limited range to full range:
    797 		 * Contrast is applied first and is used to expand Y range.
    798 		 * Brightness is applied second and is used to remove the
    799 		 * offset from Y. Saturation/hue is used to expand CbCr range.
    800 		 */
    801 		contrast = DIV_ROUND_CLOSEST(255 << 6, 235 - 16);
    802 		brightness = -DIV_ROUND_CLOSEST(16 * 255, 235 - 16);
    803 		sh_scale = DIV_ROUND_CLOSEST(128 << 7, 240 - 128);
    804 		sh_sin = SIN_0 * sh_scale;
    805 		sh_cos = COS_0 * sh_scale;
    806 	} else {
    807 		/* Pass-through everything. */
    808 		contrast = 1 << 6;
    809 		brightness = 0;
    810 		sh_scale = 1 << 7;
    811 		sh_sin = SIN_0 * sh_scale;
    812 		sh_cos = COS_0 * sh_scale;
    813 	}
    814 
    815 	/* FIXME these register are single buffered :( */
    816 	I915_WRITE_FW(SPCLRC0(pipe, plane_id),
    817 		      SP_CONTRAST(contrast) | SP_BRIGHTNESS(brightness));
    818 	I915_WRITE_FW(SPCLRC1(pipe, plane_id),
    819 		      SP_SH_SIN(sh_sin) | SP_SH_COS(sh_cos));
    820 }
    821 
    822 static void
    823 vlv_plane_ratio(const struct intel_crtc_state *crtc_state,
    824 		const struct intel_plane_state *plane_state,
    825 		unsigned int *num, unsigned int *den)
    826 {
    827 	u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR);
    828 	const struct drm_framebuffer *fb = plane_state->hw.fb;
    829 	unsigned int cpp = fb->format->cpp[0];
    830 
    831 	/*
    832 	 * VLV bspec only considers cases where all three planes are
    833 	 * enabled, and cases where the primary and one sprite is enabled.
    834 	 * Let's assume the case with just two sprites enabled also
    835 	 * maps to the latter case.
    836 	 */
    837 	if (hweight8(active_planes) == 3) {
    838 		switch (cpp) {
    839 		case 8:
    840 			*num = 11;
    841 			*den = 8;
    842 			break;
    843 		case 4:
    844 			*num = 18;
    845 			*den = 16;
    846 			break;
    847 		default:
    848 			*num = 1;
    849 			*den = 1;
    850 			break;
    851 		}
    852 	} else if (hweight8(active_planes) == 2) {
    853 		switch (cpp) {
    854 		case 8:
    855 			*num = 10;
    856 			*den = 8;
    857 			break;
    858 		case 4:
    859 			*num = 17;
    860 			*den = 16;
    861 			break;
    862 		default:
    863 			*num = 1;
    864 			*den = 1;
    865 			break;
    866 		}
    867 	} else {
    868 		switch (cpp) {
    869 		case 8:
    870 			*num = 10;
    871 			*den = 8;
    872 			break;
    873 		default:
    874 			*num = 1;
    875 			*den = 1;
    876 			break;
    877 		}
    878 	}
    879 }
    880 
    881 int vlv_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
    882 			const struct intel_plane_state *plane_state)
    883 {
    884 	unsigned int pixel_rate;
    885 	unsigned int num, den;
    886 
    887 	/*
    888 	 * Note that crtc_state->pixel_rate accounts for both
    889 	 * horizontal and vertical panel fitter downscaling factors.
    890 	 * Pre-HSW bspec tells us to only consider the horizontal
    891 	 * downscaling factor here. We ignore that and just consider
    892 	 * both for simplicity.
    893 	 */
    894 	pixel_rate = crtc_state->pixel_rate;
    895 
    896 	vlv_plane_ratio(crtc_state, plane_state, &num, &den);
    897 
    898 	return DIV_ROUND_UP(pixel_rate * num, den);
    899 }
    900 
    901 static u32 vlv_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
    902 {
    903 	u32 sprctl = 0;
    904 
    905 	if (crtc_state->gamma_enable)
    906 		sprctl |= SP_GAMMA_ENABLE;
    907 
    908 	return sprctl;
    909 }
    910 
    911 static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state,
    912 			  const struct intel_plane_state *plane_state)
    913 {
    914 	const struct drm_framebuffer *fb = plane_state->hw.fb;
    915 	unsigned int rotation = plane_state->hw.rotation;
    916 	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
    917 	u32 sprctl;
    918 
    919 	sprctl = SP_ENABLE;
    920 
    921 	switch (fb->format->format) {
    922 	case DRM_FORMAT_YUYV:
    923 		sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV;
    924 		break;
    925 	case DRM_FORMAT_YVYU:
    926 		sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU;
    927 		break;
    928 	case DRM_FORMAT_UYVY:
    929 		sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY;
    930 		break;
    931 	case DRM_FORMAT_VYUY:
    932 		sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY;
    933 		break;
    934 	case DRM_FORMAT_C8:
    935 		sprctl |= SP_FORMAT_8BPP;
    936 		break;
    937 	case DRM_FORMAT_RGB565:
    938 		sprctl |= SP_FORMAT_BGR565;
    939 		break;
    940 	case DRM_FORMAT_XRGB8888:
    941 		sprctl |= SP_FORMAT_BGRX8888;
    942 		break;
    943 	case DRM_FORMAT_ARGB8888:
    944 		sprctl |= SP_FORMAT_BGRA8888;
    945 		break;
    946 	case DRM_FORMAT_XBGR2101010:
    947 		sprctl |= SP_FORMAT_RGBX1010102;
    948 		break;
    949 	case DRM_FORMAT_ABGR2101010:
    950 		sprctl |= SP_FORMAT_RGBA1010102;
    951 		break;
    952 	case DRM_FORMAT_XRGB2101010:
    953 		sprctl |= SP_FORMAT_BGRX1010102;
    954 		break;
    955 	case DRM_FORMAT_ARGB2101010:
    956 		sprctl |= SP_FORMAT_BGRA1010102;
    957 		break;
    958 	case DRM_FORMAT_XBGR8888:
    959 		sprctl |= SP_FORMAT_RGBX8888;
    960 		break;
    961 	case DRM_FORMAT_ABGR8888:
    962 		sprctl |= SP_FORMAT_RGBA8888;
    963 		break;
    964 	default:
    965 		MISSING_CASE(fb->format->format);
    966 		return 0;
    967 	}
    968 
    969 	if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709)
    970 		sprctl |= SP_YUV_FORMAT_BT709;
    971 
    972 	if (fb->modifier == I915_FORMAT_MOD_X_TILED)
    973 		sprctl |= SP_TILED;
    974 
    975 	if (rotation & DRM_MODE_ROTATE_180)
    976 		sprctl |= SP_ROTATE_180;
    977 
    978 	if (rotation & DRM_MODE_REFLECT_X)
    979 		sprctl |= SP_MIRROR;
    980 
    981 	if (key->flags & I915_SET_COLORKEY_SOURCE)
    982 		sprctl |= SP_SOURCE_KEY;
    983 
    984 	return sprctl;
    985 }
    986 
    987 static void vlv_update_gamma(const struct intel_plane_state *plane_state)
    988 {
    989 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
    990 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
    991 	const struct drm_framebuffer *fb = plane_state->hw.fb;
    992 	enum pipe pipe = plane->pipe;
    993 	enum plane_id plane_id = plane->id;
    994 	u16 gamma[8];
    995 	int i;
    996 
    997 	/* Seems RGB data bypasses the gamma always */
    998 	if (!fb->format->is_yuv)
    999 		return;
   1000 
   1001 	i9xx_plane_linear_gamma(gamma);
   1002 
   1003 	/* FIXME these register are single buffered :( */
   1004 	/* The two end points are implicit (0.0 and 1.0) */
   1005 	for (i = 1; i < 8 - 1; i++)
   1006 		I915_WRITE_FW(SPGAMC(pipe, plane_id, i - 1),
   1007 			      gamma[i] << 16 |
   1008 			      gamma[i] << 8 |
   1009 			      gamma[i]);
   1010 }
   1011 
   1012 static void
   1013 vlv_update_plane(struct intel_plane *plane,
   1014 		 const struct intel_crtc_state *crtc_state,
   1015 		 const struct intel_plane_state *plane_state)
   1016 {
   1017 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   1018 	enum pipe pipe = plane->pipe;
   1019 	enum plane_id plane_id = plane->id;
   1020 	u32 sprsurf_offset = plane_state->color_plane[0].offset;
   1021 	u32 linear_offset;
   1022 	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
   1023 	int crtc_x = plane_state->uapi.dst.x1;
   1024 	int crtc_y = plane_state->uapi.dst.y1;
   1025 	u32 crtc_w = drm_rect_width(&plane_state->uapi.dst);
   1026 	u32 crtc_h = drm_rect_height(&plane_state->uapi.dst);
   1027 	u32 x = plane_state->color_plane[0].x;
   1028 	u32 y = plane_state->color_plane[0].y;
   1029 	unsigned long irqflags;
   1030 	u32 sprctl;
   1031 
   1032 	sprctl = plane_state->ctl | vlv_sprite_ctl_crtc(crtc_state);
   1033 
   1034 	/* Sizes are 0 based */
   1035 	crtc_w--;
   1036 	crtc_h--;
   1037 
   1038 	linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
   1039 
   1040 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
   1041 
   1042 	I915_WRITE_FW(SPSTRIDE(pipe, plane_id),
   1043 		      plane_state->color_plane[0].stride);
   1044 	I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x);
   1045 	I915_WRITE_FW(SPSIZE(pipe, plane_id), (crtc_h << 16) | crtc_w);
   1046 	I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0);
   1047 
   1048 	if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B)
   1049 		chv_update_csc(plane_state);
   1050 
   1051 	if (key->flags) {
   1052 		I915_WRITE_FW(SPKEYMINVAL(pipe, plane_id), key->min_value);
   1053 		I915_WRITE_FW(SPKEYMSK(pipe, plane_id), key->channel_mask);
   1054 		I915_WRITE_FW(SPKEYMAXVAL(pipe, plane_id), key->max_value);
   1055 	}
   1056 
   1057 	I915_WRITE_FW(SPLINOFF(pipe, plane_id), linear_offset);
   1058 	I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x);
   1059 
   1060 	/*
   1061 	 * The control register self-arms if the plane was previously
   1062 	 * disabled. Try to make the plane enable atomic by writing
   1063 	 * the control register just before the surface register.
   1064 	 */
   1065 	I915_WRITE_FW(SPCNTR(pipe, plane_id), sprctl);
   1066 	I915_WRITE_FW(SPSURF(pipe, plane_id),
   1067 		      intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
   1068 
   1069 	vlv_update_clrc(plane_state);
   1070 	vlv_update_gamma(plane_state);
   1071 
   1072 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
   1073 }
   1074 
   1075 static void
   1076 vlv_disable_plane(struct intel_plane *plane,
   1077 		  const struct intel_crtc_state *crtc_state)
   1078 {
   1079 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   1080 	enum pipe pipe = plane->pipe;
   1081 	enum plane_id plane_id = plane->id;
   1082 	unsigned long irqflags;
   1083 
   1084 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
   1085 
   1086 	I915_WRITE_FW(SPCNTR(pipe, plane_id), 0);
   1087 	I915_WRITE_FW(SPSURF(pipe, plane_id), 0);
   1088 
   1089 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
   1090 }
   1091 
   1092 static bool
   1093 vlv_plane_get_hw_state(struct intel_plane *plane,
   1094 		       enum pipe *pipe)
   1095 {
   1096 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   1097 	enum intel_display_power_domain power_domain;
   1098 	enum plane_id plane_id = plane->id;
   1099 	intel_wakeref_t wakeref;
   1100 	bool ret;
   1101 
   1102 	power_domain = POWER_DOMAIN_PIPE(plane->pipe);
   1103 	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
   1104 	if (!wakeref)
   1105 		return false;
   1106 
   1107 	ret = I915_READ(SPCNTR(plane->pipe, plane_id)) & SP_ENABLE;
   1108 
   1109 	*pipe = plane->pipe;
   1110 
   1111 	intel_display_power_put(dev_priv, power_domain, wakeref);
   1112 
   1113 	return ret;
   1114 }
   1115 
   1116 static void ivb_plane_ratio(const struct intel_crtc_state *crtc_state,
   1117 			    const struct intel_plane_state *plane_state,
   1118 			    unsigned int *num, unsigned int *den)
   1119 {
   1120 	u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR);
   1121 	const struct drm_framebuffer *fb = plane_state->hw.fb;
   1122 	unsigned int cpp = fb->format->cpp[0];
   1123 
   1124 	if (hweight8(active_planes) == 2) {
   1125 		switch (cpp) {
   1126 		case 8:
   1127 			*num = 10;
   1128 			*den = 8;
   1129 			break;
   1130 		case 4:
   1131 			*num = 17;
   1132 			*den = 16;
   1133 			break;
   1134 		default:
   1135 			*num = 1;
   1136 			*den = 1;
   1137 			break;
   1138 		}
   1139 	} else {
   1140 		switch (cpp) {
   1141 		case 8:
   1142 			*num = 9;
   1143 			*den = 8;
   1144 			break;
   1145 		default:
   1146 			*num = 1;
   1147 			*den = 1;
   1148 			break;
   1149 		}
   1150 	}
   1151 }
   1152 
   1153 static void ivb_plane_ratio_scaling(const struct intel_crtc_state *crtc_state,
   1154 				    const struct intel_plane_state *plane_state,
   1155 				    unsigned int *num, unsigned int *den)
   1156 {
   1157 	const struct drm_framebuffer *fb = plane_state->hw.fb;
   1158 	unsigned int cpp = fb->format->cpp[0];
   1159 
   1160 	switch (cpp) {
   1161 	case 8:
   1162 		*num = 12;
   1163 		*den = 8;
   1164 		break;
   1165 	case 4:
   1166 		*num = 19;
   1167 		*den = 16;
   1168 		break;
   1169 	case 2:
   1170 		*num = 33;
   1171 		*den = 32;
   1172 		break;
   1173 	default:
   1174 		*num = 1;
   1175 		*den = 1;
   1176 		break;
   1177 	}
   1178 }
   1179 
   1180 int ivb_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
   1181 			const struct intel_plane_state *plane_state)
   1182 {
   1183 	unsigned int pixel_rate;
   1184 	unsigned int num, den;
   1185 
   1186 	/*
   1187 	 * Note that crtc_state->pixel_rate accounts for both
   1188 	 * horizontal and vertical panel fitter downscaling factors.
   1189 	 * Pre-HSW bspec tells us to only consider the horizontal
   1190 	 * downscaling factor here. We ignore that and just consider
   1191 	 * both for simplicity.
   1192 	 */
   1193 	pixel_rate = crtc_state->pixel_rate;
   1194 
   1195 	ivb_plane_ratio(crtc_state, plane_state, &num, &den);
   1196 
   1197 	return DIV_ROUND_UP(pixel_rate * num, den);
   1198 }
   1199 
   1200 static int ivb_sprite_min_cdclk(const struct intel_crtc_state *crtc_state,
   1201 				const struct intel_plane_state *plane_state)
   1202 {
   1203 	unsigned int src_w, dst_w, pixel_rate;
   1204 	unsigned int num, den;
   1205 
   1206 	/*
   1207 	 * Note that crtc_state->pixel_rate accounts for both
   1208 	 * horizontal and vertical panel fitter downscaling factors.
   1209 	 * Pre-HSW bspec tells us to only consider the horizontal
   1210 	 * downscaling factor here. We ignore that and just consider
   1211 	 * both for simplicity.
   1212 	 */
   1213 	pixel_rate = crtc_state->pixel_rate;
   1214 
   1215 	src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
   1216 	dst_w = drm_rect_width(&plane_state->uapi.dst);
   1217 
   1218 	if (src_w != dst_w)
   1219 		ivb_plane_ratio_scaling(crtc_state, plane_state, &num, &den);
   1220 	else
   1221 		ivb_plane_ratio(crtc_state, plane_state, &num, &den);
   1222 
   1223 	/* Horizontal downscaling limits the maximum pixel rate */
   1224 	dst_w = min(src_w, dst_w);
   1225 
   1226 	return DIV_ROUND_UP_ULL(mul_u32_u32(pixel_rate, num * src_w),
   1227 				den * dst_w);
   1228 }
   1229 
   1230 static void hsw_plane_ratio(const struct intel_crtc_state *crtc_state,
   1231 			    const struct intel_plane_state *plane_state,
   1232 			    unsigned int *num, unsigned int *den)
   1233 {
   1234 	u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR);
   1235 	const struct drm_framebuffer *fb = plane_state->hw.fb;
   1236 	unsigned int cpp = fb->format->cpp[0];
   1237 
   1238 	if (hweight8(active_planes) == 2) {
   1239 		switch (cpp) {
   1240 		case 8:
   1241 			*num = 10;
   1242 			*den = 8;
   1243 			break;
   1244 		default:
   1245 			*num = 1;
   1246 			*den = 1;
   1247 			break;
   1248 		}
   1249 	} else {
   1250 		switch (cpp) {
   1251 		case 8:
   1252 			*num = 9;
   1253 			*den = 8;
   1254 			break;
   1255 		default:
   1256 			*num = 1;
   1257 			*den = 1;
   1258 			break;
   1259 		}
   1260 	}
   1261 }
   1262 
   1263 int hsw_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
   1264 			const struct intel_plane_state *plane_state)
   1265 {
   1266 	unsigned int pixel_rate = crtc_state->pixel_rate;
   1267 	unsigned int num, den;
   1268 
   1269 	hsw_plane_ratio(crtc_state, plane_state, &num, &den);
   1270 
   1271 	return DIV_ROUND_UP(pixel_rate * num, den);
   1272 }
   1273 
   1274 static u32 ivb_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
   1275 {
   1276 	u32 sprctl = 0;
   1277 
   1278 	if (crtc_state->gamma_enable)
   1279 		sprctl |= SPRITE_GAMMA_ENABLE;
   1280 
   1281 	if (crtc_state->csc_enable)
   1282 		sprctl |= SPRITE_PIPE_CSC_ENABLE;
   1283 
   1284 	return sprctl;
   1285 }
   1286 
   1287 static bool ivb_need_sprite_gamma(const struct intel_plane_state *plane_state)
   1288 {
   1289 	struct drm_i915_private *dev_priv =
   1290 		to_i915(plane_state->uapi.plane->dev);
   1291 	const struct drm_framebuffer *fb = plane_state->hw.fb;
   1292 
   1293 	return fb->format->cpp[0] == 8 &&
   1294 		(IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv));
   1295 }
   1296 
   1297 static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state,
   1298 			  const struct intel_plane_state *plane_state)
   1299 {
   1300 	struct drm_i915_private *dev_priv =
   1301 		to_i915(plane_state->uapi.plane->dev);
   1302 	const struct drm_framebuffer *fb = plane_state->hw.fb;
   1303 	unsigned int rotation = plane_state->hw.rotation;
   1304 	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
   1305 	u32 sprctl;
   1306 
   1307 	sprctl = SPRITE_ENABLE;
   1308 
   1309 	if (IS_IVYBRIDGE(dev_priv))
   1310 		sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
   1311 
   1312 	switch (fb->format->format) {
   1313 	case DRM_FORMAT_XBGR8888:
   1314 		sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
   1315 		break;
   1316 	case DRM_FORMAT_XRGB8888:
   1317 		sprctl |= SPRITE_FORMAT_RGBX888;
   1318 		break;
   1319 	case DRM_FORMAT_XBGR2101010:
   1320 		sprctl |= SPRITE_FORMAT_RGBX101010 | SPRITE_RGB_ORDER_RGBX;
   1321 		break;
   1322 	case DRM_FORMAT_XRGB2101010:
   1323 		sprctl |= SPRITE_FORMAT_RGBX101010;
   1324 		break;
   1325 	case DRM_FORMAT_XBGR16161616F:
   1326 		sprctl |= SPRITE_FORMAT_RGBX161616 | SPRITE_RGB_ORDER_RGBX;
   1327 		break;
   1328 	case DRM_FORMAT_XRGB16161616F:
   1329 		sprctl |= SPRITE_FORMAT_RGBX161616;
   1330 		break;
   1331 	case DRM_FORMAT_YUYV:
   1332 		sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
   1333 		break;
   1334 	case DRM_FORMAT_YVYU:
   1335 		sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
   1336 		break;
   1337 	case DRM_FORMAT_UYVY:
   1338 		sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
   1339 		break;
   1340 	case DRM_FORMAT_VYUY:
   1341 		sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
   1342 		break;
   1343 	default:
   1344 		MISSING_CASE(fb->format->format);
   1345 		return 0;
   1346 	}
   1347 
   1348 	if (!ivb_need_sprite_gamma(plane_state))
   1349 		sprctl |= SPRITE_INT_GAMMA_DISABLE;
   1350 
   1351 	if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709)
   1352 		sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709;
   1353 
   1354 	if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
   1355 		sprctl |= SPRITE_YUV_RANGE_CORRECTION_DISABLE;
   1356 
   1357 	if (fb->modifier == I915_FORMAT_MOD_X_TILED)
   1358 		sprctl |= SPRITE_TILED;
   1359 
   1360 	if (rotation & DRM_MODE_ROTATE_180)
   1361 		sprctl |= SPRITE_ROTATE_180;
   1362 
   1363 	if (key->flags & I915_SET_COLORKEY_DESTINATION)
   1364 		sprctl |= SPRITE_DEST_KEY;
   1365 	else if (key->flags & I915_SET_COLORKEY_SOURCE)
   1366 		sprctl |= SPRITE_SOURCE_KEY;
   1367 
   1368 	return sprctl;
   1369 }
   1370 
   1371 static void ivb_sprite_linear_gamma(const struct intel_plane_state *plane_state,
   1372 				    u16 gamma[18])
   1373 {
   1374 	int scale, i;
   1375 
   1376 	/*
   1377 	 * WaFP16GammaEnabling:ivb,hsw
   1378 	 * "Workaround : When using the 64-bit format, the sprite output
   1379 	 *  on each color channel has one quarter amplitude. It can be
   1380 	 *  brought up to full amplitude by using sprite internal gamma
   1381 	 *  correction, pipe gamma correction, or pipe color space
   1382 	 *  conversion to multiply the sprite output by four."
   1383 	 */
   1384 	scale = 4;
   1385 
   1386 	for (i = 0; i < 16; i++)
   1387 		gamma[i] = min((scale * i << 10) / 16, (1 << 10) - 1);
   1388 
   1389 	gamma[i] = min((scale * i << 10) / 16, 1 << 10);
   1390 	i++;
   1391 
   1392 	gamma[i] = 3 << 10;
   1393 	i++;
   1394 }
   1395 
   1396 static void ivb_update_gamma(const struct intel_plane_state *plane_state)
   1397 {
   1398 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
   1399 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   1400 	enum pipe pipe = plane->pipe;
   1401 	u16 gamma[18];
   1402 	int i;
   1403 
   1404 	if (!ivb_need_sprite_gamma(plane_state))
   1405 		return;
   1406 
   1407 	ivb_sprite_linear_gamma(plane_state, gamma);
   1408 
   1409 	/* FIXME these register are single buffered :( */
   1410 	for (i = 0; i < 16; i++)
   1411 		I915_WRITE_FW(SPRGAMC(pipe, i),
   1412 			      gamma[i] << 20 |
   1413 			      gamma[i] << 10 |
   1414 			      gamma[i]);
   1415 
   1416 	I915_WRITE_FW(SPRGAMC16(pipe, 0), gamma[i]);
   1417 	I915_WRITE_FW(SPRGAMC16(pipe, 1), gamma[i]);
   1418 	I915_WRITE_FW(SPRGAMC16(pipe, 2), gamma[i]);
   1419 	i++;
   1420 
   1421 	I915_WRITE_FW(SPRGAMC17(pipe, 0), gamma[i]);
   1422 	I915_WRITE_FW(SPRGAMC17(pipe, 1), gamma[i]);
   1423 	I915_WRITE_FW(SPRGAMC17(pipe, 2), gamma[i]);
   1424 	i++;
   1425 }
   1426 
   1427 static void
   1428 ivb_update_plane(struct intel_plane *plane,
   1429 		 const struct intel_crtc_state *crtc_state,
   1430 		 const struct intel_plane_state *plane_state)
   1431 {
   1432 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   1433 	enum pipe pipe = plane->pipe;
   1434 	u32 sprsurf_offset = plane_state->color_plane[0].offset;
   1435 	u32 linear_offset;
   1436 	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
   1437 	int crtc_x = plane_state->uapi.dst.x1;
   1438 	int crtc_y = plane_state->uapi.dst.y1;
   1439 	u32 crtc_w = drm_rect_width(&plane_state->uapi.dst);
   1440 	u32 crtc_h = drm_rect_height(&plane_state->uapi.dst);
   1441 	u32 x = plane_state->color_plane[0].x;
   1442 	u32 y = plane_state->color_plane[0].y;
   1443 	u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
   1444 	u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
   1445 	u32 sprctl, sprscale = 0;
   1446 	unsigned long irqflags;
   1447 
   1448 	sprctl = plane_state->ctl | ivb_sprite_ctl_crtc(crtc_state);
   1449 
   1450 	/* Sizes are 0 based */
   1451 	src_w--;
   1452 	src_h--;
   1453 	crtc_w--;
   1454 	crtc_h--;
   1455 
   1456 	if (crtc_w != src_w || crtc_h != src_h)
   1457 		sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
   1458 
   1459 	linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
   1460 
   1461 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
   1462 
   1463 	I915_WRITE_FW(SPRSTRIDE(pipe), plane_state->color_plane[0].stride);
   1464 	I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
   1465 	I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
   1466 	if (IS_IVYBRIDGE(dev_priv))
   1467 		I915_WRITE_FW(SPRSCALE(pipe), sprscale);
   1468 
   1469 	if (key->flags) {
   1470 		I915_WRITE_FW(SPRKEYVAL(pipe), key->min_value);
   1471 		I915_WRITE_FW(SPRKEYMSK(pipe), key->channel_mask);
   1472 		I915_WRITE_FW(SPRKEYMAX(pipe), key->max_value);
   1473 	}
   1474 
   1475 	/* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
   1476 	 * register */
   1477 	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
   1478 		I915_WRITE_FW(SPROFFSET(pipe), (y << 16) | x);
   1479 	} else {
   1480 		I915_WRITE_FW(SPRLINOFF(pipe), linear_offset);
   1481 		I915_WRITE_FW(SPRTILEOFF(pipe), (y << 16) | x);
   1482 	}
   1483 
   1484 	/*
   1485 	 * The control register self-arms if the plane was previously
   1486 	 * disabled. Try to make the plane enable atomic by writing
   1487 	 * the control register just before the surface register.
   1488 	 */
   1489 	I915_WRITE_FW(SPRCTL(pipe), sprctl);
   1490 	I915_WRITE_FW(SPRSURF(pipe),
   1491 		      intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
   1492 
   1493 	ivb_update_gamma(plane_state);
   1494 
   1495 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
   1496 }
   1497 
   1498 static void
   1499 ivb_disable_plane(struct intel_plane *plane,
   1500 		  const struct intel_crtc_state *crtc_state)
   1501 {
   1502 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   1503 	enum pipe pipe = plane->pipe;
   1504 	unsigned long irqflags;
   1505 
   1506 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
   1507 
   1508 	I915_WRITE_FW(SPRCTL(pipe), 0);
   1509 	/* Disable the scaler */
   1510 	if (IS_IVYBRIDGE(dev_priv))
   1511 		I915_WRITE_FW(SPRSCALE(pipe), 0);
   1512 	I915_WRITE_FW(SPRSURF(pipe), 0);
   1513 
   1514 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
   1515 }
   1516 
   1517 static bool
   1518 ivb_plane_get_hw_state(struct intel_plane *plane,
   1519 		       enum pipe *pipe)
   1520 {
   1521 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   1522 	enum intel_display_power_domain power_domain;
   1523 	intel_wakeref_t wakeref;
   1524 	bool ret;
   1525 
   1526 	power_domain = POWER_DOMAIN_PIPE(plane->pipe);
   1527 	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
   1528 	if (!wakeref)
   1529 		return false;
   1530 
   1531 	ret =  I915_READ(SPRCTL(plane->pipe)) & SPRITE_ENABLE;
   1532 
   1533 	*pipe = plane->pipe;
   1534 
   1535 	intel_display_power_put(dev_priv, power_domain, wakeref);
   1536 
   1537 	return ret;
   1538 }
   1539 
   1540 static int g4x_sprite_min_cdclk(const struct intel_crtc_state *crtc_state,
   1541 				const struct intel_plane_state *plane_state)
   1542 {
   1543 	const struct drm_framebuffer *fb = plane_state->hw.fb;
   1544 	unsigned int hscale, pixel_rate;
   1545 	unsigned int limit, decimate;
   1546 
   1547 	/*
   1548 	 * Note that crtc_state->pixel_rate accounts for both
   1549 	 * horizontal and vertical panel fitter downscaling factors.
   1550 	 * Pre-HSW bspec tells us to only consider the horizontal
   1551 	 * downscaling factor here. We ignore that and just consider
   1552 	 * both for simplicity.
   1553 	 */
   1554 	pixel_rate = crtc_state->pixel_rate;
   1555 
   1556 	/* Horizontal downscaling limits the maximum pixel rate */
   1557 	hscale = drm_rect_calc_hscale(&plane_state->uapi.src,
   1558 				      &plane_state->uapi.dst,
   1559 				      0, INT_MAX);
   1560 	if (hscale < 0x10000)
   1561 		return pixel_rate;
   1562 
   1563 	/* Decimation steps at 2x,4x,8x,16x */
   1564 	decimate = ilog2(hscale >> 16);
   1565 	hscale >>= decimate;
   1566 
   1567 	/* Starting limit is 90% of cdclk */
   1568 	limit = 9;
   1569 
   1570 	/* -10% per decimation step */
   1571 	limit -= decimate;
   1572 
   1573 	/* -10% for RGB */
   1574 	if (fb->format->cpp[0] >= 4)
   1575 		limit--; /* -10% for RGB */
   1576 
   1577 	/*
   1578 	 * We should also do -10% if sprite scaling is enabled
   1579 	 * on the other pipe, but we can't really check for that,
   1580 	 * so we ignore it.
   1581 	 */
   1582 
   1583 	return DIV_ROUND_UP_ULL(mul_u32_u32(pixel_rate, 10 * hscale),
   1584 				limit << 16);
   1585 }
   1586 
   1587 static unsigned int
   1588 g4x_sprite_max_stride(struct intel_plane *plane,
   1589 		      u32 pixel_format, u64 modifier,
   1590 		      unsigned int rotation)
   1591 {
   1592 	return 16384;
   1593 }
   1594 
   1595 static u32 g4x_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
   1596 {
   1597 	u32 dvscntr = 0;
   1598 
   1599 	if (crtc_state->gamma_enable)
   1600 		dvscntr |= DVS_GAMMA_ENABLE;
   1601 
   1602 	if (crtc_state->csc_enable)
   1603 		dvscntr |= DVS_PIPE_CSC_ENABLE;
   1604 
   1605 	return dvscntr;
   1606 }
   1607 
   1608 static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state,
   1609 			  const struct intel_plane_state *plane_state)
   1610 {
   1611 	struct drm_i915_private *dev_priv =
   1612 		to_i915(plane_state->uapi.plane->dev);
   1613 	const struct drm_framebuffer *fb = plane_state->hw.fb;
   1614 	unsigned int rotation = plane_state->hw.rotation;
   1615 	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
   1616 	u32 dvscntr;
   1617 
   1618 	dvscntr = DVS_ENABLE;
   1619 
   1620 	if (IS_GEN(dev_priv, 6))
   1621 		dvscntr |= DVS_TRICKLE_FEED_DISABLE;
   1622 
   1623 	switch (fb->format->format) {
   1624 	case DRM_FORMAT_XBGR8888:
   1625 		dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR;
   1626 		break;
   1627 	case DRM_FORMAT_XRGB8888:
   1628 		dvscntr |= DVS_FORMAT_RGBX888;
   1629 		break;
   1630 	case DRM_FORMAT_XBGR2101010:
   1631 		dvscntr |= DVS_FORMAT_RGBX101010 | DVS_RGB_ORDER_XBGR;
   1632 		break;
   1633 	case DRM_FORMAT_XRGB2101010:
   1634 		dvscntr |= DVS_FORMAT_RGBX101010;
   1635 		break;
   1636 	case DRM_FORMAT_XBGR16161616F:
   1637 		dvscntr |= DVS_FORMAT_RGBX161616 | DVS_RGB_ORDER_XBGR;
   1638 		break;
   1639 	case DRM_FORMAT_XRGB16161616F:
   1640 		dvscntr |= DVS_FORMAT_RGBX161616;
   1641 		break;
   1642 	case DRM_FORMAT_YUYV:
   1643 		dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
   1644 		break;
   1645 	case DRM_FORMAT_YVYU:
   1646 		dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
   1647 		break;
   1648 	case DRM_FORMAT_UYVY:
   1649 		dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
   1650 		break;
   1651 	case DRM_FORMAT_VYUY:
   1652 		dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
   1653 		break;
   1654 	default:
   1655 		MISSING_CASE(fb->format->format);
   1656 		return 0;
   1657 	}
   1658 
   1659 	if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709)
   1660 		dvscntr |= DVS_YUV_FORMAT_BT709;
   1661 
   1662 	if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
   1663 		dvscntr |= DVS_YUV_RANGE_CORRECTION_DISABLE;
   1664 
   1665 	if (fb->modifier == I915_FORMAT_MOD_X_TILED)
   1666 		dvscntr |= DVS_TILED;
   1667 
   1668 	if (rotation & DRM_MODE_ROTATE_180)
   1669 		dvscntr |= DVS_ROTATE_180;
   1670 
   1671 	if (key->flags & I915_SET_COLORKEY_DESTINATION)
   1672 		dvscntr |= DVS_DEST_KEY;
   1673 	else if (key->flags & I915_SET_COLORKEY_SOURCE)
   1674 		dvscntr |= DVS_SOURCE_KEY;
   1675 
   1676 	return dvscntr;
   1677 }
   1678 
   1679 static void g4x_update_gamma(const struct intel_plane_state *plane_state)
   1680 {
   1681 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
   1682 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   1683 	const struct drm_framebuffer *fb = plane_state->hw.fb;
   1684 	enum pipe pipe = plane->pipe;
   1685 	u16 gamma[8];
   1686 	int i;
   1687 
   1688 	/* Seems RGB data bypasses the gamma always */
   1689 	if (!fb->format->is_yuv)
   1690 		return;
   1691 
   1692 	i9xx_plane_linear_gamma(gamma);
   1693 
   1694 	/* FIXME these register are single buffered :( */
   1695 	/* The two end points are implicit (0.0 and 1.0) */
   1696 	for (i = 1; i < 8 - 1; i++)
   1697 		I915_WRITE_FW(DVSGAMC_G4X(pipe, i - 1),
   1698 			      gamma[i] << 16 |
   1699 			      gamma[i] << 8 |
   1700 			      gamma[i]);
   1701 }
   1702 
   1703 static void ilk_sprite_linear_gamma(u16 gamma[17])
   1704 {
   1705 	int i;
   1706 
   1707 	for (i = 0; i < 17; i++)
   1708 		gamma[i] = (i << 10) / 16;
   1709 }
   1710 
   1711 static void ilk_update_gamma(const struct intel_plane_state *plane_state)
   1712 {
   1713 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
   1714 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   1715 	const struct drm_framebuffer *fb = plane_state->hw.fb;
   1716 	enum pipe pipe = plane->pipe;
   1717 	u16 gamma[17];
   1718 	int i;
   1719 
   1720 	/* Seems RGB data bypasses the gamma always */
   1721 	if (!fb->format->is_yuv)
   1722 		return;
   1723 
   1724 	ilk_sprite_linear_gamma(gamma);
   1725 
   1726 	/* FIXME these register are single buffered :( */
   1727 	for (i = 0; i < 16; i++)
   1728 		I915_WRITE_FW(DVSGAMC_ILK(pipe, i),
   1729 			      gamma[i] << 20 |
   1730 			      gamma[i] << 10 |
   1731 			      gamma[i]);
   1732 
   1733 	I915_WRITE_FW(DVSGAMCMAX_ILK(pipe, 0), gamma[i]);
   1734 	I915_WRITE_FW(DVSGAMCMAX_ILK(pipe, 1), gamma[i]);
   1735 	I915_WRITE_FW(DVSGAMCMAX_ILK(pipe, 2), gamma[i]);
   1736 	i++;
   1737 }
   1738 
   1739 static void
   1740 g4x_update_plane(struct intel_plane *plane,
   1741 		 const struct intel_crtc_state *crtc_state,
   1742 		 const struct intel_plane_state *plane_state)
   1743 {
   1744 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   1745 	enum pipe pipe = plane->pipe;
   1746 	u32 dvssurf_offset = plane_state->color_plane[0].offset;
   1747 	u32 linear_offset;
   1748 	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
   1749 	int crtc_x = plane_state->uapi.dst.x1;
   1750 	int crtc_y = plane_state->uapi.dst.y1;
   1751 	u32 crtc_w = drm_rect_width(&plane_state->uapi.dst);
   1752 	u32 crtc_h = drm_rect_height(&plane_state->uapi.dst);
   1753 	u32 x = plane_state->color_plane[0].x;
   1754 	u32 y = plane_state->color_plane[0].y;
   1755 	u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
   1756 	u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
   1757 	u32 dvscntr, dvsscale = 0;
   1758 	unsigned long irqflags;
   1759 
   1760 	dvscntr = plane_state->ctl | g4x_sprite_ctl_crtc(crtc_state);
   1761 
   1762 	/* Sizes are 0 based */
   1763 	src_w--;
   1764 	src_h--;
   1765 	crtc_w--;
   1766 	crtc_h--;
   1767 
   1768 	if (crtc_w != src_w || crtc_h != src_h)
   1769 		dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h;
   1770 
   1771 	linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
   1772 
   1773 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
   1774 
   1775 	I915_WRITE_FW(DVSSTRIDE(pipe), plane_state->color_plane[0].stride);
   1776 	I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
   1777 	I915_WRITE_FW(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
   1778 	I915_WRITE_FW(DVSSCALE(pipe), dvsscale);
   1779 
   1780 	if (key->flags) {
   1781 		I915_WRITE_FW(DVSKEYVAL(pipe), key->min_value);
   1782 		I915_WRITE_FW(DVSKEYMSK(pipe), key->channel_mask);
   1783 		I915_WRITE_FW(DVSKEYMAX(pipe), key->max_value);
   1784 	}
   1785 
   1786 	I915_WRITE_FW(DVSLINOFF(pipe), linear_offset);
   1787 	I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x);
   1788 
   1789 	/*
   1790 	 * The control register self-arms if the plane was previously
   1791 	 * disabled. Try to make the plane enable atomic by writing
   1792 	 * the control register just before the surface register.
   1793 	 */
   1794 	I915_WRITE_FW(DVSCNTR(pipe), dvscntr);
   1795 	I915_WRITE_FW(DVSSURF(pipe),
   1796 		      intel_plane_ggtt_offset(plane_state) + dvssurf_offset);
   1797 
   1798 	if (IS_G4X(dev_priv))
   1799 		g4x_update_gamma(plane_state);
   1800 	else
   1801 		ilk_update_gamma(plane_state);
   1802 
   1803 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
   1804 }
   1805 
   1806 static void
   1807 g4x_disable_plane(struct intel_plane *plane,
   1808 		  const struct intel_crtc_state *crtc_state)
   1809 {
   1810 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   1811 	enum pipe pipe = plane->pipe;
   1812 	unsigned long irqflags;
   1813 
   1814 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
   1815 
   1816 	I915_WRITE_FW(DVSCNTR(pipe), 0);
   1817 	/* Disable the scaler */
   1818 	I915_WRITE_FW(DVSSCALE(pipe), 0);
   1819 	I915_WRITE_FW(DVSSURF(pipe), 0);
   1820 
   1821 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
   1822 }
   1823 
   1824 static bool
   1825 g4x_plane_get_hw_state(struct intel_plane *plane,
   1826 		       enum pipe *pipe)
   1827 {
   1828 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   1829 	enum intel_display_power_domain power_domain;
   1830 	intel_wakeref_t wakeref;
   1831 	bool ret;
   1832 
   1833 	power_domain = POWER_DOMAIN_PIPE(plane->pipe);
   1834 	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
   1835 	if (!wakeref)
   1836 		return false;
   1837 
   1838 	ret = I915_READ(DVSCNTR(plane->pipe)) & DVS_ENABLE;
   1839 
   1840 	*pipe = plane->pipe;
   1841 
   1842 	intel_display_power_put(dev_priv, power_domain, wakeref);
   1843 
   1844 	return ret;
   1845 }
   1846 
   1847 static bool intel_fb_scalable(const struct drm_framebuffer *fb)
   1848 {
   1849 	if (!fb)
   1850 		return false;
   1851 
   1852 	switch (fb->format->format) {
   1853 	case DRM_FORMAT_C8:
   1854 		return false;
   1855 	case DRM_FORMAT_XRGB16161616F:
   1856 	case DRM_FORMAT_ARGB16161616F:
   1857 	case DRM_FORMAT_XBGR16161616F:
   1858 	case DRM_FORMAT_ABGR16161616F:
   1859 		return INTEL_GEN(to_i915(fb->dev)) >= 11;
   1860 	default:
   1861 		return true;
   1862 	}
   1863 }
   1864 
   1865 static int
   1866 g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state,
   1867 			 struct intel_plane_state *plane_state)
   1868 {
   1869 	const struct drm_framebuffer *fb = plane_state->hw.fb;
   1870 	const struct drm_rect *src = &plane_state->uapi.src;
   1871 	const struct drm_rect *dst = &plane_state->uapi.dst;
   1872 	int src_x, src_w, src_h, crtc_w, crtc_h;
   1873 	const struct drm_display_mode *adjusted_mode =
   1874 		&crtc_state->hw.adjusted_mode;
   1875 	unsigned int stride = plane_state->color_plane[0].stride;
   1876 	unsigned int cpp = fb->format->cpp[0];
   1877 	unsigned int width_bytes;
   1878 	int min_width, min_height;
   1879 
   1880 	crtc_w = drm_rect_width(dst);
   1881 	crtc_h = drm_rect_height(dst);
   1882 
   1883 	src_x = src->x1 >> 16;
   1884 	src_w = drm_rect_width(src) >> 16;
   1885 	src_h = drm_rect_height(src) >> 16;
   1886 
   1887 	if (src_w == crtc_w && src_h == crtc_h)
   1888 		return 0;
   1889 
   1890 	min_width = 3;
   1891 
   1892 	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
   1893 		if (src_h & 1) {
   1894 			DRM_DEBUG_KMS("Source height must be even with interlaced modes\n");
   1895 			return -EINVAL;
   1896 		}
   1897 		min_height = 6;
   1898 	} else {
   1899 		min_height = 3;
   1900 	}
   1901 
   1902 	width_bytes = ((src_x * cpp) & 63) + src_w * cpp;
   1903 
   1904 	if (src_w < min_width || src_h < min_height ||
   1905 	    src_w > 2048 || src_h > 2048) {
   1906 		DRM_DEBUG_KMS("Source dimensions (%dx%d) exceed hardware limits (%dx%d - %dx%d)\n",
   1907 			      src_w, src_h, min_width, min_height, 2048, 2048);
   1908 		return -EINVAL;
   1909 	}
   1910 
   1911 	if (width_bytes > 4096) {
   1912 		DRM_DEBUG_KMS("Fetch width (%d) exceeds hardware max with scaling (%u)\n",
   1913 			      width_bytes, 4096);
   1914 		return -EINVAL;
   1915 	}
   1916 
   1917 	if (stride > 4096) {
   1918 		DRM_DEBUG_KMS("Stride (%u) exceeds hardware max with scaling (%u)\n",
   1919 			      stride, 4096);
   1920 		return -EINVAL;
   1921 	}
   1922 
   1923 	return 0;
   1924 }
   1925 
   1926 static int
   1927 g4x_sprite_check(struct intel_crtc_state *crtc_state,
   1928 		 struct intel_plane_state *plane_state)
   1929 {
   1930 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
   1931 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   1932 	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
   1933 	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
   1934 	int ret;
   1935 
   1936 	if (intel_fb_scalable(plane_state->hw.fb)) {
   1937 		if (INTEL_GEN(dev_priv) < 7) {
   1938 			min_scale = 1;
   1939 			max_scale = 16 << 16;
   1940 		} else if (IS_IVYBRIDGE(dev_priv)) {
   1941 			min_scale = 1;
   1942 			max_scale = 2 << 16;
   1943 		}
   1944 	}
   1945 
   1946 	ret = drm_atomic_helper_check_plane_state(&plane_state->uapi,
   1947 						  &crtc_state->uapi,
   1948 						  min_scale, max_scale,
   1949 						  true, true);
   1950 	if (ret)
   1951 		return ret;
   1952 
   1953 	ret = i9xx_check_plane_surface(plane_state);
   1954 	if (ret)
   1955 		return ret;
   1956 
   1957 	if (!plane_state->uapi.visible)
   1958 		return 0;
   1959 
   1960 	ret = intel_plane_check_src_coordinates(plane_state);
   1961 	if (ret)
   1962 		return ret;
   1963 
   1964 	ret = g4x_sprite_check_scaling(crtc_state, plane_state);
   1965 	if (ret)
   1966 		return ret;
   1967 
   1968 	if (INTEL_GEN(dev_priv) >= 7)
   1969 		plane_state->ctl = ivb_sprite_ctl(crtc_state, plane_state);
   1970 	else
   1971 		plane_state->ctl = g4x_sprite_ctl(crtc_state, plane_state);
   1972 
   1973 	return 0;
   1974 }
   1975 
   1976 int chv_plane_check_rotation(const struct intel_plane_state *plane_state)
   1977 {
   1978 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
   1979 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   1980 	unsigned int rotation = plane_state->hw.rotation;
   1981 
   1982 	/* CHV ignores the mirror bit when the rotate bit is set :( */
   1983 	if (IS_CHERRYVIEW(dev_priv) &&
   1984 	    rotation & DRM_MODE_ROTATE_180 &&
   1985 	    rotation & DRM_MODE_REFLECT_X) {
   1986 		DRM_DEBUG_KMS("Cannot rotate and reflect at the same time\n");
   1987 		return -EINVAL;
   1988 	}
   1989 
   1990 	return 0;
   1991 }
   1992 
   1993 static int
   1994 vlv_sprite_check(struct intel_crtc_state *crtc_state,
   1995 		 struct intel_plane_state *plane_state)
   1996 {
   1997 	int ret;
   1998 
   1999 	ret = chv_plane_check_rotation(plane_state);
   2000 	if (ret)
   2001 		return ret;
   2002 
   2003 	ret = drm_atomic_helper_check_plane_state(&plane_state->uapi,
   2004 						  &crtc_state->uapi,
   2005 						  DRM_PLANE_HELPER_NO_SCALING,
   2006 						  DRM_PLANE_HELPER_NO_SCALING,
   2007 						  true, true);
   2008 	if (ret)
   2009 		return ret;
   2010 
   2011 	ret = i9xx_check_plane_surface(plane_state);
   2012 	if (ret)
   2013 		return ret;
   2014 
   2015 	if (!plane_state->uapi.visible)
   2016 		return 0;
   2017 
   2018 	ret = intel_plane_check_src_coordinates(plane_state);
   2019 	if (ret)
   2020 		return ret;
   2021 
   2022 	plane_state->ctl = vlv_sprite_ctl(crtc_state, plane_state);
   2023 
   2024 	return 0;
   2025 }
   2026 
   2027 static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
   2028 			      const struct intel_plane_state *plane_state)
   2029 {
   2030 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
   2031 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   2032 	const struct drm_framebuffer *fb = plane_state->hw.fb;
   2033 	unsigned int rotation = plane_state->hw.rotation;
   2034 	struct drm_format_name_buf format_name;
   2035 
   2036 	if (!fb)
   2037 		return 0;
   2038 
   2039 	if (rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180) &&
   2040 	    is_ccs_modifier(fb->modifier)) {
   2041 		DRM_DEBUG_KMS("RC support only with 0/180 degree rotation (%x)\n",
   2042 			      rotation);
   2043 		return -EINVAL;
   2044 	}
   2045 
   2046 	if (rotation & DRM_MODE_REFLECT_X &&
   2047 	    fb->modifier == DRM_FORMAT_MOD_LINEAR) {
   2048 		DRM_DEBUG_KMS("horizontal flip is not supported with linear surface formats\n");
   2049 		return -EINVAL;
   2050 	}
   2051 
   2052 	if (drm_rotation_90_or_270(rotation)) {
   2053 		if (fb->modifier != I915_FORMAT_MOD_Y_TILED &&
   2054 		    fb->modifier != I915_FORMAT_MOD_Yf_TILED) {
   2055 			DRM_DEBUG_KMS("Y/Yf tiling required for 90/270!\n");
   2056 			return -EINVAL;
   2057 		}
   2058 
   2059 		/*
   2060 		 * 90/270 is not allowed with RGB64 16:16:16:16 and
   2061 		 * Indexed 8-bit. RGB 16-bit 5:6:5 is allowed gen11 onwards.
   2062 		 */
   2063 		switch (fb->format->format) {
   2064 		case DRM_FORMAT_RGB565:
   2065 			if (INTEL_GEN(dev_priv) >= 11)
   2066 				break;
   2067 			/* fall through */
   2068 		case DRM_FORMAT_C8:
   2069 		case DRM_FORMAT_XRGB16161616F:
   2070 		case DRM_FORMAT_XBGR16161616F:
   2071 		case DRM_FORMAT_ARGB16161616F:
   2072 		case DRM_FORMAT_ABGR16161616F:
   2073 		case DRM_FORMAT_Y210:
   2074 		case DRM_FORMAT_Y212:
   2075 		case DRM_FORMAT_Y216:
   2076 		case DRM_FORMAT_XVYU12_16161616:
   2077 		case DRM_FORMAT_XVYU16161616:
   2078 			DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n",
   2079 				      drm_get_format_name(fb->format->format,
   2080 							  &format_name));
   2081 			return -EINVAL;
   2082 		default:
   2083 			break;
   2084 		}
   2085 	}
   2086 
   2087 	/* Y-tiling is not supported in IF-ID Interlace mode */
   2088 	if (crtc_state->hw.enable &&
   2089 	    crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE &&
   2090 	    (fb->modifier == I915_FORMAT_MOD_Y_TILED ||
   2091 	     fb->modifier == I915_FORMAT_MOD_Yf_TILED ||
   2092 	     fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
   2093 	     fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS ||
   2094 	     fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS ||
   2095 	     fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS)) {
   2096 		DRM_DEBUG_KMS("Y/Yf tiling not supported in IF-ID mode\n");
   2097 		return -EINVAL;
   2098 	}
   2099 
   2100 	return 0;
   2101 }
   2102 
   2103 static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_state,
   2104 					   const struct intel_plane_state *plane_state)
   2105 {
   2106 	struct drm_i915_private *dev_priv =
   2107 		to_i915(plane_state->uapi.plane->dev);
   2108 	int crtc_x = plane_state->uapi.dst.x1;
   2109 	int crtc_w = drm_rect_width(&plane_state->uapi.dst);
   2110 	int pipe_src_w = crtc_state->pipe_src_w;
   2111 
   2112 	/*
   2113 	 * Display WA #1175: cnl,glk
   2114 	 * Planes other than the cursor may cause FIFO underflow and display
   2115 	 * corruption if starting less than 4 pixels from the right edge of
   2116 	 * the screen.
   2117 	 * Besides the above WA fix the similar problem, where planes other
   2118 	 * than the cursor ending less than 4 pixels from the left edge of the
   2119 	 * screen may cause FIFO underflow and display corruption.
   2120 	 */
   2121 	if ((IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) &&
   2122 	    (crtc_x + crtc_w < 4 || crtc_x > pipe_src_w - 4)) {
   2123 		DRM_DEBUG_KMS("requested plane X %s position %d invalid (valid range %d-%d)\n",
   2124 			      crtc_x + crtc_w < 4 ? "end" : "start",
   2125 			      crtc_x + crtc_w < 4 ? crtc_x + crtc_w : crtc_x,
   2126 			      4, pipe_src_w - 4);
   2127 		return -ERANGE;
   2128 	}
   2129 
   2130 	return 0;
   2131 }
   2132 
   2133 static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_state)
   2134 {
   2135 	const struct drm_framebuffer *fb = plane_state->hw.fb;
   2136 	unsigned int rotation = plane_state->hw.rotation;
   2137 	int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
   2138 
   2139 	/* Display WA #1106 */
   2140 	if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) &&
   2141 	    src_w & 3 &&
   2142 	    (rotation == DRM_MODE_ROTATE_270 ||
   2143 	     rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) {
   2144 		DRM_DEBUG_KMS("src width must be multiple of 4 for rotated planar YUV\n");
   2145 		return -EINVAL;
   2146 	}
   2147 
   2148 	return 0;
   2149 }
   2150 
   2151 static int skl_plane_max_scale(struct drm_i915_private *dev_priv,
   2152 			       const struct drm_framebuffer *fb)
   2153 {
   2154 	/*
   2155 	 * We don't yet know the final source width nor
   2156 	 * whether we can use the HQ scaler mode. Assume
   2157 	 * the best case.
   2158 	 * FIXME need to properly check this later.
   2159 	 */
   2160 	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv) ||
   2161 	    !intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
   2162 		return 0x30000 - 1;
   2163 	else
   2164 		return 0x20000 - 1;
   2165 }
   2166 
   2167 static int skl_plane_check(struct intel_crtc_state *crtc_state,
   2168 			   struct intel_plane_state *plane_state)
   2169 {
   2170 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
   2171 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   2172 	const struct drm_framebuffer *fb = plane_state->hw.fb;
   2173 	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
   2174 	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
   2175 	int ret;
   2176 
   2177 	ret = skl_plane_check_fb(crtc_state, plane_state);
   2178 	if (ret)
   2179 		return ret;
   2180 
   2181 	/* use scaler when colorkey is not required */
   2182 	if (!plane_state->ckey.flags && intel_fb_scalable(fb)) {
   2183 		min_scale = 1;
   2184 		max_scale = skl_plane_max_scale(dev_priv, fb);
   2185 	}
   2186 
   2187 	ret = drm_atomic_helper_check_plane_state(&plane_state->uapi,
   2188 						  &crtc_state->uapi,
   2189 						  min_scale, max_scale,
   2190 						  true, true);
   2191 	if (ret)
   2192 		return ret;
   2193 
   2194 	ret = skl_check_plane_surface(plane_state);
   2195 	if (ret)
   2196 		return ret;
   2197 
   2198 	if (!plane_state->uapi.visible)
   2199 		return 0;
   2200 
   2201 	ret = skl_plane_check_dst_coordinates(crtc_state, plane_state);
   2202 	if (ret)
   2203 		return ret;
   2204 
   2205 	ret = intel_plane_check_src_coordinates(plane_state);
   2206 	if (ret)
   2207 		return ret;
   2208 
   2209 	ret = skl_plane_check_nv12_rotation(plane_state);
   2210 	if (ret)
   2211 		return ret;
   2212 
   2213 	/* HW only has 8 bits pixel precision, disable plane if invisible */
   2214 	if (!(plane_state->hw.alpha >> 8))
   2215 		plane_state->uapi.visible = false;
   2216 
   2217 	plane_state->ctl = skl_plane_ctl(crtc_state, plane_state);
   2218 
   2219 	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
   2220 		plane_state->color_ctl = glk_plane_color_ctl(crtc_state,
   2221 							     plane_state);
   2222 
   2223 	if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) &&
   2224 	    icl_is_hdr_plane(dev_priv, plane->id))
   2225 		/* Enable and use MPEG-2 chroma siting */
   2226 		plane_state->cus_ctl = PLANE_CUS_ENABLE |
   2227 			PLANE_CUS_HPHASE_0 |
   2228 			PLANE_CUS_VPHASE_SIGN_NEGATIVE | PLANE_CUS_VPHASE_0_25;
   2229 	else
   2230 		plane_state->cus_ctl = 0;
   2231 
   2232 	return 0;
   2233 }
   2234 
   2235 static bool has_dst_key_in_primary_plane(struct drm_i915_private *dev_priv)
   2236 {
   2237 	return INTEL_GEN(dev_priv) >= 9;
   2238 }
   2239 
   2240 static void intel_plane_set_ckey(struct intel_plane_state *plane_state,
   2241 				 const struct drm_intel_sprite_colorkey *set)
   2242 {
   2243 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
   2244 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   2245 	struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
   2246 
   2247 	*key = *set;
   2248 
   2249 	/*
   2250 	 * We want src key enabled on the
   2251 	 * sprite and not on the primary.
   2252 	 */
   2253 	if (plane->id == PLANE_PRIMARY &&
   2254 	    set->flags & I915_SET_COLORKEY_SOURCE)
   2255 		key->flags = 0;
   2256 
   2257 	/*
   2258 	 * On SKL+ we want dst key enabled on
   2259 	 * the primary and not on the sprite.
   2260 	 */
   2261 	if (INTEL_GEN(dev_priv) >= 9 && plane->id != PLANE_PRIMARY &&
   2262 	    set->flags & I915_SET_COLORKEY_DESTINATION)
   2263 		key->flags = 0;
   2264 }
   2265 
   2266 int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
   2267 				    struct drm_file *file_priv)
   2268 {
   2269 	struct drm_i915_private *dev_priv = to_i915(dev);
   2270 	struct drm_intel_sprite_colorkey *set = data;
   2271 	struct drm_plane *plane;
   2272 	struct drm_plane_state *plane_state;
   2273 	struct drm_atomic_state *state;
   2274 	struct drm_modeset_acquire_ctx ctx;
   2275 	int ret = 0;
   2276 
   2277 	/* ignore the pointless "none" flag */
   2278 	set->flags &= ~I915_SET_COLORKEY_NONE;
   2279 
   2280 	if (set->flags & ~(I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
   2281 		return -EINVAL;
   2282 
   2283 	/* Make sure we don't try to enable both src & dest simultaneously */
   2284 	if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
   2285 		return -EINVAL;
   2286 
   2287 	if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
   2288 	    set->flags & I915_SET_COLORKEY_DESTINATION)
   2289 		return -EINVAL;
   2290 
   2291 	plane = drm_plane_find(dev, file_priv, set->plane_id);
   2292 	if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY)
   2293 		return -ENOENT;
   2294 
   2295 	/*
   2296 	 * SKL+ only plane 2 can do destination keying against plane 1.
   2297 	 * Also multiple planes can't do destination keying on the same
   2298 	 * pipe simultaneously.
   2299 	 */
   2300 	if (INTEL_GEN(dev_priv) >= 9 &&
   2301 	    to_intel_plane(plane)->id >= PLANE_SPRITE1 &&
   2302 	    set->flags & I915_SET_COLORKEY_DESTINATION)
   2303 		return -EINVAL;
   2304 
   2305 	drm_modeset_acquire_init(&ctx, 0);
   2306 
   2307 	state = drm_atomic_state_alloc(plane->dev);
   2308 	if (!state) {
   2309 		ret = -ENOMEM;
   2310 		goto out;
   2311 	}
   2312 	state->acquire_ctx = &ctx;
   2313 
   2314 	while (1) {
   2315 		plane_state = drm_atomic_get_plane_state(state, plane);
   2316 		ret = PTR_ERR_OR_ZERO(plane_state);
   2317 		if (!ret)
   2318 			intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
   2319 
   2320 		/*
   2321 		 * On some platforms we have to configure
   2322 		 * the dst colorkey on the primary plane.
   2323 		 */
   2324 		if (!ret && has_dst_key_in_primary_plane(dev_priv)) {
   2325 			struct intel_crtc *crtc =
   2326 				intel_get_crtc_for_pipe(dev_priv,
   2327 							to_intel_plane(plane)->pipe);
   2328 
   2329 			plane_state = drm_atomic_get_plane_state(state,
   2330 								 crtc->base.primary);
   2331 			ret = PTR_ERR_OR_ZERO(plane_state);
   2332 			if (!ret)
   2333 				intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
   2334 		}
   2335 
   2336 		if (!ret)
   2337 			ret = drm_atomic_commit(state);
   2338 
   2339 		if (ret != -EDEADLK)
   2340 			break;
   2341 
   2342 		drm_atomic_state_clear(state);
   2343 		drm_modeset_backoff(&ctx);
   2344 	}
   2345 
   2346 	drm_atomic_state_put(state);
   2347 out:
   2348 	drm_modeset_drop_locks(&ctx);
   2349 	drm_modeset_acquire_fini(&ctx);
   2350 	return ret;
   2351 }
   2352 
   2353 static const u32 g4x_plane_formats[] = {
   2354 	DRM_FORMAT_XRGB8888,
   2355 	DRM_FORMAT_YUYV,
   2356 	DRM_FORMAT_YVYU,
   2357 	DRM_FORMAT_UYVY,
   2358 	DRM_FORMAT_VYUY,
   2359 };
   2360 
   2361 static const u64 i9xx_plane_format_modifiers[] = {
   2362 	I915_FORMAT_MOD_X_TILED,
   2363 	DRM_FORMAT_MOD_LINEAR,
   2364 	DRM_FORMAT_MOD_INVALID
   2365 };
   2366 
   2367 static const u32 snb_plane_formats[] = {
   2368 	DRM_FORMAT_XRGB8888,
   2369 	DRM_FORMAT_XBGR8888,
   2370 	DRM_FORMAT_XRGB2101010,
   2371 	DRM_FORMAT_XBGR2101010,
   2372 	DRM_FORMAT_XRGB16161616F,
   2373 	DRM_FORMAT_XBGR16161616F,
   2374 	DRM_FORMAT_YUYV,
   2375 	DRM_FORMAT_YVYU,
   2376 	DRM_FORMAT_UYVY,
   2377 	DRM_FORMAT_VYUY,
   2378 };
   2379 
   2380 static const u32 vlv_plane_formats[] = {
   2381 	DRM_FORMAT_C8,
   2382 	DRM_FORMAT_RGB565,
   2383 	DRM_FORMAT_XRGB8888,
   2384 	DRM_FORMAT_XBGR8888,
   2385 	DRM_FORMAT_ARGB8888,
   2386 	DRM_FORMAT_ABGR8888,
   2387 	DRM_FORMAT_XBGR2101010,
   2388 	DRM_FORMAT_ABGR2101010,
   2389 	DRM_FORMAT_YUYV,
   2390 	DRM_FORMAT_YVYU,
   2391 	DRM_FORMAT_UYVY,
   2392 	DRM_FORMAT_VYUY,
   2393 };
   2394 
   2395 static const u32 chv_pipe_b_sprite_formats[] = {
   2396 	DRM_FORMAT_C8,
   2397 	DRM_FORMAT_RGB565,
   2398 	DRM_FORMAT_XRGB8888,
   2399 	DRM_FORMAT_XBGR8888,
   2400 	DRM_FORMAT_ARGB8888,
   2401 	DRM_FORMAT_ABGR8888,
   2402 	DRM_FORMAT_XRGB2101010,
   2403 	DRM_FORMAT_XBGR2101010,
   2404 	DRM_FORMAT_ARGB2101010,
   2405 	DRM_FORMAT_ABGR2101010,
   2406 	DRM_FORMAT_YUYV,
   2407 	DRM_FORMAT_YVYU,
   2408 	DRM_FORMAT_UYVY,
   2409 	DRM_FORMAT_VYUY,
   2410 };
   2411 
   2412 static const u32 skl_plane_formats[] = {
   2413 	DRM_FORMAT_C8,
   2414 	DRM_FORMAT_RGB565,
   2415 	DRM_FORMAT_XRGB8888,
   2416 	DRM_FORMAT_XBGR8888,
   2417 	DRM_FORMAT_ARGB8888,
   2418 	DRM_FORMAT_ABGR8888,
   2419 	DRM_FORMAT_XRGB2101010,
   2420 	DRM_FORMAT_XBGR2101010,
   2421 	DRM_FORMAT_XRGB16161616F,
   2422 	DRM_FORMAT_XBGR16161616F,
   2423 	DRM_FORMAT_YUYV,
   2424 	DRM_FORMAT_YVYU,
   2425 	DRM_FORMAT_UYVY,
   2426 	DRM_FORMAT_VYUY,
   2427 };
   2428 
   2429 static const u32 skl_planar_formats[] = {
   2430 	DRM_FORMAT_C8,
   2431 	DRM_FORMAT_RGB565,
   2432 	DRM_FORMAT_XRGB8888,
   2433 	DRM_FORMAT_XBGR8888,
   2434 	DRM_FORMAT_ARGB8888,
   2435 	DRM_FORMAT_ABGR8888,
   2436 	DRM_FORMAT_XRGB2101010,
   2437 	DRM_FORMAT_XBGR2101010,
   2438 	DRM_FORMAT_XRGB16161616F,
   2439 	DRM_FORMAT_XBGR16161616F,
   2440 	DRM_FORMAT_YUYV,
   2441 	DRM_FORMAT_YVYU,
   2442 	DRM_FORMAT_UYVY,
   2443 	DRM_FORMAT_VYUY,
   2444 	DRM_FORMAT_NV12,
   2445 };
   2446 
   2447 static const u32 glk_planar_formats[] = {
   2448 	DRM_FORMAT_C8,
   2449 	DRM_FORMAT_RGB565,
   2450 	DRM_FORMAT_XRGB8888,
   2451 	DRM_FORMAT_XBGR8888,
   2452 	DRM_FORMAT_ARGB8888,
   2453 	DRM_FORMAT_ABGR8888,
   2454 	DRM_FORMAT_XRGB2101010,
   2455 	DRM_FORMAT_XBGR2101010,
   2456 	DRM_FORMAT_XRGB16161616F,
   2457 	DRM_FORMAT_XBGR16161616F,
   2458 	DRM_FORMAT_YUYV,
   2459 	DRM_FORMAT_YVYU,
   2460 	DRM_FORMAT_UYVY,
   2461 	DRM_FORMAT_VYUY,
   2462 	DRM_FORMAT_NV12,
   2463 	DRM_FORMAT_P010,
   2464 	DRM_FORMAT_P012,
   2465 	DRM_FORMAT_P016,
   2466 };
   2467 
   2468 static const u32 icl_sdr_y_plane_formats[] = {
   2469 	DRM_FORMAT_C8,
   2470 	DRM_FORMAT_RGB565,
   2471 	DRM_FORMAT_XRGB8888,
   2472 	DRM_FORMAT_XBGR8888,
   2473 	DRM_FORMAT_ARGB8888,
   2474 	DRM_FORMAT_ABGR8888,
   2475 	DRM_FORMAT_XRGB2101010,
   2476 	DRM_FORMAT_XBGR2101010,
   2477 	DRM_FORMAT_ARGB2101010,
   2478 	DRM_FORMAT_ABGR2101010,
   2479 	DRM_FORMAT_YUYV,
   2480 	DRM_FORMAT_YVYU,
   2481 	DRM_FORMAT_UYVY,
   2482 	DRM_FORMAT_VYUY,
   2483 	DRM_FORMAT_Y210,
   2484 	DRM_FORMAT_Y212,
   2485 	DRM_FORMAT_Y216,
   2486 	DRM_FORMAT_XVYU2101010,
   2487 	DRM_FORMAT_XVYU12_16161616,
   2488 	DRM_FORMAT_XVYU16161616,
   2489 };
   2490 
   2491 static const u32 icl_sdr_uv_plane_formats[] = {
   2492 	DRM_FORMAT_C8,
   2493 	DRM_FORMAT_RGB565,
   2494 	DRM_FORMAT_XRGB8888,
   2495 	DRM_FORMAT_XBGR8888,
   2496 	DRM_FORMAT_ARGB8888,
   2497 	DRM_FORMAT_ABGR8888,
   2498 	DRM_FORMAT_XRGB2101010,
   2499 	DRM_FORMAT_XBGR2101010,
   2500 	DRM_FORMAT_ARGB2101010,
   2501 	DRM_FORMAT_ABGR2101010,
   2502 	DRM_FORMAT_YUYV,
   2503 	DRM_FORMAT_YVYU,
   2504 	DRM_FORMAT_UYVY,
   2505 	DRM_FORMAT_VYUY,
   2506 	DRM_FORMAT_NV12,
   2507 	DRM_FORMAT_P010,
   2508 	DRM_FORMAT_P012,
   2509 	DRM_FORMAT_P016,
   2510 	DRM_FORMAT_Y210,
   2511 	DRM_FORMAT_Y212,
   2512 	DRM_FORMAT_Y216,
   2513 	DRM_FORMAT_XVYU2101010,
   2514 	DRM_FORMAT_XVYU12_16161616,
   2515 	DRM_FORMAT_XVYU16161616,
   2516 };
   2517 
   2518 static const u32 icl_hdr_plane_formats[] = {
   2519 	DRM_FORMAT_C8,
   2520 	DRM_FORMAT_RGB565,
   2521 	DRM_FORMAT_XRGB8888,
   2522 	DRM_FORMAT_XBGR8888,
   2523 	DRM_FORMAT_ARGB8888,
   2524 	DRM_FORMAT_ABGR8888,
   2525 	DRM_FORMAT_XRGB2101010,
   2526 	DRM_FORMAT_XBGR2101010,
   2527 	DRM_FORMAT_ARGB2101010,
   2528 	DRM_FORMAT_ABGR2101010,
   2529 	DRM_FORMAT_XRGB16161616F,
   2530 	DRM_FORMAT_XBGR16161616F,
   2531 	DRM_FORMAT_ARGB16161616F,
   2532 	DRM_FORMAT_ABGR16161616F,
   2533 	DRM_FORMAT_YUYV,
   2534 	DRM_FORMAT_YVYU,
   2535 	DRM_FORMAT_UYVY,
   2536 	DRM_FORMAT_VYUY,
   2537 	DRM_FORMAT_NV12,
   2538 	DRM_FORMAT_P010,
   2539 	DRM_FORMAT_P012,
   2540 	DRM_FORMAT_P016,
   2541 	DRM_FORMAT_Y210,
   2542 	DRM_FORMAT_Y212,
   2543 	DRM_FORMAT_Y216,
   2544 	DRM_FORMAT_XVYU2101010,
   2545 	DRM_FORMAT_XVYU12_16161616,
   2546 	DRM_FORMAT_XVYU16161616,
   2547 };
   2548 
   2549 static const u64 skl_plane_format_modifiers_noccs[] = {
   2550 	I915_FORMAT_MOD_Yf_TILED,
   2551 	I915_FORMAT_MOD_Y_TILED,
   2552 	I915_FORMAT_MOD_X_TILED,
   2553 	DRM_FORMAT_MOD_LINEAR,
   2554 	DRM_FORMAT_MOD_INVALID
   2555 };
   2556 
   2557 static const u64 skl_plane_format_modifiers_ccs[] = {
   2558 	I915_FORMAT_MOD_Yf_TILED_CCS,
   2559 	I915_FORMAT_MOD_Y_TILED_CCS,
   2560 	I915_FORMAT_MOD_Yf_TILED,
   2561 	I915_FORMAT_MOD_Y_TILED,
   2562 	I915_FORMAT_MOD_X_TILED,
   2563 	DRM_FORMAT_MOD_LINEAR,
   2564 	DRM_FORMAT_MOD_INVALID
   2565 };
   2566 
   2567 static const u64 gen12_plane_format_modifiers_mc_ccs[] = {
   2568 	I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS,
   2569 	I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS,
   2570 	I915_FORMAT_MOD_Y_TILED,
   2571 	I915_FORMAT_MOD_X_TILED,
   2572 	DRM_FORMAT_MOD_LINEAR,
   2573 	DRM_FORMAT_MOD_INVALID
   2574 };
   2575 
   2576 static const u64 gen12_plane_format_modifiers_rc_ccs[] = {
   2577 	I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS,
   2578 	I915_FORMAT_MOD_Y_TILED,
   2579 	I915_FORMAT_MOD_X_TILED,
   2580 	DRM_FORMAT_MOD_LINEAR,
   2581 	DRM_FORMAT_MOD_INVALID
   2582 };
   2583 
   2584 static bool g4x_sprite_format_mod_supported(struct drm_plane *_plane,
   2585 					    u32 format, u64 modifier)
   2586 {
   2587 	switch (modifier) {
   2588 	case DRM_FORMAT_MOD_LINEAR:
   2589 	case I915_FORMAT_MOD_X_TILED:
   2590 		break;
   2591 	default:
   2592 		return false;
   2593 	}
   2594 
   2595 	switch (format) {
   2596 	case DRM_FORMAT_XRGB8888:
   2597 	case DRM_FORMAT_YUYV:
   2598 	case DRM_FORMAT_YVYU:
   2599 	case DRM_FORMAT_UYVY:
   2600 	case DRM_FORMAT_VYUY:
   2601 		if (modifier == DRM_FORMAT_MOD_LINEAR ||
   2602 		    modifier == I915_FORMAT_MOD_X_TILED)
   2603 			return true;
   2604 		/* fall through */
   2605 	default:
   2606 		return false;
   2607 	}
   2608 }
   2609 
   2610 static bool snb_sprite_format_mod_supported(struct drm_plane *_plane,
   2611 					    u32 format, u64 modifier)
   2612 {
   2613 	switch (modifier) {
   2614 	case DRM_FORMAT_MOD_LINEAR:
   2615 	case I915_FORMAT_MOD_X_TILED:
   2616 		break;
   2617 	default:
   2618 		return false;
   2619 	}
   2620 
   2621 	switch (format) {
   2622 	case DRM_FORMAT_XRGB8888:
   2623 	case DRM_FORMAT_XBGR8888:
   2624 	case DRM_FORMAT_XRGB2101010:
   2625 	case DRM_FORMAT_XBGR2101010:
   2626 	case DRM_FORMAT_XRGB16161616F:
   2627 	case DRM_FORMAT_XBGR16161616F:
   2628 	case DRM_FORMAT_YUYV:
   2629 	case DRM_FORMAT_YVYU:
   2630 	case DRM_FORMAT_UYVY:
   2631 	case DRM_FORMAT_VYUY:
   2632 		if (modifier == DRM_FORMAT_MOD_LINEAR ||
   2633 		    modifier == I915_FORMAT_MOD_X_TILED)
   2634 			return true;
   2635 		/* fall through */
   2636 	default:
   2637 		return false;
   2638 	}
   2639 }
   2640 
   2641 static bool vlv_sprite_format_mod_supported(struct drm_plane *_plane,
   2642 					    u32 format, u64 modifier)
   2643 {
   2644 	switch (modifier) {
   2645 	case DRM_FORMAT_MOD_LINEAR:
   2646 	case I915_FORMAT_MOD_X_TILED:
   2647 		break;
   2648 	default:
   2649 		return false;
   2650 	}
   2651 
   2652 	switch (format) {
   2653 	case DRM_FORMAT_C8:
   2654 	case DRM_FORMAT_RGB565:
   2655 	case DRM_FORMAT_ABGR8888:
   2656 	case DRM_FORMAT_ARGB8888:
   2657 	case DRM_FORMAT_XBGR8888:
   2658 	case DRM_FORMAT_XRGB8888:
   2659 	case DRM_FORMAT_XBGR2101010:
   2660 	case DRM_FORMAT_ABGR2101010:
   2661 	case DRM_FORMAT_XRGB2101010:
   2662 	case DRM_FORMAT_ARGB2101010:
   2663 	case DRM_FORMAT_YUYV:
   2664 	case DRM_FORMAT_YVYU:
   2665 	case DRM_FORMAT_UYVY:
   2666 	case DRM_FORMAT_VYUY:
   2667 		if (modifier == DRM_FORMAT_MOD_LINEAR ||
   2668 		    modifier == I915_FORMAT_MOD_X_TILED)
   2669 			return true;
   2670 		/* fall through */
   2671 	default:
   2672 		return false;
   2673 	}
   2674 }
   2675 
   2676 static bool skl_plane_format_mod_supported(struct drm_plane *_plane,
   2677 					   u32 format, u64 modifier)
   2678 {
   2679 	struct intel_plane *plane = to_intel_plane(_plane);
   2680 
   2681 	switch (modifier) {
   2682 	case DRM_FORMAT_MOD_LINEAR:
   2683 	case I915_FORMAT_MOD_X_TILED:
   2684 	case I915_FORMAT_MOD_Y_TILED:
   2685 	case I915_FORMAT_MOD_Yf_TILED:
   2686 		break;
   2687 	case I915_FORMAT_MOD_Y_TILED_CCS:
   2688 	case I915_FORMAT_MOD_Yf_TILED_CCS:
   2689 		if (!plane->has_ccs)
   2690 			return false;
   2691 		break;
   2692 	default:
   2693 		return false;
   2694 	}
   2695 
   2696 	switch (format) {
   2697 	case DRM_FORMAT_XRGB8888:
   2698 	case DRM_FORMAT_XBGR8888:
   2699 	case DRM_FORMAT_ARGB8888:
   2700 	case DRM_FORMAT_ABGR8888:
   2701 		if (is_ccs_modifier(modifier))
   2702 			return true;
   2703 		/* fall through */
   2704 	case DRM_FORMAT_RGB565:
   2705 	case DRM_FORMAT_XRGB2101010:
   2706 	case DRM_FORMAT_XBGR2101010:
   2707 	case DRM_FORMAT_ARGB2101010:
   2708 	case DRM_FORMAT_ABGR2101010:
   2709 	case DRM_FORMAT_YUYV:
   2710 	case DRM_FORMAT_YVYU:
   2711 	case DRM_FORMAT_UYVY:
   2712 	case DRM_FORMAT_VYUY:
   2713 	case DRM_FORMAT_NV12:
   2714 	case DRM_FORMAT_P010:
   2715 	case DRM_FORMAT_P012:
   2716 	case DRM_FORMAT_P016:
   2717 	case DRM_FORMAT_XVYU2101010:
   2718 		if (modifier == I915_FORMAT_MOD_Yf_TILED)
   2719 			return true;
   2720 		/* fall through */
   2721 	case DRM_FORMAT_C8:
   2722 	case DRM_FORMAT_XBGR16161616F:
   2723 	case DRM_FORMAT_ABGR16161616F:
   2724 	case DRM_FORMAT_XRGB16161616F:
   2725 	case DRM_FORMAT_ARGB16161616F:
   2726 	case DRM_FORMAT_Y210:
   2727 	case DRM_FORMAT_Y212:
   2728 	case DRM_FORMAT_Y216:
   2729 	case DRM_FORMAT_XVYU12_16161616:
   2730 	case DRM_FORMAT_XVYU16161616:
   2731 		if (modifier == DRM_FORMAT_MOD_LINEAR ||
   2732 		    modifier == I915_FORMAT_MOD_X_TILED ||
   2733 		    modifier == I915_FORMAT_MOD_Y_TILED)
   2734 			return true;
   2735 		/* fall through */
   2736 	default:
   2737 		return false;
   2738 	}
   2739 }
   2740 
   2741 static bool gen12_plane_supports_mc_ccs(enum plane_id plane_id)
   2742 {
   2743 	return plane_id < PLANE_SPRITE4;
   2744 }
   2745 
   2746 static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,
   2747 					     u32 format, u64 modifier)
   2748 {
   2749 	struct intel_plane *plane = to_intel_plane(_plane);
   2750 
   2751 	switch (modifier) {
   2752 	case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
   2753 		if (!gen12_plane_supports_mc_ccs(plane->id))
   2754 			return false;
   2755 		/* fall through */
   2756 	case DRM_FORMAT_MOD_LINEAR:
   2757 	case I915_FORMAT_MOD_X_TILED:
   2758 	case I915_FORMAT_MOD_Y_TILED:
   2759 	case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
   2760 		break;
   2761 	default:
   2762 		return false;
   2763 	}
   2764 
   2765 	switch (format) {
   2766 	case DRM_FORMAT_XRGB8888:
   2767 	case DRM_FORMAT_XBGR8888:
   2768 	case DRM_FORMAT_ARGB8888:
   2769 	case DRM_FORMAT_ABGR8888:
   2770 		if (is_ccs_modifier(modifier))
   2771 			return true;
   2772 		/* fall through */
   2773 	case DRM_FORMAT_YUYV:
   2774 	case DRM_FORMAT_YVYU:
   2775 	case DRM_FORMAT_UYVY:
   2776 	case DRM_FORMAT_VYUY:
   2777 	case DRM_FORMAT_NV12:
   2778 	case DRM_FORMAT_P010:
   2779 	case DRM_FORMAT_P012:
   2780 	case DRM_FORMAT_P016:
   2781 		if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS)
   2782 			return true;
   2783 		/* fall through */
   2784 	case DRM_FORMAT_RGB565:
   2785 	case DRM_FORMAT_XRGB2101010:
   2786 	case DRM_FORMAT_XBGR2101010:
   2787 	case DRM_FORMAT_ARGB2101010:
   2788 	case DRM_FORMAT_ABGR2101010:
   2789 	case DRM_FORMAT_XVYU2101010:
   2790 	case DRM_FORMAT_C8:
   2791 	case DRM_FORMAT_XBGR16161616F:
   2792 	case DRM_FORMAT_ABGR16161616F:
   2793 	case DRM_FORMAT_XRGB16161616F:
   2794 	case DRM_FORMAT_ARGB16161616F:
   2795 	case DRM_FORMAT_Y210:
   2796 	case DRM_FORMAT_Y212:
   2797 	case DRM_FORMAT_Y216:
   2798 	case DRM_FORMAT_XVYU12_16161616:
   2799 	case DRM_FORMAT_XVYU16161616:
   2800 		if (modifier == DRM_FORMAT_MOD_LINEAR ||
   2801 		    modifier == I915_FORMAT_MOD_X_TILED ||
   2802 		    modifier == I915_FORMAT_MOD_Y_TILED)
   2803 			return true;
   2804 		/* fall through */
   2805 	default:
   2806 		return false;
   2807 	}
   2808 }
   2809 
   2810 static const struct drm_plane_funcs g4x_sprite_funcs = {
   2811 	.update_plane = drm_atomic_helper_update_plane,
   2812 	.disable_plane = drm_atomic_helper_disable_plane,
   2813 	.destroy = intel_plane_destroy,
   2814 	.atomic_duplicate_state = intel_plane_duplicate_state,
   2815 	.atomic_destroy_state = intel_plane_destroy_state,
   2816 	.format_mod_supported = g4x_sprite_format_mod_supported,
   2817 };
   2818 
   2819 static const struct drm_plane_funcs snb_sprite_funcs = {
   2820 	.update_plane = drm_atomic_helper_update_plane,
   2821 	.disable_plane = drm_atomic_helper_disable_plane,
   2822 	.destroy = intel_plane_destroy,
   2823 	.atomic_duplicate_state = intel_plane_duplicate_state,
   2824 	.atomic_destroy_state = intel_plane_destroy_state,
   2825 	.format_mod_supported = snb_sprite_format_mod_supported,
   2826 };
   2827 
   2828 static const struct drm_plane_funcs vlv_sprite_funcs = {
   2829 	.update_plane = drm_atomic_helper_update_plane,
   2830 	.disable_plane = drm_atomic_helper_disable_plane,
   2831 	.destroy = intel_plane_destroy,
   2832 	.atomic_duplicate_state = intel_plane_duplicate_state,
   2833 	.atomic_destroy_state = intel_plane_destroy_state,
   2834 	.format_mod_supported = vlv_sprite_format_mod_supported,
   2835 };
   2836 
   2837 static const struct drm_plane_funcs skl_plane_funcs = {
   2838 	.update_plane = drm_atomic_helper_update_plane,
   2839 	.disable_plane = drm_atomic_helper_disable_plane,
   2840 	.destroy = intel_plane_destroy,
   2841 	.atomic_duplicate_state = intel_plane_duplicate_state,
   2842 	.atomic_destroy_state = intel_plane_destroy_state,
   2843 	.format_mod_supported = skl_plane_format_mod_supported,
   2844 };
   2845 
   2846 static const struct drm_plane_funcs gen12_plane_funcs = {
   2847 	.update_plane = drm_atomic_helper_update_plane,
   2848 	.disable_plane = drm_atomic_helper_disable_plane,
   2849 	.destroy = intel_plane_destroy,
   2850 	.atomic_duplicate_state = intel_plane_duplicate_state,
   2851 	.atomic_destroy_state = intel_plane_destroy_state,
   2852 	.format_mod_supported = gen12_plane_format_mod_supported,
   2853 };
   2854 
   2855 static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv,
   2856 			      enum pipe pipe, enum plane_id plane_id)
   2857 {
   2858 	if (!HAS_FBC(dev_priv))
   2859 		return false;
   2860 
   2861 	return pipe == PIPE_A && plane_id == PLANE_PRIMARY;
   2862 }
   2863 
   2864 static bool skl_plane_has_planar(struct drm_i915_private *dev_priv,
   2865 				 enum pipe pipe, enum plane_id plane_id)
   2866 {
   2867 	/* Display WA #0870: skl, bxt */
   2868 	if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv))
   2869 		return false;
   2870 
   2871 	if (IS_GEN(dev_priv, 9) && !IS_GEMINILAKE(dev_priv) && pipe == PIPE_C)
   2872 		return false;
   2873 
   2874 	if (plane_id != PLANE_PRIMARY && plane_id != PLANE_SPRITE0)
   2875 		return false;
   2876 
   2877 	return true;
   2878 }
   2879 
   2880 static const u32 *skl_get_plane_formats(struct drm_i915_private *dev_priv,
   2881 					enum pipe pipe, enum plane_id plane_id,
   2882 					int *num_formats)
   2883 {
   2884 	if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
   2885 		*num_formats = ARRAY_SIZE(skl_planar_formats);
   2886 		return skl_planar_formats;
   2887 	} else {
   2888 		*num_formats = ARRAY_SIZE(skl_plane_formats);
   2889 		return skl_plane_formats;
   2890 	}
   2891 }
   2892 
   2893 static const u32 *glk_get_plane_formats(struct drm_i915_private *dev_priv,
   2894 					enum pipe pipe, enum plane_id plane_id,
   2895 					int *num_formats)
   2896 {
   2897 	if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
   2898 		*num_formats = ARRAY_SIZE(glk_planar_formats);
   2899 		return glk_planar_formats;
   2900 	} else {
   2901 		*num_formats = ARRAY_SIZE(skl_plane_formats);
   2902 		return skl_plane_formats;
   2903 	}
   2904 }
   2905 
   2906 static const u32 *icl_get_plane_formats(struct drm_i915_private *dev_priv,
   2907 					enum pipe pipe, enum plane_id plane_id,
   2908 					int *num_formats)
   2909 {
   2910 	if (icl_is_hdr_plane(dev_priv, plane_id)) {
   2911 		*num_formats = ARRAY_SIZE(icl_hdr_plane_formats);
   2912 		return icl_hdr_plane_formats;
   2913 	} else if (icl_is_nv12_y_plane(plane_id)) {
   2914 		*num_formats = ARRAY_SIZE(icl_sdr_y_plane_formats);
   2915 		return icl_sdr_y_plane_formats;
   2916 	} else {
   2917 		*num_formats = ARRAY_SIZE(icl_sdr_uv_plane_formats);
   2918 		return icl_sdr_uv_plane_formats;
   2919 	}
   2920 }
   2921 
   2922 static const u64 *gen12_get_plane_modifiers(enum plane_id plane_id)
   2923 {
   2924 	if (gen12_plane_supports_mc_ccs(plane_id))
   2925 		return gen12_plane_format_modifiers_mc_ccs;
   2926 	else
   2927 		return gen12_plane_format_modifiers_rc_ccs;
   2928 }
   2929 
   2930 static bool skl_plane_has_ccs(struct drm_i915_private *dev_priv,
   2931 			      enum pipe pipe, enum plane_id plane_id)
   2932 {
   2933 	if (plane_id == PLANE_CURSOR)
   2934 		return false;
   2935 
   2936 	if (INTEL_GEN(dev_priv) >= 10)
   2937 		return true;
   2938 
   2939 	if (IS_GEMINILAKE(dev_priv))
   2940 		return pipe != PIPE_C;
   2941 
   2942 	return pipe != PIPE_C &&
   2943 		(plane_id == PLANE_PRIMARY ||
   2944 		 plane_id == PLANE_SPRITE0);
   2945 }
   2946 
   2947 struct intel_plane *
   2948 skl_universal_plane_create(struct drm_i915_private *dev_priv,
   2949 			   enum pipe pipe, enum plane_id plane_id)
   2950 {
   2951 	const struct drm_plane_funcs *plane_funcs;
   2952 	struct intel_plane *plane;
   2953 	enum drm_plane_type plane_type;
   2954 	unsigned int supported_rotations;
   2955 	unsigned int possible_crtcs;
   2956 	const u64 *modifiers;
   2957 	const u32 *formats;
   2958 	int num_formats;
   2959 	int ret;
   2960 
   2961 	plane = intel_plane_alloc();
   2962 	if (IS_ERR(plane))
   2963 		return plane;
   2964 
   2965 	plane->pipe = pipe;
   2966 	plane->id = plane_id;
   2967 	plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane_id);
   2968 
   2969 	plane->has_fbc = skl_plane_has_fbc(dev_priv, pipe, plane_id);
   2970 	if (plane->has_fbc) {
   2971 		struct intel_fbc *fbc = &dev_priv->fbc;
   2972 
   2973 		fbc->possible_framebuffer_bits |= plane->frontbuffer_bit;
   2974 	}
   2975 
   2976 	plane->max_stride = skl_plane_max_stride;
   2977 	plane->update_plane = skl_update_plane;
   2978 	plane->disable_plane = skl_disable_plane;
   2979 	plane->get_hw_state = skl_plane_get_hw_state;
   2980 	plane->check_plane = skl_plane_check;
   2981 	plane->min_cdclk = skl_plane_min_cdclk;
   2982 
   2983 	if (INTEL_GEN(dev_priv) >= 11)
   2984 		formats = icl_get_plane_formats(dev_priv, pipe,
   2985 						plane_id, &num_formats);
   2986 	else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
   2987 		formats = glk_get_plane_formats(dev_priv, pipe,
   2988 						plane_id, &num_formats);
   2989 	else
   2990 		formats = skl_get_plane_formats(dev_priv, pipe,
   2991 						plane_id, &num_formats);
   2992 
   2993 	plane->has_ccs = skl_plane_has_ccs(dev_priv, pipe, plane_id);
   2994 	if (INTEL_GEN(dev_priv) >= 12) {
   2995 		modifiers = gen12_get_plane_modifiers(plane_id);
   2996 		plane_funcs = &gen12_plane_funcs;
   2997 	} else {
   2998 		if (plane->has_ccs)
   2999 			modifiers = skl_plane_format_modifiers_ccs;
   3000 		else
   3001 			modifiers = skl_plane_format_modifiers_noccs;
   3002 		plane_funcs = &skl_plane_funcs;
   3003 	}
   3004 
   3005 	if (plane_id == PLANE_PRIMARY)
   3006 		plane_type = DRM_PLANE_TYPE_PRIMARY;
   3007 	else
   3008 		plane_type = DRM_PLANE_TYPE_OVERLAY;
   3009 
   3010 	possible_crtcs = BIT(pipe);
   3011 
   3012 	ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
   3013 				       possible_crtcs, plane_funcs,
   3014 				       formats, num_formats, modifiers,
   3015 				       plane_type,
   3016 				       "plane %d%c", plane_id + 1,
   3017 				       pipe_name(pipe));
   3018 	if (ret)
   3019 		goto fail;
   3020 
   3021 	supported_rotations =
   3022 		DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 |
   3023 		DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270;
   3024 
   3025 	if (INTEL_GEN(dev_priv) >= 10)
   3026 		supported_rotations |= DRM_MODE_REFLECT_X;
   3027 
   3028 	drm_plane_create_rotation_property(&plane->base,
   3029 					   DRM_MODE_ROTATE_0,
   3030 					   supported_rotations);
   3031 
   3032 	drm_plane_create_color_properties(&plane->base,
   3033 					  BIT(DRM_COLOR_YCBCR_BT601) |
   3034 					  BIT(DRM_COLOR_YCBCR_BT709),
   3035 					  BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
   3036 					  BIT(DRM_COLOR_YCBCR_FULL_RANGE),
   3037 					  DRM_COLOR_YCBCR_BT709,
   3038 					  DRM_COLOR_YCBCR_LIMITED_RANGE);
   3039 
   3040 	drm_plane_create_alpha_property(&plane->base);
   3041 	drm_plane_create_blend_mode_property(&plane->base,
   3042 					     BIT(DRM_MODE_BLEND_PIXEL_NONE) |
   3043 					     BIT(DRM_MODE_BLEND_PREMULTI) |
   3044 					     BIT(DRM_MODE_BLEND_COVERAGE));
   3045 
   3046 	drm_plane_create_zpos_immutable_property(&plane->base, plane_id);
   3047 
   3048 	drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
   3049 
   3050 	return plane;
   3051 
   3052 fail:
   3053 	intel_plane_free(plane);
   3054 
   3055 	return ERR_PTR(ret);
   3056 }
   3057 
   3058 struct intel_plane *
   3059 intel_sprite_plane_create(struct drm_i915_private *dev_priv,
   3060 			  enum pipe pipe, int sprite)
   3061 {
   3062 	struct intel_plane *plane;
   3063 	const struct drm_plane_funcs *plane_funcs;
   3064 	unsigned long possible_crtcs;
   3065 	unsigned int supported_rotations;
   3066 	const u64 *modifiers;
   3067 	const u32 *formats;
   3068 	int num_formats;
   3069 	int ret, zpos;
   3070 
   3071 	if (INTEL_GEN(dev_priv) >= 9)
   3072 		return skl_universal_plane_create(dev_priv, pipe,
   3073 						  PLANE_SPRITE0 + sprite);
   3074 
   3075 	plane = intel_plane_alloc();
   3076 	if (IS_ERR(plane))
   3077 		return plane;
   3078 
   3079 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
   3080 		plane->max_stride = i9xx_plane_max_stride;
   3081 		plane->update_plane = vlv_update_plane;
   3082 		plane->disable_plane = vlv_disable_plane;
   3083 		plane->get_hw_state = vlv_plane_get_hw_state;
   3084 		plane->check_plane = vlv_sprite_check;
   3085 		plane->min_cdclk = vlv_plane_min_cdclk;
   3086 
   3087 		if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
   3088 			formats = chv_pipe_b_sprite_formats;
   3089 			num_formats = ARRAY_SIZE(chv_pipe_b_sprite_formats);
   3090 		} else {
   3091 			formats = vlv_plane_formats;
   3092 			num_formats = ARRAY_SIZE(vlv_plane_formats);
   3093 		}
   3094 		modifiers = i9xx_plane_format_modifiers;
   3095 
   3096 		plane_funcs = &vlv_sprite_funcs;
   3097 	} else if (INTEL_GEN(dev_priv) >= 7) {
   3098 		plane->max_stride = g4x_sprite_max_stride;
   3099 		plane->update_plane = ivb_update_plane;
   3100 		plane->disable_plane = ivb_disable_plane;
   3101 		plane->get_hw_state = ivb_plane_get_hw_state;
   3102 		plane->check_plane = g4x_sprite_check;
   3103 
   3104 		if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
   3105 			plane->min_cdclk = hsw_plane_min_cdclk;
   3106 		else
   3107 			plane->min_cdclk = ivb_sprite_min_cdclk;
   3108 
   3109 		formats = snb_plane_formats;
   3110 		num_formats = ARRAY_SIZE(snb_plane_formats);
   3111 		modifiers = i9xx_plane_format_modifiers;
   3112 
   3113 		plane_funcs = &snb_sprite_funcs;
   3114 	} else {
   3115 		plane->max_stride = g4x_sprite_max_stride;
   3116 		plane->update_plane = g4x_update_plane;
   3117 		plane->disable_plane = g4x_disable_plane;
   3118 		plane->get_hw_state = g4x_plane_get_hw_state;
   3119 		plane->check_plane = g4x_sprite_check;
   3120 		plane->min_cdclk = g4x_sprite_min_cdclk;
   3121 
   3122 		modifiers = i9xx_plane_format_modifiers;
   3123 		if (IS_GEN(dev_priv, 6)) {
   3124 			formats = snb_plane_formats;
   3125 			num_formats = ARRAY_SIZE(snb_plane_formats);
   3126 
   3127 			plane_funcs = &snb_sprite_funcs;
   3128 		} else {
   3129 			formats = g4x_plane_formats;
   3130 			num_formats = ARRAY_SIZE(g4x_plane_formats);
   3131 
   3132 			plane_funcs = &g4x_sprite_funcs;
   3133 		}
   3134 	}
   3135 
   3136 	if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
   3137 		supported_rotations =
   3138 			DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
   3139 			DRM_MODE_REFLECT_X;
   3140 	} else {
   3141 		supported_rotations =
   3142 			DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
   3143 	}
   3144 
   3145 	plane->pipe = pipe;
   3146 	plane->id = PLANE_SPRITE0 + sprite;
   3147 	plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id);
   3148 
   3149 	possible_crtcs = BIT(pipe);
   3150 
   3151 	ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
   3152 				       possible_crtcs, plane_funcs,
   3153 				       formats, num_formats, modifiers,
   3154 				       DRM_PLANE_TYPE_OVERLAY,
   3155 				       "sprite %c", sprite_name(pipe, sprite));
   3156 	if (ret)
   3157 		goto fail;
   3158 
   3159 	drm_plane_create_rotation_property(&plane->base,
   3160 					   DRM_MODE_ROTATE_0,
   3161 					   supported_rotations);
   3162 
   3163 	drm_plane_create_color_properties(&plane->base,
   3164 					  BIT(DRM_COLOR_YCBCR_BT601) |
   3165 					  BIT(DRM_COLOR_YCBCR_BT709),
   3166 					  BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
   3167 					  BIT(DRM_COLOR_YCBCR_FULL_RANGE),
   3168 					  DRM_COLOR_YCBCR_BT709,
   3169 					  DRM_COLOR_YCBCR_LIMITED_RANGE);
   3170 
   3171 	zpos = sprite + 1;
   3172 	drm_plane_create_zpos_immutable_property(&plane->base, zpos);
   3173 
   3174 	drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
   3175 
   3176 	return plane;
   3177 
   3178 fail:
   3179 	intel_plane_free(plane);
   3180 
   3181 	return ERR_PTR(ret);
   3182 }
   3183