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