xref: /linux/drivers/gpu/drm/i915/display/i9xx_plane.c (revision f86ad0ed620cb3c91ec7d5468e93ac68d727539d)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2020 Intel Corporation
4  */
5 
6 #include <linux/kernel.h>
7 
8 #include <drm/drm_atomic_helper.h>
9 #include <drm/drm_blend.h>
10 #include <drm/drm_fourcc.h>
11 #include <drm/drm_print.h>
12 
13 #include "i915_reg.h"
14 #include "i915_utils.h"
15 #include "i9xx_plane.h"
16 #include "i9xx_plane_regs.h"
17 #include "intel_atomic.h"
18 #include "intel_atomic_plane.h"
19 #include "intel_de.h"
20 #include "intel_display_irq.h"
21 #include "intel_display_regs.h"
22 #include "intel_display_types.h"
23 #include "intel_fb.h"
24 #include "intel_fbc.h"
25 #include "intel_frontbuffer.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[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_crtc_state *crtc_state,
158 			  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_atomic_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(crtc_state, plane_state);
358 
359 	return 0;
360 }
361 
362 static u32 i9xx_plane_ctl_crtc(const struct intel_crtc_state *crtc_state)
363 {
364 	struct intel_display *display = to_intel_display(crtc_state);
365 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
366 	u32 dspcntr = 0;
367 
368 	if (crtc_state->gamma_enable)
369 		dspcntr |= DISP_PIPE_GAMMA_ENABLE;
370 
371 	if (crtc_state->csc_enable)
372 		dspcntr |= DISP_PIPE_CSC_ENABLE;
373 
374 	if (DISPLAY_VER(display) < 5)
375 		dspcntr |= DISP_PIPE_SEL(crtc->pipe);
376 
377 	return dspcntr;
378 }
379 
380 static void i9xx_plane_ratio(const struct intel_crtc_state *crtc_state,
381 			     const struct intel_plane_state *plane_state,
382 			     unsigned int *num, unsigned int *den)
383 {
384 	const struct drm_framebuffer *fb = plane_state->hw.fb;
385 	unsigned int cpp = fb->format->cpp[0];
386 
387 	/*
388 	 * g4x bspec says 64bpp pixel rate can't exceed 80%
389 	 * of cdclk when the sprite plane is enabled on the
390 	 * same pipe. ilk/snb bspec says 64bpp pixel rate is
391 	 * never allowed to exceed 80% of cdclk. Let's just go
392 	 * with the ilk/snb limit always.
393 	 */
394 	if (cpp == 8) {
395 		*num = 10;
396 		*den = 8;
397 	} else {
398 		*num = 1;
399 		*den = 1;
400 	}
401 }
402 
403 static int i9xx_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
404 				const struct intel_plane_state *plane_state)
405 {
406 	unsigned int pixel_rate;
407 	unsigned int num, den;
408 
409 	/*
410 	 * Note that crtc_state->pixel_rate accounts for both
411 	 * horizontal and vertical panel fitter downscaling factors.
412 	 * Pre-HSW bspec tells us to only consider the horizontal
413 	 * downscaling factor here. We ignore that and just consider
414 	 * both for simplicity.
415 	 */
416 	pixel_rate = crtc_state->pixel_rate;
417 
418 	i9xx_plane_ratio(crtc_state, plane_state, &num, &den);
419 
420 	/* two pixels per clock with double wide pipe */
421 	if (crtc_state->double_wide)
422 		den *= 2;
423 
424 	return DIV_ROUND_UP(pixel_rate * num, den);
425 }
426 
427 static void i9xx_plane_update_noarm(struct intel_dsb *dsb,
428 				    struct intel_plane *plane,
429 				    const struct intel_crtc_state *crtc_state,
430 				    const struct intel_plane_state *plane_state)
431 {
432 	struct intel_display *display = to_intel_display(plane);
433 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
434 
435 	intel_de_write_fw(display, DSPSTRIDE(display, i9xx_plane),
436 			  plane_state->view.color_plane[0].mapping_stride);
437 
438 	if (DISPLAY_VER(display) < 4) {
439 		int crtc_x = plane_state->uapi.dst.x1;
440 		int crtc_y = plane_state->uapi.dst.y1;
441 		int crtc_w = drm_rect_width(&plane_state->uapi.dst);
442 		int crtc_h = drm_rect_height(&plane_state->uapi.dst);
443 
444 		/*
445 		 * PLANE_A doesn't actually have a full window
446 		 * generator but let's assume we still need to
447 		 * program whatever is there.
448 		 */
449 		intel_de_write_fw(display, DSPPOS(display, i9xx_plane),
450 				  DISP_POS_Y(crtc_y) | DISP_POS_X(crtc_x));
451 		intel_de_write_fw(display, DSPSIZE(display, i9xx_plane),
452 				  DISP_HEIGHT(crtc_h - 1) | DISP_WIDTH(crtc_w - 1));
453 	}
454 }
455 
456 static void i9xx_plane_update_arm(struct intel_dsb *dsb,
457 				  struct intel_plane *plane,
458 				  const struct intel_crtc_state *crtc_state,
459 				  const struct intel_plane_state *plane_state)
460 {
461 	struct intel_display *display = to_intel_display(plane);
462 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
463 	int x = plane_state->view.color_plane[0].x;
464 	int y = plane_state->view.color_plane[0].y;
465 	u32 dspcntr, dspaddr_offset, linear_offset;
466 
467 	dspcntr = plane_state->ctl | i9xx_plane_ctl_crtc(crtc_state);
468 
469 	/* see intel_plane_atomic_calc_changes() */
470 	if (plane->need_async_flip_toggle_wa &&
471 	    crtc_state->async_flip_planes & BIT(plane->id))
472 		dspcntr |= DISP_ASYNC_FLIP;
473 
474 	linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
475 
476 	if (DISPLAY_VER(display) >= 4)
477 		dspaddr_offset = plane_state->view.color_plane[0].offset;
478 	else
479 		dspaddr_offset = linear_offset;
480 
481 	if (display->platform.cherryview && i9xx_plane == PLANE_B) {
482 		int crtc_x = plane_state->uapi.dst.x1;
483 		int crtc_y = plane_state->uapi.dst.y1;
484 		int crtc_w = drm_rect_width(&plane_state->uapi.dst);
485 		int crtc_h = drm_rect_height(&plane_state->uapi.dst);
486 
487 		intel_de_write_fw(display, PRIMPOS(display, i9xx_plane),
488 				  PRIM_POS_Y(crtc_y) | PRIM_POS_X(crtc_x));
489 		intel_de_write_fw(display, PRIMSIZE(display, i9xx_plane),
490 				  PRIM_HEIGHT(crtc_h - 1) | PRIM_WIDTH(crtc_w - 1));
491 		intel_de_write_fw(display,
492 				  PRIMCNSTALPHA(display, i9xx_plane), 0);
493 	}
494 
495 	if (display->platform.haswell || display->platform.broadwell) {
496 		intel_de_write_fw(display, DSPOFFSET(display, i9xx_plane),
497 				  DISP_OFFSET_Y(y) | DISP_OFFSET_X(x));
498 	} else if (DISPLAY_VER(display) >= 4) {
499 		intel_de_write_fw(display, DSPLINOFF(display, i9xx_plane),
500 				  linear_offset);
501 		intel_de_write_fw(display, DSPTILEOFF(display, i9xx_plane),
502 				  DISP_OFFSET_Y(y) | DISP_OFFSET_X(x));
503 	}
504 
505 	/*
506 	 * The control register self-arms if the plane was previously
507 	 * disabled. Try to make the plane enable atomic by writing
508 	 * the control register just before the surface register.
509 	 */
510 	intel_de_write_fw(display, DSPCNTR(display, i9xx_plane), dspcntr);
511 
512 	if (DISPLAY_VER(display) >= 4)
513 		intel_de_write_fw(display, DSPSURF(display, i9xx_plane),
514 				  intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
515 	else
516 		intel_de_write_fw(display, DSPADDR(display, i9xx_plane),
517 				  intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
518 }
519 
520 static void i830_plane_update_arm(struct intel_dsb *dsb,
521 				  struct intel_plane *plane,
522 				  const struct intel_crtc_state *crtc_state,
523 				  const struct intel_plane_state *plane_state)
524 {
525 	/*
526 	 * On i830/i845 all registers are self-arming [ALM040].
527 	 *
528 	 * Additional breakage on i830 causes register reads to return
529 	 * the last latched value instead of the last written value [ALM026].
530 	 */
531 	i9xx_plane_update_noarm(dsb, plane, crtc_state, plane_state);
532 	i9xx_plane_update_arm(dsb, plane, crtc_state, plane_state);
533 }
534 
535 static void i9xx_plane_disable_arm(struct intel_dsb *dsb,
536 				   struct intel_plane *plane,
537 				   const struct intel_crtc_state *crtc_state)
538 {
539 	struct intel_display *display = to_intel_display(plane);
540 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
541 	u32 dspcntr;
542 
543 	/*
544 	 * DSPCNTR pipe gamma enable on g4x+ and pipe csc
545 	 * enable on ilk+ affect the pipe bottom color as
546 	 * well, so we must configure them even if the plane
547 	 * is disabled.
548 	 *
549 	 * On pre-g4x there is no way to gamma correct the
550 	 * pipe bottom color but we'll keep on doing this
551 	 * anyway so that the crtc state readout works correctly.
552 	 */
553 	dspcntr = i9xx_plane_ctl_crtc(crtc_state);
554 
555 	intel_de_write_fw(display, DSPCNTR(display, i9xx_plane), dspcntr);
556 
557 	if (DISPLAY_VER(display) >= 4)
558 		intel_de_write_fw(display, DSPSURF(display, i9xx_plane), 0);
559 	else
560 		intel_de_write_fw(display, DSPADDR(display, i9xx_plane), 0);
561 }
562 
563 static void g4x_primary_capture_error(struct intel_crtc *crtc,
564 				      struct intel_plane *plane,
565 				      struct intel_plane_error *error)
566 {
567 	struct intel_display *display = to_intel_display(plane);
568 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
569 
570 	error->ctl = intel_de_read(display, DSPCNTR(display, i9xx_plane));
571 	error->surf = intel_de_read(display, DSPSURF(display, i9xx_plane));
572 	error->surflive = intel_de_read(display, DSPSURFLIVE(display, i9xx_plane));
573 }
574 
575 static void i965_plane_capture_error(struct intel_crtc *crtc,
576 				     struct intel_plane *plane,
577 				     struct intel_plane_error *error)
578 {
579 	struct intel_display *display = to_intel_display(plane);
580 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
581 
582 	error->ctl = intel_de_read(display, DSPCNTR(display, i9xx_plane));
583 	error->surf = intel_de_read(display, DSPSURF(display, i9xx_plane));
584 }
585 
586 static void i8xx_plane_capture_error(struct intel_crtc *crtc,
587 				     struct intel_plane *plane,
588 				     struct intel_plane_error *error)
589 {
590 	struct intel_display *display = to_intel_display(plane);
591 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
592 
593 	error->ctl = intel_de_read(display, DSPCNTR(display, i9xx_plane));
594 	error->surf = intel_de_read(display, DSPADDR(display, i9xx_plane));
595 }
596 
597 static void
598 g4x_primary_async_flip(struct intel_dsb *dsb,
599 		       struct intel_plane *plane,
600 		       const struct intel_crtc_state *crtc_state,
601 		       const struct intel_plane_state *plane_state,
602 		       bool async_flip)
603 {
604 	struct intel_display *display = to_intel_display(plane);
605 	u32 dspcntr = plane_state->ctl | i9xx_plane_ctl_crtc(crtc_state);
606 	u32 dspaddr_offset = plane_state->view.color_plane[0].offset;
607 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
608 
609 	if (async_flip)
610 		dspcntr |= DISP_ASYNC_FLIP;
611 
612 	intel_de_write_fw(display, DSPCNTR(display, i9xx_plane), dspcntr);
613 
614 	intel_de_write_fw(display, DSPSURF(display, i9xx_plane),
615 			  intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
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 	u32 dspaddr_offset = plane_state->view.color_plane[0].offset;
627 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
628 
629 	intel_de_write_fw(display, DSPADDR_VLV(display, i9xx_plane),
630 			  intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
631 }
632 
633 static void
634 bdw_primary_enable_flip_done(struct intel_plane *plane)
635 {
636 	struct intel_display *display = to_intel_display(plane);
637 	enum pipe pipe = plane->pipe;
638 
639 	spin_lock_irq(&display->irq.lock);
640 	bdw_enable_pipe_irq(display, pipe, GEN8_PIPE_PRIMARY_FLIP_DONE);
641 	spin_unlock_irq(&display->irq.lock);
642 }
643 
644 static void
645 bdw_primary_disable_flip_done(struct intel_plane *plane)
646 {
647 	struct intel_display *display = to_intel_display(plane);
648 	enum pipe pipe = plane->pipe;
649 
650 	spin_lock_irq(&display->irq.lock);
651 	bdw_disable_pipe_irq(display, pipe, GEN8_PIPE_PRIMARY_FLIP_DONE);
652 	spin_unlock_irq(&display->irq.lock);
653 }
654 
655 static void
656 ivb_primary_enable_flip_done(struct intel_plane *plane)
657 {
658 	struct intel_display *display = to_intel_display(plane);
659 
660 	spin_lock_irq(&display->irq.lock);
661 	ilk_enable_display_irq(display, DE_PLANE_FLIP_DONE_IVB(plane->i9xx_plane));
662 	spin_unlock_irq(&display->irq.lock);
663 }
664 
665 static void
666 ivb_primary_disable_flip_done(struct intel_plane *plane)
667 {
668 	struct intel_display *display = to_intel_display(plane);
669 
670 	spin_lock_irq(&display->irq.lock);
671 	ilk_disable_display_irq(display, DE_PLANE_FLIP_DONE_IVB(plane->i9xx_plane));
672 	spin_unlock_irq(&display->irq.lock);
673 }
674 
675 static void
676 ilk_primary_enable_flip_done(struct intel_plane *plane)
677 {
678 	struct intel_display *display = to_intel_display(plane);
679 
680 	spin_lock_irq(&display->irq.lock);
681 	ilk_enable_display_irq(display, DE_PLANE_FLIP_DONE(plane->i9xx_plane));
682 	spin_unlock_irq(&display->irq.lock);
683 }
684 
685 static void
686 ilk_primary_disable_flip_done(struct intel_plane *plane)
687 {
688 	struct intel_display *display = to_intel_display(plane);
689 
690 	spin_lock_irq(&display->irq.lock);
691 	ilk_disable_display_irq(display, DE_PLANE_FLIP_DONE(plane->i9xx_plane));
692 	spin_unlock_irq(&display->irq.lock);
693 }
694 
695 static void
696 vlv_primary_enable_flip_done(struct intel_plane *plane)
697 {
698 	struct intel_display *display = to_intel_display(plane);
699 	enum pipe pipe = plane->pipe;
700 
701 	spin_lock_irq(&display->irq.lock);
702 	i915_enable_pipestat(display, pipe, PLANE_FLIP_DONE_INT_STATUS_VLV);
703 	spin_unlock_irq(&display->irq.lock);
704 }
705 
706 static void
707 vlv_primary_disable_flip_done(struct intel_plane *plane)
708 {
709 	struct intel_display *display = to_intel_display(plane);
710 	enum pipe pipe = plane->pipe;
711 
712 	spin_lock_irq(&display->irq.lock);
713 	i915_disable_pipestat(display, pipe, PLANE_FLIP_DONE_INT_STATUS_VLV);
714 	spin_unlock_irq(&display->irq.lock);
715 }
716 
717 static bool i9xx_plane_can_async_flip(u64 modifier)
718 {
719 	return modifier == I915_FORMAT_MOD_X_TILED;
720 }
721 
722 static bool i9xx_plane_get_hw_state(struct intel_plane *plane,
723 				    enum pipe *pipe)
724 {
725 	struct intel_display *display = to_intel_display(plane);
726 	enum intel_display_power_domain power_domain;
727 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
728 	intel_wakeref_t wakeref;
729 	bool ret;
730 	u32 val;
731 
732 	/*
733 	 * Not 100% correct for planes that can move between pipes,
734 	 * but that's only the case for gen2-4 which don't have any
735 	 * display power wells.
736 	 */
737 	power_domain = POWER_DOMAIN_PIPE(plane->pipe);
738 	wakeref = intel_display_power_get_if_enabled(display, power_domain);
739 	if (!wakeref)
740 		return false;
741 
742 	val = intel_de_read(display, DSPCNTR(display, i9xx_plane));
743 
744 	ret = val & DISP_ENABLE;
745 
746 	if (DISPLAY_VER(display) >= 5)
747 		*pipe = plane->pipe;
748 	else
749 		*pipe = REG_FIELD_GET(DISP_PIPE_SEL_MASK, val);
750 
751 	intel_display_power_put(display, power_domain, wakeref);
752 
753 	return ret;
754 }
755 
756 static unsigned int
757 hsw_primary_max_stride(struct intel_plane *plane,
758 		       u32 pixel_format, u64 modifier,
759 		       unsigned int rotation)
760 {
761 	const struct drm_format_info *info = drm_format_info(pixel_format);
762 	int cpp = info->cpp[0];
763 
764 	/* Limit to 8k pixels to guarantee OFFSET.x doesn't get too big. */
765 	return min(8192 * cpp, 32 * 1024);
766 }
767 
768 static unsigned int
769 ilk_primary_max_stride(struct intel_plane *plane,
770 		       u32 pixel_format, u64 modifier,
771 		       unsigned int rotation)
772 {
773 	const struct drm_format_info *info = drm_format_info(pixel_format);
774 	int cpp = info->cpp[0];
775 
776 	/* Limit to 4k pixels to guarantee TILEOFF.x doesn't get too big. */
777 	if (modifier == I915_FORMAT_MOD_X_TILED)
778 		return min(4096 * cpp, 32 * 1024);
779 	else
780 		return 32 * 1024;
781 }
782 
783 unsigned int
784 i965_plane_max_stride(struct intel_plane *plane,
785 		      u32 pixel_format, u64 modifier,
786 		      unsigned int rotation)
787 {
788 	const struct drm_format_info *info = drm_format_info(pixel_format);
789 	int cpp = info->cpp[0];
790 
791 	/* Limit to 4k pixels to guarantee TILEOFF.x doesn't get too big. */
792 	if (modifier == I915_FORMAT_MOD_X_TILED)
793 		return min(4096 * cpp, 16 * 1024);
794 	else
795 		return 32 * 1024;
796 }
797 
798 static unsigned int
799 i915_plane_max_stride(struct intel_plane *plane,
800 		      u32 pixel_format, u64 modifier,
801 		      unsigned int rotation)
802 {
803 	if (modifier == I915_FORMAT_MOD_X_TILED)
804 		return 8 * 1024;
805 	else
806 		return 16 * 1024;
807 }
808 
809 static unsigned int
810 i8xx_plane_max_stride(struct intel_plane *plane,
811 		      u32 pixel_format, u64 modifier,
812 		      unsigned int rotation)
813 {
814 	if (plane->i9xx_plane == PLANE_C)
815 		return 4 * 1024;
816 	else
817 		return 8 * 1024;
818 }
819 
820 unsigned int vlv_plane_min_alignment(struct intel_plane *plane,
821 				     const struct drm_framebuffer *fb,
822 				     int color_plane)
823 {
824 	struct intel_display *display = to_intel_display(plane);
825 
826 	if (intel_plane_can_async_flip(plane, fb->format->format, fb->modifier))
827 		return 256 * 1024;
828 
829 	/* FIXME undocumented so not sure what's actually needed */
830 	if (intel_scanout_needs_vtd_wa(display))
831 		return 256 * 1024;
832 
833 	switch (fb->modifier) {
834 	case I915_FORMAT_MOD_X_TILED:
835 		return 4 * 1024;
836 	case DRM_FORMAT_MOD_LINEAR:
837 		return 128 * 1024;
838 	default:
839 		MISSING_CASE(fb->modifier);
840 		return 0;
841 	}
842 }
843 
844 static unsigned int g4x_primary_min_alignment(struct intel_plane *plane,
845 					      const struct drm_framebuffer *fb,
846 					      int color_plane)
847 {
848 	struct intel_display *display = to_intel_display(plane);
849 
850 	if (intel_plane_can_async_flip(plane, fb->format->format, fb->modifier))
851 		return 256 * 1024;
852 
853 	if (intel_scanout_needs_vtd_wa(display))
854 		return 256 * 1024;
855 
856 	switch (fb->modifier) {
857 	case I915_FORMAT_MOD_X_TILED:
858 	case DRM_FORMAT_MOD_LINEAR:
859 		return 4 * 1024;
860 	default:
861 		MISSING_CASE(fb->modifier);
862 		return 0;
863 	}
864 }
865 
866 static unsigned int i965_plane_min_alignment(struct intel_plane *plane,
867 					     const struct drm_framebuffer *fb,
868 					     int color_plane)
869 {
870 	switch (fb->modifier) {
871 	case I915_FORMAT_MOD_X_TILED:
872 		return 4 * 1024;
873 	case DRM_FORMAT_MOD_LINEAR:
874 		return 128 * 1024;
875 	default:
876 		MISSING_CASE(fb->modifier);
877 		return 0;
878 	}
879 }
880 
881 static unsigned int i9xx_plane_min_alignment(struct intel_plane *plane,
882 					     const struct drm_framebuffer *fb,
883 					     int color_plane)
884 {
885 	return 0;
886 }
887 
888 static const struct drm_plane_funcs i965_plane_funcs = {
889 	.update_plane = drm_atomic_helper_update_plane,
890 	.disable_plane = drm_atomic_helper_disable_plane,
891 	.destroy = intel_plane_destroy,
892 	.atomic_duplicate_state = intel_plane_duplicate_state,
893 	.atomic_destroy_state = intel_plane_destroy_state,
894 	.format_mod_supported = i965_plane_format_mod_supported,
895 	.format_mod_supported_async = intel_plane_format_mod_supported_async,
896 };
897 
898 static const struct drm_plane_funcs i8xx_plane_funcs = {
899 	.update_plane = drm_atomic_helper_update_plane,
900 	.disable_plane = drm_atomic_helper_disable_plane,
901 	.destroy = intel_plane_destroy,
902 	.atomic_duplicate_state = intel_plane_duplicate_state,
903 	.atomic_destroy_state = intel_plane_destroy_state,
904 	.format_mod_supported = i8xx_plane_format_mod_supported,
905 	.format_mod_supported_async = intel_plane_format_mod_supported_async,
906 };
907 
908 struct intel_plane *
909 intel_primary_plane_create(struct intel_display *display, enum pipe pipe)
910 {
911 	struct intel_plane *plane;
912 	const struct drm_plane_funcs *plane_funcs;
913 	unsigned int supported_rotations;
914 	const u64 *modifiers;
915 	const u32 *formats;
916 	int num_formats;
917 	int ret, zpos;
918 
919 	plane = intel_plane_alloc();
920 	if (IS_ERR(plane))
921 		return plane;
922 
923 	plane->pipe = pipe;
924 	/*
925 	 * On gen2/3 only plane A can do FBC, but the panel fitter and LVDS
926 	 * port is hooked to pipe B. Hence we want plane A feeding pipe B.
927 	 */
928 	if (HAS_FBC(display) && DISPLAY_VER(display) < 4 &&
929 	    INTEL_NUM_PIPES(display) == 2)
930 		plane->i9xx_plane = (enum i9xx_plane_id) !pipe;
931 	else
932 		plane->i9xx_plane = (enum i9xx_plane_id) pipe;
933 	plane->id = PLANE_PRIMARY;
934 	plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id);
935 
936 	intel_fbc_add_plane(i9xx_plane_fbc(display, plane->i9xx_plane), plane);
937 
938 	if (display->platform.valleyview || display->platform.cherryview) {
939 		formats = vlv_primary_formats;
940 		num_formats = ARRAY_SIZE(vlv_primary_formats);
941 	} else if (DISPLAY_VER(display) >= 4) {
942 		/*
943 		 * WaFP16GammaEnabling:ivb
944 		 * "Workaround : When using the 64-bit format, the plane
945 		 *  output on each color channel has one quarter amplitude.
946 		 *  It can be brought up to full amplitude by using pipe
947 		 *  gamma correction or pipe color space conversion to
948 		 *  multiply the plane output by four."
949 		 *
950 		 * There is no dedicated plane gamma for the primary plane,
951 		 * and using the pipe gamma/csc could conflict with other
952 		 * planes, so we choose not to expose fp16 on IVB primary
953 		 * planes. HSW primary planes no longer have this problem.
954 		 */
955 		if (display->platform.ivybridge) {
956 			formats = ivb_primary_formats;
957 			num_formats = ARRAY_SIZE(ivb_primary_formats);
958 		} else {
959 			formats = i965_primary_formats;
960 			num_formats = ARRAY_SIZE(i965_primary_formats);
961 		}
962 	} else {
963 		formats = i8xx_primary_formats;
964 		num_formats = ARRAY_SIZE(i8xx_primary_formats);
965 	}
966 
967 	if (DISPLAY_VER(display) >= 4)
968 		plane_funcs = &i965_plane_funcs;
969 	else
970 		plane_funcs = &i8xx_plane_funcs;
971 
972 	if (display->platform.valleyview || display->platform.cherryview)
973 		plane->min_cdclk = vlv_plane_min_cdclk;
974 	else if (display->platform.broadwell || display->platform.haswell)
975 		plane->min_cdclk = hsw_plane_min_cdclk;
976 	else if (display->platform.ivybridge)
977 		plane->min_cdclk = ivb_plane_min_cdclk;
978 	else
979 		plane->min_cdclk = i9xx_plane_min_cdclk;
980 
981 	if (HAS_GMCH(display)) {
982 		if (DISPLAY_VER(display) >= 4)
983 			plane->max_stride = i965_plane_max_stride;
984 		else if (DISPLAY_VER(display) == 3)
985 			plane->max_stride = i915_plane_max_stride;
986 		else
987 			plane->max_stride = i8xx_plane_max_stride;
988 	} else {
989 		if (display->platform.broadwell || display->platform.haswell)
990 			plane->max_stride = hsw_primary_max_stride;
991 		else
992 			plane->max_stride = ilk_primary_max_stride;
993 	}
994 
995 	if (display->platform.valleyview || display->platform.cherryview)
996 		plane->min_alignment = vlv_plane_min_alignment;
997 	else if (DISPLAY_VER(display) >= 5 || display->platform.g4x)
998 		plane->min_alignment = g4x_primary_min_alignment;
999 	else if (DISPLAY_VER(display) == 4)
1000 		plane->min_alignment = i965_plane_min_alignment;
1001 	else
1002 		plane->min_alignment = i9xx_plane_min_alignment;
1003 
1004 	/* FIXME undocumented for VLV/CHV so not sure what's actually needed */
1005 	if (intel_scanout_needs_vtd_wa(display))
1006 		plane->vtd_guard = 128;
1007 
1008 	if (display->platform.i830 || display->platform.i845g) {
1009 		plane->update_arm = i830_plane_update_arm;
1010 	} else {
1011 		plane->update_noarm = i9xx_plane_update_noarm;
1012 		plane->update_arm = i9xx_plane_update_arm;
1013 	}
1014 	plane->disable_arm = i9xx_plane_disable_arm;
1015 	plane->get_hw_state = i9xx_plane_get_hw_state;
1016 	plane->check_plane = i9xx_plane_check;
1017 
1018 	if (DISPLAY_VER(display) >= 5 || display->platform.g4x)
1019 		plane->capture_error = g4x_primary_capture_error;
1020 	else if (DISPLAY_VER(display) >= 4)
1021 		plane->capture_error = i965_plane_capture_error;
1022 	else
1023 		plane->capture_error = i8xx_plane_capture_error;
1024 
1025 	if (HAS_ASYNC_FLIPS(display)) {
1026 		if (display->platform.valleyview || display->platform.cherryview) {
1027 			plane->async_flip = vlv_primary_async_flip;
1028 			plane->enable_flip_done = vlv_primary_enable_flip_done;
1029 			plane->disable_flip_done = vlv_primary_disable_flip_done;
1030 			plane->can_async_flip = i9xx_plane_can_async_flip;
1031 		} else if (display->platform.broadwell) {
1032 			plane->need_async_flip_toggle_wa = true;
1033 			plane->async_flip = g4x_primary_async_flip;
1034 			plane->enable_flip_done = bdw_primary_enable_flip_done;
1035 			plane->disable_flip_done = bdw_primary_disable_flip_done;
1036 			plane->can_async_flip = i9xx_plane_can_async_flip;
1037 		} else if (DISPLAY_VER(display) >= 7) {
1038 			plane->async_flip = g4x_primary_async_flip;
1039 			plane->enable_flip_done = ivb_primary_enable_flip_done;
1040 			plane->disable_flip_done = ivb_primary_disable_flip_done;
1041 			plane->can_async_flip = i9xx_plane_can_async_flip;
1042 		} else if (DISPLAY_VER(display) >= 5) {
1043 			plane->async_flip = g4x_primary_async_flip;
1044 			plane->enable_flip_done = ilk_primary_enable_flip_done;
1045 			plane->disable_flip_done = ilk_primary_disable_flip_done;
1046 			plane->can_async_flip = i9xx_plane_can_async_flip;
1047 		}
1048 	}
1049 
1050 	modifiers = intel_fb_plane_get_modifiers(display, INTEL_PLANE_CAP_TILING_X);
1051 
1052 	if (DISPLAY_VER(display) >= 5 || display->platform.g4x)
1053 		ret = drm_universal_plane_init(display->drm, &plane->base,
1054 					       0, plane_funcs,
1055 					       formats, num_formats,
1056 					       modifiers,
1057 					       DRM_PLANE_TYPE_PRIMARY,
1058 					       "primary %c", pipe_name(pipe));
1059 	else
1060 		ret = drm_universal_plane_init(display->drm, &plane->base,
1061 					       0, plane_funcs,
1062 					       formats, num_formats,
1063 					       modifiers,
1064 					       DRM_PLANE_TYPE_PRIMARY,
1065 					       "plane %c",
1066 					       plane_name(plane->i9xx_plane));
1067 
1068 	kfree(modifiers);
1069 
1070 	if (ret)
1071 		goto fail;
1072 
1073 	if (display->platform.cherryview && pipe == PIPE_B) {
1074 		supported_rotations =
1075 			DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
1076 			DRM_MODE_REFLECT_X;
1077 	} else if (DISPLAY_VER(display) >= 4) {
1078 		supported_rotations =
1079 			DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
1080 	} else {
1081 		supported_rotations = DRM_MODE_ROTATE_0;
1082 	}
1083 
1084 	if (DISPLAY_VER(display) >= 4)
1085 		drm_plane_create_rotation_property(&plane->base,
1086 						   DRM_MODE_ROTATE_0,
1087 						   supported_rotations);
1088 
1089 	zpos = 0;
1090 	drm_plane_create_zpos_immutable_property(&plane->base, zpos);
1091 
1092 	intel_plane_helper_add(plane);
1093 
1094 	return plane;
1095 
1096 fail:
1097 	intel_plane_free(plane);
1098 
1099 	return ERR_PTR(ret);
1100 }
1101 
1102 static int i9xx_format_to_fourcc(int format)
1103 {
1104 	switch (format) {
1105 	case DISP_FORMAT_8BPP:
1106 		return DRM_FORMAT_C8;
1107 	case DISP_FORMAT_BGRA555:
1108 		return DRM_FORMAT_ARGB1555;
1109 	case DISP_FORMAT_BGRX555:
1110 		return DRM_FORMAT_XRGB1555;
1111 	case DISP_FORMAT_BGRX565:
1112 		return DRM_FORMAT_RGB565;
1113 	default:
1114 	case DISP_FORMAT_BGRX888:
1115 		return DRM_FORMAT_XRGB8888;
1116 	case DISP_FORMAT_RGBX888:
1117 		return DRM_FORMAT_XBGR8888;
1118 	case DISP_FORMAT_BGRA888:
1119 		return DRM_FORMAT_ARGB8888;
1120 	case DISP_FORMAT_RGBA888:
1121 		return DRM_FORMAT_ABGR8888;
1122 	case DISP_FORMAT_BGRX101010:
1123 		return DRM_FORMAT_XRGB2101010;
1124 	case DISP_FORMAT_RGBX101010:
1125 		return DRM_FORMAT_XBGR2101010;
1126 	case DISP_FORMAT_BGRA101010:
1127 		return DRM_FORMAT_ARGB2101010;
1128 	case DISP_FORMAT_RGBA101010:
1129 		return DRM_FORMAT_ABGR2101010;
1130 	case DISP_FORMAT_RGBX161616:
1131 		return DRM_FORMAT_XBGR16161616F;
1132 	}
1133 }
1134 
1135 void
1136 i9xx_get_initial_plane_config(struct intel_crtc *crtc,
1137 			      struct intel_initial_plane_config *plane_config)
1138 {
1139 	struct intel_display *display = to_intel_display(crtc);
1140 	struct intel_plane *plane = to_intel_plane(crtc->base.primary);
1141 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
1142 	enum pipe pipe;
1143 	u32 val, base, offset;
1144 	int fourcc, pixel_format;
1145 	unsigned int aligned_height;
1146 	struct drm_framebuffer *fb;
1147 	struct intel_framebuffer *intel_fb;
1148 
1149 	if (!plane->get_hw_state(plane, &pipe))
1150 		return;
1151 
1152 	drm_WARN_ON(display->drm, pipe != crtc->pipe);
1153 
1154 	intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
1155 	if (!intel_fb) {
1156 		drm_dbg_kms(display->drm, "failed to alloc fb\n");
1157 		return;
1158 	}
1159 
1160 	fb = &intel_fb->base;
1161 
1162 	fb->dev = display->drm;
1163 
1164 	val = intel_de_read(display, DSPCNTR(display, i9xx_plane));
1165 
1166 	if (DISPLAY_VER(display) >= 4) {
1167 		if (val & DISP_TILED) {
1168 			plane_config->tiling = I915_TILING_X;
1169 			fb->modifier = I915_FORMAT_MOD_X_TILED;
1170 		}
1171 
1172 		if (val & DISP_ROTATE_180)
1173 			plane_config->rotation = DRM_MODE_ROTATE_180;
1174 	}
1175 
1176 	if (display->platform.cherryview &&
1177 	    pipe == PIPE_B && val & DISP_MIRROR)
1178 		plane_config->rotation |= DRM_MODE_REFLECT_X;
1179 
1180 	pixel_format = val & DISP_FORMAT_MASK;
1181 	fourcc = i9xx_format_to_fourcc(pixel_format);
1182 	fb->format = drm_format_info(fourcc);
1183 
1184 	if (display->platform.haswell || display->platform.broadwell) {
1185 		offset = intel_de_read(display,
1186 				       DSPOFFSET(display, i9xx_plane));
1187 		base = intel_de_read(display, DSPSURF(display, i9xx_plane)) & DISP_ADDR_MASK;
1188 	} else if (DISPLAY_VER(display) >= 4) {
1189 		if (plane_config->tiling)
1190 			offset = intel_de_read(display,
1191 					       DSPTILEOFF(display, i9xx_plane));
1192 		else
1193 			offset = intel_de_read(display,
1194 					       DSPLINOFF(display, i9xx_plane));
1195 		base = intel_de_read(display, DSPSURF(display, i9xx_plane)) & DISP_ADDR_MASK;
1196 	} else {
1197 		offset = 0;
1198 		base = intel_de_read(display, DSPADDR(display, i9xx_plane));
1199 	}
1200 	plane_config->base = base;
1201 
1202 	drm_WARN_ON(display->drm, offset != 0);
1203 
1204 	val = intel_de_read(display, PIPESRC(display, pipe));
1205 	fb->width = REG_FIELD_GET(PIPESRC_WIDTH_MASK, val) + 1;
1206 	fb->height = REG_FIELD_GET(PIPESRC_HEIGHT_MASK, val) + 1;
1207 
1208 	val = intel_de_read(display, DSPSTRIDE(display, i9xx_plane));
1209 	fb->pitches[0] = val & 0xffffffc0;
1210 
1211 	aligned_height = intel_fb_align_height(fb, 0, fb->height);
1212 
1213 	plane_config->size = fb->pitches[0] * aligned_height;
1214 
1215 	drm_dbg_kms(display->drm,
1216 		    "[CRTC:%d:%s][PLANE:%d:%s] with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
1217 		    crtc->base.base.id, crtc->base.name,
1218 		    plane->base.base.id, plane->base.name,
1219 		    fb->width, fb->height, fb->format->cpp[0] * 8,
1220 		    base, fb->pitches[0], plane_config->size);
1221 
1222 	plane_config->fb = intel_fb;
1223 }
1224 
1225 bool i9xx_fixup_initial_plane_config(struct intel_crtc *crtc,
1226 				     const struct intel_initial_plane_config *plane_config)
1227 {
1228 	struct intel_display *display = to_intel_display(crtc);
1229 	struct intel_plane *plane = to_intel_plane(crtc->base.primary);
1230 	const struct intel_plane_state *plane_state =
1231 		to_intel_plane_state(plane->base.state);
1232 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
1233 	u32 base;
1234 
1235 	if (!plane_state->uapi.visible)
1236 		return false;
1237 
1238 	base = intel_plane_ggtt_offset(plane_state);
1239 
1240 	/*
1241 	 * We may have moved the surface to a different
1242 	 * part of ggtt, make the plane aware of that.
1243 	 */
1244 	if (plane_config->base == base)
1245 		return false;
1246 
1247 	if (DISPLAY_VER(display) >= 4)
1248 		intel_de_write(display, DSPSURF(display, i9xx_plane), base);
1249 	else
1250 		intel_de_write(display, DSPADDR(display, i9xx_plane), base);
1251 
1252 	return true;
1253 }
1254