Subversion Repositories Kolibri OS

Rev

Rev 4560 | Rev 5354 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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. #include <drm/drmP.h>
  33. #include <drm/drm_crtc.h>
  34. #include <drm/drm_fourcc.h>
  35. #include <drm/drm_rect.h>
  36. #include "intel_drv.h"
  37. #include <drm/i915_drm.h>
  38. #include "i915_drv.h"
  39.  
  40. static int usecs_to_scanlines(const struct drm_display_mode *mode, int usecs)
  41. {
  42.         /* paranoia */
  43.         if (!mode->crtc_htotal)
  44.                 return 1;
  45.  
  46.         return DIV_ROUND_UP(usecs * mode->crtc_clock, 1000 * mode->crtc_htotal);
  47. }
  48.  
  49. static bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl_count)
  50. {
  51.         struct drm_device *dev = crtc->base.dev;
  52.         const struct drm_display_mode *mode = &crtc->config.adjusted_mode;
  53.         enum pipe pipe = crtc->pipe;
  54.         long timeout = msecs_to_jiffies_timeout(1);
  55.         int scanline, min, max, vblank_start;
  56.         DEFINE_WAIT(wait);
  57.  
  58.         WARN_ON(!drm_modeset_is_locked(&crtc->base.mutex));
  59.  
  60.         vblank_start = mode->crtc_vblank_start;
  61.         if (mode->flags & DRM_MODE_FLAG_INTERLACE)
  62.                 vblank_start = DIV_ROUND_UP(vblank_start, 2);
  63.  
  64.         /* FIXME needs to be calibrated sensibly */
  65.         min = vblank_start - usecs_to_scanlines(mode, 100);
  66.         max = vblank_start - 1;
  67.  
  68.         if (min <= 0 || max <= 0)
  69.                 return false;
  70.  
  71. //   if (WARN_ON(drm_vblank_get(dev, pipe)))
  72. //       return false;
  73.  
  74. //   local_irq_disable();
  75.  
  76. //   trace_i915_pipe_update_start(crtc, min, max);
  77.  
  78.         for (;;) {
  79.                 /*
  80.                  * prepare_to_wait() has a memory barrier, which guarantees
  81.                  * other CPUs can see the task state update by the time we
  82.                  * read the scanline.
  83.                  */
  84.                 prepare_to_wait(&crtc->vbl_wait, &wait, TASK_UNINTERRUPTIBLE);
  85.  
  86.                 scanline = intel_get_crtc_scanline(crtc);
  87.                 if (scanline < min || scanline > max)
  88.                         break;
  89.  
  90.                 if (timeout <= 0) {
  91.                         DRM_ERROR("Potential atomic update failure on pipe %c\n",
  92.                                   pipe_name(crtc->pipe));
  93.                         break;
  94.                 }
  95.  
  96. //       local_irq_enable();
  97.  
  98.         schedule_timeout(timeout);
  99.         timeout = 0;
  100. //       local_irq_disable();
  101.         }
  102.  
  103.         finish_wait(&crtc->vbl_wait, &wait);
  104.  
  105. //   drm_vblank_put(dev, pipe);
  106.  
  107.         *start_vbl_count = dev->driver->get_vblank_counter(dev, pipe);
  108.  
  109. //   trace_i915_pipe_update_vblank_evaded(crtc, min, max, *start_vbl_count);
  110.  
  111.         return true;
  112. }
  113.  
  114. static void intel_pipe_update_end(struct intel_crtc *crtc, u32 start_vbl_count)
  115. {
  116.         struct drm_device *dev = crtc->base.dev;
  117.         enum pipe pipe = crtc->pipe;
  118.         u32 end_vbl_count = dev->driver->get_vblank_counter(dev, pipe);
  119.  
  120. //   trace_i915_pipe_update_end(crtc, end_vbl_count);
  121.  
  122. //   local_irq_enable();
  123.  
  124.         if (start_vbl_count != end_vbl_count)
  125.                 DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u)\n",
  126.                           pipe_name(pipe), start_vbl_count, end_vbl_count);
  127. }
  128.  
  129. static void intel_update_primary_plane(struct intel_crtc *crtc)
  130. {
  131.         struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
  132.         int reg = DSPCNTR(crtc->plane);
  133.  
  134.         if (crtc->primary_enabled)
  135.                 I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE);
  136.         else
  137.                 I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE);
  138. }
  139.  
  140. static void
  141. vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
  142.                  struct drm_framebuffer *fb,
  143.                  struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
  144.                  unsigned int crtc_w, unsigned int crtc_h,
  145.                  uint32_t x, uint32_t y,
  146.                  uint32_t src_w, uint32_t src_h)
  147. {
  148.         struct drm_device *dev = dplane->dev;
  149.         struct drm_i915_private *dev_priv = dev->dev_private;
  150.         struct intel_plane *intel_plane = to_intel_plane(dplane);
  151.         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  152.         int pipe = intel_plane->pipe;
  153.         int plane = intel_plane->plane;
  154.         u32 sprctl;
  155.         unsigned long sprsurf_offset, linear_offset;
  156.         int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
  157.         u32 start_vbl_count;
  158.         bool atomic_update;
  159.  
  160.         sprctl = I915_READ(SPCNTR(pipe, plane));
  161.  
  162.         /* Mask out pixel format bits in case we change it */
  163.         sprctl &= ~SP_PIXFORMAT_MASK;
  164.         sprctl &= ~SP_YUV_BYTE_ORDER_MASK;
  165.         sprctl &= ~SP_TILED;
  166.  
  167.         switch (fb->pixel_format) {
  168.         case DRM_FORMAT_YUYV:
  169.                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV;
  170.                 break;
  171.         case DRM_FORMAT_YVYU:
  172.                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU;
  173.                 break;
  174.         case DRM_FORMAT_UYVY:
  175.                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY;
  176.                 break;
  177.         case DRM_FORMAT_VYUY:
  178.                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY;
  179.                 break;
  180.         case DRM_FORMAT_RGB565:
  181.                 sprctl |= SP_FORMAT_BGR565;
  182.                 break;
  183.         case DRM_FORMAT_XRGB8888:
  184.                 sprctl |= SP_FORMAT_BGRX8888;
  185.                 break;
  186.         case DRM_FORMAT_ARGB8888:
  187.                 sprctl |= SP_FORMAT_BGRA8888;
  188.                 break;
  189.         case DRM_FORMAT_XBGR2101010:
  190.                 sprctl |= SP_FORMAT_RGBX1010102;
  191.                 break;
  192.         case DRM_FORMAT_ABGR2101010:
  193.                 sprctl |= SP_FORMAT_RGBA1010102;
  194.                 break;
  195.         case DRM_FORMAT_XBGR8888:
  196.                 sprctl |= SP_FORMAT_RGBX8888;
  197.                 break;
  198.         case DRM_FORMAT_ABGR8888:
  199.                 sprctl |= SP_FORMAT_RGBA8888;
  200.                 break;
  201.         default:
  202.                 /*
  203.                  * If we get here one of the upper layers failed to filter
  204.                  * out the unsupported plane formats
  205.                  */
  206.                 BUG();
  207.                 break;
  208.         }
  209.  
  210.         /*
  211.          * Enable gamma to match primary/cursor plane behaviour.
  212.          * FIXME should be user controllable via propertiesa.
  213.          */
  214.         sprctl |= SP_GAMMA_ENABLE;
  215.  
  216.         if (obj->tiling_mode != I915_TILING_NONE)
  217.                 sprctl |= SP_TILED;
  218.  
  219.         sprctl |= SP_ENABLE;
  220.  
  221.         intel_update_sprite_watermarks(dplane, crtc, src_w, src_h,
  222.                                        pixel_size, true,
  223.                                        src_w != crtc_w || src_h != crtc_h);
  224.  
  225.         /* Sizes are 0 based */
  226.         src_w--;
  227.         src_h--;
  228.         crtc_w--;
  229.         crtc_h--;
  230.  
  231.         linear_offset = y * fb->pitches[0] + x * pixel_size;
  232.         sprsurf_offset = intel_gen4_compute_page_offset(&x, &y,
  233.                                                         obj->tiling_mode,
  234.                                                         pixel_size,
  235.                                                         fb->pitches[0]);
  236.         linear_offset -= sprsurf_offset;
  237.  
  238.         atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
  239.  
  240.         intel_update_primary_plane(intel_crtc);
  241.  
  242.         I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]);
  243.         I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x);
  244.  
  245.         if (obj->tiling_mode != I915_TILING_NONE)
  246.                 I915_WRITE(SPTILEOFF(pipe, plane), (y << 16) | x);
  247.         else
  248.                 I915_WRITE(SPLINOFF(pipe, plane), linear_offset);
  249.  
  250.         I915_WRITE(SPSIZE(pipe, plane), (crtc_h << 16) | crtc_w);
  251.         I915_WRITE(SPCNTR(pipe, plane), sprctl);
  252.         I915_WRITE(SPSURF(pipe, plane), i915_gem_obj_ggtt_offset(obj) +
  253.                              sprsurf_offset);
  254.  
  255.         intel_flush_primary_plane(dev_priv, intel_crtc->plane);
  256.  
  257.         if (atomic_update)
  258.                 intel_pipe_update_end(intel_crtc, start_vbl_count);
  259. }
  260.  
  261. static void
  262. vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc)
  263. {
  264.         struct drm_device *dev = dplane->dev;
  265.         struct drm_i915_private *dev_priv = dev->dev_private;
  266.         struct intel_plane *intel_plane = to_intel_plane(dplane);
  267.         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  268.         int pipe = intel_plane->pipe;
  269.         int plane = intel_plane->plane;
  270.         u32 start_vbl_count;
  271.         bool atomic_update;
  272.  
  273.         atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
  274.  
  275.         intel_update_primary_plane(intel_crtc);
  276.  
  277.         I915_WRITE(SPCNTR(pipe, plane), I915_READ(SPCNTR(pipe, plane)) &
  278.                    ~SP_ENABLE);
  279.         /* Activate double buffered register update */
  280.         I915_WRITE(SPSURF(pipe, plane), 0);
  281.  
  282.         intel_flush_primary_plane(dev_priv, intel_crtc->plane);
  283.  
  284.         if (atomic_update)
  285.                 intel_pipe_update_end(intel_crtc, start_vbl_count);
  286.  
  287.         intel_update_sprite_watermarks(dplane, crtc, 0, 0, 0, false, false);
  288. }
  289.  
  290. static int
  291. vlv_update_colorkey(struct drm_plane *dplane,
  292.                     struct drm_intel_sprite_colorkey *key)
  293. {
  294.         struct drm_device *dev = dplane->dev;
  295.         struct drm_i915_private *dev_priv = dev->dev_private;
  296.         struct intel_plane *intel_plane = to_intel_plane(dplane);
  297.         int pipe = intel_plane->pipe;
  298.         int plane = intel_plane->plane;
  299.         u32 sprctl;
  300.  
  301.         if (key->flags & I915_SET_COLORKEY_DESTINATION)
  302.                 return -EINVAL;
  303.  
  304.         I915_WRITE(SPKEYMINVAL(pipe, plane), key->min_value);
  305.         I915_WRITE(SPKEYMAXVAL(pipe, plane), key->max_value);
  306.         I915_WRITE(SPKEYMSK(pipe, plane), key->channel_mask);
  307.  
  308.         sprctl = I915_READ(SPCNTR(pipe, plane));
  309.         sprctl &= ~SP_SOURCE_KEY;
  310.         if (key->flags & I915_SET_COLORKEY_SOURCE)
  311.                 sprctl |= SP_SOURCE_KEY;
  312.         I915_WRITE(SPCNTR(pipe, plane), sprctl);
  313.  
  314.         POSTING_READ(SPKEYMSK(pipe, plane));
  315.  
  316.         return 0;
  317. }
  318.  
  319. static void
  320. vlv_get_colorkey(struct drm_plane *dplane,
  321.                  struct drm_intel_sprite_colorkey *key)
  322. {
  323.         struct drm_device *dev = dplane->dev;
  324.         struct drm_i915_private *dev_priv = dev->dev_private;
  325.         struct intel_plane *intel_plane = to_intel_plane(dplane);
  326.         int pipe = intel_plane->pipe;
  327.         int plane = intel_plane->plane;
  328.         u32 sprctl;
  329.  
  330.         key->min_value = I915_READ(SPKEYMINVAL(pipe, plane));
  331.         key->max_value = I915_READ(SPKEYMAXVAL(pipe, plane));
  332.         key->channel_mask = I915_READ(SPKEYMSK(pipe, plane));
  333.  
  334.         sprctl = I915_READ(SPCNTR(pipe, plane));
  335.         if (sprctl & SP_SOURCE_KEY)
  336.                 key->flags = I915_SET_COLORKEY_SOURCE;
  337.         else
  338.                 key->flags = I915_SET_COLORKEY_NONE;
  339. }
  340.  
  341. static void
  342. ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
  343.                  struct drm_framebuffer *fb,
  344.                  struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
  345.                  unsigned int crtc_w, unsigned int crtc_h,
  346.                  uint32_t x, uint32_t y,
  347.                  uint32_t src_w, uint32_t src_h)
  348. {
  349.         struct drm_device *dev = plane->dev;
  350.         struct drm_i915_private *dev_priv = dev->dev_private;
  351.         struct intel_plane *intel_plane = to_intel_plane(plane);
  352.         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  353.         int pipe = intel_plane->pipe;
  354.         u32 sprctl, sprscale = 0;
  355.         unsigned long sprsurf_offset, linear_offset;
  356.         int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
  357.         u32 start_vbl_count;
  358.         bool atomic_update;
  359.  
  360.         sprctl = I915_READ(SPRCTL(pipe));
  361.  
  362.         /* Mask out pixel format bits in case we change it */
  363.         sprctl &= ~SPRITE_PIXFORMAT_MASK;
  364.         sprctl &= ~SPRITE_RGB_ORDER_RGBX;
  365.         sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK;
  366.         sprctl &= ~SPRITE_TILED;
  367.  
  368.         switch (fb->pixel_format) {
  369.         case DRM_FORMAT_XBGR8888:
  370.                 sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
  371.                 break;
  372.         case DRM_FORMAT_XRGB8888:
  373.                 sprctl |= SPRITE_FORMAT_RGBX888;
  374.                 break;
  375.         case DRM_FORMAT_YUYV:
  376.                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
  377.                 break;
  378.         case DRM_FORMAT_YVYU:
  379.                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
  380.                 break;
  381.         case DRM_FORMAT_UYVY:
  382.                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
  383.                 break;
  384.         case DRM_FORMAT_VYUY:
  385.                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
  386.                 break;
  387.         default:
  388.                 BUG();
  389.         }
  390.  
  391.         /*
  392.          * Enable gamma to match primary/cursor plane behaviour.
  393.          * FIXME should be user controllable via propertiesa.
  394.          */
  395.         sprctl |= SPRITE_GAMMA_ENABLE;
  396.  
  397.         if (obj->tiling_mode != I915_TILING_NONE)
  398.                 sprctl |= SPRITE_TILED;
  399.  
  400.         if (IS_HASWELL(dev) || IS_BROADWELL(dev))
  401.                 sprctl &= ~SPRITE_TRICKLE_FEED_DISABLE;
  402.         else
  403.         sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
  404.  
  405.         sprctl |= SPRITE_ENABLE;
  406.  
  407.         if (IS_HASWELL(dev) || IS_BROADWELL(dev))
  408.                 sprctl |= SPRITE_PIPE_CSC_ENABLE;
  409.  
  410.         intel_update_sprite_watermarks(plane, crtc, src_w, src_h, pixel_size,
  411.                                        true,
  412.                                        src_w != crtc_w || src_h != crtc_h);
  413.  
  414.         /* Sizes are 0 based */
  415.         src_w--;
  416.         src_h--;
  417.         crtc_w--;
  418.         crtc_h--;
  419.  
  420.         if (crtc_w != src_w || crtc_h != src_h)
  421.                 sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
  422.  
  423.         linear_offset = y * fb->pitches[0] + x * pixel_size;
  424.         sprsurf_offset =
  425.                 intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode,
  426.                                                  pixel_size, fb->pitches[0]);
  427.         linear_offset -= sprsurf_offset;
  428.  
  429.         atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
  430.  
  431.         intel_update_primary_plane(intel_crtc);
  432.  
  433.         I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]);
  434.         I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
  435.  
  436.         /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
  437.          * register */
  438.         if (IS_HASWELL(dev) || IS_BROADWELL(dev))
  439.                 I915_WRITE(SPROFFSET(pipe), (y << 16) | x);
  440.         else if (obj->tiling_mode != I915_TILING_NONE)
  441.                 I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x);
  442.         else
  443.                 I915_WRITE(SPRLINOFF(pipe), linear_offset);
  444.  
  445.         I915_WRITE(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
  446.         if (intel_plane->can_scale)
  447.         I915_WRITE(SPRSCALE(pipe), sprscale);
  448.         I915_WRITE(SPRCTL(pipe), sprctl);
  449.         I915_WRITE(SPRSURF(pipe),
  450.                              i915_gem_obj_ggtt_offset(obj) + sprsurf_offset);
  451.  
  452.         intel_flush_primary_plane(dev_priv, intel_crtc->plane);
  453.  
  454.         if (atomic_update)
  455.                 intel_pipe_update_end(intel_crtc, start_vbl_count);
  456. }
  457.  
  458. static void
  459. ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)
  460. {
  461.         struct drm_device *dev = plane->dev;
  462.         struct drm_i915_private *dev_priv = dev->dev_private;
  463.         struct intel_plane *intel_plane = to_intel_plane(plane);
  464.         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  465.         int pipe = intel_plane->pipe;
  466.         u32 start_vbl_count;
  467.         bool atomic_update;
  468.  
  469.         atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
  470.  
  471.         intel_update_primary_plane(intel_crtc);
  472.  
  473.         I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE);
  474.         /* Can't leave the scaler enabled... */
  475.         if (intel_plane->can_scale)
  476.         I915_WRITE(SPRSCALE(pipe), 0);
  477.         /* Activate double buffered register update */
  478.         I915_WRITE(SPRSURF(pipe), 0);
  479.  
  480.         intel_flush_primary_plane(dev_priv, intel_crtc->plane);
  481.  
  482.         if (atomic_update)
  483.                 intel_pipe_update_end(intel_crtc, start_vbl_count);
  484.  
  485.         /*
  486.          * Avoid underruns when disabling the sprite.
  487.          * FIXME remove once watermark updates are done properly.
  488.          */
  489.         intel_wait_for_vblank(dev, pipe);
  490.  
  491.         intel_update_sprite_watermarks(plane, crtc, 0, 0, 0, false, false);
  492. }
  493.  
  494. static int
  495. ivb_update_colorkey(struct drm_plane *plane,
  496.                     struct drm_intel_sprite_colorkey *key)
  497. {
  498.         struct drm_device *dev = plane->dev;
  499.         struct drm_i915_private *dev_priv = dev->dev_private;
  500.         struct intel_plane *intel_plane;
  501.         u32 sprctl;
  502.         int ret = 0;
  503.  
  504.         intel_plane = to_intel_plane(plane);
  505.  
  506.         I915_WRITE(SPRKEYVAL(intel_plane->pipe), key->min_value);
  507.         I915_WRITE(SPRKEYMAX(intel_plane->pipe), key->max_value);
  508.         I915_WRITE(SPRKEYMSK(intel_plane->pipe), key->channel_mask);
  509.  
  510.         sprctl = I915_READ(SPRCTL(intel_plane->pipe));
  511.         sprctl &= ~(SPRITE_SOURCE_KEY | SPRITE_DEST_KEY);
  512.         if (key->flags & I915_SET_COLORKEY_DESTINATION)
  513.                 sprctl |= SPRITE_DEST_KEY;
  514.         else if (key->flags & I915_SET_COLORKEY_SOURCE)
  515.                 sprctl |= SPRITE_SOURCE_KEY;
  516.         I915_WRITE(SPRCTL(intel_plane->pipe), sprctl);
  517.  
  518.         POSTING_READ(SPRKEYMSK(intel_plane->pipe));
  519.  
  520.         return ret;
  521. }
  522.  
  523. static void
  524. ivb_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key)
  525. {
  526.         struct drm_device *dev = plane->dev;
  527.         struct drm_i915_private *dev_priv = dev->dev_private;
  528.         struct intel_plane *intel_plane;
  529.         u32 sprctl;
  530.  
  531.         intel_plane = to_intel_plane(plane);
  532.  
  533.         key->min_value = I915_READ(SPRKEYVAL(intel_plane->pipe));
  534.         key->max_value = I915_READ(SPRKEYMAX(intel_plane->pipe));
  535.         key->channel_mask = I915_READ(SPRKEYMSK(intel_plane->pipe));
  536.         key->flags = 0;
  537.  
  538.         sprctl = I915_READ(SPRCTL(intel_plane->pipe));
  539.  
  540.         if (sprctl & SPRITE_DEST_KEY)
  541.                 key->flags = I915_SET_COLORKEY_DESTINATION;
  542.         else if (sprctl & SPRITE_SOURCE_KEY)
  543.                 key->flags = I915_SET_COLORKEY_SOURCE;
  544.         else
  545.                 key->flags = I915_SET_COLORKEY_NONE;
  546. }
  547.  
  548. static void
  549. ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
  550.                  struct drm_framebuffer *fb,
  551.                  struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
  552.                  unsigned int crtc_w, unsigned int crtc_h,
  553.                  uint32_t x, uint32_t y,
  554.                  uint32_t src_w, uint32_t src_h)
  555. {
  556.         struct drm_device *dev = plane->dev;
  557.         struct drm_i915_private *dev_priv = dev->dev_private;
  558.         struct intel_plane *intel_plane = to_intel_plane(plane);
  559.         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  560.         int pipe = intel_plane->pipe;
  561.         unsigned long dvssurf_offset, linear_offset;
  562.         u32 dvscntr, dvsscale;
  563.         int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
  564.         u32 start_vbl_count;
  565.         bool atomic_update;
  566.  
  567.         dvscntr = I915_READ(DVSCNTR(pipe));
  568.  
  569.         /* Mask out pixel format bits in case we change it */
  570.         dvscntr &= ~DVS_PIXFORMAT_MASK;
  571.         dvscntr &= ~DVS_RGB_ORDER_XBGR;
  572.         dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK;
  573.         dvscntr &= ~DVS_TILED;
  574.  
  575.         switch (fb->pixel_format) {
  576.         case DRM_FORMAT_XBGR8888:
  577.                 dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR;
  578.                 break;
  579.         case DRM_FORMAT_XRGB8888:
  580.                 dvscntr |= DVS_FORMAT_RGBX888;
  581.                 break;
  582.         case DRM_FORMAT_YUYV:
  583.                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
  584.                 break;
  585.         case DRM_FORMAT_YVYU:
  586.                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
  587.                 break;
  588.         case DRM_FORMAT_UYVY:
  589.                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
  590.                 break;
  591.         case DRM_FORMAT_VYUY:
  592.                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
  593.                 break;
  594.         default:
  595.                 BUG();
  596.         }
  597.  
  598.         /*
  599.          * Enable gamma to match primary/cursor plane behaviour.
  600.          * FIXME should be user controllable via propertiesa.
  601.          */
  602.         dvscntr |= DVS_GAMMA_ENABLE;
  603.  
  604.         if (obj->tiling_mode != I915_TILING_NONE)
  605.                 dvscntr |= DVS_TILED;
  606.  
  607.         if (IS_GEN6(dev))
  608.                 dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */
  609.         dvscntr |= DVS_ENABLE;
  610.  
  611.         intel_update_sprite_watermarks(plane, crtc, src_w, src_h,
  612.                                        pixel_size, true,
  613.                                        src_w != crtc_w || src_h != crtc_h);
  614.  
  615.         /* Sizes are 0 based */
  616.         src_w--;
  617.         src_h--;
  618.         crtc_w--;
  619.         crtc_h--;
  620.  
  621.         dvsscale = 0;
  622.         if (crtc_w != src_w || crtc_h != src_h)
  623.                 dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h;
  624.  
  625.         linear_offset = y * fb->pitches[0] + x * pixel_size;
  626.         dvssurf_offset =
  627.                 intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode,
  628.                                                  pixel_size, fb->pitches[0]);
  629.         linear_offset -= dvssurf_offset;
  630.  
  631.         atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
  632.  
  633.         intel_update_primary_plane(intel_crtc);
  634.  
  635.         I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]);
  636.         I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
  637.  
  638.         if (obj->tiling_mode != I915_TILING_NONE)
  639.                 I915_WRITE(DVSTILEOFF(pipe), (y << 16) | x);
  640.         else
  641.                 I915_WRITE(DVSLINOFF(pipe), linear_offset);
  642.  
  643.         I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
  644.         I915_WRITE(DVSSCALE(pipe), dvsscale);
  645.         I915_WRITE(DVSCNTR(pipe), dvscntr);
  646.         I915_WRITE(DVSSURF(pipe),
  647.                              i915_gem_obj_ggtt_offset(obj) + dvssurf_offset);
  648.  
  649.         intel_flush_primary_plane(dev_priv, intel_crtc->plane);
  650.  
  651.         if (atomic_update)
  652.                 intel_pipe_update_end(intel_crtc, start_vbl_count);
  653. }
  654.  
  655. static void
  656. ilk_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)
  657. {
  658.         struct drm_device *dev = plane->dev;
  659.         struct drm_i915_private *dev_priv = dev->dev_private;
  660.         struct intel_plane *intel_plane = to_intel_plane(plane);
  661.         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  662.         int pipe = intel_plane->pipe;
  663.         u32 start_vbl_count;
  664.         bool atomic_update;
  665.  
  666.         atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
  667.  
  668.         intel_update_primary_plane(intel_crtc);
  669.  
  670.         I915_WRITE(DVSCNTR(pipe), I915_READ(DVSCNTR(pipe)) & ~DVS_ENABLE);
  671.         /* Disable the scaler */
  672.         I915_WRITE(DVSSCALE(pipe), 0);
  673.         /* Flush double buffered register updates */
  674.         I915_WRITE(DVSSURF(pipe), 0);
  675.  
  676.         intel_flush_primary_plane(dev_priv, intel_crtc->plane);
  677.  
  678.         if (atomic_update)
  679.                 intel_pipe_update_end(intel_crtc, start_vbl_count);
  680.  
  681.         /*
  682.          * Avoid underruns when disabling the sprite.
  683.          * FIXME remove once watermark updates are done properly.
  684.          */
  685.         intel_wait_for_vblank(dev, pipe);
  686.  
  687.         intel_update_sprite_watermarks(plane, crtc, 0, 0, 0, false, false);
  688. }
  689.  
  690. static void
  691. intel_post_enable_primary(struct drm_crtc *crtc)
  692. {
  693.         struct drm_device *dev = crtc->dev;
  694.         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  695.  
  696.         /*
  697.          * FIXME IPS should be fine as long as one plane is
  698.          * enabled, but in practice it seems to have problems
  699.          * when going from primary only to sprite only and vice
  700.          * versa.
  701.          */
  702.                 hsw_enable_ips(intel_crtc);
  703.  
  704.         mutex_lock(&dev->struct_mutex);
  705.         intel_update_fbc(dev);
  706.         mutex_unlock(&dev->struct_mutex);
  707. }
  708.  
  709. static void
  710. intel_pre_disable_primary(struct drm_crtc *crtc)
  711. {
  712.         struct drm_device *dev = crtc->dev;
  713.         struct drm_i915_private *dev_priv = dev->dev_private;
  714.         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  715.  
  716.         mutex_lock(&dev->struct_mutex);
  717.         if (dev_priv->fbc.plane == intel_crtc->plane)
  718.                 intel_disable_fbc(dev);
  719.         mutex_unlock(&dev->struct_mutex);
  720.  
  721.         /*
  722.          * FIXME IPS should be fine as long as one plane is
  723.          * enabled, but in practice it seems to have problems
  724.          * when going from primary only to sprite only and vice
  725.          * versa.
  726.          */
  727.         hsw_disable_ips(intel_crtc);
  728. }
  729.  
  730. static int
  731. ilk_update_colorkey(struct drm_plane *plane,
  732.                     struct drm_intel_sprite_colorkey *key)
  733. {
  734.         struct drm_device *dev = plane->dev;
  735.         struct drm_i915_private *dev_priv = dev->dev_private;
  736.         struct intel_plane *intel_plane;
  737.         u32 dvscntr;
  738.         int ret = 0;
  739.  
  740.         intel_plane = to_intel_plane(plane);
  741.  
  742.         I915_WRITE(DVSKEYVAL(intel_plane->pipe), key->min_value);
  743.         I915_WRITE(DVSKEYMAX(intel_plane->pipe), key->max_value);
  744.         I915_WRITE(DVSKEYMSK(intel_plane->pipe), key->channel_mask);
  745.  
  746.         dvscntr = I915_READ(DVSCNTR(intel_plane->pipe));
  747.         dvscntr &= ~(DVS_SOURCE_KEY | DVS_DEST_KEY);
  748.         if (key->flags & I915_SET_COLORKEY_DESTINATION)
  749.                 dvscntr |= DVS_DEST_KEY;
  750.         else if (key->flags & I915_SET_COLORKEY_SOURCE)
  751.                 dvscntr |= DVS_SOURCE_KEY;
  752.         I915_WRITE(DVSCNTR(intel_plane->pipe), dvscntr);
  753.  
  754.         POSTING_READ(DVSKEYMSK(intel_plane->pipe));
  755.  
  756.         return ret;
  757. }
  758.  
  759. static void
  760. ilk_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key)
  761. {
  762.         struct drm_device *dev = plane->dev;
  763.         struct drm_i915_private *dev_priv = dev->dev_private;
  764.         struct intel_plane *intel_plane;
  765.         u32 dvscntr;
  766.  
  767.         intel_plane = to_intel_plane(plane);
  768.  
  769.         key->min_value = I915_READ(DVSKEYVAL(intel_plane->pipe));
  770.         key->max_value = I915_READ(DVSKEYMAX(intel_plane->pipe));
  771.         key->channel_mask = I915_READ(DVSKEYMSK(intel_plane->pipe));
  772.         key->flags = 0;
  773.  
  774.         dvscntr = I915_READ(DVSCNTR(intel_plane->pipe));
  775.  
  776.         if (dvscntr & DVS_DEST_KEY)
  777.                 key->flags = I915_SET_COLORKEY_DESTINATION;
  778.         else if (dvscntr & DVS_SOURCE_KEY)
  779.                 key->flags = I915_SET_COLORKEY_SOURCE;
  780.         else
  781.                 key->flags = I915_SET_COLORKEY_NONE;
  782. }
  783.  
  784. static bool
  785. format_is_yuv(uint32_t format)
  786. {
  787.         switch (format) {
  788.         case DRM_FORMAT_YUYV:
  789.         case DRM_FORMAT_UYVY:
  790.         case DRM_FORMAT_VYUY:
  791.         case DRM_FORMAT_YVYU:
  792.                 return true;
  793.         default:
  794.                 return false;
  795.         }
  796. }
  797.  
  798. static bool colorkey_enabled(struct intel_plane *intel_plane)
  799. {
  800.         struct drm_intel_sprite_colorkey key;
  801.  
  802.         intel_plane->get_colorkey(&intel_plane->base, &key);
  803.  
  804.         return key.flags != I915_SET_COLORKEY_NONE;
  805. }
  806.  
  807. static int
  808. intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
  809.                    struct drm_framebuffer *fb, int crtc_x, int crtc_y,
  810.                    unsigned int crtc_w, unsigned int crtc_h,
  811.                    uint32_t src_x, uint32_t src_y,
  812.                    uint32_t src_w, uint32_t src_h)
  813. {
  814.         struct drm_device *dev = plane->dev;
  815.         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  816.         struct intel_plane *intel_plane = to_intel_plane(plane);
  817.         enum pipe pipe = intel_crtc->pipe;
  818.         struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
  819.         struct drm_i915_gem_object *obj = intel_fb->obj;
  820.         struct drm_i915_gem_object *old_obj = intel_plane->obj;
  821.         int ret;
  822.         bool primary_enabled;
  823.         bool visible;
  824.         int hscale, vscale;
  825.         int max_scale, min_scale;
  826.         int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
  827.         struct drm_rect src = {
  828.                 /* sample coordinates in 16.16 fixed point */
  829.                 .x1 = src_x,
  830.                 .x2 = src_x + src_w,
  831.                 .y1 = src_y,
  832.                 .y2 = src_y + src_h,
  833.         };
  834.         struct drm_rect dst = {
  835.                 /* integer pixels */
  836.                 .x1 = crtc_x,
  837.                 .x2 = crtc_x + crtc_w,
  838.                 .y1 = crtc_y,
  839.                 .y2 = crtc_y + crtc_h,
  840.         };
  841.         const struct drm_rect clip = {
  842.                 .x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0,
  843.                 .y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0,
  844.         };
  845.         const struct {
  846.                 int crtc_x, crtc_y;
  847.                 unsigned int crtc_w, crtc_h;
  848.                 uint32_t src_x, src_y, src_w, src_h;
  849.         } orig = {
  850.                 .crtc_x = crtc_x,
  851.                 .crtc_y = crtc_y,
  852.                 .crtc_w = crtc_w,
  853.                 .crtc_h = crtc_h,
  854.                 .src_x = src_x,
  855.                 .src_y = src_y,
  856.                 .src_w = src_w,
  857.                 .src_h = src_h,
  858.         };
  859.  
  860.         /* Don't modify another pipe's plane */
  861.         if (intel_plane->pipe != intel_crtc->pipe) {
  862.                 DRM_DEBUG_KMS("Wrong plane <-> crtc mapping\n");
  863.                 return -EINVAL;
  864.         }
  865.  
  866.         /* FIXME check all gen limits */
  867.         if (fb->width < 3 || fb->height < 3 || fb->pitches[0] > 16384) {
  868.                 DRM_DEBUG_KMS("Unsuitable framebuffer for plane\n");
  869.                 return -EINVAL;
  870.         }
  871.  
  872.         /* Sprite planes can be linear or x-tiled surfaces */
  873.         switch (obj->tiling_mode) {
  874.                 case I915_TILING_NONE:
  875.                 case I915_TILING_X:
  876.                         break;
  877.                 default:
  878.                         DRM_DEBUG_KMS("Unsupported tiling mode\n");
  879.                         return -EINVAL;
  880.         }
  881.  
  882.         /*
  883.          * FIXME the following code does a bunch of fuzzy adjustments to the
  884.          * coordinates and sizes. We probably need some way to decide whether
  885.          * more strict checking should be done instead.
  886.          */
  887.         max_scale = intel_plane->max_downscale << 16;
  888.         min_scale = intel_plane->can_scale ? 1 : (1 << 16);
  889.  
  890.         hscale = drm_rect_calc_hscale_relaxed(&src, &dst, min_scale, max_scale);
  891.         BUG_ON(hscale < 0);
  892.  
  893.         vscale = drm_rect_calc_vscale_relaxed(&src, &dst, min_scale, max_scale);
  894.         BUG_ON(vscale < 0);
  895.  
  896.         visible = drm_rect_clip_scaled(&src, &dst, &clip, hscale, vscale);
  897.  
  898.         crtc_x = dst.x1;
  899.         crtc_y = dst.y1;
  900.         crtc_w = drm_rect_width(&dst);
  901.         crtc_h = drm_rect_height(&dst);
  902.  
  903.         if (visible) {
  904.                 /* check again in case clipping clamped the results */
  905.                 hscale = drm_rect_calc_hscale(&src, &dst, min_scale, max_scale);
  906.                 if (hscale < 0) {
  907.                         DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n");
  908.                         drm_rect_debug_print(&src, true);
  909.                         drm_rect_debug_print(&dst, false);
  910.  
  911.                         return hscale;
  912.         }
  913.  
  914.                 vscale = drm_rect_calc_vscale(&src, &dst, min_scale, max_scale);
  915.                 if (vscale < 0) {
  916.                         DRM_DEBUG_KMS("Vertical scaling factor out of limits\n");
  917.                         drm_rect_debug_print(&src, true);
  918.                         drm_rect_debug_print(&dst, false);
  919.  
  920.                         return vscale;
  921.         }
  922.  
  923.                 /* Make the source viewport size an exact multiple of the scaling factors. */
  924.                 drm_rect_adjust_size(&src,
  925.                                      drm_rect_width(&dst) * hscale - drm_rect_width(&src),
  926.                                      drm_rect_height(&dst) * vscale - drm_rect_height(&src));
  927.  
  928.                 /* sanity check to make sure the src viewport wasn't enlarged */
  929.                 WARN_ON(src.x1 < (int) src_x ||
  930.                         src.y1 < (int) src_y ||
  931.                         src.x2 > (int) (src_x + src_w) ||
  932.                         src.y2 > (int) (src_y + src_h));
  933.  
  934.         /*
  935.                  * Hardware doesn't handle subpixel coordinates.
  936.                  * Adjust to (macro)pixel boundary, but be careful not to
  937.                  * increase the source viewport size, because that could
  938.                  * push the downscaling factor out of bounds.
  939.          */
  940.                 src_x = src.x1 >> 16;
  941.                 src_w = drm_rect_width(&src) >> 16;
  942.                 src_y = src.y1 >> 16;
  943.                 src_h = drm_rect_height(&src) >> 16;
  944.  
  945.                 if (format_is_yuv(fb->pixel_format)) {
  946.                         src_x &= ~1;
  947.                         src_w &= ~1;
  948.  
  949.         /*
  950.                          * Must keep src and dst the
  951.                          * same if we can't scale.
  952.          */
  953.                         if (!intel_plane->can_scale)
  954.                                 crtc_w &= ~1;
  955.  
  956.                         if (crtc_w == 0)
  957.                                 visible = false;
  958.                 }
  959.         }
  960.  
  961.         /* Check size restrictions when scaling */
  962.         if (visible && (src_w != crtc_w || src_h != crtc_h)) {
  963.                 unsigned int width_bytes;
  964.  
  965.                 WARN_ON(!intel_plane->can_scale);
  966.  
  967.                 /* FIXME interlacing min height is 6 */
  968.  
  969.                 if (crtc_w < 3 || crtc_h < 3)
  970.                         visible = false;
  971.  
  972.                 if (src_w < 3 || src_h < 3)
  973.                         visible = false;
  974.  
  975.                 width_bytes = ((src_x * pixel_size) & 63) + src_w * pixel_size;
  976.  
  977.                 if (src_w > 2048 || src_h > 2048 ||
  978.                     width_bytes > 4096 || fb->pitches[0] > 4096) {
  979.                         DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
  980.                 return -EINVAL;
  981.                 }
  982.         }
  983.  
  984.         dst.x1 = crtc_x;
  985.         dst.x2 = crtc_x + crtc_w;
  986.         dst.y1 = crtc_y;
  987.         dst.y2 = crtc_y + crtc_h;
  988.  
  989.         /*
  990.          * If the sprite is completely covering the primary plane,
  991.          * we can disable the primary and save power.
  992.          */
  993.         primary_enabled = !drm_rect_equals(&dst, &clip) || colorkey_enabled(intel_plane);
  994.         WARN_ON(!primary_enabled && !visible && intel_crtc->active);
  995.  
  996.         mutex_lock(&dev->struct_mutex);
  997.  
  998.         /* Note that this will apply the VT-d workaround for scanouts,
  999.          * which is more restrictive than required for sprites. (The
  1000.          * primary plane requires 256KiB alignment with 64 PTE padding,
  1001.          * the sprite planes only require 128KiB alignment and 32 PTE padding.
  1002.          */
  1003.         ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
  1004.  
  1005.         i915_gem_track_fb(old_obj, obj,
  1006.                           INTEL_FRONTBUFFER_SPRITE(pipe));
  1007.         mutex_unlock(&dev->struct_mutex);
  1008.  
  1009.         if (ret)
  1010.                 return ret;
  1011.  
  1012.         intel_plane->crtc_x = orig.crtc_x;
  1013.         intel_plane->crtc_y = orig.crtc_y;
  1014.         intel_plane->crtc_w = orig.crtc_w;
  1015.         intel_plane->crtc_h = orig.crtc_h;
  1016.         intel_plane->src_x = orig.src_x;
  1017.         intel_plane->src_y = orig.src_y;
  1018.         intel_plane->src_w = orig.src_w;
  1019.         intel_plane->src_h = orig.src_h;
  1020.         intel_plane->obj = obj;
  1021.  
  1022.         if (intel_crtc->active) {
  1023.                 bool primary_was_enabled = intel_crtc->primary_enabled;
  1024.  
  1025.                 intel_crtc->primary_enabled = primary_enabled;
  1026.  
  1027. //       if (primary_was_enabled != primary_enabled)
  1028.  
  1029.                 if (primary_was_enabled && !primary_enabled)
  1030.                         intel_pre_disable_primary(crtc);
  1031.  
  1032.         if (visible)
  1033.                 intel_plane->update_plane(plane, crtc, fb, obj,
  1034.                                           crtc_x, crtc_y, crtc_w, crtc_h,
  1035.                                           src_x, src_y, src_w, src_h);
  1036.         else
  1037.                 intel_plane->disable_plane(plane, crtc);
  1038.  
  1039.                 if (!primary_was_enabled && primary_enabled)
  1040.                         intel_post_enable_primary(crtc);
  1041.         }
  1042.  
  1043.         /* Unpin old obj after new one is active to avoid ugliness */
  1044.         if (old_obj) {
  1045.                 /*
  1046.                  * It's fairly common to simply update the position of
  1047.                  * an existing object.  In that case, we don't need to
  1048.                  * wait for vblank to avoid ugliness, we only need to
  1049.                  * do the pin & ref bookkeeping.
  1050.                  */
  1051.                 if (old_obj != obj && intel_crtc->active)
  1052.                         intel_wait_for_vblank(dev, intel_crtc->pipe);
  1053.  
  1054.                         mutex_lock(&dev->struct_mutex);
  1055.                 intel_unpin_fb_obj(old_obj);
  1056.                 mutex_unlock(&dev->struct_mutex);
  1057.         }
  1058.  
  1059.         return 0;
  1060. }
  1061.  
  1062. static int
  1063. intel_disable_plane(struct drm_plane *plane)
  1064. {
  1065.         struct drm_device *dev = plane->dev;
  1066.         struct intel_plane *intel_plane = to_intel_plane(plane);
  1067.         struct intel_crtc *intel_crtc;
  1068.         enum pipe pipe;
  1069.  
  1070.         if (!plane->fb)
  1071.                 return 0;
  1072.  
  1073.         if (WARN_ON(!plane->crtc))
  1074.                 return -EINVAL;
  1075.  
  1076.         intel_crtc = to_intel_crtc(plane->crtc);
  1077.         pipe = intel_crtc->pipe;
  1078.  
  1079.         if (intel_crtc->active) {
  1080.                 bool primary_was_enabled = intel_crtc->primary_enabled;
  1081.  
  1082.                 intel_crtc->primary_enabled = true;
  1083.  
  1084.         intel_plane->disable_plane(plane, plane->crtc);
  1085.  
  1086.                 if (!primary_was_enabled && intel_crtc->primary_enabled)
  1087.                         intel_post_enable_primary(plane->crtc);
  1088.         }
  1089.  
  1090.         if (intel_plane->obj) {
  1091.                 if (intel_crtc->active)
  1092.         intel_wait_for_vblank(dev, intel_plane->pipe);
  1093.  
  1094.         mutex_lock(&dev->struct_mutex);
  1095.         intel_unpin_fb_obj(intel_plane->obj);
  1096.                 i915_gem_track_fb(intel_plane->obj, NULL,
  1097.                                   INTEL_FRONTBUFFER_SPRITE(pipe));
  1098.                 mutex_unlock(&dev->struct_mutex);
  1099.  
  1100.         intel_plane->obj = NULL;
  1101.         }
  1102.  
  1103.         return 0;
  1104. }
  1105.  
  1106. static void intel_destroy_plane(struct drm_plane *plane)
  1107. {
  1108.         struct intel_plane *intel_plane = to_intel_plane(plane);
  1109.         intel_disable_plane(plane);
  1110.         drm_plane_cleanup(plane);
  1111.         kfree(intel_plane);
  1112. }
  1113.  
  1114. int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
  1115.                               struct drm_file *file_priv)
  1116. {
  1117.         struct drm_intel_sprite_colorkey *set = data;
  1118.         struct drm_plane *plane;
  1119.         struct intel_plane *intel_plane;
  1120.         int ret = 0;
  1121.  
  1122.         if (!drm_core_check_feature(dev, DRIVER_MODESET))
  1123.                 return -ENODEV;
  1124.  
  1125.         /* Make sure we don't try to enable both src & dest simultaneously */
  1126.         if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
  1127.                 return -EINVAL;
  1128.  
  1129.         drm_modeset_lock_all(dev);
  1130.  
  1131.         plane = drm_plane_find(dev, set->plane_id);
  1132.         if (!plane) {
  1133.                 ret = -ENOENT;
  1134.                 goto out_unlock;
  1135.         }
  1136.  
  1137.         intel_plane = to_intel_plane(plane);
  1138.         ret = intel_plane->update_colorkey(plane, set);
  1139.  
  1140. out_unlock:
  1141.         drm_modeset_unlock_all(dev);
  1142.         return ret;
  1143. }
  1144.  
  1145. int intel_sprite_get_colorkey(struct drm_device *dev, void *data,
  1146.                               struct drm_file *file_priv)
  1147. {
  1148.         struct drm_intel_sprite_colorkey *get = data;
  1149.         struct drm_plane *plane;
  1150.         struct intel_plane *intel_plane;
  1151.         int ret = 0;
  1152.  
  1153.         if (!drm_core_check_feature(dev, DRIVER_MODESET))
  1154.                 return -ENODEV;
  1155.  
  1156.         drm_modeset_lock_all(dev);
  1157.  
  1158.         plane = drm_plane_find(dev, get->plane_id);
  1159.         if (!plane) {
  1160.                 ret = -ENOENT;
  1161.                 goto out_unlock;
  1162.         }
  1163.  
  1164.         intel_plane = to_intel_plane(plane);
  1165.         intel_plane->get_colorkey(plane, get);
  1166.  
  1167. out_unlock:
  1168.         drm_modeset_unlock_all(dev);
  1169.         return ret;
  1170. }
  1171.  
  1172. void intel_plane_restore(struct drm_plane *plane)
  1173. {
  1174.         struct intel_plane *intel_plane = to_intel_plane(plane);
  1175.  
  1176.         if (!plane->crtc || !plane->fb)
  1177.                 return;
  1178.  
  1179.         intel_update_plane(plane, plane->crtc, plane->fb,
  1180.                            intel_plane->crtc_x, intel_plane->crtc_y,
  1181.                            intel_plane->crtc_w, intel_plane->crtc_h,
  1182.                            intel_plane->src_x, intel_plane->src_y,
  1183.                            intel_plane->src_w, intel_plane->src_h);
  1184. }
  1185.  
  1186. void intel_plane_disable(struct drm_plane *plane)
  1187. {
  1188.         if (!plane->crtc || !plane->fb)
  1189.                 return;
  1190.  
  1191.         intel_disable_plane(plane);
  1192. }
  1193.  
  1194. static const struct drm_plane_funcs intel_plane_funcs = {
  1195.         .update_plane = intel_update_plane,
  1196.         .disable_plane = intel_disable_plane,
  1197.         .destroy = intel_destroy_plane,
  1198. };
  1199.  
  1200. static uint32_t ilk_plane_formats[] = {
  1201.         DRM_FORMAT_XRGB8888,
  1202.         DRM_FORMAT_YUYV,
  1203.         DRM_FORMAT_YVYU,
  1204.         DRM_FORMAT_UYVY,
  1205.         DRM_FORMAT_VYUY,
  1206. };
  1207.  
  1208. static uint32_t snb_plane_formats[] = {
  1209.         DRM_FORMAT_XBGR8888,
  1210.         DRM_FORMAT_XRGB8888,
  1211.         DRM_FORMAT_YUYV,
  1212.         DRM_FORMAT_YVYU,
  1213.         DRM_FORMAT_UYVY,
  1214.         DRM_FORMAT_VYUY,
  1215. };
  1216.  
  1217. static uint32_t vlv_plane_formats[] = {
  1218.         DRM_FORMAT_RGB565,
  1219.         DRM_FORMAT_ABGR8888,
  1220.         DRM_FORMAT_ARGB8888,
  1221.         DRM_FORMAT_XBGR8888,
  1222.         DRM_FORMAT_XRGB8888,
  1223.         DRM_FORMAT_XBGR2101010,
  1224.         DRM_FORMAT_ABGR2101010,
  1225.         DRM_FORMAT_YUYV,
  1226.         DRM_FORMAT_YVYU,
  1227.         DRM_FORMAT_UYVY,
  1228.         DRM_FORMAT_VYUY,
  1229. };
  1230.  
  1231. int
  1232. intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
  1233. {
  1234.         struct intel_plane *intel_plane;
  1235.         unsigned long possible_crtcs;
  1236.         const uint32_t *plane_formats;
  1237.         int num_plane_formats;
  1238.         int ret;
  1239.  
  1240.         if (INTEL_INFO(dev)->gen < 5)
  1241.                 return -ENODEV;
  1242.  
  1243.         intel_plane = kzalloc(sizeof(*intel_plane), GFP_KERNEL);
  1244.         if (!intel_plane)
  1245.                 return -ENOMEM;
  1246.  
  1247.         switch (INTEL_INFO(dev)->gen) {
  1248.         case 5:
  1249.         case 6:
  1250.                 intel_plane->can_scale = true;
  1251.                 intel_plane->max_downscale = 16;
  1252.                 intel_plane->update_plane = ilk_update_plane;
  1253.                 intel_plane->disable_plane = ilk_disable_plane;
  1254.                 intel_plane->update_colorkey = ilk_update_colorkey;
  1255.                 intel_plane->get_colorkey = ilk_get_colorkey;
  1256.  
  1257.         if (IS_GEN6(dev)) {
  1258.                         plane_formats = snb_plane_formats;
  1259.                         num_plane_formats = ARRAY_SIZE(snb_plane_formats);
  1260.                 } else {
  1261.                         plane_formats = ilk_plane_formats;
  1262.                         num_plane_formats = ARRAY_SIZE(ilk_plane_formats);
  1263.                 }
  1264.                 break;
  1265.  
  1266.         case 7:
  1267.         case 8:
  1268.                 if (IS_IVYBRIDGE(dev)) {
  1269.                         intel_plane->can_scale = true;
  1270.                         intel_plane->max_downscale = 2;
  1271.                 } else {
  1272.                         intel_plane->can_scale = false;
  1273.                         intel_plane->max_downscale = 1;
  1274.                 }
  1275.  
  1276.                 if (IS_VALLEYVIEW(dev)) {
  1277.                         intel_plane->update_plane = vlv_update_plane;
  1278.                         intel_plane->disable_plane = vlv_disable_plane;
  1279.                         intel_plane->update_colorkey = vlv_update_colorkey;
  1280.                         intel_plane->get_colorkey = vlv_get_colorkey;
  1281.  
  1282.                         plane_formats = vlv_plane_formats;
  1283.                         num_plane_formats = ARRAY_SIZE(vlv_plane_formats);
  1284.                 } else {
  1285.                 intel_plane->update_plane = ivb_update_plane;
  1286.                 intel_plane->disable_plane = ivb_disable_plane;
  1287.                 intel_plane->update_colorkey = ivb_update_colorkey;
  1288.                 intel_plane->get_colorkey = ivb_get_colorkey;
  1289.  
  1290.                 plane_formats = snb_plane_formats;
  1291.                 num_plane_formats = ARRAY_SIZE(snb_plane_formats);
  1292.                 }
  1293.                 break;
  1294.  
  1295.         default:
  1296.                 kfree(intel_plane);
  1297.                 return -ENODEV;
  1298.         }
  1299.  
  1300.         intel_plane->pipe = pipe;
  1301.         intel_plane->plane = plane;
  1302.         possible_crtcs = (1 << pipe);
  1303.         ret = drm_plane_init(dev, &intel_plane->base, possible_crtcs,
  1304.                              &intel_plane_funcs,
  1305.                              plane_formats, num_plane_formats,
  1306.                              false);
  1307.         if (ret)
  1308.                 kfree(intel_plane);
  1309.  
  1310.         return ret;
  1311. }
  1312.