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