Linux Audio

Check our new training course

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