xref: /linux/drivers/gpu/drm/i915/display/i9xx_plane.c (revision 07fdad3a93756b872da7b53647715c48d0f4a2d0)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2020 Intel Corporation
4  */
5 
6 #include <linux/kernel.h>
7 
8 #include <drm/drm_atomic_helper.h>
9 #include <drm/drm_blend.h>
10 #include <drm/drm_fourcc.h>
11 #include <drm/drm_print.h>
12 
13 #include "i915_reg.h"
14 #include "i915_utils.h"
15 #include "i9xx_plane.h"
16 #include "i9xx_plane_regs.h"
17 #include "intel_atomic.h"
18 #include "intel_de.h"
19 #include "intel_display_irq.h"
20 #include "intel_display_regs.h"
21 #include "intel_display_types.h"
22 #include "intel_fb.h"
23 #include "intel_fbc.h"
24 #include "intel_frontbuffer.h"
25 #include "intel_panic.h"
26 #include "intel_plane.h"
27 #include "intel_sprite.h"
28 
29 /* Primary plane formats for gen <= 3 */
30 static const u32 i8xx_primary_formats[] = {
31 	DRM_FORMAT_C8,
32 	DRM_FORMAT_XRGB1555,
33 	DRM_FORMAT_RGB565,
34 	DRM_FORMAT_XRGB8888,
35 };
36 
37 /* Primary plane formats for ivb (no fp16 due to hw issue) */
38 static const u32 ivb_primary_formats[] = {
39 	DRM_FORMAT_C8,
40 	DRM_FORMAT_RGB565,
41 	DRM_FORMAT_XRGB8888,
42 	DRM_FORMAT_XBGR8888,
43 	DRM_FORMAT_XRGB2101010,
44 	DRM_FORMAT_XBGR2101010,
45 };
46 
47 /* Primary plane formats for gen >= 4, except ivb */
48 static const u32 i965_primary_formats[] = {
49 	DRM_FORMAT_C8,
50 	DRM_FORMAT_RGB565,
51 	DRM_FORMAT_XRGB8888,
52 	DRM_FORMAT_XBGR8888,
53 	DRM_FORMAT_XRGB2101010,
54 	DRM_FORMAT_XBGR2101010,
55 	DRM_FORMAT_XBGR16161616F,
56 };
57 
58 /* Primary plane formats for vlv/chv */
59 static const u32 vlv_primary_formats[] = {
60 	DRM_FORMAT_C8,
61 	DRM_FORMAT_RGB565,
62 	DRM_FORMAT_XRGB8888,
63 	DRM_FORMAT_XBGR8888,
64 	DRM_FORMAT_ARGB8888,
65 	DRM_FORMAT_ABGR8888,
66 	DRM_FORMAT_XRGB2101010,
67 	DRM_FORMAT_XBGR2101010,
68 	DRM_FORMAT_ARGB2101010,
69 	DRM_FORMAT_ABGR2101010,
70 	DRM_FORMAT_XBGR16161616F,
71 };
72 
73 static bool i8xx_plane_format_mod_supported(struct drm_plane *_plane,
74 					    u32 format, u64 modifier)
75 {
76 	if (!intel_fb_plane_supports_modifier(to_intel_plane(_plane), modifier))
77 		return false;
78 
79 	switch (format) {
80 	case DRM_FORMAT_C8:
81 	case DRM_FORMAT_RGB565:
82 	case DRM_FORMAT_XRGB1555:
83 	case DRM_FORMAT_XRGB8888:
84 		return modifier == DRM_FORMAT_MOD_LINEAR ||
85 			modifier == I915_FORMAT_MOD_X_TILED;
86 	default:
87 		return false;
88 	}
89 }
90 
91 static bool i965_plane_format_mod_supported(struct drm_plane *_plane,
92 					    u32 format, u64 modifier)
93 {
94 	if (!intel_fb_plane_supports_modifier(to_intel_plane(_plane), modifier))
95 		return false;
96 
97 	switch (format) {
98 	case DRM_FORMAT_C8:
99 	case DRM_FORMAT_RGB565:
100 	case DRM_FORMAT_XRGB8888:
101 	case DRM_FORMAT_XBGR8888:
102 	case DRM_FORMAT_ARGB8888:
103 	case DRM_FORMAT_ABGR8888:
104 	case DRM_FORMAT_XRGB2101010:
105 	case DRM_FORMAT_XBGR2101010:
106 	case DRM_FORMAT_ARGB2101010:
107 	case DRM_FORMAT_ABGR2101010:
108 	case DRM_FORMAT_XBGR16161616F:
109 		return modifier == DRM_FORMAT_MOD_LINEAR ||
110 			modifier == I915_FORMAT_MOD_X_TILED;
111 	default:
112 		return false;
113 	}
114 }
115 
116 static bool i9xx_plane_has_fbc(struct intel_display *display,
117 			       enum i9xx_plane_id i9xx_plane)
118 {
119 	if (!HAS_FBC(display))
120 		return false;
121 
122 	if (display->platform.broadwell || display->platform.haswell)
123 		return i9xx_plane == PLANE_A; /* tied to pipe A */
124 	else if (display->platform.ivybridge)
125 		return i9xx_plane == PLANE_A || i9xx_plane == PLANE_B ||
126 			i9xx_plane == PLANE_C;
127 	else if (DISPLAY_VER(display) >= 4)
128 		return i9xx_plane == PLANE_A || i9xx_plane == PLANE_B;
129 	else
130 		return i9xx_plane == PLANE_A;
131 }
132 
133 static struct intel_fbc *i9xx_plane_fbc(struct intel_display *display,
134 					enum i9xx_plane_id i9xx_plane)
135 {
136 	if (i9xx_plane_has_fbc(display, i9xx_plane))
137 		return display->fbc[INTEL_FBC_A];
138 	else
139 		return NULL;
140 }
141 
142 static bool i9xx_plane_has_windowing(struct intel_plane *plane)
143 {
144 	struct intel_display *display = to_intel_display(plane);
145 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
146 
147 	if (display->platform.cherryview)
148 		return i9xx_plane == PLANE_B;
149 	else if (DISPLAY_VER(display) >= 5 || display->platform.g4x)
150 		return false;
151 	else if (DISPLAY_VER(display) == 4)
152 		return i9xx_plane == PLANE_C;
153 	else
154 		return i9xx_plane == PLANE_B ||
155 			i9xx_plane == PLANE_C;
156 }
157 
158 static u32 i9xx_plane_ctl(const struct intel_plane_state *plane_state)
159 {
160 	struct intel_display *display = to_intel_display(plane_state);
161 	const struct drm_framebuffer *fb = plane_state->hw.fb;
162 	unsigned int rotation = plane_state->hw.rotation;
163 	u32 dspcntr;
164 
165 	dspcntr = DISP_ENABLE;
166 
167 	if (display->platform.g4x || display->platform.ironlake ||
168 	    display->platform.sandybridge || display->platform.ivybridge)
169 		dspcntr |= DISP_TRICKLE_FEED_DISABLE;
170 
171 	switch (fb->format->format) {
172 	case DRM_FORMAT_C8:
173 		dspcntr |= DISP_FORMAT_8BPP;
174 		break;
175 	case DRM_FORMAT_XRGB1555:
176 		dspcntr |= DISP_FORMAT_BGRX555;
177 		break;
178 	case DRM_FORMAT_ARGB1555:
179 		dspcntr |= DISP_FORMAT_BGRA555;
180 		break;
181 	case DRM_FORMAT_RGB565:
182 		dspcntr |= DISP_FORMAT_BGRX565;
183 		break;
184 	case DRM_FORMAT_XRGB8888:
185 		dspcntr |= DISP_FORMAT_BGRX888;
186 		break;
187 	case DRM_FORMAT_XBGR8888:
188 		dspcntr |= DISP_FORMAT_RGBX888;
189 		break;
190 	case DRM_FORMAT_ARGB8888:
191 		dspcntr |= DISP_FORMAT_BGRA888;
192 		break;
193 	case DRM_FORMAT_ABGR8888:
194 		dspcntr |= DISP_FORMAT_RGBA888;
195 		break;
196 	case DRM_FORMAT_XRGB2101010:
197 		dspcntr |= DISP_FORMAT_BGRX101010;
198 		break;
199 	case DRM_FORMAT_XBGR2101010:
200 		dspcntr |= DISP_FORMAT_RGBX101010;
201 		break;
202 	case DRM_FORMAT_ARGB2101010:
203 		dspcntr |= DISP_FORMAT_BGRA101010;
204 		break;
205 	case DRM_FORMAT_ABGR2101010:
206 		dspcntr |= DISP_FORMAT_RGBA101010;
207 		break;
208 	case DRM_FORMAT_XBGR16161616F:
209 		dspcntr |= DISP_FORMAT_RGBX161616;
210 		break;
211 	default:
212 		MISSING_CASE(fb->format->format);
213 		return 0;
214 	}
215 
216 	if (DISPLAY_VER(display) >= 4 &&
217 	    fb->modifier == I915_FORMAT_MOD_X_TILED)
218 		dspcntr |= DISP_TILED;
219 
220 	if (rotation & DRM_MODE_ROTATE_180)
221 		dspcntr |= DISP_ROTATE_180;
222 
223 	if (rotation & DRM_MODE_REFLECT_X)
224 		dspcntr |= DISP_MIRROR;
225 
226 	return dspcntr;
227 }
228 
229 int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
230 {
231 	struct intel_display *display = to_intel_display(plane_state);
232 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
233 	const struct drm_framebuffer *fb = plane_state->hw.fb;
234 	int src_x, src_y, src_w;
235 	u32 offset;
236 	int ret;
237 
238 	ret = intel_plane_compute_gtt(plane_state);
239 	if (ret)
240 		return ret;
241 
242 	if (!plane_state->uapi.visible)
243 		return 0;
244 
245 	src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
246 	src_x = plane_state->uapi.src.x1 >> 16;
247 	src_y = plane_state->uapi.src.y1 >> 16;
248 
249 	/* Undocumented hardware limit on i965/g4x/vlv/chv */
250 	if (HAS_GMCH(display) && fb->format->cpp[0] == 8 && src_w > 2048) {
251 		drm_dbg_kms(display->drm,
252 			    "[PLANE:%d:%s] plane too wide (%d) for 64bpp\n",
253 			    plane->base.base.id, plane->base.name, src_w);
254 		return -EINVAL;
255 	}
256 
257 	intel_add_fb_offsets(&src_x, &src_y, plane_state, 0);
258 
259 	if (DISPLAY_VER(display) >= 4)
260 		offset = intel_plane_compute_aligned_offset(&src_x, &src_y,
261 							    plane_state, 0);
262 	else
263 		offset = 0;
264 
265 	/*
266 	 * When using an X-tiled surface the plane starts to
267 	 * misbehave if the x offset + width exceeds the stride.
268 	 * hsw/bdw: underrun galore
269 	 * ilk/snb/ivb: wrap to the next tile row mid scanout
270 	 * i965/g4x: so far appear immune to this
271 	 * vlv/chv: TODO check
272 	 *
273 	 * Linear surfaces seem to work just fine, even on hsw/bdw
274 	 * despite them not using the linear offset anymore.
275 	 */
276 	if (DISPLAY_VER(display) >= 4 && fb->modifier == I915_FORMAT_MOD_X_TILED) {
277 		unsigned int alignment = plane->min_alignment(plane, fb, 0);
278 		int cpp = fb->format->cpp[0];
279 
280 		while ((src_x + src_w) * cpp > plane_state->view.color_plane[0].mapping_stride) {
281 			if (offset == 0) {
282 				drm_dbg_kms(display->drm,
283 					    "[PLANE:%d:%s] unable to find suitable display surface offset due to X-tiling\n",
284 					    plane->base.base.id, plane->base.name);
285 				return -EINVAL;
286 			}
287 
288 			offset = intel_plane_adjust_aligned_offset(&src_x, &src_y, plane_state, 0,
289 								   offset, offset - alignment);
290 		}
291 	}
292 
293 	/*
294 	 * Put the final coordinates back so that the src
295 	 * coordinate checks will see the right values.
296 	 */
297 	drm_rect_translate_to(&plane_state->uapi.src,
298 			      src_x << 16, src_y << 16);
299 
300 	/* HSW/BDW do this automagically in hardware */
301 	if (!display->platform.haswell && !display->platform.broadwell) {
302 		unsigned int rotation = plane_state->hw.rotation;
303 		int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
304 		int src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
305 
306 		if (rotation & DRM_MODE_ROTATE_180) {
307 			src_x += src_w - 1;
308 			src_y += src_h - 1;
309 		} else if (rotation & DRM_MODE_REFLECT_X) {
310 			src_x += src_w - 1;
311 		}
312 	}
313 
314 	if (display->platform.haswell || display->platform.broadwell) {
315 		drm_WARN_ON(display->drm, src_x > 8191 || src_y > 4095);
316 	} else if (DISPLAY_VER(display) >= 4 &&
317 		   fb->modifier == I915_FORMAT_MOD_X_TILED) {
318 		drm_WARN_ON(display->drm, src_x > 4095 || src_y > 4095);
319 	}
320 
321 	plane_state->view.color_plane[0].offset = offset;
322 	plane_state->view.color_plane[0].x = src_x;
323 	plane_state->view.color_plane[0].y = src_y;
324 
325 	return 0;
326 }
327 
328 static int
329 i9xx_plane_check(struct intel_crtc_state *crtc_state,
330 		 struct intel_plane_state *plane_state)
331 {
332 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
333 	int ret;
334 
335 	ret = chv_plane_check_rotation(plane_state);
336 	if (ret)
337 		return ret;
338 
339 	ret = intel_plane_check_clipping(plane_state, crtc_state,
340 					 DRM_PLANE_NO_SCALING,
341 					 DRM_PLANE_NO_SCALING,
342 					 i9xx_plane_has_windowing(plane));
343 	if (ret)
344 		return ret;
345 
346 	ret = i9xx_check_plane_surface(plane_state);
347 	if (ret)
348 		return ret;
349 
350 	if (!plane_state->uapi.visible)
351 		return 0;
352 
353 	ret = intel_plane_check_src_coordinates(plane_state);
354 	if (ret)
355 		return ret;
356 
357 	plane_state->ctl = i9xx_plane_ctl(plane_state);
358 
359 	return 0;
360 }
361 
362 static u32 i8xx_plane_surf_offset(const struct intel_plane_state *plane_state)
363 {
364 	int x = plane_state->view.color_plane[0].x;
365 	int y = plane_state->view.color_plane[0].y;
366 
367 	return intel_fb_xy_to_linear(x, y, plane_state, 0);
368 }
369 
370 u32 i965_plane_surf_offset(const struct intel_plane_state *plane_state)
371 {
372 	return plane_state->view.color_plane[0].offset;
373 }
374 
375 static u32 i9xx_plane_ctl_crtc(const struct intel_crtc_state *crtc_state)
376 {
377 	struct intel_display *display = to_intel_display(crtc_state);
378 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
379 	u32 dspcntr = 0;
380 
381 	if (crtc_state->gamma_enable)
382 		dspcntr |= DISP_PIPE_GAMMA_ENABLE;
383 
384 	if (crtc_state->csc_enable)
385 		dspcntr |= DISP_PIPE_CSC_ENABLE;
386 
387 	if (DISPLAY_VER(display) < 5)
388 		dspcntr |= DISP_PIPE_SEL(crtc->pipe);
389 
390 	return dspcntr;
391 }
392 
393 static void i9xx_plane_ratio(const struct intel_crtc_state *crtc_state,
394 			     const struct intel_plane_state *plane_state,
395 			     unsigned int *num, unsigned int *den)
396 {
397 	const struct drm_framebuffer *fb = plane_state->hw.fb;
398 	unsigned int cpp = fb->format->cpp[0];
399 
400 	/*
401 	 * g4x bspec says 64bpp pixel rate can't exceed 80%
402 	 * of cdclk when the sprite plane is enabled on the
403 	 * same pipe. ilk/snb bspec says 64bpp pixel rate is
404 	 * never allowed to exceed 80% of cdclk. Let's just go
405 	 * with the ilk/snb limit always.
406 	 */
407 	if (cpp == 8) {
408 		*num = 10;
409 		*den = 8;
410 	} else {
411 		*num = 1;
412 		*den = 1;
413 	}
414 }
415 
416 static int i9xx_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
417 				const struct intel_plane_state *plane_state)
418 {
419 	unsigned int pixel_rate;
420 	unsigned int num, den;
421 
422 	/*
423 	 * Note that crtc_state->pixel_rate accounts for both
424 	 * horizontal and vertical panel fitter downscaling factors.
425 	 * Pre-HSW bspec tells us to only consider the horizontal
426 	 * downscaling factor here. We ignore that and just consider
427 	 * both for simplicity.
428 	 */
429 	pixel_rate = crtc_state->pixel_rate;
430 
431 	i9xx_plane_ratio(crtc_state, plane_state, &num, &den);
432 
433 	/* two pixels per clock with double wide pipe */
434 	if (crtc_state->double_wide)
435 		den *= 2;
436 
437 	return DIV_ROUND_UP(pixel_rate * num, den);
438 }
439 
440 static void i9xx_plane_update_noarm(struct intel_dsb *dsb,
441 				    struct intel_plane *plane,
442 				    const struct intel_crtc_state *crtc_state,
443 				    const struct intel_plane_state *plane_state)
444 {
445 	struct intel_display *display = to_intel_display(plane);
446 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
447 
448 	intel_de_write_fw(display, DSPSTRIDE(display, i9xx_plane),
449 			  plane_state->view.color_plane[0].mapping_stride);
450 
451 	if (DISPLAY_VER(display) < 4) {
452 		int crtc_x = plane_state->uapi.dst.x1;
453 		int crtc_y = plane_state->uapi.dst.y1;
454 		int crtc_w = drm_rect_width(&plane_state->uapi.dst);
455 		int crtc_h = drm_rect_height(&plane_state->uapi.dst);
456 
457 		/*
458 		 * PLANE_A doesn't actually have a full window
459 		 * generator but let's assume we still need to
460 		 * program whatever is there.
461 		 */
462 		intel_de_write_fw(display, DSPPOS(display, i9xx_plane),
463 				  DISP_POS_Y(crtc_y) | DISP_POS_X(crtc_x));
464 		intel_de_write_fw(display, DSPSIZE(display, i9xx_plane),
465 				  DISP_HEIGHT(crtc_h - 1) | DISP_WIDTH(crtc_w - 1));
466 	}
467 }
468 
469 static void i9xx_plane_update_arm(struct intel_dsb *dsb,
470 				  struct intel_plane *plane,
471 				  const struct intel_crtc_state *crtc_state,
472 				  const struct intel_plane_state *plane_state)
473 {
474 	struct intel_display *display = to_intel_display(plane);
475 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
476 	int x = plane_state->view.color_plane[0].x;
477 	int y = plane_state->view.color_plane[0].y;
478 	u32 dspcntr;
479 
480 	dspcntr = plane_state->ctl | i9xx_plane_ctl_crtc(crtc_state);
481 
482 	/* see intel_plane_atomic_calc_changes() */
483 	if (plane->need_async_flip_toggle_wa &&
484 	    crtc_state->async_flip_planes & BIT(plane->id))
485 		dspcntr |= DISP_ASYNC_FLIP;
486 
487 	if (display->platform.cherryview && i9xx_plane == PLANE_B) {
488 		int crtc_x = plane_state->uapi.dst.x1;
489 		int crtc_y = plane_state->uapi.dst.y1;
490 		int crtc_w = drm_rect_width(&plane_state->uapi.dst);
491 		int crtc_h = drm_rect_height(&plane_state->uapi.dst);
492 
493 		intel_de_write_fw(display, PRIMPOS(display, i9xx_plane),
494 				  PRIM_POS_Y(crtc_y) | PRIM_POS_X(crtc_x));
495 		intel_de_write_fw(display, PRIMSIZE(display, i9xx_plane),
496 				  PRIM_HEIGHT(crtc_h - 1) | PRIM_WIDTH(crtc_w - 1));
497 		intel_de_write_fw(display,
498 				  PRIMCNSTALPHA(display, i9xx_plane), 0);
499 	}
500 
501 	if (display->platform.haswell || display->platform.broadwell) {
502 		intel_de_write_fw(display, DSPOFFSET(display, i9xx_plane),
503 				  DISP_OFFSET_Y(y) | DISP_OFFSET_X(x));
504 	} else if (DISPLAY_VER(display) >= 4) {
505 		intel_de_write_fw(display, DSPLINOFF(display, i9xx_plane),
506 				  intel_fb_xy_to_linear(x, y, plane_state, 0));
507 		intel_de_write_fw(display, DSPTILEOFF(display, i9xx_plane),
508 				  DISP_OFFSET_Y(y) | DISP_OFFSET_X(x));
509 	}
510 
511 	/*
512 	 * The control register self-arms if the plane was previously
513 	 * disabled. Try to make the plane enable atomic by writing
514 	 * the control register just before the surface register.
515 	 */
516 	intel_de_write_fw(display, DSPCNTR(display, i9xx_plane), dspcntr);
517 
518 	if (DISPLAY_VER(display) >= 4)
519 		intel_de_write_fw(display, DSPSURF(display, i9xx_plane), plane_state->surf);
520 	else
521 		intel_de_write_fw(display, DSPADDR(display, i9xx_plane), plane_state->surf);
522 }
523 
524 static void i830_plane_update_arm(struct intel_dsb *dsb,
525 				  struct intel_plane *plane,
526 				  const struct intel_crtc_state *crtc_state,
527 				  const struct intel_plane_state *plane_state)
528 {
529 	/*
530 	 * On i830/i845 all registers are self-arming [ALM040].
531 	 *
532 	 * Additional breakage on i830 causes register reads to return
533 	 * the last latched value instead of the last written value [ALM026].
534 	 */
535 	i9xx_plane_update_noarm(dsb, plane, crtc_state, plane_state);
536 	i9xx_plane_update_arm(dsb, plane, crtc_state, plane_state);
537 }
538 
539 static void i9xx_plane_disable_arm(struct intel_dsb *dsb,
540 				   struct intel_plane *plane,
541 				   const struct intel_crtc_state *crtc_state)
542 {
543 	struct intel_display *display = to_intel_display(plane);
544 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
545 	u32 dspcntr;
546 
547 	/*
548 	 * DSPCNTR pipe gamma enable on g4x+ and pipe csc
549 	 * enable on ilk+ affect the pipe bottom color as
550 	 * well, so we must configure them even if the plane
551 	 * is disabled.
552 	 *
553 	 * On pre-g4x there is no way to gamma correct the
554 	 * pipe bottom color but we'll keep on doing this
555 	 * anyway so that the crtc state readout works correctly.
556 	 */
557 	dspcntr = i9xx_plane_ctl_crtc(crtc_state);
558 
559 	intel_de_write_fw(display, DSPCNTR(display, i9xx_plane), dspcntr);
560 
561 	if (DISPLAY_VER(display) >= 4)
562 		intel_de_write_fw(display, DSPSURF(display, i9xx_plane), 0);
563 	else
564 		intel_de_write_fw(display, DSPADDR(display, i9xx_plane), 0);
565 }
566 
567 static void g4x_primary_capture_error(struct intel_crtc *crtc,
568 				      struct intel_plane *plane,
569 				      struct intel_plane_error *error)
570 {
571 	struct intel_display *display = to_intel_display(plane);
572 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
573 
574 	error->ctl = intel_de_read(display, DSPCNTR(display, i9xx_plane));
575 	error->surf = intel_de_read(display, DSPSURF(display, i9xx_plane));
576 	error->surflive = intel_de_read(display, DSPSURFLIVE(display, i9xx_plane));
577 }
578 
579 static void i965_plane_capture_error(struct intel_crtc *crtc,
580 				     struct intel_plane *plane,
581 				     struct intel_plane_error *error)
582 {
583 	struct intel_display *display = to_intel_display(plane);
584 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
585 
586 	error->ctl = intel_de_read(display, DSPCNTR(display, i9xx_plane));
587 	error->surf = intel_de_read(display, DSPSURF(display, i9xx_plane));
588 }
589 
590 static void i8xx_plane_capture_error(struct intel_crtc *crtc,
591 				     struct intel_plane *plane,
592 				     struct intel_plane_error *error)
593 {
594 	struct intel_display *display = to_intel_display(plane);
595 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
596 
597 	error->ctl = intel_de_read(display, DSPCNTR(display, i9xx_plane));
598 	error->surf = intel_de_read(display, DSPADDR(display, i9xx_plane));
599 }
600 
601 static void
602 g4x_primary_async_flip(struct intel_dsb *dsb,
603 		       struct intel_plane *plane,
604 		       const struct intel_crtc_state *crtc_state,
605 		       const struct intel_plane_state *plane_state,
606 		       bool async_flip)
607 {
608 	struct intel_display *display = to_intel_display(plane);
609 	u32 dspcntr = plane_state->ctl | i9xx_plane_ctl_crtc(crtc_state);
610 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
611 
612 	if (async_flip)
613 		dspcntr |= DISP_ASYNC_FLIP;
614 
615 	intel_de_write_fw(display, DSPCNTR(display, i9xx_plane), dspcntr);
616 	intel_de_write_fw(display, DSPSURF(display, i9xx_plane), plane_state->surf);
617 }
618 
619 static void
620 vlv_primary_async_flip(struct intel_dsb *dsb,
621 		       struct intel_plane *plane,
622 		       const struct intel_crtc_state *crtc_state,
623 		       const struct intel_plane_state *plane_state,
624 		       bool async_flip)
625 {
626 	struct intel_display *display = to_intel_display(plane);
627 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
628 
629 	intel_de_write_fw(display, DSPADDR_VLV(display, i9xx_plane), plane_state->surf);
630 }
631 
632 static void
633 bdw_primary_enable_flip_done(struct intel_plane *plane)
634 {
635 	struct intel_display *display = to_intel_display(plane);
636 	enum pipe pipe = plane->pipe;
637 
638 	spin_lock_irq(&display->irq.lock);
639 	bdw_enable_pipe_irq(display, pipe, GEN8_PIPE_PRIMARY_FLIP_DONE);
640 	spin_unlock_irq(&display->irq.lock);
641 }
642 
643 static void
644 bdw_primary_disable_flip_done(struct intel_plane *plane)
645 {
646 	struct intel_display *display = to_intel_display(plane);
647 	enum pipe pipe = plane->pipe;
648 
649 	spin_lock_irq(&display->irq.lock);
650 	bdw_disable_pipe_irq(display, pipe, GEN8_PIPE_PRIMARY_FLIP_DONE);
651 	spin_unlock_irq(&display->irq.lock);
652 }
653 
654 static void
655 ivb_primary_enable_flip_done(struct intel_plane *plane)
656 {
657 	struct intel_display *display = to_intel_display(plane);
658 
659 	spin_lock_irq(&display->irq.lock);
660 	ilk_enable_display_irq(display, DE_PLANE_FLIP_DONE_IVB(plane->i9xx_plane));
661 	spin_unlock_irq(&display->irq.lock);
662 }
663 
664 static void
665 ivb_primary_disable_flip_done(struct intel_plane *plane)
666 {
667 	struct intel_display *display = to_intel_display(plane);
668 
669 	spin_lock_irq(&display->irq.lock);
670 	ilk_disable_display_irq(display, DE_PLANE_FLIP_DONE_IVB(plane->i9xx_plane));
671 	spin_unlock_irq(&display->irq.lock);
672 }
673 
674 static void
675 ilk_primary_enable_flip_done(struct intel_plane *plane)
676 {
677 	struct intel_display *display = to_intel_display(plane);
678 
679 	spin_lock_irq(&display->irq.lock);
680 	ilk_enable_display_irq(display, DE_PLANE_FLIP_DONE(plane->i9xx_plane));
681 	spin_unlock_irq(&display->irq.lock);
682 }
683 
684 static void
685 ilk_primary_disable_flip_done(struct intel_plane *plane)
686 {
687 	struct intel_display *display = to_intel_display(plane);
688 
689 	spin_lock_irq(&display->irq.lock);
690 	ilk_disable_display_irq(display, DE_PLANE_FLIP_DONE(plane->i9xx_plane));
691 	spin_unlock_irq(&display->irq.lock);
692 }
693 
694 static void
695 vlv_primary_enable_flip_done(struct intel_plane *plane)
696 {
697 	struct intel_display *display = to_intel_display(plane);
698 	enum pipe pipe = plane->pipe;
699 
700 	spin_lock_irq(&display->irq.lock);
701 	i915_enable_pipestat(display, pipe, PLANE_FLIP_DONE_INT_STATUS_VLV);
702 	spin_unlock_irq(&display->irq.lock);
703 }
704 
705 static void
706 vlv_primary_disable_flip_done(struct intel_plane *plane)
707 {
708 	struct intel_display *display = to_intel_display(plane);
709 	enum pipe pipe = plane->pipe;
710 
711 	spin_lock_irq(&display->irq.lock);
712 	i915_disable_pipestat(display, pipe, PLANE_FLIP_DONE_INT_STATUS_VLV);
713 	spin_unlock_irq(&display->irq.lock);
714 }
715 
716 static bool i9xx_plane_can_async_flip(u64 modifier)
717 {
718 	return modifier == I915_FORMAT_MOD_X_TILED;
719 }
720 
721 static bool i9xx_plane_get_hw_state(struct intel_plane *plane,
722 				    enum pipe *pipe)
723 {
724 	struct intel_display *display = to_intel_display(plane);
725 	enum intel_display_power_domain power_domain;
726 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
727 	intel_wakeref_t wakeref;
728 	bool ret;
729 	u32 val;
730 
731 	/*
732 	 * Not 100% correct for planes that can move between pipes,
733 	 * but that's only the case for gen2-4 which don't have any
734 	 * display power wells.
735 	 */
736 	power_domain = POWER_DOMAIN_PIPE(plane->pipe);
737 	wakeref = intel_display_power_get_if_enabled(display, power_domain);
738 	if (!wakeref)
739 		return false;
740 
741 	val = intel_de_read(display, DSPCNTR(display, i9xx_plane));
742 
743 	ret = val & DISP_ENABLE;
744 
745 	if (DISPLAY_VER(display) >= 5)
746 		*pipe = plane->pipe;
747 	else
748 		*pipe = REG_FIELD_GET(DISP_PIPE_SEL_MASK, val);
749 
750 	intel_display_power_put(display, power_domain, wakeref);
751 
752 	return ret;
753 }
754 
755 static unsigned int
756 hsw_primary_max_stride(struct intel_plane *plane,
757 		       u32 pixel_format, u64 modifier,
758 		       unsigned int rotation)
759 {
760 	const struct drm_format_info *info = drm_format_info(pixel_format);
761 	int cpp = info->cpp[0];
762 
763 	/* Limit to 8k pixels to guarantee OFFSET.x doesn't get too big. */
764 	return min(8192 * cpp, 32 * 1024);
765 }
766 
767 static unsigned int
768 ilk_primary_max_stride(struct intel_plane *plane,
769 		       u32 pixel_format, u64 modifier,
770 		       unsigned int rotation)
771 {
772 	const struct drm_format_info *info = drm_format_info(pixel_format);
773 	int cpp = info->cpp[0];
774 
775 	/* Limit to 4k pixels to guarantee TILEOFF.x doesn't get too big. */
776 	if (modifier == I915_FORMAT_MOD_X_TILED)
777 		return min(4096 * cpp, 32 * 1024);
778 	else
779 		return 32 * 1024;
780 }
781 
782 unsigned int
783 i965_plane_max_stride(struct intel_plane *plane,
784 		      u32 pixel_format, u64 modifier,
785 		      unsigned int rotation)
786 {
787 	const struct drm_format_info *info = drm_format_info(pixel_format);
788 	int cpp = info->cpp[0];
789 
790 	/* Limit to 4k pixels to guarantee TILEOFF.x doesn't get too big. */
791 	if (modifier == I915_FORMAT_MOD_X_TILED)
792 		return min(4096 * cpp, 16 * 1024);
793 	else
794 		return 32 * 1024;
795 }
796 
797 static unsigned int
798 i915_plane_max_stride(struct intel_plane *plane,
799 		      u32 pixel_format, u64 modifier,
800 		      unsigned int rotation)
801 {
802 	if (modifier == I915_FORMAT_MOD_X_TILED)
803 		return 8 * 1024;
804 	else
805 		return 16 * 1024;
806 }
807 
808 static unsigned int
809 i8xx_plane_max_stride(struct intel_plane *plane,
810 		      u32 pixel_format, u64 modifier,
811 		      unsigned int rotation)
812 {
813 	if (plane->i9xx_plane == PLANE_C)
814 		return 4 * 1024;
815 	else
816 		return 8 * 1024;
817 }
818 
819 unsigned int vlv_plane_min_alignment(struct intel_plane *plane,
820 				     const struct drm_framebuffer *fb,
821 				     int color_plane)
822 {
823 	struct intel_display *display = to_intel_display(plane);
824 
825 	if (intel_plane_can_async_flip(plane, fb->format->format, fb->modifier))
826 		return 256 * 1024;
827 
828 	/* FIXME undocumented so not sure what's actually needed */
829 	if (intel_scanout_needs_vtd_wa(display))
830 		return 256 * 1024;
831 
832 	switch (fb->modifier) {
833 	case I915_FORMAT_MOD_X_TILED:
834 		return 4 * 1024;
835 	case DRM_FORMAT_MOD_LINEAR:
836 		return 128 * 1024;
837 	default:
838 		MISSING_CASE(fb->modifier);
839 		return 0;
840 	}
841 }
842 
843 static unsigned int g4x_primary_min_alignment(struct intel_plane *plane,
844 					      const struct drm_framebuffer *fb,
845 					      int color_plane)
846 {
847 	struct intel_display *display = to_intel_display(plane);
848 
849 	if (intel_plane_can_async_flip(plane, fb->format->format, fb->modifier))
850 		return 256 * 1024;
851 
852 	if (intel_scanout_needs_vtd_wa(display))
853 		return 256 * 1024;
854 
855 	switch (fb->modifier) {
856 	case I915_FORMAT_MOD_X_TILED:
857 	case DRM_FORMAT_MOD_LINEAR:
858 		return 4 * 1024;
859 	default:
860 		MISSING_CASE(fb->modifier);
861 		return 0;
862 	}
863 }
864 
865 static unsigned int i965_plane_min_alignment(struct intel_plane *plane,
866 					     const struct drm_framebuffer *fb,
867 					     int color_plane)
868 {
869 	switch (fb->modifier) {
870 	case I915_FORMAT_MOD_X_TILED:
871 		return 4 * 1024;
872 	case DRM_FORMAT_MOD_LINEAR:
873 		return 128 * 1024;
874 	default:
875 		MISSING_CASE(fb->modifier);
876 		return 0;
877 	}
878 }
879 
880 static unsigned int i9xx_plane_min_alignment(struct intel_plane *plane,
881 					     const struct drm_framebuffer *fb,
882 					     int color_plane)
883 {
884 	return 0;
885 }
886 
887 static const struct drm_plane_funcs i965_plane_funcs = {
888 	.update_plane = drm_atomic_helper_update_plane,
889 	.disable_plane = drm_atomic_helper_disable_plane,
890 	.destroy = intel_plane_destroy,
891 	.atomic_duplicate_state = intel_plane_duplicate_state,
892 	.atomic_destroy_state = intel_plane_destroy_state,
893 	.format_mod_supported = i965_plane_format_mod_supported,
894 	.format_mod_supported_async = intel_plane_format_mod_supported_async,
895 };
896 
897 static const struct drm_plane_funcs i8xx_plane_funcs = {
898 	.update_plane = drm_atomic_helper_update_plane,
899 	.disable_plane = drm_atomic_helper_disable_plane,
900 	.destroy = intel_plane_destroy,
901 	.atomic_duplicate_state = intel_plane_duplicate_state,
902 	.atomic_destroy_state = intel_plane_destroy_state,
903 	.format_mod_supported = i8xx_plane_format_mod_supported,
904 	.format_mod_supported_async = intel_plane_format_mod_supported_async,
905 };
906 
907 static void i9xx_disable_tiling(struct intel_plane *plane)
908 {
909 	struct intel_display *display = to_intel_display(plane);
910 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
911 	u32 dspcntr;
912 	u32 reg;
913 
914 	dspcntr = intel_de_read_fw(display, DSPCNTR(display, i9xx_plane));
915 	dspcntr &= ~DISP_TILED;
916 	intel_de_write_fw(display, DSPCNTR(display, i9xx_plane), dspcntr);
917 
918 	if (DISPLAY_VER(display) >= 4) {
919 		reg = intel_de_read_fw(display, DSPSURF(display, i9xx_plane));
920 		intel_de_write_fw(display, DSPSURF(display, i9xx_plane), reg);
921 
922 	} else {
923 		reg = intel_de_read_fw(display, DSPADDR(display, i9xx_plane));
924 		intel_de_write_fw(display, DSPADDR(display, i9xx_plane), reg);
925 	}
926 }
927 
928 struct intel_plane *
929 intel_primary_plane_create(struct intel_display *display, enum pipe pipe)
930 {
931 	struct intel_plane *plane;
932 	const struct drm_plane_funcs *plane_funcs;
933 	unsigned int supported_rotations;
934 	const u64 *modifiers;
935 	const u32 *formats;
936 	int num_formats;
937 	int ret, zpos;
938 
939 	plane = intel_plane_alloc();
940 	if (IS_ERR(plane))
941 		return plane;
942 
943 	plane->pipe = pipe;
944 	/*
945 	 * On gen2/3 only plane A can do FBC, but the panel fitter and LVDS
946 	 * port is hooked to pipe B. Hence we want plane A feeding pipe B.
947 	 */
948 	if (HAS_FBC(display) && DISPLAY_VER(display) < 4 &&
949 	    INTEL_NUM_PIPES(display) == 2)
950 		plane->i9xx_plane = (enum i9xx_plane_id) !pipe;
951 	else
952 		plane->i9xx_plane = (enum i9xx_plane_id) pipe;
953 	plane->id = PLANE_PRIMARY;
954 	plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id);
955 
956 	intel_fbc_add_plane(i9xx_plane_fbc(display, plane->i9xx_plane), plane);
957 
958 	if (display->platform.valleyview || display->platform.cherryview) {
959 		formats = vlv_primary_formats;
960 		num_formats = ARRAY_SIZE(vlv_primary_formats);
961 	} else if (DISPLAY_VER(display) >= 4) {
962 		/*
963 		 * WaFP16GammaEnabling:ivb
964 		 * "Workaround : When using the 64-bit format, the plane
965 		 *  output on each color channel has one quarter amplitude.
966 		 *  It can be brought up to full amplitude by using pipe
967 		 *  gamma correction or pipe color space conversion to
968 		 *  multiply the plane output by four."
969 		 *
970 		 * There is no dedicated plane gamma for the primary plane,
971 		 * and using the pipe gamma/csc could conflict with other
972 		 * planes, so we choose not to expose fp16 on IVB primary
973 		 * planes. HSW primary planes no longer have this problem.
974 		 */
975 		if (display->platform.ivybridge) {
976 			formats = ivb_primary_formats;
977 			num_formats = ARRAY_SIZE(ivb_primary_formats);
978 		} else {
979 			formats = i965_primary_formats;
980 			num_formats = ARRAY_SIZE(i965_primary_formats);
981 		}
982 	} else {
983 		formats = i8xx_primary_formats;
984 		num_formats = ARRAY_SIZE(i8xx_primary_formats);
985 	}
986 
987 	if (DISPLAY_VER(display) >= 4)
988 		plane_funcs = &i965_plane_funcs;
989 	else
990 		plane_funcs = &i8xx_plane_funcs;
991 
992 	if (display->platform.valleyview || display->platform.cherryview)
993 		plane->min_cdclk = vlv_plane_min_cdclk;
994 	else if (display->platform.broadwell || display->platform.haswell)
995 		plane->min_cdclk = hsw_plane_min_cdclk;
996 	else if (display->platform.ivybridge)
997 		plane->min_cdclk = ivb_plane_min_cdclk;
998 	else
999 		plane->min_cdclk = i9xx_plane_min_cdclk;
1000 
1001 	if (HAS_GMCH(display)) {
1002 		if (DISPLAY_VER(display) >= 4)
1003 			plane->max_stride = i965_plane_max_stride;
1004 		else if (DISPLAY_VER(display) == 3)
1005 			plane->max_stride = i915_plane_max_stride;
1006 		else
1007 			plane->max_stride = i8xx_plane_max_stride;
1008 	} else {
1009 		if (display->platform.broadwell || display->platform.haswell)
1010 			plane->max_stride = hsw_primary_max_stride;
1011 		else
1012 			plane->max_stride = ilk_primary_max_stride;
1013 	}
1014 
1015 	if (display->platform.valleyview || display->platform.cherryview)
1016 		plane->min_alignment = vlv_plane_min_alignment;
1017 	else if (DISPLAY_VER(display) >= 5 || display->platform.g4x)
1018 		plane->min_alignment = g4x_primary_min_alignment;
1019 	else if (DISPLAY_VER(display) == 4)
1020 		plane->min_alignment = i965_plane_min_alignment;
1021 	else
1022 		plane->min_alignment = i9xx_plane_min_alignment;
1023 
1024 	/* FIXME undocumented for VLV/CHV so not sure what's actually needed */
1025 	if (intel_scanout_needs_vtd_wa(display))
1026 		plane->vtd_guard = 128;
1027 
1028 	if (display->platform.i830 || display->platform.i845g) {
1029 		plane->update_arm = i830_plane_update_arm;
1030 	} else {
1031 		plane->update_noarm = i9xx_plane_update_noarm;
1032 		plane->update_arm = i9xx_plane_update_arm;
1033 	}
1034 	plane->disable_arm = i9xx_plane_disable_arm;
1035 	plane->get_hw_state = i9xx_plane_get_hw_state;
1036 	plane->check_plane = i9xx_plane_check;
1037 
1038 	if (DISPLAY_VER(display) >= 4)
1039 		plane->surf_offset = i965_plane_surf_offset;
1040 	else
1041 		plane->surf_offset = i8xx_plane_surf_offset;
1042 
1043 	if (DISPLAY_VER(display) >= 5 || display->platform.g4x)
1044 		plane->capture_error = g4x_primary_capture_error;
1045 	else if (DISPLAY_VER(display) >= 4)
1046 		plane->capture_error = i965_plane_capture_error;
1047 	else
1048 		plane->capture_error = i8xx_plane_capture_error;
1049 
1050 	if (HAS_ASYNC_FLIPS(display)) {
1051 		if (display->platform.valleyview || display->platform.cherryview) {
1052 			plane->async_flip = vlv_primary_async_flip;
1053 			plane->enable_flip_done = vlv_primary_enable_flip_done;
1054 			plane->disable_flip_done = vlv_primary_disable_flip_done;
1055 			plane->can_async_flip = i9xx_plane_can_async_flip;
1056 		} else if (display->platform.broadwell) {
1057 			plane->need_async_flip_toggle_wa = true;
1058 			plane->async_flip = g4x_primary_async_flip;
1059 			plane->enable_flip_done = bdw_primary_enable_flip_done;
1060 			plane->disable_flip_done = bdw_primary_disable_flip_done;
1061 			plane->can_async_flip = i9xx_plane_can_async_flip;
1062 		} else if (DISPLAY_VER(display) >= 7) {
1063 			plane->async_flip = g4x_primary_async_flip;
1064 			plane->enable_flip_done = ivb_primary_enable_flip_done;
1065 			plane->disable_flip_done = ivb_primary_disable_flip_done;
1066 			plane->can_async_flip = i9xx_plane_can_async_flip;
1067 		} else if (DISPLAY_VER(display) >= 5) {
1068 			plane->async_flip = g4x_primary_async_flip;
1069 			plane->enable_flip_done = ilk_primary_enable_flip_done;
1070 			plane->disable_flip_done = ilk_primary_disable_flip_done;
1071 			plane->can_async_flip = i9xx_plane_can_async_flip;
1072 		}
1073 	}
1074 
1075 	plane->disable_tiling = i9xx_disable_tiling;
1076 
1077 	modifiers = intel_fb_plane_get_modifiers(display, INTEL_PLANE_CAP_TILING_X);
1078 
1079 	if (DISPLAY_VER(display) >= 5 || display->platform.g4x)
1080 		ret = drm_universal_plane_init(display->drm, &plane->base,
1081 					       0, plane_funcs,
1082 					       formats, num_formats,
1083 					       modifiers,
1084 					       DRM_PLANE_TYPE_PRIMARY,
1085 					       "primary %c", pipe_name(pipe));
1086 	else
1087 		ret = drm_universal_plane_init(display->drm, &plane->base,
1088 					       0, plane_funcs,
1089 					       formats, num_formats,
1090 					       modifiers,
1091 					       DRM_PLANE_TYPE_PRIMARY,
1092 					       "plane %c",
1093 					       plane_name(plane->i9xx_plane));
1094 
1095 	kfree(modifiers);
1096 
1097 	if (ret)
1098 		goto fail;
1099 
1100 	if (display->platform.cherryview && pipe == PIPE_B) {
1101 		supported_rotations =
1102 			DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
1103 			DRM_MODE_REFLECT_X;
1104 	} else if (DISPLAY_VER(display) >= 4) {
1105 		supported_rotations =
1106 			DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
1107 	} else {
1108 		supported_rotations = DRM_MODE_ROTATE_0;
1109 	}
1110 
1111 	if (DISPLAY_VER(display) >= 4)
1112 		drm_plane_create_rotation_property(&plane->base,
1113 						   DRM_MODE_ROTATE_0,
1114 						   supported_rotations);
1115 
1116 	zpos = 0;
1117 	drm_plane_create_zpos_immutable_property(&plane->base, zpos);
1118 
1119 	intel_plane_helper_add(plane);
1120 
1121 	return plane;
1122 
1123 fail:
1124 	intel_plane_free(plane);
1125 
1126 	return ERR_PTR(ret);
1127 }
1128 
1129 static int i9xx_format_to_fourcc(int format)
1130 {
1131 	switch (format) {
1132 	case DISP_FORMAT_8BPP:
1133 		return DRM_FORMAT_C8;
1134 	case DISP_FORMAT_BGRA555:
1135 		return DRM_FORMAT_ARGB1555;
1136 	case DISP_FORMAT_BGRX555:
1137 		return DRM_FORMAT_XRGB1555;
1138 	case DISP_FORMAT_BGRX565:
1139 		return DRM_FORMAT_RGB565;
1140 	default:
1141 	case DISP_FORMAT_BGRX888:
1142 		return DRM_FORMAT_XRGB8888;
1143 	case DISP_FORMAT_RGBX888:
1144 		return DRM_FORMAT_XBGR8888;
1145 	case DISP_FORMAT_BGRA888:
1146 		return DRM_FORMAT_ARGB8888;
1147 	case DISP_FORMAT_RGBA888:
1148 		return DRM_FORMAT_ABGR8888;
1149 	case DISP_FORMAT_BGRX101010:
1150 		return DRM_FORMAT_XRGB2101010;
1151 	case DISP_FORMAT_RGBX101010:
1152 		return DRM_FORMAT_XBGR2101010;
1153 	case DISP_FORMAT_BGRA101010:
1154 		return DRM_FORMAT_ARGB2101010;
1155 	case DISP_FORMAT_RGBA101010:
1156 		return DRM_FORMAT_ABGR2101010;
1157 	case DISP_FORMAT_RGBX161616:
1158 		return DRM_FORMAT_XBGR16161616F;
1159 	}
1160 }
1161 
1162 void
1163 i9xx_get_initial_plane_config(struct intel_crtc *crtc,
1164 			      struct intel_initial_plane_config *plane_config)
1165 {
1166 	struct intel_display *display = to_intel_display(crtc);
1167 	struct intel_plane *plane = to_intel_plane(crtc->base.primary);
1168 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
1169 	enum pipe pipe;
1170 	u32 val, base, offset;
1171 	int fourcc, pixel_format;
1172 	unsigned int aligned_height;
1173 	struct drm_framebuffer *fb;
1174 	struct intel_framebuffer *intel_fb;
1175 
1176 	if (!plane->get_hw_state(plane, &pipe))
1177 		return;
1178 
1179 	drm_WARN_ON(display->drm, pipe != crtc->pipe);
1180 
1181 	intel_fb = intel_framebuffer_alloc();
1182 	if (!intel_fb) {
1183 		drm_dbg_kms(display->drm, "failed to alloc fb\n");
1184 		return;
1185 	}
1186 
1187 	fb = &intel_fb->base;
1188 
1189 	fb->dev = display->drm;
1190 
1191 	val = intel_de_read(display, DSPCNTR(display, i9xx_plane));
1192 
1193 	if (DISPLAY_VER(display) >= 4) {
1194 		if (val & DISP_TILED) {
1195 			plane_config->tiling = I915_TILING_X;
1196 			fb->modifier = I915_FORMAT_MOD_X_TILED;
1197 		}
1198 
1199 		if (val & DISP_ROTATE_180)
1200 			plane_config->rotation = DRM_MODE_ROTATE_180;
1201 	}
1202 
1203 	if (display->platform.cherryview &&
1204 	    pipe == PIPE_B && val & DISP_MIRROR)
1205 		plane_config->rotation |= DRM_MODE_REFLECT_X;
1206 
1207 	pixel_format = val & DISP_FORMAT_MASK;
1208 	fourcc = i9xx_format_to_fourcc(pixel_format);
1209 	fb->format = drm_format_info(fourcc);
1210 
1211 	if (display->platform.haswell || display->platform.broadwell) {
1212 		offset = intel_de_read(display,
1213 				       DSPOFFSET(display, i9xx_plane));
1214 		base = intel_de_read(display, DSPSURF(display, i9xx_plane)) & DISP_ADDR_MASK;
1215 	} else if (DISPLAY_VER(display) >= 4) {
1216 		if (plane_config->tiling)
1217 			offset = intel_de_read(display,
1218 					       DSPTILEOFF(display, i9xx_plane));
1219 		else
1220 			offset = intel_de_read(display,
1221 					       DSPLINOFF(display, i9xx_plane));
1222 		base = intel_de_read(display, DSPSURF(display, i9xx_plane)) & DISP_ADDR_MASK;
1223 	} else {
1224 		offset = 0;
1225 		base = intel_de_read(display, DSPADDR(display, i9xx_plane));
1226 	}
1227 	plane_config->base = base;
1228 
1229 	drm_WARN_ON(display->drm, offset != 0);
1230 
1231 	val = intel_de_read(display, PIPESRC(display, pipe));
1232 	fb->width = REG_FIELD_GET(PIPESRC_WIDTH_MASK, val) + 1;
1233 	fb->height = REG_FIELD_GET(PIPESRC_HEIGHT_MASK, val) + 1;
1234 
1235 	val = intel_de_read(display, DSPSTRIDE(display, i9xx_plane));
1236 	fb->pitches[0] = val & 0xffffffc0;
1237 
1238 	aligned_height = intel_fb_align_height(fb, 0, fb->height);
1239 
1240 	plane_config->size = fb->pitches[0] * aligned_height;
1241 
1242 	drm_dbg_kms(display->drm,
1243 		    "[CRTC:%d:%s][PLANE:%d:%s] with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
1244 		    crtc->base.base.id, crtc->base.name,
1245 		    plane->base.base.id, plane->base.name,
1246 		    fb->width, fb->height, fb->format->cpp[0] * 8,
1247 		    base, fb->pitches[0], plane_config->size);
1248 
1249 	plane_config->fb = intel_fb;
1250 }
1251 
1252 bool i9xx_fixup_initial_plane_config(struct intel_crtc *crtc,
1253 				     const struct intel_initial_plane_config *plane_config)
1254 {
1255 	struct intel_display *display = to_intel_display(crtc);
1256 	struct intel_plane *plane = to_intel_plane(crtc->base.primary);
1257 	const struct intel_plane_state *plane_state =
1258 		to_intel_plane_state(plane->base.state);
1259 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
1260 
1261 	if (!plane_state->uapi.visible)
1262 		return false;
1263 
1264 	/*
1265 	 * We may have moved the surface to a different
1266 	 * part of ggtt, make the plane aware of that.
1267 	 */
1268 	if (plane_config->base == plane_state->surf)
1269 		return false;
1270 
1271 	if (DISPLAY_VER(display) >= 4)
1272 		intel_de_write(display, DSPSURF(display, i9xx_plane), plane_state->surf);
1273 	else
1274 		intel_de_write(display, DSPADDR(display, i9xx_plane), plane_state->surf);
1275 
1276 	return true;
1277 }
1278