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