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