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