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