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