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