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