Subversion Repositories Kolibri OS

Rev

Rev 5060 | Rev 6088 | 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 bool
  41. format_is_yuv(uint32_t format)
  42. {
  43.         switch (format) {
  44.         case DRM_FORMAT_YUYV:
  45.         case DRM_FORMAT_UYVY:
  46.         case DRM_FORMAT_VYUY:
  47.         case DRM_FORMAT_YVYU:
  48.                 return true;
  49.         default:
  50.                 return false;
  51.         }
  52. }
  53.  
  54. static int usecs_to_scanlines(const struct drm_display_mode *mode, int usecs)
  55. {
  56.         /* paranoia */
  57.         if (!mode->crtc_htotal)
  58.                 return 1;
  59.  
  60.         return DIV_ROUND_UP(usecs * mode->crtc_clock, 1000 * mode->crtc_htotal);
  61. }
  62.  
  63. /**
  64.  * intel_pipe_update_start() - start update of a set of display registers
  65.  * @crtc: the crtc of which the registers are going to be updated
  66.  * @start_vbl_count: vblank counter return pointer used for error checking
  67.  *
  68.  * Mark the start of an update to pipe registers that should be updated
  69.  * atomically regarding vblank. If the next vblank will happens within
  70.  * the next 100 us, this function waits until the vblank passes.
  71.  *
  72.  * After a successful call to this function, interrupts will be disabled
  73.  * until a subsequent call to intel_pipe_update_end(). That is done to
  74.  * avoid random delays. The value written to @start_vbl_count should be
  75.  * supplied to intel_pipe_update_end() for error checking.
  76.  *
  77.  * Return: true if the call was successful
  78.  */
  79. bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl_count)
  80. {
  81.         struct drm_device *dev = crtc->base.dev;
  82.         const struct drm_display_mode *mode = &crtc->config.adjusted_mode;
  83.         enum pipe pipe = crtc->pipe;
  84.         long timeout = msecs_to_jiffies_timeout(1);
  85.         int scanline, min, max, vblank_start;
  86.         wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base);
  87.         DEFINE_WAIT(wait);
  88.  
  89.         vblank_start = mode->crtc_vblank_start;
  90.         if (mode->flags & DRM_MODE_FLAG_INTERLACE)
  91.                 vblank_start = DIV_ROUND_UP(vblank_start, 2);
  92.  
  93.         /* FIXME needs to be calibrated sensibly */
  94.         min = vblank_start - usecs_to_scanlines(mode, 100);
  95.         max = vblank_start - 1;
  96.  
  97.         if (min <= 0 || max <= 0)
  98.                 return false;
  99.  
  100. //   if (WARN_ON(drm_vblank_get(dev, pipe)))
  101. //       return false;
  102.  
  103. //   local_irq_disable();
  104.  
  105. //   trace_i915_pipe_update_start(crtc, min, max);
  106.  
  107.         for (;;) {
  108.                 /*
  109.                  * prepare_to_wait() has a memory barrier, which guarantees
  110.                  * other CPUs can see the task state update by the time we
  111.                  * read the scanline.
  112.                  */
  113.                 prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE);
  114.  
  115.                 scanline = intel_get_crtc_scanline(crtc);
  116.                 if (scanline < min || scanline > max)
  117.                         break;
  118.  
  119.                 if (timeout <= 0) {
  120.                         DRM_ERROR("Potential atomic update failure on pipe %c\n",
  121.                                   pipe_name(crtc->pipe));
  122.                         break;
  123.                 }
  124.  
  125. //       local_irq_enable();
  126.  
  127.         schedule_timeout(timeout);
  128.         timeout = 0;
  129. //       local_irq_disable();
  130.         }
  131.  
  132.         finish_wait(wq, &wait);
  133.  
  134. //   drm_vblank_put(dev, pipe);
  135.  
  136.         *start_vbl_count = dev->driver->get_vblank_counter(dev, pipe);
  137.  
  138. //   trace_i915_pipe_update_vblank_evaded(crtc, min, max, *start_vbl_count);
  139.  
  140.         return true;
  141. }
  142.  
  143. /**
  144.  * intel_pipe_update_end() - end update of a set of display registers
  145.  * @crtc: the crtc of which the registers were updated
  146.  * @start_vbl_count: start vblank counter (used for error checking)
  147.  *
  148.  * Mark the end of an update started with intel_pipe_update_start(). This
  149.  * re-enables interrupts and verifies the update was actually completed
  150.  * before a vblank using the value of @start_vbl_count.
  151.  */
  152. void intel_pipe_update_end(struct intel_crtc *crtc, u32 start_vbl_count)
  153. {
  154.         struct drm_device *dev = crtc->base.dev;
  155.         enum pipe pipe = crtc->pipe;
  156.         u32 end_vbl_count = dev->driver->get_vblank_counter(dev, pipe);
  157.  
  158. //   trace_i915_pipe_update_end(crtc, end_vbl_count);
  159.  
  160. //   local_irq_enable();
  161.  
  162.         if (start_vbl_count != end_vbl_count)
  163.                 DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u)\n",
  164.                           pipe_name(pipe), start_vbl_count, end_vbl_count);
  165. }
  166.  
  167. static void intel_update_primary_plane(struct intel_crtc *crtc)
  168. {
  169.         struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
  170.         int reg = DSPCNTR(crtc->plane);
  171.  
  172.         if (crtc->primary_enabled)
  173.                 I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE);
  174.         else
  175.                 I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE);
  176. }
  177.  
  178. static void
  179. skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
  180.                  struct drm_framebuffer *fb,
  181.                  struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
  182.                  unsigned int crtc_w, unsigned int crtc_h,
  183.                  uint32_t x, uint32_t y,
  184.                  uint32_t src_w, uint32_t src_h)
  185. {
  186.         struct drm_device *dev = drm_plane->dev;
  187.         struct drm_i915_private *dev_priv = dev->dev_private;
  188.         struct intel_plane *intel_plane = to_intel_plane(drm_plane);
  189.         const int pipe = intel_plane->pipe;
  190.         const int plane = intel_plane->plane + 1;
  191.         u32 plane_ctl, stride;
  192.         int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
  193.  
  194.         plane_ctl = I915_READ(PLANE_CTL(pipe, plane));
  195.  
  196.         /* Mask out pixel format bits in case we change it */
  197.         plane_ctl &= ~PLANE_CTL_FORMAT_MASK;
  198.         plane_ctl &= ~PLANE_CTL_ORDER_RGBX;
  199.         plane_ctl &= ~PLANE_CTL_YUV422_ORDER_MASK;
  200.         plane_ctl &= ~PLANE_CTL_TILED_MASK;
  201.         plane_ctl &= ~PLANE_CTL_ALPHA_MASK;
  202.         plane_ctl &= ~PLANE_CTL_ROTATE_MASK;
  203.  
  204.         /* Trickle feed has to be enabled */
  205.         plane_ctl &= ~PLANE_CTL_TRICKLE_FEED_DISABLE;
  206.  
  207.         switch (fb->pixel_format) {
  208.         case DRM_FORMAT_RGB565:
  209.                 plane_ctl |= PLANE_CTL_FORMAT_RGB_565;
  210.                 break;
  211.         case DRM_FORMAT_XBGR8888:
  212.                 plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX;
  213.                 break;
  214.         case DRM_FORMAT_XRGB8888:
  215.                 plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
  216.                 break;
  217.         /*
  218.          * XXX: For ARBG/ABGR formats we default to expecting scanout buffers
  219.          * to be already pre-multiplied. We need to add a knob (or a different
  220.          * DRM_FORMAT) for user-space to configure that.
  221.          */
  222.         case DRM_FORMAT_ABGR8888:
  223.                 plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 |
  224.                              PLANE_CTL_ORDER_RGBX |
  225.                              PLANE_CTL_ALPHA_SW_PREMULTIPLY;
  226.                 break;
  227.         case DRM_FORMAT_ARGB8888:
  228.                 plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 |
  229.                              PLANE_CTL_ALPHA_SW_PREMULTIPLY;
  230.                 break;
  231.         case DRM_FORMAT_YUYV:
  232.                 plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YUYV;
  233.                 break;
  234.         case DRM_FORMAT_YVYU:
  235.                 plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YVYU;
  236.                 break;
  237.         case DRM_FORMAT_UYVY:
  238.                 plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY;
  239.                 break;
  240.         case DRM_FORMAT_VYUY:
  241.                 plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY;
  242.                 break;
  243.         default:
  244.                 BUG();
  245.         }
  246.  
  247.         switch (obj->tiling_mode) {
  248.         case I915_TILING_NONE:
  249.                 stride = fb->pitches[0] >> 6;
  250.                 break;
  251.         case I915_TILING_X:
  252.                 plane_ctl |= PLANE_CTL_TILED_X;
  253.                 stride = fb->pitches[0] >> 9;
  254.                 break;
  255.         default:
  256.                 BUG();
  257.         }
  258.         if (intel_plane->rotation == BIT(DRM_ROTATE_180))
  259.                 plane_ctl |= PLANE_CTL_ROTATE_180;
  260.  
  261.         plane_ctl |= PLANE_CTL_ENABLE;
  262.         plane_ctl |= PLANE_CTL_PIPE_CSC_ENABLE;
  263.  
  264.         intel_update_sprite_watermarks(drm_plane, crtc, src_w, src_h,
  265.                                        pixel_size, true,
  266.                                        src_w != crtc_w || src_h != crtc_h);
  267.  
  268.         /* Sizes are 0 based */
  269.         src_w--;
  270.         src_h--;
  271.         crtc_w--;
  272.         crtc_h--;
  273.  
  274.         I915_WRITE(PLANE_OFFSET(pipe, plane), (y << 16) | x);
  275.         I915_WRITE(PLANE_STRIDE(pipe, plane), stride);
  276.         I915_WRITE(PLANE_POS(pipe, plane), (crtc_y << 16) | crtc_x);
  277.         I915_WRITE(PLANE_SIZE(pipe, plane), (crtc_h << 16) | crtc_w);
  278.         I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl);
  279.         I915_WRITE(PLANE_SURF(pipe, plane), i915_gem_obj_ggtt_offset(obj));
  280.         POSTING_READ(PLANE_SURF(pipe, plane));
  281. }
  282.  
  283. static void
  284. skl_disable_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc)
  285. {
  286.         struct drm_device *dev = drm_plane->dev;
  287.         struct drm_i915_private *dev_priv = dev->dev_private;
  288.         struct intel_plane *intel_plane = to_intel_plane(drm_plane);
  289.         const int pipe = intel_plane->pipe;
  290.         const int plane = intel_plane->plane + 1;
  291.  
  292.         I915_WRITE(PLANE_CTL(pipe, plane),
  293.                    I915_READ(PLANE_CTL(pipe, plane)) & ~PLANE_CTL_ENABLE);
  294.  
  295.         /* Activate double buffered register update */
  296.         I915_WRITE(PLANE_CTL(pipe, plane), 0);
  297.         POSTING_READ(PLANE_CTL(pipe, plane));
  298.  
  299.         intel_update_sprite_watermarks(drm_plane, crtc, 0, 0, 0, false, false);
  300. }
  301.  
  302. static int
  303. skl_update_colorkey(struct drm_plane *drm_plane,
  304.                     struct drm_intel_sprite_colorkey *key)
  305. {
  306.         struct drm_device *dev = drm_plane->dev;
  307.         struct drm_i915_private *dev_priv = dev->dev_private;
  308.         struct intel_plane *intel_plane = to_intel_plane(drm_plane);
  309.         const int pipe = intel_plane->pipe;
  310.         const int plane = intel_plane->plane;
  311.         u32 plane_ctl;
  312.  
  313.         I915_WRITE(PLANE_KEYVAL(pipe, plane), key->min_value);
  314.         I915_WRITE(PLANE_KEYMAX(pipe, plane), key->max_value);
  315.         I915_WRITE(PLANE_KEYMSK(pipe, plane), key->channel_mask);
  316.  
  317.         plane_ctl = I915_READ(PLANE_CTL(pipe, plane));
  318.         plane_ctl &= ~PLANE_CTL_KEY_ENABLE_MASK;
  319.         if (key->flags & I915_SET_COLORKEY_DESTINATION)
  320.                 plane_ctl |= PLANE_CTL_KEY_ENABLE_DESTINATION;
  321.         else if (key->flags & I915_SET_COLORKEY_SOURCE)
  322.                 plane_ctl |= PLANE_CTL_KEY_ENABLE_SOURCE;
  323.         I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl);
  324.  
  325.         POSTING_READ(PLANE_CTL(pipe, plane));
  326.  
  327.         return 0;
  328. }
  329.  
  330. static void
  331. skl_get_colorkey(struct drm_plane *drm_plane,
  332.                  struct drm_intel_sprite_colorkey *key)
  333. {
  334.         struct drm_device *dev = drm_plane->dev;
  335.         struct drm_i915_private *dev_priv = dev->dev_private;
  336.         struct intel_plane *intel_plane = to_intel_plane(drm_plane);
  337.         const int pipe = intel_plane->pipe;
  338.         const int plane = intel_plane->plane;
  339.         u32 plane_ctl;
  340.  
  341.         key->min_value = I915_READ(PLANE_KEYVAL(pipe, plane));
  342.         key->max_value = I915_READ(PLANE_KEYMAX(pipe, plane));
  343.         key->channel_mask = I915_READ(PLANE_KEYMSK(pipe, plane));
  344.  
  345.         plane_ctl = I915_READ(PLANE_CTL(pipe, plane));
  346.  
  347.         switch (plane_ctl & PLANE_CTL_KEY_ENABLE_MASK) {
  348.         case PLANE_CTL_KEY_ENABLE_DESTINATION:
  349.                 key->flags = I915_SET_COLORKEY_DESTINATION;
  350.                 break;
  351.         case PLANE_CTL_KEY_ENABLE_SOURCE:
  352.                 key->flags = I915_SET_COLORKEY_SOURCE;
  353.                 break;
  354.         default:
  355.                 key->flags = I915_SET_COLORKEY_NONE;
  356.         }
  357. }
  358.  
  359. static void
  360. chv_update_csc(struct intel_plane *intel_plane, uint32_t format)
  361. {
  362.         struct drm_i915_private *dev_priv = intel_plane->base.dev->dev_private;
  363.         int plane = intel_plane->plane;
  364.  
  365.         /* Seems RGB data bypasses the CSC always */
  366.         if (!format_is_yuv(format))
  367.                 return;
  368.  
  369.         /*
  370.          * BT.601 limited range YCbCr -> full range RGB
  371.          *
  372.          * |r|   | 6537 4769     0|   |cr  |
  373.          * |g| = |-3330 4769 -1605| x |y-64|
  374.          * |b|   |    0 4769  8263|   |cb  |
  375.          *
  376.          * Cb and Cr apparently come in as signed already, so no
  377.          * need for any offset. For Y we need to remove the offset.
  378.          */
  379.         I915_WRITE(SPCSCYGOFF(plane), SPCSC_OOFF(0) | SPCSC_IOFF(-64));
  380.         I915_WRITE(SPCSCCBOFF(plane), SPCSC_OOFF(0) | SPCSC_IOFF(0));
  381.         I915_WRITE(SPCSCCROFF(plane), SPCSC_OOFF(0) | SPCSC_IOFF(0));
  382.  
  383.         I915_WRITE(SPCSCC01(plane), SPCSC_C1(4769) | SPCSC_C0(6537));
  384.         I915_WRITE(SPCSCC23(plane), SPCSC_C1(-3330) | SPCSC_C0(0));
  385.         I915_WRITE(SPCSCC45(plane), SPCSC_C1(-1605) | SPCSC_C0(4769));
  386.         I915_WRITE(SPCSCC67(plane), SPCSC_C1(4769) | SPCSC_C0(0));
  387.         I915_WRITE(SPCSCC8(plane), SPCSC_C0(8263));
  388.  
  389.         I915_WRITE(SPCSCYGICLAMP(plane), SPCSC_IMAX(940) | SPCSC_IMIN(64));
  390.         I915_WRITE(SPCSCCBICLAMP(plane), SPCSC_IMAX(448) | SPCSC_IMIN(-448));
  391.         I915_WRITE(SPCSCCRICLAMP(plane), SPCSC_IMAX(448) | SPCSC_IMIN(-448));
  392.  
  393.         I915_WRITE(SPCSCYGOCLAMP(plane), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
  394.         I915_WRITE(SPCSCCBOCLAMP(plane), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
  395.         I915_WRITE(SPCSCCROCLAMP(plane), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
  396. }
  397.  
  398. static void
  399. vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
  400.                  struct drm_framebuffer *fb,
  401.                  struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
  402.                  unsigned int crtc_w, unsigned int crtc_h,
  403.                  uint32_t x, uint32_t y,
  404.                  uint32_t src_w, uint32_t src_h)
  405. {
  406.         struct drm_device *dev = dplane->dev;
  407.         struct drm_i915_private *dev_priv = dev->dev_private;
  408.         struct intel_plane *intel_plane = to_intel_plane(dplane);
  409.         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  410.         int pipe = intel_plane->pipe;
  411.         int plane = intel_plane->plane;
  412.         u32 sprctl;
  413.         unsigned long sprsurf_offset, linear_offset;
  414.         int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
  415.         u32 start_vbl_count;
  416.         bool atomic_update;
  417.  
  418.         sprctl = I915_READ(SPCNTR(pipe, plane));
  419.  
  420.         /* Mask out pixel format bits in case we change it */
  421.         sprctl &= ~SP_PIXFORMAT_MASK;
  422.         sprctl &= ~SP_YUV_BYTE_ORDER_MASK;
  423.         sprctl &= ~SP_TILED;
  424.         sprctl &= ~SP_ROTATE_180;
  425.  
  426.         switch (fb->pixel_format) {
  427.         case DRM_FORMAT_YUYV:
  428.                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV;
  429.                 break;
  430.         case DRM_FORMAT_YVYU:
  431.                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU;
  432.                 break;
  433.         case DRM_FORMAT_UYVY:
  434.                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY;
  435.                 break;
  436.         case DRM_FORMAT_VYUY:
  437.                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY;
  438.                 break;
  439.         case DRM_FORMAT_RGB565:
  440.                 sprctl |= SP_FORMAT_BGR565;
  441.                 break;
  442.         case DRM_FORMAT_XRGB8888:
  443.                 sprctl |= SP_FORMAT_BGRX8888;
  444.                 break;
  445.         case DRM_FORMAT_ARGB8888:
  446.                 sprctl |= SP_FORMAT_BGRA8888;
  447.                 break;
  448.         case DRM_FORMAT_XBGR2101010:
  449.                 sprctl |= SP_FORMAT_RGBX1010102;
  450.                 break;
  451.         case DRM_FORMAT_ABGR2101010:
  452.                 sprctl |= SP_FORMAT_RGBA1010102;
  453.                 break;
  454.         case DRM_FORMAT_XBGR8888:
  455.                 sprctl |= SP_FORMAT_RGBX8888;
  456.                 break;
  457.         case DRM_FORMAT_ABGR8888:
  458.                 sprctl |= SP_FORMAT_RGBA8888;
  459.                 break;
  460.         default:
  461.                 /*
  462.                  * If we get here one of the upper layers failed to filter
  463.                  * out the unsupported plane formats
  464.                  */
  465.                 BUG();
  466.                 break;
  467.         }
  468.  
  469.         /*
  470.          * Enable gamma to match primary/cursor plane behaviour.
  471.          * FIXME should be user controllable via propertiesa.
  472.          */
  473.         sprctl |= SP_GAMMA_ENABLE;
  474.  
  475.         if (obj->tiling_mode != I915_TILING_NONE)
  476.                 sprctl |= SP_TILED;
  477.  
  478.         sprctl |= SP_ENABLE;
  479.  
  480.         intel_update_sprite_watermarks(dplane, crtc, src_w, src_h,
  481.                                        pixel_size, true,
  482.                                        src_w != crtc_w || src_h != crtc_h);
  483.  
  484.         /* Sizes are 0 based */
  485.         src_w--;
  486.         src_h--;
  487.         crtc_w--;
  488.         crtc_h--;
  489.  
  490.         linear_offset = y * fb->pitches[0] + x * pixel_size;
  491.         sprsurf_offset = intel_gen4_compute_page_offset(&x, &y,
  492.                                                         obj->tiling_mode,
  493.                                                         pixel_size,
  494.                                                         fb->pitches[0]);
  495.         linear_offset -= sprsurf_offset;
  496.  
  497.         if (intel_plane->rotation == BIT(DRM_ROTATE_180)) {
  498.                 sprctl |= SP_ROTATE_180;
  499.  
  500.                 x += src_w;
  501.                 y += src_h;
  502.                 linear_offset += src_h * fb->pitches[0] + src_w * pixel_size;
  503.         }
  504.  
  505.         atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
  506.  
  507.         intel_update_primary_plane(intel_crtc);
  508.  
  509.         if (IS_CHERRYVIEW(dev) && pipe == PIPE_B)
  510.                 chv_update_csc(intel_plane, fb->pixel_format);
  511.  
  512.         I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]);
  513.         I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x);
  514.  
  515.         if (obj->tiling_mode != I915_TILING_NONE)
  516.                 I915_WRITE(SPTILEOFF(pipe, plane), (y << 16) | x);
  517.         else
  518.                 I915_WRITE(SPLINOFF(pipe, plane), linear_offset);
  519.  
  520.         I915_WRITE(SPCONSTALPHA(pipe, plane), 0);
  521.  
  522.         I915_WRITE(SPSIZE(pipe, plane), (crtc_h << 16) | crtc_w);
  523.         I915_WRITE(SPCNTR(pipe, plane), sprctl);
  524.         I915_WRITE(SPSURF(pipe, plane), i915_gem_obj_ggtt_offset(obj) +
  525.                              sprsurf_offset);
  526.  
  527.         intel_flush_primary_plane(dev_priv, intel_crtc->plane);
  528.  
  529.         if (atomic_update)
  530.                 intel_pipe_update_end(intel_crtc, start_vbl_count);
  531. }
  532.  
  533. static void
  534. vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc)
  535. {
  536.         struct drm_device *dev = dplane->dev;
  537.         struct drm_i915_private *dev_priv = dev->dev_private;
  538.         struct intel_plane *intel_plane = to_intel_plane(dplane);
  539.         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  540.         int pipe = intel_plane->pipe;
  541.         int plane = intel_plane->plane;
  542.         u32 start_vbl_count;
  543.         bool atomic_update;
  544.  
  545.         atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
  546.  
  547.         intel_update_primary_plane(intel_crtc);
  548.  
  549.         I915_WRITE(SPCNTR(pipe, plane), I915_READ(SPCNTR(pipe, plane)) &
  550.                    ~SP_ENABLE);
  551.         /* Activate double buffered register update */
  552.         I915_WRITE(SPSURF(pipe, plane), 0);
  553.  
  554.         intel_flush_primary_plane(dev_priv, intel_crtc->plane);
  555.  
  556.         if (atomic_update)
  557.                 intel_pipe_update_end(intel_crtc, start_vbl_count);
  558.  
  559.         intel_update_sprite_watermarks(dplane, crtc, 0, 0, 0, false, false);
  560. }
  561.  
  562. static int
  563. vlv_update_colorkey(struct drm_plane *dplane,
  564.                     struct drm_intel_sprite_colorkey *key)
  565. {
  566.         struct drm_device *dev = dplane->dev;
  567.         struct drm_i915_private *dev_priv = dev->dev_private;
  568.         struct intel_plane *intel_plane = to_intel_plane(dplane);
  569.         int pipe = intel_plane->pipe;
  570.         int plane = intel_plane->plane;
  571.         u32 sprctl;
  572.  
  573.         if (key->flags & I915_SET_COLORKEY_DESTINATION)
  574.                 return -EINVAL;
  575.  
  576.         I915_WRITE(SPKEYMINVAL(pipe, plane), key->min_value);
  577.         I915_WRITE(SPKEYMAXVAL(pipe, plane), key->max_value);
  578.         I915_WRITE(SPKEYMSK(pipe, plane), key->channel_mask);
  579.  
  580.         sprctl = I915_READ(SPCNTR(pipe, plane));
  581.         sprctl &= ~SP_SOURCE_KEY;
  582.         if (key->flags & I915_SET_COLORKEY_SOURCE)
  583.                 sprctl |= SP_SOURCE_KEY;
  584.         I915_WRITE(SPCNTR(pipe, plane), sprctl);
  585.  
  586.         POSTING_READ(SPKEYMSK(pipe, plane));
  587.  
  588.         return 0;
  589. }
  590.  
  591. static void
  592. vlv_get_colorkey(struct drm_plane *dplane,
  593.                  struct drm_intel_sprite_colorkey *key)
  594. {
  595.         struct drm_device *dev = dplane->dev;
  596.         struct drm_i915_private *dev_priv = dev->dev_private;
  597.         struct intel_plane *intel_plane = to_intel_plane(dplane);
  598.         int pipe = intel_plane->pipe;
  599.         int plane = intel_plane->plane;
  600.         u32 sprctl;
  601.  
  602.         key->min_value = I915_READ(SPKEYMINVAL(pipe, plane));
  603.         key->max_value = I915_READ(SPKEYMAXVAL(pipe, plane));
  604.         key->channel_mask = I915_READ(SPKEYMSK(pipe, plane));
  605.  
  606.         sprctl = I915_READ(SPCNTR(pipe, plane));
  607.         if (sprctl & SP_SOURCE_KEY)
  608.                 key->flags = I915_SET_COLORKEY_SOURCE;
  609.         else
  610.                 key->flags = I915_SET_COLORKEY_NONE;
  611. }
  612.  
  613. static void
  614. ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
  615.                  struct drm_framebuffer *fb,
  616.                  struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
  617.                  unsigned int crtc_w, unsigned int crtc_h,
  618.                  uint32_t x, uint32_t y,
  619.                  uint32_t src_w, uint32_t src_h)
  620. {
  621.         struct drm_device *dev = plane->dev;
  622.         struct drm_i915_private *dev_priv = dev->dev_private;
  623.         struct intel_plane *intel_plane = to_intel_plane(plane);
  624.         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  625.         int pipe = intel_plane->pipe;
  626.         u32 sprctl, sprscale = 0;
  627.         unsigned long sprsurf_offset, linear_offset;
  628.         int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
  629.         u32 start_vbl_count;
  630.         bool atomic_update;
  631.  
  632.         sprctl = I915_READ(SPRCTL(pipe));
  633.  
  634.         /* Mask out pixel format bits in case we change it */
  635.         sprctl &= ~SPRITE_PIXFORMAT_MASK;
  636.         sprctl &= ~SPRITE_RGB_ORDER_RGBX;
  637.         sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK;
  638.         sprctl &= ~SPRITE_TILED;
  639.         sprctl &= ~SPRITE_ROTATE_180;
  640.  
  641.         switch (fb->pixel_format) {
  642.         case DRM_FORMAT_XBGR8888:
  643.                 sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
  644.                 break;
  645.         case DRM_FORMAT_XRGB8888:
  646.                 sprctl |= SPRITE_FORMAT_RGBX888;
  647.                 break;
  648.         case DRM_FORMAT_YUYV:
  649.                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
  650.                 break;
  651.         case DRM_FORMAT_YVYU:
  652.                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
  653.                 break;
  654.         case DRM_FORMAT_UYVY:
  655.                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
  656.                 break;
  657.         case DRM_FORMAT_VYUY:
  658.                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
  659.                 break;
  660.         default:
  661.                 BUG();
  662.         }
  663.  
  664.         /*
  665.          * Enable gamma to match primary/cursor plane behaviour.
  666.          * FIXME should be user controllable via propertiesa.
  667.          */
  668.         sprctl |= SPRITE_GAMMA_ENABLE;
  669.  
  670.         if (obj->tiling_mode != I915_TILING_NONE)
  671.                 sprctl |= SPRITE_TILED;
  672.  
  673.         if (IS_HASWELL(dev) || IS_BROADWELL(dev))
  674.                 sprctl &= ~SPRITE_TRICKLE_FEED_DISABLE;
  675.         else
  676.         sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
  677.  
  678.         sprctl |= SPRITE_ENABLE;
  679.  
  680.         if (IS_HASWELL(dev) || IS_BROADWELL(dev))
  681.                 sprctl |= SPRITE_PIPE_CSC_ENABLE;
  682.  
  683.         intel_update_sprite_watermarks(plane, crtc, src_w, src_h, pixel_size,
  684.                                        true,
  685.                                        src_w != crtc_w || src_h != crtc_h);
  686.  
  687.         /* Sizes are 0 based */
  688.         src_w--;
  689.         src_h--;
  690.         crtc_w--;
  691.         crtc_h--;
  692.  
  693.         if (crtc_w != src_w || crtc_h != src_h)
  694.                 sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
  695.  
  696.         linear_offset = y * fb->pitches[0] + x * pixel_size;
  697.         sprsurf_offset =
  698.                 intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode,
  699.                                                  pixel_size, fb->pitches[0]);
  700.         linear_offset -= sprsurf_offset;
  701.  
  702.         if (intel_plane->rotation == BIT(DRM_ROTATE_180)) {
  703.                 sprctl |= SPRITE_ROTATE_180;
  704.  
  705.                 /* HSW and BDW does this automagically in hardware */
  706.                 if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) {
  707.                         x += src_w;
  708.                         y += src_h;
  709.                         linear_offset += src_h * fb->pitches[0] +
  710.                                 src_w * pixel_size;
  711.                 }
  712.         }
  713.  
  714.         atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
  715.  
  716.         intel_update_primary_plane(intel_crtc);
  717.  
  718.         I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]);
  719.         I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
  720.  
  721.         /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
  722.          * register */
  723.         if (IS_HASWELL(dev) || IS_BROADWELL(dev))
  724.                 I915_WRITE(SPROFFSET(pipe), (y << 16) | x);
  725.         else if (obj->tiling_mode != I915_TILING_NONE)
  726.                 I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x);
  727.         else
  728.                 I915_WRITE(SPRLINOFF(pipe), linear_offset);
  729.  
  730.         I915_WRITE(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
  731.         if (intel_plane->can_scale)
  732.         I915_WRITE(SPRSCALE(pipe), sprscale);
  733.         I915_WRITE(SPRCTL(pipe), sprctl);
  734.         I915_WRITE(SPRSURF(pipe),
  735.                              i915_gem_obj_ggtt_offset(obj) + sprsurf_offset);
  736.  
  737.         intel_flush_primary_plane(dev_priv, intel_crtc->plane);
  738.  
  739.         if (atomic_update)
  740.                 intel_pipe_update_end(intel_crtc, start_vbl_count);
  741. }
  742.  
  743. static void
  744. ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)
  745. {
  746.         struct drm_device *dev = plane->dev;
  747.         struct drm_i915_private *dev_priv = dev->dev_private;
  748.         struct intel_plane *intel_plane = to_intel_plane(plane);
  749.         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  750.         int pipe = intel_plane->pipe;
  751.         u32 start_vbl_count;
  752.         bool atomic_update;
  753.  
  754.         atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
  755.  
  756.         intel_update_primary_plane(intel_crtc);
  757.  
  758.         I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE);
  759.         /* Can't leave the scaler enabled... */
  760.         if (intel_plane->can_scale)
  761.         I915_WRITE(SPRSCALE(pipe), 0);
  762.         /* Activate double buffered register update */
  763.         I915_WRITE(SPRSURF(pipe), 0);
  764.  
  765.         intel_flush_primary_plane(dev_priv, intel_crtc->plane);
  766.  
  767.         if (atomic_update)
  768.                 intel_pipe_update_end(intel_crtc, start_vbl_count);
  769.  
  770.         /*
  771.          * Avoid underruns when disabling the sprite.
  772.          * FIXME remove once watermark updates are done properly.
  773.          */
  774.         intel_wait_for_vblank(dev, pipe);
  775.  
  776.         intel_update_sprite_watermarks(plane, crtc, 0, 0, 0, false, false);
  777. }
  778.  
  779. static int
  780. ivb_update_colorkey(struct drm_plane *plane,
  781.                     struct drm_intel_sprite_colorkey *key)
  782. {
  783.         struct drm_device *dev = plane->dev;
  784.         struct drm_i915_private *dev_priv = dev->dev_private;
  785.         struct intel_plane *intel_plane;
  786.         u32 sprctl;
  787.         int ret = 0;
  788.  
  789.         intel_plane = to_intel_plane(plane);
  790.  
  791.         I915_WRITE(SPRKEYVAL(intel_plane->pipe), key->min_value);
  792.         I915_WRITE(SPRKEYMAX(intel_plane->pipe), key->max_value);
  793.         I915_WRITE(SPRKEYMSK(intel_plane->pipe), key->channel_mask);
  794.  
  795.         sprctl = I915_READ(SPRCTL(intel_plane->pipe));
  796.         sprctl &= ~(SPRITE_SOURCE_KEY | SPRITE_DEST_KEY);
  797.         if (key->flags & I915_SET_COLORKEY_DESTINATION)
  798.                 sprctl |= SPRITE_DEST_KEY;
  799.         else if (key->flags & I915_SET_COLORKEY_SOURCE)
  800.                 sprctl |= SPRITE_SOURCE_KEY;
  801.         I915_WRITE(SPRCTL(intel_plane->pipe), sprctl);
  802.  
  803.         POSTING_READ(SPRKEYMSK(intel_plane->pipe));
  804.  
  805.         return ret;
  806. }
  807.  
  808. static void
  809. ivb_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key)
  810. {
  811.         struct drm_device *dev = plane->dev;
  812.         struct drm_i915_private *dev_priv = dev->dev_private;
  813.         struct intel_plane *intel_plane;
  814.         u32 sprctl;
  815.  
  816.         intel_plane = to_intel_plane(plane);
  817.  
  818.         key->min_value = I915_READ(SPRKEYVAL(intel_plane->pipe));
  819.         key->max_value = I915_READ(SPRKEYMAX(intel_plane->pipe));
  820.         key->channel_mask = I915_READ(SPRKEYMSK(intel_plane->pipe));
  821.         key->flags = 0;
  822.  
  823.         sprctl = I915_READ(SPRCTL(intel_plane->pipe));
  824.  
  825.         if (sprctl & SPRITE_DEST_KEY)
  826.                 key->flags = I915_SET_COLORKEY_DESTINATION;
  827.         else if (sprctl & SPRITE_SOURCE_KEY)
  828.                 key->flags = I915_SET_COLORKEY_SOURCE;
  829.         else
  830.                 key->flags = I915_SET_COLORKEY_NONE;
  831. }
  832.  
  833. static void
  834. ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
  835.                  struct drm_framebuffer *fb,
  836.                  struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
  837.                  unsigned int crtc_w, unsigned int crtc_h,
  838.                  uint32_t x, uint32_t y,
  839.                  uint32_t src_w, uint32_t src_h)
  840. {
  841.         struct drm_device *dev = plane->dev;
  842.         struct drm_i915_private *dev_priv = dev->dev_private;
  843.         struct intel_plane *intel_plane = to_intel_plane(plane);
  844.         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  845.         int pipe = intel_plane->pipe;
  846.         unsigned long dvssurf_offset, linear_offset;
  847.         u32 dvscntr, dvsscale;
  848.         int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
  849.         u32 start_vbl_count;
  850.         bool atomic_update;
  851.  
  852.         dvscntr = I915_READ(DVSCNTR(pipe));
  853.  
  854.         /* Mask out pixel format bits in case we change it */
  855.         dvscntr &= ~DVS_PIXFORMAT_MASK;
  856.         dvscntr &= ~DVS_RGB_ORDER_XBGR;
  857.         dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK;
  858.         dvscntr &= ~DVS_TILED;
  859.         dvscntr &= ~DVS_ROTATE_180;
  860.  
  861.         switch (fb->pixel_format) {
  862.         case DRM_FORMAT_XBGR8888:
  863.                 dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR;
  864.                 break;
  865.         case DRM_FORMAT_XRGB8888:
  866.                 dvscntr |= DVS_FORMAT_RGBX888;
  867.                 break;
  868.         case DRM_FORMAT_YUYV:
  869.                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
  870.                 break;
  871.         case DRM_FORMAT_YVYU:
  872.                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
  873.                 break;
  874.         case DRM_FORMAT_UYVY:
  875.                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
  876.                 break;
  877.         case DRM_FORMAT_VYUY:
  878.                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
  879.                 break;
  880.         default:
  881.                 BUG();
  882.         }
  883.  
  884.         /*
  885.          * Enable gamma to match primary/cursor plane behaviour.
  886.          * FIXME should be user controllable via propertiesa.
  887.          */
  888.         dvscntr |= DVS_GAMMA_ENABLE;
  889.  
  890.         if (obj->tiling_mode != I915_TILING_NONE)
  891.                 dvscntr |= DVS_TILED;
  892.  
  893.         if (IS_GEN6(dev))
  894.                 dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */
  895.         dvscntr |= DVS_ENABLE;
  896.  
  897.         intel_update_sprite_watermarks(plane, crtc, src_w, src_h,
  898.                                        pixel_size, true,
  899.                                        src_w != crtc_w || src_h != crtc_h);
  900.  
  901.         /* Sizes are 0 based */
  902.         src_w--;
  903.         src_h--;
  904.         crtc_w--;
  905.         crtc_h--;
  906.  
  907.         dvsscale = 0;
  908.         if (crtc_w != src_w || crtc_h != src_h)
  909.                 dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h;
  910.  
  911.         linear_offset = y * fb->pitches[0] + x * pixel_size;
  912.         dvssurf_offset =
  913.                 intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode,
  914.                                                  pixel_size, fb->pitches[0]);
  915.         linear_offset -= dvssurf_offset;
  916.  
  917.         if (intel_plane->rotation == BIT(DRM_ROTATE_180)) {
  918.                 dvscntr |= DVS_ROTATE_180;
  919.  
  920.                 x += src_w;
  921.                 y += src_h;
  922.                 linear_offset += src_h * fb->pitches[0] + src_w * pixel_size;
  923.         }
  924.  
  925.         atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
  926.  
  927.         intel_update_primary_plane(intel_crtc);
  928.  
  929.         I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]);
  930.         I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
  931.  
  932.         if (obj->tiling_mode != I915_TILING_NONE)
  933.                 I915_WRITE(DVSTILEOFF(pipe), (y << 16) | x);
  934.         else
  935.                 I915_WRITE(DVSLINOFF(pipe), linear_offset);
  936.  
  937.         I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
  938.         I915_WRITE(DVSSCALE(pipe), dvsscale);
  939.         I915_WRITE(DVSCNTR(pipe), dvscntr);
  940.         I915_WRITE(DVSSURF(pipe),
  941.                              i915_gem_obj_ggtt_offset(obj) + dvssurf_offset);
  942.  
  943.         intel_flush_primary_plane(dev_priv, intel_crtc->plane);
  944.  
  945.         if (atomic_update)
  946.                 intel_pipe_update_end(intel_crtc, start_vbl_count);
  947. }
  948.  
  949. static void
  950. ilk_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)
  951. {
  952.         struct drm_device *dev = plane->dev;
  953.         struct drm_i915_private *dev_priv = dev->dev_private;
  954.         struct intel_plane *intel_plane = to_intel_plane(plane);
  955.         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  956.         int pipe = intel_plane->pipe;
  957.         u32 start_vbl_count;
  958.         bool atomic_update;
  959.  
  960.         atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
  961.  
  962.         intel_update_primary_plane(intel_crtc);
  963.  
  964.         I915_WRITE(DVSCNTR(pipe), I915_READ(DVSCNTR(pipe)) & ~DVS_ENABLE);
  965.         /* Disable the scaler */
  966.         I915_WRITE(DVSSCALE(pipe), 0);
  967.         /* Flush double buffered register updates */
  968.         I915_WRITE(DVSSURF(pipe), 0);
  969.  
  970.         intel_flush_primary_plane(dev_priv, intel_crtc->plane);
  971.  
  972.         if (atomic_update)
  973.                 intel_pipe_update_end(intel_crtc, start_vbl_count);
  974.  
  975.         /*
  976.          * Avoid underruns when disabling the sprite.
  977.          * FIXME remove once watermark updates are done properly.
  978.          */
  979.         intel_wait_for_vblank(dev, pipe);
  980.  
  981.         intel_update_sprite_watermarks(plane, crtc, 0, 0, 0, false, false);
  982. }
  983.  
  984. static void
  985. intel_post_enable_primary(struct drm_crtc *crtc)
  986. {
  987.         struct drm_device *dev = crtc->dev;
  988.         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  989.  
  990.         /*
  991.          * BDW signals flip done immediately if the plane
  992.          * is disabled, even if the plane enable is already
  993.          * armed to occur at the next vblank :(
  994.          */
  995.         if (IS_BROADWELL(dev))
  996.                 intel_wait_for_vblank(dev, intel_crtc->pipe);
  997.  
  998.         /*
  999.          * FIXME IPS should be fine as long as one plane is
  1000.          * enabled, but in practice it seems to have problems
  1001.          * when going from primary only to sprite only and vice
  1002.          * versa.
  1003.          */
  1004.                 hsw_enable_ips(intel_crtc);
  1005.  
  1006.         mutex_lock(&dev->struct_mutex);
  1007.         intel_update_fbc(dev);
  1008.         mutex_unlock(&dev->struct_mutex);
  1009. }
  1010.  
  1011. static void
  1012. intel_pre_disable_primary(struct drm_crtc *crtc)
  1013. {
  1014.         struct drm_device *dev = crtc->dev;
  1015.         struct drm_i915_private *dev_priv = dev->dev_private;
  1016.         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  1017.  
  1018.         mutex_lock(&dev->struct_mutex);
  1019.         if (dev_priv->fbc.plane == intel_crtc->plane)
  1020.                 intel_disable_fbc(dev);
  1021.         mutex_unlock(&dev->struct_mutex);
  1022.  
  1023.         /*
  1024.          * FIXME IPS should be fine as long as one plane is
  1025.          * enabled, but in practice it seems to have problems
  1026.          * when going from primary only to sprite only and vice
  1027.          * versa.
  1028.          */
  1029.         hsw_disable_ips(intel_crtc);
  1030. }
  1031.  
  1032. static int
  1033. ilk_update_colorkey(struct drm_plane *plane,
  1034.                     struct drm_intel_sprite_colorkey *key)
  1035. {
  1036.         struct drm_device *dev = plane->dev;
  1037.         struct drm_i915_private *dev_priv = dev->dev_private;
  1038.         struct intel_plane *intel_plane;
  1039.         u32 dvscntr;
  1040.         int ret = 0;
  1041.  
  1042.         intel_plane = to_intel_plane(plane);
  1043.  
  1044.         I915_WRITE(DVSKEYVAL(intel_plane->pipe), key->min_value);
  1045.         I915_WRITE(DVSKEYMAX(intel_plane->pipe), key->max_value);
  1046.         I915_WRITE(DVSKEYMSK(intel_plane->pipe), key->channel_mask);
  1047.  
  1048.         dvscntr = I915_READ(DVSCNTR(intel_plane->pipe));
  1049.         dvscntr &= ~(DVS_SOURCE_KEY | DVS_DEST_KEY);
  1050.         if (key->flags & I915_SET_COLORKEY_DESTINATION)
  1051.                 dvscntr |= DVS_DEST_KEY;
  1052.         else if (key->flags & I915_SET_COLORKEY_SOURCE)
  1053.                 dvscntr |= DVS_SOURCE_KEY;
  1054.         I915_WRITE(DVSCNTR(intel_plane->pipe), dvscntr);
  1055.  
  1056.         POSTING_READ(DVSKEYMSK(intel_plane->pipe));
  1057.  
  1058.         return ret;
  1059. }
  1060.  
  1061. static void
  1062. ilk_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key)
  1063. {
  1064.         struct drm_device *dev = plane->dev;
  1065.         struct drm_i915_private *dev_priv = dev->dev_private;
  1066.         struct intel_plane *intel_plane;
  1067.         u32 dvscntr;
  1068.  
  1069.         intel_plane = to_intel_plane(plane);
  1070.  
  1071.         key->min_value = I915_READ(DVSKEYVAL(intel_plane->pipe));
  1072.         key->max_value = I915_READ(DVSKEYMAX(intel_plane->pipe));
  1073.         key->channel_mask = I915_READ(DVSKEYMSK(intel_plane->pipe));
  1074.         key->flags = 0;
  1075.  
  1076.         dvscntr = I915_READ(DVSCNTR(intel_plane->pipe));
  1077.  
  1078.         if (dvscntr & DVS_DEST_KEY)
  1079.                 key->flags = I915_SET_COLORKEY_DESTINATION;
  1080.         else if (dvscntr & DVS_SOURCE_KEY)
  1081.                 key->flags = I915_SET_COLORKEY_SOURCE;
  1082.         else
  1083.                 key->flags = I915_SET_COLORKEY_NONE;
  1084. }
  1085.  
  1086. static bool colorkey_enabled(struct intel_plane *intel_plane)
  1087. {
  1088.         struct drm_intel_sprite_colorkey key;
  1089.  
  1090.         intel_plane->get_colorkey(&intel_plane->base, &key);
  1091.  
  1092.         return key.flags != I915_SET_COLORKEY_NONE;
  1093. }
  1094.  
  1095. static int
  1096. intel_check_sprite_plane(struct drm_plane *plane,
  1097.                          struct intel_plane_state *state)
  1098. {
  1099.         struct intel_crtc *intel_crtc = to_intel_crtc(state->crtc);
  1100.         struct intel_plane *intel_plane = to_intel_plane(plane);
  1101.         struct drm_framebuffer *fb = state->fb;
  1102.         struct drm_i915_gem_object *obj = intel_fb_obj(fb);
  1103.         int crtc_x, crtc_y;
  1104.         unsigned int crtc_w, crtc_h;
  1105.         uint32_t src_x, src_y, src_w, src_h;
  1106.         struct drm_rect *src = &state->src;
  1107.         struct drm_rect *dst = &state->dst;
  1108.         struct drm_rect *orig_src = &state->orig_src;
  1109.         const struct drm_rect *clip = &state->clip;
  1110.         int hscale, vscale;
  1111.         int max_scale, min_scale;
  1112.         int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
  1113.  
  1114.         /* Don't modify another pipe's plane */
  1115.         if (intel_plane->pipe != intel_crtc->pipe) {
  1116.                 DRM_DEBUG_KMS("Wrong plane <-> crtc mapping\n");
  1117.                 return -EINVAL;
  1118.         }
  1119.  
  1120.         /* FIXME check all gen limits */
  1121.         if (fb->width < 3 || fb->height < 3 || fb->pitches[0] > 16384) {
  1122.                 DRM_DEBUG_KMS("Unsuitable framebuffer for plane\n");
  1123.                 return -EINVAL;
  1124.         }
  1125.  
  1126.         /* Sprite planes can be linear or x-tiled surfaces */
  1127.         switch (obj->tiling_mode) {
  1128.                 case I915_TILING_NONE:
  1129.                 case I915_TILING_X:
  1130.                         break;
  1131.                 default:
  1132.                         DRM_DEBUG_KMS("Unsupported tiling mode\n");
  1133.                         return -EINVAL;
  1134.         }
  1135.  
  1136.         /*
  1137.          * FIXME the following code does a bunch of fuzzy adjustments to the
  1138.          * coordinates and sizes. We probably need some way to decide whether
  1139.          * more strict checking should be done instead.
  1140.          */
  1141.         max_scale = intel_plane->max_downscale << 16;
  1142.         min_scale = intel_plane->can_scale ? 1 : (1 << 16);
  1143.  
  1144.         drm_rect_rotate(src, fb->width << 16, fb->height << 16,
  1145.                         intel_plane->rotation);
  1146.  
  1147.         hscale = drm_rect_calc_hscale_relaxed(src, dst, min_scale, max_scale);
  1148.         BUG_ON(hscale < 0);
  1149.  
  1150.         vscale = drm_rect_calc_vscale_relaxed(src, dst, min_scale, max_scale);
  1151.         BUG_ON(vscale < 0);
  1152.  
  1153.         state->visible =  drm_rect_clip_scaled(src, dst, clip, hscale, vscale);
  1154.  
  1155.         crtc_x = dst->x1;
  1156.         crtc_y = dst->y1;
  1157.         crtc_w = drm_rect_width(dst);
  1158.         crtc_h = drm_rect_height(dst);
  1159.  
  1160.         if (state->visible) {
  1161.                 /* check again in case clipping clamped the results */
  1162.                 hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
  1163.                 if (hscale < 0) {
  1164.                         DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n");
  1165.                         drm_rect_debug_print(src, true);
  1166.                         drm_rect_debug_print(dst, false);
  1167.  
  1168.                         return hscale;
  1169.         }
  1170.  
  1171.                 vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
  1172.                 if (vscale < 0) {
  1173.                         DRM_DEBUG_KMS("Vertical scaling factor out of limits\n");
  1174.                         drm_rect_debug_print(src, true);
  1175.                         drm_rect_debug_print(dst, false);
  1176.  
  1177.                         return vscale;
  1178.         }
  1179.  
  1180.                 /* Make the source viewport size an exact multiple of the scaling factors. */
  1181.                 drm_rect_adjust_size(src,
  1182.                                      drm_rect_width(dst) * hscale - drm_rect_width(src),
  1183.                                      drm_rect_height(dst) * vscale - drm_rect_height(src));
  1184.  
  1185.                 drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16,
  1186.                                     intel_plane->rotation);
  1187.  
  1188.                 /* sanity check to make sure the src viewport wasn't enlarged */
  1189.                 WARN_ON(src->x1 < (int) orig_src->x1 ||
  1190.                         src->y1 < (int) orig_src->y1 ||
  1191.                         src->x2 > (int) orig_src->x2 ||
  1192.                         src->y2 > (int) orig_src->y2);
  1193.  
  1194.         /*
  1195.                  * Hardware doesn't handle subpixel coordinates.
  1196.                  * Adjust to (macro)pixel boundary, but be careful not to
  1197.                  * increase the source viewport size, because that could
  1198.                  * push the downscaling factor out of bounds.
  1199.          */
  1200.                 src_x = src->x1 >> 16;
  1201.                 src_w = drm_rect_width(src) >> 16;
  1202.                 src_y = src->y1 >> 16;
  1203.                 src_h = drm_rect_height(src) >> 16;
  1204.  
  1205.                 if (format_is_yuv(fb->pixel_format)) {
  1206.                         src_x &= ~1;
  1207.                         src_w &= ~1;
  1208.  
  1209.         /*
  1210.                          * Must keep src and dst the
  1211.                          * same if we can't scale.
  1212.          */
  1213.                         if (!intel_plane->can_scale)
  1214.                                 crtc_w &= ~1;
  1215.  
  1216.                         if (crtc_w == 0)
  1217.                                 state->visible = false;
  1218.                 }
  1219.         }
  1220.  
  1221.         /* Check size restrictions when scaling */
  1222.         if (state->visible && (src_w != crtc_w || src_h != crtc_h)) {
  1223.                 unsigned int width_bytes;
  1224.  
  1225.                 WARN_ON(!intel_plane->can_scale);
  1226.  
  1227.                 /* FIXME interlacing min height is 6 */
  1228.  
  1229.                 if (crtc_w < 3 || crtc_h < 3)
  1230.                         state->visible = false;
  1231.  
  1232.                 if (src_w < 3 || src_h < 3)
  1233.                         state->visible = false;
  1234.  
  1235.                 width_bytes = ((src_x * pixel_size) & 63) +
  1236.                                         src_w * pixel_size;
  1237.  
  1238.                 if (src_w > 2048 || src_h > 2048 ||
  1239.                     width_bytes > 4096 || fb->pitches[0] > 4096) {
  1240.                         DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
  1241.                 return -EINVAL;
  1242.                 }
  1243.         }
  1244.  
  1245.         if (state->visible) {
  1246.                 src->x1 = src_x;
  1247.                 src->x2 = src_x + src_w;
  1248.                 src->y1 = src_y;
  1249.                 src->y2 = src_y + src_h;
  1250.         }
  1251.  
  1252.         dst->x1 = crtc_x;
  1253.         dst->x2 = crtc_x + crtc_w;
  1254.         dst->y1 = crtc_y;
  1255.         dst->y2 = crtc_y + crtc_h;
  1256.  
  1257.         return 0;
  1258. }
  1259.  
  1260. static int
  1261. intel_prepare_sprite_plane(struct drm_plane *plane,
  1262.                            struct intel_plane_state *state)
  1263. {
  1264.         struct drm_device *dev = plane->dev;
  1265.         struct drm_crtc *crtc = state->crtc;
  1266.         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  1267.         struct intel_plane *intel_plane = to_intel_plane(plane);
  1268.         enum pipe pipe = intel_crtc->pipe;
  1269.         struct drm_framebuffer *fb = state->fb;
  1270.         struct drm_i915_gem_object *obj = intel_fb_obj(fb);
  1271.         struct drm_i915_gem_object *old_obj = intel_plane->obj;
  1272.         int ret;
  1273.  
  1274.         if (old_obj != obj) {
  1275.         mutex_lock(&dev->struct_mutex);
  1276.  
  1277.         /* Note that this will apply the VT-d workaround for scanouts,
  1278.          * which is more restrictive than required for sprites. (The
  1279.          * primary plane requires 256KiB alignment with 64 PTE padding,
  1280.                  * the sprite planes only require 128KiB alignment and 32 PTE
  1281.                  * padding.
  1282.          */
  1283.                 ret = intel_pin_and_fence_fb_obj(plane, fb, NULL);
  1284.                 if (ret == 0)
  1285.         i915_gem_track_fb(old_obj, obj,
  1286.                           INTEL_FRONTBUFFER_SPRITE(pipe));
  1287.         mutex_unlock(&dev->struct_mutex);
  1288.         if (ret)
  1289.                 return ret;
  1290.         }
  1291.  
  1292.         return 0;
  1293. }
  1294.  
  1295. static void
  1296. intel_commit_sprite_plane(struct drm_plane *plane,
  1297.                           struct intel_plane_state *state)
  1298. {
  1299.         struct drm_device *dev = plane->dev;
  1300.         struct drm_crtc *crtc = state->crtc;
  1301.         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  1302.         struct intel_plane *intel_plane = to_intel_plane(plane);
  1303.         enum pipe pipe = intel_crtc->pipe;
  1304.         struct drm_framebuffer *fb = state->fb;
  1305.         struct drm_i915_gem_object *obj = intel_fb_obj(fb);
  1306.         struct drm_i915_gem_object *old_obj = intel_plane->obj;
  1307.         int crtc_x, crtc_y;
  1308.         unsigned int crtc_w, crtc_h;
  1309.         uint32_t src_x, src_y, src_w, src_h;
  1310.         struct drm_rect *dst = &state->dst;
  1311.         const struct drm_rect *clip = &state->clip;
  1312.         bool primary_enabled;
  1313.  
  1314.         /*
  1315.          * If the sprite is completely covering the primary plane,
  1316.          * we can disable the primary and save power.
  1317.          */
  1318.         primary_enabled = !drm_rect_equals(dst, clip) || colorkey_enabled(intel_plane);
  1319.         WARN_ON(!primary_enabled && !state->visible && intel_crtc->active);
  1320.  
  1321.         intel_plane->crtc_x = state->orig_dst.x1;
  1322.         intel_plane->crtc_y = state->orig_dst.y1;
  1323.         intel_plane->crtc_w = drm_rect_width(&state->orig_dst);
  1324.         intel_plane->crtc_h = drm_rect_height(&state->orig_dst);
  1325.         intel_plane->src_x = state->orig_src.x1;
  1326.         intel_plane->src_y = state->orig_src.y1;
  1327.         intel_plane->src_w = drm_rect_width(&state->orig_src);
  1328.         intel_plane->src_h = drm_rect_height(&state->orig_src);
  1329.         intel_plane->obj = obj;
  1330.  
  1331.         if (intel_crtc->active) {
  1332.                 bool primary_was_enabled = intel_crtc->primary_enabled;
  1333.  
  1334.                 intel_crtc->primary_enabled = primary_enabled;
  1335.  
  1336. //       if (primary_was_enabled != primary_enabled)
  1337. //           intel_crtc_wait_for_pending_flips(crtc);
  1338.  
  1339.                 if (primary_was_enabled && !primary_enabled)
  1340.                         intel_pre_disable_primary(crtc);
  1341.  
  1342.                 if (state->visible) {
  1343.                         crtc_x = state->dst.x1;
  1344.                         crtc_y = state->dst.y1;
  1345.                         crtc_w = drm_rect_width(&state->dst);
  1346.                         crtc_h = drm_rect_height(&state->dst);
  1347.                         src_x = state->src.x1;
  1348.                         src_y = state->src.y1;
  1349.                         src_w = drm_rect_width(&state->src);
  1350.                         src_h = drm_rect_height(&state->src);
  1351.                 intel_plane->update_plane(plane, crtc, fb, obj,
  1352.                                           crtc_x, crtc_y, crtc_w, crtc_h,
  1353.                                           src_x, src_y, src_w, src_h);
  1354.                 } else {
  1355.                 intel_plane->disable_plane(plane, crtc);
  1356.                 }
  1357.  
  1358.  
  1359.                 intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_SPRITE(pipe));
  1360.  
  1361.                 if (!primary_was_enabled && primary_enabled)
  1362.                         intel_post_enable_primary(crtc);
  1363.         }
  1364.  
  1365.         /* Unpin old obj after new one is active to avoid ugliness */
  1366.         if (old_obj && old_obj != obj) {
  1367.  
  1368.                 /*
  1369.                  * It's fairly common to simply update the position of
  1370.                  * an existing object.  In that case, we don't need to
  1371.                  * wait for vblank to avoid ugliness, we only need to
  1372.                  * do the pin & ref bookkeeping.
  1373.                  */
  1374.                 if (intel_crtc->active)
  1375.                         intel_wait_for_vblank(dev, intel_crtc->pipe);
  1376.  
  1377.                         mutex_lock(&dev->struct_mutex);
  1378.                 intel_unpin_fb_obj(old_obj);
  1379.                 mutex_unlock(&dev->struct_mutex);
  1380.         }
  1381. }
  1382.  
  1383. static int
  1384. intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
  1385.                    struct drm_framebuffer *fb, int crtc_x, int crtc_y,
  1386.                    unsigned int crtc_w, unsigned int crtc_h,
  1387.                    uint32_t src_x, uint32_t src_y,
  1388.                    uint32_t src_w, uint32_t src_h)
  1389. {
  1390.         struct intel_plane_state state;
  1391.         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  1392.         int ret;
  1393.  
  1394.         state.crtc = crtc;
  1395.         state.fb = fb;
  1396.  
  1397.         /* sample coordinates in 16.16 fixed point */
  1398.         state.src.x1 = src_x;
  1399.         state.src.x2 = src_x + src_w;
  1400.         state.src.y1 = src_y;
  1401.         state.src.y2 = src_y + src_h;
  1402.  
  1403.         /* integer pixels */
  1404.         state.dst.x1 = crtc_x;
  1405.         state.dst.x2 = crtc_x + crtc_w;
  1406.         state.dst.y1 = crtc_y;
  1407.         state.dst.y2 = crtc_y + crtc_h;
  1408.  
  1409.         state.clip.x1 = 0;
  1410.         state.clip.y1 = 0;
  1411.         state.clip.x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0;
  1412.         state.clip.y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0;
  1413.         state.orig_src = state.src;
  1414.         state.orig_dst = state.dst;
  1415.  
  1416.         ret = intel_check_sprite_plane(plane, &state);
  1417.         if (ret)
  1418.                 return ret;
  1419.  
  1420.         ret = intel_prepare_sprite_plane(plane, &state);
  1421.         if (ret)
  1422.                 return ret;
  1423.  
  1424.         intel_commit_sprite_plane(plane, &state);
  1425.         return 0;
  1426. }
  1427.  
  1428. static int
  1429. intel_disable_plane(struct drm_plane *plane)
  1430. {
  1431.         struct drm_device *dev = plane->dev;
  1432.         struct intel_plane *intel_plane = to_intel_plane(plane);
  1433.         struct intel_crtc *intel_crtc;
  1434.         enum pipe pipe;
  1435.  
  1436.         if (!plane->fb)
  1437.                 return 0;
  1438.  
  1439.         if (WARN_ON(!plane->crtc))
  1440.                 return -EINVAL;
  1441.  
  1442.         intel_crtc = to_intel_crtc(plane->crtc);
  1443.         pipe = intel_crtc->pipe;
  1444.  
  1445.         if (intel_crtc->active) {
  1446.                 bool primary_was_enabled = intel_crtc->primary_enabled;
  1447.  
  1448.                 intel_crtc->primary_enabled = true;
  1449.  
  1450.         intel_plane->disable_plane(plane, plane->crtc);
  1451.  
  1452.                 if (!primary_was_enabled && intel_crtc->primary_enabled)
  1453.                         intel_post_enable_primary(plane->crtc);
  1454.         }
  1455.  
  1456.         if (intel_plane->obj) {
  1457.                 if (intel_crtc->active)
  1458.         intel_wait_for_vblank(dev, intel_plane->pipe);
  1459.  
  1460.         mutex_lock(&dev->struct_mutex);
  1461.         intel_unpin_fb_obj(intel_plane->obj);
  1462.                 i915_gem_track_fb(intel_plane->obj, NULL,
  1463.                                   INTEL_FRONTBUFFER_SPRITE(pipe));
  1464.                 mutex_unlock(&dev->struct_mutex);
  1465.  
  1466.         intel_plane->obj = NULL;
  1467.         }
  1468.  
  1469.         return 0;
  1470. }
  1471.  
  1472. static void intel_destroy_plane(struct drm_plane *plane)
  1473. {
  1474.         struct intel_plane *intel_plane = to_intel_plane(plane);
  1475.         intel_disable_plane(plane);
  1476.         drm_plane_cleanup(plane);
  1477.         kfree(intel_plane);
  1478. }
  1479.  
  1480. int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
  1481.                               struct drm_file *file_priv)
  1482. {
  1483.         struct drm_intel_sprite_colorkey *set = data;
  1484.         struct drm_plane *plane;
  1485.         struct intel_plane *intel_plane;
  1486.         int ret = 0;
  1487.  
  1488.         if (!drm_core_check_feature(dev, DRIVER_MODESET))
  1489.                 return -ENODEV;
  1490.  
  1491.         /* Make sure we don't try to enable both src & dest simultaneously */
  1492.         if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
  1493.                 return -EINVAL;
  1494.  
  1495.         drm_modeset_lock_all(dev);
  1496.  
  1497.         plane = drm_plane_find(dev, set->plane_id);
  1498.         if (!plane) {
  1499.                 ret = -ENOENT;
  1500.                 goto out_unlock;
  1501.         }
  1502.  
  1503.         intel_plane = to_intel_plane(plane);
  1504.         ret = intel_plane->update_colorkey(plane, set);
  1505.  
  1506. out_unlock:
  1507.         drm_modeset_unlock_all(dev);
  1508.         return ret;
  1509. }
  1510.  
  1511. int intel_sprite_get_colorkey(struct drm_device *dev, void *data,
  1512.                               struct drm_file *file_priv)
  1513. {
  1514.         struct drm_intel_sprite_colorkey *get = data;
  1515.         struct drm_plane *plane;
  1516.         struct intel_plane *intel_plane;
  1517.         int ret = 0;
  1518.  
  1519.         if (!drm_core_check_feature(dev, DRIVER_MODESET))
  1520.                 return -ENODEV;
  1521.  
  1522.         drm_modeset_lock_all(dev);
  1523.  
  1524.         plane = drm_plane_find(dev, get->plane_id);
  1525.         if (!plane) {
  1526.                 ret = -ENOENT;
  1527.                 goto out_unlock;
  1528.         }
  1529.  
  1530.         intel_plane = to_intel_plane(plane);
  1531.         intel_plane->get_colorkey(plane, get);
  1532.  
  1533. out_unlock:
  1534.         drm_modeset_unlock_all(dev);
  1535.         return ret;
  1536. }
  1537.  
  1538. int intel_plane_set_property(struct drm_plane *plane,
  1539.                              struct drm_property *prop,
  1540.                              uint64_t val)
  1541. {
  1542.         struct drm_device *dev = plane->dev;
  1543.         struct intel_plane *intel_plane = to_intel_plane(plane);
  1544.         uint64_t old_val;
  1545.         int ret = -ENOENT;
  1546.  
  1547.         if (prop == dev->mode_config.rotation_property) {
  1548.                 /* exactly one rotation angle please */
  1549.                 if (hweight32(val & 0xf) != 1)
  1550.                         return -EINVAL;
  1551.  
  1552.                 if (intel_plane->rotation == val)
  1553.                         return 0;
  1554.  
  1555.                 old_val = intel_plane->rotation;
  1556.                 intel_plane->rotation = val;
  1557.                 ret = intel_plane_restore(plane);
  1558.                 if (ret)
  1559.                         intel_plane->rotation = old_val;
  1560.         }
  1561.  
  1562.         return ret;
  1563. }
  1564.  
  1565. int intel_plane_restore(struct drm_plane *plane)
  1566. {
  1567.         struct intel_plane *intel_plane = to_intel_plane(plane);
  1568.  
  1569.         if (!plane->crtc || !plane->fb)
  1570.                 return 0;
  1571.  
  1572.         return plane->funcs->update_plane(plane, plane->crtc, plane->fb,
  1573.                            intel_plane->crtc_x, intel_plane->crtc_y,
  1574.                            intel_plane->crtc_w, intel_plane->crtc_h,
  1575.                            intel_plane->src_x, intel_plane->src_y,
  1576.                            intel_plane->src_w, intel_plane->src_h);
  1577. }
  1578.  
  1579. void intel_plane_disable(struct drm_plane *plane)
  1580. {
  1581.         if (!plane->crtc || !plane->fb)
  1582.                 return;
  1583.  
  1584.         intel_disable_plane(plane);
  1585. }
  1586.  
  1587. static const struct drm_plane_funcs intel_plane_funcs = {
  1588.         .update_plane = intel_update_plane,
  1589.         .disable_plane = intel_disable_plane,
  1590.         .destroy = intel_destroy_plane,
  1591.         .set_property = intel_plane_set_property,
  1592. };
  1593.  
  1594. static uint32_t ilk_plane_formats[] = {
  1595.         DRM_FORMAT_XRGB8888,
  1596.         DRM_FORMAT_YUYV,
  1597.         DRM_FORMAT_YVYU,
  1598.         DRM_FORMAT_UYVY,
  1599.         DRM_FORMAT_VYUY,
  1600. };
  1601.  
  1602. static uint32_t snb_plane_formats[] = {
  1603.         DRM_FORMAT_XBGR8888,
  1604.         DRM_FORMAT_XRGB8888,
  1605.         DRM_FORMAT_YUYV,
  1606.         DRM_FORMAT_YVYU,
  1607.         DRM_FORMAT_UYVY,
  1608.         DRM_FORMAT_VYUY,
  1609. };
  1610.  
  1611. static uint32_t vlv_plane_formats[] = {
  1612.         DRM_FORMAT_RGB565,
  1613.         DRM_FORMAT_ABGR8888,
  1614.         DRM_FORMAT_ARGB8888,
  1615.         DRM_FORMAT_XBGR8888,
  1616.         DRM_FORMAT_XRGB8888,
  1617.         DRM_FORMAT_XBGR2101010,
  1618.         DRM_FORMAT_ABGR2101010,
  1619.         DRM_FORMAT_YUYV,
  1620.         DRM_FORMAT_YVYU,
  1621.         DRM_FORMAT_UYVY,
  1622.         DRM_FORMAT_VYUY,
  1623. };
  1624.  
  1625. static uint32_t skl_plane_formats[] = {
  1626.         DRM_FORMAT_RGB565,
  1627.         DRM_FORMAT_ABGR8888,
  1628.         DRM_FORMAT_ARGB8888,
  1629.         DRM_FORMAT_XBGR8888,
  1630.         DRM_FORMAT_XRGB8888,
  1631.         DRM_FORMAT_YUYV,
  1632.         DRM_FORMAT_YVYU,
  1633.         DRM_FORMAT_UYVY,
  1634.         DRM_FORMAT_VYUY,
  1635. };
  1636.  
  1637. int
  1638. intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
  1639. {
  1640.         struct intel_plane *intel_plane;
  1641.         unsigned long possible_crtcs;
  1642.         const uint32_t *plane_formats;
  1643.         int num_plane_formats;
  1644.         int ret;
  1645.  
  1646.         if (INTEL_INFO(dev)->gen < 5)
  1647.                 return -ENODEV;
  1648.  
  1649.         intel_plane = kzalloc(sizeof(*intel_plane), GFP_KERNEL);
  1650.         if (!intel_plane)
  1651.                 return -ENOMEM;
  1652.  
  1653.         switch (INTEL_INFO(dev)->gen) {
  1654.         case 5:
  1655.         case 6:
  1656.                 intel_plane->can_scale = true;
  1657.                 intel_plane->max_downscale = 16;
  1658.                 intel_plane->update_plane = ilk_update_plane;
  1659.                 intel_plane->disable_plane = ilk_disable_plane;
  1660.                 intel_plane->update_colorkey = ilk_update_colorkey;
  1661.                 intel_plane->get_colorkey = ilk_get_colorkey;
  1662.  
  1663.         if (IS_GEN6(dev)) {
  1664.                         plane_formats = snb_plane_formats;
  1665.                         num_plane_formats = ARRAY_SIZE(snb_plane_formats);
  1666.                 } else {
  1667.                         plane_formats = ilk_plane_formats;
  1668.                         num_plane_formats = ARRAY_SIZE(ilk_plane_formats);
  1669.                 }
  1670.                 break;
  1671.  
  1672.         case 7:
  1673.         case 8:
  1674.                 if (IS_IVYBRIDGE(dev)) {
  1675.                         intel_plane->can_scale = true;
  1676.                         intel_plane->max_downscale = 2;
  1677.                 } else {
  1678.                         intel_plane->can_scale = false;
  1679.                         intel_plane->max_downscale = 1;
  1680.                 }
  1681.  
  1682.                 if (IS_VALLEYVIEW(dev)) {
  1683.                         intel_plane->update_plane = vlv_update_plane;
  1684.                         intel_plane->disable_plane = vlv_disable_plane;
  1685.                         intel_plane->update_colorkey = vlv_update_colorkey;
  1686.                         intel_plane->get_colorkey = vlv_get_colorkey;
  1687.  
  1688.                         plane_formats = vlv_plane_formats;
  1689.                         num_plane_formats = ARRAY_SIZE(vlv_plane_formats);
  1690.                 } else {
  1691.                 intel_plane->update_plane = ivb_update_plane;
  1692.                 intel_plane->disable_plane = ivb_disable_plane;
  1693.                 intel_plane->update_colorkey = ivb_update_colorkey;
  1694.                 intel_plane->get_colorkey = ivb_get_colorkey;
  1695.  
  1696.                 plane_formats = snb_plane_formats;
  1697.                 num_plane_formats = ARRAY_SIZE(snb_plane_formats);
  1698.                 }
  1699.                 break;
  1700.         case 9:
  1701.                 /*
  1702.                  * FIXME: Skylake planes can be scaled (with some restrictions),
  1703.                  * but this is for another time.
  1704.                  */
  1705.                 intel_plane->can_scale = false;
  1706.                 intel_plane->max_downscale = 1;
  1707.                 intel_plane->update_plane = skl_update_plane;
  1708.                 intel_plane->disable_plane = skl_disable_plane;
  1709.                 intel_plane->update_colorkey = skl_update_colorkey;
  1710.                 intel_plane->get_colorkey = skl_get_colorkey;
  1711.  
  1712.                 plane_formats = skl_plane_formats;
  1713.                 num_plane_formats = ARRAY_SIZE(skl_plane_formats);
  1714.                 break;
  1715.         default:
  1716.                 kfree(intel_plane);
  1717.                 return -ENODEV;
  1718.         }
  1719.  
  1720.         intel_plane->pipe = pipe;
  1721.         intel_plane->plane = plane;
  1722.         intel_plane->rotation = BIT(DRM_ROTATE_0);
  1723.         possible_crtcs = (1 << pipe);
  1724.         ret = drm_universal_plane_init(dev, &intel_plane->base, possible_crtcs,
  1725.                              &intel_plane_funcs,
  1726.                              plane_formats, num_plane_formats,
  1727.                                        DRM_PLANE_TYPE_OVERLAY);
  1728.         if (ret) {
  1729.                 kfree(intel_plane);
  1730.                 goto out;
  1731.         }
  1732.  
  1733.         if (!dev->mode_config.rotation_property)
  1734.                 dev->mode_config.rotation_property =
  1735.                         drm_mode_create_rotation_property(dev,
  1736.                                                           BIT(DRM_ROTATE_0) |
  1737.                                                           BIT(DRM_ROTATE_180));
  1738.  
  1739.         if (dev->mode_config.rotation_property)
  1740.                 drm_object_attach_property(&intel_plane->base.base,
  1741.                                            dev->mode_config.rotation_property,
  1742.                                            intel_plane->rotation);
  1743.  
  1744.  out:
  1745.         return ret;
  1746. }
  1747.