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#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 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 (plane_state)
 540                intel_psr2_program_plane_sel_fetch(plane, crtc_state, plane_state, 0);
 541        else
 542                intel_psr2_disable_plane_sel_fetch(plane, crtc_state);
 543
 544        if (plane->cursor.base != base ||
 545            plane->cursor.size != fbc_ctl ||
 546            plane->cursor.cntl != cntl) {
 547                if (HAS_CUR_FBC(dev_priv))
 548                        intel_de_write_fw(dev_priv, CUR_FBC_CTL(pipe),
 549                                          fbc_ctl);
 550                intel_de_write_fw(dev_priv, CURCNTR(pipe), cntl);
 551                intel_de_write_fw(dev_priv, CURPOS(pipe), pos);
 552                intel_de_write_fw(dev_priv, CURBASE(pipe), base);
 553
 554                plane->cursor.base = base;
 555                plane->cursor.size = fbc_ctl;
 556                plane->cursor.cntl = cntl;
 557        } else {
 558                intel_de_write_fw(dev_priv, CURPOS(pipe), pos);
 559                intel_de_write_fw(dev_priv, CURBASE(pipe), base);
 560        }
 561
 562        spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 563}
 564
 565static void i9xx_disable_cursor(struct intel_plane *plane,
 566                                const struct intel_crtc_state *crtc_state)
 567{
 568        i9xx_update_cursor(plane, crtc_state, NULL);
 569}
 570
 571static bool i9xx_cursor_get_hw_state(struct intel_plane *plane,
 572                                     enum pipe *pipe)
 573{
 574        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 575        enum intel_display_power_domain power_domain;
 576        intel_wakeref_t wakeref;
 577        bool ret;
 578        u32 val;
 579
 580        /*
 581         * Not 100% correct for planes that can move between pipes,
 582         * but that's only the case for gen2-3 which don't have any
 583         * display power wells.
 584         */
 585        power_domain = POWER_DOMAIN_PIPE(plane->pipe);
 586        wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
 587        if (!wakeref)
 588                return false;
 589
 590        val = intel_de_read(dev_priv, CURCNTR(plane->pipe));
 591
 592        ret = val & MCURSOR_MODE;
 593
 594        if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv))
 595                *pipe = plane->pipe;
 596        else
 597                *pipe = (val & MCURSOR_PIPE_SELECT_MASK) >>
 598                        MCURSOR_PIPE_SELECT_SHIFT;
 599
 600        intel_display_power_put(dev_priv, power_domain, wakeref);
 601
 602        return ret;
 603}
 604
 605static bool intel_cursor_format_mod_supported(struct drm_plane *_plane,
 606                                              u32 format, u64 modifier)
 607{
 608        return modifier == DRM_FORMAT_MOD_LINEAR &&
 609                format == DRM_FORMAT_ARGB8888;
 610}
 611
 612static int
 613intel_legacy_cursor_update(struct drm_plane *_plane,
 614                           struct drm_crtc *_crtc,
 615                           struct drm_framebuffer *fb,
 616                           int crtc_x, int crtc_y,
 617                           unsigned int crtc_w, unsigned int crtc_h,
 618                           u32 src_x, u32 src_y,
 619                           u32 src_w, u32 src_h,
 620                           struct drm_modeset_acquire_ctx *ctx)
 621{
 622        struct intel_plane *plane = to_intel_plane(_plane);
 623        struct intel_crtc *crtc = to_intel_crtc(_crtc);
 624        struct intel_plane_state *old_plane_state =
 625                to_intel_plane_state(plane->base.state);
 626        struct intel_plane_state *new_plane_state;
 627        struct intel_crtc_state *crtc_state =
 628                to_intel_crtc_state(crtc->base.state);
 629        struct intel_crtc_state *new_crtc_state;
 630        int ret;
 631
 632        /*
 633         * When crtc is inactive or there is a modeset pending,
 634         * wait for it to complete in the slowpath.
 635         * PSR2 selective fetch also requires the slow path as
 636         * PSR2 plane and transcoder registers can only be updated during
 637         * vblank.
 638         *
 639         * FIXME bigjoiner fastpath would be good
 640         */
 641        if (!crtc_state->hw.active || intel_crtc_needs_modeset(crtc_state) ||
 642            crtc_state->update_pipe || crtc_state->bigjoiner)
 643                goto slow;
 644
 645        /*
 646         * Don't do an async update if there is an outstanding commit modifying
 647         * the plane.  This prevents our async update's changes from getting
 648         * overridden by a previous synchronous update's state.
 649         */
 650        if (old_plane_state->uapi.commit &&
 651            !try_wait_for_completion(&old_plane_state->uapi.commit->hw_done))
 652                goto slow;
 653
 654        /*
 655         * If any parameters change that may affect watermarks,
 656         * take the slowpath. Only changing fb or position should be
 657         * in the fastpath.
 658         */
 659        if (old_plane_state->uapi.crtc != &crtc->base ||
 660            old_plane_state->uapi.src_w != src_w ||
 661            old_plane_state->uapi.src_h != src_h ||
 662            old_plane_state->uapi.crtc_w != crtc_w ||
 663            old_plane_state->uapi.crtc_h != crtc_h ||
 664            !old_plane_state->uapi.fb != !fb)
 665                goto slow;
 666
 667        new_plane_state = to_intel_plane_state(intel_plane_duplicate_state(&plane->base));
 668        if (!new_plane_state)
 669                return -ENOMEM;
 670
 671        new_crtc_state = to_intel_crtc_state(intel_crtc_duplicate_state(&crtc->base));
 672        if (!new_crtc_state) {
 673                ret = -ENOMEM;
 674                goto out_free;
 675        }
 676
 677        drm_atomic_set_fb_for_plane(&new_plane_state->uapi, fb);
 678
 679        new_plane_state->uapi.src_x = src_x;
 680        new_plane_state->uapi.src_y = src_y;
 681        new_plane_state->uapi.src_w = src_w;
 682        new_plane_state->uapi.src_h = src_h;
 683        new_plane_state->uapi.crtc_x = crtc_x;
 684        new_plane_state->uapi.crtc_y = crtc_y;
 685        new_plane_state->uapi.crtc_w = crtc_w;
 686        new_plane_state->uapi.crtc_h = crtc_h;
 687
 688        intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state, crtc);
 689
 690        ret = intel_plane_atomic_check_with_state(crtc_state, new_crtc_state,
 691                                                  old_plane_state, new_plane_state);
 692        if (ret)
 693                goto out_free;
 694
 695        ret = intel_plane_pin_fb(new_plane_state);
 696        if (ret)
 697                goto out_free;
 698
 699        intel_frontbuffer_flush(to_intel_frontbuffer(new_plane_state->hw.fb),
 700                                ORIGIN_CURSOR_UPDATE);
 701        intel_frontbuffer_track(to_intel_frontbuffer(old_plane_state->hw.fb),
 702                                to_intel_frontbuffer(new_plane_state->hw.fb),
 703                                plane->frontbuffer_bit);
 704
 705        /* Swap plane state */
 706        plane->base.state = &new_plane_state->uapi;
 707
 708        /*
 709         * We cannot swap crtc_state as it may be in use by an atomic commit or
 710         * page flip that's running simultaneously. If we swap crtc_state and
 711         * destroy the old state, we will cause a use-after-free there.
 712         *
 713         * Only update active_planes, which is needed for our internal
 714         * bookkeeping. Either value will do the right thing when updating
 715         * planes atomically. If the cursor was part of the atomic update then
 716         * we would have taken the slowpath.
 717         */
 718        crtc_state->active_planes = new_crtc_state->active_planes;
 719
 720        if (new_plane_state->uapi.visible)
 721                intel_update_plane(plane, crtc_state, new_plane_state);
 722        else
 723                intel_disable_plane(plane, crtc_state);
 724
 725        intel_plane_unpin_fb(old_plane_state);
 726
 727out_free:
 728        if (new_crtc_state)
 729                intel_crtc_destroy_state(&crtc->base, &new_crtc_state->uapi);
 730        if (ret)
 731                intel_plane_destroy_state(&plane->base, &new_plane_state->uapi);
 732        else
 733                intel_plane_destroy_state(&plane->base, &old_plane_state->uapi);
 734        return ret;
 735
 736slow:
 737        return drm_atomic_helper_update_plane(&plane->base, &crtc->base, fb,
 738                                              crtc_x, crtc_y, crtc_w, crtc_h,
 739                                              src_x, src_y, src_w, src_h, ctx);
 740}
 741
 742static const struct drm_plane_funcs intel_cursor_plane_funcs = {
 743        .update_plane = intel_legacy_cursor_update,
 744        .disable_plane = drm_atomic_helper_disable_plane,
 745        .destroy = intel_plane_destroy,
 746        .atomic_duplicate_state = intel_plane_duplicate_state,
 747        .atomic_destroy_state = intel_plane_destroy_state,
 748        .format_mod_supported = intel_cursor_format_mod_supported,
 749};
 750
 751struct intel_plane *
 752intel_cursor_plane_create(struct drm_i915_private *dev_priv,
 753                          enum pipe pipe)
 754{
 755        struct intel_plane *cursor;
 756        int ret, zpos;
 757
 758        cursor = intel_plane_alloc();
 759        if (IS_ERR(cursor))
 760                return cursor;
 761
 762        cursor->pipe = pipe;
 763        cursor->i9xx_plane = (enum i9xx_plane_id) pipe;
 764        cursor->id = PLANE_CURSOR;
 765        cursor->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, cursor->id);
 766
 767        if (IS_I845G(dev_priv) || IS_I865G(dev_priv)) {
 768                cursor->max_stride = i845_cursor_max_stride;
 769                cursor->update_plane = i845_update_cursor;
 770                cursor->disable_plane = i845_disable_cursor;
 771                cursor->get_hw_state = i845_cursor_get_hw_state;
 772                cursor->check_plane = i845_check_cursor;
 773        } else {
 774                cursor->max_stride = i9xx_cursor_max_stride;
 775                cursor->update_plane = i9xx_update_cursor;
 776                cursor->disable_plane = i9xx_disable_cursor;
 777                cursor->get_hw_state = i9xx_cursor_get_hw_state;
 778                cursor->check_plane = i9xx_check_cursor;
 779        }
 780
 781        cursor->cursor.base = ~0;
 782        cursor->cursor.cntl = ~0;
 783
 784        if (IS_I845G(dev_priv) || IS_I865G(dev_priv) || HAS_CUR_FBC(dev_priv))
 785                cursor->cursor.size = ~0;
 786
 787        ret = drm_universal_plane_init(&dev_priv->drm, &cursor->base,
 788                                       0, &intel_cursor_plane_funcs,
 789                                       intel_cursor_formats,
 790                                       ARRAY_SIZE(intel_cursor_formats),
 791                                       cursor_format_modifiers,
 792                                       DRM_PLANE_TYPE_CURSOR,
 793                                       "cursor %c", pipe_name(pipe));
 794        if (ret)
 795                goto fail;
 796
 797        if (DISPLAY_VER(dev_priv) >= 4)
 798                drm_plane_create_rotation_property(&cursor->base,
 799                                                   DRM_MODE_ROTATE_0,
 800                                                   DRM_MODE_ROTATE_0 |
 801                                                   DRM_MODE_ROTATE_180);
 802
 803        zpos = RUNTIME_INFO(dev_priv)->num_sprites[pipe] + 1;
 804        drm_plane_create_zpos_immutable_property(&cursor->base, zpos);
 805
 806        if (DISPLAY_VER(dev_priv) >= 12)
 807                drm_plane_enable_fb_damage_clips(&cursor->base);
 808
 809        intel_plane_helper_add(cursor);
 810
 811        return cursor;
 812
 813fail:
 814        intel_plane_free(cursor);
 815
 816        return ERR_PTR(ret);
 817}
 818