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