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_damage_helper.h>
38 #include <drm/drm_fourcc.h>
39 #include <drm/drm_plane_helper.h>
40 #include <drm/drm_rect.h>
41 
42 #include "i915_drv.h"
43 #include "i915_vgpu.h"
44 #include "i9xx_plane.h"
45 #include "intel_atomic_plane.h"
46 #include "intel_crtc.h"
47 #include "intel_de.h"
48 #include "intel_display_types.h"
49 #include "intel_fb.h"
50 #include "intel_frontbuffer.h"
51 #include "intel_sprite.h"
52 #include "intel_vrr.h"
53 
54 int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
55 {
56 	const struct drm_framebuffer *fb = plane_state->hw.fb;
57 	struct drm_rect *src = &plane_state->uapi.src;
58 	u32 src_x, src_y, src_w, src_h, hsub, vsub;
59 	bool rotated = drm_rotation_90_or_270(plane_state->hw.rotation);
60 
61 	/*
62 	 * FIXME hsub/vsub vs. block size is a mess. Pre-tgl CCS
63 	 * abuses hsub/vsub so we can't use them here. But as they
64 	 * are limited to 32bpp RGB formats we don't actually need
65 	 * to check anything.
66 	 */
67 	if (fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
68 	    fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS)
69 		return 0;
70 
71 	/*
72 	 * Hardware doesn't handle subpixel coordinates.
73 	 * Adjust to (macro)pixel boundary, but be careful not to
74 	 * increase the source viewport size, because that could
75 	 * push the downscaling factor out of bounds.
76 	 */
77 	src_x = src->x1 >> 16;
78 	src_w = drm_rect_width(src) >> 16;
79 	src_y = src->y1 >> 16;
80 	src_h = drm_rect_height(src) >> 16;
81 
82 	drm_rect_init(src, src_x << 16, src_y << 16,
83 		      src_w << 16, src_h << 16);
84 
85 	if (fb->format->format == DRM_FORMAT_RGB565 && rotated) {
86 		hsub = 2;
87 		vsub = 2;
88 	} else {
89 		hsub = fb->format->hsub;
90 		vsub = fb->format->vsub;
91 	}
92 
93 	if (rotated)
94 		hsub = vsub = max(hsub, vsub);
95 
96 	if (src_x % hsub || src_w % hsub) {
97 		DRM_DEBUG_KMS("src x/w (%u, %u) must be a multiple of %u (rotated: %s)\n",
98 			      src_x, src_w, hsub, yesno(rotated));
99 		return -EINVAL;
100 	}
101 
102 	if (src_y % vsub || src_h % vsub) {
103 		DRM_DEBUG_KMS("src y/h (%u, %u) must be a multiple of %u (rotated: %s)\n",
104 			      src_y, src_h, vsub, yesno(rotated));
105 		return -EINVAL;
106 	}
107 
108 	return 0;
109 }
110 
111 static void i9xx_plane_linear_gamma(u16 gamma[8])
112 {
113 	/* The points are not evenly spaced. */
114 	static const u8 in[8] = { 0, 1, 2, 4, 8, 16, 24, 32 };
115 	int i;
116 
117 	for (i = 0; i < 8; i++)
118 		gamma[i] = (in[i] << 8) / 32;
119 }
120 
121 static void
122 chv_sprite_update_csc(const struct intel_plane_state *plane_state)
123 {
124 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
125 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
126 	const struct drm_framebuffer *fb = plane_state->hw.fb;
127 	enum plane_id plane_id = plane->id;
128 	/*
129 	 * |r|   | c0 c1 c2 |   |cr|
130 	 * |g| = | c3 c4 c5 | x |y |
131 	 * |b|   | c6 c7 c8 |   |cb|
132 	 *
133 	 * Coefficients are s3.12.
134 	 *
135 	 * Cb and Cr apparently come in as signed already, and
136 	 * we always get full range data in on account of CLRC0/1.
137 	 */
138 	static const s16 csc_matrix[][9] = {
139 		/* BT.601 full range YCbCr -> full range RGB */
140 		[DRM_COLOR_YCBCR_BT601] = {
141 			 5743, 4096,     0,
142 			-2925, 4096, -1410,
143 			    0, 4096,  7258,
144 		},
145 		/* BT.709 full range YCbCr -> full range RGB */
146 		[DRM_COLOR_YCBCR_BT709] = {
147 			 6450, 4096,     0,
148 			-1917, 4096,  -767,
149 			    0, 4096,  7601,
150 		},
151 	};
152 	const s16 *csc = csc_matrix[plane_state->hw.color_encoding];
153 
154 	/* Seems RGB data bypasses the CSC always */
155 	if (!fb->format->is_yuv)
156 		return;
157 
158 	intel_de_write_fw(dev_priv, SPCSCYGOFF(plane_id),
159 			  SPCSC_OOFF(0) | SPCSC_IOFF(0));
160 	intel_de_write_fw(dev_priv, SPCSCCBOFF(plane_id),
161 			  SPCSC_OOFF(0) | SPCSC_IOFF(0));
162 	intel_de_write_fw(dev_priv, SPCSCCROFF(plane_id),
163 			  SPCSC_OOFF(0) | SPCSC_IOFF(0));
164 
165 	intel_de_write_fw(dev_priv, SPCSCC01(plane_id),
166 			  SPCSC_C1(csc[1]) | SPCSC_C0(csc[0]));
167 	intel_de_write_fw(dev_priv, SPCSCC23(plane_id),
168 			  SPCSC_C1(csc[3]) | SPCSC_C0(csc[2]));
169 	intel_de_write_fw(dev_priv, SPCSCC45(plane_id),
170 			  SPCSC_C1(csc[5]) | SPCSC_C0(csc[4]));
171 	intel_de_write_fw(dev_priv, SPCSCC67(plane_id),
172 			  SPCSC_C1(csc[7]) | SPCSC_C0(csc[6]));
173 	intel_de_write_fw(dev_priv, SPCSCC8(plane_id), SPCSC_C0(csc[8]));
174 
175 	intel_de_write_fw(dev_priv, SPCSCYGICLAMP(plane_id),
176 			  SPCSC_IMAX(1023) | SPCSC_IMIN(0));
177 	intel_de_write_fw(dev_priv, SPCSCCBICLAMP(plane_id),
178 			  SPCSC_IMAX(512) | SPCSC_IMIN(-512));
179 	intel_de_write_fw(dev_priv, SPCSCCRICLAMP(plane_id),
180 			  SPCSC_IMAX(512) | SPCSC_IMIN(-512));
181 
182 	intel_de_write_fw(dev_priv, SPCSCYGOCLAMP(plane_id),
183 			  SPCSC_OMAX(1023) | SPCSC_OMIN(0));
184 	intel_de_write_fw(dev_priv, SPCSCCBOCLAMP(plane_id),
185 			  SPCSC_OMAX(1023) | SPCSC_OMIN(0));
186 	intel_de_write_fw(dev_priv, SPCSCCROCLAMP(plane_id),
187 			  SPCSC_OMAX(1023) | SPCSC_OMIN(0));
188 }
189 
190 #define SIN_0 0
191 #define COS_0 1
192 
193 static void
194 vlv_sprite_update_clrc(const struct intel_plane_state *plane_state)
195 {
196 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
197 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
198 	const struct drm_framebuffer *fb = plane_state->hw.fb;
199 	enum pipe pipe = plane->pipe;
200 	enum plane_id plane_id = plane->id;
201 	int contrast, brightness, sh_scale, sh_sin, sh_cos;
202 
203 	if (fb->format->is_yuv &&
204 	    plane_state->hw.color_range == DRM_COLOR_YCBCR_LIMITED_RANGE) {
205 		/*
206 		 * Expand limited range to full range:
207 		 * Contrast is applied first and is used to expand Y range.
208 		 * Brightness is applied second and is used to remove the
209 		 * offset from Y. Saturation/hue is used to expand CbCr range.
210 		 */
211 		contrast = DIV_ROUND_CLOSEST(255 << 6, 235 - 16);
212 		brightness = -DIV_ROUND_CLOSEST(16 * 255, 235 - 16);
213 		sh_scale = DIV_ROUND_CLOSEST(128 << 7, 240 - 128);
214 		sh_sin = SIN_0 * sh_scale;
215 		sh_cos = COS_0 * sh_scale;
216 	} else {
217 		/* Pass-through everything. */
218 		contrast = 1 << 6;
219 		brightness = 0;
220 		sh_scale = 1 << 7;
221 		sh_sin = SIN_0 * sh_scale;
222 		sh_cos = COS_0 * sh_scale;
223 	}
224 
225 	/* FIXME these register are single buffered :( */
226 	intel_de_write_fw(dev_priv, SPCLRC0(pipe, plane_id),
227 			  SP_CONTRAST(contrast) | SP_BRIGHTNESS(brightness));
228 	intel_de_write_fw(dev_priv, SPCLRC1(pipe, plane_id),
229 			  SP_SH_SIN(sh_sin) | SP_SH_COS(sh_cos));
230 }
231 
232 static void
233 vlv_plane_ratio(const struct intel_crtc_state *crtc_state,
234 		const struct intel_plane_state *plane_state,
235 		unsigned int *num, unsigned int *den)
236 {
237 	u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR);
238 	const struct drm_framebuffer *fb = plane_state->hw.fb;
239 	unsigned int cpp = fb->format->cpp[0];
240 
241 	/*
242 	 * VLV bspec only considers cases where all three planes are
243 	 * enabled, and cases where the primary and one sprite is enabled.
244 	 * Let's assume the case with just two sprites enabled also
245 	 * maps to the latter case.
246 	 */
247 	if (hweight8(active_planes) == 3) {
248 		switch (cpp) {
249 		case 8:
250 			*num = 11;
251 			*den = 8;
252 			break;
253 		case 4:
254 			*num = 18;
255 			*den = 16;
256 			break;
257 		default:
258 			*num = 1;
259 			*den = 1;
260 			break;
261 		}
262 	} else if (hweight8(active_planes) == 2) {
263 		switch (cpp) {
264 		case 8:
265 			*num = 10;
266 			*den = 8;
267 			break;
268 		case 4:
269 			*num = 17;
270 			*den = 16;
271 			break;
272 		default:
273 			*num = 1;
274 			*den = 1;
275 			break;
276 		}
277 	} else {
278 		switch (cpp) {
279 		case 8:
280 			*num = 10;
281 			*den = 8;
282 			break;
283 		default:
284 			*num = 1;
285 			*den = 1;
286 			break;
287 		}
288 	}
289 }
290 
291 int vlv_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
292 			const struct intel_plane_state *plane_state)
293 {
294 	unsigned int pixel_rate;
295 	unsigned int num, den;
296 
297 	/*
298 	 * Note that crtc_state->pixel_rate accounts for both
299 	 * horizontal and vertical panel fitter downscaling factors.
300 	 * Pre-HSW bspec tells us to only consider the horizontal
301 	 * downscaling factor here. We ignore that and just consider
302 	 * both for simplicity.
303 	 */
304 	pixel_rate = crtc_state->pixel_rate;
305 
306 	vlv_plane_ratio(crtc_state, plane_state, &num, &den);
307 
308 	return DIV_ROUND_UP(pixel_rate * num, den);
309 }
310 
311 static u32 vlv_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
312 {
313 	u32 sprctl = 0;
314 
315 	if (crtc_state->gamma_enable)
316 		sprctl |= SP_GAMMA_ENABLE;
317 
318 	return sprctl;
319 }
320 
321 static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state,
322 			  const struct intel_plane_state *plane_state)
323 {
324 	const struct drm_framebuffer *fb = plane_state->hw.fb;
325 	unsigned int rotation = plane_state->hw.rotation;
326 	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
327 	u32 sprctl;
328 
329 	sprctl = SP_ENABLE;
330 
331 	switch (fb->format->format) {
332 	case DRM_FORMAT_YUYV:
333 		sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV;
334 		break;
335 	case DRM_FORMAT_YVYU:
336 		sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU;
337 		break;
338 	case DRM_FORMAT_UYVY:
339 		sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY;
340 		break;
341 	case DRM_FORMAT_VYUY:
342 		sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY;
343 		break;
344 	case DRM_FORMAT_C8:
345 		sprctl |= SP_FORMAT_8BPP;
346 		break;
347 	case DRM_FORMAT_RGB565:
348 		sprctl |= SP_FORMAT_BGR565;
349 		break;
350 	case DRM_FORMAT_XRGB8888:
351 		sprctl |= SP_FORMAT_BGRX8888;
352 		break;
353 	case DRM_FORMAT_ARGB8888:
354 		sprctl |= SP_FORMAT_BGRA8888;
355 		break;
356 	case DRM_FORMAT_XBGR2101010:
357 		sprctl |= SP_FORMAT_RGBX1010102;
358 		break;
359 	case DRM_FORMAT_ABGR2101010:
360 		sprctl |= SP_FORMAT_RGBA1010102;
361 		break;
362 	case DRM_FORMAT_XRGB2101010:
363 		sprctl |= SP_FORMAT_BGRX1010102;
364 		break;
365 	case DRM_FORMAT_ARGB2101010:
366 		sprctl |= SP_FORMAT_BGRA1010102;
367 		break;
368 	case DRM_FORMAT_XBGR8888:
369 		sprctl |= SP_FORMAT_RGBX8888;
370 		break;
371 	case DRM_FORMAT_ABGR8888:
372 		sprctl |= SP_FORMAT_RGBA8888;
373 		break;
374 	default:
375 		MISSING_CASE(fb->format->format);
376 		return 0;
377 	}
378 
379 	if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709)
380 		sprctl |= SP_YUV_FORMAT_BT709;
381 
382 	if (fb->modifier == I915_FORMAT_MOD_X_TILED)
383 		sprctl |= SP_TILED;
384 
385 	if (rotation & DRM_MODE_ROTATE_180)
386 		sprctl |= SP_ROTATE_180;
387 
388 	if (rotation & DRM_MODE_REFLECT_X)
389 		sprctl |= SP_MIRROR;
390 
391 	if (key->flags & I915_SET_COLORKEY_SOURCE)
392 		sprctl |= SP_SOURCE_KEY;
393 
394 	return sprctl;
395 }
396 
397 static void vlv_sprite_update_gamma(const struct intel_plane_state *plane_state)
398 {
399 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
400 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
401 	const struct drm_framebuffer *fb = plane_state->hw.fb;
402 	enum pipe pipe = plane->pipe;
403 	enum plane_id plane_id = plane->id;
404 	u16 gamma[8];
405 	int i;
406 
407 	/* Seems RGB data bypasses the gamma always */
408 	if (!fb->format->is_yuv)
409 		return;
410 
411 	i9xx_plane_linear_gamma(gamma);
412 
413 	/* FIXME these register are single buffered :( */
414 	/* The two end points are implicit (0.0 and 1.0) */
415 	for (i = 1; i < 8 - 1; i++)
416 		intel_de_write_fw(dev_priv, SPGAMC(pipe, plane_id, i - 1),
417 				  gamma[i] << 16 | gamma[i] << 8 | gamma[i]);
418 }
419 
420 static void
421 vlv_sprite_update_noarm(struct intel_plane *plane,
422 			const struct intel_crtc_state *crtc_state,
423 			const struct intel_plane_state *plane_state)
424 {
425 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
426 	enum pipe pipe = plane->pipe;
427 	enum plane_id plane_id = plane->id;
428 	int crtc_x = plane_state->uapi.dst.x1;
429 	int crtc_y = plane_state->uapi.dst.y1;
430 	u32 crtc_w = drm_rect_width(&plane_state->uapi.dst);
431 	u32 crtc_h = drm_rect_height(&plane_state->uapi.dst);
432 	unsigned long irqflags;
433 
434 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
435 
436 	intel_de_write_fw(dev_priv, SPSTRIDE(pipe, plane_id),
437 			  plane_state->view.color_plane[0].mapping_stride);
438 	intel_de_write_fw(dev_priv, SPPOS(pipe, plane_id),
439 			  (crtc_y << 16) | crtc_x);
440 	intel_de_write_fw(dev_priv, SPSIZE(pipe, plane_id),
441 			  ((crtc_h - 1) << 16) | (crtc_w - 1));
442 
443 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
444 }
445 
446 static void
447 vlv_sprite_update_arm(struct intel_plane *plane,
448 		      const struct intel_crtc_state *crtc_state,
449 		      const struct intel_plane_state *plane_state)
450 {
451 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
452 	enum pipe pipe = plane->pipe;
453 	enum plane_id plane_id = plane->id;
454 	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
455 	u32 sprsurf_offset = plane_state->view.color_plane[0].offset;
456 	u32 x = plane_state->view.color_plane[0].x;
457 	u32 y = plane_state->view.color_plane[0].y;
458 	u32 sprctl, linear_offset;
459 	unsigned long irqflags;
460 
461 	sprctl = plane_state->ctl | vlv_sprite_ctl_crtc(crtc_state);
462 
463 	linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
464 
465 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
466 
467 	if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B)
468 		chv_sprite_update_csc(plane_state);
469 
470 	if (key->flags) {
471 		intel_de_write_fw(dev_priv, SPKEYMINVAL(pipe, plane_id),
472 				  key->min_value);
473 		intel_de_write_fw(dev_priv, SPKEYMSK(pipe, plane_id),
474 				  key->channel_mask);
475 		intel_de_write_fw(dev_priv, SPKEYMAXVAL(pipe, plane_id),
476 				  key->max_value);
477 	}
478 
479 	intel_de_write_fw(dev_priv, SPCONSTALPHA(pipe, plane_id), 0);
480 
481 	intel_de_write_fw(dev_priv, SPLINOFF(pipe, plane_id), linear_offset);
482 	intel_de_write_fw(dev_priv, SPTILEOFF(pipe, plane_id), (y << 16) | x);
483 
484 	/*
485 	 * The control register self-arms if the plane was previously
486 	 * disabled. Try to make the plane enable atomic by writing
487 	 * the control register just before the surface register.
488 	 */
489 	intel_de_write_fw(dev_priv, SPCNTR(pipe, plane_id), sprctl);
490 	intel_de_write_fw(dev_priv, SPSURF(pipe, plane_id),
491 			  intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
492 
493 	vlv_sprite_update_clrc(plane_state);
494 	vlv_sprite_update_gamma(plane_state);
495 
496 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
497 }
498 
499 static void
500 vlv_sprite_disable_arm(struct intel_plane *plane,
501 		       const struct intel_crtc_state *crtc_state)
502 {
503 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
504 	enum pipe pipe = plane->pipe;
505 	enum plane_id plane_id = plane->id;
506 	unsigned long irqflags;
507 
508 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
509 
510 	intel_de_write_fw(dev_priv, SPCNTR(pipe, plane_id), 0);
511 	intel_de_write_fw(dev_priv, SPSURF(pipe, plane_id), 0);
512 
513 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
514 }
515 
516 static bool
517 vlv_sprite_get_hw_state(struct intel_plane *plane,
518 			enum pipe *pipe)
519 {
520 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
521 	enum intel_display_power_domain power_domain;
522 	enum plane_id plane_id = plane->id;
523 	intel_wakeref_t wakeref;
524 	bool ret;
525 
526 	power_domain = POWER_DOMAIN_PIPE(plane->pipe);
527 	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
528 	if (!wakeref)
529 		return false;
530 
531 	ret = intel_de_read(dev_priv, SPCNTR(plane->pipe, plane_id)) & SP_ENABLE;
532 
533 	*pipe = plane->pipe;
534 
535 	intel_display_power_put(dev_priv, power_domain, wakeref);
536 
537 	return ret;
538 }
539 
540 static void ivb_plane_ratio(const struct intel_crtc_state *crtc_state,
541 			    const struct intel_plane_state *plane_state,
542 			    unsigned int *num, unsigned int *den)
543 {
544 	u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR);
545 	const struct drm_framebuffer *fb = plane_state->hw.fb;
546 	unsigned int cpp = fb->format->cpp[0];
547 
548 	if (hweight8(active_planes) == 2) {
549 		switch (cpp) {
550 		case 8:
551 			*num = 10;
552 			*den = 8;
553 			break;
554 		case 4:
555 			*num = 17;
556 			*den = 16;
557 			break;
558 		default:
559 			*num = 1;
560 			*den = 1;
561 			break;
562 		}
563 	} else {
564 		switch (cpp) {
565 		case 8:
566 			*num = 9;
567 			*den = 8;
568 			break;
569 		default:
570 			*num = 1;
571 			*den = 1;
572 			break;
573 		}
574 	}
575 }
576 
577 static void ivb_plane_ratio_scaling(const struct intel_crtc_state *crtc_state,
578 				    const struct intel_plane_state *plane_state,
579 				    unsigned int *num, unsigned int *den)
580 {
581 	const struct drm_framebuffer *fb = plane_state->hw.fb;
582 	unsigned int cpp = fb->format->cpp[0];
583 
584 	switch (cpp) {
585 	case 8:
586 		*num = 12;
587 		*den = 8;
588 		break;
589 	case 4:
590 		*num = 19;
591 		*den = 16;
592 		break;
593 	case 2:
594 		*num = 33;
595 		*den = 32;
596 		break;
597 	default:
598 		*num = 1;
599 		*den = 1;
600 		break;
601 	}
602 }
603 
604 int ivb_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
605 			const struct intel_plane_state *plane_state)
606 {
607 	unsigned int pixel_rate;
608 	unsigned int num, den;
609 
610 	/*
611 	 * Note that crtc_state->pixel_rate accounts for both
612 	 * horizontal and vertical panel fitter downscaling factors.
613 	 * Pre-HSW bspec tells us to only consider the horizontal
614 	 * downscaling factor here. We ignore that and just consider
615 	 * both for simplicity.
616 	 */
617 	pixel_rate = crtc_state->pixel_rate;
618 
619 	ivb_plane_ratio(crtc_state, plane_state, &num, &den);
620 
621 	return DIV_ROUND_UP(pixel_rate * num, den);
622 }
623 
624 static int ivb_sprite_min_cdclk(const struct intel_crtc_state *crtc_state,
625 				const struct intel_plane_state *plane_state)
626 {
627 	unsigned int src_w, dst_w, pixel_rate;
628 	unsigned int num, den;
629 
630 	/*
631 	 * Note that crtc_state->pixel_rate accounts for both
632 	 * horizontal and vertical panel fitter downscaling factors.
633 	 * Pre-HSW bspec tells us to only consider the horizontal
634 	 * downscaling factor here. We ignore that and just consider
635 	 * both for simplicity.
636 	 */
637 	pixel_rate = crtc_state->pixel_rate;
638 
639 	src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
640 	dst_w = drm_rect_width(&plane_state->uapi.dst);
641 
642 	if (src_w != dst_w)
643 		ivb_plane_ratio_scaling(crtc_state, plane_state, &num, &den);
644 	else
645 		ivb_plane_ratio(crtc_state, plane_state, &num, &den);
646 
647 	/* Horizontal downscaling limits the maximum pixel rate */
648 	dst_w = min(src_w, dst_w);
649 
650 	return DIV_ROUND_UP_ULL(mul_u32_u32(pixel_rate, num * src_w),
651 				den * dst_w);
652 }
653 
654 static void hsw_plane_ratio(const struct intel_crtc_state *crtc_state,
655 			    const struct intel_plane_state *plane_state,
656 			    unsigned int *num, unsigned int *den)
657 {
658 	u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR);
659 	const struct drm_framebuffer *fb = plane_state->hw.fb;
660 	unsigned int cpp = fb->format->cpp[0];
661 
662 	if (hweight8(active_planes) == 2) {
663 		switch (cpp) {
664 		case 8:
665 			*num = 10;
666 			*den = 8;
667 			break;
668 		default:
669 			*num = 1;
670 			*den = 1;
671 			break;
672 		}
673 	} else {
674 		switch (cpp) {
675 		case 8:
676 			*num = 9;
677 			*den = 8;
678 			break;
679 		default:
680 			*num = 1;
681 			*den = 1;
682 			break;
683 		}
684 	}
685 }
686 
687 int hsw_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
688 			const struct intel_plane_state *plane_state)
689 {
690 	unsigned int pixel_rate = crtc_state->pixel_rate;
691 	unsigned int num, den;
692 
693 	hsw_plane_ratio(crtc_state, plane_state, &num, &den);
694 
695 	return DIV_ROUND_UP(pixel_rate * num, den);
696 }
697 
698 static u32 ivb_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
699 {
700 	u32 sprctl = 0;
701 
702 	if (crtc_state->gamma_enable)
703 		sprctl |= SPRITE_GAMMA_ENABLE;
704 
705 	if (crtc_state->csc_enable)
706 		sprctl |= SPRITE_PIPE_CSC_ENABLE;
707 
708 	return sprctl;
709 }
710 
711 static bool ivb_need_sprite_gamma(const struct intel_plane_state *plane_state)
712 {
713 	struct drm_i915_private *dev_priv =
714 		to_i915(plane_state->uapi.plane->dev);
715 	const struct drm_framebuffer *fb = plane_state->hw.fb;
716 
717 	return fb->format->cpp[0] == 8 &&
718 		(IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv));
719 }
720 
721 static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state,
722 			  const struct intel_plane_state *plane_state)
723 {
724 	struct drm_i915_private *dev_priv =
725 		to_i915(plane_state->uapi.plane->dev);
726 	const struct drm_framebuffer *fb = plane_state->hw.fb;
727 	unsigned int rotation = plane_state->hw.rotation;
728 	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
729 	u32 sprctl;
730 
731 	sprctl = SPRITE_ENABLE;
732 
733 	if (IS_IVYBRIDGE(dev_priv))
734 		sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
735 
736 	switch (fb->format->format) {
737 	case DRM_FORMAT_XBGR8888:
738 		sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
739 		break;
740 	case DRM_FORMAT_XRGB8888:
741 		sprctl |= SPRITE_FORMAT_RGBX888;
742 		break;
743 	case DRM_FORMAT_XBGR2101010:
744 		sprctl |= SPRITE_FORMAT_RGBX101010 | SPRITE_RGB_ORDER_RGBX;
745 		break;
746 	case DRM_FORMAT_XRGB2101010:
747 		sprctl |= SPRITE_FORMAT_RGBX101010;
748 		break;
749 	case DRM_FORMAT_XBGR16161616F:
750 		sprctl |= SPRITE_FORMAT_RGBX161616 | SPRITE_RGB_ORDER_RGBX;
751 		break;
752 	case DRM_FORMAT_XRGB16161616F:
753 		sprctl |= SPRITE_FORMAT_RGBX161616;
754 		break;
755 	case DRM_FORMAT_YUYV:
756 		sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
757 		break;
758 	case DRM_FORMAT_YVYU:
759 		sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
760 		break;
761 	case DRM_FORMAT_UYVY:
762 		sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
763 		break;
764 	case DRM_FORMAT_VYUY:
765 		sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
766 		break;
767 	default:
768 		MISSING_CASE(fb->format->format);
769 		return 0;
770 	}
771 
772 	if (!ivb_need_sprite_gamma(plane_state))
773 		sprctl |= SPRITE_INT_GAMMA_DISABLE;
774 
775 	if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709)
776 		sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709;
777 
778 	if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
779 		sprctl |= SPRITE_YUV_RANGE_CORRECTION_DISABLE;
780 
781 	if (fb->modifier == I915_FORMAT_MOD_X_TILED)
782 		sprctl |= SPRITE_TILED;
783 
784 	if (rotation & DRM_MODE_ROTATE_180)
785 		sprctl |= SPRITE_ROTATE_180;
786 
787 	if (key->flags & I915_SET_COLORKEY_DESTINATION)
788 		sprctl |= SPRITE_DEST_KEY;
789 	else if (key->flags & I915_SET_COLORKEY_SOURCE)
790 		sprctl |= SPRITE_SOURCE_KEY;
791 
792 	return sprctl;
793 }
794 
795 static void ivb_sprite_linear_gamma(const struct intel_plane_state *plane_state,
796 				    u16 gamma[18])
797 {
798 	int scale, i;
799 
800 	/*
801 	 * WaFP16GammaEnabling:ivb,hsw
802 	 * "Workaround : When using the 64-bit format, the sprite output
803 	 *  on each color channel has one quarter amplitude. It can be
804 	 *  brought up to full amplitude by using sprite internal gamma
805 	 *  correction, pipe gamma correction, or pipe color space
806 	 *  conversion to multiply the sprite output by four."
807 	 */
808 	scale = 4;
809 
810 	for (i = 0; i < 16; i++)
811 		gamma[i] = min((scale * i << 10) / 16, (1 << 10) - 1);
812 
813 	gamma[i] = min((scale * i << 10) / 16, 1 << 10);
814 	i++;
815 
816 	gamma[i] = 3 << 10;
817 	i++;
818 }
819 
820 static void ivb_sprite_update_gamma(const struct intel_plane_state *plane_state)
821 {
822 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
823 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
824 	enum pipe pipe = plane->pipe;
825 	u16 gamma[18];
826 	int i;
827 
828 	if (!ivb_need_sprite_gamma(plane_state))
829 		return;
830 
831 	ivb_sprite_linear_gamma(plane_state, gamma);
832 
833 	/* FIXME these register are single buffered :( */
834 	for (i = 0; i < 16; i++)
835 		intel_de_write_fw(dev_priv, SPRGAMC(pipe, i),
836 				  gamma[i] << 20 | gamma[i] << 10 | gamma[i]);
837 
838 	intel_de_write_fw(dev_priv, SPRGAMC16(pipe, 0), gamma[i]);
839 	intel_de_write_fw(dev_priv, SPRGAMC16(pipe, 1), gamma[i]);
840 	intel_de_write_fw(dev_priv, SPRGAMC16(pipe, 2), gamma[i]);
841 	i++;
842 
843 	intel_de_write_fw(dev_priv, SPRGAMC17(pipe, 0), gamma[i]);
844 	intel_de_write_fw(dev_priv, SPRGAMC17(pipe, 1), gamma[i]);
845 	intel_de_write_fw(dev_priv, SPRGAMC17(pipe, 2), gamma[i]);
846 	i++;
847 }
848 
849 static void
850 ivb_sprite_update_noarm(struct intel_plane *plane,
851 			const struct intel_crtc_state *crtc_state,
852 			const struct intel_plane_state *plane_state)
853 {
854 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
855 	enum pipe pipe = plane->pipe;
856 	int crtc_x = plane_state->uapi.dst.x1;
857 	int crtc_y = plane_state->uapi.dst.y1;
858 	u32 crtc_w = drm_rect_width(&plane_state->uapi.dst);
859 	u32 crtc_h = drm_rect_height(&plane_state->uapi.dst);
860 	u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
861 	u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
862 	u32 sprscale = 0;
863 	unsigned long irqflags;
864 
865 	if (crtc_w != src_w || crtc_h != src_h)
866 		sprscale = SPRITE_SCALE_ENABLE | ((src_w - 1) << 16) | (src_h - 1);
867 
868 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
869 
870 	intel_de_write_fw(dev_priv, SPRSTRIDE(pipe),
871 			  plane_state->view.color_plane[0].mapping_stride);
872 	intel_de_write_fw(dev_priv, SPRPOS(pipe), (crtc_y << 16) | crtc_x);
873 	intel_de_write_fw(dev_priv, SPRSIZE(pipe), ((crtc_h - 1) << 16) | (crtc_w - 1));
874 	if (IS_IVYBRIDGE(dev_priv))
875 		intel_de_write_fw(dev_priv, SPRSCALE(pipe), sprscale);
876 
877 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
878 }
879 
880 static void
881 ivb_sprite_update_arm(struct intel_plane *plane,
882 		      const struct intel_crtc_state *crtc_state,
883 		      const struct intel_plane_state *plane_state)
884 {
885 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
886 	enum pipe pipe = plane->pipe;
887 	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
888 	u32 sprsurf_offset = plane_state->view.color_plane[0].offset;
889 	u32 x = plane_state->view.color_plane[0].x;
890 	u32 y = plane_state->view.color_plane[0].y;
891 	u32 sprctl, linear_offset;
892 	unsigned long irqflags;
893 
894 	sprctl = plane_state->ctl | ivb_sprite_ctl_crtc(crtc_state);
895 
896 	linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
897 
898 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
899 
900 	if (key->flags) {
901 		intel_de_write_fw(dev_priv, SPRKEYVAL(pipe), key->min_value);
902 		intel_de_write_fw(dev_priv, SPRKEYMSK(pipe),
903 				  key->channel_mask);
904 		intel_de_write_fw(dev_priv, SPRKEYMAX(pipe), key->max_value);
905 	}
906 
907 	/* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
908 	 * register */
909 	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
910 		intel_de_write_fw(dev_priv, SPROFFSET(pipe), (y << 16) | x);
911 	} else {
912 		intel_de_write_fw(dev_priv, SPRLINOFF(pipe), linear_offset);
913 		intel_de_write_fw(dev_priv, SPRTILEOFF(pipe), (y << 16) | x);
914 	}
915 
916 	/*
917 	 * The control register self-arms if the plane was previously
918 	 * disabled. Try to make the plane enable atomic by writing
919 	 * the control register just before the surface register.
920 	 */
921 	intel_de_write_fw(dev_priv, SPRCTL(pipe), sprctl);
922 	intel_de_write_fw(dev_priv, SPRSURF(pipe),
923 			  intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
924 
925 	ivb_sprite_update_gamma(plane_state);
926 
927 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
928 }
929 
930 static void
931 ivb_sprite_disable_arm(struct intel_plane *plane,
932 		       const struct intel_crtc_state *crtc_state)
933 {
934 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
935 	enum pipe pipe = plane->pipe;
936 	unsigned long irqflags;
937 
938 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
939 
940 	intel_de_write_fw(dev_priv, SPRCTL(pipe), 0);
941 	/* Disable the scaler */
942 	if (IS_IVYBRIDGE(dev_priv))
943 		intel_de_write_fw(dev_priv, SPRSCALE(pipe), 0);
944 	intel_de_write_fw(dev_priv, SPRSURF(pipe), 0);
945 
946 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
947 }
948 
949 static bool
950 ivb_sprite_get_hw_state(struct intel_plane *plane,
951 			enum pipe *pipe)
952 {
953 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
954 	enum intel_display_power_domain power_domain;
955 	intel_wakeref_t wakeref;
956 	bool ret;
957 
958 	power_domain = POWER_DOMAIN_PIPE(plane->pipe);
959 	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
960 	if (!wakeref)
961 		return false;
962 
963 	ret =  intel_de_read(dev_priv, SPRCTL(plane->pipe)) & SPRITE_ENABLE;
964 
965 	*pipe = plane->pipe;
966 
967 	intel_display_power_put(dev_priv, power_domain, wakeref);
968 
969 	return ret;
970 }
971 
972 static int g4x_sprite_min_cdclk(const struct intel_crtc_state *crtc_state,
973 				const struct intel_plane_state *plane_state)
974 {
975 	const struct drm_framebuffer *fb = plane_state->hw.fb;
976 	unsigned int hscale, pixel_rate;
977 	unsigned int limit, decimate;
978 
979 	/*
980 	 * Note that crtc_state->pixel_rate accounts for both
981 	 * horizontal and vertical panel fitter downscaling factors.
982 	 * Pre-HSW bspec tells us to only consider the horizontal
983 	 * downscaling factor here. We ignore that and just consider
984 	 * both for simplicity.
985 	 */
986 	pixel_rate = crtc_state->pixel_rate;
987 
988 	/* Horizontal downscaling limits the maximum pixel rate */
989 	hscale = drm_rect_calc_hscale(&plane_state->uapi.src,
990 				      &plane_state->uapi.dst,
991 				      0, INT_MAX);
992 	hscale = max(hscale, 0x10000u);
993 
994 	/* Decimation steps at 2x,4x,8x,16x */
995 	decimate = ilog2(hscale >> 16);
996 	hscale >>= decimate;
997 
998 	/* Starting limit is 90% of cdclk */
999 	limit = 9;
1000 
1001 	/* -10% per decimation step */
1002 	limit -= decimate;
1003 
1004 	/* -10% for RGB */
1005 	if (!fb->format->is_yuv)
1006 		limit--;
1007 
1008 	/*
1009 	 * We should also do -10% if sprite scaling is enabled
1010 	 * on the other pipe, but we can't really check for that,
1011 	 * so we ignore it.
1012 	 */
1013 
1014 	return DIV_ROUND_UP_ULL(mul_u32_u32(pixel_rate, 10 * hscale),
1015 				limit << 16);
1016 }
1017 
1018 static unsigned int
1019 g4x_sprite_max_stride(struct intel_plane *plane,
1020 		      u32 pixel_format, u64 modifier,
1021 		      unsigned int rotation)
1022 {
1023 	const struct drm_format_info *info = drm_format_info(pixel_format);
1024 	int cpp = info->cpp[0];
1025 
1026 	/* Limit to 4k pixels to guarantee TILEOFF.x doesn't get too big. */
1027 	if (modifier == I915_FORMAT_MOD_X_TILED)
1028 		return min(4096 * cpp, 16 * 1024);
1029 	else
1030 		return 16 * 1024;
1031 }
1032 
1033 static unsigned int
1034 hsw_sprite_max_stride(struct intel_plane *plane,
1035 		      u32 pixel_format, u64 modifier,
1036 		      unsigned int rotation)
1037 {
1038 	const struct drm_format_info *info = drm_format_info(pixel_format);
1039 	int cpp = info->cpp[0];
1040 
1041 	/* Limit to 8k pixels to guarantee OFFSET.x doesn't get too big. */
1042 	return min(8192 * cpp, 16 * 1024);
1043 }
1044 
1045 static u32 g4x_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
1046 {
1047 	u32 dvscntr = 0;
1048 
1049 	if (crtc_state->gamma_enable)
1050 		dvscntr |= DVS_GAMMA_ENABLE;
1051 
1052 	if (crtc_state->csc_enable)
1053 		dvscntr |= DVS_PIPE_CSC_ENABLE;
1054 
1055 	return dvscntr;
1056 }
1057 
1058 static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state,
1059 			  const struct intel_plane_state *plane_state)
1060 {
1061 	struct drm_i915_private *dev_priv =
1062 		to_i915(plane_state->uapi.plane->dev);
1063 	const struct drm_framebuffer *fb = plane_state->hw.fb;
1064 	unsigned int rotation = plane_state->hw.rotation;
1065 	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1066 	u32 dvscntr;
1067 
1068 	dvscntr = DVS_ENABLE;
1069 
1070 	if (IS_SANDYBRIDGE(dev_priv))
1071 		dvscntr |= DVS_TRICKLE_FEED_DISABLE;
1072 
1073 	switch (fb->format->format) {
1074 	case DRM_FORMAT_XBGR8888:
1075 		dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR;
1076 		break;
1077 	case DRM_FORMAT_XRGB8888:
1078 		dvscntr |= DVS_FORMAT_RGBX888;
1079 		break;
1080 	case DRM_FORMAT_XBGR2101010:
1081 		dvscntr |= DVS_FORMAT_RGBX101010 | DVS_RGB_ORDER_XBGR;
1082 		break;
1083 	case DRM_FORMAT_XRGB2101010:
1084 		dvscntr |= DVS_FORMAT_RGBX101010;
1085 		break;
1086 	case DRM_FORMAT_XBGR16161616F:
1087 		dvscntr |= DVS_FORMAT_RGBX161616 | DVS_RGB_ORDER_XBGR;
1088 		break;
1089 	case DRM_FORMAT_XRGB16161616F:
1090 		dvscntr |= DVS_FORMAT_RGBX161616;
1091 		break;
1092 	case DRM_FORMAT_YUYV:
1093 		dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
1094 		break;
1095 	case DRM_FORMAT_YVYU:
1096 		dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
1097 		break;
1098 	case DRM_FORMAT_UYVY:
1099 		dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
1100 		break;
1101 	case DRM_FORMAT_VYUY:
1102 		dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
1103 		break;
1104 	default:
1105 		MISSING_CASE(fb->format->format);
1106 		return 0;
1107 	}
1108 
1109 	if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709)
1110 		dvscntr |= DVS_YUV_FORMAT_BT709;
1111 
1112 	if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
1113 		dvscntr |= DVS_YUV_RANGE_CORRECTION_DISABLE;
1114 
1115 	if (fb->modifier == I915_FORMAT_MOD_X_TILED)
1116 		dvscntr |= DVS_TILED;
1117 
1118 	if (rotation & DRM_MODE_ROTATE_180)
1119 		dvscntr |= DVS_ROTATE_180;
1120 
1121 	if (key->flags & I915_SET_COLORKEY_DESTINATION)
1122 		dvscntr |= DVS_DEST_KEY;
1123 	else if (key->flags & I915_SET_COLORKEY_SOURCE)
1124 		dvscntr |= DVS_SOURCE_KEY;
1125 
1126 	return dvscntr;
1127 }
1128 
1129 static void g4x_sprite_update_gamma(const struct intel_plane_state *plane_state)
1130 {
1131 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
1132 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1133 	const struct drm_framebuffer *fb = plane_state->hw.fb;
1134 	enum pipe pipe = plane->pipe;
1135 	u16 gamma[8];
1136 	int i;
1137 
1138 	/* Seems RGB data bypasses the gamma always */
1139 	if (!fb->format->is_yuv)
1140 		return;
1141 
1142 	i9xx_plane_linear_gamma(gamma);
1143 
1144 	/* FIXME these register are single buffered :( */
1145 	/* The two end points are implicit (0.0 and 1.0) */
1146 	for (i = 1; i < 8 - 1; i++)
1147 		intel_de_write_fw(dev_priv, DVSGAMC_G4X(pipe, i - 1),
1148 				  gamma[i] << 16 | gamma[i] << 8 | gamma[i]);
1149 }
1150 
1151 static void ilk_sprite_linear_gamma(u16 gamma[17])
1152 {
1153 	int i;
1154 
1155 	for (i = 0; i < 17; i++)
1156 		gamma[i] = (i << 10) / 16;
1157 }
1158 
1159 static void ilk_sprite_update_gamma(const struct intel_plane_state *plane_state)
1160 {
1161 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
1162 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1163 	const struct drm_framebuffer *fb = plane_state->hw.fb;
1164 	enum pipe pipe = plane->pipe;
1165 	u16 gamma[17];
1166 	int i;
1167 
1168 	/* Seems RGB data bypasses the gamma always */
1169 	if (!fb->format->is_yuv)
1170 		return;
1171 
1172 	ilk_sprite_linear_gamma(gamma);
1173 
1174 	/* FIXME these register are single buffered :( */
1175 	for (i = 0; i < 16; i++)
1176 		intel_de_write_fw(dev_priv, DVSGAMC_ILK(pipe, i),
1177 				  gamma[i] << 20 | gamma[i] << 10 | gamma[i]);
1178 
1179 	intel_de_write_fw(dev_priv, DVSGAMCMAX_ILK(pipe, 0), gamma[i]);
1180 	intel_de_write_fw(dev_priv, DVSGAMCMAX_ILK(pipe, 1), gamma[i]);
1181 	intel_de_write_fw(dev_priv, DVSGAMCMAX_ILK(pipe, 2), gamma[i]);
1182 	i++;
1183 }
1184 
1185 static void
1186 g4x_sprite_update_noarm(struct intel_plane *plane,
1187 			const struct intel_crtc_state *crtc_state,
1188 			const struct intel_plane_state *plane_state)
1189 {
1190 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1191 	enum pipe pipe = plane->pipe;
1192 	int crtc_x = plane_state->uapi.dst.x1;
1193 	int crtc_y = plane_state->uapi.dst.y1;
1194 	u32 crtc_w = drm_rect_width(&plane_state->uapi.dst);
1195 	u32 crtc_h = drm_rect_height(&plane_state->uapi.dst);
1196 	u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
1197 	u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
1198 	u32 dvsscale = 0;
1199 	unsigned long irqflags;
1200 
1201 	if (crtc_w != src_w || crtc_h != src_h)
1202 		dvsscale = DVS_SCALE_ENABLE | ((src_w - 1) << 16) | (src_h - 1);
1203 
1204 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1205 
1206 	intel_de_write_fw(dev_priv, DVSSTRIDE(pipe),
1207 			  plane_state->view.color_plane[0].mapping_stride);
1208 	intel_de_write_fw(dev_priv, DVSPOS(pipe), (crtc_y << 16) | crtc_x);
1209 	intel_de_write_fw(dev_priv, DVSSIZE(pipe), ((crtc_h - 1) << 16) | (crtc_w - 1));
1210 	intel_de_write_fw(dev_priv, DVSSCALE(pipe), dvsscale);
1211 
1212 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1213 }
1214 
1215 static void
1216 g4x_sprite_update_arm(struct intel_plane *plane,
1217 		      const struct intel_crtc_state *crtc_state,
1218 		      const struct intel_plane_state *plane_state)
1219 {
1220 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1221 	enum pipe pipe = plane->pipe;
1222 	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1223 	u32 dvssurf_offset = plane_state->view.color_plane[0].offset;
1224 	u32 x = plane_state->view.color_plane[0].x;
1225 	u32 y = plane_state->view.color_plane[0].y;
1226 	u32 dvscntr, linear_offset;
1227 	unsigned long irqflags;
1228 
1229 	dvscntr = plane_state->ctl | g4x_sprite_ctl_crtc(crtc_state);
1230 
1231 	linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
1232 
1233 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1234 
1235 	if (key->flags) {
1236 		intel_de_write_fw(dev_priv, DVSKEYVAL(pipe), key->min_value);
1237 		intel_de_write_fw(dev_priv, DVSKEYMSK(pipe),
1238 				  key->channel_mask);
1239 		intel_de_write_fw(dev_priv, DVSKEYMAX(pipe), key->max_value);
1240 	}
1241 
1242 	intel_de_write_fw(dev_priv, DVSLINOFF(pipe), linear_offset);
1243 	intel_de_write_fw(dev_priv, DVSTILEOFF(pipe), (y << 16) | x);
1244 
1245 	/*
1246 	 * The control register self-arms if the plane was previously
1247 	 * disabled. Try to make the plane enable atomic by writing
1248 	 * the control register just before the surface register.
1249 	 */
1250 	intel_de_write_fw(dev_priv, DVSCNTR(pipe), dvscntr);
1251 	intel_de_write_fw(dev_priv, DVSSURF(pipe),
1252 			  intel_plane_ggtt_offset(plane_state) + dvssurf_offset);
1253 
1254 	if (IS_G4X(dev_priv))
1255 		g4x_sprite_update_gamma(plane_state);
1256 	else
1257 		ilk_sprite_update_gamma(plane_state);
1258 
1259 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1260 }
1261 
1262 static void
1263 g4x_sprite_disable_arm(struct intel_plane *plane,
1264 		       const struct intel_crtc_state *crtc_state)
1265 {
1266 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1267 	enum pipe pipe = plane->pipe;
1268 	unsigned long irqflags;
1269 
1270 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1271 
1272 	intel_de_write_fw(dev_priv, DVSCNTR(pipe), 0);
1273 	/* Disable the scaler */
1274 	intel_de_write_fw(dev_priv, DVSSCALE(pipe), 0);
1275 	intel_de_write_fw(dev_priv, DVSSURF(pipe), 0);
1276 
1277 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1278 }
1279 
1280 static bool
1281 g4x_sprite_get_hw_state(struct intel_plane *plane,
1282 			enum pipe *pipe)
1283 {
1284 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1285 	enum intel_display_power_domain power_domain;
1286 	intel_wakeref_t wakeref;
1287 	bool ret;
1288 
1289 	power_domain = POWER_DOMAIN_PIPE(plane->pipe);
1290 	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
1291 	if (!wakeref)
1292 		return false;
1293 
1294 	ret = intel_de_read(dev_priv, DVSCNTR(plane->pipe)) & DVS_ENABLE;
1295 
1296 	*pipe = plane->pipe;
1297 
1298 	intel_display_power_put(dev_priv, power_domain, wakeref);
1299 
1300 	return ret;
1301 }
1302 
1303 static bool g4x_fb_scalable(const struct drm_framebuffer *fb)
1304 {
1305 	if (!fb)
1306 		return false;
1307 
1308 	switch (fb->format->format) {
1309 	case DRM_FORMAT_C8:
1310 	case DRM_FORMAT_XRGB16161616F:
1311 	case DRM_FORMAT_ARGB16161616F:
1312 	case DRM_FORMAT_XBGR16161616F:
1313 	case DRM_FORMAT_ABGR16161616F:
1314 		return false;
1315 	default:
1316 		return true;
1317 	}
1318 }
1319 
1320 static int
1321 g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state,
1322 			 struct intel_plane_state *plane_state)
1323 {
1324 	const struct drm_framebuffer *fb = plane_state->hw.fb;
1325 	const struct drm_rect *src = &plane_state->uapi.src;
1326 	const struct drm_rect *dst = &plane_state->uapi.dst;
1327 	int src_x, src_w, src_h, crtc_w, crtc_h;
1328 	const struct drm_display_mode *adjusted_mode =
1329 		&crtc_state->hw.adjusted_mode;
1330 	unsigned int stride = plane_state->view.color_plane[0].mapping_stride;
1331 	unsigned int cpp = fb->format->cpp[0];
1332 	unsigned int width_bytes;
1333 	int min_width, min_height;
1334 
1335 	crtc_w = drm_rect_width(dst);
1336 	crtc_h = drm_rect_height(dst);
1337 
1338 	src_x = src->x1 >> 16;
1339 	src_w = drm_rect_width(src) >> 16;
1340 	src_h = drm_rect_height(src) >> 16;
1341 
1342 	if (src_w == crtc_w && src_h == crtc_h)
1343 		return 0;
1344 
1345 	min_width = 3;
1346 
1347 	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
1348 		if (src_h & 1) {
1349 			DRM_DEBUG_KMS("Source height must be even with interlaced modes\n");
1350 			return -EINVAL;
1351 		}
1352 		min_height = 6;
1353 	} else {
1354 		min_height = 3;
1355 	}
1356 
1357 	width_bytes = ((src_x * cpp) & 63) + src_w * cpp;
1358 
1359 	if (src_w < min_width || src_h < min_height ||
1360 	    src_w > 2048 || src_h > 2048) {
1361 		DRM_DEBUG_KMS("Source dimensions (%dx%d) exceed hardware limits (%dx%d - %dx%d)\n",
1362 			      src_w, src_h, min_width, min_height, 2048, 2048);
1363 		return -EINVAL;
1364 	}
1365 
1366 	if (width_bytes > 4096) {
1367 		DRM_DEBUG_KMS("Fetch width (%d) exceeds hardware max with scaling (%u)\n",
1368 			      width_bytes, 4096);
1369 		return -EINVAL;
1370 	}
1371 
1372 	if (stride > 4096) {
1373 		DRM_DEBUG_KMS("Stride (%u) exceeds hardware max with scaling (%u)\n",
1374 			      stride, 4096);
1375 		return -EINVAL;
1376 	}
1377 
1378 	return 0;
1379 }
1380 
1381 static int
1382 g4x_sprite_check(struct intel_crtc_state *crtc_state,
1383 		 struct intel_plane_state *plane_state)
1384 {
1385 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
1386 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1387 	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
1388 	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
1389 	int ret;
1390 
1391 	if (g4x_fb_scalable(plane_state->hw.fb)) {
1392 		if (DISPLAY_VER(dev_priv) < 7) {
1393 			min_scale = 1;
1394 			max_scale = 16 << 16;
1395 		} else if (IS_IVYBRIDGE(dev_priv)) {
1396 			min_scale = 1;
1397 			max_scale = 2 << 16;
1398 		}
1399 	}
1400 
1401 	ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
1402 						min_scale, max_scale, true);
1403 	if (ret)
1404 		return ret;
1405 
1406 	ret = i9xx_check_plane_surface(plane_state);
1407 	if (ret)
1408 		return ret;
1409 
1410 	if (!plane_state->uapi.visible)
1411 		return 0;
1412 
1413 	ret = intel_plane_check_src_coordinates(plane_state);
1414 	if (ret)
1415 		return ret;
1416 
1417 	ret = g4x_sprite_check_scaling(crtc_state, plane_state);
1418 	if (ret)
1419 		return ret;
1420 
1421 	if (DISPLAY_VER(dev_priv) >= 7)
1422 		plane_state->ctl = ivb_sprite_ctl(crtc_state, plane_state);
1423 	else
1424 		plane_state->ctl = g4x_sprite_ctl(crtc_state, plane_state);
1425 
1426 	return 0;
1427 }
1428 
1429 int chv_plane_check_rotation(const struct intel_plane_state *plane_state)
1430 {
1431 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
1432 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1433 	unsigned int rotation = plane_state->hw.rotation;
1434 
1435 	/* CHV ignores the mirror bit when the rotate bit is set :( */
1436 	if (IS_CHERRYVIEW(dev_priv) &&
1437 	    rotation & DRM_MODE_ROTATE_180 &&
1438 	    rotation & DRM_MODE_REFLECT_X) {
1439 		drm_dbg_kms(&dev_priv->drm,
1440 			    "Cannot rotate and reflect at the same time\n");
1441 		return -EINVAL;
1442 	}
1443 
1444 	return 0;
1445 }
1446 
1447 static int
1448 vlv_sprite_check(struct intel_crtc_state *crtc_state,
1449 		 struct intel_plane_state *plane_state)
1450 {
1451 	int ret;
1452 
1453 	ret = chv_plane_check_rotation(plane_state);
1454 	if (ret)
1455 		return ret;
1456 
1457 	ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
1458 						DRM_PLANE_HELPER_NO_SCALING,
1459 						DRM_PLANE_HELPER_NO_SCALING,
1460 						true);
1461 	if (ret)
1462 		return ret;
1463 
1464 	ret = i9xx_check_plane_surface(plane_state);
1465 	if (ret)
1466 		return ret;
1467 
1468 	if (!plane_state->uapi.visible)
1469 		return 0;
1470 
1471 	ret = intel_plane_check_src_coordinates(plane_state);
1472 	if (ret)
1473 		return ret;
1474 
1475 	plane_state->ctl = vlv_sprite_ctl(crtc_state, plane_state);
1476 
1477 	return 0;
1478 }
1479 
1480 static bool has_dst_key_in_primary_plane(struct drm_i915_private *dev_priv)
1481 {
1482 	return DISPLAY_VER(dev_priv) >= 9;
1483 }
1484 
1485 static void intel_plane_set_ckey(struct intel_plane_state *plane_state,
1486 				 const struct drm_intel_sprite_colorkey *set)
1487 {
1488 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
1489 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1490 	struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1491 
1492 	*key = *set;
1493 
1494 	/*
1495 	 * We want src key enabled on the
1496 	 * sprite and not on the primary.
1497 	 */
1498 	if (plane->id == PLANE_PRIMARY &&
1499 	    set->flags & I915_SET_COLORKEY_SOURCE)
1500 		key->flags = 0;
1501 
1502 	/*
1503 	 * On SKL+ we want dst key enabled on
1504 	 * the primary and not on the sprite.
1505 	 */
1506 	if (DISPLAY_VER(dev_priv) >= 9 && plane->id != PLANE_PRIMARY &&
1507 	    set->flags & I915_SET_COLORKEY_DESTINATION)
1508 		key->flags = 0;
1509 }
1510 
1511 int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
1512 				    struct drm_file *file_priv)
1513 {
1514 	struct drm_i915_private *dev_priv = to_i915(dev);
1515 	struct drm_intel_sprite_colorkey *set = data;
1516 	struct drm_plane *plane;
1517 	struct drm_plane_state *plane_state;
1518 	struct drm_atomic_state *state;
1519 	struct drm_modeset_acquire_ctx ctx;
1520 	int ret = 0;
1521 
1522 	/* ignore the pointless "none" flag */
1523 	set->flags &= ~I915_SET_COLORKEY_NONE;
1524 
1525 	if (set->flags & ~(I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
1526 		return -EINVAL;
1527 
1528 	/* Make sure we don't try to enable both src & dest simultaneously */
1529 	if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
1530 		return -EINVAL;
1531 
1532 	if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
1533 	    set->flags & I915_SET_COLORKEY_DESTINATION)
1534 		return -EINVAL;
1535 
1536 	plane = drm_plane_find(dev, file_priv, set->plane_id);
1537 	if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY)
1538 		return -ENOENT;
1539 
1540 	/*
1541 	 * SKL+ only plane 2 can do destination keying against plane 1.
1542 	 * Also multiple planes can't do destination keying on the same
1543 	 * pipe simultaneously.
1544 	 */
1545 	if (DISPLAY_VER(dev_priv) >= 9 &&
1546 	    to_intel_plane(plane)->id >= PLANE_SPRITE1 &&
1547 	    set->flags & I915_SET_COLORKEY_DESTINATION)
1548 		return -EINVAL;
1549 
1550 	drm_modeset_acquire_init(&ctx, 0);
1551 
1552 	state = drm_atomic_state_alloc(plane->dev);
1553 	if (!state) {
1554 		ret = -ENOMEM;
1555 		goto out;
1556 	}
1557 	state->acquire_ctx = &ctx;
1558 
1559 	while (1) {
1560 		plane_state = drm_atomic_get_plane_state(state, plane);
1561 		ret = PTR_ERR_OR_ZERO(plane_state);
1562 		if (!ret)
1563 			intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
1564 
1565 		/*
1566 		 * On some platforms we have to configure
1567 		 * the dst colorkey on the primary plane.
1568 		 */
1569 		if (!ret && has_dst_key_in_primary_plane(dev_priv)) {
1570 			struct intel_crtc *crtc =
1571 				intel_crtc_for_pipe(dev_priv,
1572 						    to_intel_plane(plane)->pipe);
1573 
1574 			plane_state = drm_atomic_get_plane_state(state,
1575 								 crtc->base.primary);
1576 			ret = PTR_ERR_OR_ZERO(plane_state);
1577 			if (!ret)
1578 				intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
1579 		}
1580 
1581 		if (!ret)
1582 			ret = drm_atomic_commit(state);
1583 
1584 		if (ret != -EDEADLK)
1585 			break;
1586 
1587 		drm_atomic_state_clear(state);
1588 		drm_modeset_backoff(&ctx);
1589 	}
1590 
1591 	drm_atomic_state_put(state);
1592 out:
1593 	drm_modeset_drop_locks(&ctx);
1594 	drm_modeset_acquire_fini(&ctx);
1595 	return ret;
1596 }
1597 
1598 static const u32 g4x_sprite_formats[] = {
1599 	DRM_FORMAT_XRGB8888,
1600 	DRM_FORMAT_YUYV,
1601 	DRM_FORMAT_YVYU,
1602 	DRM_FORMAT_UYVY,
1603 	DRM_FORMAT_VYUY,
1604 };
1605 
1606 static const u32 snb_sprite_formats[] = {
1607 	DRM_FORMAT_XRGB8888,
1608 	DRM_FORMAT_XBGR8888,
1609 	DRM_FORMAT_XRGB2101010,
1610 	DRM_FORMAT_XBGR2101010,
1611 	DRM_FORMAT_XRGB16161616F,
1612 	DRM_FORMAT_XBGR16161616F,
1613 	DRM_FORMAT_YUYV,
1614 	DRM_FORMAT_YVYU,
1615 	DRM_FORMAT_UYVY,
1616 	DRM_FORMAT_VYUY,
1617 };
1618 
1619 static const u32 vlv_sprite_formats[] = {
1620 	DRM_FORMAT_C8,
1621 	DRM_FORMAT_RGB565,
1622 	DRM_FORMAT_XRGB8888,
1623 	DRM_FORMAT_XBGR8888,
1624 	DRM_FORMAT_ARGB8888,
1625 	DRM_FORMAT_ABGR8888,
1626 	DRM_FORMAT_XBGR2101010,
1627 	DRM_FORMAT_ABGR2101010,
1628 	DRM_FORMAT_YUYV,
1629 	DRM_FORMAT_YVYU,
1630 	DRM_FORMAT_UYVY,
1631 	DRM_FORMAT_VYUY,
1632 };
1633 
1634 static const u32 chv_pipe_b_sprite_formats[] = {
1635 	DRM_FORMAT_C8,
1636 	DRM_FORMAT_RGB565,
1637 	DRM_FORMAT_XRGB8888,
1638 	DRM_FORMAT_XBGR8888,
1639 	DRM_FORMAT_ARGB8888,
1640 	DRM_FORMAT_ABGR8888,
1641 	DRM_FORMAT_XRGB2101010,
1642 	DRM_FORMAT_XBGR2101010,
1643 	DRM_FORMAT_ARGB2101010,
1644 	DRM_FORMAT_ABGR2101010,
1645 	DRM_FORMAT_YUYV,
1646 	DRM_FORMAT_YVYU,
1647 	DRM_FORMAT_UYVY,
1648 	DRM_FORMAT_VYUY,
1649 };
1650 
1651 static bool g4x_sprite_format_mod_supported(struct drm_plane *_plane,
1652 					    u32 format, u64 modifier)
1653 {
1654 	if (!intel_fb_plane_supports_modifier(to_intel_plane(_plane), modifier))
1655 		return false;
1656 
1657 	switch (format) {
1658 	case DRM_FORMAT_XRGB8888:
1659 	case DRM_FORMAT_YUYV:
1660 	case DRM_FORMAT_YVYU:
1661 	case DRM_FORMAT_UYVY:
1662 	case DRM_FORMAT_VYUY:
1663 		if (modifier == DRM_FORMAT_MOD_LINEAR ||
1664 		    modifier == I915_FORMAT_MOD_X_TILED)
1665 			return true;
1666 		fallthrough;
1667 	default:
1668 		return false;
1669 	}
1670 }
1671 
1672 static bool snb_sprite_format_mod_supported(struct drm_plane *_plane,
1673 					    u32 format, u64 modifier)
1674 {
1675 	if (!intel_fb_plane_supports_modifier(to_intel_plane(_plane), modifier))
1676 		return false;
1677 
1678 	switch (format) {
1679 	case DRM_FORMAT_XRGB8888:
1680 	case DRM_FORMAT_XBGR8888:
1681 	case DRM_FORMAT_XRGB2101010:
1682 	case DRM_FORMAT_XBGR2101010:
1683 	case DRM_FORMAT_XRGB16161616F:
1684 	case DRM_FORMAT_XBGR16161616F:
1685 	case DRM_FORMAT_YUYV:
1686 	case DRM_FORMAT_YVYU:
1687 	case DRM_FORMAT_UYVY:
1688 	case DRM_FORMAT_VYUY:
1689 		if (modifier == DRM_FORMAT_MOD_LINEAR ||
1690 		    modifier == I915_FORMAT_MOD_X_TILED)
1691 			return true;
1692 		fallthrough;
1693 	default:
1694 		return false;
1695 	}
1696 }
1697 
1698 static bool vlv_sprite_format_mod_supported(struct drm_plane *_plane,
1699 					    u32 format, u64 modifier)
1700 {
1701 	if (!intel_fb_plane_supports_modifier(to_intel_plane(_plane), modifier))
1702 		return false;
1703 
1704 	switch (format) {
1705 	case DRM_FORMAT_C8:
1706 	case DRM_FORMAT_RGB565:
1707 	case DRM_FORMAT_ABGR8888:
1708 	case DRM_FORMAT_ARGB8888:
1709 	case DRM_FORMAT_XBGR8888:
1710 	case DRM_FORMAT_XRGB8888:
1711 	case DRM_FORMAT_XBGR2101010:
1712 	case DRM_FORMAT_ABGR2101010:
1713 	case DRM_FORMAT_XRGB2101010:
1714 	case DRM_FORMAT_ARGB2101010:
1715 	case DRM_FORMAT_YUYV:
1716 	case DRM_FORMAT_YVYU:
1717 	case DRM_FORMAT_UYVY:
1718 	case DRM_FORMAT_VYUY:
1719 		if (modifier == DRM_FORMAT_MOD_LINEAR ||
1720 		    modifier == I915_FORMAT_MOD_X_TILED)
1721 			return true;
1722 		fallthrough;
1723 	default:
1724 		return false;
1725 	}
1726 }
1727 
1728 static const struct drm_plane_funcs g4x_sprite_funcs = {
1729 	.update_plane = drm_atomic_helper_update_plane,
1730 	.disable_plane = drm_atomic_helper_disable_plane,
1731 	.destroy = intel_plane_destroy,
1732 	.atomic_duplicate_state = intel_plane_duplicate_state,
1733 	.atomic_destroy_state = intel_plane_destroy_state,
1734 	.format_mod_supported = g4x_sprite_format_mod_supported,
1735 };
1736 
1737 static const struct drm_plane_funcs snb_sprite_funcs = {
1738 	.update_plane = drm_atomic_helper_update_plane,
1739 	.disable_plane = drm_atomic_helper_disable_plane,
1740 	.destroy = intel_plane_destroy,
1741 	.atomic_duplicate_state = intel_plane_duplicate_state,
1742 	.atomic_destroy_state = intel_plane_destroy_state,
1743 	.format_mod_supported = snb_sprite_format_mod_supported,
1744 };
1745 
1746 static const struct drm_plane_funcs vlv_sprite_funcs = {
1747 	.update_plane = drm_atomic_helper_update_plane,
1748 	.disable_plane = drm_atomic_helper_disable_plane,
1749 	.destroy = intel_plane_destroy,
1750 	.atomic_duplicate_state = intel_plane_duplicate_state,
1751 	.atomic_destroy_state = intel_plane_destroy_state,
1752 	.format_mod_supported = vlv_sprite_format_mod_supported,
1753 };
1754 
1755 struct intel_plane *
1756 intel_sprite_plane_create(struct drm_i915_private *dev_priv,
1757 			  enum pipe pipe, int sprite)
1758 {
1759 	struct intel_plane *plane;
1760 	const struct drm_plane_funcs *plane_funcs;
1761 	unsigned int supported_rotations;
1762 	const u64 *modifiers;
1763 	const u32 *formats;
1764 	int num_formats;
1765 	int ret, zpos;
1766 
1767 	plane = intel_plane_alloc();
1768 	if (IS_ERR(plane))
1769 		return plane;
1770 
1771 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
1772 		plane->update_noarm = vlv_sprite_update_noarm;
1773 		plane->update_arm = vlv_sprite_update_arm;
1774 		plane->disable_arm = vlv_sprite_disable_arm;
1775 		plane->get_hw_state = vlv_sprite_get_hw_state;
1776 		plane->check_plane = vlv_sprite_check;
1777 		plane->max_stride = i965_plane_max_stride;
1778 		plane->min_cdclk = vlv_plane_min_cdclk;
1779 
1780 		if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
1781 			formats = chv_pipe_b_sprite_formats;
1782 			num_formats = ARRAY_SIZE(chv_pipe_b_sprite_formats);
1783 		} else {
1784 			formats = vlv_sprite_formats;
1785 			num_formats = ARRAY_SIZE(vlv_sprite_formats);
1786 		}
1787 
1788 		plane_funcs = &vlv_sprite_funcs;
1789 	} else if (DISPLAY_VER(dev_priv) >= 7) {
1790 		plane->update_noarm = ivb_sprite_update_noarm;
1791 		plane->update_arm = ivb_sprite_update_arm;
1792 		plane->disable_arm = ivb_sprite_disable_arm;
1793 		plane->get_hw_state = ivb_sprite_get_hw_state;
1794 		plane->check_plane = g4x_sprite_check;
1795 
1796 		if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) {
1797 			plane->max_stride = hsw_sprite_max_stride;
1798 			plane->min_cdclk = hsw_plane_min_cdclk;
1799 		} else {
1800 			plane->max_stride = g4x_sprite_max_stride;
1801 			plane->min_cdclk = ivb_sprite_min_cdclk;
1802 		}
1803 
1804 		formats = snb_sprite_formats;
1805 		num_formats = ARRAY_SIZE(snb_sprite_formats);
1806 
1807 		plane_funcs = &snb_sprite_funcs;
1808 	} else {
1809 		plane->update_noarm = g4x_sprite_update_noarm;
1810 		plane->update_arm = g4x_sprite_update_arm;
1811 		plane->disable_arm = g4x_sprite_disable_arm;
1812 		plane->get_hw_state = g4x_sprite_get_hw_state;
1813 		plane->check_plane = g4x_sprite_check;
1814 		plane->max_stride = g4x_sprite_max_stride;
1815 		plane->min_cdclk = g4x_sprite_min_cdclk;
1816 
1817 		if (IS_SANDYBRIDGE(dev_priv)) {
1818 			formats = snb_sprite_formats;
1819 			num_formats = ARRAY_SIZE(snb_sprite_formats);
1820 
1821 			plane_funcs = &snb_sprite_funcs;
1822 		} else {
1823 			formats = g4x_sprite_formats;
1824 			num_formats = ARRAY_SIZE(g4x_sprite_formats);
1825 
1826 			plane_funcs = &g4x_sprite_funcs;
1827 		}
1828 	}
1829 
1830 	if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
1831 		supported_rotations =
1832 			DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
1833 			DRM_MODE_REFLECT_X;
1834 	} else {
1835 		supported_rotations =
1836 			DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
1837 	}
1838 
1839 	plane->pipe = pipe;
1840 	plane->id = PLANE_SPRITE0 + sprite;
1841 	plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id);
1842 
1843 	modifiers = intel_fb_plane_get_modifiers(dev_priv, INTEL_PLANE_CAP_TILING_X);
1844 
1845 	ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
1846 				       0, plane_funcs,
1847 				       formats, num_formats, modifiers,
1848 				       DRM_PLANE_TYPE_OVERLAY,
1849 				       "sprite %c", sprite_name(pipe, sprite));
1850 	kfree(modifiers);
1851 
1852 	if (ret)
1853 		goto fail;
1854 
1855 	drm_plane_create_rotation_property(&plane->base,
1856 					   DRM_MODE_ROTATE_0,
1857 					   supported_rotations);
1858 
1859 	drm_plane_create_color_properties(&plane->base,
1860 					  BIT(DRM_COLOR_YCBCR_BT601) |
1861 					  BIT(DRM_COLOR_YCBCR_BT709),
1862 					  BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
1863 					  BIT(DRM_COLOR_YCBCR_FULL_RANGE),
1864 					  DRM_COLOR_YCBCR_BT709,
1865 					  DRM_COLOR_YCBCR_LIMITED_RANGE);
1866 
1867 	zpos = sprite + 1;
1868 	drm_plane_create_zpos_immutable_property(&plane->base, zpos);
1869 
1870 	intel_plane_helper_add(plane);
1871 
1872 	return plane;
1873 
1874 fail:
1875 	intel_plane_free(plane);
1876 
1877 	return ERR_PTR(ret);
1878 }
1879