linux/drivers/gpu/drm/i915/intel_overlay.c
<<
>>
Prefs
   1/*
   2 * Copyright © 2009
   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 *    Daniel Vetter <daniel@ffwll.ch>
  25 *
  26 * Derived from Xorg ddx, xf86-video-intel, src/i830_video.c
  27 */
  28
  29#include <linux/seq_file.h>
  30#include "drmP.h"
  31#include "drm.h"
  32#include "i915_drm.h"
  33#include "i915_drv.h"
  34#include "i915_reg.h"
  35#include "intel_drv.h"
  36
  37/* Limits for overlay size. According to intel doc, the real limits are:
  38 * Y width: 4095, UV width (planar): 2047, Y height: 2047,
  39 * UV width (planar): * 1023. But the xorg thinks 2048 for height and width. Use
  40 * the mininum of both.  */
  41#define IMAGE_MAX_WIDTH         2048
  42#define IMAGE_MAX_HEIGHT        2046 /* 2 * 1023 */
  43/* on 830 and 845 these large limits result in the card hanging */
  44#define IMAGE_MAX_WIDTH_LEGACY  1024
  45#define IMAGE_MAX_HEIGHT_LEGACY 1088
  46
  47/* overlay register definitions */
  48/* OCMD register */
  49#define OCMD_TILED_SURFACE      (0x1<<19)
  50#define OCMD_MIRROR_MASK        (0x3<<17)
  51#define OCMD_MIRROR_MODE        (0x3<<17)
  52#define OCMD_MIRROR_HORIZONTAL  (0x1<<17)
  53#define OCMD_MIRROR_VERTICAL    (0x2<<17)
  54#define OCMD_MIRROR_BOTH        (0x3<<17)
  55#define OCMD_BYTEORDER_MASK     (0x3<<14) /* zero for YUYV or FOURCC YUY2 */
  56#define OCMD_UV_SWAP            (0x1<<14) /* YVYU */
  57#define OCMD_Y_SWAP             (0x2<<14) /* UYVY or FOURCC UYVY */
  58#define OCMD_Y_AND_UV_SWAP      (0x3<<14) /* VYUY */
  59#define OCMD_SOURCE_FORMAT_MASK (0xf<<10)
  60#define OCMD_RGB_888            (0x1<<10) /* not in i965 Intel docs */
  61#define OCMD_RGB_555            (0x2<<10) /* not in i965 Intel docs */
  62#define OCMD_RGB_565            (0x3<<10) /* not in i965 Intel docs */
  63#define OCMD_YUV_422_PACKED     (0x8<<10)
  64#define OCMD_YUV_411_PACKED     (0x9<<10) /* not in i965 Intel docs */
  65#define OCMD_YUV_420_PLANAR     (0xc<<10)
  66#define OCMD_YUV_422_PLANAR     (0xd<<10)
  67#define OCMD_YUV_410_PLANAR     (0xe<<10) /* also 411 */
  68#define OCMD_TVSYNCFLIP_PARITY  (0x1<<9)
  69#define OCMD_TVSYNCFLIP_ENABLE  (0x1<<7)
  70#define OCMD_BUF_TYPE_MASK      (0x1<<5)
  71#define OCMD_BUF_TYPE_FRAME     (0x0<<5)
  72#define OCMD_BUF_TYPE_FIELD     (0x1<<5)
  73#define OCMD_TEST_MODE          (0x1<<4)
  74#define OCMD_BUFFER_SELECT      (0x3<<2)
  75#define OCMD_BUFFER0            (0x0<<2)
  76#define OCMD_BUFFER1            (0x1<<2)
  77#define OCMD_FIELD_SELECT       (0x1<<2)
  78#define OCMD_FIELD0             (0x0<<1)
  79#define OCMD_FIELD1             (0x1<<1)
  80#define OCMD_ENABLE             (0x1<<0)
  81
  82/* OCONFIG register */
  83#define OCONF_PIPE_MASK         (0x1<<18)
  84#define OCONF_PIPE_A            (0x0<<18)
  85#define OCONF_PIPE_B            (0x1<<18)
  86#define OCONF_GAMMA2_ENABLE     (0x1<<16)
  87#define OCONF_CSC_MODE_BT601    (0x0<<5)
  88#define OCONF_CSC_MODE_BT709    (0x1<<5)
  89#define OCONF_CSC_BYPASS        (0x1<<4)
  90#define OCONF_CC_OUT_8BIT       (0x1<<3)
  91#define OCONF_TEST_MODE         (0x1<<2)
  92#define OCONF_THREE_LINE_BUFFER (0x1<<0)
  93#define OCONF_TWO_LINE_BUFFER   (0x0<<0)
  94
  95/* DCLRKM (dst-key) register */
  96#define DST_KEY_ENABLE          (0x1<<31)
  97#define CLK_RGB24_MASK          0x0
  98#define CLK_RGB16_MASK          0x070307
  99#define CLK_RGB15_MASK          0x070707
 100#define CLK_RGB8I_MASK          0xffffff
 101
 102#define RGB16_TO_COLORKEY(c) \
 103        (((c & 0xF800) << 8) | ((c & 0x07E0) << 5) | ((c & 0x001F) << 3))
 104#define RGB15_TO_COLORKEY(c) \
 105        (((c & 0x7c00) << 9) | ((c & 0x03E0) << 6) | ((c & 0x001F) << 3))
 106
 107/* overlay flip addr flag */
 108#define OFC_UPDATE              0x1
 109
 110/* polyphase filter coefficients */
 111#define N_HORIZ_Y_TAPS          5
 112#define N_VERT_Y_TAPS           3
 113#define N_HORIZ_UV_TAPS         3
 114#define N_VERT_UV_TAPS          3
 115#define N_PHASES                17
 116#define MAX_TAPS                5
 117
 118/* memory bufferd overlay registers */
 119struct overlay_registers {
 120    u32 OBUF_0Y;
 121    u32 OBUF_1Y;
 122    u32 OBUF_0U;
 123    u32 OBUF_0V;
 124    u32 OBUF_1U;
 125    u32 OBUF_1V;
 126    u32 OSTRIDE;
 127    u32 YRGB_VPH;
 128    u32 UV_VPH;
 129    u32 HORZ_PH;
 130    u32 INIT_PHS;
 131    u32 DWINPOS;
 132    u32 DWINSZ;
 133    u32 SWIDTH;
 134    u32 SWIDTHSW;
 135    u32 SHEIGHT;
 136    u32 YRGBSCALE;
 137    u32 UVSCALE;
 138    u32 OCLRC0;
 139    u32 OCLRC1;
 140    u32 DCLRKV;
 141    u32 DCLRKM;
 142    u32 SCLRKVH;
 143    u32 SCLRKVL;
 144    u32 SCLRKEN;
 145    u32 OCONFIG;
 146    u32 OCMD;
 147    u32 RESERVED1; /* 0x6C */
 148    u32 OSTART_0Y;
 149    u32 OSTART_1Y;
 150    u32 OSTART_0U;
 151    u32 OSTART_0V;
 152    u32 OSTART_1U;
 153    u32 OSTART_1V;
 154    u32 OTILEOFF_0Y;
 155    u32 OTILEOFF_1Y;
 156    u32 OTILEOFF_0U;
 157    u32 OTILEOFF_0V;
 158    u32 OTILEOFF_1U;
 159    u32 OTILEOFF_1V;
 160    u32 FASTHSCALE; /* 0xA0 */
 161    u32 UVSCALEV; /* 0xA4 */
 162    u32 RESERVEDC[(0x200 - 0xA8) / 4]; /* 0xA8 - 0x1FC */
 163    u16 Y_VCOEFS[N_VERT_Y_TAPS * N_PHASES]; /* 0x200 */
 164    u16 RESERVEDD[0x100 / 2 - N_VERT_Y_TAPS * N_PHASES];
 165    u16 Y_HCOEFS[N_HORIZ_Y_TAPS * N_PHASES]; /* 0x300 */
 166    u16 RESERVEDE[0x200 / 2 - N_HORIZ_Y_TAPS * N_PHASES];
 167    u16 UV_VCOEFS[N_VERT_UV_TAPS * N_PHASES]; /* 0x500 */
 168    u16 RESERVEDF[0x100 / 2 - N_VERT_UV_TAPS * N_PHASES];
 169    u16 UV_HCOEFS[N_HORIZ_UV_TAPS * N_PHASES]; /* 0x600 */
 170    u16 RESERVEDG[0x100 / 2 - N_HORIZ_UV_TAPS * N_PHASES];
 171};
 172
 173struct intel_overlay {
 174        struct drm_device *dev;
 175        struct intel_crtc *crtc;
 176        struct drm_i915_gem_object *vid_bo;
 177        struct drm_i915_gem_object *old_vid_bo;
 178        int active;
 179        int pfit_active;
 180        u32 pfit_vscale_ratio; /* shifted-point number, (1<<12) == 1.0 */
 181        u32 color_key;
 182        u32 brightness, contrast, saturation;
 183        u32 old_xscale, old_yscale;
 184        /* register access */
 185        u32 flip_addr;
 186        struct drm_i915_gem_object *reg_bo;
 187        /* flip handling */
 188        uint32_t last_flip_req;
 189        void (*flip_tail)(struct intel_overlay *);
 190};
 191
 192static struct overlay_registers *
 193intel_overlay_map_regs(struct intel_overlay *overlay)
 194{
 195        drm_i915_private_t *dev_priv = overlay->dev->dev_private;
 196        struct overlay_registers *regs;
 197
 198        if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
 199                regs = overlay->reg_bo->phys_obj->handle->vaddr;
 200        else
 201                regs = io_mapping_map_wc(dev_priv->mm.gtt_mapping,
 202                                         overlay->reg_bo->gtt_offset);
 203
 204        return regs;
 205}
 206
 207static void intel_overlay_unmap_regs(struct intel_overlay *overlay,
 208                                     struct overlay_registers *regs)
 209{
 210        if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
 211                io_mapping_unmap(regs);
 212}
 213
 214static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
 215                                         struct drm_i915_gem_request *request,
 216                                         bool interruptible,
 217                                         void (*tail)(struct intel_overlay *))
 218{
 219        struct drm_device *dev = overlay->dev;
 220        drm_i915_private_t *dev_priv = dev->dev_private;
 221        int ret;
 222
 223        BUG_ON(overlay->last_flip_req);
 224        ret = i915_add_request(dev, NULL, request, LP_RING(dev_priv));
 225        if (ret) {
 226            kfree(request);
 227            return ret;
 228        }
 229        overlay->last_flip_req = request->seqno;
 230        overlay->flip_tail = tail;
 231        ret = i915_do_wait_request(dev,
 232                                   overlay->last_flip_req, true,
 233                                   LP_RING(dev_priv));
 234        if (ret)
 235                return ret;
 236
 237        overlay->last_flip_req = 0;
 238        return 0;
 239}
 240
 241/* Workaround for i830 bug where pipe a must be enable to change control regs */
 242static int
 243i830_activate_pipe_a(struct drm_device *dev)
 244{
 245        drm_i915_private_t *dev_priv = dev->dev_private;
 246        struct intel_crtc *crtc;
 247        struct drm_crtc_helper_funcs *crtc_funcs;
 248        struct drm_display_mode vesa_640x480 = {
 249                DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
 250                         752, 800, 0, 480, 489, 492, 525, 0,
 251                         DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)
 252        }, *mode;
 253
 254        crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[0]);
 255        if (crtc->dpms_mode == DRM_MODE_DPMS_ON)
 256                return 0;
 257
 258        /* most i8xx have pipe a forced on, so don't trust dpms mode */
 259        if (I915_READ(PIPEACONF) & PIPECONF_ENABLE)
 260                return 0;
 261
 262        crtc_funcs = crtc->base.helper_private;
 263        if (crtc_funcs->dpms == NULL)
 264                return 0;
 265
 266        DRM_DEBUG_DRIVER("Enabling pipe A in order to enable overlay\n");
 267
 268        mode = drm_mode_duplicate(dev, &vesa_640x480);
 269        drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
 270        if(!drm_crtc_helper_set_mode(&crtc->base, mode,
 271                                       crtc->base.x, crtc->base.y,
 272                                       crtc->base.fb))
 273                return 0;
 274
 275        crtc_funcs->dpms(&crtc->base, DRM_MODE_DPMS_ON);
 276        return 1;
 277}
 278
 279static void
 280i830_deactivate_pipe_a(struct drm_device *dev)
 281{
 282        drm_i915_private_t *dev_priv = dev->dev_private;
 283        struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[0];
 284        struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
 285
 286        crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
 287}
 288
 289/* overlay needs to be disable in OCMD reg */
 290static int intel_overlay_on(struct intel_overlay *overlay)
 291{
 292        struct drm_device *dev = overlay->dev;
 293        struct drm_i915_private *dev_priv = dev->dev_private;
 294        struct drm_i915_gem_request *request;
 295        int pipe_a_quirk = 0;
 296        int ret;
 297
 298        BUG_ON(overlay->active);
 299        overlay->active = 1;
 300
 301        if (IS_I830(dev)) {
 302                pipe_a_quirk = i830_activate_pipe_a(dev);
 303                if (pipe_a_quirk < 0)
 304                        return pipe_a_quirk;
 305        }
 306
 307        request = kzalloc(sizeof(*request), GFP_KERNEL);
 308        if (request == NULL) {
 309                ret = -ENOMEM;
 310                goto out;
 311        }
 312
 313        ret = BEGIN_LP_RING(4);
 314        if (ret) {
 315                kfree(request);
 316                goto out;
 317        }
 318
 319        OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_ON);
 320        OUT_RING(overlay->flip_addr | OFC_UPDATE);
 321        OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
 322        OUT_RING(MI_NOOP);
 323        ADVANCE_LP_RING();
 324
 325        ret = intel_overlay_do_wait_request(overlay, request, true, NULL);
 326out:
 327        if (pipe_a_quirk)
 328                i830_deactivate_pipe_a(dev);
 329
 330        return ret;
 331}
 332
 333/* overlay needs to be enabled in OCMD reg */
 334static int intel_overlay_continue(struct intel_overlay *overlay,
 335                                  bool load_polyphase_filter)
 336{
 337        struct drm_device *dev = overlay->dev;
 338        drm_i915_private_t *dev_priv = dev->dev_private;
 339        struct drm_i915_gem_request *request;
 340        u32 flip_addr = overlay->flip_addr;
 341        u32 tmp;
 342        int ret;
 343
 344        BUG_ON(!overlay->active);
 345
 346        request = kzalloc(sizeof(*request), GFP_KERNEL);
 347        if (request == NULL)
 348                return -ENOMEM;
 349
 350        if (load_polyphase_filter)
 351                flip_addr |= OFC_UPDATE;
 352
 353        /* check for underruns */
 354        tmp = I915_READ(DOVSTA);
 355        if (tmp & (1 << 17))
 356                DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp);
 357
 358        ret = BEGIN_LP_RING(2);
 359        if (ret) {
 360                kfree(request);
 361                return ret;
 362        }
 363        OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
 364        OUT_RING(flip_addr);
 365        ADVANCE_LP_RING();
 366
 367        ret = i915_add_request(dev, NULL, request, LP_RING(dev_priv));
 368        if (ret) {
 369                kfree(request);
 370                return ret;
 371        }
 372
 373        overlay->last_flip_req = request->seqno;
 374        return 0;
 375}
 376
 377static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
 378{
 379        struct drm_i915_gem_object *obj = overlay->old_vid_bo;
 380
 381        i915_gem_object_unpin(obj);
 382        drm_gem_object_unreference(&obj->base);
 383
 384        overlay->old_vid_bo = NULL;
 385}
 386
 387static void intel_overlay_off_tail(struct intel_overlay *overlay)
 388{
 389        struct drm_i915_gem_object *obj = overlay->vid_bo;
 390
 391        /* never have the overlay hw on without showing a frame */
 392        BUG_ON(!overlay->vid_bo);
 393
 394        i915_gem_object_unpin(obj);
 395        drm_gem_object_unreference(&obj->base);
 396        overlay->vid_bo = NULL;
 397
 398        overlay->crtc->overlay = NULL;
 399        overlay->crtc = NULL;
 400        overlay->active = 0;
 401}
 402
 403/* overlay needs to be disabled in OCMD reg */
 404static int intel_overlay_off(struct intel_overlay *overlay,
 405                             bool interruptible)
 406{
 407        struct drm_device *dev = overlay->dev;
 408        struct drm_i915_private *dev_priv = dev->dev_private;
 409        u32 flip_addr = overlay->flip_addr;
 410        struct drm_i915_gem_request *request;
 411        int ret;
 412
 413        BUG_ON(!overlay->active);
 414
 415        request = kzalloc(sizeof(*request), GFP_KERNEL);
 416        if (request == NULL)
 417                return -ENOMEM;
 418
 419        /* According to intel docs the overlay hw may hang (when switching
 420         * off) without loading the filter coeffs. It is however unclear whether
 421         * this applies to the disabling of the overlay or to the switching off
 422         * of the hw. Do it in both cases */
 423        flip_addr |= OFC_UPDATE;
 424
 425        ret = BEGIN_LP_RING(6);
 426        if (ret) {
 427                kfree(request);
 428                return ret;
 429        }
 430        /* wait for overlay to go idle */
 431        OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
 432        OUT_RING(flip_addr);
 433        OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
 434        /* turn overlay off */
 435        OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
 436        OUT_RING(flip_addr);
 437        OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
 438        ADVANCE_LP_RING();
 439
 440        return intel_overlay_do_wait_request(overlay, request, interruptible,
 441                                             intel_overlay_off_tail);
 442}
 443
 444/* recover from an interruption due to a signal
 445 * We have to be careful not to repeat work forever an make forward progess. */
 446static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
 447                                                bool interruptible)
 448{
 449        struct drm_device *dev = overlay->dev;
 450        drm_i915_private_t *dev_priv = dev->dev_private;
 451        int ret;
 452
 453        if (overlay->last_flip_req == 0)
 454                return 0;
 455
 456        ret = i915_do_wait_request(dev, overlay->last_flip_req,
 457                                   interruptible, LP_RING(dev_priv));
 458        if (ret)
 459                return ret;
 460
 461        if (overlay->flip_tail)
 462                overlay->flip_tail(overlay);
 463
 464        overlay->last_flip_req = 0;
 465        return 0;
 466}
 467
 468/* Wait for pending overlay flip and release old frame.
 469 * Needs to be called before the overlay register are changed
 470 * via intel_overlay_(un)map_regs
 471 */
 472static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
 473{
 474        struct drm_device *dev = overlay->dev;
 475        drm_i915_private_t *dev_priv = dev->dev_private;
 476        int ret;
 477
 478        /* Only wait if there is actually an old frame to release to
 479         * guarantee forward progress.
 480         */
 481        if (!overlay->old_vid_bo)
 482                return 0;
 483
 484        if (I915_READ(ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT) {
 485                struct drm_i915_gem_request *request;
 486
 487                /* synchronous slowpath */
 488                request = kzalloc(sizeof(*request), GFP_KERNEL);
 489                if (request == NULL)
 490                        return -ENOMEM;
 491
 492                ret = BEGIN_LP_RING(2);
 493                if (ret) {
 494                        kfree(request);
 495                        return ret;
 496                }
 497
 498                OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
 499                OUT_RING(MI_NOOP);
 500                ADVANCE_LP_RING();
 501
 502                ret = intel_overlay_do_wait_request(overlay, request, true,
 503                                                    intel_overlay_release_old_vid_tail);
 504                if (ret)
 505                        return ret;
 506        }
 507
 508        intel_overlay_release_old_vid_tail(overlay);
 509        return 0;
 510}
 511
 512struct put_image_params {
 513        int format;
 514        short dst_x;
 515        short dst_y;
 516        short dst_w;
 517        short dst_h;
 518        short src_w;
 519        short src_scan_h;
 520        short src_scan_w;
 521        short src_h;
 522        short stride_Y;
 523        short stride_UV;
 524        int offset_Y;
 525        int offset_U;
 526        int offset_V;
 527};
 528
 529static int packed_depth_bytes(u32 format)
 530{
 531        switch (format & I915_OVERLAY_DEPTH_MASK) {
 532        case I915_OVERLAY_YUV422:
 533                return 4;
 534        case I915_OVERLAY_YUV411:
 535                /* return 6; not implemented */
 536        default:
 537                return -EINVAL;
 538        }
 539}
 540
 541static int packed_width_bytes(u32 format, short width)
 542{
 543        switch (format & I915_OVERLAY_DEPTH_MASK) {
 544        case I915_OVERLAY_YUV422:
 545                return width << 1;
 546        default:
 547                return -EINVAL;
 548        }
 549}
 550
 551static int uv_hsubsampling(u32 format)
 552{
 553        switch (format & I915_OVERLAY_DEPTH_MASK) {
 554        case I915_OVERLAY_YUV422:
 555        case I915_OVERLAY_YUV420:
 556                return 2;
 557        case I915_OVERLAY_YUV411:
 558        case I915_OVERLAY_YUV410:
 559                return 4;
 560        default:
 561                return -EINVAL;
 562        }
 563}
 564
 565static int uv_vsubsampling(u32 format)
 566{
 567        switch (format & I915_OVERLAY_DEPTH_MASK) {
 568        case I915_OVERLAY_YUV420:
 569        case I915_OVERLAY_YUV410:
 570                return 2;
 571        case I915_OVERLAY_YUV422:
 572        case I915_OVERLAY_YUV411:
 573                return 1;
 574        default:
 575                return -EINVAL;
 576        }
 577}
 578
 579static u32 calc_swidthsw(struct drm_device *dev, u32 offset, u32 width)
 580{
 581        u32 mask, shift, ret;
 582        if (IS_GEN2(dev)) {
 583                mask = 0x1f;
 584                shift = 5;
 585        } else {
 586                mask = 0x3f;
 587                shift = 6;
 588        }
 589        ret = ((offset + width + mask) >> shift) - (offset >> shift);
 590        if (!IS_GEN2(dev))
 591                ret <<= 1;
 592        ret -=1;
 593        return ret << 2;
 594}
 595
 596static const u16 y_static_hcoeffs[N_HORIZ_Y_TAPS * N_PHASES] = {
 597        0x3000, 0xb4a0, 0x1930, 0x1920, 0xb4a0,
 598        0x3000, 0xb500, 0x19d0, 0x1880, 0xb440,
 599        0x3000, 0xb540, 0x1a88, 0x2f80, 0xb3e0,
 600        0x3000, 0xb580, 0x1b30, 0x2e20, 0xb380,
 601        0x3000, 0xb5c0, 0x1bd8, 0x2cc0, 0xb320,
 602        0x3020, 0xb5e0, 0x1c60, 0x2b80, 0xb2c0,
 603        0x3020, 0xb5e0, 0x1cf8, 0x2a20, 0xb260,
 604        0x3020, 0xb5e0, 0x1d80, 0x28e0, 0xb200,
 605        0x3020, 0xb5c0, 0x1e08, 0x3f40, 0xb1c0,
 606        0x3020, 0xb580, 0x1e78, 0x3ce0, 0xb160,
 607        0x3040, 0xb520, 0x1ed8, 0x3aa0, 0xb120,
 608        0x3040, 0xb4a0, 0x1f30, 0x3880, 0xb0e0,
 609        0x3040, 0xb400, 0x1f78, 0x3680, 0xb0a0,
 610        0x3020, 0xb340, 0x1fb8, 0x34a0, 0xb060,
 611        0x3020, 0xb240, 0x1fe0, 0x32e0, 0xb040,
 612        0x3020, 0xb140, 0x1ff8, 0x3160, 0xb020,
 613        0xb000, 0x3000, 0x0800, 0x3000, 0xb000
 614};
 615
 616static const u16 uv_static_hcoeffs[N_HORIZ_UV_TAPS * N_PHASES] = {
 617        0x3000, 0x1800, 0x1800, 0xb000, 0x18d0, 0x2e60,
 618        0xb000, 0x1990, 0x2ce0, 0xb020, 0x1a68, 0x2b40,
 619        0xb040, 0x1b20, 0x29e0, 0xb060, 0x1bd8, 0x2880,
 620        0xb080, 0x1c88, 0x3e60, 0xb0a0, 0x1d28, 0x3c00,
 621        0xb0c0, 0x1db8, 0x39e0, 0xb0e0, 0x1e40, 0x37e0,
 622        0xb100, 0x1eb8, 0x3620, 0xb100, 0x1f18, 0x34a0,
 623        0xb100, 0x1f68, 0x3360, 0xb0e0, 0x1fa8, 0x3240,
 624        0xb0c0, 0x1fe0, 0x3140, 0xb060, 0x1ff0, 0x30a0,
 625        0x3000, 0x0800, 0x3000
 626};
 627
 628static void update_polyphase_filter(struct overlay_registers *regs)
 629{
 630        memcpy(regs->Y_HCOEFS, y_static_hcoeffs, sizeof(y_static_hcoeffs));
 631        memcpy(regs->UV_HCOEFS, uv_static_hcoeffs, sizeof(uv_static_hcoeffs));
 632}
 633
 634static bool update_scaling_factors(struct intel_overlay *overlay,
 635                                   struct overlay_registers *regs,
 636                                   struct put_image_params *params)
 637{
 638        /* fixed point with a 12 bit shift */
 639        u32 xscale, yscale, xscale_UV, yscale_UV;
 640#define FP_SHIFT 12
 641#define FRACT_MASK 0xfff
 642        bool scale_changed = false;
 643        int uv_hscale = uv_hsubsampling(params->format);
 644        int uv_vscale = uv_vsubsampling(params->format);
 645
 646        if (params->dst_w > 1)
 647                xscale = ((params->src_scan_w - 1) << FP_SHIFT)
 648                        /(params->dst_w);
 649        else
 650                xscale = 1 << FP_SHIFT;
 651
 652        if (params->dst_h > 1)
 653                yscale = ((params->src_scan_h - 1) << FP_SHIFT)
 654                        /(params->dst_h);
 655        else
 656                yscale = 1 << FP_SHIFT;
 657
 658        /*if (params->format & I915_OVERLAY_YUV_PLANAR) {*/
 659        xscale_UV = xscale/uv_hscale;
 660        yscale_UV = yscale/uv_vscale;
 661        /* make the Y scale to UV scale ratio an exact multiply */
 662        xscale = xscale_UV * uv_hscale;
 663        yscale = yscale_UV * uv_vscale;
 664        /*} else {
 665          xscale_UV = 0;
 666          yscale_UV = 0;
 667          }*/
 668
 669        if (xscale != overlay->old_xscale || yscale != overlay->old_yscale)
 670                scale_changed = true;
 671        overlay->old_xscale = xscale;
 672        overlay->old_yscale = yscale;
 673
 674        regs->YRGBSCALE = (((yscale & FRACT_MASK) << 20) |
 675                           ((xscale >> FP_SHIFT)  << 16) |
 676                           ((xscale & FRACT_MASK) << 3));
 677
 678        regs->UVSCALE = (((yscale_UV & FRACT_MASK) << 20) |
 679                         ((xscale_UV >> FP_SHIFT)  << 16) |
 680                         ((xscale_UV & FRACT_MASK) << 3));
 681
 682        regs->UVSCALEV = ((((yscale    >> FP_SHIFT) << 16) |
 683                           ((yscale_UV >> FP_SHIFT) << 0)));
 684
 685        if (scale_changed)
 686                update_polyphase_filter(regs);
 687
 688        return scale_changed;
 689}
 690
 691static void update_colorkey(struct intel_overlay *overlay,
 692                            struct overlay_registers *regs)
 693{
 694        u32 key = overlay->color_key;
 695
 696        switch (overlay->crtc->base.fb->bits_per_pixel) {
 697        case 8:
 698                regs->DCLRKV = 0;
 699                regs->DCLRKM = CLK_RGB8I_MASK | DST_KEY_ENABLE;
 700                break;
 701
 702        case 16:
 703                if (overlay->crtc->base.fb->depth == 15) {
 704                        regs->DCLRKV = RGB15_TO_COLORKEY(key);
 705                        regs->DCLRKM = CLK_RGB15_MASK | DST_KEY_ENABLE;
 706                } else {
 707                        regs->DCLRKV = RGB16_TO_COLORKEY(key);
 708                        regs->DCLRKM = CLK_RGB16_MASK | DST_KEY_ENABLE;
 709                }
 710                break;
 711
 712        case 24:
 713        case 32:
 714                regs->DCLRKV = key;
 715                regs->DCLRKM = CLK_RGB24_MASK | DST_KEY_ENABLE;
 716                break;
 717        }
 718}
 719
 720static u32 overlay_cmd_reg(struct put_image_params *params)
 721{
 722        u32 cmd = OCMD_ENABLE | OCMD_BUF_TYPE_FRAME | OCMD_BUFFER0;
 723
 724        if (params->format & I915_OVERLAY_YUV_PLANAR) {
 725                switch (params->format & I915_OVERLAY_DEPTH_MASK) {
 726                case I915_OVERLAY_YUV422:
 727                        cmd |= OCMD_YUV_422_PLANAR;
 728                        break;
 729                case I915_OVERLAY_YUV420:
 730                        cmd |= OCMD_YUV_420_PLANAR;
 731                        break;
 732                case I915_OVERLAY_YUV411:
 733                case I915_OVERLAY_YUV410:
 734                        cmd |= OCMD_YUV_410_PLANAR;
 735                        break;
 736                }
 737        } else { /* YUV packed */
 738                switch (params->format & I915_OVERLAY_DEPTH_MASK) {
 739                case I915_OVERLAY_YUV422:
 740                        cmd |= OCMD_YUV_422_PACKED;
 741                        break;
 742                case I915_OVERLAY_YUV411:
 743                        cmd |= OCMD_YUV_411_PACKED;
 744                        break;
 745                }
 746
 747                switch (params->format & I915_OVERLAY_SWAP_MASK) {
 748                case I915_OVERLAY_NO_SWAP:
 749                        break;
 750                case I915_OVERLAY_UV_SWAP:
 751                        cmd |= OCMD_UV_SWAP;
 752                        break;
 753                case I915_OVERLAY_Y_SWAP:
 754                        cmd |= OCMD_Y_SWAP;
 755                        break;
 756                case I915_OVERLAY_Y_AND_UV_SWAP:
 757                        cmd |= OCMD_Y_AND_UV_SWAP;
 758                        break;
 759                }
 760        }
 761
 762        return cmd;
 763}
 764
 765static int intel_overlay_do_put_image(struct intel_overlay *overlay,
 766                                      struct drm_i915_gem_object *new_bo,
 767                                      struct put_image_params *params)
 768{
 769        int ret, tmp_width;
 770        struct overlay_registers *regs;
 771        bool scale_changed = false;
 772        struct drm_device *dev = overlay->dev;
 773
 774        BUG_ON(!mutex_is_locked(&dev->struct_mutex));
 775        BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
 776        BUG_ON(!overlay);
 777
 778        ret = intel_overlay_release_old_vid(overlay);
 779        if (ret != 0)
 780                return ret;
 781
 782        ret = i915_gem_object_pin(new_bo, PAGE_SIZE, true);
 783        if (ret != 0)
 784                return ret;
 785
 786        ret = i915_gem_object_set_to_gtt_domain(new_bo, 0);
 787        if (ret != 0)
 788                goto out_unpin;
 789
 790        ret = i915_gem_object_put_fence(new_bo);
 791        if (ret)
 792                goto out_unpin;
 793
 794        if (!overlay->active) {
 795                regs = intel_overlay_map_regs(overlay);
 796                if (!regs) {
 797                        ret = -ENOMEM;
 798                        goto out_unpin;
 799                }
 800                regs->OCONFIG = OCONF_CC_OUT_8BIT;
 801                if (IS_GEN4(overlay->dev))
 802                        regs->OCONFIG |= OCONF_CSC_MODE_BT709;
 803                regs->OCONFIG |= overlay->crtc->pipe == 0 ?
 804                        OCONF_PIPE_A : OCONF_PIPE_B;
 805                intel_overlay_unmap_regs(overlay, regs);
 806
 807                ret = intel_overlay_on(overlay);
 808                if (ret != 0)
 809                        goto out_unpin;
 810        }
 811
 812        regs = intel_overlay_map_regs(overlay);
 813        if (!regs) {
 814                ret = -ENOMEM;
 815                goto out_unpin;
 816        }
 817
 818        regs->DWINPOS = (params->dst_y << 16) | params->dst_x;
 819        regs->DWINSZ = (params->dst_h << 16) | params->dst_w;
 820
 821        if (params->format & I915_OVERLAY_YUV_PACKED)
 822                tmp_width = packed_width_bytes(params->format, params->src_w);
 823        else
 824                tmp_width = params->src_w;
 825
 826        regs->SWIDTH = params->src_w;
 827        regs->SWIDTHSW = calc_swidthsw(overlay->dev,
 828                                       params->offset_Y, tmp_width);
 829        regs->SHEIGHT = params->src_h;
 830        regs->OBUF_0Y = new_bo->gtt_offset + params-> offset_Y;
 831        regs->OSTRIDE = params->stride_Y;
 832
 833        if (params->format & I915_OVERLAY_YUV_PLANAR) {
 834                int uv_hscale = uv_hsubsampling(params->format);
 835                int uv_vscale = uv_vsubsampling(params->format);
 836                u32 tmp_U, tmp_V;
 837                regs->SWIDTH |= (params->src_w/uv_hscale) << 16;
 838                tmp_U = calc_swidthsw(overlay->dev, params->offset_U,
 839                                      params->src_w/uv_hscale);
 840                tmp_V = calc_swidthsw(overlay->dev, params->offset_V,
 841                                      params->src_w/uv_hscale);
 842                regs->SWIDTHSW |= max_t(u32, tmp_U, tmp_V) << 16;
 843                regs->SHEIGHT |= (params->src_h/uv_vscale) << 16;
 844                regs->OBUF_0U = new_bo->gtt_offset + params->offset_U;
 845                regs->OBUF_0V = new_bo->gtt_offset + params->offset_V;
 846                regs->OSTRIDE |= params->stride_UV << 16;
 847        }
 848
 849        scale_changed = update_scaling_factors(overlay, regs, params);
 850
 851        update_colorkey(overlay, regs);
 852
 853        regs->OCMD = overlay_cmd_reg(params);
 854
 855        intel_overlay_unmap_regs(overlay, regs);
 856
 857        ret = intel_overlay_continue(overlay, scale_changed);
 858        if (ret)
 859                goto out_unpin;
 860
 861        overlay->old_vid_bo = overlay->vid_bo;
 862        overlay->vid_bo = new_bo;
 863
 864        return 0;
 865
 866out_unpin:
 867        i915_gem_object_unpin(new_bo);
 868        return ret;
 869}
 870
 871int intel_overlay_switch_off(struct intel_overlay *overlay,
 872                             bool interruptible)
 873{
 874        struct overlay_registers *regs;
 875        struct drm_device *dev = overlay->dev;
 876        int ret;
 877
 878        BUG_ON(!mutex_is_locked(&dev->struct_mutex));
 879        BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
 880
 881        ret = intel_overlay_recover_from_interrupt(overlay, interruptible);
 882        if (ret != 0)
 883                return ret;
 884
 885        if (!overlay->active)
 886                return 0;
 887
 888        ret = intel_overlay_release_old_vid(overlay);
 889        if (ret != 0)
 890                return ret;
 891
 892        regs = intel_overlay_map_regs(overlay);
 893        regs->OCMD = 0;
 894        intel_overlay_unmap_regs(overlay, regs);
 895
 896        ret = intel_overlay_off(overlay, interruptible);
 897        if (ret != 0)
 898                return ret;
 899
 900        intel_overlay_off_tail(overlay);
 901        return 0;
 902}
 903
 904static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
 905                                          struct intel_crtc *crtc)
 906{
 907        drm_i915_private_t *dev_priv = overlay->dev->dev_private;
 908
 909        if (!crtc->active)
 910                return -EINVAL;
 911
 912        /* can't use the overlay with double wide pipe */
 913        if (INTEL_INFO(overlay->dev)->gen < 4 &&
 914            (I915_READ(PIPECONF(crtc->pipe)) & (PIPECONF_DOUBLE_WIDE | PIPECONF_ENABLE)) != PIPECONF_ENABLE)
 915                return -EINVAL;
 916
 917        return 0;
 918}
 919
 920static void update_pfit_vscale_ratio(struct intel_overlay *overlay)
 921{
 922        struct drm_device *dev = overlay->dev;
 923        drm_i915_private_t *dev_priv = dev->dev_private;
 924        u32 pfit_control = I915_READ(PFIT_CONTROL);
 925        u32 ratio;
 926
 927        /* XXX: This is not the same logic as in the xorg driver, but more in
 928         * line with the intel documentation for the i965
 929         */
 930        if (INTEL_INFO(dev)->gen >= 4) {
 931                /* on i965 use the PGM reg to read out the autoscaler values */
 932                ratio = I915_READ(PFIT_PGM_RATIOS) >> PFIT_VERT_SCALE_SHIFT_965;
 933        } else {
 934                if (pfit_control & VERT_AUTO_SCALE)
 935                        ratio = I915_READ(PFIT_AUTO_RATIOS);
 936                else
 937                        ratio = I915_READ(PFIT_PGM_RATIOS);
 938                ratio >>= PFIT_VERT_SCALE_SHIFT;
 939        }
 940
 941        overlay->pfit_vscale_ratio = ratio;
 942}
 943
 944static int check_overlay_dst(struct intel_overlay *overlay,
 945                             struct drm_intel_overlay_put_image *rec)
 946{
 947        struct drm_display_mode *mode = &overlay->crtc->base.mode;
 948
 949        if (rec->dst_x < mode->crtc_hdisplay &&
 950            rec->dst_x + rec->dst_width <= mode->crtc_hdisplay &&
 951            rec->dst_y < mode->crtc_vdisplay &&
 952            rec->dst_y + rec->dst_height <= mode->crtc_vdisplay)
 953                return 0;
 954        else
 955                return -EINVAL;
 956}
 957
 958static int check_overlay_scaling(struct put_image_params *rec)
 959{
 960        u32 tmp;
 961
 962        /* downscaling limit is 8.0 */
 963        tmp = ((rec->src_scan_h << 16) / rec->dst_h) >> 16;
 964        if (tmp > 7)
 965                return -EINVAL;
 966        tmp = ((rec->src_scan_w << 16) / rec->dst_w) >> 16;
 967        if (tmp > 7)
 968                return -EINVAL;
 969
 970        return 0;
 971}
 972
 973static int check_overlay_src(struct drm_device *dev,
 974                             struct drm_intel_overlay_put_image *rec,
 975                             struct drm_i915_gem_object *new_bo)
 976{
 977        int uv_hscale = uv_hsubsampling(rec->flags);
 978        int uv_vscale = uv_vsubsampling(rec->flags);
 979        u32 stride_mask;
 980        int depth;
 981        u32 tmp;
 982
 983        /* check src dimensions */
 984        if (IS_845G(dev) || IS_I830(dev)) {
 985                if (rec->src_height > IMAGE_MAX_HEIGHT_LEGACY ||
 986                    rec->src_width  > IMAGE_MAX_WIDTH_LEGACY)
 987                        return -EINVAL;
 988        } else {
 989                if (rec->src_height > IMAGE_MAX_HEIGHT ||
 990                    rec->src_width  > IMAGE_MAX_WIDTH)
 991                        return -EINVAL;
 992        }
 993
 994        /* better safe than sorry, use 4 as the maximal subsampling ratio */
 995        if (rec->src_height < N_VERT_Y_TAPS*4 ||
 996            rec->src_width  < N_HORIZ_Y_TAPS*4)
 997                return -EINVAL;
 998
 999        /* check alignment constraints */
1000        switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
1001        case I915_OVERLAY_RGB:
1002                /* not implemented */
1003                return -EINVAL;
1004
1005        case I915_OVERLAY_YUV_PACKED:
1006                if (uv_vscale != 1)
1007                        return -EINVAL;
1008
1009                depth = packed_depth_bytes(rec->flags);
1010                if (depth < 0)
1011                        return depth;
1012
1013                /* ignore UV planes */
1014                rec->stride_UV = 0;
1015                rec->offset_U = 0;
1016                rec->offset_V = 0;
1017                /* check pixel alignment */
1018                if (rec->offset_Y % depth)
1019                        return -EINVAL;
1020                break;
1021
1022        case I915_OVERLAY_YUV_PLANAR:
1023                if (uv_vscale < 0 || uv_hscale < 0)
1024                        return -EINVAL;
1025                /* no offset restrictions for planar formats */
1026                break;
1027
1028        default:
1029                return -EINVAL;
1030        }
1031
1032        if (rec->src_width % uv_hscale)
1033                return -EINVAL;
1034
1035        /* stride checking */
1036        if (IS_I830(dev) || IS_845G(dev))
1037                stride_mask = 255;
1038        else
1039                stride_mask = 63;
1040
1041        if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask)
1042                return -EINVAL;
1043        if (IS_GEN4(dev) && rec->stride_Y < 512)
1044                return -EINVAL;
1045
1046        tmp = (rec->flags & I915_OVERLAY_TYPE_MASK) == I915_OVERLAY_YUV_PLANAR ?
1047                4096 : 8192;
1048        if (rec->stride_Y > tmp || rec->stride_UV > 2*1024)
1049                return -EINVAL;
1050
1051        /* check buffer dimensions */
1052        switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
1053        case I915_OVERLAY_RGB:
1054        case I915_OVERLAY_YUV_PACKED:
1055                /* always 4 Y values per depth pixels */
1056                if (packed_width_bytes(rec->flags, rec->src_width) > rec->stride_Y)
1057                        return -EINVAL;
1058
1059                tmp = rec->stride_Y*rec->src_height;
1060                if (rec->offset_Y + tmp > new_bo->base.size)
1061                        return -EINVAL;
1062                break;
1063
1064        case I915_OVERLAY_YUV_PLANAR:
1065                if (rec->src_width > rec->stride_Y)
1066                        return -EINVAL;
1067                if (rec->src_width/uv_hscale > rec->stride_UV)
1068                        return -EINVAL;
1069
1070                tmp = rec->stride_Y * rec->src_height;
1071                if (rec->offset_Y + tmp > new_bo->base.size)
1072                        return -EINVAL;
1073
1074                tmp = rec->stride_UV * (rec->src_height / uv_vscale);
1075                if (rec->offset_U + tmp > new_bo->base.size ||
1076                    rec->offset_V + tmp > new_bo->base.size)
1077                        return -EINVAL;
1078                break;
1079        }
1080
1081        return 0;
1082}
1083
1084/**
1085 * Return the pipe currently connected to the panel fitter,
1086 * or -1 if the panel fitter is not present or not in use
1087 */
1088static int intel_panel_fitter_pipe(struct drm_device *dev)
1089{
1090        struct drm_i915_private *dev_priv = dev->dev_private;
1091        u32  pfit_control;
1092
1093        /* i830 doesn't have a panel fitter */
1094        if (IS_I830(dev))
1095                return -1;
1096
1097        pfit_control = I915_READ(PFIT_CONTROL);
1098
1099        /* See if the panel fitter is in use */
1100        if ((pfit_control & PFIT_ENABLE) == 0)
1101                return -1;
1102
1103        /* 965 can place panel fitter on either pipe */
1104        if (IS_GEN4(dev))
1105                return (pfit_control >> 29) & 0x3;
1106
1107        /* older chips can only use pipe 1 */
1108        return 1;
1109}
1110
1111int intel_overlay_put_image(struct drm_device *dev, void *data,
1112                            struct drm_file *file_priv)
1113{
1114        struct drm_intel_overlay_put_image *put_image_rec = data;
1115        drm_i915_private_t *dev_priv = dev->dev_private;
1116        struct intel_overlay *overlay;
1117        struct drm_mode_object *drmmode_obj;
1118        struct intel_crtc *crtc;
1119        struct drm_i915_gem_object *new_bo;
1120        struct put_image_params *params;
1121        int ret;
1122
1123        if (!dev_priv) {
1124                DRM_ERROR("called with no initialization\n");
1125                return -EINVAL;
1126        }
1127
1128        overlay = dev_priv->overlay;
1129        if (!overlay) {
1130                DRM_DEBUG("userspace bug: no overlay\n");
1131                return -ENODEV;
1132        }
1133
1134        if (!(put_image_rec->flags & I915_OVERLAY_ENABLE)) {
1135                mutex_lock(&dev->mode_config.mutex);
1136                mutex_lock(&dev->struct_mutex);
1137
1138                ret = intel_overlay_switch_off(overlay, true);
1139
1140                mutex_unlock(&dev->struct_mutex);
1141                mutex_unlock(&dev->mode_config.mutex);
1142
1143                return ret;
1144        }
1145
1146        params = kmalloc(sizeof(struct put_image_params), GFP_KERNEL);
1147        if (!params)
1148                return -ENOMEM;
1149
1150        drmmode_obj = drm_mode_object_find(dev, put_image_rec->crtc_id,
1151                                           DRM_MODE_OBJECT_CRTC);
1152        if (!drmmode_obj) {
1153                ret = -ENOENT;
1154                goto out_free;
1155        }
1156        crtc = to_intel_crtc(obj_to_crtc(drmmode_obj));
1157
1158        new_bo = to_intel_bo(drm_gem_object_lookup(dev, file_priv,
1159                                                   put_image_rec->bo_handle));
1160        if (!new_bo) {
1161                ret = -ENOENT;
1162                goto out_free;
1163        }
1164
1165        mutex_lock(&dev->mode_config.mutex);
1166        mutex_lock(&dev->struct_mutex);
1167
1168        if (new_bo->tiling_mode) {
1169                DRM_ERROR("buffer used for overlay image can not be tiled\n");
1170                ret = -EINVAL;
1171                goto out_unlock;
1172        }
1173
1174        ret = intel_overlay_recover_from_interrupt(overlay, true);
1175        if (ret != 0)
1176                goto out_unlock;
1177
1178        if (overlay->crtc != crtc) {
1179                struct drm_display_mode *mode = &crtc->base.mode;
1180                ret = intel_overlay_switch_off(overlay, true);
1181                if (ret != 0)
1182                        goto out_unlock;
1183
1184                ret = check_overlay_possible_on_crtc(overlay, crtc);
1185                if (ret != 0)
1186                        goto out_unlock;
1187
1188                overlay->crtc = crtc;
1189                crtc->overlay = overlay;
1190
1191                /* line too wide, i.e. one-line-mode */
1192                if (mode->hdisplay > 1024 &&
1193                    intel_panel_fitter_pipe(dev) == crtc->pipe) {
1194                        overlay->pfit_active = 1;
1195                        update_pfit_vscale_ratio(overlay);
1196                } else
1197                        overlay->pfit_active = 0;
1198        }
1199
1200        ret = check_overlay_dst(overlay, put_image_rec);
1201        if (ret != 0)
1202                goto out_unlock;
1203
1204        if (overlay->pfit_active) {
1205                params->dst_y = ((((u32)put_image_rec->dst_y) << 12) /
1206                                 overlay->pfit_vscale_ratio);
1207                /* shifting right rounds downwards, so add 1 */
1208                params->dst_h = ((((u32)put_image_rec->dst_height) << 12) /
1209                                 overlay->pfit_vscale_ratio) + 1;
1210        } else {
1211                params->dst_y = put_image_rec->dst_y;
1212                params->dst_h = put_image_rec->dst_height;
1213        }
1214        params->dst_x = put_image_rec->dst_x;
1215        params->dst_w = put_image_rec->dst_width;
1216
1217        params->src_w = put_image_rec->src_width;
1218        params->src_h = put_image_rec->src_height;
1219        params->src_scan_w = put_image_rec->src_scan_width;
1220        params->src_scan_h = put_image_rec->src_scan_height;
1221        if (params->src_scan_h > params->src_h ||
1222            params->src_scan_w > params->src_w) {
1223                ret = -EINVAL;
1224                goto out_unlock;
1225        }
1226
1227        ret = check_overlay_src(dev, put_image_rec, new_bo);
1228        if (ret != 0)
1229                goto out_unlock;
1230        params->format = put_image_rec->flags & ~I915_OVERLAY_FLAGS_MASK;
1231        params->stride_Y = put_image_rec->stride_Y;
1232        params->stride_UV = put_image_rec->stride_UV;
1233        params->offset_Y = put_image_rec->offset_Y;
1234        params->offset_U = put_image_rec->offset_U;
1235        params->offset_V = put_image_rec->offset_V;
1236
1237        /* Check scaling after src size to prevent a divide-by-zero. */
1238        ret = check_overlay_scaling(params);
1239        if (ret != 0)
1240                goto out_unlock;
1241
1242        ret = intel_overlay_do_put_image(overlay, new_bo, params);
1243        if (ret != 0)
1244                goto out_unlock;
1245
1246        mutex_unlock(&dev->struct_mutex);
1247        mutex_unlock(&dev->mode_config.mutex);
1248
1249        kfree(params);
1250
1251        return 0;
1252
1253out_unlock:
1254        mutex_unlock(&dev->struct_mutex);
1255        mutex_unlock(&dev->mode_config.mutex);
1256        drm_gem_object_unreference_unlocked(&new_bo->base);
1257out_free:
1258        kfree(params);
1259
1260        return ret;
1261}
1262
1263static void update_reg_attrs(struct intel_overlay *overlay,
1264                             struct overlay_registers *regs)
1265{
1266        regs->OCLRC0 = (overlay->contrast << 18) | (overlay->brightness & 0xff);
1267        regs->OCLRC1 = overlay->saturation;
1268}
1269
1270static bool check_gamma_bounds(u32 gamma1, u32 gamma2)
1271{
1272        int i;
1273
1274        if (gamma1 & 0xff000000 || gamma2 & 0xff000000)
1275                return false;
1276
1277        for (i = 0; i < 3; i++) {
1278                if (((gamma1 >> i*8) & 0xff) >= ((gamma2 >> i*8) & 0xff))
1279                        return false;
1280        }
1281
1282        return true;
1283}
1284
1285static bool check_gamma5_errata(u32 gamma5)
1286{
1287        int i;
1288
1289        for (i = 0; i < 3; i++) {
1290                if (((gamma5 >> i*8) & 0xff) == 0x80)
1291                        return false;
1292        }
1293
1294        return true;
1295}
1296
1297static int check_gamma(struct drm_intel_overlay_attrs *attrs)
1298{
1299        if (!check_gamma_bounds(0, attrs->gamma0) ||
1300            !check_gamma_bounds(attrs->gamma0, attrs->gamma1) ||
1301            !check_gamma_bounds(attrs->gamma1, attrs->gamma2) ||
1302            !check_gamma_bounds(attrs->gamma2, attrs->gamma3) ||
1303            !check_gamma_bounds(attrs->gamma3, attrs->gamma4) ||
1304            !check_gamma_bounds(attrs->gamma4, attrs->gamma5) ||
1305            !check_gamma_bounds(attrs->gamma5, 0x00ffffff))
1306                return -EINVAL;
1307
1308        if (!check_gamma5_errata(attrs->gamma5))
1309                return -EINVAL;
1310
1311        return 0;
1312}
1313
1314int intel_overlay_attrs(struct drm_device *dev, void *data,
1315                        struct drm_file *file_priv)
1316{
1317        struct drm_intel_overlay_attrs *attrs = data;
1318        drm_i915_private_t *dev_priv = dev->dev_private;
1319        struct intel_overlay *overlay;
1320        struct overlay_registers *regs;
1321        int ret;
1322
1323        if (!dev_priv) {
1324                DRM_ERROR("called with no initialization\n");
1325                return -EINVAL;
1326        }
1327
1328        overlay = dev_priv->overlay;
1329        if (!overlay) {
1330                DRM_DEBUG("userspace bug: no overlay\n");
1331                return -ENODEV;
1332        }
1333
1334        mutex_lock(&dev->mode_config.mutex);
1335        mutex_lock(&dev->struct_mutex);
1336
1337        ret = -EINVAL;
1338        if (!(attrs->flags & I915_OVERLAY_UPDATE_ATTRS)) {
1339                attrs->color_key  = overlay->color_key;
1340                attrs->brightness = overlay->brightness;
1341                attrs->contrast   = overlay->contrast;
1342                attrs->saturation = overlay->saturation;
1343
1344                if (!IS_GEN2(dev)) {
1345                        attrs->gamma0 = I915_READ(OGAMC0);
1346                        attrs->gamma1 = I915_READ(OGAMC1);
1347                        attrs->gamma2 = I915_READ(OGAMC2);
1348                        attrs->gamma3 = I915_READ(OGAMC3);
1349                        attrs->gamma4 = I915_READ(OGAMC4);
1350                        attrs->gamma5 = I915_READ(OGAMC5);
1351                }
1352        } else {
1353                if (attrs->brightness < -128 || attrs->brightness > 127)
1354                        goto out_unlock;
1355                if (attrs->contrast > 255)
1356                        goto out_unlock;
1357                if (attrs->saturation > 1023)
1358                        goto out_unlock;
1359
1360                overlay->color_key  = attrs->color_key;
1361                overlay->brightness = attrs->brightness;
1362                overlay->contrast   = attrs->contrast;
1363                overlay->saturation = attrs->saturation;
1364
1365                regs = intel_overlay_map_regs(overlay);
1366                if (!regs) {
1367                        ret = -ENOMEM;
1368                        goto out_unlock;
1369                }
1370
1371                update_reg_attrs(overlay, regs);
1372
1373                intel_overlay_unmap_regs(overlay, regs);
1374
1375                if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) {
1376                        if (IS_GEN2(dev))
1377                                goto out_unlock;
1378
1379                        if (overlay->active) {
1380                                ret = -EBUSY;
1381                                goto out_unlock;
1382                        }
1383
1384                        ret = check_gamma(attrs);
1385                        if (ret)
1386                                goto out_unlock;
1387
1388                        I915_WRITE(OGAMC0, attrs->gamma0);
1389                        I915_WRITE(OGAMC1, attrs->gamma1);
1390                        I915_WRITE(OGAMC2, attrs->gamma2);
1391                        I915_WRITE(OGAMC3, attrs->gamma3);
1392                        I915_WRITE(OGAMC4, attrs->gamma4);
1393                        I915_WRITE(OGAMC5, attrs->gamma5);
1394                }
1395        }
1396
1397        ret = 0;
1398out_unlock:
1399        mutex_unlock(&dev->struct_mutex);
1400        mutex_unlock(&dev->mode_config.mutex);
1401
1402        return ret;
1403}
1404
1405void intel_setup_overlay(struct drm_device *dev)
1406{
1407        drm_i915_private_t *dev_priv = dev->dev_private;
1408        struct intel_overlay *overlay;
1409        struct drm_i915_gem_object *reg_bo;
1410        struct overlay_registers *regs;
1411        int ret;
1412
1413        if (!HAS_OVERLAY(dev))
1414                return;
1415
1416        overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL);
1417        if (!overlay)
1418                return;
1419        overlay->dev = dev;
1420
1421        reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE);
1422        if (!reg_bo)
1423                goto out_free;
1424        overlay->reg_bo = reg_bo;
1425
1426        if (OVERLAY_NEEDS_PHYSICAL(dev)) {
1427                ret = i915_gem_attach_phys_object(dev, reg_bo,
1428                                                  I915_GEM_PHYS_OVERLAY_REGS,
1429                                                  PAGE_SIZE);
1430                if (ret) {
1431                        DRM_ERROR("failed to attach phys overlay regs\n");
1432                        goto out_free_bo;
1433                }
1434                overlay->flip_addr = reg_bo->phys_obj->handle->busaddr;
1435        } else {
1436                ret = i915_gem_object_pin(reg_bo, PAGE_SIZE, true);
1437                if (ret) {
1438                        DRM_ERROR("failed to pin overlay register bo\n");
1439                        goto out_free_bo;
1440                }
1441                overlay->flip_addr = reg_bo->gtt_offset;
1442
1443                ret = i915_gem_object_set_to_gtt_domain(reg_bo, true);
1444                if (ret) {
1445                        DRM_ERROR("failed to move overlay register bo into the GTT\n");
1446                        goto out_unpin_bo;
1447                }
1448        }
1449
1450        /* init all values */
1451        overlay->color_key = 0x0101fe;
1452        overlay->brightness = -19;
1453        overlay->contrast = 75;
1454        overlay->saturation = 146;
1455
1456        regs = intel_overlay_map_regs(overlay);
1457        if (!regs)
1458                goto out_free_bo;
1459
1460        memset(regs, 0, sizeof(struct overlay_registers));
1461        update_polyphase_filter(regs);
1462        update_reg_attrs(overlay, regs);
1463
1464        intel_overlay_unmap_regs(overlay, regs);
1465
1466        dev_priv->overlay = overlay;
1467        DRM_INFO("initialized overlay support\n");
1468        return;
1469
1470out_unpin_bo:
1471        i915_gem_object_unpin(reg_bo);
1472out_free_bo:
1473        drm_gem_object_unreference(&reg_bo->base);
1474out_free:
1475        kfree(overlay);
1476        return;
1477}
1478
1479void intel_cleanup_overlay(struct drm_device *dev)
1480{
1481        drm_i915_private_t *dev_priv = dev->dev_private;
1482
1483        if (!dev_priv->overlay)
1484                return;
1485
1486        /* The bo's should be free'd by the generic code already.
1487         * Furthermore modesetting teardown happens beforehand so the
1488         * hardware should be off already */
1489        BUG_ON(dev_priv->overlay->active);
1490
1491        drm_gem_object_unreference_unlocked(&dev_priv->overlay->reg_bo->base);
1492        kfree(dev_priv->overlay);
1493}
1494
1495#ifdef CONFIG_DEBUG_FS
1496#include <linux/seq_file.h>
1497
1498struct intel_overlay_error_state {
1499        struct overlay_registers regs;
1500        unsigned long base;
1501        u32 dovsta;
1502        u32 isr;
1503};
1504
1505static struct overlay_registers *
1506intel_overlay_map_regs_atomic(struct intel_overlay *overlay)
1507{
1508        drm_i915_private_t *dev_priv = overlay->dev->dev_private;
1509        struct overlay_registers *regs;
1510
1511        if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
1512                regs = overlay->reg_bo->phys_obj->handle->vaddr;
1513        else
1514                regs = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
1515                                                overlay->reg_bo->gtt_offset);
1516
1517        return regs;
1518}
1519
1520static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay,
1521                                            struct overlay_registers *regs)
1522{
1523        if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
1524                io_mapping_unmap_atomic(regs);
1525}
1526
1527
1528struct intel_overlay_error_state *
1529intel_overlay_capture_error_state(struct drm_device *dev)
1530{
1531        drm_i915_private_t *dev_priv = dev->dev_private;
1532        struct intel_overlay *overlay = dev_priv->overlay;
1533        struct intel_overlay_error_state *error;
1534        struct overlay_registers __iomem *regs;
1535
1536        if (!overlay || !overlay->active)
1537                return NULL;
1538
1539        error = kmalloc(sizeof(*error), GFP_ATOMIC);
1540        if (error == NULL)
1541                return NULL;
1542
1543        error->dovsta = I915_READ(DOVSTA);
1544        error->isr = I915_READ(ISR);
1545        if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
1546                error->base = (long) overlay->reg_bo->phys_obj->handle->vaddr;
1547        else
1548                error->base = (long) overlay->reg_bo->gtt_offset;
1549
1550        regs = intel_overlay_map_regs_atomic(overlay);
1551        if (!regs)
1552                goto err;
1553
1554        memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers));
1555        intel_overlay_unmap_regs_atomic(overlay, regs);
1556
1557        return error;
1558
1559err:
1560        kfree(error);
1561        return NULL;
1562}
1563
1564void
1565intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error)
1566{
1567        seq_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n",
1568                   error->dovsta, error->isr);
1569        seq_printf(m, "  Register file at 0x%08lx:\n",
1570                   error->base);
1571
1572#define P(x) seq_printf(m, "    " #x ": 0x%08x\n", error->regs.x)
1573        P(OBUF_0Y);
1574        P(OBUF_1Y);
1575        P(OBUF_0U);
1576        P(OBUF_0V);
1577        P(OBUF_1U);
1578        P(OBUF_1V);
1579        P(OSTRIDE);
1580        P(YRGB_VPH);
1581        P(UV_VPH);
1582        P(HORZ_PH);
1583        P(INIT_PHS);
1584        P(DWINPOS);
1585        P(DWINSZ);
1586        P(SWIDTH);
1587        P(SWIDTHSW);
1588        P(SHEIGHT);
1589        P(YRGBSCALE);
1590        P(UVSCALE);
1591        P(OCLRC0);
1592        P(OCLRC1);
1593        P(DCLRKV);
1594        P(DCLRKM);
1595        P(SCLRKVH);
1596        P(SCLRKVL);
1597        P(SCLRKEN);
1598        P(OCONFIG);
1599        P(OCMD);
1600        P(OSTART_0Y);
1601        P(OSTART_1Y);
1602        P(OSTART_0U);
1603        P(OSTART_0V);
1604        P(OSTART_1U);
1605        P(OSTART_1V);
1606        P(OTILEOFF_0Y);
1607        P(OTILEOFF_1Y);
1608        P(OTILEOFF_0U);
1609        P(OTILEOFF_0V);
1610        P(OTILEOFF_1U);
1611        P(OTILEOFF_1V);
1612        P(FASTHSCALE);
1613        P(UVSCALEV);
1614#undef P
1615}
1616#endif
1617