linux/drivers/gpu/drm/i915/display/intel_sprite.c
<<
>>
Prefs
   1/*
   2 * Copyright © 2011 Intel Corporation
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice (including the next
  12 * paragraph) shall be included in all copies or substantial portions of the
  13 * Software.
  14 *
  15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21 * SOFTWARE.
  22 *
  23 * Authors:
  24 *   Jesse Barnes <jbarnes@virtuousgeek.org>
  25 *
  26 * New plane/sprite handling.
  27 *
  28 * The older chips had a separate interface for programming plane related
  29 * registers; newer ones are much simpler and we can use the new DRM plane
  30 * support.
  31 */
  32
  33#include <drm/drm_atomic.h>
  34#include <drm/drm_atomic_helper.h>
  35#include <drm/drm_color_mgmt.h>
  36#include <drm/drm_crtc.h>
  37#include <drm/drm_fourcc.h>
  38#include <drm/drm_plane_helper.h>
  39#include <drm/drm_rect.h>
  40#include <drm/i915_drm.h>
  41
  42#include "i915_drv.h"
  43#include "i915_trace.h"
  44#include "intel_atomic_plane.h"
  45#include "intel_display_types.h"
  46#include "intel_frontbuffer.h"
  47#include "intel_pm.h"
  48#include "intel_psr.h"
  49#include "intel_sprite.h"
  50
  51int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
  52                             int usecs)
  53{
  54        /* paranoia */
  55        if (!adjusted_mode->crtc_htotal)
  56                return 1;
  57
  58        return DIV_ROUND_UP(usecs * adjusted_mode->crtc_clock,
  59                            1000 * adjusted_mode->crtc_htotal);
  60}
  61
  62/* FIXME: We should instead only take spinlocks once for the entire update
  63 * instead of once per mmio. */
  64#if IS_ENABLED(CONFIG_PROVE_LOCKING)
  65#define VBLANK_EVASION_TIME_US 250
  66#else
  67#define VBLANK_EVASION_TIME_US 100
  68#endif
  69
  70/**
  71 * intel_pipe_update_start() - start update of a set of display registers
  72 * @new_crtc_state: the new crtc state
  73 *
  74 * Mark the start of an update to pipe registers that should be updated
  75 * atomically regarding vblank. If the next vblank will happens within
  76 * the next 100 us, this function waits until the vblank passes.
  77 *
  78 * After a successful call to this function, interrupts will be disabled
  79 * until a subsequent call to intel_pipe_update_end(). That is done to
  80 * avoid random delays.
  81 */
  82void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state)
  83{
  84        struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
  85        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
  86        const struct drm_display_mode *adjusted_mode = &new_crtc_state->base.adjusted_mode;
  87        long timeout = msecs_to_jiffies_timeout(1);
  88        int scanline, min, max, vblank_start;
  89        wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base);
  90        bool need_vlv_dsi_wa = (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
  91                intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI);
  92        DEFINE_WAIT(wait);
  93        u32 psr_status;
  94
  95        vblank_start = adjusted_mode->crtc_vblank_start;
  96        if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
  97                vblank_start = DIV_ROUND_UP(vblank_start, 2);
  98
  99        /* FIXME needs to be calibrated sensibly */
 100        min = vblank_start - intel_usecs_to_scanlines(adjusted_mode,
 101                                                      VBLANK_EVASION_TIME_US);
 102        max = vblank_start - 1;
 103
 104        if (min <= 0 || max <= 0)
 105                goto irq_disable;
 106
 107        if (WARN_ON(drm_crtc_vblank_get(&crtc->base)))
 108                goto irq_disable;
 109
 110        /*
 111         * Wait for psr to idle out after enabling the VBL interrupts
 112         * VBL interrupts will start the PSR exit and prevent a PSR
 113         * re-entry as well.
 114         */
 115        if (intel_psr_wait_for_idle(new_crtc_state, &psr_status))
 116                DRM_ERROR("PSR idle timed out 0x%x, atomic update may fail\n",
 117                          psr_status);
 118
 119        local_irq_disable();
 120
 121        crtc->debug.min_vbl = min;
 122        crtc->debug.max_vbl = max;
 123        trace_i915_pipe_update_start(crtc);
 124
 125        for (;;) {
 126                /*
 127                 * prepare_to_wait() has a memory barrier, which guarantees
 128                 * other CPUs can see the task state update by the time we
 129                 * read the scanline.
 130                 */
 131                prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE);
 132
 133                scanline = intel_get_crtc_scanline(crtc);
 134                if (scanline < min || scanline > max)
 135                        break;
 136
 137                if (!timeout) {
 138                        DRM_ERROR("Potential atomic update failure on pipe %c\n",
 139                                  pipe_name(crtc->pipe));
 140                        break;
 141                }
 142
 143                local_irq_enable();
 144
 145                timeout = schedule_timeout(timeout);
 146
 147                local_irq_disable();
 148        }
 149
 150        finish_wait(wq, &wait);
 151
 152        drm_crtc_vblank_put(&crtc->base);
 153
 154        /*
 155         * On VLV/CHV DSI the scanline counter would appear to
 156         * increment approx. 1/3 of a scanline before start of vblank.
 157         * The registers still get latched at start of vblank however.
 158         * This means we must not write any registers on the first
 159         * line of vblank (since not the whole line is actually in
 160         * vblank). And unfortunately we can't use the interrupt to
 161         * wait here since it will fire too soon. We could use the
 162         * frame start interrupt instead since it will fire after the
 163         * critical scanline, but that would require more changes
 164         * in the interrupt code. So for now we'll just do the nasty
 165         * thing and poll for the bad scanline to pass us by.
 166         *
 167         * FIXME figure out if BXT+ DSI suffers from this as well
 168         */
 169        while (need_vlv_dsi_wa && scanline == vblank_start)
 170                scanline = intel_get_crtc_scanline(crtc);
 171
 172        crtc->debug.scanline_start = scanline;
 173        crtc->debug.start_vbl_time = ktime_get();
 174        crtc->debug.start_vbl_count = intel_crtc_get_vblank_counter(crtc);
 175
 176        trace_i915_pipe_update_vblank_evaded(crtc);
 177        return;
 178
 179irq_disable:
 180        local_irq_disable();
 181}
 182
 183/**
 184 * intel_pipe_update_end() - end update of a set of display registers
 185 * @new_crtc_state: the new crtc state
 186 *
 187 * Mark the end of an update started with intel_pipe_update_start(). This
 188 * re-enables interrupts and verifies the update was actually completed
 189 * before a vblank.
 190 */
 191void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state)
 192{
 193        struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
 194        enum pipe pipe = crtc->pipe;
 195        int scanline_end = intel_get_crtc_scanline(crtc);
 196        u32 end_vbl_count = intel_crtc_get_vblank_counter(crtc);
 197        ktime_t end_vbl_time = ktime_get();
 198        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 199
 200        trace_i915_pipe_update_end(crtc, end_vbl_count, scanline_end);
 201
 202        /* We're still in the vblank-evade critical section, this can't race.
 203         * Would be slightly nice to just grab the vblank count and arm the
 204         * event outside of the critical section - the spinlock might spin for a
 205         * while ... */
 206        if (new_crtc_state->base.event) {
 207                WARN_ON(drm_crtc_vblank_get(&crtc->base) != 0);
 208
 209                spin_lock(&crtc->base.dev->event_lock);
 210                drm_crtc_arm_vblank_event(&crtc->base, new_crtc_state->base.event);
 211                spin_unlock(&crtc->base.dev->event_lock);
 212
 213                new_crtc_state->base.event = NULL;
 214        }
 215
 216        local_irq_enable();
 217
 218        if (intel_vgpu_active(dev_priv))
 219                return;
 220
 221        if (crtc->debug.start_vbl_count &&
 222            crtc->debug.start_vbl_count != end_vbl_count) {
 223                DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u) time %lld us, min %d, max %d, scanline start %d, end %d\n",
 224                          pipe_name(pipe), crtc->debug.start_vbl_count,
 225                          end_vbl_count,
 226                          ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time),
 227                          crtc->debug.min_vbl, crtc->debug.max_vbl,
 228                          crtc->debug.scanline_start, scanline_end);
 229        }
 230#ifdef CONFIG_DRM_I915_DEBUG_VBLANK_EVADE
 231        else if (ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time) >
 232                 VBLANK_EVASION_TIME_US)
 233                DRM_WARN("Atomic update on pipe (%c) took %lld us, max time under evasion is %u us\n",
 234                         pipe_name(pipe),
 235                         ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time),
 236                         VBLANK_EVASION_TIME_US);
 237#endif
 238}
 239
 240int intel_plane_check_stride(const struct intel_plane_state *plane_state)
 241{
 242        struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
 243        const struct drm_framebuffer *fb = plane_state->base.fb;
 244        unsigned int rotation = plane_state->base.rotation;
 245        u32 stride, max_stride;
 246
 247        /*
 248         * We ignore stride for all invisible planes that
 249         * can be remapped. Otherwise we could end up
 250         * with a false positive when the remapping didn't
 251         * kick in due the plane being invisible.
 252         */
 253        if (intel_plane_can_remap(plane_state) &&
 254            !plane_state->base.visible)
 255                return 0;
 256
 257        /* FIXME other color planes? */
 258        stride = plane_state->color_plane[0].stride;
 259        max_stride = plane->max_stride(plane, fb->format->format,
 260                                       fb->modifier, rotation);
 261
 262        if (stride > max_stride) {
 263                DRM_DEBUG_KMS("[FB:%d] stride (%d) exceeds [PLANE:%d:%s] max stride (%d)\n",
 264                              fb->base.id, stride,
 265                              plane->base.base.id, plane->base.name, max_stride);
 266                return -EINVAL;
 267        }
 268
 269        return 0;
 270}
 271
 272int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
 273{
 274        const struct drm_framebuffer *fb = plane_state->base.fb;
 275        struct drm_rect *src = &plane_state->base.src;
 276        u32 src_x, src_y, src_w, src_h, hsub, vsub;
 277        bool rotated = drm_rotation_90_or_270(plane_state->base.rotation);
 278
 279        /*
 280         * Hardware doesn't handle subpixel coordinates.
 281         * Adjust to (macro)pixel boundary, but be careful not to
 282         * increase the source viewport size, because that could
 283         * push the downscaling factor out of bounds.
 284         */
 285        src_x = src->x1 >> 16;
 286        src_w = drm_rect_width(src) >> 16;
 287        src_y = src->y1 >> 16;
 288        src_h = drm_rect_height(src) >> 16;
 289
 290        drm_rect_init(src, src_x << 16, src_y << 16,
 291                      src_w << 16, src_h << 16);
 292
 293        if (!fb->format->is_yuv)
 294                return 0;
 295
 296        /* YUV specific checks */
 297        if (!rotated) {
 298                hsub = fb->format->hsub;
 299                vsub = fb->format->vsub;
 300        } else {
 301                hsub = vsub = max(fb->format->hsub, fb->format->vsub);
 302        }
 303
 304        if (src_x % hsub || src_w % hsub) {
 305                DRM_DEBUG_KMS("src x/w (%u, %u) must be a multiple of %u for %sYUV planes\n",
 306                              src_x, src_w, hsub, rotated ? "rotated " : "");
 307                return -EINVAL;
 308        }
 309
 310        if (src_y % vsub || src_h % vsub) {
 311                DRM_DEBUG_KMS("src y/h (%u, %u) must be a multiple of %u for %sYUV planes\n",
 312                              src_y, src_h, vsub, rotated ? "rotated " : "");
 313                return -EINVAL;
 314        }
 315
 316        return 0;
 317}
 318
 319bool icl_is_hdr_plane(struct drm_i915_private *dev_priv, enum plane_id plane_id)
 320{
 321        return INTEL_GEN(dev_priv) >= 11 &&
 322                icl_hdr_plane_mask() & BIT(plane_id);
 323}
 324
 325static void
 326skl_plane_ratio(const struct intel_crtc_state *crtc_state,
 327                const struct intel_plane_state *plane_state,
 328                unsigned int *num, unsigned int *den)
 329{
 330        struct drm_i915_private *dev_priv = to_i915(plane_state->base.plane->dev);
 331        const struct drm_framebuffer *fb = plane_state->base.fb;
 332
 333        if (fb->format->cpp[0] == 8) {
 334                if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) {
 335                        *num = 10;
 336                        *den = 8;
 337                } else {
 338                        *num = 9;
 339                        *den = 8;
 340                }
 341        } else {
 342                *num = 1;
 343                *den = 1;
 344        }
 345}
 346
 347static int skl_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
 348                               const struct intel_plane_state *plane_state)
 349{
 350        struct drm_i915_private *dev_priv = to_i915(plane_state->base.plane->dev);
 351        unsigned int pixel_rate = crtc_state->pixel_rate;
 352        unsigned int src_w, src_h, dst_w, dst_h;
 353        unsigned int num, den;
 354
 355        skl_plane_ratio(crtc_state, plane_state, &num, &den);
 356
 357        /* two pixels per clock on glk+ */
 358        if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
 359                den *= 2;
 360
 361        src_w = drm_rect_width(&plane_state->base.src) >> 16;
 362        src_h = drm_rect_height(&plane_state->base.src) >> 16;
 363        dst_w = drm_rect_width(&plane_state->base.dst);
 364        dst_h = drm_rect_height(&plane_state->base.dst);
 365
 366        /* Downscaling limits the maximum pixel rate */
 367        dst_w = min(src_w, dst_w);
 368        dst_h = min(src_h, dst_h);
 369
 370        return DIV64_U64_ROUND_UP(mul_u32_u32(pixel_rate * num, src_w * src_h),
 371                                  mul_u32_u32(den, dst_w * dst_h));
 372}
 373
 374static unsigned int
 375skl_plane_max_stride(struct intel_plane *plane,
 376                     u32 pixel_format, u64 modifier,
 377                     unsigned int rotation)
 378{
 379        const struct drm_format_info *info = drm_format_info(pixel_format);
 380        int cpp = info->cpp[0];
 381
 382        /*
 383         * "The stride in bytes must not exceed the
 384         * of the size of 8K pixels and 32K bytes."
 385         */
 386        if (drm_rotation_90_or_270(rotation))
 387                return min(8192, 32768 / cpp);
 388        else
 389                return min(8192 * cpp, 32768);
 390}
 391
 392static void
 393skl_program_scaler(struct intel_plane *plane,
 394                   const struct intel_crtc_state *crtc_state,
 395                   const struct intel_plane_state *plane_state)
 396{
 397        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 398        const struct drm_framebuffer *fb = plane_state->base.fb;
 399        enum pipe pipe = plane->pipe;
 400        int scaler_id = plane_state->scaler_id;
 401        const struct intel_scaler *scaler =
 402                &crtc_state->scaler_state.scalers[scaler_id];
 403        int crtc_x = plane_state->base.dst.x1;
 404        int crtc_y = plane_state->base.dst.y1;
 405        u32 crtc_w = drm_rect_width(&plane_state->base.dst);
 406        u32 crtc_h = drm_rect_height(&plane_state->base.dst);
 407        u16 y_hphase, uv_rgb_hphase;
 408        u16 y_vphase, uv_rgb_vphase;
 409        int hscale, vscale;
 410
 411        hscale = drm_rect_calc_hscale(&plane_state->base.src,
 412                                      &plane_state->base.dst,
 413                                      0, INT_MAX);
 414        vscale = drm_rect_calc_vscale(&plane_state->base.src,
 415                                      &plane_state->base.dst,
 416                                      0, INT_MAX);
 417
 418        /* TODO: handle sub-pixel coordinates */
 419        if (drm_format_info_is_yuv_semiplanar(fb->format) &&
 420            !icl_is_hdr_plane(dev_priv, plane->id)) {
 421                y_hphase = skl_scaler_calc_phase(1, hscale, false);
 422                y_vphase = skl_scaler_calc_phase(1, vscale, false);
 423
 424                /* MPEG2 chroma siting convention */
 425                uv_rgb_hphase = skl_scaler_calc_phase(2, hscale, true);
 426                uv_rgb_vphase = skl_scaler_calc_phase(2, vscale, false);
 427        } else {
 428                /* not used */
 429                y_hphase = 0;
 430                y_vphase = 0;
 431
 432                uv_rgb_hphase = skl_scaler_calc_phase(1, hscale, false);
 433                uv_rgb_vphase = skl_scaler_calc_phase(1, vscale, false);
 434        }
 435
 436        I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id),
 437                      PS_SCALER_EN | PS_PLANE_SEL(plane->id) | scaler->mode);
 438        I915_WRITE_FW(SKL_PS_VPHASE(pipe, scaler_id),
 439                      PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase));
 440        I915_WRITE_FW(SKL_PS_HPHASE(pipe, scaler_id),
 441                      PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase));
 442        I915_WRITE_FW(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y);
 443        I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id), (crtc_w << 16) | crtc_h);
 444}
 445
 446/* Preoffset values for YUV to RGB Conversion */
 447#define PREOFF_YUV_TO_RGB_HI            0x1800
 448#define PREOFF_YUV_TO_RGB_ME            0x1F00
 449#define PREOFF_YUV_TO_RGB_LO            0x1800
 450
 451#define  ROFF(x)          (((x) & 0xffff) << 16)
 452#define  GOFF(x)          (((x) & 0xffff) << 0)
 453#define  BOFF(x)          (((x) & 0xffff) << 16)
 454
 455static void
 456icl_program_input_csc(struct intel_plane *plane,
 457                      const struct intel_crtc_state *crtc_state,
 458                      const struct intel_plane_state *plane_state)
 459{
 460        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 461        enum pipe pipe = plane->pipe;
 462        enum plane_id plane_id = plane->id;
 463
 464        static const u16 input_csc_matrix[][9] = {
 465                /*
 466                 * BT.601 full range YCbCr -> full range RGB
 467                 * The matrix required is :
 468                 * [1.000, 0.000, 1.371,
 469                 *  1.000, -0.336, -0.698,
 470                 *  1.000, 1.732, 0.0000]
 471                 */
 472                [DRM_COLOR_YCBCR_BT601] = {
 473                        0x7AF8, 0x7800, 0x0,
 474                        0x8B28, 0x7800, 0x9AC0,
 475                        0x0, 0x7800, 0x7DD8,
 476                },
 477                /*
 478                 * BT.709 full range YCbCr -> full range RGB
 479                 * The matrix required is :
 480                 * [1.000, 0.000, 1.574,
 481                 *  1.000, -0.187, -0.468,
 482                 *  1.000, 1.855, 0.0000]
 483                 */
 484                [DRM_COLOR_YCBCR_BT709] = {
 485                        0x7C98, 0x7800, 0x0,
 486                        0x9EF8, 0x7800, 0xAC00,
 487                        0x0, 0x7800,  0x7ED8,
 488                },
 489                /*
 490                 * BT.2020 full range YCbCr -> full range RGB
 491                 * The matrix required is :
 492                 * [1.000, 0.000, 1.474,
 493                 *  1.000, -0.1645, -0.5713,
 494                 *  1.000, 1.8814, 0.0000]
 495                 */
 496                [DRM_COLOR_YCBCR_BT2020] = {
 497                        0x7BC8, 0x7800, 0x0,
 498                        0x8928, 0x7800, 0xAA88,
 499                        0x0, 0x7800, 0x7F10,
 500                },
 501        };
 502
 503        /* Matrix for Limited Range to Full Range Conversion */
 504        static const u16 input_csc_matrix_lr[][9] = {
 505                /*
 506                 * BT.601 Limted range YCbCr -> full range RGB
 507                 * The matrix required is :
 508                 * [1.164384, 0.000, 1.596027,
 509                 *  1.164384, -0.39175, -0.812813,
 510                 *  1.164384, 2.017232, 0.0000]
 511                 */
 512                [DRM_COLOR_YCBCR_BT601] = {
 513                        0x7CC8, 0x7950, 0x0,
 514                        0x8D00, 0x7950, 0x9C88,
 515                        0x0, 0x7950, 0x6810,
 516                },
 517                /*
 518                 * BT.709 Limited range YCbCr -> full range RGB
 519                 * The matrix required is :
 520                 * [1.164384, 0.000, 1.792741,
 521                 *  1.164384, -0.213249, -0.532909,
 522                 *  1.164384, 2.112402, 0.0000]
 523                 */
 524                [DRM_COLOR_YCBCR_BT709] = {
 525                        0x7E58, 0x7950, 0x0,
 526                        0x8888, 0x7950, 0xADA8,
 527                        0x0, 0x7950,  0x6870,
 528                },
 529                /*
 530                 * BT.2020 Limited range YCbCr -> full range RGB
 531                 * The matrix required is :
 532                 * [1.164, 0.000, 1.678,
 533                 *  1.164, -0.1873, -0.6504,
 534                 *  1.164, 2.1417, 0.0000]
 535                 */
 536                [DRM_COLOR_YCBCR_BT2020] = {
 537                        0x7D70, 0x7950, 0x0,
 538                        0x8A68, 0x7950, 0xAC00,
 539                        0x0, 0x7950, 0x6890,
 540                },
 541        };
 542        const u16 *csc;
 543
 544        if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
 545                csc = input_csc_matrix[plane_state->base.color_encoding];
 546        else
 547                csc = input_csc_matrix_lr[plane_state->base.color_encoding];
 548
 549        I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 0), ROFF(csc[0]) |
 550                      GOFF(csc[1]));
 551        I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 1), BOFF(csc[2]));
 552        I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 2), ROFF(csc[3]) |
 553                      GOFF(csc[4]));
 554        I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 3), BOFF(csc[5]));
 555        I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 4), ROFF(csc[6]) |
 556                      GOFF(csc[7]));
 557        I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 5), BOFF(csc[8]));
 558
 559        I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 0),
 560                      PREOFF_YUV_TO_RGB_HI);
 561        if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
 562                I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1), 0);
 563        else
 564                I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1),
 565                              PREOFF_YUV_TO_RGB_ME);
 566        I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 2),
 567                      PREOFF_YUV_TO_RGB_LO);
 568        I915_WRITE_FW(PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 0), 0x0);
 569        I915_WRITE_FW(PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 1), 0x0);
 570        I915_WRITE_FW(PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 2), 0x0);
 571}
 572
 573static void
 574skl_program_plane(struct intel_plane *plane,
 575                  const struct intel_crtc_state *crtc_state,
 576                  const struct intel_plane_state *plane_state,
 577                  int color_plane, bool slave, u32 plane_ctl)
 578{
 579        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 580        enum plane_id plane_id = plane->id;
 581        enum pipe pipe = plane->pipe;
 582        const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
 583        u32 surf_addr = plane_state->color_plane[color_plane].offset;
 584        u32 stride = skl_plane_stride(plane_state, color_plane);
 585        u32 aux_stride = skl_plane_stride(plane_state, 1);
 586        int crtc_x = plane_state->base.dst.x1;
 587        int crtc_y = plane_state->base.dst.y1;
 588        u32 x = plane_state->color_plane[color_plane].x;
 589        u32 y = plane_state->color_plane[color_plane].y;
 590        u32 src_w = drm_rect_width(&plane_state->base.src) >> 16;
 591        u32 src_h = drm_rect_height(&plane_state->base.src) >> 16;
 592        struct intel_plane *linked = plane_state->planar_linked_plane;
 593        const struct drm_framebuffer *fb = plane_state->base.fb;
 594        u8 alpha = plane_state->base.alpha >> 8;
 595        u32 plane_color_ctl = 0;
 596        unsigned long irqflags;
 597        u32 keymsk, keymax;
 598
 599        plane_ctl |= skl_plane_ctl_crtc(crtc_state);
 600
 601        if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
 602                plane_color_ctl = plane_state->color_ctl |
 603                        glk_plane_color_ctl_crtc(crtc_state);
 604
 605        /* Sizes are 0 based */
 606        src_w--;
 607        src_h--;
 608
 609        keymax = (key->max_value & 0xffffff) | PLANE_KEYMAX_ALPHA(alpha);
 610
 611        keymsk = key->channel_mask & 0x7ffffff;
 612        if (alpha < 0xff)
 613                keymsk |= PLANE_KEYMSK_ALPHA_ENABLE;
 614
 615        /* The scaler will handle the output position */
 616        if (plane_state->scaler_id >= 0) {
 617                crtc_x = 0;
 618                crtc_y = 0;
 619        }
 620
 621        spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 622
 623        I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride);
 624        I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x);
 625        I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w);
 626        I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id),
 627                      (plane_state->color_plane[1].offset - surf_addr) | aux_stride);
 628
 629        if (icl_is_hdr_plane(dev_priv, plane_id)) {
 630                u32 cus_ctl = 0;
 631
 632                if (linked) {
 633                        /* Enable and use MPEG-2 chroma siting */
 634                        cus_ctl = PLANE_CUS_ENABLE |
 635                                PLANE_CUS_HPHASE_0 |
 636                                PLANE_CUS_VPHASE_SIGN_NEGATIVE |
 637                                PLANE_CUS_VPHASE_0_25;
 638
 639                        if (linked->id == PLANE_SPRITE5)
 640                                cus_ctl |= PLANE_CUS_PLANE_7;
 641                        else if (linked->id == PLANE_SPRITE4)
 642                                cus_ctl |= PLANE_CUS_PLANE_6;
 643                        else
 644                                MISSING_CASE(linked->id);
 645                }
 646
 647                I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), cus_ctl);
 648        }
 649
 650        if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
 651                I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id), plane_color_ctl);
 652
 653        if (fb->format->is_yuv && icl_is_hdr_plane(dev_priv, plane_id))
 654                icl_program_input_csc(plane, crtc_state, plane_state);
 655
 656        skl_write_plane_wm(plane, crtc_state);
 657
 658        I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
 659        I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk);
 660        I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax);
 661
 662        I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x);
 663
 664        if (INTEL_GEN(dev_priv) < 11)
 665                I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
 666                              (plane_state->color_plane[1].y << 16) |
 667                              plane_state->color_plane[1].x);
 668
 669        /*
 670         * The control register self-arms if the plane was previously
 671         * disabled. Try to make the plane enable atomic by writing
 672         * the control register just before the surface register.
 673         */
 674        I915_WRITE_FW(PLANE_CTL(pipe, plane_id), plane_ctl);
 675        I915_WRITE_FW(PLANE_SURF(pipe, plane_id),
 676                      intel_plane_ggtt_offset(plane_state) + surf_addr);
 677
 678        if (!slave && plane_state->scaler_id >= 0)
 679                skl_program_scaler(plane, crtc_state, plane_state);
 680
 681        spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 682}
 683
 684static void
 685skl_update_plane(struct intel_plane *plane,
 686                 const struct intel_crtc_state *crtc_state,
 687                 const struct intel_plane_state *plane_state)
 688{
 689        int color_plane = 0;
 690
 691        if (plane_state->planar_linked_plane) {
 692                /* Program the UV plane */
 693                color_plane = 1;
 694        }
 695
 696        skl_program_plane(plane, crtc_state, plane_state,
 697                          color_plane, false, plane_state->ctl);
 698}
 699
 700static void
 701icl_update_slave(struct intel_plane *plane,
 702                 const struct intel_crtc_state *crtc_state,
 703                 const struct intel_plane_state *plane_state)
 704{
 705        skl_program_plane(plane, crtc_state, plane_state, 0, true,
 706                          plane_state->ctl | PLANE_CTL_YUV420_Y_PLANE);
 707}
 708
 709static void
 710skl_disable_plane(struct intel_plane *plane,
 711                  const struct intel_crtc_state *crtc_state)
 712{
 713        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 714        enum plane_id plane_id = plane->id;
 715        enum pipe pipe = plane->pipe;
 716        unsigned long irqflags;
 717
 718        spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 719
 720        if (icl_is_hdr_plane(dev_priv, plane_id))
 721                I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), 0);
 722
 723        skl_write_plane_wm(plane, crtc_state);
 724
 725        I915_WRITE_FW(PLANE_CTL(pipe, plane_id), 0);
 726        I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 0);
 727
 728        spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 729}
 730
 731static bool
 732skl_plane_get_hw_state(struct intel_plane *plane,
 733                       enum pipe *pipe)
 734{
 735        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 736        enum intel_display_power_domain power_domain;
 737        enum plane_id plane_id = plane->id;
 738        intel_wakeref_t wakeref;
 739        bool ret;
 740
 741        power_domain = POWER_DOMAIN_PIPE(plane->pipe);
 742        wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
 743        if (!wakeref)
 744                return false;
 745
 746        ret = I915_READ(PLANE_CTL(plane->pipe, plane_id)) & PLANE_CTL_ENABLE;
 747
 748        *pipe = plane->pipe;
 749
 750        intel_display_power_put(dev_priv, power_domain, wakeref);
 751
 752        return ret;
 753}
 754
 755static void i9xx_plane_linear_gamma(u16 gamma[8])
 756{
 757        /* The points are not evenly spaced. */
 758        static const u8 in[8] = { 0, 1, 2, 4, 8, 16, 24, 32 };
 759        int i;
 760
 761        for (i = 0; i < 8; i++)
 762                gamma[i] = (in[i] << 8) / 32;
 763}
 764
 765static void
 766chv_update_csc(const struct intel_plane_state *plane_state)
 767{
 768        struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
 769        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 770        const struct drm_framebuffer *fb = plane_state->base.fb;
 771        enum plane_id plane_id = plane->id;
 772        /*
 773         * |r|   | c0 c1 c2 |   |cr|
 774         * |g| = | c3 c4 c5 | x |y |
 775         * |b|   | c6 c7 c8 |   |cb|
 776         *
 777         * Coefficients are s3.12.
 778         *
 779         * Cb and Cr apparently come in as signed already, and
 780         * we always get full range data in on account of CLRC0/1.
 781         */
 782        static const s16 csc_matrix[][9] = {
 783                /* BT.601 full range YCbCr -> full range RGB */
 784                [DRM_COLOR_YCBCR_BT601] = {
 785                         5743, 4096,     0,
 786                        -2925, 4096, -1410,
 787                            0, 4096,  7258,
 788                },
 789                /* BT.709 full range YCbCr -> full range RGB */
 790                [DRM_COLOR_YCBCR_BT709] = {
 791                         6450, 4096,     0,
 792                        -1917, 4096,  -767,
 793                            0, 4096,  7601,
 794                },
 795        };
 796        const s16 *csc = csc_matrix[plane_state->base.color_encoding];
 797
 798        /* Seems RGB data bypasses the CSC always */
 799        if (!fb->format->is_yuv)
 800                return;
 801
 802        I915_WRITE_FW(SPCSCYGOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
 803        I915_WRITE_FW(SPCSCCBOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
 804        I915_WRITE_FW(SPCSCCROFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
 805
 806        I915_WRITE_FW(SPCSCC01(plane_id), SPCSC_C1(csc[1]) | SPCSC_C0(csc[0]));
 807        I915_WRITE_FW(SPCSCC23(plane_id), SPCSC_C1(csc[3]) | SPCSC_C0(csc[2]));
 808        I915_WRITE_FW(SPCSCC45(plane_id), SPCSC_C1(csc[5]) | SPCSC_C0(csc[4]));
 809        I915_WRITE_FW(SPCSCC67(plane_id), SPCSC_C1(csc[7]) | SPCSC_C0(csc[6]));
 810        I915_WRITE_FW(SPCSCC8(plane_id), SPCSC_C0(csc[8]));
 811
 812        I915_WRITE_FW(SPCSCYGICLAMP(plane_id), SPCSC_IMAX(1023) | SPCSC_IMIN(0));
 813        I915_WRITE_FW(SPCSCCBICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512));
 814        I915_WRITE_FW(SPCSCCRICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512));
 815
 816        I915_WRITE_FW(SPCSCYGOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
 817        I915_WRITE_FW(SPCSCCBOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
 818        I915_WRITE_FW(SPCSCCROCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
 819}
 820
 821#define SIN_0 0
 822#define COS_0 1
 823
 824static void
 825vlv_update_clrc(const struct intel_plane_state *plane_state)
 826{
 827        struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
 828        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 829        const struct drm_framebuffer *fb = plane_state->base.fb;
 830        enum pipe pipe = plane->pipe;
 831        enum plane_id plane_id = plane->id;
 832        int contrast, brightness, sh_scale, sh_sin, sh_cos;
 833
 834        if (fb->format->is_yuv &&
 835            plane_state->base.color_range == DRM_COLOR_YCBCR_LIMITED_RANGE) {
 836                /*
 837                 * Expand limited range to full range:
 838                 * Contrast is applied first and is used to expand Y range.
 839                 * Brightness is applied second and is used to remove the
 840                 * offset from Y. Saturation/hue is used to expand CbCr range.
 841                 */
 842                contrast = DIV_ROUND_CLOSEST(255 << 6, 235 - 16);
 843                brightness = -DIV_ROUND_CLOSEST(16 * 255, 235 - 16);
 844                sh_scale = DIV_ROUND_CLOSEST(128 << 7, 240 - 128);
 845                sh_sin = SIN_0 * sh_scale;
 846                sh_cos = COS_0 * sh_scale;
 847        } else {
 848                /* Pass-through everything. */
 849                contrast = 1 << 6;
 850                brightness = 0;
 851                sh_scale = 1 << 7;
 852                sh_sin = SIN_0 * sh_scale;
 853                sh_cos = COS_0 * sh_scale;
 854        }
 855
 856        /* FIXME these register are single buffered :( */
 857        I915_WRITE_FW(SPCLRC0(pipe, plane_id),
 858                      SP_CONTRAST(contrast) | SP_BRIGHTNESS(brightness));
 859        I915_WRITE_FW(SPCLRC1(pipe, plane_id),
 860                      SP_SH_SIN(sh_sin) | SP_SH_COS(sh_cos));
 861}
 862
 863static void
 864vlv_plane_ratio(const struct intel_crtc_state *crtc_state,
 865                const struct intel_plane_state *plane_state,
 866                unsigned int *num, unsigned int *den)
 867{
 868        u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR);
 869        const struct drm_framebuffer *fb = plane_state->base.fb;
 870        unsigned int cpp = fb->format->cpp[0];
 871
 872        /*
 873         * VLV bspec only considers cases where all three planes are
 874         * enabled, and cases where the primary and one sprite is enabled.
 875         * Let's assume the case with just two sprites enabled also
 876         * maps to the latter case.
 877         */
 878        if (hweight8(active_planes) == 3) {
 879                switch (cpp) {
 880                case 8:
 881                        *num = 11;
 882                        *den = 8;
 883                        break;
 884                case 4:
 885                        *num = 18;
 886                        *den = 16;
 887                        break;
 888                default:
 889                        *num = 1;
 890                        *den = 1;
 891                        break;
 892                }
 893        } else if (hweight8(active_planes) == 2) {
 894                switch (cpp) {
 895                case 8:
 896                        *num = 10;
 897                        *den = 8;
 898                        break;
 899                case 4:
 900                        *num = 17;
 901                        *den = 16;
 902                        break;
 903                default:
 904                        *num = 1;
 905                        *den = 1;
 906                        break;
 907                }
 908        } else {
 909                switch (cpp) {
 910                case 8:
 911                        *num = 10;
 912                        *den = 8;
 913                        break;
 914                default:
 915                        *num = 1;
 916                        *den = 1;
 917                        break;
 918                }
 919        }
 920}
 921
 922int vlv_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
 923                        const struct intel_plane_state *plane_state)
 924{
 925        unsigned int pixel_rate;
 926        unsigned int num, den;
 927
 928        /*
 929         * Note that crtc_state->pixel_rate accounts for both
 930         * horizontal and vertical panel fitter downscaling factors.
 931         * Pre-HSW bspec tells us to only consider the horizontal
 932         * downscaling factor here. We ignore that and just consider
 933         * both for simplicity.
 934         */
 935        pixel_rate = crtc_state->pixel_rate;
 936
 937        vlv_plane_ratio(crtc_state, plane_state, &num, &den);
 938
 939        return DIV_ROUND_UP(pixel_rate * num, den);
 940}
 941
 942static u32 vlv_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
 943{
 944        u32 sprctl = 0;
 945
 946        if (crtc_state->gamma_enable)
 947                sprctl |= SP_GAMMA_ENABLE;
 948
 949        return sprctl;
 950}
 951
 952static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state,
 953                          const struct intel_plane_state *plane_state)
 954{
 955        const struct drm_framebuffer *fb = plane_state->base.fb;
 956        unsigned int rotation = plane_state->base.rotation;
 957        const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
 958        u32 sprctl;
 959
 960        sprctl = SP_ENABLE;
 961
 962        switch (fb->format->format) {
 963        case DRM_FORMAT_YUYV:
 964                sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV;
 965                break;
 966        case DRM_FORMAT_YVYU:
 967                sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU;
 968                break;
 969        case DRM_FORMAT_UYVY:
 970                sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY;
 971                break;
 972        case DRM_FORMAT_VYUY:
 973                sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY;
 974                break;
 975        case DRM_FORMAT_RGB565:
 976                sprctl |= SP_FORMAT_BGR565;
 977                break;
 978        case DRM_FORMAT_XRGB8888:
 979                sprctl |= SP_FORMAT_BGRX8888;
 980                break;
 981        case DRM_FORMAT_ARGB8888:
 982                sprctl |= SP_FORMAT_BGRA8888;
 983                break;
 984        case DRM_FORMAT_XBGR2101010:
 985                sprctl |= SP_FORMAT_RGBX1010102;
 986                break;
 987        case DRM_FORMAT_ABGR2101010:
 988                sprctl |= SP_FORMAT_RGBA1010102;
 989                break;
 990        case DRM_FORMAT_XBGR8888:
 991                sprctl |= SP_FORMAT_RGBX8888;
 992                break;
 993        case DRM_FORMAT_ABGR8888:
 994                sprctl |= SP_FORMAT_RGBA8888;
 995                break;
 996        default:
 997                MISSING_CASE(fb->format->format);
 998                return 0;
 999        }
1000
1001        if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
1002                sprctl |= SP_YUV_FORMAT_BT709;
1003
1004        if (fb->modifier == I915_FORMAT_MOD_X_TILED)
1005                sprctl |= SP_TILED;
1006
1007        if (rotation & DRM_MODE_ROTATE_180)
1008                sprctl |= SP_ROTATE_180;
1009
1010        if (rotation & DRM_MODE_REFLECT_X)
1011                sprctl |= SP_MIRROR;
1012
1013        if (key->flags & I915_SET_COLORKEY_SOURCE)
1014                sprctl |= SP_SOURCE_KEY;
1015
1016        return sprctl;
1017}
1018
1019static void vlv_update_gamma(const struct intel_plane_state *plane_state)
1020{
1021        struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1022        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1023        const struct drm_framebuffer *fb = plane_state->base.fb;
1024        enum pipe pipe = plane->pipe;
1025        enum plane_id plane_id = plane->id;
1026        u16 gamma[8];
1027        int i;
1028
1029        /* Seems RGB data bypasses the gamma always */
1030        if (!fb->format->is_yuv)
1031                return;
1032
1033        i9xx_plane_linear_gamma(gamma);
1034
1035        /* FIXME these register are single buffered :( */
1036        /* The two end points are implicit (0.0 and 1.0) */
1037        for (i = 1; i < 8 - 1; i++)
1038                I915_WRITE_FW(SPGAMC(pipe, plane_id, i - 1),
1039                              gamma[i] << 16 |
1040                              gamma[i] << 8 |
1041                              gamma[i]);
1042}
1043
1044static void
1045vlv_update_plane(struct intel_plane *plane,
1046                 const struct intel_crtc_state *crtc_state,
1047                 const struct intel_plane_state *plane_state)
1048{
1049        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1050        enum pipe pipe = plane->pipe;
1051        enum plane_id plane_id = plane->id;
1052        u32 sprsurf_offset = plane_state->color_plane[0].offset;
1053        u32 linear_offset;
1054        const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1055        int crtc_x = plane_state->base.dst.x1;
1056        int crtc_y = plane_state->base.dst.y1;
1057        u32 crtc_w = drm_rect_width(&plane_state->base.dst);
1058        u32 crtc_h = drm_rect_height(&plane_state->base.dst);
1059        u32 x = plane_state->color_plane[0].x;
1060        u32 y = plane_state->color_plane[0].y;
1061        unsigned long irqflags;
1062        u32 sprctl;
1063
1064        sprctl = plane_state->ctl | vlv_sprite_ctl_crtc(crtc_state);
1065
1066        /* Sizes are 0 based */
1067        crtc_w--;
1068        crtc_h--;
1069
1070        linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
1071
1072        spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1073
1074        I915_WRITE_FW(SPSTRIDE(pipe, plane_id),
1075                      plane_state->color_plane[0].stride);
1076        I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x);
1077        I915_WRITE_FW(SPSIZE(pipe, plane_id), (crtc_h << 16) | crtc_w);
1078        I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0);
1079
1080        if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B)
1081                chv_update_csc(plane_state);
1082
1083        if (key->flags) {
1084                I915_WRITE_FW(SPKEYMINVAL(pipe, plane_id), key->min_value);
1085                I915_WRITE_FW(SPKEYMSK(pipe, plane_id), key->channel_mask);
1086                I915_WRITE_FW(SPKEYMAXVAL(pipe, plane_id), key->max_value);
1087        }
1088
1089        I915_WRITE_FW(SPLINOFF(pipe, plane_id), linear_offset);
1090        I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x);
1091
1092        /*
1093         * The control register self-arms if the plane was previously
1094         * disabled. Try to make the plane enable atomic by writing
1095         * the control register just before the surface register.
1096         */
1097        I915_WRITE_FW(SPCNTR(pipe, plane_id), sprctl);
1098        I915_WRITE_FW(SPSURF(pipe, plane_id),
1099                      intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
1100
1101        vlv_update_clrc(plane_state);
1102        vlv_update_gamma(plane_state);
1103
1104        spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1105}
1106
1107static void
1108vlv_disable_plane(struct intel_plane *plane,
1109                  const struct intel_crtc_state *crtc_state)
1110{
1111        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1112        enum pipe pipe = plane->pipe;
1113        enum plane_id plane_id = plane->id;
1114        unsigned long irqflags;
1115
1116        spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1117
1118        I915_WRITE_FW(SPCNTR(pipe, plane_id), 0);
1119        I915_WRITE_FW(SPSURF(pipe, plane_id), 0);
1120
1121        spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1122}
1123
1124static bool
1125vlv_plane_get_hw_state(struct intel_plane *plane,
1126                       enum pipe *pipe)
1127{
1128        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1129        enum intel_display_power_domain power_domain;
1130        enum plane_id plane_id = plane->id;
1131        intel_wakeref_t wakeref;
1132        bool ret;
1133
1134        power_domain = POWER_DOMAIN_PIPE(plane->pipe);
1135        wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
1136        if (!wakeref)
1137                return false;
1138
1139        ret = I915_READ(SPCNTR(plane->pipe, plane_id)) & SP_ENABLE;
1140
1141        *pipe = plane->pipe;
1142
1143        intel_display_power_put(dev_priv, power_domain, wakeref);
1144
1145        return ret;
1146}
1147
1148static void ivb_plane_ratio(const struct intel_crtc_state *crtc_state,
1149                            const struct intel_plane_state *plane_state,
1150                            unsigned int *num, unsigned int *den)
1151{
1152        u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR);
1153        const struct drm_framebuffer *fb = plane_state->base.fb;
1154        unsigned int cpp = fb->format->cpp[0];
1155
1156        if (hweight8(active_planes) == 2) {
1157                switch (cpp) {
1158                case 8:
1159                        *num = 10;
1160                        *den = 8;
1161                        break;
1162                case 4:
1163                        *num = 17;
1164                        *den = 16;
1165                        break;
1166                default:
1167                        *num = 1;
1168                        *den = 1;
1169                        break;
1170                }
1171        } else {
1172                switch (cpp) {
1173                case 8:
1174                        *num = 9;
1175                        *den = 8;
1176                        break;
1177                default:
1178                        *num = 1;
1179                        *den = 1;
1180                        break;
1181                }
1182        }
1183}
1184
1185static void ivb_plane_ratio_scaling(const struct intel_crtc_state *crtc_state,
1186                                    const struct intel_plane_state *plane_state,
1187                                    unsigned int *num, unsigned int *den)
1188{
1189        const struct drm_framebuffer *fb = plane_state->base.fb;
1190        unsigned int cpp = fb->format->cpp[0];
1191
1192        switch (cpp) {
1193        case 8:
1194                *num = 12;
1195                *den = 8;
1196                break;
1197        case 4:
1198                *num = 19;
1199                *den = 16;
1200                break;
1201        case 2:
1202                *num = 33;
1203                *den = 32;
1204                break;
1205        default:
1206                *num = 1;
1207                *den = 1;
1208                break;
1209        }
1210}
1211
1212int ivb_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
1213                        const struct intel_plane_state *plane_state)
1214{
1215        unsigned int pixel_rate;
1216        unsigned int num, den;
1217
1218        /*
1219         * Note that crtc_state->pixel_rate accounts for both
1220         * horizontal and vertical panel fitter downscaling factors.
1221         * Pre-HSW bspec tells us to only consider the horizontal
1222         * downscaling factor here. We ignore that and just consider
1223         * both for simplicity.
1224         */
1225        pixel_rate = crtc_state->pixel_rate;
1226
1227        ivb_plane_ratio(crtc_state, plane_state, &num, &den);
1228
1229        return DIV_ROUND_UP(pixel_rate * num, den);
1230}
1231
1232static int ivb_sprite_min_cdclk(const struct intel_crtc_state *crtc_state,
1233                                const struct intel_plane_state *plane_state)
1234{
1235        unsigned int src_w, dst_w, pixel_rate;
1236        unsigned int num, den;
1237
1238        /*
1239         * Note that crtc_state->pixel_rate accounts for both
1240         * horizontal and vertical panel fitter downscaling factors.
1241         * Pre-HSW bspec tells us to only consider the horizontal
1242         * downscaling factor here. We ignore that and just consider
1243         * both for simplicity.
1244         */
1245        pixel_rate = crtc_state->pixel_rate;
1246
1247        src_w = drm_rect_width(&plane_state->base.src) >> 16;
1248        dst_w = drm_rect_width(&plane_state->base.dst);
1249
1250        if (src_w != dst_w)
1251                ivb_plane_ratio_scaling(crtc_state, plane_state, &num, &den);
1252        else
1253                ivb_plane_ratio(crtc_state, plane_state, &num, &den);
1254
1255        /* Horizontal downscaling limits the maximum pixel rate */
1256        dst_w = min(src_w, dst_w);
1257
1258        return DIV_ROUND_UP_ULL(mul_u32_u32(pixel_rate, num * src_w),
1259                                den * dst_w);
1260}
1261
1262static void hsw_plane_ratio(const struct intel_crtc_state *crtc_state,
1263                            const struct intel_plane_state *plane_state,
1264                            unsigned int *num, unsigned int *den)
1265{
1266        u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR);
1267        const struct drm_framebuffer *fb = plane_state->base.fb;
1268        unsigned int cpp = fb->format->cpp[0];
1269
1270        if (hweight8(active_planes) == 2) {
1271                switch (cpp) {
1272                case 8:
1273                        *num = 10;
1274                        *den = 8;
1275                        break;
1276                default:
1277                        *num = 1;
1278                        *den = 1;
1279                        break;
1280                }
1281        } else {
1282                switch (cpp) {
1283                case 8:
1284                        *num = 9;
1285                        *den = 8;
1286                        break;
1287                default:
1288                        *num = 1;
1289                        *den = 1;
1290                        break;
1291                }
1292        }
1293}
1294
1295int hsw_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
1296                        const struct intel_plane_state *plane_state)
1297{
1298        unsigned int pixel_rate = crtc_state->pixel_rate;
1299        unsigned int num, den;
1300
1301        hsw_plane_ratio(crtc_state, plane_state, &num, &den);
1302
1303        return DIV_ROUND_UP(pixel_rate * num, den);
1304}
1305
1306static u32 ivb_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
1307{
1308        u32 sprctl = 0;
1309
1310        if (crtc_state->gamma_enable)
1311                sprctl |= SPRITE_GAMMA_ENABLE;
1312
1313        if (crtc_state->csc_enable)
1314                sprctl |= SPRITE_PIPE_CSC_ENABLE;
1315
1316        return sprctl;
1317}
1318
1319static bool ivb_need_sprite_gamma(const struct intel_plane_state *plane_state)
1320{
1321        struct drm_i915_private *dev_priv =
1322                to_i915(plane_state->base.plane->dev);
1323        const struct drm_framebuffer *fb = plane_state->base.fb;
1324
1325        return fb->format->cpp[0] == 8 &&
1326                (IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv));
1327}
1328
1329static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state,
1330                          const struct intel_plane_state *plane_state)
1331{
1332        struct drm_i915_private *dev_priv =
1333                to_i915(plane_state->base.plane->dev);
1334        const struct drm_framebuffer *fb = plane_state->base.fb;
1335        unsigned int rotation = plane_state->base.rotation;
1336        const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1337        u32 sprctl;
1338
1339        sprctl = SPRITE_ENABLE;
1340
1341        if (IS_IVYBRIDGE(dev_priv))
1342                sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
1343
1344        switch (fb->format->format) {
1345        case DRM_FORMAT_XBGR8888:
1346                sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
1347                break;
1348        case DRM_FORMAT_XRGB8888:
1349                sprctl |= SPRITE_FORMAT_RGBX888;
1350                break;
1351        case DRM_FORMAT_XBGR16161616F:
1352                sprctl |= SPRITE_FORMAT_RGBX161616 | SPRITE_RGB_ORDER_RGBX;
1353                break;
1354        case DRM_FORMAT_XRGB16161616F:
1355                sprctl |= SPRITE_FORMAT_RGBX161616;
1356                break;
1357        case DRM_FORMAT_YUYV:
1358                sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
1359                break;
1360        case DRM_FORMAT_YVYU:
1361                sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
1362                break;
1363        case DRM_FORMAT_UYVY:
1364                sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
1365                break;
1366        case DRM_FORMAT_VYUY:
1367                sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
1368                break;
1369        default:
1370                MISSING_CASE(fb->format->format);
1371                return 0;
1372        }
1373
1374        if (!ivb_need_sprite_gamma(plane_state))
1375                sprctl |= SPRITE_INT_GAMMA_DISABLE;
1376
1377        if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
1378                sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709;
1379
1380        if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
1381                sprctl |= SPRITE_YUV_RANGE_CORRECTION_DISABLE;
1382
1383        if (fb->modifier == I915_FORMAT_MOD_X_TILED)
1384                sprctl |= SPRITE_TILED;
1385
1386        if (rotation & DRM_MODE_ROTATE_180)
1387                sprctl |= SPRITE_ROTATE_180;
1388
1389        if (key->flags & I915_SET_COLORKEY_DESTINATION)
1390                sprctl |= SPRITE_DEST_KEY;
1391        else if (key->flags & I915_SET_COLORKEY_SOURCE)
1392                sprctl |= SPRITE_SOURCE_KEY;
1393
1394        return sprctl;
1395}
1396
1397static void ivb_sprite_linear_gamma(const struct intel_plane_state *plane_state,
1398                                    u16 gamma[18])
1399{
1400        int scale, i;
1401
1402        /*
1403         * WaFP16GammaEnabling:ivb,hsw
1404         * "Workaround : When using the 64-bit format, the sprite output
1405         *  on each color channel has one quarter amplitude. It can be
1406         *  brought up to full amplitude by using sprite internal gamma
1407         *  correction, pipe gamma correction, or pipe color space
1408         *  conversion to multiply the sprite output by four."
1409         */
1410        scale = 4;
1411
1412        for (i = 0; i < 16; i++)
1413                gamma[i] = min((scale * i << 10) / 16, (1 << 10) - 1);
1414
1415        gamma[i] = min((scale * i << 10) / 16, 1 << 10);
1416        i++;
1417
1418        gamma[i] = 3 << 10;
1419        i++;
1420}
1421
1422static void ivb_update_gamma(const struct intel_plane_state *plane_state)
1423{
1424        struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1425        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1426        enum pipe pipe = plane->pipe;
1427        u16 gamma[18];
1428        int i;
1429
1430        if (!ivb_need_sprite_gamma(plane_state))
1431                return;
1432
1433        ivb_sprite_linear_gamma(plane_state, gamma);
1434
1435        /* FIXME these register are single buffered :( */
1436        for (i = 0; i < 16; i++)
1437                I915_WRITE_FW(SPRGAMC(pipe, i),
1438                              gamma[i] << 20 |
1439                              gamma[i] << 10 |
1440                              gamma[i]);
1441
1442        I915_WRITE_FW(SPRGAMC16(pipe, 0), gamma[i]);
1443        I915_WRITE_FW(SPRGAMC16(pipe, 1), gamma[i]);
1444        I915_WRITE_FW(SPRGAMC16(pipe, 2), gamma[i]);
1445        i++;
1446
1447        I915_WRITE_FW(SPRGAMC17(pipe, 0), gamma[i]);
1448        I915_WRITE_FW(SPRGAMC17(pipe, 1), gamma[i]);
1449        I915_WRITE_FW(SPRGAMC17(pipe, 2), gamma[i]);
1450        i++;
1451}
1452
1453static void
1454ivb_update_plane(struct intel_plane *plane,
1455                 const struct intel_crtc_state *crtc_state,
1456                 const struct intel_plane_state *plane_state)
1457{
1458        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1459        enum pipe pipe = plane->pipe;
1460        u32 sprsurf_offset = plane_state->color_plane[0].offset;
1461        u32 linear_offset;
1462        const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1463        int crtc_x = plane_state->base.dst.x1;
1464        int crtc_y = plane_state->base.dst.y1;
1465        u32 crtc_w = drm_rect_width(&plane_state->base.dst);
1466        u32 crtc_h = drm_rect_height(&plane_state->base.dst);
1467        u32 x = plane_state->color_plane[0].x;
1468        u32 y = plane_state->color_plane[0].y;
1469        u32 src_w = drm_rect_width(&plane_state->base.src) >> 16;
1470        u32 src_h = drm_rect_height(&plane_state->base.src) >> 16;
1471        u32 sprctl, sprscale = 0;
1472        unsigned long irqflags;
1473
1474        sprctl = plane_state->ctl | ivb_sprite_ctl_crtc(crtc_state);
1475
1476        /* Sizes are 0 based */
1477        src_w--;
1478        src_h--;
1479        crtc_w--;
1480        crtc_h--;
1481
1482        if (crtc_w != src_w || crtc_h != src_h)
1483                sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
1484
1485        linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
1486
1487        spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1488
1489        I915_WRITE_FW(SPRSTRIDE(pipe), plane_state->color_plane[0].stride);
1490        I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
1491        I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
1492        if (IS_IVYBRIDGE(dev_priv))
1493                I915_WRITE_FW(SPRSCALE(pipe), sprscale);
1494
1495        if (key->flags) {
1496                I915_WRITE_FW(SPRKEYVAL(pipe), key->min_value);
1497                I915_WRITE_FW(SPRKEYMSK(pipe), key->channel_mask);
1498                I915_WRITE_FW(SPRKEYMAX(pipe), key->max_value);
1499        }
1500
1501        /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
1502         * register */
1503        if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
1504                I915_WRITE_FW(SPROFFSET(pipe), (y << 16) | x);
1505        } else {
1506                I915_WRITE_FW(SPRLINOFF(pipe), linear_offset);
1507                I915_WRITE_FW(SPRTILEOFF(pipe), (y << 16) | x);
1508        }
1509
1510        /*
1511         * The control register self-arms if the plane was previously
1512         * disabled. Try to make the plane enable atomic by writing
1513         * the control register just before the surface register.
1514         */
1515        I915_WRITE_FW(SPRCTL(pipe), sprctl);
1516        I915_WRITE_FW(SPRSURF(pipe),
1517                      intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
1518
1519        ivb_update_gamma(plane_state);
1520
1521        spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1522}
1523
1524static void
1525ivb_disable_plane(struct intel_plane *plane,
1526                  const struct intel_crtc_state *crtc_state)
1527{
1528        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1529        enum pipe pipe = plane->pipe;
1530        unsigned long irqflags;
1531
1532        spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1533
1534        I915_WRITE_FW(SPRCTL(pipe), 0);
1535        /* Disable the scaler */
1536        if (IS_IVYBRIDGE(dev_priv))
1537                I915_WRITE_FW(SPRSCALE(pipe), 0);
1538        I915_WRITE_FW(SPRSURF(pipe), 0);
1539
1540        spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1541}
1542
1543static bool
1544ivb_plane_get_hw_state(struct intel_plane *plane,
1545                       enum pipe *pipe)
1546{
1547        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1548        enum intel_display_power_domain power_domain;
1549        intel_wakeref_t wakeref;
1550        bool ret;
1551
1552        power_domain = POWER_DOMAIN_PIPE(plane->pipe);
1553        wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
1554        if (!wakeref)
1555                return false;
1556
1557        ret =  I915_READ(SPRCTL(plane->pipe)) & SPRITE_ENABLE;
1558
1559        *pipe = plane->pipe;
1560
1561        intel_display_power_put(dev_priv, power_domain, wakeref);
1562
1563        return ret;
1564}
1565
1566static int g4x_sprite_min_cdclk(const struct intel_crtc_state *crtc_state,
1567                                const struct intel_plane_state *plane_state)
1568{
1569        const struct drm_framebuffer *fb = plane_state->base.fb;
1570        unsigned int hscale, pixel_rate;
1571        unsigned int limit, decimate;
1572
1573        /*
1574         * Note that crtc_state->pixel_rate accounts for both
1575         * horizontal and vertical panel fitter downscaling factors.
1576         * Pre-HSW bspec tells us to only consider the horizontal
1577         * downscaling factor here. We ignore that and just consider
1578         * both for simplicity.
1579         */
1580        pixel_rate = crtc_state->pixel_rate;
1581
1582        /* Horizontal downscaling limits the maximum pixel rate */
1583        hscale = drm_rect_calc_hscale(&plane_state->base.src,
1584                                      &plane_state->base.dst,
1585                                      0, INT_MAX);
1586        if (hscale < 0x10000)
1587                return pixel_rate;
1588
1589        /* Decimation steps at 2x,4x,8x,16x */
1590        decimate = ilog2(hscale >> 16);
1591        hscale >>= decimate;
1592
1593        /* Starting limit is 90% of cdclk */
1594        limit = 9;
1595
1596        /* -10% per decimation step */
1597        limit -= decimate;
1598
1599        /* -10% for RGB */
1600        if (fb->format->cpp[0] >= 4)
1601                limit--; /* -10% for RGB */
1602
1603        /*
1604         * We should also do -10% if sprite scaling is enabled
1605         * on the other pipe, but we can't really check for that,
1606         * so we ignore it.
1607         */
1608
1609        return DIV_ROUND_UP_ULL(mul_u32_u32(pixel_rate, 10 * hscale),
1610                                limit << 16);
1611}
1612
1613static unsigned int
1614g4x_sprite_max_stride(struct intel_plane *plane,
1615                      u32 pixel_format, u64 modifier,
1616                      unsigned int rotation)
1617{
1618        return 16384;
1619}
1620
1621static u32 g4x_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
1622{
1623        u32 dvscntr = 0;
1624
1625        if (crtc_state->gamma_enable)
1626                dvscntr |= DVS_GAMMA_ENABLE;
1627
1628        if (crtc_state->csc_enable)
1629                dvscntr |= DVS_PIPE_CSC_ENABLE;
1630
1631        return dvscntr;
1632}
1633
1634static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state,
1635                          const struct intel_plane_state *plane_state)
1636{
1637        struct drm_i915_private *dev_priv =
1638                to_i915(plane_state->base.plane->dev);
1639        const struct drm_framebuffer *fb = plane_state->base.fb;
1640        unsigned int rotation = plane_state->base.rotation;
1641        const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1642        u32 dvscntr;
1643
1644        dvscntr = DVS_ENABLE;
1645
1646        if (IS_GEN(dev_priv, 6))
1647                dvscntr |= DVS_TRICKLE_FEED_DISABLE;
1648
1649        switch (fb->format->format) {
1650        case DRM_FORMAT_XBGR8888:
1651                dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR;
1652                break;
1653        case DRM_FORMAT_XRGB8888:
1654                dvscntr |= DVS_FORMAT_RGBX888;
1655                break;
1656        case DRM_FORMAT_XBGR16161616F:
1657                dvscntr |= DVS_FORMAT_RGBX161616 | DVS_RGB_ORDER_XBGR;
1658                break;
1659        case DRM_FORMAT_XRGB16161616F:
1660                dvscntr |= DVS_FORMAT_RGBX161616;
1661                break;
1662        case DRM_FORMAT_YUYV:
1663                dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
1664                break;
1665        case DRM_FORMAT_YVYU:
1666                dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
1667                break;
1668        case DRM_FORMAT_UYVY:
1669                dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
1670                break;
1671        case DRM_FORMAT_VYUY:
1672                dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
1673                break;
1674        default:
1675                MISSING_CASE(fb->format->format);
1676                return 0;
1677        }
1678
1679        if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
1680                dvscntr |= DVS_YUV_FORMAT_BT709;
1681
1682        if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
1683                dvscntr |= DVS_YUV_RANGE_CORRECTION_DISABLE;
1684
1685        if (fb->modifier == I915_FORMAT_MOD_X_TILED)
1686                dvscntr |= DVS_TILED;
1687
1688        if (rotation & DRM_MODE_ROTATE_180)
1689                dvscntr |= DVS_ROTATE_180;
1690
1691        if (key->flags & I915_SET_COLORKEY_DESTINATION)
1692                dvscntr |= DVS_DEST_KEY;
1693        else if (key->flags & I915_SET_COLORKEY_SOURCE)
1694                dvscntr |= DVS_SOURCE_KEY;
1695
1696        return dvscntr;
1697}
1698
1699static void g4x_update_gamma(const struct intel_plane_state *plane_state)
1700{
1701        struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1702        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1703        const struct drm_framebuffer *fb = plane_state->base.fb;
1704        enum pipe pipe = plane->pipe;
1705        u16 gamma[8];
1706        int i;
1707
1708        /* Seems RGB data bypasses the gamma always */
1709        if (!fb->format->is_yuv)
1710                return;
1711
1712        i9xx_plane_linear_gamma(gamma);
1713
1714        /* FIXME these register are single buffered :( */
1715        /* The two end points are implicit (0.0 and 1.0) */
1716        for (i = 1; i < 8 - 1; i++)
1717                I915_WRITE_FW(DVSGAMC_G4X(pipe, i - 1),
1718                              gamma[i] << 16 |
1719                              gamma[i] << 8 |
1720                              gamma[i]);
1721}
1722
1723static void ilk_sprite_linear_gamma(u16 gamma[17])
1724{
1725        int i;
1726
1727        for (i = 0; i < 17; i++)
1728                gamma[i] = (i << 10) / 16;
1729}
1730
1731static void ilk_update_gamma(const struct intel_plane_state *plane_state)
1732{
1733        struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1734        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1735        const struct drm_framebuffer *fb = plane_state->base.fb;
1736        enum pipe pipe = plane->pipe;
1737        u16 gamma[17];
1738        int i;
1739
1740        /* Seems RGB data bypasses the gamma always */
1741        if (!fb->format->is_yuv)
1742                return;
1743
1744        ilk_sprite_linear_gamma(gamma);
1745
1746        /* FIXME these register are single buffered :( */
1747        for (i = 0; i < 16; i++)
1748                I915_WRITE_FW(DVSGAMC_ILK(pipe, i),
1749                              gamma[i] << 20 |
1750                              gamma[i] << 10 |
1751                              gamma[i]);
1752
1753        I915_WRITE_FW(DVSGAMCMAX_ILK(pipe, 0), gamma[i]);
1754        I915_WRITE_FW(DVSGAMCMAX_ILK(pipe, 1), gamma[i]);
1755        I915_WRITE_FW(DVSGAMCMAX_ILK(pipe, 2), gamma[i]);
1756        i++;
1757}
1758
1759static void
1760g4x_update_plane(struct intel_plane *plane,
1761                 const struct intel_crtc_state *crtc_state,
1762                 const struct intel_plane_state *plane_state)
1763{
1764        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1765        enum pipe pipe = plane->pipe;
1766        u32 dvssurf_offset = plane_state->color_plane[0].offset;
1767        u32 linear_offset;
1768        const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1769        int crtc_x = plane_state->base.dst.x1;
1770        int crtc_y = plane_state->base.dst.y1;
1771        u32 crtc_w = drm_rect_width(&plane_state->base.dst);
1772        u32 crtc_h = drm_rect_height(&plane_state->base.dst);
1773        u32 x = plane_state->color_plane[0].x;
1774        u32 y = plane_state->color_plane[0].y;
1775        u32 src_w = drm_rect_width(&plane_state->base.src) >> 16;
1776        u32 src_h = drm_rect_height(&plane_state->base.src) >> 16;
1777        u32 dvscntr, dvsscale = 0;
1778        unsigned long irqflags;
1779
1780        dvscntr = plane_state->ctl | g4x_sprite_ctl_crtc(crtc_state);
1781
1782        /* Sizes are 0 based */
1783        src_w--;
1784        src_h--;
1785        crtc_w--;
1786        crtc_h--;
1787
1788        if (crtc_w != src_w || crtc_h != src_h)
1789                dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h;
1790
1791        linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
1792
1793        spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1794
1795        I915_WRITE_FW(DVSSTRIDE(pipe), plane_state->color_plane[0].stride);
1796        I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
1797        I915_WRITE_FW(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
1798        I915_WRITE_FW(DVSSCALE(pipe), dvsscale);
1799
1800        if (key->flags) {
1801                I915_WRITE_FW(DVSKEYVAL(pipe), key->min_value);
1802                I915_WRITE_FW(DVSKEYMSK(pipe), key->channel_mask);
1803                I915_WRITE_FW(DVSKEYMAX(pipe), key->max_value);
1804        }
1805
1806        I915_WRITE_FW(DVSLINOFF(pipe), linear_offset);
1807        I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x);
1808
1809        /*
1810         * The control register self-arms if the plane was previously
1811         * disabled. Try to make the plane enable atomic by writing
1812         * the control register just before the surface register.
1813         */
1814        I915_WRITE_FW(DVSCNTR(pipe), dvscntr);
1815        I915_WRITE_FW(DVSSURF(pipe),
1816                      intel_plane_ggtt_offset(plane_state) + dvssurf_offset);
1817
1818        if (IS_G4X(dev_priv))
1819                g4x_update_gamma(plane_state);
1820        else
1821                ilk_update_gamma(plane_state);
1822
1823        spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1824}
1825
1826static void
1827g4x_disable_plane(struct intel_plane *plane,
1828                  const struct intel_crtc_state *crtc_state)
1829{
1830        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1831        enum pipe pipe = plane->pipe;
1832        unsigned long irqflags;
1833
1834        spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1835
1836        I915_WRITE_FW(DVSCNTR(pipe), 0);
1837        /* Disable the scaler */
1838        I915_WRITE_FW(DVSSCALE(pipe), 0);
1839        I915_WRITE_FW(DVSSURF(pipe), 0);
1840
1841        spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1842}
1843
1844static bool
1845g4x_plane_get_hw_state(struct intel_plane *plane,
1846                       enum pipe *pipe)
1847{
1848        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1849        enum intel_display_power_domain power_domain;
1850        intel_wakeref_t wakeref;
1851        bool ret;
1852
1853        power_domain = POWER_DOMAIN_PIPE(plane->pipe);
1854        wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
1855        if (!wakeref)
1856                return false;
1857
1858        ret = I915_READ(DVSCNTR(plane->pipe)) & DVS_ENABLE;
1859
1860        *pipe = plane->pipe;
1861
1862        intel_display_power_put(dev_priv, power_domain, wakeref);
1863
1864        return ret;
1865}
1866
1867static bool intel_fb_scalable(const struct drm_framebuffer *fb)
1868{
1869        if (!fb)
1870                return false;
1871
1872        switch (fb->format->format) {
1873        case DRM_FORMAT_C8:
1874                return false;
1875        case DRM_FORMAT_XRGB16161616F:
1876        case DRM_FORMAT_ARGB16161616F:
1877        case DRM_FORMAT_XBGR16161616F:
1878        case DRM_FORMAT_ABGR16161616F:
1879                return INTEL_GEN(to_i915(fb->dev)) >= 11;
1880        default:
1881                return true;
1882        }
1883}
1884
1885static int
1886g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state,
1887                         struct intel_plane_state *plane_state)
1888{
1889        const struct drm_framebuffer *fb = plane_state->base.fb;
1890        const struct drm_rect *src = &plane_state->base.src;
1891        const struct drm_rect *dst = &plane_state->base.dst;
1892        int src_x, src_w, src_h, crtc_w, crtc_h;
1893        const struct drm_display_mode *adjusted_mode =
1894                &crtc_state->base.adjusted_mode;
1895        unsigned int stride = plane_state->color_plane[0].stride;
1896        unsigned int cpp = fb->format->cpp[0];
1897        unsigned int width_bytes;
1898        int min_width, min_height;
1899
1900        crtc_w = drm_rect_width(dst);
1901        crtc_h = drm_rect_height(dst);
1902
1903        src_x = src->x1 >> 16;
1904        src_w = drm_rect_width(src) >> 16;
1905        src_h = drm_rect_height(src) >> 16;
1906
1907        if (src_w == crtc_w && src_h == crtc_h)
1908                return 0;
1909
1910        min_width = 3;
1911
1912        if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
1913                if (src_h & 1) {
1914                        DRM_DEBUG_KMS("Source height must be even with interlaced modes\n");
1915                        return -EINVAL;
1916                }
1917                min_height = 6;
1918        } else {
1919                min_height = 3;
1920        }
1921
1922        width_bytes = ((src_x * cpp) & 63) + src_w * cpp;
1923
1924        if (src_w < min_width || src_h < min_height ||
1925            src_w > 2048 || src_h > 2048) {
1926                DRM_DEBUG_KMS("Source dimensions (%dx%d) exceed hardware limits (%dx%d - %dx%d)\n",
1927                              src_w, src_h, min_width, min_height, 2048, 2048);
1928                return -EINVAL;
1929        }
1930
1931        if (width_bytes > 4096) {
1932                DRM_DEBUG_KMS("Fetch width (%d) exceeds hardware max with scaling (%u)\n",
1933                              width_bytes, 4096);
1934                return -EINVAL;
1935        }
1936
1937        if (stride > 4096) {
1938                DRM_DEBUG_KMS("Stride (%u) exceeds hardware max with scaling (%u)\n",
1939                              stride, 4096);
1940                return -EINVAL;
1941        }
1942
1943        return 0;
1944}
1945
1946static int
1947g4x_sprite_check(struct intel_crtc_state *crtc_state,
1948                 struct intel_plane_state *plane_state)
1949{
1950        struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1951        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1952        int min_scale = DRM_PLANE_HELPER_NO_SCALING;
1953        int max_scale = DRM_PLANE_HELPER_NO_SCALING;
1954        int ret;
1955
1956        if (intel_fb_scalable(plane_state->base.fb)) {
1957                if (INTEL_GEN(dev_priv) < 7) {
1958                        min_scale = 1;
1959                        max_scale = 16 << 16;
1960                } else if (IS_IVYBRIDGE(dev_priv)) {
1961                        min_scale = 1;
1962                        max_scale = 2 << 16;
1963                }
1964        }
1965
1966        ret = drm_atomic_helper_check_plane_state(&plane_state->base,
1967                                                  &crtc_state->base,
1968                                                  min_scale, max_scale,
1969                                                  true, true);
1970        if (ret)
1971                return ret;
1972
1973        ret = i9xx_check_plane_surface(plane_state);
1974        if (ret)
1975                return ret;
1976
1977        if (!plane_state->base.visible)
1978                return 0;
1979
1980        ret = intel_plane_check_src_coordinates(plane_state);
1981        if (ret)
1982                return ret;
1983
1984        ret = g4x_sprite_check_scaling(crtc_state, plane_state);
1985        if (ret)
1986                return ret;
1987
1988        if (INTEL_GEN(dev_priv) >= 7)
1989                plane_state->ctl = ivb_sprite_ctl(crtc_state, plane_state);
1990        else
1991                plane_state->ctl = g4x_sprite_ctl(crtc_state, plane_state);
1992
1993        return 0;
1994}
1995
1996int chv_plane_check_rotation(const struct intel_plane_state *plane_state)
1997{
1998        struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1999        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
2000        unsigned int rotation = plane_state->base.rotation;
2001
2002        /* CHV ignores the mirror bit when the rotate bit is set :( */
2003        if (IS_CHERRYVIEW(dev_priv) &&
2004            rotation & DRM_MODE_ROTATE_180 &&
2005            rotation & DRM_MODE_REFLECT_X) {
2006                DRM_DEBUG_KMS("Cannot rotate and reflect at the same time\n");
2007                return -EINVAL;
2008        }
2009
2010        return 0;
2011}
2012
2013static int
2014vlv_sprite_check(struct intel_crtc_state *crtc_state,
2015                 struct intel_plane_state *plane_state)
2016{
2017        int ret;
2018
2019        ret = chv_plane_check_rotation(plane_state);
2020        if (ret)
2021                return ret;
2022
2023        ret = drm_atomic_helper_check_plane_state(&plane_state->base,
2024                                                  &crtc_state->base,
2025                                                  DRM_PLANE_HELPER_NO_SCALING,
2026                                                  DRM_PLANE_HELPER_NO_SCALING,
2027                                                  true, true);
2028        if (ret)
2029                return ret;
2030
2031        ret = i9xx_check_plane_surface(plane_state);
2032        if (ret)
2033                return ret;
2034
2035        if (!plane_state->base.visible)
2036                return 0;
2037
2038        ret = intel_plane_check_src_coordinates(plane_state);
2039        if (ret)
2040                return ret;
2041
2042        plane_state->ctl = vlv_sprite_ctl(crtc_state, plane_state);
2043
2044        return 0;
2045}
2046
2047static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
2048                              const struct intel_plane_state *plane_state)
2049{
2050        struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
2051        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
2052        const struct drm_framebuffer *fb = plane_state->base.fb;
2053        unsigned int rotation = plane_state->base.rotation;
2054        struct drm_format_name_buf format_name;
2055
2056        if (!fb)
2057                return 0;
2058
2059        if (rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180) &&
2060            is_ccs_modifier(fb->modifier)) {
2061                DRM_DEBUG_KMS("RC support only with 0/180 degree rotation (%x)\n",
2062                              rotation);
2063                return -EINVAL;
2064        }
2065
2066        if (rotation & DRM_MODE_REFLECT_X &&
2067            fb->modifier == DRM_FORMAT_MOD_LINEAR) {
2068                DRM_DEBUG_KMS("horizontal flip is not supported with linear surface formats\n");
2069                return -EINVAL;
2070        }
2071
2072        if (drm_rotation_90_or_270(rotation)) {
2073                if (fb->modifier != I915_FORMAT_MOD_Y_TILED &&
2074                    fb->modifier != I915_FORMAT_MOD_Yf_TILED) {
2075                        DRM_DEBUG_KMS("Y/Yf tiling required for 90/270!\n");
2076                        return -EINVAL;
2077                }
2078
2079                /*
2080                 * 90/270 is not allowed with RGB64 16:16:16:16 and
2081                 * Indexed 8-bit. RGB 16-bit 5:6:5 is allowed gen11 onwards.
2082                 */
2083                switch (fb->format->format) {
2084                case DRM_FORMAT_RGB565:
2085                        if (INTEL_GEN(dev_priv) >= 11)
2086                                break;
2087                        /* fall through */
2088                case DRM_FORMAT_C8:
2089                case DRM_FORMAT_XRGB16161616F:
2090                case DRM_FORMAT_XBGR16161616F:
2091                case DRM_FORMAT_ARGB16161616F:
2092                case DRM_FORMAT_ABGR16161616F:
2093                case DRM_FORMAT_Y210:
2094                case DRM_FORMAT_Y212:
2095                case DRM_FORMAT_Y216:
2096                case DRM_FORMAT_XVYU12_16161616:
2097                case DRM_FORMAT_XVYU16161616:
2098                        DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n",
2099                                      drm_get_format_name(fb->format->format,
2100                                                          &format_name));
2101                        return -EINVAL;
2102                default:
2103                        break;
2104                }
2105        }
2106
2107        /* Y-tiling is not supported in IF-ID Interlace mode */
2108        if (crtc_state->base.enable &&
2109            crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE &&
2110            (fb->modifier == I915_FORMAT_MOD_Y_TILED ||
2111             fb->modifier == I915_FORMAT_MOD_Yf_TILED ||
2112             fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
2113             fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS)) {
2114                DRM_DEBUG_KMS("Y/Yf tiling not supported in IF-ID mode\n");
2115                return -EINVAL;
2116        }
2117
2118        return 0;
2119}
2120
2121static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_state,
2122                                           const struct intel_plane_state *plane_state)
2123{
2124        struct drm_i915_private *dev_priv =
2125                to_i915(plane_state->base.plane->dev);
2126        int crtc_x = plane_state->base.dst.x1;
2127        int crtc_w = drm_rect_width(&plane_state->base.dst);
2128        int pipe_src_w = crtc_state->pipe_src_w;
2129
2130        /*
2131         * Display WA #1175: cnl,glk
2132         * Planes other than the cursor may cause FIFO underflow and display
2133         * corruption if starting less than 4 pixels from the right edge of
2134         * the screen.
2135         * Besides the above WA fix the similar problem, where planes other
2136         * than the cursor ending less than 4 pixels from the left edge of the
2137         * screen may cause FIFO underflow and display corruption.
2138         */
2139        if ((IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) &&
2140            (crtc_x + crtc_w < 4 || crtc_x > pipe_src_w - 4)) {
2141                DRM_DEBUG_KMS("requested plane X %s position %d invalid (valid range %d-%d)\n",
2142                              crtc_x + crtc_w < 4 ? "end" : "start",
2143                              crtc_x + crtc_w < 4 ? crtc_x + crtc_w : crtc_x,
2144                              4, pipe_src_w - 4);
2145                return -ERANGE;
2146        }
2147
2148        return 0;
2149}
2150
2151static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_state)
2152{
2153        const struct drm_framebuffer *fb = plane_state->base.fb;
2154        unsigned int rotation = plane_state->base.rotation;
2155        int src_w = drm_rect_width(&plane_state->base.src) >> 16;
2156
2157        /* Display WA #1106 */
2158        if (drm_format_info_is_yuv_semiplanar(fb->format) && src_w & 3 &&
2159            (rotation == DRM_MODE_ROTATE_270 ||
2160             rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) {
2161                DRM_DEBUG_KMS("src width must be multiple of 4 for rotated planar YUV\n");
2162                return -EINVAL;
2163        }
2164
2165        return 0;
2166}
2167
2168static int skl_plane_max_scale(struct drm_i915_private *dev_priv,
2169                               const struct drm_framebuffer *fb)
2170{
2171        /*
2172         * We don't yet know the final source width nor
2173         * whether we can use the HQ scaler mode. Assume
2174         * the best case.
2175         * FIXME need to properly check this later.
2176         */
2177        if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv) ||
2178            !drm_format_info_is_yuv_semiplanar(fb->format))
2179                return 0x30000 - 1;
2180        else
2181                return 0x20000 - 1;
2182}
2183
2184static int skl_plane_check(struct intel_crtc_state *crtc_state,
2185                           struct intel_plane_state *plane_state)
2186{
2187        struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
2188        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
2189        const struct drm_framebuffer *fb = plane_state->base.fb;
2190        int min_scale = DRM_PLANE_HELPER_NO_SCALING;
2191        int max_scale = DRM_PLANE_HELPER_NO_SCALING;
2192        int ret;
2193
2194        ret = skl_plane_check_fb(crtc_state, plane_state);
2195        if (ret)
2196                return ret;
2197
2198        /* use scaler when colorkey is not required */
2199        if (!plane_state->ckey.flags && intel_fb_scalable(fb)) {
2200                min_scale = 1;
2201                max_scale = skl_plane_max_scale(dev_priv, fb);
2202        }
2203
2204        ret = drm_atomic_helper_check_plane_state(&plane_state->base,
2205                                                  &crtc_state->base,
2206                                                  min_scale, max_scale,
2207                                                  true, true);
2208        if (ret)
2209                return ret;
2210
2211        ret = skl_check_plane_surface(plane_state);
2212        if (ret)
2213                return ret;
2214
2215        if (!plane_state->base.visible)
2216                return 0;
2217
2218        ret = skl_plane_check_dst_coordinates(crtc_state, plane_state);
2219        if (ret)
2220                return ret;
2221
2222        ret = intel_plane_check_src_coordinates(plane_state);
2223        if (ret)
2224                return ret;
2225
2226        ret = skl_plane_check_nv12_rotation(plane_state);
2227        if (ret)
2228                return ret;
2229
2230        /* HW only has 8 bits pixel precision, disable plane if invisible */
2231        if (!(plane_state->base.alpha >> 8))
2232                plane_state->base.visible = false;
2233
2234        plane_state->ctl = skl_plane_ctl(crtc_state, plane_state);
2235
2236        if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
2237                plane_state->color_ctl = glk_plane_color_ctl(crtc_state,
2238                                                             plane_state);
2239
2240        return 0;
2241}
2242
2243static bool has_dst_key_in_primary_plane(struct drm_i915_private *dev_priv)
2244{
2245        return INTEL_GEN(dev_priv) >= 9;
2246}
2247
2248static void intel_plane_set_ckey(struct intel_plane_state *plane_state,
2249                                 const struct drm_intel_sprite_colorkey *set)
2250{
2251        struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
2252        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
2253        struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
2254
2255        *key = *set;
2256
2257        /*
2258         * We want src key enabled on the
2259         * sprite and not on the primary.
2260         */
2261        if (plane->id == PLANE_PRIMARY &&
2262            set->flags & I915_SET_COLORKEY_SOURCE)
2263                key->flags = 0;
2264
2265        /*
2266         * On SKL+ we want dst key enabled on
2267         * the primary and not on the sprite.
2268         */
2269        if (INTEL_GEN(dev_priv) >= 9 && plane->id != PLANE_PRIMARY &&
2270            set->flags & I915_SET_COLORKEY_DESTINATION)
2271                key->flags = 0;
2272}
2273
2274int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
2275                                    struct drm_file *file_priv)
2276{
2277        struct drm_i915_private *dev_priv = to_i915(dev);
2278        struct drm_intel_sprite_colorkey *set = data;
2279        struct drm_plane *plane;
2280        struct drm_plane_state *plane_state;
2281        struct drm_atomic_state *state;
2282        struct drm_modeset_acquire_ctx ctx;
2283        int ret = 0;
2284
2285        /* ignore the pointless "none" flag */
2286        set->flags &= ~I915_SET_COLORKEY_NONE;
2287
2288        if (set->flags & ~(I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
2289                return -EINVAL;
2290
2291        /* Make sure we don't try to enable both src & dest simultaneously */
2292        if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
2293                return -EINVAL;
2294
2295        if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
2296            set->flags & I915_SET_COLORKEY_DESTINATION)
2297                return -EINVAL;
2298
2299        plane = drm_plane_find(dev, file_priv, set->plane_id);
2300        if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY)
2301                return -ENOENT;
2302
2303        /*
2304         * SKL+ only plane 2 can do destination keying against plane 1.
2305         * Also multiple planes can't do destination keying on the same
2306         * pipe simultaneously.
2307         */
2308        if (INTEL_GEN(dev_priv) >= 9 &&
2309            to_intel_plane(plane)->id >= PLANE_SPRITE1 &&
2310            set->flags & I915_SET_COLORKEY_DESTINATION)
2311                return -EINVAL;
2312
2313        drm_modeset_acquire_init(&ctx, 0);
2314
2315        state = drm_atomic_state_alloc(plane->dev);
2316        if (!state) {
2317                ret = -ENOMEM;
2318                goto out;
2319        }
2320        state->acquire_ctx = &ctx;
2321
2322        while (1) {
2323                plane_state = drm_atomic_get_plane_state(state, plane);
2324                ret = PTR_ERR_OR_ZERO(plane_state);
2325                if (!ret)
2326                        intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
2327
2328                /*
2329                 * On some platforms we have to configure
2330                 * the dst colorkey on the primary plane.
2331                 */
2332                if (!ret && has_dst_key_in_primary_plane(dev_priv)) {
2333                        struct intel_crtc *crtc =
2334                                intel_get_crtc_for_pipe(dev_priv,
2335                                                        to_intel_plane(plane)->pipe);
2336
2337                        plane_state = drm_atomic_get_plane_state(state,
2338                                                                 crtc->base.primary);
2339                        ret = PTR_ERR_OR_ZERO(plane_state);
2340                        if (!ret)
2341                                intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
2342                }
2343
2344                if (!ret)
2345                        ret = drm_atomic_commit(state);
2346
2347                if (ret != -EDEADLK)
2348                        break;
2349
2350                drm_atomic_state_clear(state);
2351                drm_modeset_backoff(&ctx);
2352        }
2353
2354        drm_atomic_state_put(state);
2355out:
2356        drm_modeset_drop_locks(&ctx);
2357        drm_modeset_acquire_fini(&ctx);
2358        return ret;
2359}
2360
2361static const u32 g4x_plane_formats[] = {
2362        DRM_FORMAT_XRGB8888,
2363        DRM_FORMAT_YUYV,
2364        DRM_FORMAT_YVYU,
2365        DRM_FORMAT_UYVY,
2366        DRM_FORMAT_VYUY,
2367};
2368
2369static const u64 i9xx_plane_format_modifiers[] = {
2370        I915_FORMAT_MOD_X_TILED,
2371        DRM_FORMAT_MOD_LINEAR,
2372        DRM_FORMAT_MOD_INVALID
2373};
2374
2375static const u32 snb_plane_formats[] = {
2376        DRM_FORMAT_XRGB8888,
2377        DRM_FORMAT_XBGR8888,
2378        DRM_FORMAT_XRGB16161616F,
2379        DRM_FORMAT_XBGR16161616F,
2380        DRM_FORMAT_YUYV,
2381        DRM_FORMAT_YVYU,
2382        DRM_FORMAT_UYVY,
2383        DRM_FORMAT_VYUY,
2384};
2385
2386static const u32 vlv_plane_formats[] = {
2387        DRM_FORMAT_RGB565,
2388        DRM_FORMAT_ABGR8888,
2389        DRM_FORMAT_ARGB8888,
2390        DRM_FORMAT_XBGR8888,
2391        DRM_FORMAT_XRGB8888,
2392        DRM_FORMAT_XBGR2101010,
2393        DRM_FORMAT_ABGR2101010,
2394        DRM_FORMAT_YUYV,
2395        DRM_FORMAT_YVYU,
2396        DRM_FORMAT_UYVY,
2397        DRM_FORMAT_VYUY,
2398};
2399
2400static const u32 skl_plane_formats[] = {
2401        DRM_FORMAT_C8,
2402        DRM_FORMAT_RGB565,
2403        DRM_FORMAT_XRGB8888,
2404        DRM_FORMAT_XBGR8888,
2405        DRM_FORMAT_ARGB8888,
2406        DRM_FORMAT_ABGR8888,
2407        DRM_FORMAT_XRGB2101010,
2408        DRM_FORMAT_XBGR2101010,
2409        DRM_FORMAT_XRGB16161616F,
2410        DRM_FORMAT_XBGR16161616F,
2411        DRM_FORMAT_YUYV,
2412        DRM_FORMAT_YVYU,
2413        DRM_FORMAT_UYVY,
2414        DRM_FORMAT_VYUY,
2415};
2416
2417static const u32 skl_planar_formats[] = {
2418        DRM_FORMAT_C8,
2419        DRM_FORMAT_RGB565,
2420        DRM_FORMAT_XRGB8888,
2421        DRM_FORMAT_XBGR8888,
2422        DRM_FORMAT_ARGB8888,
2423        DRM_FORMAT_ABGR8888,
2424        DRM_FORMAT_XRGB2101010,
2425        DRM_FORMAT_XBGR2101010,
2426        DRM_FORMAT_XRGB16161616F,
2427        DRM_FORMAT_XBGR16161616F,
2428        DRM_FORMAT_YUYV,
2429        DRM_FORMAT_YVYU,
2430        DRM_FORMAT_UYVY,
2431        DRM_FORMAT_VYUY,
2432        DRM_FORMAT_NV12,
2433};
2434
2435static const u32 glk_planar_formats[] = {
2436        DRM_FORMAT_C8,
2437        DRM_FORMAT_RGB565,
2438        DRM_FORMAT_XRGB8888,
2439        DRM_FORMAT_XBGR8888,
2440        DRM_FORMAT_ARGB8888,
2441        DRM_FORMAT_ABGR8888,
2442        DRM_FORMAT_XRGB2101010,
2443        DRM_FORMAT_XBGR2101010,
2444        DRM_FORMAT_XRGB16161616F,
2445        DRM_FORMAT_XBGR16161616F,
2446        DRM_FORMAT_YUYV,
2447        DRM_FORMAT_YVYU,
2448        DRM_FORMAT_UYVY,
2449        DRM_FORMAT_VYUY,
2450        DRM_FORMAT_NV12,
2451        DRM_FORMAT_P010,
2452        DRM_FORMAT_P012,
2453        DRM_FORMAT_P016,
2454};
2455
2456static const u32 icl_sdr_y_plane_formats[] = {
2457        DRM_FORMAT_C8,
2458        DRM_FORMAT_RGB565,
2459        DRM_FORMAT_XRGB8888,
2460        DRM_FORMAT_XBGR8888,
2461        DRM_FORMAT_ARGB8888,
2462        DRM_FORMAT_ABGR8888,
2463        DRM_FORMAT_XRGB2101010,
2464        DRM_FORMAT_XBGR2101010,
2465        DRM_FORMAT_YUYV,
2466        DRM_FORMAT_YVYU,
2467        DRM_FORMAT_UYVY,
2468        DRM_FORMAT_VYUY,
2469        DRM_FORMAT_Y210,
2470        DRM_FORMAT_Y212,
2471        DRM_FORMAT_Y216,
2472        DRM_FORMAT_XVYU2101010,
2473        DRM_FORMAT_XVYU12_16161616,
2474        DRM_FORMAT_XVYU16161616,
2475};
2476
2477static const u32 icl_sdr_uv_plane_formats[] = {
2478        DRM_FORMAT_C8,
2479        DRM_FORMAT_RGB565,
2480        DRM_FORMAT_XRGB8888,
2481        DRM_FORMAT_XBGR8888,
2482        DRM_FORMAT_ARGB8888,
2483        DRM_FORMAT_ABGR8888,
2484        DRM_FORMAT_XRGB2101010,
2485        DRM_FORMAT_XBGR2101010,
2486        DRM_FORMAT_YUYV,
2487        DRM_FORMAT_YVYU,
2488        DRM_FORMAT_UYVY,
2489        DRM_FORMAT_VYUY,
2490        DRM_FORMAT_NV12,
2491        DRM_FORMAT_P010,
2492        DRM_FORMAT_P012,
2493        DRM_FORMAT_P016,
2494        DRM_FORMAT_Y210,
2495        DRM_FORMAT_Y212,
2496        DRM_FORMAT_Y216,
2497        DRM_FORMAT_XVYU2101010,
2498        DRM_FORMAT_XVYU12_16161616,
2499        DRM_FORMAT_XVYU16161616,
2500};
2501
2502static const u32 icl_hdr_plane_formats[] = {
2503        DRM_FORMAT_C8,
2504        DRM_FORMAT_RGB565,
2505        DRM_FORMAT_XRGB8888,
2506        DRM_FORMAT_XBGR8888,
2507        DRM_FORMAT_ARGB8888,
2508        DRM_FORMAT_ABGR8888,
2509        DRM_FORMAT_XRGB2101010,
2510        DRM_FORMAT_XBGR2101010,
2511        DRM_FORMAT_XRGB16161616F,
2512        DRM_FORMAT_XBGR16161616F,
2513        DRM_FORMAT_ARGB16161616F,
2514        DRM_FORMAT_ABGR16161616F,
2515        DRM_FORMAT_YUYV,
2516        DRM_FORMAT_YVYU,
2517        DRM_FORMAT_UYVY,
2518        DRM_FORMAT_VYUY,
2519        DRM_FORMAT_NV12,
2520        DRM_FORMAT_P010,
2521        DRM_FORMAT_P012,
2522        DRM_FORMAT_P016,
2523        DRM_FORMAT_Y210,
2524        DRM_FORMAT_Y212,
2525        DRM_FORMAT_Y216,
2526        DRM_FORMAT_XVYU2101010,
2527        DRM_FORMAT_XVYU12_16161616,
2528        DRM_FORMAT_XVYU16161616,
2529};
2530
2531static const u64 skl_plane_format_modifiers_noccs[] = {
2532        I915_FORMAT_MOD_Yf_TILED,
2533        I915_FORMAT_MOD_Y_TILED,
2534        I915_FORMAT_MOD_X_TILED,
2535        DRM_FORMAT_MOD_LINEAR,
2536        DRM_FORMAT_MOD_INVALID
2537};
2538
2539static const u64 skl_plane_format_modifiers_ccs[] = {
2540        I915_FORMAT_MOD_Yf_TILED_CCS,
2541        I915_FORMAT_MOD_Y_TILED_CCS,
2542        I915_FORMAT_MOD_Yf_TILED,
2543        I915_FORMAT_MOD_Y_TILED,
2544        I915_FORMAT_MOD_X_TILED,
2545        DRM_FORMAT_MOD_LINEAR,
2546        DRM_FORMAT_MOD_INVALID
2547};
2548
2549static const u64 gen12_plane_format_modifiers_noccs[] = {
2550        I915_FORMAT_MOD_Y_TILED,
2551        I915_FORMAT_MOD_X_TILED,
2552        DRM_FORMAT_MOD_LINEAR,
2553        DRM_FORMAT_MOD_INVALID
2554};
2555
2556static bool g4x_sprite_format_mod_supported(struct drm_plane *_plane,
2557                                            u32 format, u64 modifier)
2558{
2559        switch (modifier) {
2560        case DRM_FORMAT_MOD_LINEAR:
2561        case I915_FORMAT_MOD_X_TILED:
2562                break;
2563        default:
2564                return false;
2565        }
2566
2567        switch (format) {
2568        case DRM_FORMAT_XRGB8888:
2569        case DRM_FORMAT_YUYV:
2570        case DRM_FORMAT_YVYU:
2571        case DRM_FORMAT_UYVY:
2572        case DRM_FORMAT_VYUY:
2573                if (modifier == DRM_FORMAT_MOD_LINEAR ||
2574                    modifier == I915_FORMAT_MOD_X_TILED)
2575                        return true;
2576                /* fall through */
2577        default:
2578                return false;
2579        }
2580}
2581
2582static bool snb_sprite_format_mod_supported(struct drm_plane *_plane,
2583                                            u32 format, u64 modifier)
2584{
2585        switch (modifier) {
2586        case DRM_FORMAT_MOD_LINEAR:
2587        case I915_FORMAT_MOD_X_TILED:
2588                break;
2589        default:
2590                return false;
2591        }
2592
2593        switch (format) {
2594        case DRM_FORMAT_XRGB8888:
2595        case DRM_FORMAT_XBGR8888:
2596        case DRM_FORMAT_XRGB16161616F:
2597        case DRM_FORMAT_XBGR16161616F:
2598        case DRM_FORMAT_YUYV:
2599        case DRM_FORMAT_YVYU:
2600        case DRM_FORMAT_UYVY:
2601        case DRM_FORMAT_VYUY:
2602                if (modifier == DRM_FORMAT_MOD_LINEAR ||
2603                    modifier == I915_FORMAT_MOD_X_TILED)
2604                        return true;
2605                /* fall through */
2606        default:
2607                return false;
2608        }
2609}
2610
2611static bool vlv_sprite_format_mod_supported(struct drm_plane *_plane,
2612                                            u32 format, u64 modifier)
2613{
2614        switch (modifier) {
2615        case DRM_FORMAT_MOD_LINEAR:
2616        case I915_FORMAT_MOD_X_TILED:
2617                break;
2618        default:
2619                return false;
2620        }
2621
2622        switch (format) {
2623        case DRM_FORMAT_RGB565:
2624        case DRM_FORMAT_ABGR8888:
2625        case DRM_FORMAT_ARGB8888:
2626        case DRM_FORMAT_XBGR8888:
2627        case DRM_FORMAT_XRGB8888:
2628        case DRM_FORMAT_XBGR2101010:
2629        case DRM_FORMAT_ABGR2101010:
2630        case DRM_FORMAT_YUYV:
2631        case DRM_FORMAT_YVYU:
2632        case DRM_FORMAT_UYVY:
2633        case DRM_FORMAT_VYUY:
2634                if (modifier == DRM_FORMAT_MOD_LINEAR ||
2635                    modifier == I915_FORMAT_MOD_X_TILED)
2636                        return true;
2637                /* fall through */
2638        default:
2639                return false;
2640        }
2641}
2642
2643static bool skl_plane_format_mod_supported(struct drm_plane *_plane,
2644                                           u32 format, u64 modifier)
2645{
2646        struct intel_plane *plane = to_intel_plane(_plane);
2647
2648        switch (modifier) {
2649        case DRM_FORMAT_MOD_LINEAR:
2650        case I915_FORMAT_MOD_X_TILED:
2651        case I915_FORMAT_MOD_Y_TILED:
2652        case I915_FORMAT_MOD_Yf_TILED:
2653                break;
2654        case I915_FORMAT_MOD_Y_TILED_CCS:
2655        case I915_FORMAT_MOD_Yf_TILED_CCS:
2656                if (!plane->has_ccs)
2657                        return false;
2658                break;
2659        default:
2660                return false;
2661        }
2662
2663        switch (format) {
2664        case DRM_FORMAT_XRGB8888:
2665        case DRM_FORMAT_XBGR8888:
2666        case DRM_FORMAT_ARGB8888:
2667        case DRM_FORMAT_ABGR8888:
2668                if (is_ccs_modifier(modifier))
2669                        return true;
2670                /* fall through */
2671        case DRM_FORMAT_RGB565:
2672        case DRM_FORMAT_XRGB2101010:
2673        case DRM_FORMAT_XBGR2101010:
2674        case DRM_FORMAT_YUYV:
2675        case DRM_FORMAT_YVYU:
2676        case DRM_FORMAT_UYVY:
2677        case DRM_FORMAT_VYUY:
2678        case DRM_FORMAT_NV12:
2679        case DRM_FORMAT_P010:
2680        case DRM_FORMAT_P012:
2681        case DRM_FORMAT_P016:
2682        case DRM_FORMAT_XVYU2101010:
2683                if (modifier == I915_FORMAT_MOD_Yf_TILED)
2684                        return true;
2685                /* fall through */
2686        case DRM_FORMAT_C8:
2687        case DRM_FORMAT_XBGR16161616F:
2688        case DRM_FORMAT_ABGR16161616F:
2689        case DRM_FORMAT_XRGB16161616F:
2690        case DRM_FORMAT_ARGB16161616F:
2691        case DRM_FORMAT_Y210:
2692        case DRM_FORMAT_Y212:
2693        case DRM_FORMAT_Y216:
2694        case DRM_FORMAT_XVYU12_16161616:
2695        case DRM_FORMAT_XVYU16161616:
2696                if (modifier == DRM_FORMAT_MOD_LINEAR ||
2697                    modifier == I915_FORMAT_MOD_X_TILED ||
2698                    modifier == I915_FORMAT_MOD_Y_TILED)
2699                        return true;
2700                /* fall through */
2701        default:
2702                return false;
2703        }
2704}
2705
2706static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,
2707                                             u32 format, u64 modifier)
2708{
2709        switch (modifier) {
2710        case DRM_FORMAT_MOD_LINEAR:
2711        case I915_FORMAT_MOD_X_TILED:
2712        case I915_FORMAT_MOD_Y_TILED:
2713                break;
2714        default:
2715                return false;
2716        }
2717
2718        switch (format) {
2719        case DRM_FORMAT_XRGB8888:
2720        case DRM_FORMAT_XBGR8888:
2721        case DRM_FORMAT_ARGB8888:
2722        case DRM_FORMAT_ABGR8888:
2723        case DRM_FORMAT_RGB565:
2724        case DRM_FORMAT_XRGB2101010:
2725        case DRM_FORMAT_XBGR2101010:
2726        case DRM_FORMAT_YUYV:
2727        case DRM_FORMAT_YVYU:
2728        case DRM_FORMAT_UYVY:
2729        case DRM_FORMAT_VYUY:
2730        case DRM_FORMAT_NV12:
2731        case DRM_FORMAT_P010:
2732        case DRM_FORMAT_P012:
2733        case DRM_FORMAT_P016:
2734        case DRM_FORMAT_XVYU2101010:
2735        case DRM_FORMAT_C8:
2736        case DRM_FORMAT_XBGR16161616F:
2737        case DRM_FORMAT_ABGR16161616F:
2738        case DRM_FORMAT_XRGB16161616F:
2739        case DRM_FORMAT_ARGB16161616F:
2740        case DRM_FORMAT_Y210:
2741        case DRM_FORMAT_Y212:
2742        case DRM_FORMAT_Y216:
2743        case DRM_FORMAT_XVYU12_16161616:
2744        case DRM_FORMAT_XVYU16161616:
2745                if (modifier == DRM_FORMAT_MOD_LINEAR ||
2746                    modifier == I915_FORMAT_MOD_X_TILED ||
2747                    modifier == I915_FORMAT_MOD_Y_TILED)
2748                        return true;
2749                /* fall through */
2750        default:
2751                return false;
2752        }
2753}
2754
2755static const struct drm_plane_funcs g4x_sprite_funcs = {
2756        .update_plane = drm_atomic_helper_update_plane,
2757        .disable_plane = drm_atomic_helper_disable_plane,
2758        .destroy = intel_plane_destroy,
2759        .atomic_duplicate_state = intel_plane_duplicate_state,
2760        .atomic_destroy_state = intel_plane_destroy_state,
2761        .format_mod_supported = g4x_sprite_format_mod_supported,
2762};
2763
2764static const struct drm_plane_funcs snb_sprite_funcs = {
2765        .update_plane = drm_atomic_helper_update_plane,
2766        .disable_plane = drm_atomic_helper_disable_plane,
2767        .destroy = intel_plane_destroy,
2768        .atomic_duplicate_state = intel_plane_duplicate_state,
2769        .atomic_destroy_state = intel_plane_destroy_state,
2770        .format_mod_supported = snb_sprite_format_mod_supported,
2771};
2772
2773static const struct drm_plane_funcs vlv_sprite_funcs = {
2774        .update_plane = drm_atomic_helper_update_plane,
2775        .disable_plane = drm_atomic_helper_disable_plane,
2776        .destroy = intel_plane_destroy,
2777        .atomic_duplicate_state = intel_plane_duplicate_state,
2778        .atomic_destroy_state = intel_plane_destroy_state,
2779        .format_mod_supported = vlv_sprite_format_mod_supported,
2780};
2781
2782static const struct drm_plane_funcs skl_plane_funcs = {
2783        .update_plane = drm_atomic_helper_update_plane,
2784        .disable_plane = drm_atomic_helper_disable_plane,
2785        .destroy = intel_plane_destroy,
2786        .atomic_duplicate_state = intel_plane_duplicate_state,
2787        .atomic_destroy_state = intel_plane_destroy_state,
2788        .format_mod_supported = skl_plane_format_mod_supported,
2789};
2790
2791static const struct drm_plane_funcs gen12_plane_funcs = {
2792        .update_plane = drm_atomic_helper_update_plane,
2793        .disable_plane = drm_atomic_helper_disable_plane,
2794        .destroy = intel_plane_destroy,
2795        .atomic_duplicate_state = intel_plane_duplicate_state,
2796        .atomic_destroy_state = intel_plane_destroy_state,
2797        .format_mod_supported = gen12_plane_format_mod_supported,
2798};
2799
2800static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv,
2801                              enum pipe pipe, enum plane_id plane_id)
2802{
2803        if (!HAS_FBC(dev_priv))
2804                return false;
2805
2806        return pipe == PIPE_A && plane_id == PLANE_PRIMARY;
2807}
2808
2809static bool skl_plane_has_planar(struct drm_i915_private *dev_priv,
2810                                 enum pipe pipe, enum plane_id plane_id)
2811{
2812        /* Display WA #0870: skl, bxt */
2813        if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv))
2814                return false;
2815
2816        if (IS_GEN(dev_priv, 9) && !IS_GEMINILAKE(dev_priv) && pipe == PIPE_C)
2817                return false;
2818
2819        if (plane_id != PLANE_PRIMARY && plane_id != PLANE_SPRITE0)
2820                return false;
2821
2822        return true;
2823}
2824
2825static const u32 *skl_get_plane_formats(struct drm_i915_private *dev_priv,
2826                                        enum pipe pipe, enum plane_id plane_id,
2827                                        int *num_formats)
2828{
2829        if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
2830                *num_formats = ARRAY_SIZE(skl_planar_formats);
2831                return skl_planar_formats;
2832        } else {
2833                *num_formats = ARRAY_SIZE(skl_plane_formats);
2834                return skl_plane_formats;
2835        }
2836}
2837
2838static const u32 *glk_get_plane_formats(struct drm_i915_private *dev_priv,
2839                                        enum pipe pipe, enum plane_id plane_id,
2840                                        int *num_formats)
2841{
2842        if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
2843                *num_formats = ARRAY_SIZE(glk_planar_formats);
2844                return glk_planar_formats;
2845        } else {
2846                *num_formats = ARRAY_SIZE(skl_plane_formats);
2847                return skl_plane_formats;
2848        }
2849}
2850
2851static const u32 *icl_get_plane_formats(struct drm_i915_private *dev_priv,
2852                                        enum pipe pipe, enum plane_id plane_id,
2853                                        int *num_formats)
2854{
2855        if (icl_is_hdr_plane(dev_priv, plane_id)) {
2856                *num_formats = ARRAY_SIZE(icl_hdr_plane_formats);
2857                return icl_hdr_plane_formats;
2858        } else if (icl_is_nv12_y_plane(plane_id)) {
2859                *num_formats = ARRAY_SIZE(icl_sdr_y_plane_formats);
2860                return icl_sdr_y_plane_formats;
2861        } else {
2862                *num_formats = ARRAY_SIZE(icl_sdr_uv_plane_formats);
2863                return icl_sdr_uv_plane_formats;
2864        }
2865}
2866
2867static bool skl_plane_has_ccs(struct drm_i915_private *dev_priv,
2868                              enum pipe pipe, enum plane_id plane_id)
2869{
2870        if (plane_id == PLANE_CURSOR)
2871                return false;
2872
2873        if (INTEL_GEN(dev_priv) >= 10)
2874                return true;
2875
2876        if (IS_GEMINILAKE(dev_priv))
2877                return pipe != PIPE_C;
2878
2879        return pipe != PIPE_C &&
2880                (plane_id == PLANE_PRIMARY ||
2881                 plane_id == PLANE_SPRITE0);
2882}
2883
2884struct intel_plane *
2885skl_universal_plane_create(struct drm_i915_private *dev_priv,
2886                           enum pipe pipe, enum plane_id plane_id)
2887{
2888        const struct drm_plane_funcs *plane_funcs;
2889        struct intel_plane *plane;
2890        enum drm_plane_type plane_type;
2891        unsigned int supported_rotations;
2892        unsigned int possible_crtcs;
2893        const u64 *modifiers;
2894        const u32 *formats;
2895        int num_formats;
2896        int ret;
2897
2898        plane = intel_plane_alloc();
2899        if (IS_ERR(plane))
2900                return plane;
2901
2902        plane->pipe = pipe;
2903        plane->id = plane_id;
2904        plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane_id);
2905
2906        plane->has_fbc = skl_plane_has_fbc(dev_priv, pipe, plane_id);
2907        if (plane->has_fbc) {
2908                struct intel_fbc *fbc = &dev_priv->fbc;
2909
2910                fbc->possible_framebuffer_bits |= plane->frontbuffer_bit;
2911        }
2912
2913        plane->max_stride = skl_plane_max_stride;
2914        plane->update_plane = skl_update_plane;
2915        plane->disable_plane = skl_disable_plane;
2916        plane->get_hw_state = skl_plane_get_hw_state;
2917        plane->check_plane = skl_plane_check;
2918        plane->min_cdclk = skl_plane_min_cdclk;
2919        if (icl_is_nv12_y_plane(plane_id))
2920                plane->update_slave = icl_update_slave;
2921
2922        if (INTEL_GEN(dev_priv) >= 11)
2923                formats = icl_get_plane_formats(dev_priv, pipe,
2924                                                plane_id, &num_formats);
2925        else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
2926                formats = glk_get_plane_formats(dev_priv, pipe,
2927                                                plane_id, &num_formats);
2928        else
2929                formats = skl_get_plane_formats(dev_priv, pipe,
2930                                                plane_id, &num_formats);
2931
2932        if (INTEL_GEN(dev_priv) >= 12) {
2933                /* TODO: Implement support for gen-12 CCS modifiers */
2934                plane->has_ccs = false;
2935                modifiers = gen12_plane_format_modifiers_noccs;
2936                plane_funcs = &gen12_plane_funcs;
2937        } else {
2938                plane->has_ccs = skl_plane_has_ccs(dev_priv, pipe, plane_id);
2939                if (plane->has_ccs)
2940                        modifiers = skl_plane_format_modifiers_ccs;
2941                else
2942                        modifiers = skl_plane_format_modifiers_noccs;
2943                plane_funcs = &skl_plane_funcs;
2944        }
2945
2946        if (plane_id == PLANE_PRIMARY)
2947                plane_type = DRM_PLANE_TYPE_PRIMARY;
2948        else
2949                plane_type = DRM_PLANE_TYPE_OVERLAY;
2950
2951        possible_crtcs = BIT(pipe);
2952
2953        ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
2954                                       possible_crtcs, plane_funcs,
2955                                       formats, num_formats, modifiers,
2956                                       plane_type,
2957                                       "plane %d%c", plane_id + 1,
2958                                       pipe_name(pipe));
2959        if (ret)
2960                goto fail;
2961
2962        supported_rotations =
2963                DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 |
2964                DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270;
2965
2966        if (INTEL_GEN(dev_priv) >= 10)
2967                supported_rotations |= DRM_MODE_REFLECT_X;
2968
2969        drm_plane_create_rotation_property(&plane->base,
2970                                           DRM_MODE_ROTATE_0,
2971                                           supported_rotations);
2972
2973        drm_plane_create_color_properties(&plane->base,
2974                                          BIT(DRM_COLOR_YCBCR_BT601) |
2975                                          BIT(DRM_COLOR_YCBCR_BT709),
2976                                          BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
2977                                          BIT(DRM_COLOR_YCBCR_FULL_RANGE),
2978                                          DRM_COLOR_YCBCR_BT709,
2979                                          DRM_COLOR_YCBCR_LIMITED_RANGE);
2980
2981        drm_plane_create_alpha_property(&plane->base);
2982        drm_plane_create_blend_mode_property(&plane->base,
2983                                             BIT(DRM_MODE_BLEND_PIXEL_NONE) |
2984                                             BIT(DRM_MODE_BLEND_PREMULTI) |
2985                                             BIT(DRM_MODE_BLEND_COVERAGE));
2986
2987        drm_plane_create_zpos_immutable_property(&plane->base, plane_id);
2988
2989        drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
2990
2991        return plane;
2992
2993fail:
2994        intel_plane_free(plane);
2995
2996        return ERR_PTR(ret);
2997}
2998
2999struct intel_plane *
3000intel_sprite_plane_create(struct drm_i915_private *dev_priv,
3001                          enum pipe pipe, int sprite)
3002{
3003        struct intel_plane *plane;
3004        const struct drm_plane_funcs *plane_funcs;
3005        unsigned long possible_crtcs;
3006        unsigned int supported_rotations;
3007        const u64 *modifiers;
3008        const u32 *formats;
3009        int num_formats;
3010        int ret, zpos;
3011
3012        if (INTEL_GEN(dev_priv) >= 9)
3013                return skl_universal_plane_create(dev_priv, pipe,
3014                                                  PLANE_SPRITE0 + sprite);
3015
3016        plane = intel_plane_alloc();
3017        if (IS_ERR(plane))
3018                return plane;
3019
3020        if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
3021                plane->max_stride = i9xx_plane_max_stride;
3022                plane->update_plane = vlv_update_plane;
3023                plane->disable_plane = vlv_disable_plane;
3024                plane->get_hw_state = vlv_plane_get_hw_state;
3025                plane->check_plane = vlv_sprite_check;
3026                plane->min_cdclk = vlv_plane_min_cdclk;
3027
3028                formats = vlv_plane_formats;
3029                num_formats = ARRAY_SIZE(vlv_plane_formats);
3030                modifiers = i9xx_plane_format_modifiers;
3031
3032                plane_funcs = &vlv_sprite_funcs;
3033        } else if (INTEL_GEN(dev_priv) >= 7) {
3034                plane->max_stride = g4x_sprite_max_stride;
3035                plane->update_plane = ivb_update_plane;
3036                plane->disable_plane = ivb_disable_plane;
3037                plane->get_hw_state = ivb_plane_get_hw_state;
3038                plane->check_plane = g4x_sprite_check;
3039
3040                if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
3041                        plane->min_cdclk = hsw_plane_min_cdclk;
3042                else
3043                        plane->min_cdclk = ivb_sprite_min_cdclk;
3044
3045                formats = snb_plane_formats;
3046                num_formats = ARRAY_SIZE(snb_plane_formats);
3047                modifiers = i9xx_plane_format_modifiers;
3048
3049                plane_funcs = &snb_sprite_funcs;
3050        } else {
3051                plane->max_stride = g4x_sprite_max_stride;
3052                plane->update_plane = g4x_update_plane;
3053                plane->disable_plane = g4x_disable_plane;
3054                plane->get_hw_state = g4x_plane_get_hw_state;
3055                plane->check_plane = g4x_sprite_check;
3056                plane->min_cdclk = g4x_sprite_min_cdclk;
3057
3058                modifiers = i9xx_plane_format_modifiers;
3059                if (IS_GEN(dev_priv, 6)) {
3060                        formats = snb_plane_formats;
3061                        num_formats = ARRAY_SIZE(snb_plane_formats);
3062
3063                        plane_funcs = &snb_sprite_funcs;
3064                } else {
3065                        formats = g4x_plane_formats;
3066                        num_formats = ARRAY_SIZE(g4x_plane_formats);
3067
3068                        plane_funcs = &g4x_sprite_funcs;
3069                }
3070        }
3071
3072        if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
3073                supported_rotations =
3074                        DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
3075                        DRM_MODE_REFLECT_X;
3076        } else {
3077                supported_rotations =
3078                        DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
3079        }
3080
3081        plane->pipe = pipe;
3082        plane->id = PLANE_SPRITE0 + sprite;
3083        plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id);
3084
3085        possible_crtcs = BIT(pipe);
3086
3087        ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
3088                                       possible_crtcs, plane_funcs,
3089                                       formats, num_formats, modifiers,
3090                                       DRM_PLANE_TYPE_OVERLAY,
3091                                       "sprite %c", sprite_name(pipe, sprite));
3092        if (ret)
3093                goto fail;
3094
3095        drm_plane_create_rotation_property(&plane->base,
3096                                           DRM_MODE_ROTATE_0,
3097                                           supported_rotations);
3098
3099        drm_plane_create_color_properties(&plane->base,
3100                                          BIT(DRM_COLOR_YCBCR_BT601) |
3101                                          BIT(DRM_COLOR_YCBCR_BT709),
3102                                          BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
3103                                          BIT(DRM_COLOR_YCBCR_FULL_RANGE),
3104                                          DRM_COLOR_YCBCR_BT709,
3105                                          DRM_COLOR_YCBCR_LIMITED_RANGE);
3106
3107        zpos = sprite + 1;
3108        drm_plane_create_zpos_immutable_property(&plane->base, zpos);
3109
3110        drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
3111
3112        return plane;
3113
3114fail:
3115        intel_plane_free(plane);
3116
3117        return ERR_PTR(ret);
3118}
3119