cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

intel_cursor.c (23476B)


      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_damage_helper.h>
     10#include <drm/drm_plane_helper.h>
     11#include <drm/drm_fourcc.h>
     12
     13#include "intel_atomic.h"
     14#include "intel_atomic_plane.h"
     15#include "intel_cursor.h"
     16#include "intel_de.h"
     17#include "intel_display_types.h"
     18#include "intel_display.h"
     19#include "intel_fb.h"
     20#include "intel_fb_pin.h"
     21#include "intel_frontbuffer.h"
     22#include "intel_pm.h"
     23#include "intel_psr.h"
     24#include "intel_sprite.h"
     25
     26/* Cursor formats */
     27static const u32 intel_cursor_formats[] = {
     28	DRM_FORMAT_ARGB8888,
     29};
     30
     31static u32 intel_cursor_base(const struct intel_plane_state *plane_state)
     32{
     33	struct drm_i915_private *dev_priv =
     34		to_i915(plane_state->uapi.plane->dev);
     35	const struct drm_framebuffer *fb = plane_state->hw.fb;
     36	const struct drm_i915_gem_object *obj = intel_fb_obj(fb);
     37	u32 base;
     38
     39	if (INTEL_INFO(dev_priv)->display.cursor_needs_physical)
     40		base = sg_dma_address(obj->mm.pages->sgl);
     41	else
     42		base = intel_plane_ggtt_offset(plane_state);
     43
     44	return base + plane_state->view.color_plane[0].offset;
     45}
     46
     47static u32 intel_cursor_position(const struct intel_plane_state *plane_state)
     48{
     49	int x = plane_state->uapi.dst.x1;
     50	int y = plane_state->uapi.dst.y1;
     51	u32 pos = 0;
     52
     53	if (x < 0) {
     54		pos |= CURSOR_POS_X_SIGN;
     55		x = -x;
     56	}
     57	pos |= CURSOR_POS_X(x);
     58
     59	if (y < 0) {
     60		pos |= CURSOR_POS_Y_SIGN;
     61		y = -y;
     62	}
     63	pos |= CURSOR_POS_Y(y);
     64
     65	return pos;
     66}
     67
     68static bool intel_cursor_size_ok(const struct intel_plane_state *plane_state)
     69{
     70	const struct drm_mode_config *config =
     71		&plane_state->uapi.plane->dev->mode_config;
     72	int width = drm_rect_width(&plane_state->uapi.dst);
     73	int height = drm_rect_height(&plane_state->uapi.dst);
     74
     75	return width > 0 && width <= config->cursor_width &&
     76		height > 0 && height <= config->cursor_height;
     77}
     78
     79static int intel_cursor_check_surface(struct intel_plane_state *plane_state)
     80{
     81	struct drm_i915_private *dev_priv =
     82		to_i915(plane_state->uapi.plane->dev);
     83	unsigned int rotation = plane_state->hw.rotation;
     84	int src_x, src_y;
     85	u32 offset;
     86	int ret;
     87
     88	ret = intel_plane_compute_gtt(plane_state);
     89	if (ret)
     90		return ret;
     91
     92	if (!plane_state->uapi.visible)
     93		return 0;
     94
     95	src_x = plane_state->uapi.src.x1 >> 16;
     96	src_y = plane_state->uapi.src.y1 >> 16;
     97
     98	intel_add_fb_offsets(&src_x, &src_y, plane_state, 0);
     99	offset = intel_plane_compute_aligned_offset(&src_x, &src_y,
    100						    plane_state, 0);
    101
    102	if (src_x != 0 || src_y != 0) {
    103		drm_dbg_kms(&dev_priv->drm,
    104			    "Arbitrary cursor panning not supported\n");
    105		return -EINVAL;
    106	}
    107
    108	/*
    109	 * Put the final coordinates back so that the src
    110	 * coordinate checks will see the right values.
    111	 */
    112	drm_rect_translate_to(&plane_state->uapi.src,
    113			      src_x << 16, src_y << 16);
    114
    115	/* ILK+ do this automagically in hardware */
    116	if (HAS_GMCH(dev_priv) && rotation & DRM_MODE_ROTATE_180) {
    117		const struct drm_framebuffer *fb = plane_state->hw.fb;
    118		int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
    119		int src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
    120
    121		offset += (src_h * src_w - 1) * fb->format->cpp[0];
    122	}
    123
    124	plane_state->view.color_plane[0].offset = offset;
    125	plane_state->view.color_plane[0].x = src_x;
    126	plane_state->view.color_plane[0].y = src_y;
    127
    128	return 0;
    129}
    130
    131static int intel_check_cursor(struct intel_crtc_state *crtc_state,
    132			      struct intel_plane_state *plane_state)
    133{
    134	const struct drm_framebuffer *fb = plane_state->hw.fb;
    135	struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
    136	const struct drm_rect src = plane_state->uapi.src;
    137	const struct drm_rect dst = plane_state->uapi.dst;
    138	int ret;
    139
    140	if (fb && fb->modifier != DRM_FORMAT_MOD_LINEAR) {
    141		drm_dbg_kms(&i915->drm, "cursor cannot be tiled\n");
    142		return -EINVAL;
    143	}
    144
    145	ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
    146						DRM_PLANE_HELPER_NO_SCALING,
    147						DRM_PLANE_HELPER_NO_SCALING,
    148						true);
    149	if (ret)
    150		return ret;
    151
    152	/* Use the unclipped src/dst rectangles, which we program to hw */
    153	plane_state->uapi.src = src;
    154	plane_state->uapi.dst = dst;
    155
    156	/* final plane coordinates will be relative to the plane's pipe */
    157	drm_rect_translate(&plane_state->uapi.dst,
    158			   -crtc_state->pipe_src.x1,
    159			   -crtc_state->pipe_src.y1);
    160
    161	ret = intel_cursor_check_surface(plane_state);
    162	if (ret)
    163		return ret;
    164
    165	if (!plane_state->uapi.visible)
    166		return 0;
    167
    168	ret = intel_plane_check_src_coordinates(plane_state);
    169	if (ret)
    170		return ret;
    171
    172	return 0;
    173}
    174
    175static unsigned int
    176i845_cursor_max_stride(struct intel_plane *plane,
    177		       u32 pixel_format, u64 modifier,
    178		       unsigned int rotation)
    179{
    180	return 2048;
    181}
    182
    183static u32 i845_cursor_ctl_crtc(const struct intel_crtc_state *crtc_state)
    184{
    185	u32 cntl = 0;
    186
    187	if (crtc_state->gamma_enable)
    188		cntl |= CURSOR_PIPE_GAMMA_ENABLE;
    189
    190	return cntl;
    191}
    192
    193static u32 i845_cursor_ctl(const struct intel_crtc_state *crtc_state,
    194			   const struct intel_plane_state *plane_state)
    195{
    196	return CURSOR_ENABLE |
    197		CURSOR_FORMAT_ARGB |
    198		CURSOR_STRIDE(plane_state->view.color_plane[0].mapping_stride);
    199}
    200
    201static bool i845_cursor_size_ok(const struct intel_plane_state *plane_state)
    202{
    203	int width = drm_rect_width(&plane_state->uapi.dst);
    204
    205	/*
    206	 * 845g/865g are only limited by the width of their cursors,
    207	 * the height is arbitrary up to the precision of the register.
    208	 */
    209	return intel_cursor_size_ok(plane_state) && IS_ALIGNED(width, 64);
    210}
    211
    212static int i845_check_cursor(struct intel_crtc_state *crtc_state,
    213			     struct intel_plane_state *plane_state)
    214{
    215	const struct drm_framebuffer *fb = plane_state->hw.fb;
    216	struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
    217	int ret;
    218
    219	ret = intel_check_cursor(crtc_state, plane_state);
    220	if (ret)
    221		return ret;
    222
    223	/* if we want to turn off the cursor ignore width and height */
    224	if (!fb)
    225		return 0;
    226
    227	/* Check for which cursor types we support */
    228	if (!i845_cursor_size_ok(plane_state)) {
    229		drm_dbg_kms(&i915->drm,
    230			    "Cursor dimension %dx%d not supported\n",
    231			    drm_rect_width(&plane_state->uapi.dst),
    232			    drm_rect_height(&plane_state->uapi.dst));
    233		return -EINVAL;
    234	}
    235
    236	drm_WARN_ON(&i915->drm, plane_state->uapi.visible &&
    237		    plane_state->view.color_plane[0].mapping_stride != fb->pitches[0]);
    238
    239	switch (fb->pitches[0]) {
    240	case 256:
    241	case 512:
    242	case 1024:
    243	case 2048:
    244		break;
    245	default:
    246		 drm_dbg_kms(&i915->drm, "Invalid cursor stride (%u)\n",
    247			     fb->pitches[0]);
    248		return -EINVAL;
    249	}
    250
    251	plane_state->ctl = i845_cursor_ctl(crtc_state, plane_state);
    252
    253	return 0;
    254}
    255
    256/* TODO: split into noarm+arm pair */
    257static void i845_cursor_update_arm(struct intel_plane *plane,
    258				   const struct intel_crtc_state *crtc_state,
    259				   const struct intel_plane_state *plane_state)
    260{
    261	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
    262	u32 cntl = 0, base = 0, pos = 0, size = 0;
    263
    264	if (plane_state && plane_state->uapi.visible) {
    265		unsigned int width = drm_rect_width(&plane_state->uapi.dst);
    266		unsigned int height = drm_rect_height(&plane_state->uapi.dst);
    267
    268		cntl = plane_state->ctl |
    269			i845_cursor_ctl_crtc(crtc_state);
    270
    271		size = CURSOR_HEIGHT(height) | CURSOR_WIDTH(width);
    272
    273		base = intel_cursor_base(plane_state);
    274		pos = intel_cursor_position(plane_state);
    275	}
    276
    277	/* On these chipsets we can only modify the base/size/stride
    278	 * whilst the cursor is disabled.
    279	 */
    280	if (plane->cursor.base != base ||
    281	    plane->cursor.size != size ||
    282	    plane->cursor.cntl != cntl) {
    283		intel_de_write_fw(dev_priv, CURCNTR(PIPE_A), 0);
    284		intel_de_write_fw(dev_priv, CURBASE(PIPE_A), base);
    285		intel_de_write_fw(dev_priv, CURSIZE(PIPE_A), size);
    286		intel_de_write_fw(dev_priv, CURPOS(PIPE_A), pos);
    287		intel_de_write_fw(dev_priv, CURCNTR(PIPE_A), cntl);
    288
    289		plane->cursor.base = base;
    290		plane->cursor.size = size;
    291		plane->cursor.cntl = cntl;
    292	} else {
    293		intel_de_write_fw(dev_priv, CURPOS(PIPE_A), pos);
    294	}
    295}
    296
    297static void i845_cursor_disable_arm(struct intel_plane *plane,
    298				    const struct intel_crtc_state *crtc_state)
    299{
    300	i845_cursor_update_arm(plane, crtc_state, NULL);
    301}
    302
    303static bool i845_cursor_get_hw_state(struct intel_plane *plane,
    304				     enum pipe *pipe)
    305{
    306	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
    307	enum intel_display_power_domain power_domain;
    308	intel_wakeref_t wakeref;
    309	bool ret;
    310
    311	power_domain = POWER_DOMAIN_PIPE(PIPE_A);
    312	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
    313	if (!wakeref)
    314		return false;
    315
    316	ret = intel_de_read(dev_priv, CURCNTR(PIPE_A)) & CURSOR_ENABLE;
    317
    318	*pipe = PIPE_A;
    319
    320	intel_display_power_put(dev_priv, power_domain, wakeref);
    321
    322	return ret;
    323}
    324
    325static unsigned int
    326i9xx_cursor_max_stride(struct intel_plane *plane,
    327		       u32 pixel_format, u64 modifier,
    328		       unsigned int rotation)
    329{
    330	return plane->base.dev->mode_config.cursor_width * 4;
    331}
    332
    333static u32 i9xx_cursor_ctl_crtc(const struct intel_crtc_state *crtc_state)
    334{
    335	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
    336	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
    337	u32 cntl = 0;
    338
    339	if (DISPLAY_VER(dev_priv) >= 11)
    340		return cntl;
    341
    342	if (crtc_state->gamma_enable)
    343		cntl = MCURSOR_PIPE_GAMMA_ENABLE;
    344
    345	if (crtc_state->csc_enable)
    346		cntl |= MCURSOR_PIPE_CSC_ENABLE;
    347
    348	if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv))
    349		cntl |= MCURSOR_PIPE_SEL(crtc->pipe);
    350
    351	return cntl;
    352}
    353
    354static u32 i9xx_cursor_ctl(const struct intel_crtc_state *crtc_state,
    355			   const struct intel_plane_state *plane_state)
    356{
    357	struct drm_i915_private *dev_priv =
    358		to_i915(plane_state->uapi.plane->dev);
    359	u32 cntl = 0;
    360
    361	if (IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv))
    362		cntl |= MCURSOR_TRICKLE_FEED_DISABLE;
    363
    364	switch (drm_rect_width(&plane_state->uapi.dst)) {
    365	case 64:
    366		cntl |= MCURSOR_MODE_64_ARGB_AX;
    367		break;
    368	case 128:
    369		cntl |= MCURSOR_MODE_128_ARGB_AX;
    370		break;
    371	case 256:
    372		cntl |= MCURSOR_MODE_256_ARGB_AX;
    373		break;
    374	default:
    375		MISSING_CASE(drm_rect_width(&plane_state->uapi.dst));
    376		return 0;
    377	}
    378
    379	if (plane_state->hw.rotation & DRM_MODE_ROTATE_180)
    380		cntl |= MCURSOR_ROTATE_180;
    381
    382	/* Wa_22012358565:adl-p */
    383	if (DISPLAY_VER(dev_priv) == 13)
    384		cntl |= MCURSOR_ARB_SLOTS(1);
    385
    386	return cntl;
    387}
    388
    389static bool i9xx_cursor_size_ok(const struct intel_plane_state *plane_state)
    390{
    391	struct drm_i915_private *dev_priv =
    392		to_i915(plane_state->uapi.plane->dev);
    393	int width = drm_rect_width(&plane_state->uapi.dst);
    394	int height = drm_rect_height(&plane_state->uapi.dst);
    395
    396	if (!intel_cursor_size_ok(plane_state))
    397		return false;
    398
    399	/* Cursor width is limited to a few power-of-two sizes */
    400	switch (width) {
    401	case 256:
    402	case 128:
    403	case 64:
    404		break;
    405	default:
    406		return false;
    407	}
    408
    409	/*
    410	 * IVB+ have CUR_FBC_CTL which allows an arbitrary cursor
    411	 * height from 8 lines up to the cursor width, when the
    412	 * cursor is not rotated. Everything else requires square
    413	 * cursors.
    414	 */
    415	if (HAS_CUR_FBC(dev_priv) &&
    416	    plane_state->hw.rotation & DRM_MODE_ROTATE_0) {
    417		if (height < 8 || height > width)
    418			return false;
    419	} else {
    420		if (height != width)
    421			return false;
    422	}
    423
    424	return true;
    425}
    426
    427static int i9xx_check_cursor(struct intel_crtc_state *crtc_state,
    428			     struct intel_plane_state *plane_state)
    429{
    430	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
    431	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
    432	const struct drm_framebuffer *fb = plane_state->hw.fb;
    433	enum pipe pipe = plane->pipe;
    434	int ret;
    435
    436	ret = intel_check_cursor(crtc_state, plane_state);
    437	if (ret)
    438		return ret;
    439
    440	/* if we want to turn off the cursor ignore width and height */
    441	if (!fb)
    442		return 0;
    443
    444	/* Check for which cursor types we support */
    445	if (!i9xx_cursor_size_ok(plane_state)) {
    446		drm_dbg(&dev_priv->drm,
    447			"Cursor dimension %dx%d not supported\n",
    448			drm_rect_width(&plane_state->uapi.dst),
    449			drm_rect_height(&plane_state->uapi.dst));
    450		return -EINVAL;
    451	}
    452
    453	drm_WARN_ON(&dev_priv->drm, plane_state->uapi.visible &&
    454		    plane_state->view.color_plane[0].mapping_stride != fb->pitches[0]);
    455
    456	if (fb->pitches[0] !=
    457	    drm_rect_width(&plane_state->uapi.dst) * fb->format->cpp[0]) {
    458		drm_dbg_kms(&dev_priv->drm,
    459			    "Invalid cursor stride (%u) (cursor width %d)\n",
    460			    fb->pitches[0],
    461			    drm_rect_width(&plane_state->uapi.dst));
    462		return -EINVAL;
    463	}
    464
    465	/*
    466	 * There's something wrong with the cursor on CHV pipe C.
    467	 * If it straddles the left edge of the screen then
    468	 * moving it away from the edge or disabling it often
    469	 * results in a pipe underrun, and often that can lead to
    470	 * dead pipe (constant underrun reported, and it scans
    471	 * out just a solid color). To recover from that, the
    472	 * display power well must be turned off and on again.
    473	 * Refuse the put the cursor into that compromised position.
    474	 */
    475	if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_C &&
    476	    plane_state->uapi.visible && plane_state->uapi.dst.x1 < 0) {
    477		drm_dbg_kms(&dev_priv->drm,
    478			    "CHV cursor C not allowed to straddle the left screen edge\n");
    479		return -EINVAL;
    480	}
    481
    482	plane_state->ctl = i9xx_cursor_ctl(crtc_state, plane_state);
    483
    484	return 0;
    485}
    486
    487/* TODO: split into noarm+arm pair */
    488static void i9xx_cursor_update_arm(struct intel_plane *plane,
    489				   const struct intel_crtc_state *crtc_state,
    490				   const struct intel_plane_state *plane_state)
    491{
    492	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
    493	enum pipe pipe = plane->pipe;
    494	u32 cntl = 0, base = 0, pos = 0, fbc_ctl = 0;
    495
    496	if (plane_state && plane_state->uapi.visible) {
    497		int width = drm_rect_width(&plane_state->uapi.dst);
    498		int height = drm_rect_height(&plane_state->uapi.dst);
    499
    500		cntl = plane_state->ctl |
    501			i9xx_cursor_ctl_crtc(crtc_state);
    502
    503		if (width != height)
    504			fbc_ctl = CUR_FBC_EN | CUR_FBC_HEIGHT(height - 1);
    505
    506		base = intel_cursor_base(plane_state);
    507		pos = intel_cursor_position(plane_state);
    508	}
    509
    510	/*
    511	 * On some platforms writing CURCNTR first will also
    512	 * cause CURPOS to be armed by the CURBASE write.
    513	 * Without the CURCNTR write the CURPOS write would
    514	 * arm itself. Thus we always update CURCNTR before
    515	 * CURPOS.
    516	 *
    517	 * On other platforms CURPOS always requires the
    518	 * CURBASE write to arm the update. Additonally
    519	 * a write to any of the cursor register will cancel
    520	 * an already armed cursor update. Thus leaving out
    521	 * the CURBASE write after CURPOS could lead to a
    522	 * cursor that doesn't appear to move, or even change
    523	 * shape. Thus we always write CURBASE.
    524	 *
    525	 * The other registers are armed by the CURBASE write
    526	 * except when the plane is getting enabled at which time
    527	 * the CURCNTR write arms the update.
    528	 */
    529
    530	if (DISPLAY_VER(dev_priv) >= 9)
    531		skl_write_cursor_wm(plane, crtc_state);
    532
    533	if (plane_state)
    534		intel_psr2_program_plane_sel_fetch(plane, crtc_state, plane_state, 0);
    535	else
    536		intel_psr2_disable_plane_sel_fetch(plane, crtc_state);
    537
    538	if (plane->cursor.base != base ||
    539	    plane->cursor.size != fbc_ctl ||
    540	    plane->cursor.cntl != cntl) {
    541		if (HAS_CUR_FBC(dev_priv))
    542			intel_de_write_fw(dev_priv, CUR_FBC_CTL(pipe),
    543					  fbc_ctl);
    544		intel_de_write_fw(dev_priv, CURCNTR(pipe), cntl);
    545		intel_de_write_fw(dev_priv, CURPOS(pipe), pos);
    546		intel_de_write_fw(dev_priv, CURBASE(pipe), base);
    547
    548		plane->cursor.base = base;
    549		plane->cursor.size = fbc_ctl;
    550		plane->cursor.cntl = cntl;
    551	} else {
    552		intel_de_write_fw(dev_priv, CURPOS(pipe), pos);
    553		intel_de_write_fw(dev_priv, CURBASE(pipe), base);
    554	}
    555}
    556
    557static void i9xx_cursor_disable_arm(struct intel_plane *plane,
    558				    const struct intel_crtc_state *crtc_state)
    559{
    560	i9xx_cursor_update_arm(plane, crtc_state, NULL);
    561}
    562
    563static bool i9xx_cursor_get_hw_state(struct intel_plane *plane,
    564				     enum pipe *pipe)
    565{
    566	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
    567	enum intel_display_power_domain power_domain;
    568	intel_wakeref_t wakeref;
    569	bool ret;
    570	u32 val;
    571
    572	/*
    573	 * Not 100% correct for planes that can move between pipes,
    574	 * but that's only the case for gen2-3 which don't have any
    575	 * display power wells.
    576	 */
    577	power_domain = POWER_DOMAIN_PIPE(plane->pipe);
    578	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
    579	if (!wakeref)
    580		return false;
    581
    582	val = intel_de_read(dev_priv, CURCNTR(plane->pipe));
    583
    584	ret = val & MCURSOR_MODE_MASK;
    585
    586	if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv))
    587		*pipe = plane->pipe;
    588	else
    589		*pipe = REG_FIELD_GET(MCURSOR_PIPE_SEL_MASK, val);
    590
    591	intel_display_power_put(dev_priv, power_domain, wakeref);
    592
    593	return ret;
    594}
    595
    596static bool intel_cursor_format_mod_supported(struct drm_plane *_plane,
    597					      u32 format, u64 modifier)
    598{
    599	if (!intel_fb_plane_supports_modifier(to_intel_plane(_plane), modifier))
    600		return false;
    601
    602	return format == DRM_FORMAT_ARGB8888;
    603}
    604
    605static int
    606intel_legacy_cursor_update(struct drm_plane *_plane,
    607			   struct drm_crtc *_crtc,
    608			   struct drm_framebuffer *fb,
    609			   int crtc_x, int crtc_y,
    610			   unsigned int crtc_w, unsigned int crtc_h,
    611			   u32 src_x, u32 src_y,
    612			   u32 src_w, u32 src_h,
    613			   struct drm_modeset_acquire_ctx *ctx)
    614{
    615	struct intel_plane *plane = to_intel_plane(_plane);
    616	struct intel_crtc *crtc = to_intel_crtc(_crtc);
    617	struct intel_plane_state *old_plane_state =
    618		to_intel_plane_state(plane->base.state);
    619	struct intel_plane_state *new_plane_state;
    620	struct intel_crtc_state *crtc_state =
    621		to_intel_crtc_state(crtc->base.state);
    622	struct intel_crtc_state *new_crtc_state;
    623	int ret;
    624
    625	/*
    626	 * When crtc is inactive or there is a modeset pending,
    627	 * wait for it to complete in the slowpath.
    628	 * PSR2 selective fetch also requires the slow path as
    629	 * PSR2 plane and transcoder registers can only be updated during
    630	 * vblank.
    631	 *
    632	 * FIXME bigjoiner fastpath would be good
    633	 */
    634	if (!crtc_state->hw.active || intel_crtc_needs_modeset(crtc_state) ||
    635	    crtc_state->update_pipe || crtc_state->bigjoiner_pipes)
    636		goto slow;
    637
    638	/*
    639	 * Don't do an async update if there is an outstanding commit modifying
    640	 * the plane.  This prevents our async update's changes from getting
    641	 * overridden by a previous synchronous update's state.
    642	 */
    643	if (old_plane_state->uapi.commit &&
    644	    !try_wait_for_completion(&old_plane_state->uapi.commit->hw_done))
    645		goto slow;
    646
    647	/*
    648	 * If any parameters change that may affect watermarks,
    649	 * take the slowpath. Only changing fb or position should be
    650	 * in the fastpath.
    651	 */
    652	if (old_plane_state->uapi.crtc != &crtc->base ||
    653	    old_plane_state->uapi.src_w != src_w ||
    654	    old_plane_state->uapi.src_h != src_h ||
    655	    old_plane_state->uapi.crtc_w != crtc_w ||
    656	    old_plane_state->uapi.crtc_h != crtc_h ||
    657	    !old_plane_state->uapi.fb != !fb)
    658		goto slow;
    659
    660	new_plane_state = to_intel_plane_state(intel_plane_duplicate_state(&plane->base));
    661	if (!new_plane_state)
    662		return -ENOMEM;
    663
    664	new_crtc_state = to_intel_crtc_state(intel_crtc_duplicate_state(&crtc->base));
    665	if (!new_crtc_state) {
    666		ret = -ENOMEM;
    667		goto out_free;
    668	}
    669
    670	drm_atomic_set_fb_for_plane(&new_plane_state->uapi, fb);
    671
    672	new_plane_state->uapi.src_x = src_x;
    673	new_plane_state->uapi.src_y = src_y;
    674	new_plane_state->uapi.src_w = src_w;
    675	new_plane_state->uapi.src_h = src_h;
    676	new_plane_state->uapi.crtc_x = crtc_x;
    677	new_plane_state->uapi.crtc_y = crtc_y;
    678	new_plane_state->uapi.crtc_w = crtc_w;
    679	new_plane_state->uapi.crtc_h = crtc_h;
    680
    681	intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state, crtc);
    682
    683	ret = intel_plane_atomic_check_with_state(crtc_state, new_crtc_state,
    684						  old_plane_state, new_plane_state);
    685	if (ret)
    686		goto out_free;
    687
    688	ret = intel_plane_pin_fb(new_plane_state);
    689	if (ret)
    690		goto out_free;
    691
    692	intel_frontbuffer_flush(to_intel_frontbuffer(new_plane_state->hw.fb),
    693				ORIGIN_CURSOR_UPDATE);
    694	intel_frontbuffer_track(to_intel_frontbuffer(old_plane_state->hw.fb),
    695				to_intel_frontbuffer(new_plane_state->hw.fb),
    696				plane->frontbuffer_bit);
    697
    698	/* Swap plane state */
    699	plane->base.state = &new_plane_state->uapi;
    700
    701	/*
    702	 * We cannot swap crtc_state as it may be in use by an atomic commit or
    703	 * page flip that's running simultaneously. If we swap crtc_state and
    704	 * destroy the old state, we will cause a use-after-free there.
    705	 *
    706	 * Only update active_planes, which is needed for our internal
    707	 * bookkeeping. Either value will do the right thing when updating
    708	 * planes atomically. If the cursor was part of the atomic update then
    709	 * we would have taken the slowpath.
    710	 */
    711	crtc_state->active_planes = new_crtc_state->active_planes;
    712
    713	/*
    714	 * Technically we should do a vblank evasion here to make
    715	 * sure all the cursor registers update on the same frame.
    716	 * For now just make sure the register writes happen as
    717	 * quickly as possible to minimize the race window.
    718	 */
    719	local_irq_disable();
    720
    721	if (new_plane_state->uapi.visible) {
    722		intel_plane_update_noarm(plane, crtc_state, new_plane_state);
    723		intel_plane_update_arm(plane, crtc_state, new_plane_state);
    724	} else {
    725		intel_plane_disable_arm(plane, crtc_state);
    726	}
    727
    728	local_irq_enable();
    729
    730	intel_plane_unpin_fb(old_plane_state);
    731
    732out_free:
    733	if (new_crtc_state)
    734		intel_crtc_destroy_state(&crtc->base, &new_crtc_state->uapi);
    735	if (ret)
    736		intel_plane_destroy_state(&plane->base, &new_plane_state->uapi);
    737	else
    738		intel_plane_destroy_state(&plane->base, &old_plane_state->uapi);
    739	return ret;
    740
    741slow:
    742	return drm_atomic_helper_update_plane(&plane->base, &crtc->base, fb,
    743					      crtc_x, crtc_y, crtc_w, crtc_h,
    744					      src_x, src_y, src_w, src_h, ctx);
    745}
    746
    747static const struct drm_plane_funcs intel_cursor_plane_funcs = {
    748	.update_plane = intel_legacy_cursor_update,
    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 = intel_cursor_format_mod_supported,
    754};
    755
    756struct intel_plane *
    757intel_cursor_plane_create(struct drm_i915_private *dev_priv,
    758			  enum pipe pipe)
    759{
    760	struct intel_plane *cursor;
    761	int ret, zpos;
    762	u64 *modifiers;
    763
    764	cursor = intel_plane_alloc();
    765	if (IS_ERR(cursor))
    766		return cursor;
    767
    768	cursor->pipe = pipe;
    769	cursor->i9xx_plane = (enum i9xx_plane_id) pipe;
    770	cursor->id = PLANE_CURSOR;
    771	cursor->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, cursor->id);
    772
    773	if (IS_I845G(dev_priv) || IS_I865G(dev_priv)) {
    774		cursor->max_stride = i845_cursor_max_stride;
    775		cursor->update_arm = i845_cursor_update_arm;
    776		cursor->disable_arm = i845_cursor_disable_arm;
    777		cursor->get_hw_state = i845_cursor_get_hw_state;
    778		cursor->check_plane = i845_check_cursor;
    779	} else {
    780		cursor->max_stride = i9xx_cursor_max_stride;
    781		cursor->update_arm = i9xx_cursor_update_arm;
    782		cursor->disable_arm = i9xx_cursor_disable_arm;
    783		cursor->get_hw_state = i9xx_cursor_get_hw_state;
    784		cursor->check_plane = i9xx_check_cursor;
    785	}
    786
    787	cursor->cursor.base = ~0;
    788	cursor->cursor.cntl = ~0;
    789
    790	if (IS_I845G(dev_priv) || IS_I865G(dev_priv) || HAS_CUR_FBC(dev_priv))
    791		cursor->cursor.size = ~0;
    792
    793	modifiers = intel_fb_plane_get_modifiers(dev_priv, INTEL_PLANE_CAP_NONE);
    794
    795	ret = drm_universal_plane_init(&dev_priv->drm, &cursor->base,
    796				       0, &intel_cursor_plane_funcs,
    797				       intel_cursor_formats,
    798				       ARRAY_SIZE(intel_cursor_formats),
    799				       modifiers,
    800				       DRM_PLANE_TYPE_CURSOR,
    801				       "cursor %c", pipe_name(pipe));
    802
    803	kfree(modifiers);
    804
    805	if (ret)
    806		goto fail;
    807
    808	if (DISPLAY_VER(dev_priv) >= 4)
    809		drm_plane_create_rotation_property(&cursor->base,
    810						   DRM_MODE_ROTATE_0,
    811						   DRM_MODE_ROTATE_0 |
    812						   DRM_MODE_ROTATE_180);
    813
    814	zpos = RUNTIME_INFO(dev_priv)->num_sprites[pipe] + 1;
    815	drm_plane_create_zpos_immutable_property(&cursor->base, zpos);
    816
    817	if (DISPLAY_VER(dev_priv) >= 12)
    818		drm_plane_enable_fb_damage_clips(&cursor->base);
    819
    820	intel_plane_helper_add(cursor);
    821
    822	return cursor;
    823
    824fail:
    825	intel_plane_free(cursor);
    826
    827	return ERR_PTR(ret);
    828}