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