]> git.baikalelectronics.ru Git - kernel.git/commitdiff
Merge remote-tracking branch 'airlied/drm-next' into drm-intel-next-queued
authorDaniel Vetter <daniel.vetter@ffwll.ch>
Mon, 15 Aug 2016 08:41:47 +0000 (10:41 +0200)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Mon, 15 Aug 2016 08:41:47 +0000 (10:41 +0200)
Backmerge because too many conflicts, and also we need to get at the
latest struct fence patches from Gustavo. Requested by Chris Wilson.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
1  2 
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/i915/intel_sprite.c

Simple merge
Simple merge
Simple merge
index 21ec74ea77d2a422ef2055b88002c75dcf1293b8,c6f27ab99e8f292f4aaee717fc419cbdf8acd372..c5c0c35d4f6e55ff193fb080fce2d88a7c0f9325
@@@ -2456,177 -2383,6 +2456,177 @@@ static u32 _intel_compute_tile_offset(c
        return offset_aligned;
  }
  
-                                                   BIT(DRM_ROTATE_0), tile_size);
 +u32 intel_compute_tile_offset(int *x, int *y,
 +                            const struct intel_plane_state *state,
 +                            int plane)
 +{
 +      const struct drm_i915_private *dev_priv = to_i915(state->base.plane->dev);
 +      const struct drm_framebuffer *fb = state->base.fb;
 +      unsigned int rotation = state->base.rotation;
 +      int pitch = intel_fb_pitch(fb, plane, rotation);
 +      u32 alignment;
 +
 +      /* AUX_DIST needs only 4K alignment */
 +      if (fb->pixel_format == DRM_FORMAT_NV12 && plane == 1)
 +              alignment = 4096;
 +      else
 +              alignment = intel_surf_alignment(dev_priv, fb->modifier[plane]);
 +
 +      return _intel_compute_tile_offset(dev_priv, x, y, fb, plane, pitch,
 +                                        rotation, alignment);
 +}
 +
 +/* Convert the fb->offset[] linear offset into x/y offsets */
 +static void intel_fb_offset_to_xy(int *x, int *y,
 +                                const struct drm_framebuffer *fb, int plane)
 +{
 +      unsigned int cpp = drm_format_plane_cpp(fb->pixel_format, plane);
 +      unsigned int pitch = fb->pitches[plane];
 +      u32 linear_offset = fb->offsets[plane];
 +
 +      *y = linear_offset / pitch;
 +      *x = linear_offset % pitch / cpp;
 +}
 +
 +static unsigned int intel_fb_modifier_to_tiling(uint64_t fb_modifier)
 +{
 +      switch (fb_modifier) {
 +      case I915_FORMAT_MOD_X_TILED:
 +              return I915_TILING_X;
 +      case I915_FORMAT_MOD_Y_TILED:
 +              return I915_TILING_Y;
 +      default:
 +              return I915_TILING_NONE;
 +      }
 +}
 +
 +static int
 +intel_fill_fb_info(struct drm_i915_private *dev_priv,
 +                 struct drm_framebuffer *fb)
 +{
 +      struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
 +      struct intel_rotation_info *rot_info = &intel_fb->rot_info;
 +      u32 gtt_offset_rotated = 0;
 +      unsigned int max_size = 0;
 +      uint32_t format = fb->pixel_format;
 +      int i, num_planes = drm_format_num_planes(format);
 +      unsigned int tile_size = intel_tile_size(dev_priv);
 +
 +      for (i = 0; i < num_planes; i++) {
 +              unsigned int width, height;
 +              unsigned int cpp, size;
 +              u32 offset;
 +              int x, y;
 +
 +              cpp = drm_format_plane_cpp(format, i);
 +              width = drm_format_plane_width(fb->width, format, i);
 +              height = drm_format_plane_height(fb->height, format, i);
 +
 +              intel_fb_offset_to_xy(&x, &y, fb, i);
 +
 +              /*
 +               * The fence (if used) is aligned to the start of the object
 +               * so having the framebuffer wrap around across the edge of the
 +               * fenced region doesn't really work. We have no API to configure
 +               * the fence start offset within the object (nor could we probably
 +               * on gen2/3). So it's just easier if we just require that the
 +               * fb layout agrees with the fence layout. We already check that the
 +               * fb stride matches the fence stride elsewhere.
 +               */
 +              if (i915_gem_object_is_tiled(intel_fb->obj) &&
 +                  (x + width) * cpp > fb->pitches[i]) {
 +                      DRM_DEBUG("bad fb plane %d offset: 0x%x\n",
 +                                i, fb->offsets[i]);
 +                      return -EINVAL;
 +              }
 +
 +              /*
 +               * First pixel of the framebuffer from
 +               * the start of the normal gtt mapping.
 +               */
 +              intel_fb->normal[i].x = x;
 +              intel_fb->normal[i].y = y;
 +
 +              offset = _intel_compute_tile_offset(dev_priv, &x, &y,
 +                                                  fb, 0, fb->pitches[i],
-                                       BIT(DRM_ROTATE_270));
++                                                  DRM_ROTATE_0, tile_size);
 +              offset /= tile_size;
 +
 +              if (fb->modifier[i] != DRM_FORMAT_MOD_NONE) {
 +                      unsigned int tile_width, tile_height;
 +                      unsigned int pitch_tiles;
 +                      struct drm_rect r;
 +
 +                      intel_tile_dims(dev_priv, &tile_width, &tile_height,
 +                                      fb->modifier[i], cpp);
 +
 +                      rot_info->plane[i].offset = offset;
 +                      rot_info->plane[i].stride = DIV_ROUND_UP(fb->pitches[i], tile_width * cpp);
 +                      rot_info->plane[i].width = DIV_ROUND_UP(x + width, tile_width);
 +                      rot_info->plane[i].height = DIV_ROUND_UP(y + height, tile_height);
 +
 +                      intel_fb->rotated[i].pitch =
 +                              rot_info->plane[i].height * tile_height;
 +
 +                      /* how many tiles does this plane need */
 +                      size = rot_info->plane[i].stride * rot_info->plane[i].height;
 +                      /*
 +                       * If the plane isn't horizontally tile aligned,
 +                       * we need one more tile.
 +                       */
 +                      if (x != 0)
 +                              size++;
 +
 +                      /* rotate the x/y offsets to match the GTT view */
 +                      r.x1 = x;
 +                      r.y1 = y;
 +                      r.x2 = x + width;
 +                      r.y2 = y + height;
 +                      drm_rect_rotate(&r,
 +                                      rot_info->plane[i].width * tile_width,
 +                                      rot_info->plane[i].height * tile_height,
++                                      DRM_ROTATE_270);
 +                      x = r.x1;
 +                      y = r.y1;
 +
 +                      /* rotate the tile dimensions to match the GTT view */
 +                      pitch_tiles = intel_fb->rotated[i].pitch / tile_height;
 +                      swap(tile_width, tile_height);
 +
 +                      /*
 +                       * We only keep the x/y offsets, so push all of the
 +                       * gtt offset into the x/y offsets.
 +                       */
 +                      _intel_adjust_tile_offset(&x, &y, tile_size,
 +                                                tile_width, tile_height, pitch_tiles,
 +                                                gtt_offset_rotated * tile_size, 0);
 +
 +                      gtt_offset_rotated += rot_info->plane[i].width * rot_info->plane[i].height;
 +
 +                      /*
 +                       * First pixel of the framebuffer from
 +                       * the start of the rotated gtt mapping.
 +                       */
 +                      intel_fb->rotated[i].x = x;
 +                      intel_fb->rotated[i].y = y;
 +              } else {
 +                      size = DIV_ROUND_UP((y + height) * fb->pitches[i] +
 +                                          x * cpp, tile_size);
 +              }
 +
 +              /* how many tiles in total needed in the bo */
 +              max_size = max(max_size, offset + size);
 +      }
 +
 +      if (max_size * tile_size > to_intel_framebuffer(fb)->obj->base.size) {
 +              DRM_DEBUG("fb too big for bo (need %u bytes, have %zu bytes)\n",
 +                        max_size * tile_size, to_intel_framebuffer(fb)->obj->base.size);
 +              return -EINVAL;
 +      }
 +
 +      return 0;
 +}
 +
  static int i9xx_format_to_fourcc(int format)
  {
        switch (format) {
@@@ -2848,169 -2604,6 +2848,169 @@@ valid_fb
                  &obj->frontbuffer_bits);
  }
  
