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