• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_fourcc.h>
9 #include <drm/drm_plane_helper.h>
10 
11 #include "intel_atomic.h"
12 #include "intel_atomic_plane.h"
13 #include "intel_de.h"
14 #include "intel_display_types.h"
15 #include "intel_fb.h"
16 #include "intel_sprite.h"
17 #include "i9xx_plane.h"
18 
19 /* Primary plane formats for gen <= 3 */
20 static const u32 i8xx_primary_formats[] = {
21 	DRM_FORMAT_C8,
22 	DRM_FORMAT_XRGB1555,
23 	DRM_FORMAT_RGB565,
24 	DRM_FORMAT_XRGB8888,
25 };
26 
27 /* Primary plane formats for ivb (no fp16 due to hw issue) */
28 static const u32 ivb_primary_formats[] = {
29 	DRM_FORMAT_C8,
30 	DRM_FORMAT_RGB565,
31 	DRM_FORMAT_XRGB8888,
32 	DRM_FORMAT_XBGR8888,
33 	DRM_FORMAT_XRGB2101010,
34 	DRM_FORMAT_XBGR2101010,
35 };
36 
37 /* Primary plane formats for gen >= 4, except ivb */
38 static const u32 i965_primary_formats[] = {
39 	DRM_FORMAT_C8,
40 	DRM_FORMAT_RGB565,
41 	DRM_FORMAT_XRGB8888,
42 	DRM_FORMAT_XBGR8888,
43 	DRM_FORMAT_XRGB2101010,
44 	DRM_FORMAT_XBGR2101010,
45 	DRM_FORMAT_XBGR16161616F,
46 };
47 
48 /* Primary plane formats for vlv/chv */
49 static const u32 vlv_primary_formats[] = {
50 	DRM_FORMAT_C8,
51 	DRM_FORMAT_RGB565,
52 	DRM_FORMAT_XRGB8888,
53 	DRM_FORMAT_XBGR8888,
54 	DRM_FORMAT_ARGB8888,
55 	DRM_FORMAT_ABGR8888,
56 	DRM_FORMAT_XRGB2101010,
57 	DRM_FORMAT_XBGR2101010,
58 	DRM_FORMAT_ARGB2101010,
59 	DRM_FORMAT_ABGR2101010,
60 	DRM_FORMAT_XBGR16161616F,
61 };
62 
63 static const u64 i9xx_format_modifiers[] = {
64 	I915_FORMAT_MOD_X_TILED,
65 	DRM_FORMAT_MOD_LINEAR,
66 	DRM_FORMAT_MOD_INVALID
67 };
68 
i8xx_plane_format_mod_supported(struct drm_plane * _plane,u32 format,u64 modifier)69 static bool i8xx_plane_format_mod_supported(struct drm_plane *_plane,
70 					    u32 format, u64 modifier)
71 {
72 	switch (modifier) {
73 	case DRM_FORMAT_MOD_LINEAR:
74 	case I915_FORMAT_MOD_X_TILED:
75 		break;
76 	default:
77 		return false;
78 	}
79 
80 	switch (format) {
81 	case DRM_FORMAT_C8:
82 	case DRM_FORMAT_RGB565:
83 	case DRM_FORMAT_XRGB1555:
84 	case DRM_FORMAT_XRGB8888:
85 		return modifier == DRM_FORMAT_MOD_LINEAR ||
86 			modifier == I915_FORMAT_MOD_X_TILED;
87 	default:
88 		return false;
89 	}
90 }
91 
i965_plane_format_mod_supported(struct drm_plane * _plane,u32 format,u64 modifier)92 static bool i965_plane_format_mod_supported(struct drm_plane *_plane,
93 					    u32 format, u64 modifier)
94 {
95 	switch (modifier) {
96 	case DRM_FORMAT_MOD_LINEAR:
97 	case I915_FORMAT_MOD_X_TILED:
98 		break;
99 	default:
100 		return false;
101 	}
102 
103 	switch (format) {
104 	case DRM_FORMAT_C8:
105 	case DRM_FORMAT_RGB565:
106 	case DRM_FORMAT_XRGB8888:
107 	case DRM_FORMAT_XBGR8888:
108 	case DRM_FORMAT_ARGB8888:
109 	case DRM_FORMAT_ABGR8888:
110 	case DRM_FORMAT_XRGB2101010:
111 	case DRM_FORMAT_XBGR2101010:
112 	case DRM_FORMAT_ARGB2101010:
113 	case DRM_FORMAT_ABGR2101010:
114 	case DRM_FORMAT_XBGR16161616F:
115 		return modifier == DRM_FORMAT_MOD_LINEAR ||
116 			modifier == I915_FORMAT_MOD_X_TILED;
117 	default:
118 		return false;
119 	}
120 }
121 
i9xx_plane_has_fbc(struct drm_i915_private * dev_priv,enum i9xx_plane_id i9xx_plane)122 static bool i9xx_plane_has_fbc(struct drm_i915_private *dev_priv,
123 			       enum i9xx_plane_id i9xx_plane)
124 {
125 	if (!HAS_FBC(dev_priv))
126 		return false;
127 
128 	if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
129 		return i9xx_plane == PLANE_A; /* tied to pipe A */
130 	else if (IS_IVYBRIDGE(dev_priv))
131 		return i9xx_plane == PLANE_A || i9xx_plane == PLANE_B ||
132 			i9xx_plane == PLANE_C;
133 	else if (DISPLAY_VER(dev_priv) >= 4)
134 		return i9xx_plane == PLANE_A || i9xx_plane == PLANE_B;
135 	else
136 		return i9xx_plane == PLANE_A;
137 }
138 
i9xx_plane_has_windowing(struct intel_plane * plane)139 static bool i9xx_plane_has_windowing(struct intel_plane *plane)
140 {
141 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
142 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
143 
144 	if (IS_CHERRYVIEW(dev_priv))
145 		return i9xx_plane == PLANE_B;
146 	else if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv))
147 		return false;
148 	else if (DISPLAY_VER(dev_priv) == 4)
149 		return i9xx_plane == PLANE_C;
150 	else
151 		return i9xx_plane == PLANE_B ||
152 			i9xx_plane == PLANE_C;
153 }
154 
i9xx_plane_ctl(const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)155 static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state,
156 			  const struct intel_plane_state *plane_state)
157 {
158 	struct drm_i915_private *dev_priv =
159 		to_i915(plane_state->uapi.plane->dev);
160 	const struct drm_framebuffer *fb = plane_state->hw.fb;
161 	unsigned int rotation = plane_state->hw.rotation;
162 	u32 dspcntr;
163 
164 	dspcntr = DISPLAY_PLANE_ENABLE;
165 
166 	if (IS_G4X(dev_priv) || IS_IRONLAKE(dev_priv) ||
167 	    IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv))
168 		dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
169 
170 	switch (fb->format->format) {
171 	case DRM_FORMAT_C8:
172 		dspcntr |= DISPPLANE_8BPP;
173 		break;
174 	case DRM_FORMAT_XRGB1555:
175 		dspcntr |= DISPPLANE_BGRX555;
176 		break;
177 	case DRM_FORMAT_ARGB1555:
178 		dspcntr |= DISPPLANE_BGRA555;
179 		break;
180 	case DRM_FORMAT_RGB565:
181 		dspcntr |= DISPPLANE_BGRX565;
182 		break;
183 	case DRM_FORMAT_XRGB8888:
184 		dspcntr |= DISPPLANE_BGRX888;
185 		break;
186 	case DRM_FORMAT_XBGR8888:
187 		dspcntr |= DISPPLANE_RGBX888;
188 		break;
189 	case DRM_FORMAT_ARGB8888:
190 		dspcntr |= DISPPLANE_BGRA888;
191 		break;
192 	case DRM_FORMAT_ABGR8888:
193 		dspcntr |= DISPPLANE_RGBA888;
194 		break;
195 	case DRM_FORMAT_XRGB2101010:
196 		dspcntr |= DISPPLANE_BGRX101010;
197 		break;
198 	case DRM_FORMAT_XBGR2101010:
199 		dspcntr |= DISPPLANE_RGBX101010;
200 		break;
201 	case DRM_FORMAT_ARGB2101010:
202 		dspcntr |= DISPPLANE_BGRA101010;
203 		break;
204 	case DRM_FORMAT_ABGR2101010:
205 		dspcntr |= DISPPLANE_RGBA101010;
206 		break;
207 	case DRM_FORMAT_XBGR16161616F:
208 		dspcntr |= DISPPLANE_RGBX161616;
209 		break;
210 	default:
211 		MISSING_CASE(fb->format->format);
212 		return 0;
213 	}
214 
215 	if (DISPLAY_VER(dev_priv) >= 4 &&
216 	    fb->modifier == I915_FORMAT_MOD_X_TILED)
217 		dspcntr |= DISPPLANE_TILED;
218 
219 	if (rotation & DRM_MODE_ROTATE_180)
220 		dspcntr |= DISPPLANE_ROTATE_180;
221 
222 	if (rotation & DRM_MODE_REFLECT_X)
223 		dspcntr |= DISPPLANE_MIRROR;
224 
225 	return dspcntr;
226 }
227 
i9xx_check_plane_surface(struct intel_plane_state * plane_state)228 int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
229 {
230 	struct drm_i915_private *dev_priv =
231 		to_i915(plane_state->uapi.plane->dev);
232 	const struct drm_framebuffer *fb = plane_state->hw.fb;
233 	int src_x, src_y, src_w;
234 	u32 offset;
235 	int ret;
236 
237 	ret = intel_plane_compute_gtt(plane_state);
238 	if (ret)
239 		return ret;
240 
241 	if (!plane_state->uapi.visible)
242 		return 0;
243 
244 	src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
245 	src_x = plane_state->uapi.src.x1 >> 16;
246 	src_y = plane_state->uapi.src.y1 >> 16;
247 
248 	/* Undocumented hardware limit on i965/g4x/vlv/chv */
249 	if (HAS_GMCH(dev_priv) && fb->format->cpp[0] == 8 && src_w > 2048)
250 		return -EINVAL;
251 
252 	intel_add_fb_offsets(&src_x, &src_y, plane_state, 0);
253 
254 	if (DISPLAY_VER(dev_priv) >= 4)
255 		offset = intel_plane_compute_aligned_offset(&src_x, &src_y,
256 							    plane_state, 0);
257 	else
258 		offset = 0;
259 
260 	/*
261 	 * When using an X-tiled surface the plane starts to
262 	 * misbehave if the x offset + width exceeds the stride.
263 	 * hsw/bdw: underrun galore
264 	 * ilk/snb/ivb: wrap to the next tile row mid scanout
265 	 * i965/g4x: so far appear immune to this
266 	 * vlv/chv: TODO check
267 	 *
268 	 * Linear surfaces seem to work just fine, even on hsw/bdw
269 	 * despite them not using the linear offset anymore.
270 	 */
271 	if (DISPLAY_VER(dev_priv) >= 4 && fb->modifier == I915_FORMAT_MOD_X_TILED) {
272 		u32 alignment = intel_surf_alignment(fb, 0);
273 		int cpp = fb->format->cpp[0];
274 
275 		while ((src_x + src_w) * cpp > plane_state->view.color_plane[0].stride) {
276 			if (offset == 0) {
277 				drm_dbg_kms(&dev_priv->drm,
278 					    "Unable to find suitable display surface offset due to X-tiling\n");
279 				return -EINVAL;
280 			}
281 
282 			offset = intel_plane_adjust_aligned_offset(&src_x, &src_y, plane_state, 0,
283 								   offset, offset - alignment);
284 		}
285 	}
286 
287 	/*
288 	 * Put the final coordinates back so that the src
289 	 * coordinate checks will see the right values.
290 	 */
291 	drm_rect_translate_to(&plane_state->uapi.src,
292 			      src_x << 16, src_y << 16);
293 
294 	/* HSW/BDW do this automagically in hardware */
295 	if (!IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv)) {
296 		unsigned int rotation = plane_state->hw.rotation;
297 		int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
298 		int src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
299 
300 		if (rotation & DRM_MODE_ROTATE_180) {
301 			src_x += src_w - 1;
302 			src_y += src_h - 1;
303 		} else if (rotation & DRM_MODE_REFLECT_X) {
304 			src_x += src_w - 1;
305 		}
306 	}
307 
308 	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
309 		drm_WARN_ON(&dev_priv->drm, src_x > 8191 || src_y > 4095);
310 	} else if (DISPLAY_VER(dev_priv) >= 4 &&
311 		   fb->modifier == I915_FORMAT_MOD_X_TILED) {
312 		drm_WARN_ON(&dev_priv->drm, src_x > 4095 || src_y > 4095);
313 	}
314 
315 	plane_state->view.color_plane[0].offset = offset;
316 	plane_state->view.color_plane[0].x = src_x;
317 	plane_state->view.color_plane[0].y = src_y;
318 
319 	return 0;
320 }
321 
322 static int
i9xx_plane_check(struct intel_crtc_state * crtc_state,struct intel_plane_state * plane_state)323 i9xx_plane_check(struct intel_crtc_state *crtc_state,
324 		 struct intel_plane_state *plane_state)
325 {
326 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
327 	int ret;
328 
329 	ret = chv_plane_check_rotation(plane_state);
330 	if (ret)
331 		return ret;
332 
333 	ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
334 						DRM_PLANE_HELPER_NO_SCALING,
335 						DRM_PLANE_HELPER_NO_SCALING,
336 						i9xx_plane_has_windowing(plane));
337 	if (ret)
338 		return ret;
339 
340 	ret = i9xx_check_plane_surface(plane_state);
341 	if (ret)
342 		return ret;
343 
344 	if (!plane_state->uapi.visible)
345 		return 0;
346 
347 	ret = intel_plane_check_src_coordinates(plane_state);
348 	if (ret)
349 		return ret;
350 
351 	plane_state->ctl = i9xx_plane_ctl(crtc_state, plane_state);
352 
353 	return 0;
354 }
355 
i9xx_plane_ctl_crtc(const struct intel_crtc_state * crtc_state)356 static u32 i9xx_plane_ctl_crtc(const struct intel_crtc_state *crtc_state)
357 {
358 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
359 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
360 	u32 dspcntr = 0;
361 
362 	if (crtc_state->gamma_enable)
363 		dspcntr |= DISPPLANE_GAMMA_ENABLE;
364 
365 	if (crtc_state->csc_enable)
366 		dspcntr |= DISPPLANE_PIPE_CSC_ENABLE;
367 
368 	if (DISPLAY_VER(dev_priv) < 5)
369 		dspcntr |= DISPPLANE_SEL_PIPE(crtc->pipe);
370 
371 	return dspcntr;
372 }
373 
i9xx_plane_ratio(const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state,unsigned int * num,unsigned int * den)374 static void i9xx_plane_ratio(const struct intel_crtc_state *crtc_state,
375 			     const struct intel_plane_state *plane_state,
376 			     unsigned int *num, unsigned int *den)
377 {
378 	const struct drm_framebuffer *fb = plane_state->hw.fb;
379 	unsigned int cpp = fb->format->cpp[0];
380 
381 	/*
382 	 * g4x bspec says 64bpp pixel rate can't exceed 80%
383 	 * of cdclk when the sprite plane is enabled on the
384 	 * same pipe. ilk/snb bspec says 64bpp pixel rate is
385 	 * never allowed to exceed 80% of cdclk. Let's just go
386 	 * with the ilk/snb limit always.
387 	 */
388 	if (cpp == 8) {
389 		*num = 10;
390 		*den = 8;
391 	} else {
392 		*num = 1;
393 		*den = 1;
394 	}
395 }
396 
i9xx_plane_min_cdclk(const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)397 static int i9xx_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
398 				const struct intel_plane_state *plane_state)
399 {
400 	unsigned int pixel_rate;
401 	unsigned int num, den;
402 
403 	/*
404 	 * Note that crtc_state->pixel_rate accounts for both
405 	 * horizontal and vertical panel fitter downscaling factors.
406 	 * Pre-HSW bspec tells us to only consider the horizontal
407 	 * downscaling factor here. We ignore that and just consider
408 	 * both for simplicity.
409 	 */
410 	pixel_rate = crtc_state->pixel_rate;
411 
412 	i9xx_plane_ratio(crtc_state, plane_state, &num, &den);
413 
414 	/* two pixels per clock with double wide pipe */
415 	if (crtc_state->double_wide)
416 		den *= 2;
417 
418 	return DIV_ROUND_UP(pixel_rate * num, den);
419 }
420 
i9xx_update_plane(struct intel_plane * plane,const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)421 static void i9xx_update_plane(struct intel_plane *plane,
422 			      const struct intel_crtc_state *crtc_state,
423 			      const struct intel_plane_state *plane_state)
424 {
425 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
426 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
427 	u32 linear_offset;
428 	int x = plane_state->view.color_plane[0].x;
429 	int y = plane_state->view.color_plane[0].y;
430 	int crtc_x = plane_state->uapi.dst.x1;
431 	int crtc_y = plane_state->uapi.dst.y1;
432 	int crtc_w = drm_rect_width(&plane_state->uapi.dst);
433 	int crtc_h = drm_rect_height(&plane_state->uapi.dst);
434 	unsigned long irqflags;
435 	u32 dspaddr_offset;
436 	u32 dspcntr;
437 
438 	dspcntr = plane_state->ctl | i9xx_plane_ctl_crtc(crtc_state);
439 
440 	linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
441 
442 	if (DISPLAY_VER(dev_priv) >= 4)
443 		dspaddr_offset = plane_state->view.color_plane[0].offset;
444 	else
445 		dspaddr_offset = linear_offset;
446 
447 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
448 
449 	intel_de_write_fw(dev_priv, DSPSTRIDE(i9xx_plane),
450 			  plane_state->view.color_plane[0].stride);
451 
452 	if (DISPLAY_VER(dev_priv) < 4) {
453 		/*
454 		 * PLANE_A doesn't actually have a full window
455 		 * generator but let's assume we still need to
456 		 * program whatever is there.
457 		 */
458 		intel_de_write_fw(dev_priv, DSPPOS(i9xx_plane),
459 				  (crtc_y << 16) | crtc_x);
460 		intel_de_write_fw(dev_priv, DSPSIZE(i9xx_plane),
461 				  ((crtc_h - 1) << 16) | (crtc_w - 1));
462 	} else if (IS_CHERRYVIEW(dev_priv) && i9xx_plane == PLANE_B) {
463 		intel_de_write_fw(dev_priv, PRIMPOS(i9xx_plane),
464 				  (crtc_y << 16) | crtc_x);
465 		intel_de_write_fw(dev_priv, PRIMSIZE(i9xx_plane),
466 				  ((crtc_h - 1) << 16) | (crtc_w - 1));
467 		intel_de_write_fw(dev_priv, PRIMCNSTALPHA(i9xx_plane), 0);
468 	}
469 
470 	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
471 		intel_de_write_fw(dev_priv, DSPOFFSET(i9xx_plane),
472 				  (y << 16) | x);
473 	} else if (DISPLAY_VER(dev_priv) >= 4) {
474 		intel_de_write_fw(dev_priv, DSPLINOFF(i9xx_plane),
475 				  linear_offset);
476 		intel_de_write_fw(dev_priv, DSPTILEOFF(i9xx_plane),
477 				  (y << 16) | x);
478 	}
479 
480 	/*
481 	 * The control register self-arms if the plane was previously
482 	 * disabled. Try to make the plane enable atomic by writing
483 	 * the control register just before the surface register.
484 	 */
485 	intel_de_write_fw(dev_priv, DSPCNTR(i9xx_plane), dspcntr);
486 	if (DISPLAY_VER(dev_priv) >= 4)
487 		intel_de_write_fw(dev_priv, DSPSURF(i9xx_plane),
488 				  intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
489 	else
490 		intel_de_write_fw(dev_priv, DSPADDR(i9xx_plane),
491 				  intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
492 
493 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
494 }
495 
i9xx_disable_plane(struct intel_plane * plane,const struct intel_crtc_state * crtc_state)496 static void i9xx_disable_plane(struct intel_plane *plane,
497 			       const struct intel_crtc_state *crtc_state)
498 {
499 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
500 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
501 	unsigned long irqflags;
502 	u32 dspcntr;
503 
504 	/*
505 	 * DSPCNTR pipe gamma enable on g4x+ and pipe csc
506 	 * enable on ilk+ affect the pipe bottom color as
507 	 * well, so we must configure them even if the plane
508 	 * is disabled.
509 	 *
510 	 * On pre-g4x there is no way to gamma correct the
511 	 * pipe bottom color but we'll keep on doing this
512 	 * anyway so that the crtc state readout works correctly.
513 	 */
514 	dspcntr = i9xx_plane_ctl_crtc(crtc_state);
515 
516 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
517 
518 	intel_de_write_fw(dev_priv, DSPCNTR(i9xx_plane), dspcntr);
519 	if (DISPLAY_VER(dev_priv) >= 4)
520 		intel_de_write_fw(dev_priv, DSPSURF(i9xx_plane), 0);
521 	else
522 		intel_de_write_fw(dev_priv, DSPADDR(i9xx_plane), 0);
523 
524 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
525 }
526 
527 static void
g4x_primary_async_flip(struct intel_plane * plane,const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state,bool async_flip)528 g4x_primary_async_flip(struct intel_plane *plane,
529 		       const struct intel_crtc_state *crtc_state,
530 		       const struct intel_plane_state *plane_state,
531 		       bool async_flip)
532 {
533 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
534 	u32 dspcntr = plane_state->ctl | i9xx_plane_ctl_crtc(crtc_state);
535 	u32 dspaddr_offset = plane_state->view.color_plane[0].offset;
536 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
537 	unsigned long irqflags;
538 
539 	if (async_flip)
540 		dspcntr |= DISPPLANE_ASYNC_FLIP;
541 
542 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
543 	intel_de_write_fw(dev_priv, DSPCNTR(i9xx_plane), dspcntr);
544 	intel_de_write_fw(dev_priv, DSPSURF(i9xx_plane),
545 			  intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
546 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
547 }
548 
549 static void
vlv_primary_async_flip(struct intel_plane * plane,const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state,bool async_flip)550 vlv_primary_async_flip(struct intel_plane *plane,
551 		       const struct intel_crtc_state *crtc_state,
552 		       const struct intel_plane_state *plane_state,
553 		       bool async_flip)
554 {
555 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
556 	u32 dspaddr_offset = plane_state->view.color_plane[0].offset;
557 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
558 	unsigned long irqflags;
559 
560 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
561 	intel_de_write_fw(dev_priv, DSPADDR_VLV(i9xx_plane),
562 			  intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
563 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
564 }
565 
566 static void
bdw_primary_enable_flip_done(struct intel_plane * plane)567 bdw_primary_enable_flip_done(struct intel_plane *plane)
568 {
569 	struct drm_i915_private *i915 = to_i915(plane->base.dev);
570 	enum pipe pipe = plane->pipe;
571 
572 	spin_lock_irq(&i915->irq_lock);
573 	bdw_enable_pipe_irq(i915, pipe, GEN8_PIPE_PRIMARY_FLIP_DONE);
574 	spin_unlock_irq(&i915->irq_lock);
575 }
576 
577 static void
bdw_primary_disable_flip_done(struct intel_plane * plane)578 bdw_primary_disable_flip_done(struct intel_plane *plane)
579 {
580 	struct drm_i915_private *i915 = to_i915(plane->base.dev);
581 	enum pipe pipe = plane->pipe;
582 
583 	spin_lock_irq(&i915->irq_lock);
584 	bdw_disable_pipe_irq(i915, pipe, GEN8_PIPE_PRIMARY_FLIP_DONE);
585 	spin_unlock_irq(&i915->irq_lock);
586 }
587 
588 static void
ivb_primary_enable_flip_done(struct intel_plane * plane)589 ivb_primary_enable_flip_done(struct intel_plane *plane)
590 {
591 	struct drm_i915_private *i915 = to_i915(plane->base.dev);
592 
593 	spin_lock_irq(&i915->irq_lock);
594 	ilk_enable_display_irq(i915, DE_PLANE_FLIP_DONE_IVB(plane->i9xx_plane));
595 	spin_unlock_irq(&i915->irq_lock);
596 }
597 
598 static void
ivb_primary_disable_flip_done(struct intel_plane * plane)599 ivb_primary_disable_flip_done(struct intel_plane *plane)
600 {
601 	struct drm_i915_private *i915 = to_i915(plane->base.dev);
602 
603 	spin_lock_irq(&i915->irq_lock);
604 	ilk_disable_display_irq(i915, DE_PLANE_FLIP_DONE_IVB(plane->i9xx_plane));
605 	spin_unlock_irq(&i915->irq_lock);
606 }
607 
608 static void
ilk_primary_enable_flip_done(struct intel_plane * plane)609 ilk_primary_enable_flip_done(struct intel_plane *plane)
610 {
611 	struct drm_i915_private *i915 = to_i915(plane->base.dev);
612 
613 	spin_lock_irq(&i915->irq_lock);
614 	ilk_enable_display_irq(i915, DE_PLANE_FLIP_DONE(plane->i9xx_plane));
615 	spin_unlock_irq(&i915->irq_lock);
616 }
617 
618 static void
ilk_primary_disable_flip_done(struct intel_plane * plane)619 ilk_primary_disable_flip_done(struct intel_plane *plane)
620 {
621 	struct drm_i915_private *i915 = to_i915(plane->base.dev);
622 
623 	spin_lock_irq(&i915->irq_lock);
624 	ilk_disable_display_irq(i915, DE_PLANE_FLIP_DONE(plane->i9xx_plane));
625 	spin_unlock_irq(&i915->irq_lock);
626 }
627 
628 static void
vlv_primary_enable_flip_done(struct intel_plane * plane)629 vlv_primary_enable_flip_done(struct intel_plane *plane)
630 {
631 	struct drm_i915_private *i915 = to_i915(plane->base.dev);
632 	enum pipe pipe = plane->pipe;
633 
634 	spin_lock_irq(&i915->irq_lock);
635 	i915_enable_pipestat(i915, pipe, PLANE_FLIP_DONE_INT_STATUS_VLV);
636 	spin_unlock_irq(&i915->irq_lock);
637 }
638 
639 static void
vlv_primary_disable_flip_done(struct intel_plane * plane)640 vlv_primary_disable_flip_done(struct intel_plane *plane)
641 {
642 	struct drm_i915_private *i915 = to_i915(plane->base.dev);
643 	enum pipe pipe = plane->pipe;
644 
645 	spin_lock_irq(&i915->irq_lock);
646 	i915_disable_pipestat(i915, pipe, PLANE_FLIP_DONE_INT_STATUS_VLV);
647 	spin_unlock_irq(&i915->irq_lock);
648 }
649 
i9xx_plane_get_hw_state(struct intel_plane * plane,enum pipe * pipe)650 static bool i9xx_plane_get_hw_state(struct intel_plane *plane,
651 				    enum pipe *pipe)
652 {
653 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
654 	enum intel_display_power_domain power_domain;
655 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
656 	intel_wakeref_t wakeref;
657 	bool ret;
658 	u32 val;
659 
660 	/*
661 	 * Not 100% correct for planes that can move between pipes,
662 	 * but that's only the case for gen2-4 which don't have any
663 	 * display power wells.
664 	 */
665 	power_domain = POWER_DOMAIN_PIPE(plane->pipe);
666 	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
667 	if (!wakeref)
668 		return false;
669 
670 	val = intel_de_read(dev_priv, DSPCNTR(i9xx_plane));
671 
672 	ret = val & DISPLAY_PLANE_ENABLE;
673 
674 	if (DISPLAY_VER(dev_priv) >= 5)
675 		*pipe = plane->pipe;
676 	else
677 		*pipe = (val & DISPPLANE_SEL_PIPE_MASK) >>
678 			DISPPLANE_SEL_PIPE_SHIFT;
679 
680 	intel_display_power_put(dev_priv, power_domain, wakeref);
681 
682 	return ret;
683 }
684 
685 static unsigned int
hsw_primary_max_stride(struct intel_plane * plane,u32 pixel_format,u64 modifier,unsigned int rotation)686 hsw_primary_max_stride(struct intel_plane *plane,
687 		       u32 pixel_format, u64 modifier,
688 		       unsigned int rotation)
689 {
690 	const struct drm_format_info *info = drm_format_info(pixel_format);
691 	int cpp = info->cpp[0];
692 
693 	/* Limit to 8k pixels to guarantee OFFSET.x doesn't get too big. */
694 	return min(8192 * cpp, 32 * 1024);
695 }
696 
697 static unsigned int
ilk_primary_max_stride(struct intel_plane * plane,u32 pixel_format,u64 modifier,unsigned int rotation)698 ilk_primary_max_stride(struct intel_plane *plane,
699 		       u32 pixel_format, u64 modifier,
700 		       unsigned int rotation)
701 {
702 	const struct drm_format_info *info = drm_format_info(pixel_format);
703 	int cpp = info->cpp[0];
704 
705 	/* Limit to 4k pixels to guarantee TILEOFF.x doesn't get too big. */
706 	if (modifier == I915_FORMAT_MOD_X_TILED)
707 		return min(4096 * cpp, 32 * 1024);
708 	else
709 		return 32 * 1024;
710 }
711 
712 unsigned int
i965_plane_max_stride(struct intel_plane * plane,u32 pixel_format,u64 modifier,unsigned int rotation)713 i965_plane_max_stride(struct intel_plane *plane,
714 		      u32 pixel_format, u64 modifier,
715 		      unsigned int rotation)
716 {
717 	const struct drm_format_info *info = drm_format_info(pixel_format);
718 	int cpp = info->cpp[0];
719 
720 	/* Limit to 4k pixels to guarantee TILEOFF.x doesn't get too big. */
721 	if (modifier == I915_FORMAT_MOD_X_TILED)
722 		return min(4096 * cpp, 16 * 1024);
723 	else
724 		return 32 * 1024;
725 }
726 
727 static unsigned int
i9xx_plane_max_stride(struct intel_plane * plane,u32 pixel_format,u64 modifier,unsigned int rotation)728 i9xx_plane_max_stride(struct intel_plane *plane,
729 		      u32 pixel_format, u64 modifier,
730 		      unsigned int rotation)
731 {
732 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
733 
734 	if (DISPLAY_VER(dev_priv) >= 3) {
735 		if (modifier == I915_FORMAT_MOD_X_TILED)
736 			return 8*1024;
737 		else
738 			return 16*1024;
739 	} else {
740 		if (plane->i9xx_plane == PLANE_C)
741 			return 4*1024;
742 		else
743 			return 8*1024;
744 	}
745 }
746 
747 static const struct drm_plane_funcs i965_plane_funcs = {
748 	.update_plane = drm_atomic_helper_update_plane,
749 	.disable_plane = drm_atomic_helper_disable_plane,
750 	.destroy = intel_plane_destroy,
751 	.atomic_duplicate_state = intel_plane_duplicate_state,
752 	.atomic_destroy_state = intel_plane_destroy_state,
753 	.format_mod_supported = i965_plane_format_mod_supported,
754 };
755 
756 static const struct drm_plane_funcs i8xx_plane_funcs = {
757 	.update_plane = drm_atomic_helper_update_plane,
758 	.disable_plane = drm_atomic_helper_disable_plane,
759 	.destroy = intel_plane_destroy,
760 	.atomic_duplicate_state = intel_plane_duplicate_state,
761 	.atomic_destroy_state = intel_plane_destroy_state,
762 	.format_mod_supported = i8xx_plane_format_mod_supported,
763 };
764 
765 struct intel_plane *
intel_primary_plane_create(struct drm_i915_private * dev_priv,enum pipe pipe)766 intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
767 {
768 	struct intel_plane *plane;
769 	const struct drm_plane_funcs *plane_funcs;
770 	unsigned int supported_rotations;
771 	const u32 *formats;
772 	int num_formats;
773 	int ret, zpos;
774 
775 	plane = intel_plane_alloc();
776 	if (IS_ERR(plane))
777 		return plane;
778 
779 	plane->pipe = pipe;
780 	/*
781 	 * On gen2/3 only plane A can do FBC, but the panel fitter and LVDS
782 	 * port is hooked to pipe B. Hence we want plane A feeding pipe B.
783 	 */
784 	if (HAS_FBC(dev_priv) && DISPLAY_VER(dev_priv) < 4 &&
785 	    INTEL_NUM_PIPES(dev_priv) == 2)
786 		plane->i9xx_plane = (enum i9xx_plane_id) !pipe;
787 	else
788 		plane->i9xx_plane = (enum i9xx_plane_id) pipe;
789 	plane->id = PLANE_PRIMARY;
790 	plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id);
791 
792 	plane->has_fbc = i9xx_plane_has_fbc(dev_priv, plane->i9xx_plane);
793 	if (plane->has_fbc) {
794 		struct intel_fbc *fbc = &dev_priv->fbc;
795 
796 		fbc->possible_framebuffer_bits |= plane->frontbuffer_bit;
797 	}
798 
799 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
800 		formats = vlv_primary_formats;
801 		num_formats = ARRAY_SIZE(vlv_primary_formats);
802 	} else if (DISPLAY_VER(dev_priv) >= 4) {
803 		/*
804 		 * WaFP16GammaEnabling:ivb
805 		 * "Workaround : When using the 64-bit format, the plane
806 		 *  output on each color channel has one quarter amplitude.
807 		 *  It can be brought up to full amplitude by using pipe
808 		 *  gamma correction or pipe color space conversion to
809 		 *  multiply the plane output by four."
810 		 *
811 		 * There is no dedicated plane gamma for the primary plane,
812 		 * and using the pipe gamma/csc could conflict with other
813 		 * planes, so we choose not to expose fp16 on IVB primary
814 		 * planes. HSW primary planes no longer have this problem.
815 		 */
816 		if (IS_IVYBRIDGE(dev_priv)) {
817 			formats = ivb_primary_formats;
818 			num_formats = ARRAY_SIZE(ivb_primary_formats);
819 		} else {
820 			formats = i965_primary_formats;
821 			num_formats = ARRAY_SIZE(i965_primary_formats);
822 		}
823 	} else {
824 		formats = i8xx_primary_formats;
825 		num_formats = ARRAY_SIZE(i8xx_primary_formats);
826 	}
827 
828 	if (DISPLAY_VER(dev_priv) >= 4)
829 		plane_funcs = &i965_plane_funcs;
830 	else
831 		plane_funcs = &i8xx_plane_funcs;
832 
833 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
834 		plane->min_cdclk = vlv_plane_min_cdclk;
835 	else if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
836 		plane->min_cdclk = hsw_plane_min_cdclk;
837 	else if (IS_IVYBRIDGE(dev_priv))
838 		plane->min_cdclk = ivb_plane_min_cdclk;
839 	else
840 		plane->min_cdclk = i9xx_plane_min_cdclk;
841 
842 	if (HAS_GMCH(dev_priv)) {
843 		if (DISPLAY_VER(dev_priv) >= 4)
844 			plane->max_stride = i965_plane_max_stride;
845 		else
846 			plane->max_stride = i9xx_plane_max_stride;
847 	} else {
848 		if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
849 			plane->max_stride = hsw_primary_max_stride;
850 		else
851 			plane->max_stride = ilk_primary_max_stride;
852 	}
853 
854 	plane->update_plane = i9xx_update_plane;
855 	plane->disable_plane = i9xx_disable_plane;
856 	plane->get_hw_state = i9xx_plane_get_hw_state;
857 	plane->check_plane = i9xx_plane_check;
858 
859 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
860 		plane->async_flip = vlv_primary_async_flip;
861 		plane->enable_flip_done = vlv_primary_enable_flip_done;
862 		plane->disable_flip_done = vlv_primary_disable_flip_done;
863 	} else if (IS_BROADWELL(dev_priv)) {
864 		plane->need_async_flip_disable_wa = true;
865 		plane->async_flip = g4x_primary_async_flip;
866 		plane->enable_flip_done = bdw_primary_enable_flip_done;
867 		plane->disable_flip_done = bdw_primary_disable_flip_done;
868 	} else if (DISPLAY_VER(dev_priv) >= 7) {
869 		plane->async_flip = g4x_primary_async_flip;
870 		plane->enable_flip_done = ivb_primary_enable_flip_done;
871 		plane->disable_flip_done = ivb_primary_disable_flip_done;
872 	} else if (DISPLAY_VER(dev_priv) >= 5) {
873 		plane->async_flip = g4x_primary_async_flip;
874 		plane->enable_flip_done = ilk_primary_enable_flip_done;
875 		plane->disable_flip_done = ilk_primary_disable_flip_done;
876 	}
877 
878 	if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv))
879 		ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
880 					       0, plane_funcs,
881 					       formats, num_formats,
882 					       i9xx_format_modifiers,
883 					       DRM_PLANE_TYPE_PRIMARY,
884 					       "primary %c", pipe_name(pipe));
885 	else
886 		ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
887 					       0, plane_funcs,
888 					       formats, num_formats,
889 					       i9xx_format_modifiers,
890 					       DRM_PLANE_TYPE_PRIMARY,
891 					       "plane %c",
892 					       plane_name(plane->i9xx_plane));
893 	if (ret)
894 		goto fail;
895 
896 	if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
897 		supported_rotations =
898 			DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
899 			DRM_MODE_REFLECT_X;
900 	} else if (DISPLAY_VER(dev_priv) >= 4) {
901 		supported_rotations =
902 			DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
903 	} else {
904 		supported_rotations = DRM_MODE_ROTATE_0;
905 	}
906 
907 	if (DISPLAY_VER(dev_priv) >= 4)
908 		drm_plane_create_rotation_property(&plane->base,
909 						   DRM_MODE_ROTATE_0,
910 						   supported_rotations);
911 
912 	zpos = 0;
913 	drm_plane_create_zpos_immutable_property(&plane->base, zpos);
914 
915 	intel_plane_helper_add(plane);
916 
917 	return plane;
918 
919 fail:
920 	intel_plane_free(plane);
921 
922 	return ERR_PTR(ret);
923 }
924 
i9xx_format_to_fourcc(int format)925 static int i9xx_format_to_fourcc(int format)
926 {
927 	switch (format) {
928 	case DISPPLANE_8BPP:
929 		return DRM_FORMAT_C8;
930 	case DISPPLANE_BGRA555:
931 		return DRM_FORMAT_ARGB1555;
932 	case DISPPLANE_BGRX555:
933 		return DRM_FORMAT_XRGB1555;
934 	case DISPPLANE_BGRX565:
935 		return DRM_FORMAT_RGB565;
936 	default:
937 	case DISPPLANE_BGRX888:
938 		return DRM_FORMAT_XRGB8888;
939 	case DISPPLANE_RGBX888:
940 		return DRM_FORMAT_XBGR8888;
941 	case DISPPLANE_BGRA888:
942 		return DRM_FORMAT_ARGB8888;
943 	case DISPPLANE_RGBA888:
944 		return DRM_FORMAT_ABGR8888;
945 	case DISPPLANE_BGRX101010:
946 		return DRM_FORMAT_XRGB2101010;
947 	case DISPPLANE_RGBX101010:
948 		return DRM_FORMAT_XBGR2101010;
949 	case DISPPLANE_BGRA101010:
950 		return DRM_FORMAT_ARGB2101010;
951 	case DISPPLANE_RGBA101010:
952 		return DRM_FORMAT_ABGR2101010;
953 	case DISPPLANE_RGBX161616:
954 		return DRM_FORMAT_XBGR16161616F;
955 	}
956 }
957 
958 void
i9xx_get_initial_plane_config(struct intel_crtc * crtc,struct intel_initial_plane_config * plane_config)959 i9xx_get_initial_plane_config(struct intel_crtc *crtc,
960 			      struct intel_initial_plane_config *plane_config)
961 {
962 	struct drm_device *dev = crtc->base.dev;
963 	struct drm_i915_private *dev_priv = to_i915(dev);
964 	struct intel_plane *plane = to_intel_plane(crtc->base.primary);
965 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
966 	enum pipe pipe;
967 	u32 val, base, offset;
968 	int fourcc, pixel_format;
969 	unsigned int aligned_height;
970 	struct drm_framebuffer *fb;
971 	struct intel_framebuffer *intel_fb;
972 
973 	if (!plane->get_hw_state(plane, &pipe))
974 		return;
975 
976 	drm_WARN_ON(dev, pipe != crtc->pipe);
977 
978 	intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
979 	if (!intel_fb) {
980 		drm_dbg_kms(&dev_priv->drm, "failed to alloc fb\n");
981 		return;
982 	}
983 
984 	fb = &intel_fb->base;
985 
986 	fb->dev = dev;
987 
988 	val = intel_de_read(dev_priv, DSPCNTR(i9xx_plane));
989 
990 	if (DISPLAY_VER(dev_priv) >= 4) {
991 		if (val & DISPPLANE_TILED) {
992 			plane_config->tiling = I915_TILING_X;
993 			fb->modifier = I915_FORMAT_MOD_X_TILED;
994 		}
995 
996 		if (val & DISPPLANE_ROTATE_180)
997 			plane_config->rotation = DRM_MODE_ROTATE_180;
998 	}
999 
1000 	if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B &&
1001 	    val & DISPPLANE_MIRROR)
1002 		plane_config->rotation |= DRM_MODE_REFLECT_X;
1003 
1004 	pixel_format = val & DISPPLANE_PIXFORMAT_MASK;
1005 	fourcc = i9xx_format_to_fourcc(pixel_format);
1006 	fb->format = drm_format_info(fourcc);
1007 
1008 	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
1009 		offset = intel_de_read(dev_priv, DSPOFFSET(i9xx_plane));
1010 		base = intel_de_read(dev_priv, DSPSURF(i9xx_plane)) & 0xfffff000;
1011 	} else if (DISPLAY_VER(dev_priv) >= 4) {
1012 		if (plane_config->tiling)
1013 			offset = intel_de_read(dev_priv,
1014 					       DSPTILEOFF(i9xx_plane));
1015 		else
1016 			offset = intel_de_read(dev_priv,
1017 					       DSPLINOFF(i9xx_plane));
1018 		base = intel_de_read(dev_priv, DSPSURF(i9xx_plane)) & 0xfffff000;
1019 	} else {
1020 		base = intel_de_read(dev_priv, DSPADDR(i9xx_plane));
1021 	}
1022 	plane_config->base = base;
1023 
1024 	val = intel_de_read(dev_priv, PIPESRC(pipe));
1025 	fb->width = ((val >> 16) & 0xfff) + 1;
1026 	fb->height = ((val >> 0) & 0xfff) + 1;
1027 
1028 	val = intel_de_read(dev_priv, DSPSTRIDE(i9xx_plane));
1029 	fb->pitches[0] = val & 0xffffffc0;
1030 
1031 	aligned_height = intel_fb_align_height(fb, 0, fb->height);
1032 
1033 	plane_config->size = fb->pitches[0] * aligned_height;
1034 
1035 	drm_dbg_kms(&dev_priv->drm,
1036 		    "%s/%s with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
1037 		    crtc->base.name, plane->base.name, fb->width, fb->height,
1038 		    fb->format->cpp[0] * 8, base, fb->pitches[0],
1039 		    plane_config->size);
1040 
1041 	plane_config->fb = intel_fb;
1042 }
1043