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