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_atomic_uapi.h>
   9#include <drm/drm_blend.h>
  10#include <drm/drm_damage_helper.h>
  11#include <drm/drm_fourcc.h>
  12#include <drm/drm_vblank.h>
  13
  14#include "i915_reg.h"
  15#include "intel_atomic.h"
  16#include "intel_atomic_plane.h"
  17#include "intel_cursor.h"
  18#include "intel_cursor_regs.h"
  19#include "intel_de.h"
  20#include "intel_display.h"
  21#include "intel_display_types.h"
  22#include "intel_fb.h"
  23#include "intel_fb_pin.h"
  24#include "intel_frontbuffer.h"
  25#include "intel_psr.h"
  26#include "intel_psr_regs.h"
  27#include "intel_vblank.h"
  28#include "skl_watermark.h"
  29
  30/* Cursor formats */
  31static const u32 intel_cursor_formats[] = {
  32	DRM_FORMAT_ARGB8888,
  33};
  34
  35static u32 intel_cursor_base(const struct intel_plane_state *plane_state)
  36{
  37	struct drm_i915_private *dev_priv =
  38		to_i915(plane_state->uapi.plane->dev);
  39	u32 base;
  40
  41	if (DISPLAY_INFO(dev_priv)->cursor_needs_physical)
  42		base = plane_state->phys_dma_addr;
  43	else
  44		base = intel_plane_ggtt_offset(plane_state);
  45
  46	return base + plane_state->view.color_plane[0].offset;
  47}
  48
  49static u32 intel_cursor_position(const struct intel_crtc_state *crtc_state,
  50				 const struct intel_plane_state *plane_state,
  51				 bool early_tpt)
  52{
  53	int x = plane_state->uapi.dst.x1;
  54	int y = plane_state->uapi.dst.y1;
  55	u32 pos = 0;
  56
  57	/*
  58	 * Formula from Bspec:
  59	 * MAX(-1 * <Cursor vertical size from CUR_CTL base on cursor mode
  60	 * select setting> + 1, CUR_POS Y Position - Update region Y position
  61	 */
  62	if (early_tpt)
  63		y = max(-1 * drm_rect_height(&plane_state->uapi.dst) + 1,
  64			y - crtc_state->psr2_su_area.y1);
  65
  66	if (x < 0) {
  67		pos |= CURSOR_POS_X_SIGN;
  68		x = -x;
  69	}
  70	pos |= CURSOR_POS_X(x);
  71
  72	if (y < 0) {
  73		pos |= CURSOR_POS_Y_SIGN;
  74		y = -y;
  75	}
  76	pos |= CURSOR_POS_Y(y);
  77
  78	return pos;
  79}
  80
  81static bool intel_cursor_size_ok(const struct intel_plane_state *plane_state)
  82{
  83	const struct drm_mode_config *config =
  84		&plane_state->uapi.plane->dev->mode_config;
  85	int width = drm_rect_width(&plane_state->uapi.dst);
  86	int height = drm_rect_height(&plane_state->uapi.dst);
  87
  88	return width > 0 && width <= config->cursor_width &&
  89		height > 0 && height <= config->cursor_height;
  90}
  91
  92static int intel_cursor_check_surface(struct intel_plane_state *plane_state)
  93{
  94	struct drm_i915_private *dev_priv =
  95		to_i915(plane_state->uapi.plane->dev);
  96	unsigned int rotation = plane_state->hw.rotation;
  97	int src_x, src_y;
  98	u32 offset;
  99	int ret;
 100
 101	ret = intel_plane_compute_gtt(plane_state);
 102	if (ret)
 103		return ret;
 104
 105	if (!plane_state->uapi.visible)
 106		return 0;
 107
 108	src_x = plane_state->uapi.src.x1 >> 16;
 109	src_y = plane_state->uapi.src.y1 >> 16;
 110
 111	intel_add_fb_offsets(&src_x, &src_y, plane_state, 0);
 112	offset = intel_plane_compute_aligned_offset(&src_x, &src_y,
 113						    plane_state, 0);
 114
 115	if (src_x != 0 || src_y != 0) {
 116		drm_dbg_kms(&dev_priv->drm,
 117			    "Arbitrary cursor panning not supported\n");
 118		return -EINVAL;
 119	}
 120
 121	/*
 122	 * Put the final coordinates back so that the src
 123	 * coordinate checks will see the right values.
 124	 */
 125	drm_rect_translate_to(&plane_state->uapi.src,
 126			      src_x << 16, src_y << 16);
 127
 128	/* ILK+ do this automagically in hardware */
 129	if (HAS_GMCH(dev_priv) && rotation & DRM_MODE_ROTATE_180) {
 130		const struct drm_framebuffer *fb = plane_state->hw.fb;
 131		int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
 132		int src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
 133
 134		offset += (src_h * src_w - 1) * fb->format->cpp[0];
 135	}
 136
 137	plane_state->view.color_plane[0].offset = offset;
 138	plane_state->view.color_plane[0].x = src_x;
 139	plane_state->view.color_plane[0].y = src_y;
 140
 141	return 0;
 142}
 143
 144static int intel_check_cursor(struct intel_crtc_state *crtc_state,
 145			      struct intel_plane_state *plane_state)
 146{
 147	const struct drm_framebuffer *fb = plane_state->hw.fb;
 148	struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
 149	const struct drm_rect src = plane_state->uapi.src;
 150	const struct drm_rect dst = plane_state->uapi.dst;
 151	int ret;
 152
 153	if (fb && fb->modifier != DRM_FORMAT_MOD_LINEAR) {
 154		drm_dbg_kms(&i915->drm, "cursor cannot be tiled\n");
 155		return -EINVAL;
 156	}
 157
 158	ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
 159						DRM_PLANE_NO_SCALING,
 160						DRM_PLANE_NO_SCALING,
 161						true);
 162	if (ret)
 163		return ret;
 164
 165	/* Use the unclipped src/dst rectangles, which we program to hw */
 166	plane_state->uapi.src = src;
 167	plane_state->uapi.dst = dst;
 168
 169	/* final plane coordinates will be relative to the plane's pipe */
 170	drm_rect_translate(&plane_state->uapi.dst,
 171			   -crtc_state->pipe_src.x1,
 172			   -crtc_state->pipe_src.y1);
 173
 174	ret = intel_cursor_check_surface(plane_state);
 175	if (ret)
 176		return ret;
 177
 178	if (!plane_state->uapi.visible)
 179		return 0;
 180
 181	ret = intel_plane_check_src_coordinates(plane_state);
 182	if (ret)
 183		return ret;
 184
 185	return 0;
 186}
 187
 188static unsigned int
 189i845_cursor_max_stride(struct intel_plane *plane,
 190		       u32 pixel_format, u64 modifier,
 191		       unsigned int rotation)
 192{
 193	return 2048;
 194}
 195
 196static unsigned int i845_cursor_min_alignment(struct intel_plane *plane,
 197					      const struct drm_framebuffer *fb,
 198					      int color_plane)
 199{
 200	return 32;
 201}
 202
 203static u32 i845_cursor_ctl_crtc(const struct intel_crtc_state *crtc_state)
 204{
 205	u32 cntl = 0;
 206
 207	if (crtc_state->gamma_enable)
 208		cntl |= CURSOR_PIPE_GAMMA_ENABLE;
 209
 210	return cntl;
 211}
 212
 213static u32 i845_cursor_ctl(const struct intel_crtc_state *crtc_state,
 214			   const struct intel_plane_state *plane_state)
 215{
 216	return CURSOR_ENABLE |
 217		CURSOR_FORMAT_ARGB |
 218		CURSOR_STRIDE(plane_state->view.color_plane[0].mapping_stride);
 219}
 220
 221static bool i845_cursor_size_ok(const struct intel_plane_state *plane_state)
 222{
 223	int width = drm_rect_width(&plane_state->uapi.dst);
 224
 225	/*
 226	 * 845g/865g are only limited by the width of their cursors,
 227	 * the height is arbitrary up to the precision of the register.
 228	 */
 229	return intel_cursor_size_ok(plane_state) && IS_ALIGNED(width, 64);
 230}
 231
 232static int i845_check_cursor(struct intel_crtc_state *crtc_state,
 233			     struct intel_plane_state *plane_state)
 234{
 235	const struct drm_framebuffer *fb = plane_state->hw.fb;
 236	struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
 237	int ret;
 238
 239	ret = intel_check_cursor(crtc_state, plane_state);
 240	if (ret)
 241		return ret;
 242
 243	/* if we want to turn off the cursor ignore width and height */
 244	if (!fb)
 245		return 0;
 246
 247	/* Check for which cursor types we support */
 248	if (!i845_cursor_size_ok(plane_state)) {
 249		drm_dbg_kms(&i915->drm,
 250			    "Cursor dimension %dx%d not supported\n",
 251			    drm_rect_width(&plane_state->uapi.dst),
 252			    drm_rect_height(&plane_state->uapi.dst));
 253		return -EINVAL;
 254	}
 255
 256	drm_WARN_ON(&i915->drm, plane_state->uapi.visible &&
 257		    plane_state->view.color_plane[0].mapping_stride != fb->pitches[0]);
 258
 259	switch (fb->pitches[0]) {
 260	case 256:
 261	case 512:
 262	case 1024:
 263	case 2048:
 264		break;
 265	default:
 266		 drm_dbg_kms(&i915->drm, "Invalid cursor stride (%u)\n",
 267			     fb->pitches[0]);
 268		return -EINVAL;
 269	}
 270
 271	plane_state->ctl = i845_cursor_ctl(crtc_state, plane_state);
 272
 273	return 0;
 274}
 275
 276/* TODO: split into noarm+arm pair */
 277static void i845_cursor_update_arm(struct intel_dsb *dsb,
 278				   struct intel_plane *plane,
 279				   const struct intel_crtc_state *crtc_state,
 280				   const struct intel_plane_state *plane_state)
 281{
 282	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 283	u32 cntl = 0, base = 0, pos = 0, size = 0;
 284
 285	if (plane_state && plane_state->uapi.visible) {
 286		unsigned int width = drm_rect_width(&plane_state->uapi.dst);
 287		unsigned int height = drm_rect_height(&plane_state->uapi.dst);
 288
 289		cntl = plane_state->ctl |
 290			i845_cursor_ctl_crtc(crtc_state);
 291
 292		size = CURSOR_HEIGHT(height) | CURSOR_WIDTH(width);
 293
 294		base = intel_cursor_base(plane_state);
 295		pos = intel_cursor_position(crtc_state, plane_state, false);
 296	}
 297
 298	/* On these chipsets we can only modify the base/size/stride
 299	 * whilst the cursor is disabled.
 300	 */
 301	if (plane->cursor.base != base ||
 302	    plane->cursor.size != size ||
 303	    plane->cursor.cntl != cntl) {
 304		intel_de_write_fw(dev_priv, CURCNTR(dev_priv, PIPE_A), 0);
 305		intel_de_write_fw(dev_priv, CURBASE(dev_priv, PIPE_A), base);
 306		intel_de_write_fw(dev_priv, CURSIZE(dev_priv, PIPE_A), size);
 307		intel_de_write_fw(dev_priv, CURPOS(dev_priv, PIPE_A), pos);
 308		intel_de_write_fw(dev_priv, CURCNTR(dev_priv, PIPE_A), cntl);
 309
 310		plane->cursor.base = base;
 311		plane->cursor.size = size;
 312		plane->cursor.cntl = cntl;
 313	} else {
 314		intel_de_write_fw(dev_priv, CURPOS(dev_priv, PIPE_A), pos);
 315	}
 316}
 317
 318static void i845_cursor_disable_arm(struct intel_dsb *dsb,
 319				    struct intel_plane *plane,
 320				    const struct intel_crtc_state *crtc_state)
 321{
 322	i845_cursor_update_arm(dsb, plane, crtc_state, NULL);
 323}
 324
 325static bool i845_cursor_get_hw_state(struct intel_plane *plane,
 326				     enum pipe *pipe)
 327{
 328	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 329	enum intel_display_power_domain power_domain;
 330	intel_wakeref_t wakeref;
 331	bool ret;
 332
 333	power_domain = POWER_DOMAIN_PIPE(PIPE_A);
 334	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
 335	if (!wakeref)
 336		return false;
 337
 338	ret = intel_de_read(dev_priv, CURCNTR(dev_priv, PIPE_A)) & CURSOR_ENABLE;
 339
 340	*pipe = PIPE_A;
 341
 342	intel_display_power_put(dev_priv, power_domain, wakeref);
 343
 344	return ret;
 345}
 346
 347static unsigned int
 348i9xx_cursor_max_stride(struct intel_plane *plane,
 349		       u32 pixel_format, u64 modifier,
 350		       unsigned int rotation)
 351{
 352	return plane->base.dev->mode_config.cursor_width * 4;
 353}
 354
 355static unsigned int i830_cursor_min_alignment(struct intel_plane *plane,
 356					      const struct drm_framebuffer *fb,
 357					      int color_plane)
 358{
 359	/* "AlmadorM Errata – Requires 32-bpp cursor data to be 16KB aligned." */
 360	return 16 * 1024; /* physical */
 361}
 362
 363static unsigned int i85x_cursor_min_alignment(struct intel_plane *plane,
 364					      const struct drm_framebuffer *fb,
 365					      int color_plane)
 366{
 367	return 256; /* physical */
 368}
 369
 370static unsigned int i9xx_cursor_min_alignment(struct intel_plane *plane,
 371					      const struct drm_framebuffer *fb,
 372					      int color_plane)
 373{
 374	return 4 * 1024; /* physical for i915/i945 */
 375}
 376
 377static u32 i9xx_cursor_ctl_crtc(const struct intel_crtc_state *crtc_state)
 378{
 379	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 380	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 381	u32 cntl = 0;
 382
 383	if (DISPLAY_VER(dev_priv) >= 11)
 384		return cntl;
 385
 386	if (crtc_state->gamma_enable)
 387		cntl = MCURSOR_PIPE_GAMMA_ENABLE;
 388
 389	if (crtc_state->csc_enable)
 390		cntl |= MCURSOR_PIPE_CSC_ENABLE;
 391
 392	if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv))
 393		cntl |= MCURSOR_PIPE_SEL(crtc->pipe);
 394
 395	return cntl;
 396}
 397
 398static u32 i9xx_cursor_ctl(const struct intel_crtc_state *crtc_state,
 399			   const struct intel_plane_state *plane_state)
 400{
 401	struct drm_i915_private *dev_priv =
 402		to_i915(plane_state->uapi.plane->dev);
 403	u32 cntl = 0;
 404
 405	if (IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv))
 406		cntl |= MCURSOR_TRICKLE_FEED_DISABLE;
 407
 408	switch (drm_rect_width(&plane_state->uapi.dst)) {
 409	case 64:
 410		cntl |= MCURSOR_MODE_64_ARGB_AX;
 411		break;
 412	case 128:
 413		cntl |= MCURSOR_MODE_128_ARGB_AX;
 414		break;
 415	case 256:
 416		cntl |= MCURSOR_MODE_256_ARGB_AX;
 417		break;
 418	default:
 419		MISSING_CASE(drm_rect_width(&plane_state->uapi.dst));
 420		return 0;
 421	}
 422
 423	if (plane_state->hw.rotation & DRM_MODE_ROTATE_180)
 424		cntl |= MCURSOR_ROTATE_180;
 425
 426	/* Wa_22012358565:adl-p */
 427	if (DISPLAY_VER(dev_priv) == 13)
 428		cntl |= MCURSOR_ARB_SLOTS(1);
 429
 430	return cntl;
 431}
 432
 433static bool i9xx_cursor_size_ok(const struct intel_plane_state *plane_state)
 434{
 435	struct drm_i915_private *dev_priv =
 436		to_i915(plane_state->uapi.plane->dev);
 437	int width = drm_rect_width(&plane_state->uapi.dst);
 438	int height = drm_rect_height(&plane_state->uapi.dst);
 439
 440	if (!intel_cursor_size_ok(plane_state))
 441		return false;
 442
 443	/* Cursor width is limited to a few power-of-two sizes */
 444	switch (width) {
 445	case 256:
 446	case 128:
 447	case 64:
 448		break;
 449	default:
 450		return false;
 451	}
 452
 453	/*
 454	 * IVB+ have CUR_FBC_CTL which allows an arbitrary cursor
 455	 * height from 8 lines up to the cursor width, when the
 456	 * cursor is not rotated. Everything else requires square
 457	 * cursors.
 458	 */
 459	if (HAS_CUR_FBC(dev_priv) &&
 460	    plane_state->hw.rotation & DRM_MODE_ROTATE_0) {
 461		if (height < 8 || height > width)
 462			return false;
 463	} else {
 464		if (height != width)
 465			return false;
 466	}
 467
 468	return true;
 469}
 470
 471static int i9xx_check_cursor(struct intel_crtc_state *crtc_state,
 472			     struct intel_plane_state *plane_state)
 473{
 474	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
 475	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 476	const struct drm_framebuffer *fb = plane_state->hw.fb;
 477	enum pipe pipe = plane->pipe;
 478	int ret;
 479
 480	ret = intel_check_cursor(crtc_state, plane_state);
 481	if (ret)
 482		return ret;
 483
 484	/* if we want to turn off the cursor ignore width and height */
 485	if (!fb)
 486		return 0;
 487
 488	/* Check for which cursor types we support */
 489	if (!i9xx_cursor_size_ok(plane_state)) {
 490		drm_dbg(&dev_priv->drm,
 491			"Cursor dimension %dx%d not supported\n",
 492			drm_rect_width(&plane_state->uapi.dst),
 493			drm_rect_height(&plane_state->uapi.dst));
 494		return -EINVAL;
 495	}
 496
 497	drm_WARN_ON(&dev_priv->drm, plane_state->uapi.visible &&
 498		    plane_state->view.color_plane[0].mapping_stride != fb->pitches[0]);
 499
 500	if (fb->pitches[0] !=
 501	    drm_rect_width(&plane_state->uapi.dst) * fb->format->cpp[0]) {
 502		drm_dbg_kms(&dev_priv->drm,
 503			    "Invalid cursor stride (%u) (cursor width %d)\n",
 504			    fb->pitches[0],
 505			    drm_rect_width(&plane_state->uapi.dst));
 506		return -EINVAL;
 507	}
 508
 509	/*
 510	 * There's something wrong with the cursor on CHV pipe C.
 511	 * If it straddles the left edge of the screen then
 512	 * moving it away from the edge or disabling it often
 513	 * results in a pipe underrun, and often that can lead to
 514	 * dead pipe (constant underrun reported, and it scans
 515	 * out just a solid color). To recover from that, the
 516	 * display power well must be turned off and on again.
 517	 * Refuse the put the cursor into that compromised position.
 518	 */
 519	if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_C &&
 520	    plane_state->uapi.visible && plane_state->uapi.dst.x1 < 0) {
 521		drm_dbg_kms(&dev_priv->drm,
 522			    "CHV cursor C not allowed to straddle the left screen edge\n");
 523		return -EINVAL;
 524	}
 525
 526	plane_state->ctl = i9xx_cursor_ctl(crtc_state, plane_state);
 527
 528	return 0;
 529}
 530
 531static void i9xx_cursor_disable_sel_fetch_arm(struct intel_dsb *dsb,
 532					      struct intel_plane *plane,
 533					      const struct intel_crtc_state *crtc_state)
 534{
 535	struct intel_display *display = to_intel_display(plane->base.dev);
 536	enum pipe pipe = plane->pipe;
 537
 538	if (!crtc_state->enable_psr2_sel_fetch)
 539		return;
 540
 541	intel_de_write_dsb(display, dsb, SEL_FETCH_CUR_CTL(pipe), 0);
 542}
 543
 544static void wa_16021440873(struct intel_dsb *dsb,
 545			   struct intel_plane *plane,
 546			   const struct intel_crtc_state *crtc_state,
 547			   const struct intel_plane_state *plane_state)
 548{
 549	struct intel_display *display = to_intel_display(plane->base.dev);
 550	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 551	u32 ctl = plane_state->ctl;
 552	int et_y_position = drm_rect_height(&crtc_state->pipe_src) + 1;
 553	enum pipe pipe = plane->pipe;
 554
 555	ctl &= ~MCURSOR_MODE_MASK;
 556	ctl |= MCURSOR_MODE_64_2B;
 557
 558	intel_de_write_dsb(display, dsb, SEL_FETCH_CUR_CTL(pipe), ctl);
 559
 560	intel_de_write_dsb(display, dsb, CURPOS_ERLY_TPT(dev_priv, pipe),
 561			   CURSOR_POS_Y(et_y_position));
 562}
 563
 564static void i9xx_cursor_update_sel_fetch_arm(struct intel_dsb *dsb,
 565					     struct intel_plane *plane,
 566					     const struct intel_crtc_state *crtc_state,
 567					     const struct intel_plane_state *plane_state)
 568{
 569	struct intel_display *display = to_intel_display(plane->base.dev);
 570	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 571	enum pipe pipe = plane->pipe;
 572
 573	if (!crtc_state->enable_psr2_sel_fetch)
 574		return;
 575
 576	if (drm_rect_height(&plane_state->psr2_sel_fetch_area) > 0) {
 577		if (crtc_state->enable_psr2_su_region_et) {
 578			u32 val = intel_cursor_position(crtc_state, plane_state,
 579				true);
 580
 581			intel_de_write_dsb(display, dsb, CURPOS_ERLY_TPT(dev_priv, pipe), val);
 582		}
 583
 584		intel_de_write_dsb(display, dsb, SEL_FETCH_CUR_CTL(pipe), plane_state->ctl);
 585	} else {
 586		/* Wa_16021440873 */
 587		if (crtc_state->enable_psr2_su_region_et)
 588			wa_16021440873(dsb, plane, crtc_state, plane_state);
 589		else
 590			i9xx_cursor_disable_sel_fetch_arm(dsb, plane, crtc_state);
 591	}
 592}
 593
 594static u32 skl_cursor_ddb_reg_val(const struct skl_ddb_entry *entry)
 595{
 596	if (!entry->end)
 597		return 0;
 598
 599	return CUR_BUF_END(entry->end - 1) |
 600		CUR_BUF_START(entry->start);
 601}
 602
 603static u32 skl_cursor_wm_reg_val(const struct skl_wm_level *level)
 604{
 605	u32 val = 0;
 606
 607	if (level->enable)
 608		val |= CUR_WM_EN;
 609	if (level->ignore_lines)
 610		val |= CUR_WM_IGNORE_LINES;
 611	val |= REG_FIELD_PREP(CUR_WM_BLOCKS_MASK, level->blocks);
 612	val |= REG_FIELD_PREP(CUR_WM_LINES_MASK, level->lines);
 613
 614	return val;
 615}
 616
 617static void skl_write_cursor_wm(struct intel_dsb *dsb,
 618				struct intel_plane *plane,
 619				const struct intel_crtc_state *crtc_state)
 620{
 621	struct intel_display *display = to_intel_display(plane->base.dev);
 622	struct drm_i915_private *i915 = to_i915(plane->base.dev);
 623	enum plane_id plane_id = plane->id;
 624	enum pipe pipe = plane->pipe;
 625	const struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
 626	const struct skl_ddb_entry *ddb =
 627		&crtc_state->wm.skl.plane_ddb[plane_id];
 628	int level;
 629
 630	for (level = 0; level < i915->display.wm.num_levels; level++)
 631		intel_de_write_dsb(display, dsb, CUR_WM(pipe, level),
 632				   skl_cursor_wm_reg_val(skl_plane_wm_level(pipe_wm, plane_id, level)));
 633
 634	intel_de_write_dsb(display, dsb, CUR_WM_TRANS(pipe),
 635			   skl_cursor_wm_reg_val(skl_plane_trans_wm(pipe_wm, plane_id)));
 636
 637	if (HAS_HW_SAGV_WM(i915)) {
 638		const struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
 639
 640		intel_de_write_dsb(display, dsb, CUR_WM_SAGV(pipe),
 641				   skl_cursor_wm_reg_val(&wm->sagv.wm0));
 642		intel_de_write_dsb(display, dsb, CUR_WM_SAGV_TRANS(pipe),
 643				   skl_cursor_wm_reg_val(&wm->sagv.trans_wm));
 644	}
 645
 646	intel_de_write_dsb(display, dsb, CUR_BUF_CFG(pipe),
 647			   skl_cursor_ddb_reg_val(ddb));
 648}
 649
 650/* TODO: split into noarm+arm pair */
 651static void i9xx_cursor_update_arm(struct intel_dsb *dsb,
 652				   struct intel_plane *plane,
 653				   const struct intel_crtc_state *crtc_state,
 654				   const struct intel_plane_state *plane_state)
 655{
 656	struct intel_display *display = to_intel_display(plane->base.dev);
 657	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 658	enum pipe pipe = plane->pipe;
 659	u32 cntl = 0, base = 0, pos = 0, fbc_ctl = 0;
 660
 661	if (plane_state && plane_state->uapi.visible) {
 662		int width = drm_rect_width(&plane_state->uapi.dst);
 663		int height = drm_rect_height(&plane_state->uapi.dst);
 664
 665		cntl = plane_state->ctl |
 666			i9xx_cursor_ctl_crtc(crtc_state);
 667
 668		if (width != height)
 669			fbc_ctl = CUR_FBC_EN | CUR_FBC_HEIGHT(height - 1);
 670
 671		base = intel_cursor_base(plane_state);
 672		pos = intel_cursor_position(crtc_state, plane_state, false);
 673	}
 674
 675	/*
 676	 * On some platforms writing CURCNTR first will also
 677	 * cause CURPOS to be armed by the CURBASE write.
 678	 * Without the CURCNTR write the CURPOS write would
 679	 * arm itself. Thus we always update CURCNTR before
 680	 * CURPOS.
 681	 *
 682	 * On other platforms CURPOS always requires the
 683	 * CURBASE write to arm the update. Additonally
 684	 * a write to any of the cursor register will cancel
 685	 * an already armed cursor update. Thus leaving out
 686	 * the CURBASE write after CURPOS could lead to a
 687	 * cursor that doesn't appear to move, or even change
 688	 * shape. Thus we always write CURBASE.
 689	 *
 690	 * The other registers are armed by the CURBASE write
 691	 * except when the plane is getting enabled at which time
 692	 * the CURCNTR write arms the update.
 693	 */
 694
 695	if (DISPLAY_VER(dev_priv) >= 9)
 696		skl_write_cursor_wm(dsb, plane, crtc_state);
 697
 698	if (plane_state)
 699		i9xx_cursor_update_sel_fetch_arm(dsb, plane, crtc_state, plane_state);
 700	else
 701		i9xx_cursor_disable_sel_fetch_arm(dsb, plane, crtc_state);
 702
 703	if (plane->cursor.base != base ||
 704	    plane->cursor.size != fbc_ctl ||
 705	    plane->cursor.cntl != cntl) {
 706		if (HAS_CUR_FBC(dev_priv))
 707			intel_de_write_dsb(display, dsb, CUR_FBC_CTL(dev_priv, pipe), fbc_ctl);
 708		intel_de_write_dsb(display, dsb, CURCNTR(dev_priv, pipe), cntl);
 709		intel_de_write_dsb(display, dsb, CURPOS(dev_priv, pipe), pos);
 710		intel_de_write_dsb(display, dsb, CURBASE(dev_priv, pipe), base);
 711
 712		plane->cursor.base = base;
 713		plane->cursor.size = fbc_ctl;
 714		plane->cursor.cntl = cntl;
 715	} else {
 716		intel_de_write_dsb(display, dsb, CURPOS(dev_priv, pipe), pos);
 717		intel_de_write_dsb(display, dsb, CURBASE(dev_priv, pipe), base);
 718	}
 719}
 720
 721static void i9xx_cursor_disable_arm(struct intel_dsb *dsb,
 722				    struct intel_plane *plane,
 723				    const struct intel_crtc_state *crtc_state)
 724{
 725	i9xx_cursor_update_arm(dsb, plane, crtc_state, NULL);
 726}
 727
 728static bool i9xx_cursor_get_hw_state(struct intel_plane *plane,
 729				     enum pipe *pipe)
 730{
 731	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 732	enum intel_display_power_domain power_domain;
 733	intel_wakeref_t wakeref;
 734	bool ret;
 735	u32 val;
 736
 737	/*
 738	 * Not 100% correct for planes that can move between pipes,
 739	 * but that's only the case for gen2-3 which don't have any
 740	 * display power wells.
 741	 */
 742	power_domain = POWER_DOMAIN_PIPE(plane->pipe);
 743	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
 744	if (!wakeref)
 745		return false;
 746
 747	val = intel_de_read(dev_priv, CURCNTR(dev_priv, plane->pipe));
 748
 749	ret = val & MCURSOR_MODE_MASK;
 750
 751	if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv))
 752		*pipe = plane->pipe;
 753	else
 754		*pipe = REG_FIELD_GET(MCURSOR_PIPE_SEL_MASK, val);
 755
 756	intel_display_power_put(dev_priv, power_domain, wakeref);
 757
 758	return ret;
 759}
 760
 761static bool intel_cursor_format_mod_supported(struct drm_plane *_plane,
 762					      u32 format, u64 modifier)
 763{
 764	if (!intel_fb_plane_supports_modifier(to_intel_plane(_plane), modifier))
 765		return false;
 766
 767	return format == DRM_FORMAT_ARGB8888;
 768}
 769
 770void intel_cursor_unpin_work(struct kthread_work *base)
 771{
 772	struct drm_vblank_work *work = to_drm_vblank_work(base);
 773	struct intel_plane_state *plane_state =
 774		container_of(work, typeof(*plane_state), unpin_work);
 775	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
 776
 777	intel_plane_unpin_fb(plane_state);
 778	intel_plane_destroy_state(&plane->base, &plane_state->uapi);
 779}
 780
 781static int
 782intel_legacy_cursor_update(struct drm_plane *_plane,
 783			   struct drm_crtc *_crtc,
 784			   struct drm_framebuffer *fb,
 785			   int crtc_x, int crtc_y,
 786			   unsigned int crtc_w, unsigned int crtc_h,
 787			   u32 src_x, u32 src_y,
 788			   u32 src_w, u32 src_h,
 789			   struct drm_modeset_acquire_ctx *ctx)
 790{
 791	struct intel_plane *plane = to_intel_plane(_plane);
 792	struct intel_crtc *crtc = to_intel_crtc(_crtc);
 793	struct drm_i915_private *i915 = to_i915(plane->base.dev);
 794	struct intel_plane_state *old_plane_state =
 795		to_intel_plane_state(plane->base.state);
 796	struct intel_plane_state *new_plane_state;
 797	struct intel_crtc_state *crtc_state =
 798		to_intel_crtc_state(crtc->base.state);
 799	struct intel_crtc_state *new_crtc_state;
 800	struct intel_vblank_evade_ctx evade;
 801	int ret;
 802
 803	/*
 804	 * When crtc is inactive or there is a modeset pending,
 805	 * wait for it to complete in the slowpath.
 806	 * PSR2 selective fetch also requires the slow path as
 807	 * PSR2 plane and transcoder registers can only be updated during
 808	 * vblank.
 809	 *
 810	 * FIXME joiner fastpath would be good
 811	 */
 812	if (!crtc_state->hw.active ||
 813	    intel_crtc_needs_modeset(crtc_state) ||
 814	    intel_crtc_needs_fastset(crtc_state) ||
 815	    crtc_state->joiner_pipes)
 816		goto slow;
 817
 818	/*
 819	 * Don't do an async update if there is an outstanding commit modifying
 820	 * the plane.  This prevents our async update's changes from getting
 821	 * overridden by a previous synchronous update's state.
 822	 */
 823	if (old_plane_state->uapi.commit &&
 824	    !try_wait_for_completion(&old_plane_state->uapi.commit->hw_done))
 825		goto slow;
 826
 827	/*
 828	 * If any parameters change that may affect watermarks,
 829	 * take the slowpath. Only changing fb or position should be
 830	 * in the fastpath.
 831	 */
 832	if (old_plane_state->uapi.crtc != &crtc->base ||
 833	    old_plane_state->uapi.src_w != src_w ||
 834	    old_plane_state->uapi.src_h != src_h ||
 835	    old_plane_state->uapi.crtc_w != crtc_w ||
 836	    old_plane_state->uapi.crtc_h != crtc_h ||
 837	    !old_plane_state->uapi.fb != !fb)
 838		goto slow;
 839
 840	new_plane_state = to_intel_plane_state(intel_plane_duplicate_state(&plane->base));
 841	if (!new_plane_state)
 842		return -ENOMEM;
 843
 844	new_crtc_state = to_intel_crtc_state(intel_crtc_duplicate_state(&crtc->base));
 845	if (!new_crtc_state) {
 846		ret = -ENOMEM;
 847		goto out_free;
 848	}
 849
 850	drm_atomic_set_fb_for_plane(&new_plane_state->uapi, fb);
 851
 852	new_plane_state->uapi.src_x = src_x;
 853	new_plane_state->uapi.src_y = src_y;
 854	new_plane_state->uapi.src_w = src_w;
 855	new_plane_state->uapi.src_h = src_h;
 856	new_plane_state->uapi.crtc_x = crtc_x;
 857	new_plane_state->uapi.crtc_y = crtc_y;
 858	new_plane_state->uapi.crtc_w = crtc_w;
 859	new_plane_state->uapi.crtc_h = crtc_h;
 860
 861	intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state, crtc);
 862
 863	ret = intel_plane_atomic_check_with_state(crtc_state, new_crtc_state,
 864						  old_plane_state, new_plane_state);
 865	if (ret)
 866		goto out_free;
 867
 868	ret = intel_plane_pin_fb(new_plane_state);
 869	if (ret)
 870		goto out_free;
 871
 872	intel_frontbuffer_flush(to_intel_frontbuffer(new_plane_state->hw.fb),
 873				ORIGIN_CURSOR_UPDATE);
 874	intel_frontbuffer_track(to_intel_frontbuffer(old_plane_state->hw.fb),
 875				to_intel_frontbuffer(new_plane_state->hw.fb),
 876				plane->frontbuffer_bit);
 877
 878	/* Swap plane state */
 879	plane->base.state = &new_plane_state->uapi;
 880
 881	/*
 882	 * We cannot swap crtc_state as it may be in use by an atomic commit or
 883	 * page flip that's running simultaneously. If we swap crtc_state and
 884	 * destroy the old state, we will cause a use-after-free there.
 885	 *
 886	 * Only update active_planes, which is needed for our internal
 887	 * bookkeeping. Either value will do the right thing when updating
 888	 * planes atomically. If the cursor was part of the atomic update then
 889	 * we would have taken the slowpath.
 890	 */
 891	crtc_state->active_planes = new_crtc_state->active_planes;
 892
 893	intel_vblank_evade_init(crtc_state, crtc_state, &evade);
 894
 895	intel_psr_lock(crtc_state);
 896
 897	if (!drm_WARN_ON(&i915->drm, drm_crtc_vblank_get(&crtc->base))) {
 898		/*
 899		 * TODO: maybe check if we're still in PSR
 900		 * and skip the vblank evasion entirely?
 901		 */
 902		intel_psr_wait_for_idle_locked(crtc_state);
 903
 904		local_irq_disable();
 905
 906		intel_vblank_evade(&evade);
 907
 908		drm_crtc_vblank_put(&crtc->base);
 909	} else {
 910		local_irq_disable();
 911	}
 912
 913	if (new_plane_state->uapi.visible) {
 914		intel_plane_update_noarm(NULL, plane, crtc_state, new_plane_state);
 915		intel_plane_update_arm(NULL, plane, crtc_state, new_plane_state);
 916	} else {
 917		intel_plane_disable_arm(NULL, plane, crtc_state);
 918	}
 919
 920	local_irq_enable();
 921
 922	intel_psr_unlock(crtc_state);
 923
 924	if (old_plane_state->ggtt_vma != new_plane_state->ggtt_vma) {
 925		drm_vblank_work_init(&old_plane_state->unpin_work, &crtc->base,
 926				     intel_cursor_unpin_work);
 927
 928		drm_vblank_work_schedule(&old_plane_state->unpin_work,
 929					 drm_crtc_accurate_vblank_count(&crtc->base) + 1,
 930					 false);
 931
 932		old_plane_state = NULL;
 933	} else {
 934		intel_plane_unpin_fb(old_plane_state);
 935	}
 936
 937out_free:
 938	if (new_crtc_state)
 939		intel_crtc_destroy_state(&crtc->base, &new_crtc_state->uapi);
 940	if (ret)
 941		intel_plane_destroy_state(&plane->base, &new_plane_state->uapi);
 942	else if (old_plane_state)
 943		intel_plane_destroy_state(&plane->base, &old_plane_state->uapi);
 944	return ret;
 945
 946slow:
 947	return drm_atomic_helper_update_plane(&plane->base, &crtc->base, fb,
 948					      crtc_x, crtc_y, crtc_w, crtc_h,
 949					      src_x, src_y, src_w, src_h, ctx);
 950}
 951
 952static const struct drm_plane_funcs intel_cursor_plane_funcs = {
 953	.update_plane = intel_legacy_cursor_update,
 954	.disable_plane = drm_atomic_helper_disable_plane,
 955	.destroy = intel_plane_destroy,
 956	.atomic_duplicate_state = intel_plane_duplicate_state,
 957	.atomic_destroy_state = intel_plane_destroy_state,
 958	.format_mod_supported = intel_cursor_format_mod_supported,
 959};
 960
 961static void intel_cursor_add_size_hints_property(struct intel_plane *plane)
 962{
 963	struct drm_i915_private *i915 = to_i915(plane->base.dev);
 964	const struct drm_mode_config *config = &i915->drm.mode_config;
 965	struct drm_plane_size_hint hints[4];
 966	int size, max_size, num_hints = 0;
 967
 968	max_size = min(config->cursor_width, config->cursor_height);
 969
 970	/* for simplicity only enumerate the supported square+POT sizes */
 971	for (size = 64; size <= max_size; size *= 2) {
 972		if (drm_WARN_ON(&i915->drm, num_hints >= ARRAY_SIZE(hints)))
 973			break;
 974
 975		hints[num_hints].width = size;
 976		hints[num_hints].height = size;
 977		num_hints++;
 978	}
 979
 980	drm_plane_add_size_hints_property(&plane->base, hints, num_hints);
 981}
 982
 983struct intel_plane *
 984intel_cursor_plane_create(struct drm_i915_private *dev_priv,
 985			  enum pipe pipe)
 986{
 987	struct intel_plane *cursor;
 988	int ret, zpos;
 989	u64 *modifiers;
 990
 991	cursor = intel_plane_alloc();
 992	if (IS_ERR(cursor))
 993		return cursor;
 994
 995	cursor->pipe = pipe;
 996	cursor->i9xx_plane = (enum i9xx_plane_id) pipe;
 997	cursor->id = PLANE_CURSOR;
 998	cursor->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, cursor->id);
 999
