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