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