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