1000	if (IS_I845G(dev_priv) || IS_I865G(dev_priv)) {
1001		cursor->max_stride = i845_cursor_max_stride;
1002		cursor->min_alignment = i845_cursor_min_alignment;
1003		cursor->update_arm = i845_cursor_update_arm;
1004		cursor->disable_arm = i845_cursor_disable_arm;
1005		cursor->get_hw_state = i845_cursor_get_hw_state;
1006		cursor->check_plane = i845_check_cursor;
1007	} else {
1008		cursor->max_stride = i9xx_cursor_max_stride;
1009
1010		if (IS_I830(dev_priv))
1011			cursor->min_alignment = i830_cursor_min_alignment;
1012		else if (IS_I85X(dev_priv))
1013			cursor->min_alignment = i85x_cursor_min_alignment;
1014		else
1015			cursor->min_alignment = i9xx_cursor_min_alignment;
1016
1017		cursor->update_arm = i9xx_cursor_update_arm;
1018		cursor->disable_arm = i9xx_cursor_disable_arm;
1019		cursor->get_hw_state = i9xx_cursor_get_hw_state;
1020		cursor->check_plane = i9xx_check_cursor;
1021	}
1022
1023	cursor->cursor.base = ~0;
1024	cursor->cursor.cntl = ~0;
1025
1026	if (IS_I845G(dev_priv) || IS_I865G(dev_priv) || HAS_CUR_FBC(dev_priv))
1027		cursor->cursor.size = ~0;
1028
1029	modifiers = intel_fb_plane_get_modifiers(dev_priv, INTEL_PLANE_CAP_NONE);
1030
1031	ret = drm_universal_plane_init(&dev_priv->drm, &cursor->base,
1032				       0, &intel_cursor_plane_funcs,
1033				       intel_cursor_formats,
1034				       ARRAY_SIZE(intel_cursor_formats),
1035				       modifiers,
1036				       DRM_PLANE_TYPE_CURSOR,
1037				       "cursor %c", pipe_name(pipe));
1038
1039	kfree(modifiers);
1040
1041	if (ret)
1042		goto fail;
1043
1044	if (DISPLAY_VER(dev_priv) >= 4)
1045		drm_plane_create_rotation_property(&cursor->base,
1046						   DRM_MODE_ROTATE_0,
1047						   DRM_MODE_ROTATE_0 |
1048						   DRM_MODE_ROTATE_180);
1049
1050	intel_cursor_add_size_hints_property(cursor);
1051
1052	zpos = DISPLAY_RUNTIME_INFO(dev_priv)->num_sprites[pipe] + 1;
1053	drm_plane_create_zpos_immutable_property(&cursor->base, zpos);
1054
1055	if (DISPLAY_VER(dev_priv) >= 12)
1056		drm_plane_enable_fb_damage_clips(&cursor->base);
1057
1058	intel_plane_helper_add(cursor);
1059
1060	return cursor;
1061
1062fail:
1063	intel_plane_free(cursor);
1064
1065	return ERR_PTR(ret);
1066}