-       int x = plane_state->src.x1 >> 16;
-       int y = plane_state->src.y1 >> 16;
-       int w = drm_rect_width(&plane_state->src) >> 16;
-       int h = drm_rect_height(&plane_state->src) >> 16;
 +static int skl_max_plane_width(const struct drm_framebuffer *fb, int plane,
 +                             unsigned int rotation)
 +{
 +      int cpp = drm_format_plane_cpp(fb->pixel_format, plane);
 +
 +      switch (fb->modifier[plane]) {
 +      case DRM_FORMAT_MOD_NONE:
 +      case I915_FORMAT_MOD_X_TILED:
 +              switch (cpp) {
 +              case 8:
 +                      return 4096;
 +              case 4:
 +              case 2:
 +              case 1:
 +                      return 8192;
 +              default:
 +                      MISSING_CASE(cpp);
 +                      break;
 +              }
 +              break;
 +      case I915_FORMAT_MOD_Y_TILED:
 +      case I915_FORMAT_MOD_Yf_TILED:
 +              switch (cpp) {
 +              case 8:
 +                      return 2048;
 +              case 4:
 +                      return 4096;
 +              case 2:
 +              case 1:
 +                      return 8192;
 +              default:
 +                      MISSING_CASE(cpp);
 +                      break;
 +              }
 +              break;
 +      default:
 +              MISSING_CASE(fb->modifier[plane]);
 +      }
 +
 +      return 2048;
 +}
 +
 +static int skl_check_main_surface(struct intel_plane_state *plane_state)
 +{
 +      const struct drm_i915_private *dev_priv = to_i915(plane_state->base.plane->dev);
 +      const struct drm_framebuffer *fb = plane_state->base.fb;
 +      unsigned int rotation = plane_state->base.rotation;
-       int x = plane_state->src.x1 >> 17;
-       int y = plane_state->src.y1 >> 17;
-       int w = drm_rect_width(&plane_state->src) >> 17;
-       int h = drm_rect_height(&plane_state->src) >> 17;
++      int x = plane_state->base.src.x1 >> 16;
++      int y = plane_state->base.src.y1 >> 16;
++      int w = drm_rect_width(&plane_state->base.src) >> 16;
++      int h = drm_rect_height(&plane_state->base.src) >> 16;
 +      int max_width = skl_max_plane_width(fb, 0, rotation);
 +      int max_height = 4096;
 +      u32 alignment, offset, aux_offset = plane_state->aux.offset;
 +
 +      if (w > max_width || h > max_height) {
 +              DRM_DEBUG_KMS("requested Y/RGB source size %dx%d too big (limit %dx%d)\n",
 +                            w, h, max_width, max_height);
 +              return -EINVAL;
 +      }
 +
 +      intel_add_fb_offsets(&x, &y, plane_state, 0);
 +      offset = intel_compute_tile_offset(&x, &y, plane_state, 0);
 +
 +      alignment = intel_surf_alignment(dev_priv, fb->modifier[0]);
 +
 +      /*
 +       * AUX surface offset is specified as the distance from the
 +       * main surface offset, and it must be non-negative. Make
 +       * sure that is what we will get.
 +       */
 +      if (offset > aux_offset)
 +              offset = intel_adjust_tile_offset(&x, &y, plane_state, 0,
 +                                                offset, aux_offset & ~(alignment - 1));
 +
 +      /*
 +       * When using an X-tiled surface, the plane blows up
 +       * if the x offset + width exceed the stride.
 +       *
 +       * TODO: linear and Y-tiled seem fine, Yf untested,
 +       */
 +      if (fb->modifier[0] == I915_FORMAT_MOD_X_TILED) {
 +              int cpp = drm_format_plane_cpp(fb->pixel_format, 0);
 +
 +              while ((x + w) * cpp > fb->pitches[0]) {
 +                      if (offset == 0) {
 +                              DRM_DEBUG_KMS("Unable to find suitable display surface offset\n");
 +                              return -EINVAL;
 +                      }
 +
 +                      offset = intel_adjust_tile_offset(&x, &y, plane_state, 0,
 +                                                        offset, offset - alignment);
 +              }
 +      }
 +
 +      plane_state->main.offset = offset;
 +      plane_state->main.x = x;
 +      plane_state->main.y = y;
 +
 +      return 0;
 +}
 +
 +static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state)
 +{
 +      const struct drm_framebuffer *fb = plane_state->base.fb;
 +      unsigned int rotation = plane_state->base.rotation;
 +      int max_width = skl_max_plane_width(fb, 1, rotation);
 +      int max_height = 4096;
-               drm_rect_rotate(&plane_state->src,
-                               fb->width, fb->height, BIT(DRM_ROTATE_270));
++      int x = plane_state->base.src.x1 >> 17;
++      int y = plane_state->base.src.y1 >> 17;
++      int w = drm_rect_width(&plane_state->base.src) >> 17;
++      int h = drm_rect_height(&plane_state->base.src) >> 17;
 +      u32 offset;
 +
 +      intel_add_fb_offsets(&x, &y, plane_state, 1);
 +      offset = intel_compute_tile_offset(&x, &y, plane_state, 1);
 +
 +      /* FIXME not quite sure how/if these apply to the chroma plane */
 +      if (w > max_width || h > max_height) {
 +              DRM_DEBUG_KMS("CbCr source size %dx%d too big (limit %dx%d)\n",
 +                            w, h, max_width, max_height);
 +              return -EINVAL;
 +      }
 +
 +      plane_state->aux.offset = offset;
 +      plane_state->aux.x = x;
 +      plane_state->aux.y = y;
 +
 +      return 0;
 +}
 +
 +int skl_check_plane_surface(struct intel_plane_state *plane_state)
 +{
 +      const struct drm_framebuffer *fb = plane_state->base.fb;
 +      unsigned int rotation = plane_state->base.rotation;
 +      int ret;
 +
 +      /* Rotate src coordinates to match rotated GTT view */
 +      if (intel_rotation_90_or_270(rotation))
++              drm_rect_rotate(&plane_state->base.src,
++                              fb->width, fb->height, DRM_ROTATE_270);
 +
 +      /*
 +       * Handle the AUX surface first since
 +       * the main surface setup depends on it.
 +       */
 +      if (fb->pixel_format == DRM_FORMAT_NV12) {
 +              ret = skl_check_nv12_aux_surface(plane_state);
 +              if (ret)
 +                      return ret;
 +      } else {
 +              plane_state->aux.offset = ~0xfff;
 +              plane_state->aux.x = 0;
 +              plane_state->aux.y = 0;
 +      }
 +
 +      ret = skl_check_main_surface(plane_state);
 +      if (ret)
 +              return ret;
 +
 +      return 0;
 +}
 +
  static void i9xx_update_primary_plane(struct drm_plane *primary,
                                      const struct intel_crtc_state *crtc_state,
                                      const struct intel_plane_state *plane_state)
        u32 dspcntr;
        i915_reg_t reg = DSPCNTR(plane);
        unsigned int rotation = plane_state->base.rotation;
