Subversion Repositories Kolibri OS

Rev

Rev 3480 | Rev 3746 | 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 "intel_drv.h"
  36. #include <drm/i915_drm.h>
  37. #include "i915_drv.h"
  38.  
  39. static void
  40. ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
  41.                  struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
  42.                  unsigned int crtc_w, unsigned int crtc_h,
  43.                  uint32_t x, uint32_t y,
  44.                  uint32_t src_w, uint32_t src_h)
  45. {
  46.         struct drm_device *dev = plane->dev;
  47.         struct drm_i915_private *dev_priv = dev->dev_private;
  48.         struct intel_plane *intel_plane = to_intel_plane(plane);
  49.         int pipe = intel_plane->pipe;
  50.         u32 sprctl, sprscale = 0;
  51.         unsigned long sprsurf_offset, linear_offset;
  52.         int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
  53.         bool scaling_was_enabled = dev_priv->sprite_scaling_enabled;
  54.  
  55.         sprctl = I915_READ(SPRCTL(pipe));
  56.  
  57.         /* Mask out pixel format bits in case we change it */
  58.         sprctl &= ~SPRITE_PIXFORMAT_MASK;
  59.         sprctl &= ~SPRITE_RGB_ORDER_RGBX;
  60.         sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK;
  61.         sprctl &= ~SPRITE_TILED;
  62.  
  63.         switch (fb->pixel_format) {
  64.         case DRM_FORMAT_XBGR8888:
  65.                 sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
  66.                 break;
  67.         case DRM_FORMAT_XRGB8888:
  68.                 sprctl |= SPRITE_FORMAT_RGBX888;
  69.                 break;
  70.         case DRM_FORMAT_YUYV:
  71.                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
  72.                 break;
  73.         case DRM_FORMAT_YVYU:
  74.                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
  75.                 break;
  76.         case DRM_FORMAT_UYVY:
  77.                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
  78.                 break;
  79.         case DRM_FORMAT_VYUY:
  80.                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
  81.                 break;
  82.         default:
  83.                 BUG();
  84.         }
  85.  
  86.         if (obj->tiling_mode != I915_TILING_NONE)
  87.                 sprctl |= SPRITE_TILED;
  88.  
  89.         /* must disable */
  90.         sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
  91.         sprctl |= SPRITE_ENABLE;
  92.  
  93.         if (IS_HASWELL(dev))
  94.                 sprctl |= SPRITE_PIPE_CSC_ENABLE;
  95.  
  96.         /* Sizes are 0 based */
  97.         src_w--;
  98.         src_h--;
  99.         crtc_w--;
  100.         crtc_h--;
  101.  
  102.         intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size);
  103.  
  104.         /*
  105.          * IVB workaround: must disable low power watermarks for at least
  106.          * one frame before enabling scaling.  LP watermarks can be re-enabled
  107.          * when scaling is disabled.
  108.          */
  109.         if (crtc_w != src_w || crtc_h != src_h) {
  110.                 dev_priv->sprite_scaling_enabled |= 1 << pipe;
  111.  
  112.                 if (!scaling_was_enabled) {
  113.                         intel_update_watermarks(dev);
  114.                 intel_wait_for_vblank(dev, pipe);
  115.                 }
  116.                 sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
  117.         } else
  118.                 dev_priv->sprite_scaling_enabled &= ~(1 << pipe);
  119.  
  120.         I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]);
  121.         I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
  122.  
  123.         linear_offset = y * fb->pitches[0] + x * pixel_size;
  124.         sprsurf_offset =
  125.                 intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode,
  126.                                                  pixel_size, fb->pitches[0]);
  127.         linear_offset -= sprsurf_offset;
  128.  
  129.         /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
  130.          * register */
  131.         if (IS_HASWELL(dev))
  132.                 I915_WRITE(SPROFFSET(pipe), (y << 16) | x);
  133.         else if (obj->tiling_mode != I915_TILING_NONE)
  134.                 I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x);
  135.         else
  136.                 I915_WRITE(SPRLINOFF(pipe), linear_offset);
  137.  
  138.         I915_WRITE(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
  139.         if (intel_plane->can_scale)
  140.         I915_WRITE(SPRSCALE(pipe), sprscale);
  141.         I915_WRITE(SPRCTL(pipe), sprctl);
  142.         I915_MODIFY_DISPBASE(SPRSURF(pipe), obj->gtt_offset + sprsurf_offset);
  143.         POSTING_READ(SPRSURF(pipe));
  144.  
  145.         /* potentially re-enable LP watermarks */
  146.         if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled)
  147.                 intel_update_watermarks(dev);
  148. }
  149.  
  150. static void
  151. ivb_disable_plane(struct drm_plane *plane)
  152. {
  153.         struct drm_device *dev = plane->dev;
  154.         struct drm_i915_private *dev_priv = dev->dev_private;
  155.         struct intel_plane *intel_plane = to_intel_plane(plane);
  156.         int pipe = intel_plane->pipe;
  157.         bool scaling_was_enabled = dev_priv->sprite_scaling_enabled;
  158.  
  159.         I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE);
  160.         /* Can't leave the scaler enabled... */
  161.         if (intel_plane->can_scale)
  162.         I915_WRITE(SPRSCALE(pipe), 0);
  163.         /* Activate double buffered register update */
  164.         I915_MODIFY_DISPBASE(SPRSURF(pipe), 0);
  165.         POSTING_READ(SPRSURF(pipe));
  166.  
  167.         dev_priv->sprite_scaling_enabled &= ~(1 << pipe);
  168.  
  169.         /* potentially re-enable LP watermarks */
  170.         if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled)
  171.         intel_update_watermarks(dev);
  172. }
  173.  
  174. static int
  175. ivb_update_colorkey(struct drm_plane *plane,
  176.                     struct drm_intel_sprite_colorkey *key)
  177. {
  178.         struct drm_device *dev = plane->dev;
  179.         struct drm_i915_private *dev_priv = dev->dev_private;
  180.         struct intel_plane *intel_plane;
  181.         u32 sprctl;
  182.         int ret = 0;
  183.  
  184.         intel_plane = to_intel_plane(plane);
  185.  
  186.         I915_WRITE(SPRKEYVAL(intel_plane->pipe), key->min_value);
  187.         I915_WRITE(SPRKEYMAX(intel_plane->pipe), key->max_value);
  188.         I915_WRITE(SPRKEYMSK(intel_plane->pipe), key->channel_mask);
  189.  
  190.         sprctl = I915_READ(SPRCTL(intel_plane->pipe));
  191.         sprctl &= ~(SPRITE_SOURCE_KEY | SPRITE_DEST_KEY);
  192.         if (key->flags & I915_SET_COLORKEY_DESTINATION)
  193.                 sprctl |= SPRITE_DEST_KEY;
  194.         else if (key->flags & I915_SET_COLORKEY_SOURCE)
  195.                 sprctl |= SPRITE_SOURCE_KEY;
  196.         I915_WRITE(SPRCTL(intel_plane->pipe), sprctl);
  197.  
  198.         POSTING_READ(SPRKEYMSK(intel_plane->pipe));
  199.  
  200.         return ret;
  201. }
  202.  
  203. static void
  204. ivb_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key)
  205. {
  206.         struct drm_device *dev = plane->dev;
  207.         struct drm_i915_private *dev_priv = dev->dev_private;
  208.         struct intel_plane *intel_plane;
  209.         u32 sprctl;
  210.  
  211.         intel_plane = to_intel_plane(plane);
  212.  
  213.         key->min_value = I915_READ(SPRKEYVAL(intel_plane->pipe));
  214.         key->max_value = I915_READ(SPRKEYMAX(intel_plane->pipe));
  215.         key->channel_mask = I915_READ(SPRKEYMSK(intel_plane->pipe));
  216.         key->flags = 0;
  217.  
  218.         sprctl = I915_READ(SPRCTL(intel_plane->pipe));
  219.  
  220.         if (sprctl & SPRITE_DEST_KEY)
  221.                 key->flags = I915_SET_COLORKEY_DESTINATION;
  222.         else if (sprctl & SPRITE_SOURCE_KEY)
  223.                 key->flags = I915_SET_COLORKEY_SOURCE;
  224.         else
  225.                 key->flags = I915_SET_COLORKEY_NONE;
  226. }
  227.  
  228. static void
  229. ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
  230.                  struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
  231.                  unsigned int crtc_w, unsigned int crtc_h,
  232.                  uint32_t x, uint32_t y,
  233.                  uint32_t src_w, uint32_t src_h)
  234. {
  235.         struct drm_device *dev = plane->dev;
  236.         struct drm_i915_private *dev_priv = dev->dev_private;
  237.         struct intel_plane *intel_plane = to_intel_plane(plane);
  238.         int pipe = intel_plane->pipe;
  239.         unsigned long dvssurf_offset, linear_offset;
  240.         u32 dvscntr, dvsscale;
  241.         int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
  242.  
  243.         dvscntr = I915_READ(DVSCNTR(pipe));
  244.  
  245.         /* Mask out pixel format bits in case we change it */
  246.         dvscntr &= ~DVS_PIXFORMAT_MASK;
  247.         dvscntr &= ~DVS_RGB_ORDER_XBGR;
  248.         dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK;
  249.         dvscntr &= ~DVS_TILED;
  250.  
  251.         switch (fb->pixel_format) {
  252.         case DRM_FORMAT_XBGR8888:
  253.                 dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR;
  254.                 break;
  255.         case DRM_FORMAT_XRGB8888:
  256.                 dvscntr |= DVS_FORMAT_RGBX888;
  257.                 break;
  258.         case DRM_FORMAT_YUYV:
  259.                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
  260.                 break;
  261.         case DRM_FORMAT_YVYU:
  262.                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
  263.                 break;
  264.         case DRM_FORMAT_UYVY:
  265.                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
  266.                 break;
  267.         case DRM_FORMAT_VYUY:
  268.                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
  269.                 break;
  270.         default:
  271.                 BUG();
  272.         }
  273.  
  274.         if (obj->tiling_mode != I915_TILING_NONE)
  275.                 dvscntr |= DVS_TILED;
  276.  
  277.         if (IS_GEN6(dev))
  278.                 dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */
  279.         dvscntr |= DVS_ENABLE;
  280.  
  281.         /* Sizes are 0 based */
  282.         src_w--;
  283.         src_h--;
  284.         crtc_w--;
  285.         crtc_h--;
  286.  
  287.         intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size);
  288.  
  289.         dvsscale = 0;
  290.         if (IS_GEN5(dev) || crtc_w != src_w || crtc_h != src_h)
  291.                 dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h;
  292.  
  293.         I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]);
  294.         I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
  295.  
  296.         linear_offset = y * fb->pitches[0] + x * pixel_size;
  297.         dvssurf_offset =
  298.                 intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode,
  299.                                                  pixel_size, fb->pitches[0]);
  300.         linear_offset -= dvssurf_offset;
  301.  
  302.         if (obj->tiling_mode != I915_TILING_NONE)
  303.                 I915_WRITE(DVSTILEOFF(pipe), (y << 16) | x);
  304.         else
  305.                 I915_WRITE(DVSLINOFF(pipe), linear_offset);
  306.  
  307.         I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
  308.         I915_WRITE(DVSSCALE(pipe), dvsscale);
  309.         I915_WRITE(DVSCNTR(pipe), dvscntr);
  310.         I915_MODIFY_DISPBASE(DVSSURF(pipe), obj->gtt_offset + dvssurf_offset);
  311.         POSTING_READ(DVSSURF(pipe));
  312. }
  313.  
  314. static void
  315. ilk_disable_plane(struct drm_plane *plane)
  316. {
  317.         struct drm_device *dev = plane->dev;
  318.         struct drm_i915_private *dev_priv = dev->dev_private;
  319.         struct intel_plane *intel_plane = to_intel_plane(plane);
  320.         int pipe = intel_plane->pipe;
  321.  
  322.         I915_WRITE(DVSCNTR(pipe), I915_READ(DVSCNTR(pipe)) & ~DVS_ENABLE);
  323.         /* Disable the scaler */
  324.         I915_WRITE(DVSSCALE(pipe), 0);
  325.         /* Flush double buffered register updates */
  326.         I915_MODIFY_DISPBASE(DVSSURF(pipe), 0);
  327.         POSTING_READ(DVSSURF(pipe));
  328. }
  329.  
  330. static void
  331. intel_enable_primary(struct drm_crtc *crtc)
  332. {
  333.         struct drm_device *dev = crtc->dev;
  334.         struct drm_i915_private *dev_priv = dev->dev_private;
  335.         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  336.         int reg = DSPCNTR(intel_crtc->plane);
  337.  
  338.         if (!intel_crtc->primary_disabled)
  339.                 return;
  340.  
  341.         intel_crtc->primary_disabled = false;
  342.         intel_update_fbc(dev);
  343.  
  344.         I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE);
  345. }
  346.  
  347. static void
  348. intel_disable_primary(struct drm_crtc *crtc)
  349. {
  350.         struct drm_device *dev = crtc->dev;
  351.         struct drm_i915_private *dev_priv = dev->dev_private;
  352.         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  353.         int reg = DSPCNTR(intel_crtc->plane);
  354.  
  355.         if (intel_crtc->primary_disabled)
  356.                 return;
  357.  
  358.         I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE);
  359.  
  360.         intel_crtc->primary_disabled = true;
  361.         intel_update_fbc(dev);
  362. }
  363.  
  364. static int
  365. ilk_update_colorkey(struct drm_plane *plane,
  366.                     struct drm_intel_sprite_colorkey *key)
  367. {
  368.         struct drm_device *dev = plane->dev;
  369.         struct drm_i915_private *dev_priv = dev->dev_private;
  370.         struct intel_plane *intel_plane;
  371.         u32 dvscntr;
  372.         int ret = 0;
  373.  
  374.         intel_plane = to_intel_plane(plane);
  375.  
  376.         I915_WRITE(DVSKEYVAL(intel_plane->pipe), key->min_value);
  377.         I915_WRITE(DVSKEYMAX(intel_plane->pipe), key->max_value);
  378.         I915_WRITE(DVSKEYMSK(intel_plane->pipe), key->channel_mask);
  379.  
  380.         dvscntr = I915_READ(DVSCNTR(intel_plane->pipe));
  381.         dvscntr &= ~(DVS_SOURCE_KEY | DVS_DEST_KEY);
  382.         if (key->flags & I915_SET_COLORKEY_DESTINATION)
  383.                 dvscntr |= DVS_DEST_KEY;
  384.         else if (key->flags & I915_SET_COLORKEY_SOURCE)
  385.                 dvscntr |= DVS_SOURCE_KEY;
  386.         I915_WRITE(DVSCNTR(intel_plane->pipe), dvscntr);
  387.  
  388.         POSTING_READ(DVSKEYMSK(intel_plane->pipe));
  389.  
  390.         return ret;
  391. }
  392.  
  393. static void
  394. ilk_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key)
  395. {
  396.         struct drm_device *dev = plane->dev;
  397.         struct drm_i915_private *dev_priv = dev->dev_private;
  398.         struct intel_plane *intel_plane;
  399.         u32 dvscntr;
  400.  
  401.         intel_plane = to_intel_plane(plane);
  402.  
  403.         key->min_value = I915_READ(DVSKEYVAL(intel_plane->pipe));
  404.         key->max_value = I915_READ(DVSKEYMAX(intel_plane->pipe));
  405.         key->channel_mask = I915_READ(DVSKEYMSK(intel_plane->pipe));
  406.         key->flags = 0;
  407.  
  408.         dvscntr = I915_READ(DVSCNTR(intel_plane->pipe));
  409.  
  410.         if (dvscntr & DVS_DEST_KEY)
  411.                 key->flags = I915_SET_COLORKEY_DESTINATION;
  412.         else if (dvscntr & DVS_SOURCE_KEY)
  413.                 key->flags = I915_SET_COLORKEY_SOURCE;
  414.         else
  415.                 key->flags = I915_SET_COLORKEY_NONE;
  416. }
  417.  
  418. static int
  419. intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
  420.                    struct drm_framebuffer *fb, int crtc_x, int crtc_y,
  421.                    unsigned int crtc_w, unsigned int crtc_h,
  422.                    uint32_t src_x, uint32_t src_y,
  423.                    uint32_t src_w, uint32_t src_h)
  424. {
  425.         struct drm_device *dev = plane->dev;
  426.         struct drm_i915_private *dev_priv = dev->dev_private;
  427.         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  428.         struct intel_plane *intel_plane = to_intel_plane(plane);
  429.         struct intel_framebuffer *intel_fb;
  430.         struct drm_i915_gem_object *obj, *old_obj;
  431.         int pipe = intel_plane->pipe;
  432.         enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
  433.                                                                       pipe);
  434.         int ret = 0;
  435.         int x = src_x >> 16, y = src_y >> 16;
  436.         int primary_w = crtc->mode.hdisplay, primary_h = crtc->mode.vdisplay;
  437.         bool disable_primary = false;
  438.  
  439.         intel_fb = to_intel_framebuffer(fb);
  440.         obj = intel_fb->obj;
  441.  
  442.         old_obj = intel_plane->obj;
  443.  
  444.         src_w = src_w >> 16;
  445.         src_h = src_h >> 16;
  446.  
  447.         /* Pipe must be running... */
  448.         if (!(I915_READ(PIPECONF(cpu_transcoder)) & PIPECONF_ENABLE))
  449.                 return -EINVAL;
  450.  
  451.         if (crtc_x >= primary_w || crtc_y >= primary_h)
  452.                 return -EINVAL;
  453.  
  454.         /* Don't modify another pipe's plane */
  455.         if (intel_plane->pipe != intel_crtc->pipe)
  456.                 return -EINVAL;
  457.  
  458.         /* Sprite planes can be linear or x-tiled surfaces */
  459.         switch (obj->tiling_mode) {
  460.                 case I915_TILING_NONE:
  461.                 case I915_TILING_X:
  462.                         break;
  463.                 default:
  464.                         return -EINVAL;
  465.         }
  466.  
  467.         /*
  468.          * Clamp the width & height into the visible area.  Note we don't
  469.          * try to scale the source if part of the visible region is offscreen.
  470.          * The caller must handle that by adjusting source offset and size.
  471.          */
  472.         if ((crtc_x < 0) && ((crtc_x + crtc_w) > 0)) {
  473.                 crtc_w += crtc_x;
  474.                 crtc_x = 0;
  475.         }
  476.         if ((crtc_x + crtc_w) <= 0) /* Nothing to display */
  477.                 goto out;
  478.         if ((crtc_x + crtc_w) > primary_w)
  479.                 crtc_w = primary_w - crtc_x;
  480.  
  481.         if ((crtc_y < 0) && ((crtc_y + crtc_h) > 0)) {
  482.                 crtc_h += crtc_y;
  483.                 crtc_y = 0;
  484.         }
  485.         if ((crtc_y + crtc_h) <= 0) /* Nothing to display */
  486.                 goto out;
  487.         if (crtc_y + crtc_h > primary_h)
  488.                 crtc_h = primary_h - crtc_y;
  489.  
  490.         if (!crtc_w || !crtc_h) /* Again, nothing to display */
  491.                 goto out;
  492.  
  493.         /*
  494.          * We may not have a scaler, eg. HSW does not have it any more
  495.          */
  496.         if (!intel_plane->can_scale && (crtc_w != src_w || crtc_h != src_h))
  497.                 return -EINVAL;
  498.  
  499.         /*
  500.          * We can take a larger source and scale it down, but
  501.          * only so much...  16x is the max on SNB.
  502.          */
  503.         if (((src_w * src_h) / (crtc_w * crtc_h)) > intel_plane->max_downscale)
  504.                 return -EINVAL;
  505.  
  506.         /*
  507.          * If the sprite is completely covering the primary plane,
  508.          * we can disable the primary and save power.
  509.          */
  510.         if ((crtc_x == 0) && (crtc_y == 0) &&
  511.             (crtc_w == primary_w) && (crtc_h == primary_h))
  512.                 disable_primary = true;
  513.  
  514.         mutex_lock(&dev->struct_mutex);
  515.  
  516.         ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
  517.         if (ret)
  518.                 goto out_unlock;
  519.  
  520.         intel_plane->obj = obj;
  521.  
  522.         /*
  523.          * Be sure to re-enable the primary before the sprite is no longer
  524.          * covering it fully.
  525.          */
  526.         if (!disable_primary)
  527.                 intel_enable_primary(crtc);
  528.  
  529.         intel_plane->update_plane(plane, fb, obj, crtc_x, crtc_y,
  530.                                   crtc_w, crtc_h, x, y, src_w, src_h);
  531.  
  532.         if (disable_primary)
  533.                 intel_disable_primary(crtc);
  534.  
  535.         /* Unpin old obj after new one is active to avoid ugliness */
  536.         if (old_obj) {
  537.                 /*
  538.                  * It's fairly common to simply update the position of
  539.                  * an existing object.  In that case, we don't need to
  540.                  * wait for vblank to avoid ugliness, we only need to
  541.                  * do the pin & ref bookkeeping.
  542.                  */
  543.                 if (old_obj != obj) {
  544.                         mutex_unlock(&dev->struct_mutex);
  545.                         intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe);
  546.                         mutex_lock(&dev->struct_mutex);
  547.                 }
  548.                 intel_unpin_fb_obj(old_obj);
  549.         }
  550.  
  551. out_unlock:
  552.         mutex_unlock(&dev->struct_mutex);
  553. out:
  554.         return ret;
  555. }
  556.  
  557. static int
  558. intel_disable_plane(struct drm_plane *plane)
  559. {
  560.         struct drm_device *dev = plane->dev;
  561.         struct intel_plane *intel_plane = to_intel_plane(plane);
  562.         int ret = 0;
  563.  
  564.         if (plane->crtc)
  565.                 intel_enable_primary(plane->crtc);
  566.         intel_plane->disable_plane(plane);
  567.  
  568.         if (!intel_plane->obj)
  569.                 goto out;
  570.  
  571.         mutex_lock(&dev->struct_mutex);
  572.         intel_unpin_fb_obj(intel_plane->obj);
  573.         intel_plane->obj = NULL;
  574.         mutex_unlock(&dev->struct_mutex);
  575. out:
  576.  
  577.         return ret;
  578. }
  579.  
  580. static void intel_destroy_plane(struct drm_plane *plane)
  581. {
  582.         struct intel_plane *intel_plane = to_intel_plane(plane);
  583.         intel_disable_plane(plane);
  584.         drm_plane_cleanup(plane);
  585.         kfree(intel_plane);
  586. }
  587.  
  588. int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
  589.                               struct drm_file *file_priv)
  590. {
  591.         struct drm_intel_sprite_colorkey *set = data;
  592.         struct drm_mode_object *obj;
  593.         struct drm_plane *plane;
  594.         struct intel_plane *intel_plane;
  595.         int ret = 0;
  596.  
  597.         if (!drm_core_check_feature(dev, DRIVER_MODESET))
  598.                 return -ENODEV;
  599.  
  600.         /* Make sure we don't try to enable both src & dest simultaneously */
  601.         if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
  602.                 return -EINVAL;
  603.  
  604.         drm_modeset_lock_all(dev);
  605.  
  606.         obj = drm_mode_object_find(dev, set->plane_id, DRM_MODE_OBJECT_PLANE);
  607.         if (!obj) {
  608.                 ret = -EINVAL;
  609.                 goto out_unlock;
  610.         }
  611.  
  612.         plane = obj_to_plane(obj);
  613.         intel_plane = to_intel_plane(plane);
  614.         ret = intel_plane->update_colorkey(plane, set);
  615.  
  616. out_unlock:
  617.         drm_modeset_unlock_all(dev);
  618.         return ret;
  619. }
  620.  
  621. int intel_sprite_get_colorkey(struct drm_device *dev, void *data,
  622.                               struct drm_file *file_priv)
  623. {
  624.         struct drm_intel_sprite_colorkey *get = data;
  625.         struct drm_mode_object *obj;
  626.         struct drm_plane *plane;
  627.         struct intel_plane *intel_plane;
  628.         int ret = 0;
  629.  
  630.         if (!drm_core_check_feature(dev, DRIVER_MODESET))
  631.                 return -ENODEV;
  632.  
  633.         drm_modeset_lock_all(dev);
  634.  
  635.         obj = drm_mode_object_find(dev, get->plane_id, DRM_MODE_OBJECT_PLANE);
  636.         if (!obj) {
  637.                 ret = -EINVAL;
  638.                 goto out_unlock;
  639.         }
  640.  
  641.         plane = obj_to_plane(obj);
  642.         intel_plane = to_intel_plane(plane);
  643.         intel_plane->get_colorkey(plane, get);
  644.  
  645. out_unlock:
  646.         drm_modeset_unlock_all(dev);
  647.         return ret;
  648. }
  649.  
  650. static const struct drm_plane_funcs intel_plane_funcs = {
  651.         .update_plane = intel_update_plane,
  652.         .disable_plane = intel_disable_plane,
  653.         .destroy = intel_destroy_plane,
  654. };
  655.  
  656. static uint32_t ilk_plane_formats[] = {
  657.         DRM_FORMAT_XRGB8888,
  658.         DRM_FORMAT_YUYV,
  659.         DRM_FORMAT_YVYU,
  660.         DRM_FORMAT_UYVY,
  661.         DRM_FORMAT_VYUY,
  662. };
  663.  
  664. static uint32_t snb_plane_formats[] = {
  665.         DRM_FORMAT_XBGR8888,
  666.         DRM_FORMAT_XRGB8888,
  667.         DRM_FORMAT_YUYV,
  668.         DRM_FORMAT_YVYU,
  669.         DRM_FORMAT_UYVY,
  670.         DRM_FORMAT_VYUY,
  671. };
  672.  
  673. int
  674. intel_plane_init(struct drm_device *dev, enum pipe pipe)
  675. {
  676.         struct intel_plane *intel_plane;
  677.         unsigned long possible_crtcs;
  678.         const uint32_t *plane_formats;
  679.         int num_plane_formats;
  680.         int ret;
  681.  
  682.         if (INTEL_INFO(dev)->gen < 5)
  683.                 return -ENODEV;
  684.  
  685.         intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL);
  686.         if (!intel_plane)
  687.                 return -ENOMEM;
  688.  
  689.         switch (INTEL_INFO(dev)->gen) {
  690.         case 5:
  691.         case 6:
  692.                 intel_plane->can_scale = true;
  693.                 intel_plane->max_downscale = 16;
  694.                 intel_plane->update_plane = ilk_update_plane;
  695.                 intel_plane->disable_plane = ilk_disable_plane;
  696.                 intel_plane->update_colorkey = ilk_update_colorkey;
  697.                 intel_plane->get_colorkey = ilk_get_colorkey;
  698.  
  699.         if (IS_GEN6(dev)) {
  700.                         plane_formats = snb_plane_formats;
  701.                         num_plane_formats = ARRAY_SIZE(snb_plane_formats);
  702.                 } else {
  703.                         plane_formats = ilk_plane_formats;
  704.                         num_plane_formats = ARRAY_SIZE(ilk_plane_formats);
  705.                 }
  706.                 break;
  707.  
  708.         case 7:
  709.                 if (IS_HASWELL(dev) || IS_VALLEYVIEW(dev))
  710.                         intel_plane->can_scale = false;
  711.                 else
  712.                         intel_plane->can_scale = true;
  713.                 intel_plane->max_downscale = 2;
  714.                 intel_plane->update_plane = ivb_update_plane;
  715.                 intel_plane->disable_plane = ivb_disable_plane;
  716.                 intel_plane->update_colorkey = ivb_update_colorkey;
  717.                 intel_plane->get_colorkey = ivb_get_colorkey;
  718.  
  719.                 plane_formats = snb_plane_formats;
  720.                 num_plane_formats = ARRAY_SIZE(snb_plane_formats);
  721.                 break;
  722.  
  723.         default:
  724.                 kfree(intel_plane);
  725.                 return -ENODEV;
  726.         }
  727.  
  728.         intel_plane->pipe = pipe;
  729.         possible_crtcs = (1 << pipe);
  730.         ret = drm_plane_init(dev, &intel_plane->base, possible_crtcs,
  731.                              &intel_plane_funcs,
  732.                              plane_formats, num_plane_formats,
  733.                              false);
  734.         if (ret)
  735.                 kfree(intel_plane);
  736.  
  737.         return ret;
  738. }
  739.