xref: /linux/drivers/gpu/drm/i915/display/i9xx_plane.c (revision d30c1683aaecb93d2ab95685dc4300a33d3cea7a)
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 "i9xx_plane.h"
15 #include "i9xx_plane_regs.h"
16 #include "intel_atomic.h"
17 #include "intel_de.h"
18 #include "intel_display_irq.h"
19 #include "intel_display_regs.h"
20 #include "intel_display_types.h"
21 #include "intel_display_utils.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 		       const struct drm_format_info *info,
758 		       u64 modifier, unsigned int rotation)
759 {
760 	int cpp = info->cpp[0];
761 
762 	/* Limit to 8k pixels to guarantee OFFSET.x doesn't get too big. */
763 	return min(8192 * cpp, 32 * 1024);
764 }
765 
766 static unsigned int
767 ilk_primary_max_stride(struct intel_plane *plane,
768 		       const struct drm_format_info *info,
769 		       u64 modifier, unsigned int rotation)
770 {
771 	int cpp = info->cpp[0];
772 
773 	/* Limit to 4k pixels to guarantee TILEOFF.x doesn't get too big. */
774 	if (modifier == I915_FORMAT_MOD_X_TILED)
775 		return min(4096 * cpp, 32 * 1024);
776 	else
777 		return 32 * 1024;
778 }
779 
780 unsigned int
781 i965_plane_max_stride(struct intel_plane *plane,
782 		      const struct drm_format_info *info,
783 		      u64 modifier, unsigned int rotation)
784 {
785 	int cpp = info->cpp[0];
786 
787 	/* Limit to 4k pixels to guarantee TILEOFF.x doesn't get too big. */
788 	if (modifier == I915_FORMAT_MOD_X_TILED)
789 		return min(4096 * cpp, 16 * 1024);
790 	else
791 		return 32 * 1024;
792 }
793 
794 static unsigned int
795 i915_plane_max_stride(struct intel_plane *plane,
796 		      const struct drm_format_info *info,
797 		      u64 modifier, unsigned int rotation)
798 {
799 	if (modifier == I915_FORMAT_MOD_X_TILED)
800 		return 8 * 1024;
801 	else
802 		return 16 * 1024;
803 }
804 
805 static unsigned int
806 i8xx_plane_max_stride(struct intel_plane *plane,
807 		      const struct drm_format_info *info,
808 		      u64 modifier, unsigned int rotation)
809 {
810 	if (plane->i9xx_plane == PLANE_C)
811 		return 4 * 1024;
812 	else
813 		return 8 * 1024;
814 }
815 
816 unsigned int vlv_plane_min_alignment(struct intel_plane *plane,
817 				     const struct drm_framebuffer *fb,
818 				     int color_plane)
819 {
820 	struct intel_display *display = to_intel_display(plane);
821 
822 	if (intel_plane_can_async_flip(plane, fb->format->format, fb->modifier))
823 		return 256 * 1024;
824 
825 	/* FIXME undocumented so not sure what's actually needed */
826 	if (intel_scanout_needs_vtd_wa(display))
827 		return 256 * 1024;
828 
829 	switch (fb->modifier) {
830 	case I915_FORMAT_MOD_X_TILED:
831 		return 4 * 1024;
832 	case DRM_FORMAT_MOD_LINEAR:
833 		return 128 * 1024;
834 	default:
835 		MISSING_CASE(fb->modifier);
836 		return 0;
837 	}
838 }
839 
840 static unsigned int g4x_primary_min_alignment(struct intel_plane *plane,
841 					      const struct drm_framebuffer *fb,
842 					      int color_plane)
843 {
844 	struct intel_display *display = to_intel_display(plane);
845 
846 	if (intel_plane_can_async_flip(plane, fb->format->format, fb->modifier))
847 		return 256 * 1024;
848 
849 	if (intel_scanout_needs_vtd_wa(display))
850 		return 256 * 1024;
851 
852 	switch (fb->modifier) {
853 	case I915_FORMAT_MOD_X_TILED:
854 	case DRM_FORMAT_MOD_LINEAR:
855 		return 4 * 1024;
856 	default:
857 		MISSING_CASE(fb->modifier);
858 		return 0;
859 	}
860 }
861 
862 static unsigned int i965_plane_min_alignment(struct intel_plane *plane,
863 					     const struct drm_framebuffer *fb,
864 					     int color_plane)
865 {
866 	switch (fb->modifier) {
867 	case I915_FORMAT_MOD_X_TILED:
868 		return 4 * 1024;
869 	case DRM_FORMAT_MOD_LINEAR:
870 		return 128 * 1024;
871 	default:
872 		MISSING_CASE(fb->modifier);
873 		return 0;
874 	}
875 }
876 
877 static unsigned int i9xx_plane_min_alignment(struct intel_plane *plane,
878 					     const struct drm_framebuffer *fb,
879 					     int color_plane)
880 {
881 	return 0;
882 }
883 
884 static const struct drm_plane_funcs i965_plane_funcs = {
885 	.update_plane = drm_atomic_helper_update_plane,
886 	.disable_plane = drm_atomic_helper_disable_plane,
887 	.destroy = intel_plane_destroy,
888 	.atomic_duplicate_state = intel_plane_duplicate_state,
889 	.atomic_destroy_state = intel_plane_destroy_state,
890 	.format_mod_supported = i965_plane_format_mod_supported,
891 	.format_mod_supported_async = intel_plane_format_mod_supported_async,
892 };
893 
894 static const struct drm_plane_funcs i8xx_plane_funcs = {
895 	.update_plane = drm_atomic_helper_update_plane,
896 	.disable_plane = drm_atomic_helper_disable_plane,
897 	.destroy = intel_plane_destroy,
898 	.atomic_duplicate_state = intel_plane_duplicate_state,
899 	.atomic_destroy_state = intel_plane_destroy_state,
900 	.format_mod_supported = i8xx_plane_format_mod_supported,
901 	.format_mod_supported_async = intel_plane_format_mod_supported_async,
902 };
903 
904 static void i9xx_disable_tiling(struct intel_plane *plane)
905 {
906 	struct intel_display *display = to_intel_display(plane);
907 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
908 	u32 dspcntr;
909 	u32 reg;
910 
911 	dspcntr = intel_de_read_fw(display, DSPCNTR(display, i9xx_plane));
912 	dspcntr &= ~DISP_TILED;
913 	intel_de_write_fw(display, DSPCNTR(display, i9xx_plane), dspcntr);
914 
915 	if (DISPLAY_VER(display) >= 4) {
916 		reg = intel_de_read_fw(display, DSPSURF(display, i9xx_plane));
917 		intel_de_write_fw(display, DSPSURF(display, i9xx_plane), reg);
918 
919 	} else {
920 		reg = intel_de_read_fw(display, DSPADDR(display, i9xx_plane));
921 		intel_de_write_fw(display, DSPADDR(display, i9xx_plane), reg);
922 	}
923 }
924 
925 struct intel_plane *
926 intel_primary_plane_create(struct intel_display *display, enum pipe pipe)
927 {
928 	struct intel_plane *plane;
929 	const struct drm_plane_funcs *plane_funcs;
930 	unsigned int supported_rotations;
931 	const u64 *modifiers;
932 	const u32 *formats;
933 	int num_formats;
934 	int ret, zpos;
935 
936 	plane = intel_plane_alloc();
937 	if (IS_ERR(plane))
938 		return plane;
939 
940 	plane->pipe = pipe;
941 	/*
942 	 * On gen2/3 only plane A can do FBC, but the panel fitter and LVDS
943 	 * port is hooked to pipe B. Hence we want plane A feeding pipe B.
944 	 */
945 	if (HAS_FBC(display) && DISPLAY_VER(display) < 4 &&
946 	    INTEL_NUM_PIPES(display) == 2)
947 		plane->i9xx_plane = (enum i9xx_plane_id) !pipe;
948 	else
949 		plane->i9xx_plane = (enum i9xx_plane_id) pipe;
950 	plane->id = PLANE_PRIMARY;
951 	plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id);
952 
953 	intel_fbc_add_plane(i9xx_plane_fbc(display, plane->i9xx_plane), plane);
954 
955 	if (display->platform.valleyview || display->platform.cherryview) {
956 		formats = vlv_primary_formats;
957 		num_formats = ARRAY_SIZE(vlv_primary_formats);
958 	} else if (DISPLAY_VER(display) >= 4) {
959 		/*
960 		 * WaFP16GammaEnabling:ivb
961 		 * "Workaround : When using the 64-bit format, the plane
962 		 *  output on each color channel has one quarter amplitude.
963 		 *  It can be brought up to full amplitude by using pipe
964 		 *  gamma correction or pipe color space conversion to
965 		 *  multiply the plane output by four."
966 		 *
967 		 * There is no dedicated plane gamma for the primary plane,
968 		 * and using the pipe gamma/csc could conflict with other
969 		 * planes, so we choose not to expose fp16 on IVB primary
970 		 * planes. HSW primary planes no longer have this problem.
971 		 */
972 		if (display->platform.ivybridge) {
973 			formats = ivb_primary_formats;
974 			num_formats = ARRAY_SIZE(ivb_primary_formats);
975 		} else {
976 			formats = i965_primary_formats;
977 			num_formats = ARRAY_SIZE(i965_primary_formats);
978 		}
979 	} else {
980 		formats = i8xx_primary_formats;
981 		num_formats = ARRAY_SIZE(i8xx_primary_formats);
982 	}
983 
984 	if (DISPLAY_VER(display) >= 4)
985 		plane_funcs = &i965_plane_funcs;
986 	else
987 		plane_funcs = &i8xx_plane_funcs;
988 
989 	if (display->platform.valleyview || display->platform.cherryview)
990 		plane->min_cdclk = vlv_plane_min_cdclk;
991 	else if (display->platform.broadwell || display->platform.haswell)
992 		plane->min_cdclk = hsw_plane_min_cdclk;
993 	else if (display->platform.ivybridge)
994 		plane->min_cdclk = ivb_plane_min_cdclk;
995 	else
996 		plane->min_cdclk = i9xx_plane_min_cdclk;
997 
998 	if (HAS_GMCH(display)) {
999 		if (DISPLAY_VER(display) >= 4)
1000 			plane->max_stride = i965_plane_max_stride;
1001 		else if (DISPLAY_VER(display) == 3)
1002 			plane->max_stride = i915_plane_max_stride;
1003 		else
1004 			plane->max_stride = i8xx_plane_max_stride;
1005 	} else {
1006 		if (display->platform.broadwell || display->platform.haswell)
1007 			plane->max_stride = hsw_primary_max_stride;
1008 		else
1009 			plane->max_stride = ilk_primary_max_stride;
1010 	}
1011 
1012 	if (display->platform.valleyview || display->platform.cherryview)
1013 		plane->min_alignment = vlv_plane_min_alignment;
1014 	else if (DISPLAY_VER(display) >= 5 || display->platform.g4x)
1015 		plane->min_alignment = g4x_primary_min_alignment;
1016 	else if (DISPLAY_VER(display) == 4)
1017 		plane->min_alignment = i965_plane_min_alignment;
1018 	else
1019 		plane->min_alignment = i9xx_plane_min_alignment;
1020 
1021 	/* FIXME undocumented for VLV/CHV so not sure what's actually needed */
1022 	if (intel_scanout_needs_vtd_wa(display))
1023 		plane->vtd_guard = 128;
1024 
1025 	if (display->platform.i830 || display->platform.i845g) {
1026 		plane->update_arm = i830_plane_update_arm;
1027 	} else {
1028 		plane->update_noarm = i9xx_plane_update_noarm;
1029 		plane->update_arm = i9xx_plane_update_arm;
1030 	}
1031 	plane->disable_arm = i9xx_plane_disable_arm;
1032 	plane->get_hw_state = i9xx_plane_get_hw_state;
1033 	plane->check_plane = i9xx_plane_check;
1034 
1035 	if (DISPLAY_VER(display) >= 4)
1036 		plane->surf_offset = i965_plane_surf_offset;
1037 	else
1038 		plane->surf_offset = i8xx_plane_surf_offset;
1039 
1040 	if (DISPLAY_VER(display) >= 5 || display->platform.g4x)
1041 		plane->capture_error = g4x_primary_capture_error;
1042 	else if (DISPLAY_VER(display) >= 4)
1043 		plane->capture_error = i965_plane_capture_error;
1044 	else
1045 		plane->capture_error = i8xx_plane_capture_error;
1046 
1047 	if (HAS_ASYNC_FLIPS(display)) {
1048 		if (display->platform.valleyview || display->platform.cherryview) {
1049 			plane->async_flip = vlv_primary_async_flip;
1050 			plane->enable_flip_done = vlv_primary_enable_flip_done;
1051 			plane->disable_flip_done = vlv_primary_disable_flip_done;
1052 			plane->can_async_flip = i9xx_plane_can_async_flip;
1053 		} else if (display->platform.broadwell) {
1054 			plane->need_async_flip_toggle_wa = true;
1055 			plane->async_flip = g4x_primary_async_flip;
1056 			plane->enable_flip_done = bdw_primary_enable_flip_done;
1057 			plane->disable_flip_done = bdw_primary_disable_flip_done;
1058 			plane->can_async_flip = i9xx_plane_can_async_flip;
1059 		} else if (DISPLAY_VER(display) >= 7) {
1060 			plane->async_flip = g4x_primary_async_flip;
1061 			plane->enable_flip_done = ivb_primary_enable_flip_done;
1062 			plane->disable_flip_done = ivb_primary_disable_flip_done;
1063 			plane->can_async_flip = i9xx_plane_can_async_flip;
1064 		} else if (DISPLAY_VER(display) >= 5) {
1065 			plane->async_flip = g4x_primary_async_flip;
1066 			plane->enable_flip_done = ilk_primary_enable_flip_done;
1067 			plane->disable_flip_done = ilk_primary_disable_flip_done;
1068 			plane->can_async_flip = i9xx_plane_can_async_flip;
1069 		}
1070 	}
1071 
1072 	plane->disable_tiling = i9xx_disable_tiling;
1073 
1074 	modifiers = intel_fb_plane_get_modifiers(display, INTEL_PLANE_CAP_TILING_X);
1075 
1076 	if (DISPLAY_VER(display) >= 5 || display->platform.g4x)
1077 		ret = drm_universal_plane_init(display->drm, &plane->base,
1078 					       0, plane_funcs,
1079 					       formats, num_formats,
1080 					       modifiers,
1081 					       DRM_PLANE_TYPE_PRIMARY,
1082 					       "primary %c", pipe_name(pipe));
1083 	else
1084 		ret = drm_universal_plane_init(display->drm, &plane->base,
1085 					       0, plane_funcs,
1086 					       formats, num_formats,
1087 					       modifiers,
1088 					       DRM_PLANE_TYPE_PRIMARY,
1089 					       "plane %c",
1090 					       plane_name(plane->i9xx_plane));
1091 
1092 	kfree(modifiers);
1093 
1094 	if (ret)
1095 		goto fail;
1096 
1097 	if (display->platform.cherryview && pipe == PIPE_B) {
1098 		supported_rotations =
1099 			DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
1100 			DRM_MODE_REFLECT_X;
1101 	} else if (DISPLAY_VER(display) >= 4) {
1102 		supported_rotations =
1103 			DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
1104 	} else {
1105 		supported_rotations = DRM_MODE_ROTATE_0;
1106 	}
1107 
1108 	if (DISPLAY_VER(display) >= 4)
1109 		drm_plane_create_rotation_property(&plane->base,
1110 						   DRM_MODE_ROTATE_0,
1111 						   supported_rotations);
1112 
1113 	zpos = 0;
1114 	drm_plane_create_zpos_immutable_property(&plane->base, zpos);
1115 
1116 	intel_plane_helper_add(plane);
1117 
1118 	return plane;
1119 
1120 fail:
1121 	intel_plane_free(plane);
1122 
1123 	return ERR_PTR(ret);
1124 }
1125 
1126 static int i9xx_format_to_fourcc(int format)
1127 {
1128 	switch (format) {
1129 	case DISP_FORMAT_8BPP:
1130 		return DRM_FORMAT_C8;
1131 	case DISP_FORMAT_BGRA555:
1132 		return DRM_FORMAT_ARGB1555;
1133 	case DISP_FORMAT_BGRX555:
1134 		return DRM_FORMAT_XRGB1555;
1135 	case DISP_FORMAT_BGRX565:
1136 		return DRM_FORMAT_RGB565;
1137 	default:
1138 	case DISP_FORMAT_BGRX888:
1139 		return DRM_FORMAT_XRGB8888;
1140 	case DISP_FORMAT_RGBX888:
1141 		return DRM_FORMAT_XBGR8888;
1142 	case DISP_FORMAT_BGRA888:
1143 		return DRM_FORMAT_ARGB8888;
1144 	case DISP_FORMAT_RGBA888:
1145 		return DRM_FORMAT_ABGR8888;
1146 	case DISP_FORMAT_BGRX101010:
1147 		return DRM_FORMAT_XRGB2101010;
1148 	case DISP_FORMAT_RGBX101010:
1149 		return DRM_FORMAT_XBGR2101010;
1150 	case DISP_FORMAT_BGRA101010:
1151 		return DRM_FORMAT_ARGB2101010;
1152 	case DISP_FORMAT_RGBA101010:
1153 		return DRM_FORMAT_ABGR2101010;
1154 	case DISP_FORMAT_RGBX161616:
1155 		return DRM_FORMAT_XBGR16161616F;
1156 	}
1157 }
1158 
1159 void
1160 i9xx_get_initial_plane_config(struct intel_crtc *crtc,
1161 			      struct intel_initial_plane_config *plane_config)
1162 {
1163 	struct intel_display *display = to_intel_display(crtc);
1164 	struct intel_plane *plane = to_intel_plane(crtc->base.primary);
1165 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
1166 	enum pipe pipe;
1167 	u32 val, base, offset;
1168 	int fourcc, pixel_format;
1169 	unsigned int aligned_height;
1170 	struct drm_framebuffer *fb;
1171 	struct intel_framebuffer *intel_fb;
1172 
1173 	if (!plane->get_hw_state(plane, &pipe))
1174 		return;
1175 
1176 	drm_WARN_ON(display->drm, pipe != crtc->pipe);
1177 
1178 	intel_fb = intel_framebuffer_alloc();
1179 	if (!intel_fb) {
1180 		drm_dbg_kms(display->drm, "failed to alloc fb\n");
1181 		return;
1182 	}
1183 
1184 	fb = &intel_fb->base;
1185 
1186 	fb->dev = display->drm;
1187 
1188 	val = intel_de_read(display, DSPCNTR(display, i9xx_plane));
1189 
1190 	if (DISPLAY_VER(display) >= 4) {
1191 		if (val & DISP_TILED)
1192 			fb->modifier = I915_FORMAT_MOD_X_TILED;
1193 
1194 		if (val & DISP_ROTATE_180)
1195 			plane_config->rotation = DRM_MODE_ROTATE_180;
1196 	}
1197 
1198 	if (display->platform.cherryview &&
1199 	    pipe == PIPE_B && val & DISP_MIRROR)
1200 		plane_config->rotation |= DRM_MODE_REFLECT_X;
1201 
1202 	pixel_format = val & DISP_FORMAT_MASK;
1203 	fourcc = i9xx_format_to_fourcc(pixel_format);
1204 
1205 	fb->format = drm_get_format_info(display->drm, fourcc, fb->modifier);
1206 
1207 	if (display->platform.haswell || display->platform.broadwell) {
1208 		offset = intel_de_read(display,
1209 				       DSPOFFSET(display, i9xx_plane));
1210 		base = intel_de_read(display, DSPSURF(display, i9xx_plane)) & DISP_ADDR_MASK;
1211 	} else if (DISPLAY_VER(display) >= 4) {
1212 		if (fb->modifier == I915_FORMAT_MOD_X_TILED)
1213 			offset = intel_de_read(display,
1214 					       DSPTILEOFF(display, i9xx_plane));
1215 		else
1216 			offset = intel_de_read(display,
1217 					       DSPLINOFF(display, i9xx_plane));
1218 		base = intel_de_read(display, DSPSURF(display, i9xx_plane)) & DISP_ADDR_MASK;
1219 	} else {
1220 		offset = 0;
1221 		base = intel_de_read(display, DSPADDR(display, i9xx_plane));
1222 	}
1223 	plane_config->base = base;
1224 
1225 	drm_WARN_ON(display->drm, offset != 0);
1226 
1227 	val = intel_de_read(display, PIPESRC(display, pipe));
1228 	fb->width = REG_FIELD_GET(PIPESRC_WIDTH_MASK, val) + 1;
1229 	fb->height = REG_FIELD_GET(PIPESRC_HEIGHT_MASK, val) + 1;
1230 
1231 	val = intel_de_read(display, DSPSTRIDE(display, i9xx_plane));
1232 	fb->pitches[0] = val & 0xffffffc0;
1233 
1234 	aligned_height = intel_fb_align_height(fb, 0, fb->height);
1235 
1236 	plane_config->size = fb->pitches[0] * aligned_height;
1237 
1238 	drm_dbg_kms(display->drm,
1239 		    "[CRTC:%d:%s][PLANE:%d:%s] with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
1240 		    crtc->base.base.id, crtc->base.name,
1241 		    plane->base.base.id, plane->base.name,
1242 		    fb->width, fb->height, fb->format->cpp[0] * 8,
1243 		    base, fb->pitches[0], plane_config->size);
1244 
1245 	plane_config->fb = intel_fb;
1246 }
1247 
1248 bool i9xx_fixup_initial_plane_config(struct intel_crtc *crtc,
1249 				     const struct intel_initial_plane_config *plane_config)
1250 {
1251 	struct intel_display *display = to_intel_display(crtc);
1252 	struct intel_plane *plane = to_intel_plane(crtc->base.primary);
1253 	const struct intel_plane_state *plane_state =
1254 		to_intel_plane_state(plane->base.state);
1255 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
1256 
1257 	if (!plane_state->uapi.visible)
1258 		return false;
1259 
1260 	/*
1261 	 * We may have moved the surface to a different
1262 	 * part of ggtt, make the plane aware of that.
1263 	 */
1264 	if (plane_config->base == plane_state->surf)
1265 		return false;
1266 
1267 	if (DISPLAY_VER(display) >= 4)
1268 		intel_de_write(display, DSPSURF(display, i9xx_plane), plane_state->surf);
1269 	else
1270 		intel_de_write(display, DSPADDR(display, i9xx_plane), plane_state->surf);
1271 
1272 	return true;
1273 }
1274