-       int x = plane_state->src.x1 >> 16;
-       int y = plane_state->src.y1 >> 16;
 -      int cpp = drm_format_plane_cpp(fb->pixel_format, 0);
+       int x = plane_state->base.src.x1 >> 16;
+       int y = plane_state->base.src.y1 >> 16;
  
        dspcntr = DISPPLANE_GAMMA_ENABLE;
  
        if (IS_G4X(dev))
                dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
  
 -      linear_offset = y * fb->pitches[0] + x * cpp;
 +      intel_add_fb_offsets(&x, &y, plane_state, 0);
  
 -      if (INTEL_INFO(dev)->gen >= 4) {
 +      if (INTEL_INFO(dev)->gen >= 4)
                intel_crtc->dspaddr_offset =
 -                      intel_compute_tile_offset(&x, &y, fb, 0,
 -                                                fb->pitches[0], rotation);
 -              linear_offset -= intel_crtc->dspaddr_offset;
 -      } else {
 -              intel_crtc->dspaddr_offset = linear_offset;
 -      }
 +                      intel_compute_tile_offset(&x, &y, plane_state, 0);
  
-       if (rotation == BIT(DRM_ROTATE_180)) {
+       if (rotation == DRM_ROTATE_180) {
                dspcntr |= DISPPLANE_ROTATE_180;
  
                x += (crtc_state->pipe_src_w - 1);
@@@ -3148,8 -2747,9 +3148,8 @@@ static void ironlake_update_primary_pla
        u32 dspcntr;
        i915_reg_t reg = DSPCNTR(plane);
        unsigned int rotation = plane_state->base.rotation;
-       int x = plane_state->src.x1 >> 16;
-       int y = plane_state->src.y1 >> 16;
 -      int cpp = drm_format_plane_cpp(fb->pixel_format, 0);
+       int x = plane_state->base.src.x1 >> 16;
+       int y = plane_state->base.src.y1 >> 16;
  
        dspcntr = DISPPLANE_GAMMA_ENABLE;
        dspcntr |= DISPLAY_PLANE_ENABLE;
        if (!IS_HASWELL(dev) && !IS_BROADWELL(dev))
                dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
  
 -      linear_offset = y * fb->pitches[0] + x * cpp;
 +      intel_add_fb_offsets(&x, &y, plane_state, 0);
 +
        intel_crtc->dspaddr_offset =
 -              intel_compute_tile_offset(&x, &y, fb, 0,
 -                                        fb->pitches[0], rotation);
 -      linear_offset -= intel_crtc->dspaddr_offset;
 +              intel_compute_tile_offset(&x, &y, plane_state, 0);
 +
-       if (rotation == BIT(DRM_ROTATE_180)) {
+       if (rotation == DRM_ROTATE_180) {
                dspcntr |= DISPPLANE_ROTATE_180;
  
                if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) {
@@@ -3386,20 -2979,22 +3386,20 @@@ static void skylake_update_primary_plan
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
        struct drm_framebuffer *fb = plane_state->base.fb;
 -      struct drm_i915_gem_object *obj = intel_fb_obj(fb);
        int pipe = intel_crtc->pipe;
 -      u32 plane_ctl, stride_div, stride;
 -      u32 tile_height, plane_offset, plane_size;
 +      u32 plane_ctl;
        unsigned int rotation = plane_state->base.rotation;
 -      int x_offset, y_offset;
 -      u32 surf_addr;
 +      u32 stride = skl_plane_stride(fb, 0, rotation);
 +      u32 surf_addr = plane_state->main.offset;
        int scaler_id = plane_state->scaler_id;
 -      int src_x = plane_state->base.src.x1 >> 16;
 -      int src_y = plane_state->base.src.y1 >> 16;
 +      int src_x = plane_state->main.x;
 +      int src_y = plane_state->main.y;
-       int src_w = drm_rect_width(&plane_state->src) >> 16;
-       int src_h = drm_rect_height(&plane_state->src) >> 16;
-       int dst_x = plane_state->dst.x1;
-       int dst_y = plane_state->dst.y1;
-       int dst_w = drm_rect_width(&plane_state->dst);
-       int dst_h = drm_rect_height(&plane_state->dst);
+       int src_w = drm_rect_width(&plane_state->base.src) >> 16;
+       int src_h = drm_rect_height(&plane_state->base.src) >> 16;
+       int dst_x = plane_state->base.dst.x1;
+       int dst_y = plane_state->base.dst.y1;
+       int dst_w = drm_rect_width(&plane_state->base.dst);
+       int dst_h = drm_rect_height(&plane_state->base.dst);
  
        plane_ctl = PLANE_CTL_ENABLE |
                    PLANE_CTL_PIPE_GAMMA_ENABLE |
@@@ -3482,10 -3093,12 +3482,10 @@@ static void intel_update_primary_planes
  
        for_each_crtc(dev, crtc) {
                struct intel_plane *plane = to_intel_plane(crtc->primary);
 -              struct intel_plane_state *plane_state;
 -
 -              drm_modeset_lock_crtc(crtc, &plane->base);
 -              plane_state = to_intel_plane_state(plane->base.state);
 +              struct intel_plane_state *plane_state =
 +                      to_intel_plane_state(plane->base.state);
  
-               if (plane_state->visible)
+               if (plane_state->base.visible)
                        plane->update_plane(&plane->base,
                                            to_intel_crtc_state(crtc->state),
                                            plane_state);
@@@ -14568,9 -14106,7 +14559,8 @@@ intel_check_primary_plane(struct drm_pl
                          struct intel_crtc_state *crtc_state,
                          struct intel_plane_state *state)
  {
 +      struct drm_i915_private *dev_priv = to_i915(plane->dev);
        struct drm_crtc *crtc = state->base.crtc;
-       struct drm_framebuffer *fb = state->base.fb;
        int min_scale = DRM_PLANE_HELPER_NO_SCALING;
        int max_scale = DRM_PLANE_HELPER_NO_SCALING;
        bool can_position = false;
                can_position = true;
        }
  
-       ret = drm_plane_helper_check_update(plane, crtc, fb, &state->src,
-                                           &state->dst, &state->clip,
-                                           state->base.rotation,
 -      return drm_plane_helper_check_state(&state->base,
 -                                          &state->clip,
--                                          min_scale, max_scale,
-                                           can_position, true,
-                                           &state->visible);
 -                                          can_position, true);
++      ret = drm_plane_helper_check_state(&state->base,
++                                         &state->clip,
++                                         min_scale, max_scale,
++                                         can_position, true);
 +      if (ret)
 +              return ret;
 +
-       if (!fb)
++      if (!state->base.fb)
 +              return 0;
 +
 +      if (INTEL_GEN(dev_priv) >= 9) {
 +              ret = skl_check_plane_surface(state);
 +              if (ret)
 +                      return ret;
 +      }
 +
 +      return 0;
  }
  
  static void intel_begin_crtc_commit(struct drm_crtc *crtc,
index bb34d5470cba5207ca974cee5ea3b74c26904249,c29a429cbc45f4902ee23a4204587e7b355df701..9539f0e63fa5d3a33b8931b1eb423f3c1e909f4e
@@@ -348,20 -338,8 +348,17 @@@ struct intel_atomic_state 
  
  struct intel_plane_state {
        struct drm_plane_state base;
-       struct drm_rect src;
-       struct drm_rect dst;
        struct drm_rect clip;
-       bool visible;
  
 +      struct {
 +              u32 offset;
 +              int x, y;
 +      } main;
 +      struct {
 +              u32 offset;
 +              int x, y;
 +      } aux;
 +
        /*
         * scaler_id
         *    = -1 : not using a scaler
Simple merge
index c2e2c31dc9721ec82d87b810af9ba2c9f70f0508,cbdca7e4d3077d3884ef95d41346c5ec1e77d9db..366900dcde34595153fe9b00b9eb75b9b1bdce07
@@@ -203,21 -203,23 +203,21 @@@ skl_update_plane(struct drm_plane *drm_
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct intel_plane *intel_plane = to_intel_plane(drm_plane);
        struct drm_framebuffer *fb = plane_state->base.fb;
 -      struct drm_i915_gem_object *obj = intel_fb_obj(fb);
        const int pipe = intel_plane->pipe;
        const int plane = intel_plane->plane + 1;
 -      u32 plane_ctl, stride_div, stride;
 +      u32 plane_ctl;
        const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
 -      u32 surf_addr;
 -      u32 tile_height, plane_offset, plane_size;
 +      u32 surf_addr = plane_state->main.offset;
        unsigned int rotation = plane_state->base.rotation;
 -      int x_offset, y_offset;
 +      u32 stride = skl_plane_stride(fb, 0, rotation);
-       int crtc_x = plane_state->dst.x1;
-       int crtc_y = plane_state->dst.y1;
-       uint32_t crtc_w = drm_rect_width(&plane_state->dst);
-       uint32_t crtc_h = drm_rect_height(&plane_state->dst);
+       int crtc_x = plane_state->base.dst.x1;
+       int crtc_y = plane_state->base.dst.y1;
+       uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
+       uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
 -      uint32_t x = plane_state->base.src.x1 >> 16;
 -      uint32_t y = plane_state->base.src.y1 >> 16;
 +      uint32_t x = plane_state->main.x;
 +      uint32_t y = plane_state->main.y;
-       uint32_t src_w = drm_rect_width(&plane_state->src) >> 16;
-       uint32_t src_h = drm_rect_height(&plane_state->src) >> 16;
+       uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
+       uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
  
        plane_ctl = PLANE_CTL_ENABLE |
                PLANE_CTL_PIPE_GAMMA_ENABLE |
@@@ -345,15 -369,16 +345,15 @@@ vlv_update_plane(struct drm_plane *dpla
        u32 sprctl;
        u32 sprsurf_offset, linear_offset;
        unsigned int rotation = dplane->state->rotation;
 -      int cpp = drm_format_plane_cpp(fb->pixel_format, 0);
        const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
-       int crtc_x = plane_state->dst.x1;
-       int crtc_y = plane_state->dst.y1;
-       uint32_t crtc_w = drm_rect_width(&plane_state->dst);
-       uint32_t crtc_h = drm_rect_height(&plane_state->dst);
-       uint32_t x = plane_state->src.x1 >> 16;
-       uint32_t y = plane_state->src.y1 >> 16;
-       uint32_t src_w = drm_rect_width(&plane_state->src) >> 16;
-       uint32_t src_h = drm_rect_height(&plane_state->src) >> 16;
+       int crtc_x = plane_state->base.dst.x1;
+       int crtc_y = plane_state->base.dst.y1;
+       uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
+       uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
+       uint32_t x = plane_state->base.src.x1 >> 16;
+       uint32_t y = plane_state->base.src.y1 >> 16;
+       uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
+       uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
  
        sprctl = SP_ENABLE;
  
        crtc_w--;
        crtc_h--;
  
 -      linear_offset = y * fb->pitches[0] + x * cpp;
 -      sprsurf_offset = intel_compute_tile_offset(&x, &y, fb, 0,
 -                                                 fb->pitches[0], rotation);
 -      linear_offset -= sprsurf_offset;
 +      intel_add_fb_offsets(&x, &y, plane_state, 0);
 +      sprsurf_offset = intel_compute_tile_offset(&x, &y, plane_state, 0);
  
-       if (rotation == BIT(DRM_ROTATE_180)) {
+       if (rotation == DRM_ROTATE_180) {
                sprctl |= SP_ROTATE_180;
  
                x += src_w;
@@@ -484,15 -511,16 +484,15 @@@ ivb_update_plane(struct drm_plane *plan
        u32 sprctl, sprscale = 0;
        u32 sprsurf_offset, linear_offset;
        unsigned int rotation = plane_state->base.rotation;
 -      int cpp = drm_format_plane_cpp(fb->pixel_format, 0);
        const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
-       int crtc_x = plane_state->dst.x1;
-       int crtc_y = plane_state->dst.y1;
-       uint32_t crtc_w = drm_rect_width(&plane_state->dst);
-       uint32_t crtc_h = drm_rect_height(&plane_state->dst);
-       uint32_t x = plane_state->src.x1 >> 16;
-       uint32_t y = plane_state->src.y1 >> 16;
-       uint32_t src_w = drm_rect_width(&plane_state->src) >> 16;
-       uint32_t src_h = drm_rect_height(&plane_state->src) >> 16;
+       int crtc_x = plane_state->base.dst.x1;
+       int crtc_y = plane_state->base.dst.y1;
+       uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
+       uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
+       uint32_t x = plane_state->base.src.x1 >> 16;
+       uint32_t y = plane_state->base.src.y1 >> 16;
+       uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
+       uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
  
        sprctl = SPRITE_ENABLE;
  
        if (crtc_w != src_w || crtc_h != src_h)
                sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
  
 -      linear_offset = y * fb->pitches[0] + x * cpp;
 -      sprsurf_offset = intel_compute_tile_offset(&x, &y, fb, 0,
 -                                                 fb->pitches[0], rotation);
 -      linear_offset -= sprsurf_offset;
 +      intel_add_fb_offsets(&x, &y, plane_state, 0);
 +      sprsurf_offset = intel_compute_tile_offset(&x, &y, plane_state, 0);
  
-       if (rotation == BIT(DRM_ROTATE_180)) {
+       if (rotation == DRM_ROTATE_180) {
                sprctl |= SPRITE_ROTATE_180;
  
                /* HSW and BDW does this automagically in hardware */
@@@ -622,15 -652,16 +622,15 @@@ ilk_update_plane(struct drm_plane *plan
        u32 dvscntr, dvsscale;
        u32 dvssurf_offset, linear_offset;
        unsigned int rotation = plane_state->base.rotation;
 -      int cpp = drm_format_plane_cpp(fb->pixel_format, 0);
        const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
-       int crtc_x = plane_state->dst.x1;
-       int crtc_y = plane_state->dst.y1;
-       uint32_t crtc_w = drm_rect_width(&plane_state->dst);
-       uint32_t crtc_h = drm_rect_height(&plane_state->dst);
-       uint32_t x = plane_state->src.x1 >> 16;
-       uint32_t y = plane_state->src.y1 >> 16;
-       uint32_t src_w = drm_rect_width(&plane_state->src) >> 16;
-       uint32_t src_h = drm_rect_height(&plane_state->src) >> 16;
+       int crtc_x = plane_state->base.dst.x1;
+       int crtc_y = plane_state->base.dst.y1;
+       uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
+       uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
+       uint32_t x = plane_state->base.src.x1 >> 16;
+       uint32_t y = plane_state->base.src.y1 >> 16;
+       uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
+       uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
  
        dvscntr = DVS_ENABLE;
  
        if (crtc_w != src_w || crtc_h != src_h)
                dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h;
  
 -      linear_offset = y * fb->pitches[0] + x * cpp;
 -      dvssurf_offset = intel_compute_tile_offset(&x, &y, fb, 0,
 -                                                 fb->pitches[0], rotation);
 -      linear_offset -= dvssurf_offset;
 +      intel_add_fb_offsets(&x, &y, plane_state, 0);
 +      dvssurf_offset = intel_compute_tile_offset(&x, &y, plane_state, 0);
  
-       if (rotation == BIT(DRM_ROTATE_180)) {
+       if (rotation == DRM_ROTATE_180) {
                dvscntr |= DVS_ROTATE_180;
  
                x += src_w;
@@@ -753,10 -785,19 +753,20 @@@ intel_check_sprite_plane(struct drm_pla
        int hscale, vscale;
        int max_scale, min_scale;
        bool can_scale;
 +      int ret;
  
+       src->x1 = state->base.src_x;
+       src->y1 = state->base.src_y;
+       src->x2 = state->base.src_x + state->base.src_w;
+       src->y2 = state->base.src_y + state->base.src_h;
+       dst->x1 = state->base.crtc_x;
+       dst->y1 = state->base.crtc_y;
+       dst->x2 = state->base.crtc_x + state->base.crtc_w;
+       dst->y2 = state->base.crtc_y + state->base.crtc_h;
        if (!fb) {
-               state->visible = false;
+               state->base.visible = false;
                return 0;
        }