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 stride = plane_state->color_plane[0].stride;
1532 	unsigned int cpp = fb->format->cpp[0];
1533 	unsigned int width_bytes;
1534 	int min_width, min_height;
1535 
1536 	crtc_w = drm_rect_width(dst);
1537 	crtc_h = drm_rect_height(dst);
1538 
1539 	src_x = src->x1 >> 16;
1540 	src_w = drm_rect_width(src) >> 16;
1541 	src_h = drm_rect_height(src) >> 16;
1542 
1543 	if (src_w == crtc_w && src_h == crtc_h)
1544 		return 0;
1545 
1546 	min_width = 3;
1547 
1548 	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
1549 		if (src_h & 1) {
1550 			DRM_DEBUG_KMS("Source height must be even with interlaced modes\n");
1551 			return -EINVAL;
1552 		}
1553 		min_height = 6;
1554 	} else {
1555 		min_height = 3;
1556 	}
1557 
1558 	width_bytes = ((src_x * cpp) & 63) + src_w * cpp;
1559 
1560 	if (src_w < min_width || src_h < min_height ||
1561 	    src_w > 2048 || src_h > 2048) {
1562 		DRM_DEBUG_KMS("Source dimensions (%dx%d) exceed hardware limits (%dx%d - %dx%d)\n",
1563 			      src_w, src_h, min_width, min_height, 2048, 2048);
1564 		return -EINVAL;
1565 	}
1566 
1567 	if (width_bytes > 4096) {
1568 		DRM_DEBUG_KMS("Fetch width (%d) exceeds hardware max with scaling (%u)\n",
1569 			      width_bytes, 4096);
1570 		return -EINVAL;
1571 	}
1572 
1573 	if (stride > 4096) {
1574 		DRM_DEBUG_KMS("Stride (%u) exceeds hardware max with scaling (%u)\n",
1575 			      stride, 4096);
1576 		return -EINVAL;
1577 	}
1578 
1579 	return 0;
1580 }
1581 
1582 static int
1583 g4x_sprite_check(struct intel_crtc_state *crtc_state,
1584 		 struct intel_plane_state *plane_state)
1585 {
1586 	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1587 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1588 	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
1589 	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
1590 	int ret;
1591 
1592 	if (intel_fb_scalable(plane_state->base.fb)) {
1593 		if (INTEL_GEN(dev_priv) < 7) {
1594 			min_scale = 1;
1595 			max_scale = 16 << 16;
1596 		} else if (IS_IVYBRIDGE(dev_priv)) {
1597 			min_scale = 1;
1598 			max_scale = 2 << 16;
1599 		}
1600 	}
1601 
1602 	ret = drm_atomic_helper_check_plane_state(&plane_state->base,
1603 						  &crtc_state->base,
1604 						  min_scale, max_scale,
1605 						  true, true);
1606 	if (ret)
1607 		return ret;
1608 
1609 	ret = i9xx_check_plane_surface(plane_state);
1610 	if (ret)
1611 		return ret;
1612 
1613 	if (!plane_state->base.visible)
1614 		return 0;
1615 
1616 	ret = intel_plane_check_src_coordinates(plane_state);
1617 	if (ret)
1618 		return ret;
1619 
1620 	ret = g4x_sprite_check_scaling(crtc_state, plane_state);
1621 	if (ret)
1622 		return ret;
1623 
1624 	if (INTEL_GEN(dev_priv) >= 7)
1625 		plane_state->ctl = ivb_sprite_ctl(crtc_state, plane_state);
1626 	else
1627 		plane_state->ctl = g4x_sprite_ctl(crtc_state, plane_state);
1628 
1629 	return 0;
1630 }
1631 
1632 int chv_plane_check_rotation(const struct intel_plane_state *plane_state)
1633 {
1634 	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1635 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1636 	unsigned int rotation = plane_state->base.rotation;
1637 
1638 	/* CHV ignores the mirror bit when the rotate bit is set :( */
1639 	if (IS_CHERRYVIEW(dev_priv) &&
1640 	    rotation & DRM_MODE_ROTATE_180 &&
1641 	    rotation & DRM_MODE_REFLECT_X) {
1642 		DRM_DEBUG_KMS("Cannot rotate and reflect at the same time\n");
1643 		return -EINVAL;
1644 	}
1645 
1646 	return 0;
1647 }
1648 
1649 static int
1650 vlv_sprite_check(struct intel_crtc_state *crtc_state,
1651 		 struct intel_plane_state *plane_state)
1652 {
1653 	int ret;
1654 
1655 	ret = chv_plane_check_rotation(plane_state);
1656 	if (ret)
1657 		return ret;
1658 
1659 	ret = drm_atomic_helper_check_plane_state(&plane_state->base,
1660 						  &crtc_state->base,
1661 						  DRM_PLANE_HELPER_NO_SCALING,
1662 						  DRM_PLANE_HELPER_NO_SCALING,
1663 						  true, true);
1664 	if (ret)
1665 		return ret;
1666 
1667 	ret = i9xx_check_plane_surface(plane_state);
1668 	if (ret)
1669 		return ret;
1670 
1671 	if (!plane_state->base.visible)
1672 		return 0;
1673 
1674 	ret = intel_plane_check_src_coordinates(plane_state);
1675 	if (ret)
1676 		return ret;
1677 
1678 	plane_state->ctl = vlv_sprite_ctl(crtc_state, plane_state);
1679 
1680 	return 0;
1681 }
1682 
1683 static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
1684 			      const struct intel_plane_state *plane_state)
1685 {
1686 	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1687 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1688 	const struct drm_framebuffer *fb = plane_state->base.fb;
1689 	unsigned int rotation = plane_state->base.rotation;
1690 	struct drm_format_name_buf format_name;
1691 
1692 	if (!fb)
1693 		return 0;
1694 
1695 	if (rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180) &&
1696 	    is_ccs_modifier(fb->modifier)) {
1697 		DRM_DEBUG_KMS("RC support only with 0/180 degree rotation (%x)\n",
1698 			      rotation);
1699 		return -EINVAL;
1700 	}
1701 
1702 	if (rotation & DRM_MODE_REFLECT_X &&
1703 	    fb->modifier == DRM_FORMAT_MOD_LINEAR) {
1704 		DRM_DEBUG_KMS("horizontal flip is not supported with linear surface formats\n");
1705 		return -EINVAL;
1706 	}
1707 
1708 	if (drm_rotation_90_or_270(rotation)) {
1709 		if (fb->modifier != I915_FORMAT_MOD_Y_TILED &&
1710 		    fb->modifier != I915_FORMAT_MOD_Yf_TILED) {
1711 			DRM_DEBUG_KMS("Y/Yf tiling required for 90/270!\n");
1712 			return -EINVAL;
1713 		}
1714 
1715 		/*
1716 		 * 90/270 is not allowed with RGB64 16:16:16:16 and
1717 		 * Indexed 8-bit. RGB 16-bit 5:6:5 is allowed gen11 onwards.
1718 		 */
1719 		switch (fb->format->format) {
1720 		case DRM_FORMAT_RGB565:
1721 			if (INTEL_GEN(dev_priv) >= 11)
1722 				break;
1723 			/* fall through */
1724 		case DRM_FORMAT_C8:
1725 		case DRM_FORMAT_XRGB16161616F:
1726 		case DRM_FORMAT_XBGR16161616F:
1727 		case DRM_FORMAT_ARGB16161616F:
1728 		case DRM_FORMAT_ABGR16161616F:
1729 		case DRM_FORMAT_Y210:
1730 		case DRM_FORMAT_Y212:
1731 		case DRM_FORMAT_Y216:
1732 		case DRM_FORMAT_XVYU12_16161616:
1733 		case DRM_FORMAT_XVYU16161616:
1734 			DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n",
1735 				      drm_get_format_name(fb->format->format,
1736 							  &format_name));
1737 			return -EINVAL;
1738 		default:
1739 			break;
1740 		}
1741 	}
1742 
1743 	/* Y-tiling is not supported in IF-ID Interlace mode */
1744 	if (crtc_state->base.enable &&
1745 	    crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE &&
1746 	    (fb->modifier == I915_FORMAT_MOD_Y_TILED ||
1747 	     fb->modifier == I915_FORMAT_MOD_Yf_TILED ||
1748 	     fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
1749 	     fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS)) {
1750 		DRM_DEBUG_KMS("Y/Yf tiling not supported in IF-ID mode\n");
1751 		return -EINVAL;
1752 	}
1753 
1754 	return 0;
1755 }
1756 
1757 static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_state,
1758 					   const struct intel_plane_state *plane_state)
1759 {
1760 	struct drm_i915_private *dev_priv =
1761 		to_i915(plane_state->base.plane->dev);
1762 	int crtc_x = plane_state->base.dst.x1;
1763 	int crtc_w = drm_rect_width(&plane_state->base.dst);
1764 	int pipe_src_w = crtc_state->pipe_src_w;
1765 
1766 	/*
1767 	 * Display WA #1175: cnl,glk
1768 	 * Planes other than the cursor may cause FIFO underflow and display
1769 	 * corruption if starting less than 4 pixels from the right edge of
1770 	 * the screen.
1771 	 * Besides the above WA fix the similar problem, where planes other
1772 	 * than the cursor ending less than 4 pixels from the left edge of the
1773 	 * screen may cause FIFO underflow and display corruption.
1774 	 */
1775 	if ((IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) &&
1776 	    (crtc_x + crtc_w < 4 || crtc_x > pipe_src_w - 4)) {
1777 		DRM_DEBUG_KMS("requested plane X %s position %d invalid (valid range %d-%d)\n",
1778 			      crtc_x + crtc_w < 4 ? "end" : "start",
1779 			      crtc_x + crtc_w < 4 ? crtc_x + crtc_w : crtc_x,
1780 			      4, pipe_src_w - 4);
1781 		return -ERANGE;
1782 	}
1783 
1784 	return 0;
1785 }
1786 
1787 static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_state)
1788 {
1789 	const struct drm_framebuffer *fb = plane_state->base.fb;
1790 	unsigned int rotation = plane_state->base.rotation;
1791 	int src_w = drm_rect_width(&plane_state->base.src) >> 16;
1792 
1793 	/* Display WA #1106 */
1794 	if (is_planar_yuv_format(fb->format->format) && src_w & 3 &&
1795 	    (rotation == DRM_MODE_ROTATE_270 ||
1796 	     rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) {
1797 		DRM_DEBUG_KMS("src width must be multiple of 4 for rotated planar YUV\n");
1798 		return -EINVAL;
1799 	}
1800 
1801 	return 0;
1802 }
1803 
1804 static int skl_plane_check(struct intel_crtc_state *crtc_state,
1805 			   struct intel_plane_state *plane_state)
1806 {
1807 	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1808 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1809 	const struct drm_framebuffer *fb = plane_state->base.fb;
1810 	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
1811 	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
1812 	int ret;
1813 
1814 	ret = skl_plane_check_fb(crtc_state, plane_state);
1815 	if (ret)
1816 		return ret;
1817 
1818 	/* use scaler when colorkey is not required */
1819 	if (!plane_state->ckey.flags && intel_fb_scalable(fb)) {
1820 		min_scale = 1;
1821 		max_scale = skl_max_scale(crtc_state, fb->format->format);
1822 	}
1823 
1824 	ret = drm_atomic_helper_check_plane_state(&plane_state->base,
1825 						  &crtc_state->base,
1826 						  min_scale, max_scale,
1827 						  true, true);
1828 	if (ret)
1829 		return ret;
1830 
1831 	ret = skl_check_plane_surface(plane_state);
1832 	if (ret)
1833 		return ret;
1834 
1835 	if (!plane_state->base.visible)
1836 		return 0;
1837 
1838 	ret = skl_plane_check_dst_coordinates(crtc_state, plane_state);
1839 	if (ret)
1840 		return ret;
1841 
1842 	ret = intel_plane_check_src_coordinates(plane_state);
1843 	if (ret)
1844 		return ret;
1845 
1846 	ret = skl_plane_check_nv12_rotation(plane_state);
1847 	if (ret)
1848 		return ret;
1849 
1850 	/* HW only has 8 bits pixel precision, disable plane if invisible */
1851 	if (!(plane_state->base.alpha >> 8))
1852 		plane_state->base.visible = false;
1853 
1854 	plane_state->ctl = skl_plane_ctl(crtc_state, plane_state);
1855 
1856 	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
1857 		plane_state->color_ctl = glk_plane_color_ctl(crtc_state,
1858 							     plane_state);
1859 
1860 	return 0;
1861 }
1862 
1863 static bool has_dst_key_in_primary_plane(struct drm_i915_private *dev_priv)
1864 {
1865 	return INTEL_GEN(dev_priv) >= 9;
1866 }
1867 
1868 static void intel_plane_set_ckey(struct intel_plane_state *plane_state,
1869 				 const struct drm_intel_sprite_colorkey *set)
1870 {
1871 	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1872 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1873 	struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1874 
1875 	*key = *set;
1876 
1877 	/*
1878 	 * We want src key enabled on the
1879 	 * sprite and not on the primary.
1880 	 */
1881 	if (plane->id == PLANE_PRIMARY &&
1882 	    set->flags & I915_SET_COLORKEY_SOURCE)
1883 		key->flags = 0;
1884 
1885 	/*
1886 	 * On SKL+ we want dst key enabled on
1887 	 * the primary and not on the sprite.
1888 	 */
1889 	if (INTEL_GEN(dev_priv) >= 9 && plane->id != PLANE_PRIMARY &&
1890 	    set->flags & I915_SET_COLORKEY_DESTINATION)
1891 		key->flags = 0;
1892 }
1893 
1894 int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
1895 				    struct drm_file *file_priv)
1896 {
1897 	struct drm_i915_private *dev_priv = to_i915(dev);
1898 	struct drm_intel_sprite_colorkey *set = data;
1899 	struct drm_plane *plane;
1900 	struct drm_plane_state *plane_state;
1901 	struct drm_atomic_state *state;
1902 	struct drm_modeset_acquire_ctx ctx;
1903 	int ret = 0;
1904 
1905 	/* ignore the pointless "none" flag */
1906 	set->flags &= ~I915_SET_COLORKEY_NONE;
1907 
1908 	if (set->flags & ~(I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
1909 		return -EINVAL;
1910 
1911 	/* Make sure we don't try to enable both src & dest simultaneously */
1912 	if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
1913 		return -EINVAL;
1914 
1915 	if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
1916 	    set->flags & I915_SET_COLORKEY_DESTINATION)
1917 		return -EINVAL;
1918 
1919 	plane = drm_plane_find(dev, file_priv, set->plane_id);
1920 	if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY)
1921 		return -ENOENT;
1922 
1923 	/*
1924 	 * SKL+ only plane 2 can do destination keying against plane 1.
1925 	 * Also multiple planes can't do destination keying on the same
1926 	 * pipe simultaneously.
1927 	 */
1928 	if (INTEL_GEN(dev_priv) >= 9 &&
1929 	    to_intel_plane(plane)->id >= PLANE_SPRITE1 &&
1930 	    set->flags & I915_SET_COLORKEY_DESTINATION)
1931 		return -EINVAL;
1932 
1933 	drm_modeset_acquire_init(&ctx, 0);
1934 
1935 	state = drm_atomic_state_alloc(plane->dev);
1936 	if (!state) {
1937 		ret = -ENOMEM;
1938 		goto out;
1939 	}
1940 	state->acquire_ctx = &ctx;
1941 
1942 	while (1) {
1943 		plane_state = drm_atomic_get_plane_state(state, plane);
1944 		ret = PTR_ERR_OR_ZERO(plane_state);
1945 		if (!ret)
1946 			intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
1947 
1948 		/*
1949 		 * On some platforms we have to configure
1950 		 * the dst colorkey on the primary plane.
1951 		 */
1952 		if (!ret && has_dst_key_in_primary_plane(dev_priv)) {
1953 			struct intel_crtc *crtc =
1954 				intel_get_crtc_for_pipe(dev_priv,
1955 							to_intel_plane(plane)->pipe);
1956 
1957 			plane_state = drm_atomic_get_plane_state(state,
1958 								 crtc->base.primary);
1959 			ret = PTR_ERR_OR_ZERO(plane_state);
1960 			if (!ret)
1961 				intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
1962 		}
1963 
1964 		if (!ret)
1965 			ret = drm_atomic_commit(state);
1966 
1967 		if (ret != -EDEADLK)
1968 			break;
1969 
1970 		drm_atomic_state_clear(state);
1971 		drm_modeset_backoff(&ctx);
1972 	}
1973 
1974 	drm_atomic_state_put(state);
1975 out:
1976 	drm_modeset_drop_locks(&ctx);
1977 	drm_modeset_acquire_fini(&ctx);
1978 	return ret;
1979 }
1980 
1981 static const u32 g4x_plane_formats[] = {
1982 	DRM_FORMAT_XRGB8888,
1983 	DRM_FORMAT_YUYV,
1984 	DRM_FORMAT_YVYU,
1985 	DRM_FORMAT_UYVY,
1986 	DRM_FORMAT_VYUY,
1987 };
1988 
1989 static const u64 i9xx_plane_format_modifiers[] = {
1990 	I915_FORMAT_MOD_X_TILED,
1991 	DRM_FORMAT_MOD_LINEAR,
1992 	DRM_FORMAT_MOD_INVALID
1993 };
1994 
1995 static const u32 snb_plane_formats[] = {
1996 	DRM_FORMAT_XBGR8888,
1997 	DRM_FORMAT_XRGB8888,
1998 	DRM_FORMAT_YUYV,
1999 	DRM_FORMAT_YVYU,
2000 	DRM_FORMAT_UYVY,
2001 	DRM_FORMAT_VYUY,
2002 };
2003 
2004 static const u32 vlv_plane_formats[] = {
2005 	DRM_FORMAT_RGB565,
2006 	DRM_FORMAT_ABGR8888,
2007 	DRM_FORMAT_ARGB8888,
2008 	DRM_FORMAT_XBGR8888,
2009 	DRM_FORMAT_XRGB8888,
2010 	DRM_FORMAT_XBGR2101010,
2011 	DRM_FORMAT_ABGR2101010,
2012 	DRM_FORMAT_YUYV,
2013 	DRM_FORMAT_YVYU,
2014 	DRM_FORMAT_UYVY,
2015 	DRM_FORMAT_VYUY,
2016 };
2017 
2018 static const u32 skl_plane_formats[] = {
2019 	DRM_FORMAT_C8,
2020 	DRM_FORMAT_RGB565,
2021 	DRM_FORMAT_XRGB8888,
2022 	DRM_FORMAT_XBGR8888,
2023 	DRM_FORMAT_ARGB8888,
2024 	DRM_FORMAT_ABGR8888,
2025 	DRM_FORMAT_XRGB2101010,
2026 	DRM_FORMAT_XBGR2101010,
2027 	DRM_FORMAT_YUYV,
2028 	DRM_FORMAT_YVYU,
2029 	DRM_FORMAT_UYVY,
2030 	DRM_FORMAT_VYUY,
2031 };
2032 
2033 static const u32 skl_planar_formats[] = {
2034 	DRM_FORMAT_C8,
2035 	DRM_FORMAT_RGB565,
2036 	DRM_FORMAT_XRGB8888,
2037 	DRM_FORMAT_XBGR8888,
2038 	DRM_FORMAT_ARGB8888,
2039 	DRM_FORMAT_ABGR8888,
2040 	DRM_FORMAT_XRGB2101010,
2041 	DRM_FORMAT_XBGR2101010,
2042 	DRM_FORMAT_YUYV,
2043 	DRM_FORMAT_YVYU,
2044 	DRM_FORMAT_UYVY,
2045 	DRM_FORMAT_VYUY,
2046 	DRM_FORMAT_NV12,
2047 };
2048 
2049 static const u32 glk_planar_formats[] = {
2050 	DRM_FORMAT_C8,
2051 	DRM_FORMAT_RGB565,
2052 	DRM_FORMAT_XRGB8888,
2053 	DRM_FORMAT_XBGR8888,
2054 	DRM_FORMAT_ARGB8888,
2055 	DRM_FORMAT_ABGR8888,
2056 	DRM_FORMAT_XRGB2101010,
2057 	DRM_FORMAT_XBGR2101010,
2058 	DRM_FORMAT_YUYV,
2059 	DRM_FORMAT_YVYU,
2060 	DRM_FORMAT_UYVY,
2061 	DRM_FORMAT_VYUY,
2062 	DRM_FORMAT_NV12,
2063 	DRM_FORMAT_P010,
2064 	DRM_FORMAT_P012,
2065 	DRM_FORMAT_P016,
2066 };
2067 
2068 static const u32 icl_sdr_y_plane_formats[] = {
2069 	DRM_FORMAT_C8,
2070 	DRM_FORMAT_RGB565,
2071 	DRM_FORMAT_XRGB8888,
2072 	DRM_FORMAT_XBGR8888,
2073 	DRM_FORMAT_ARGB8888,
2074 	DRM_FORMAT_ABGR8888,
2075 	DRM_FORMAT_XRGB2101010,
2076 	DRM_FORMAT_XBGR2101010,
2077 	DRM_FORMAT_YUYV,
2078 	DRM_FORMAT_YVYU,
2079 	DRM_FORMAT_UYVY,
2080 	DRM_FORMAT_VYUY,
2081 	DRM_FORMAT_Y210,
2082 	DRM_FORMAT_Y212,
2083 	DRM_FORMAT_Y216,
2084 	DRM_FORMAT_XVYU2101010,
2085 	DRM_FORMAT_XVYU12_16161616,
2086 	DRM_FORMAT_XVYU16161616,
2087 };
2088 
2089 static const u32 icl_sdr_uv_plane_formats[] = {
2090 	DRM_FORMAT_C8,
2091 	DRM_FORMAT_RGB565,
2092 	DRM_FORMAT_XRGB8888,
2093 	DRM_FORMAT_XBGR8888,
2094 	DRM_FORMAT_ARGB8888,
2095 	DRM_FORMAT_ABGR8888,
2096 	DRM_FORMAT_XRGB2101010,
2097 	DRM_FORMAT_XBGR2101010,
2098 	DRM_FORMAT_YUYV,
2099 	DRM_FORMAT_YVYU,
2100 	DRM_FORMAT_UYVY,
2101 	DRM_FORMAT_VYUY,
2102 	DRM_FORMAT_NV12,
2103 	DRM_FORMAT_P010,
2104 	DRM_FORMAT_P012,
2105 	DRM_FORMAT_P016,
2106 	DRM_FORMAT_Y210,
2107 	DRM_FORMAT_Y212,
2108 	DRM_FORMAT_Y216,
2109 	DRM_FORMAT_XVYU2101010,
2110 	DRM_FORMAT_XVYU12_16161616,
2111 	DRM_FORMAT_XVYU16161616,
2112 };
2113 
2114 static const u32 icl_hdr_plane_formats[] = {
2115 	DRM_FORMAT_C8,
2116 	DRM_FORMAT_RGB565,
2117 	DRM_FORMAT_XRGB8888,
2118 	DRM_FORMAT_XBGR8888,
2119 	DRM_FORMAT_ARGB8888,
2120 	DRM_FORMAT_ABGR8888,
2121 	DRM_FORMAT_XRGB2101010,
2122 	DRM_FORMAT_XBGR2101010,
2123 	DRM_FORMAT_XRGB16161616F,
2124 	DRM_FORMAT_XBGR16161616F,
2125 	DRM_FORMAT_ARGB16161616F,
2126 	DRM_FORMAT_ABGR16161616F,
2127 	DRM_FORMAT_YUYV,
2128 	DRM_FORMAT_YVYU,
2129 	DRM_FORMAT_UYVY,
2130 	DRM_FORMAT_VYUY,
2131 	DRM_FORMAT_NV12,
2132 	DRM_FORMAT_P010,
2133 	DRM_FORMAT_P012,
2134 	DRM_FORMAT_P016,
2135 	DRM_FORMAT_Y210,
2136 	DRM_FORMAT_Y212,
2137 	DRM_FORMAT_Y216,
2138 	DRM_FORMAT_XVYU2101010,
2139 	DRM_FORMAT_XVYU12_16161616,
2140 	DRM_FORMAT_XVYU16161616,
2141 };
2142 
2143 static const u64 skl_plane_format_modifiers_noccs[] = {
2144 	I915_FORMAT_MOD_Yf_TILED,
2145 	I915_FORMAT_MOD_Y_TILED,
2146 	I915_FORMAT_MOD_X_TILED,
2147 	DRM_FORMAT_MOD_LINEAR,
2148 	DRM_FORMAT_MOD_INVALID
2149 };
2150 
2151 static const u64 skl_plane_format_modifiers_ccs[] = {
2152 	I915_FORMAT_MOD_Yf_TILED_CCS,
2153 	I915_FORMAT_MOD_Y_TILED_CCS,
2154 	I915_FORMAT_MOD_Yf_TILED,
2155 	I915_FORMAT_MOD_Y_TILED,
2156 	I915_FORMAT_MOD_X_TILED,
2157 	DRM_FORMAT_MOD_LINEAR,
2158 	DRM_FORMAT_MOD_INVALID
2159 };
2160 
2161 static bool g4x_sprite_format_mod_supported(struct drm_plane *_plane,
2162 					    u32 format, u64 modifier)
2163 {
2164 	switch (modifier) {
2165 	case DRM_FORMAT_MOD_LINEAR:
2166 	case I915_FORMAT_MOD_X_TILED:
2167 		break;
2168 	default:
2169 		return false;
2170 	}
2171 
2172 	switch (format) {
2173 	case DRM_FORMAT_XRGB8888:
2174 	case DRM_FORMAT_YUYV:
2175 	case DRM_FORMAT_YVYU:
2176 	case DRM_FORMAT_UYVY:
2177 	case DRM_FORMAT_VYUY:
2178 		if (modifier == DRM_FORMAT_MOD_LINEAR ||
2179 		    modifier == I915_FORMAT_MOD_X_TILED)
2180 			return true;
2181 		/* fall through */
2182 	default:
2183 		return false;
2184 	}
2185 }
2186 
2187 static bool snb_sprite_format_mod_supported(struct drm_plane *_plane,
2188 					    u32 format, u64 modifier)
2189 {
2190 	switch (modifier) {
2191 	case DRM_FORMAT_MOD_LINEAR:
2192 	case I915_FORMAT_MOD_X_TILED:
2193 		break;
2194 	default:
2195 		return false;
2196 	}
2197 
2198 	switch (format) {
2199 	case DRM_FORMAT_XRGB8888:
2200 	case DRM_FORMAT_XBGR8888:
2201 	case DRM_FORMAT_YUYV:
2202 	case DRM_FORMAT_YVYU:
2203 	case DRM_FORMAT_UYVY:
2204 	case DRM_FORMAT_VYUY:
2205 		if (modifier == DRM_FORMAT_MOD_LINEAR ||
2206 		    modifier == I915_FORMAT_MOD_X_TILED)
2207 			return true;
2208 		/* fall through */
2209 	default:
2210 		return false;
2211 	}
2212 }
2213 
2214 static bool vlv_sprite_format_mod_supported(struct drm_plane *_plane,
2215 					    u32 format, u64 modifier)
2216 {
2217 	switch (modifier) {
2218 	case DRM_FORMAT_MOD_LINEAR:
2219 	case I915_FORMAT_MOD_X_TILED:
2220 		break;
2221 	default:
2222 		return false;
2223 	}
2224 
2225 	switch (format) {
2226 	case DRM_FORMAT_RGB565:
2227 	case DRM_FORMAT_ABGR8888:
2228 	case DRM_FORMAT_ARGB8888:
2229 	case DRM_FORMAT_XBGR8888:
2230 	case DRM_FORMAT_XRGB8888:
2231 	case DRM_FORMAT_XBGR2101010:
2232 	case DRM_FORMAT_ABGR2101010:
2233 	case DRM_FORMAT_YUYV:
2234 	case DRM_FORMAT_YVYU:
2235 	case DRM_FORMAT_UYVY:
2236 	case DRM_FORMAT_VYUY:
2237 		if (modifier == DRM_FORMAT_MOD_LINEAR ||
2238 		    modifier == I915_FORMAT_MOD_X_TILED)
2239 			return true;
2240 		/* fall through */
2241 	default:
2242 		return false;
2243 	}
2244 }
2245 
2246 static bool skl_plane_format_mod_supported(struct drm_plane *_plane,
2247 					   u32 format, u64 modifier)
2248 {
2249 	struct intel_plane *plane = to_intel_plane(_plane);
2250 
2251 	switch (modifier) {
2252 	case DRM_FORMAT_MOD_LINEAR:
2253 	case I915_FORMAT_MOD_X_TILED:
2254 	case I915_FORMAT_MOD_Y_TILED:
2255 	case I915_FORMAT_MOD_Yf_TILED:
2256 		break;
2257 	case I915_FORMAT_MOD_Y_TILED_CCS:
2258 	case I915_FORMAT_MOD_Yf_TILED_CCS:
2259 		if (!plane->has_ccs)
2260 			return false;
2261 		break;
2262 	default:
2263 		return false;
2264 	}
2265 
2266 	switch (format) {
2267 	case DRM_FORMAT_XRGB8888:
2268 	case DRM_FORMAT_XBGR8888:
2269 	case DRM_FORMAT_ARGB8888:
2270 	case DRM_FORMAT_ABGR8888:
2271 		if (is_ccs_modifier(modifier))
2272 			return true;
2273 		/* fall through */
2274 	case DRM_FORMAT_RGB565:
2275 	case DRM_FORMAT_XRGB2101010:
2276 	case DRM_FORMAT_XBGR2101010:
2277 	case DRM_FORMAT_YUYV:
2278 	case DRM_FORMAT_YVYU:
2279 	case DRM_FORMAT_UYVY:
2280 	case DRM_FORMAT_VYUY:
2281 	case DRM_FORMAT_NV12:
2282 	case DRM_FORMAT_P010:
2283 	case DRM_FORMAT_P012:
2284 	case DRM_FORMAT_P016:
2285 	case DRM_FORMAT_XVYU2101010:
2286 		if (modifier == I915_FORMAT_MOD_Yf_TILED)
2287 			return true;
2288 		/* fall through */
2289 	case DRM_FORMAT_C8:
2290 	case DRM_FORMAT_XBGR16161616F:
2291 	case DRM_FORMAT_ABGR16161616F:
2292 	case DRM_FORMAT_XRGB16161616F:
2293 	case DRM_FORMAT_ARGB16161616F:
2294 	case DRM_FORMAT_Y210:
2295 	case DRM_FORMAT_Y212:
2296 	case DRM_FORMAT_Y216:
2297 	case DRM_FORMAT_XVYU12_16161616:
2298 	case DRM_FORMAT_XVYU16161616:
2299 		if (modifier == DRM_FORMAT_MOD_LINEAR ||
2300 		    modifier == I915_FORMAT_MOD_X_TILED ||
2301 		    modifier == I915_FORMAT_MOD_Y_TILED)
2302 			return true;
2303 		/* fall through */
2304 	default:
2305 		return false;
2306 	}
2307 }
2308 
2309 static const struct drm_plane_funcs g4x_sprite_funcs = {
2310 	.update_plane = drm_atomic_helper_update_plane,
2311 	.disable_plane = drm_atomic_helper_disable_plane,
2312 	.destroy = intel_plane_destroy,
2313 	.atomic_duplicate_state = intel_plane_duplicate_state,
2314 	.atomic_destroy_state = intel_plane_destroy_state,
2315 	.format_mod_supported = g4x_sprite_format_mod_supported,
2316 };
2317 
2318 static const struct drm_plane_funcs snb_sprite_funcs = {
2319 	.update_plane = drm_atomic_helper_update_plane,
2320 	.disable_plane = drm_atomic_helper_disable_plane,
2321 	.destroy = intel_plane_destroy,
2322 	.atomic_duplicate_state = intel_plane_duplicate_state,
2323 	.atomic_destroy_state = intel_plane_destroy_state,
2324 	.format_mod_supported = snb_sprite_format_mod_supported,
2325 };
2326 
2327 static const struct drm_plane_funcs vlv_sprite_funcs = {
2328 	.update_plane = drm_atomic_helper_update_plane,
2329 	.disable_plane = drm_atomic_helper_disable_plane,
2330 	.destroy = intel_plane_destroy,
2331 	.atomic_duplicate_state = intel_plane_duplicate_state,
2332 	.atomic_destroy_state = intel_plane_destroy_state,
2333 	.format_mod_supported = vlv_sprite_format_mod_supported,
2334 };
2335 
2336 static const struct drm_plane_funcs skl_plane_funcs = {
2337 	.update_plane = drm_atomic_helper_update_plane,
2338 	.disable_plane = drm_atomic_helper_disable_plane,
2339 	.destroy = intel_plane_destroy,
2340 	.atomic_duplicate_state = intel_plane_duplicate_state,
2341 	.atomic_destroy_state = intel_plane_destroy_state,
2342 	.format_mod_supported = skl_plane_format_mod_supported,
2343 };
2344 
2345 static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv,
2346 			      enum pipe pipe, enum plane_id plane_id)
2347 {
2348 	if (!HAS_FBC(dev_priv))
2349 		return false;
2350 
2351 	return pipe == PIPE_A && plane_id == PLANE_PRIMARY;
2352 }
2353 
2354 static bool skl_plane_has_planar(struct drm_i915_private *dev_priv,
2355 				 enum pipe pipe, enum plane_id plane_id)
2356 {
2357 	/* Display WA #0870: skl, bxt */
2358 	if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv))
2359 		return false;
2360 
2361 	if (IS_GEN(dev_priv, 9) && !IS_GEMINILAKE(dev_priv) && pipe == PIPE_C)
2362 		return false;
2363 
2364 	if (plane_id != PLANE_PRIMARY && plane_id != PLANE_SPRITE0)
2365 		return false;
2366 
2367 	return true;
2368 }
2369 
2370 static const u32 *skl_get_plane_formats(struct drm_i915_private *dev_priv,
2371 					enum pipe pipe, enum plane_id plane_id,
2372 					int *num_formats)
2373 {
2374 	if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
2375 		*num_formats = ARRAY_SIZE(skl_planar_formats);
2376 		return skl_planar_formats;
2377 	} else {
2378 		*num_formats = ARRAY_SIZE(skl_plane_formats);
2379 		return skl_plane_formats;
2380 	}
2381 }
2382 
2383 static const u32 *glk_get_plane_formats(struct drm_i915_private *dev_priv,
2384 					enum pipe pipe, enum plane_id plane_id,
2385 					int *num_formats)
2386 {
2387 	if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
2388 		*num_formats = ARRAY_SIZE(glk_planar_formats);
2389 		return glk_planar_formats;
2390 	} else {
2391 		*num_formats = ARRAY_SIZE(skl_plane_formats);
2392 		return skl_plane_formats;
2393 	}
2394 }
2395 
2396 static const u32 *icl_get_plane_formats(struct drm_i915_private *dev_priv,
2397 					enum pipe pipe, enum plane_id plane_id,
2398 					int *num_formats)
2399 {
2400 	if (icl_is_hdr_plane(dev_priv, plane_id)) {
2401 		*num_formats = ARRAY_SIZE(icl_hdr_plane_formats);
2402 		return icl_hdr_plane_formats;
2403 	} else if (icl_is_nv12_y_plane(plane_id)) {
2404 		*num_formats = ARRAY_SIZE(icl_sdr_y_plane_formats);
2405 		return icl_sdr_y_plane_formats;
2406 	} else {
2407 		*num_formats = ARRAY_SIZE(icl_sdr_uv_plane_formats);
2408 		return icl_sdr_uv_plane_formats;
2409 	}
2410 }
2411 
2412 static bool skl_plane_has_ccs(struct drm_i915_private *dev_priv,
2413 			      enum pipe pipe, enum plane_id plane_id)
2414 {
2415 	if (plane_id == PLANE_CURSOR)
2416 		return false;
2417 
2418 	if (INTEL_GEN(dev_priv) >= 10)
2419 		return true;
2420 
2421 	if (IS_GEMINILAKE(dev_priv))
2422 		return pipe != PIPE_C;
2423 
2424 	return pipe != PIPE_C &&
2425 		(plane_id == PLANE_PRIMARY ||
2426 		 plane_id == PLANE_SPRITE0);
2427 }
2428 
2429 struct intel_plane *
2430 skl_universal_plane_create(struct drm_i915_private *dev_priv,
2431 			   enum pipe pipe, enum plane_id plane_id)
2432 {
2433 	struct intel_plane *plane;
2434 	enum drm_plane_type plane_type;
2435 	unsigned int supported_rotations;
2436 	unsigned int possible_crtcs;
2437 	const u64 *modifiers;
2438 	const u32 *formats;
2439 	int num_formats;
2440 	int ret;
2441 
2442 	plane = intel_plane_alloc();
2443 	if (IS_ERR(plane))
2444 		return plane;
2445 
2446 	plane->pipe = pipe;
2447 	plane->id = plane_id;
2448 	plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane_id);
2449 
2450 	plane->has_fbc = skl_plane_has_fbc(dev_priv, pipe, plane_id);
2451 	if (plane->has_fbc) {
2452 		struct intel_fbc *fbc = &dev_priv->fbc;
2453 
2454 		fbc->possible_framebuffer_bits |= plane->frontbuffer_bit;
2455 	}
2456 
2457 	plane->max_stride = skl_plane_max_stride;
2458 	plane->update_plane = skl_update_plane;
2459 	plane->disable_plane = skl_disable_plane;
2460 	plane->get_hw_state = skl_plane_get_hw_state;
2461 	plane->check_plane = skl_plane_check;
2462 	if (icl_is_nv12_y_plane(plane_id))
2463 		plane->update_slave = icl_update_slave;
2464 
2465 	if (INTEL_GEN(dev_priv) >= 11)
2466 		formats = icl_get_plane_formats(dev_priv, pipe,
2467 						plane_id, &num_formats);
2468 	else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
2469 		formats = glk_get_plane_formats(dev_priv, pipe,
2470 						plane_id, &num_formats);
2471 	else
2472 		formats = skl_get_plane_formats(dev_priv, pipe,
2473 						plane_id, &num_formats);
2474 
2475 	plane->has_ccs = skl_plane_has_ccs(dev_priv, pipe, plane_id);
2476 	if (plane->has_ccs)
2477 		modifiers = skl_plane_format_modifiers_ccs;
2478 	else
2479 		modifiers = skl_plane_format_modifiers_noccs;
2480 
2481 	if (plane_id == PLANE_PRIMARY)
2482 		plane_type = DRM_PLANE_TYPE_PRIMARY;
2483 	else
2484 		plane_type = DRM_PLANE_TYPE_OVERLAY;
2485 
2486 	possible_crtcs = BIT(pipe);
2487 
2488 	ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
2489 				       possible_crtcs, &skl_plane_funcs,
2490 				       formats, num_formats, modifiers,
2491 				       plane_type,
2492 				       "plane %d%c", plane_id + 1,
2493 				       pipe_name(pipe));
2494 	if (ret)
2495 		goto fail;
2496 
2497 	supported_rotations =
2498 		DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 |
2499 		DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270;
2500 
2501 	if (INTEL_GEN(dev_priv) >= 10)
2502 		supported_rotations |= DRM_MODE_REFLECT_X;
2503 
2504 	drm_plane_create_rotation_property(&plane->base,
2505 					   DRM_MODE_ROTATE_0,
2506 					   supported_rotations);
2507 
2508 	drm_plane_create_color_properties(&plane->base,
2509 					  BIT(DRM_COLOR_YCBCR_BT601) |
2510 					  BIT(DRM_COLOR_YCBCR_BT709),
2511 					  BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
2512 					  BIT(DRM_COLOR_YCBCR_FULL_RANGE),
2513 					  DRM_COLOR_YCBCR_BT709,
2514 					  DRM_COLOR_YCBCR_LIMITED_RANGE);
2515 
2516 	drm_plane_create_alpha_property(&plane->base);
2517 	drm_plane_create_blend_mode_property(&plane->base,
2518 					     BIT(DRM_MODE_BLEND_PIXEL_NONE) |
2519 					     BIT(DRM_MODE_BLEND_PREMULTI) |
2520 					     BIT(DRM_MODE_BLEND_COVERAGE));
2521 
2522 	drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
2523 
2524 	return plane;
2525 
2526 fail:
2527 	intel_plane_free(plane);
2528 
2529 	return ERR_PTR(ret);
2530 }
2531 
2532 struct intel_plane *
2533 intel_sprite_plane_create(struct drm_i915_private *dev_priv,
2534 			  enum pipe pipe, int sprite)
2535 {
2536 	struct intel_plane *plane;
2537 	const struct drm_plane_funcs *plane_funcs;
2538 	unsigned long possible_crtcs;
2539 	unsigned int supported_rotations;
2540 	const u64 *modifiers;
2541 	const u32 *formats;
2542 	int num_formats;
2543 	int ret;
2544 
2545 	if (INTEL_GEN(dev_priv) >= 9)
2546 		return skl_universal_plane_create(dev_priv, pipe,
2547 						  PLANE_SPRITE0 + sprite);
2548 
2549 	plane = intel_plane_alloc();
2550 	if (IS_ERR(plane))
2551 		return plane;
2552 
2553 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
2554 		plane->max_stride = i9xx_plane_max_stride;
2555 		plane->update_plane = vlv_update_plane;
2556 		plane->disable_plane = vlv_disable_plane;
2557 		plane->get_hw_state = vlv_plane_get_hw_state;
2558 		plane->check_plane = vlv_sprite_check;
2559 
2560 		formats = vlv_plane_formats;
2561 		num_formats = ARRAY_SIZE(vlv_plane_formats);
2562 		modifiers = i9xx_plane_format_modifiers;
2563 
2564 		plane_funcs = &vlv_sprite_funcs;
2565 	} else if (INTEL_GEN(dev_priv) >= 7) {
2566 		plane->max_stride = g4x_sprite_max_stride;
2567 		plane->update_plane = ivb_update_plane;
2568 		plane->disable_plane = ivb_disable_plane;
2569 		plane->get_hw_state = ivb_plane_get_hw_state;
2570 		plane->check_plane = g4x_sprite_check;
2571 
2572 		formats = snb_plane_formats;
2573 		num_formats = ARRAY_SIZE(snb_plane_formats);
2574 		modifiers = i9xx_plane_format_modifiers;
2575 
2576 		plane_funcs = &snb_sprite_funcs;
2577 	} else {
2578 		plane->max_stride = g4x_sprite_max_stride;
2579 		plane->update_plane = g4x_update_plane;
2580 		plane->disable_plane = g4x_disable_plane;
2581 		plane->get_hw_state = g4x_plane_get_hw_state;
2582 		plane->check_plane = g4x_sprite_check;
2583 
2584 		modifiers = i9xx_plane_format_modifiers;
2585 		if (IS_GEN(dev_priv, 6)) {
2586 			formats = snb_plane_formats;
2587 			num_formats = ARRAY_SIZE(snb_plane_formats);
2588 
2589 			plane_funcs = &snb_sprite_funcs;
2590 		} else {
2591 			formats = g4x_plane_formats;
2592 			num_formats = ARRAY_SIZE(g4x_plane_formats);
2593 
2594 			plane_funcs = &g4x_sprite_funcs;
2595 		}
2596 	}
2597 
2598 	if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
2599 		supported_rotations =
2600 			DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
2601 			DRM_MODE_REFLECT_X;
2602 	} else {
2603 		supported_rotations =
2604 			DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
2605 	}
2606 
2607 	plane->pipe = pipe;
2608 	plane->id = PLANE_SPRITE0 + sprite;
2609 	plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id);
2610 
2611 	possible_crtcs = BIT(pipe);
2612 
2613 	ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
2614 				       possible_crtcs, plane_funcs,
2615 				       formats, num_formats, modifiers,
2616 				       DRM_PLANE_TYPE_OVERLAY,
2617 				       "sprite %c", sprite_name(pipe, sprite));
2618 	if (ret)
2619 		goto fail;
2620 
2621 	drm_plane_create_rotation_property(&plane->base,
2622 					   DRM_MODE_ROTATE_0,
2623 					   supported_rotations);
2624 
2625 	drm_plane_create_color_properties(&plane->base,
2626 					  BIT(DRM_COLOR_YCBCR_BT601) |
2627 					  BIT(DRM_COLOR_YCBCR_BT709),
2628 					  BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
2629 					  BIT(DRM_COLOR_YCBCR_FULL_RANGE),
2630 					  DRM_COLOR_YCBCR_BT709,
2631 					  DRM_COLOR_YCBCR_LIMITED_RANGE);
2632 
2633 	drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
2634 
2635 	return plane;
2636 
2637 fail:
2638 	intel_plane_free(plane);
2639 
2640 	return ERR_PTR(ret);
2641 }
2642