Merge tag 'drm-intel-next-2015-02-27' of git://anongit.freedesktop.org/drm-intel...
[cascardo/linux.git] / drivers / gpu / drm / i915 / intel_display.c
index 3d220a6..dbd8179 100644 (file)
@@ -390,7 +390,7 @@ static const intel_limit_t intel_limits_chv = {
         * them would make no difference.
         */
        .dot = { .min = 25000 * 5, .max = 540000 * 5},
-       .vco = { .min = 4860000, .max = 6700000 },
+       .vco = { .min = 4860000, .max = 6480000 },
        .n = { .min = 1, .max = 1 },
        .m1 = { .min = 2, .max = 2 },
        .m2 = { .min = 24 << 22, .max = 175 << 22 },
@@ -2190,11 +2190,50 @@ static bool need_vtd_wa(struct drm_device *dev)
 }
 
 int
-intel_fb_align_height(struct drm_device *dev, int height, unsigned int tiling)
+intel_fb_align_height(struct drm_device *dev, int height,
+                     uint32_t pixel_format,
+                     uint64_t fb_format_modifier)
 {
        int tile_height;
+       uint32_t bits_per_pixel;
+
+       switch (fb_format_modifier) {
+       case DRM_FORMAT_MOD_NONE:
+               tile_height = 1;
+               break;
+       case I915_FORMAT_MOD_X_TILED:
+               tile_height = IS_GEN2(dev) ? 16 : 8;
+               break;
+       case I915_FORMAT_MOD_Y_TILED:
+               tile_height = 32;
+               break;
+       case I915_FORMAT_MOD_Yf_TILED:
+               bits_per_pixel = drm_format_plane_cpp(pixel_format, 0) * 8;
+               switch (bits_per_pixel) {
+               default:
+               case 8:
+                       tile_height = 64;
+                       break;
+               case 16:
+               case 32:
+                       tile_height = 32;
+                       break;
+               case 64:
+                       tile_height = 16;
+                       break;
+               case 128:
+                       WARN_ONCE(1,
+                                 "128-bit pixels are not supported for display!");
+                       tile_height = 16;
+                       break;
+               }
+               break;
+       default:
+               MISSING_CASE(fb_format_modifier);
+               tile_height = 1;
+               break;
+       }
 
-       tile_height = tiling ? (IS_GEN2(dev) ? 16 : 8) : 1;
        return ALIGN(height, tile_height);
 }
 
@@ -2211,8 +2250,8 @@ intel_pin_and_fence_fb_obj(struct drm_plane *plane,
 
        WARN_ON(!mutex_is_locked(&dev->struct_mutex));
 
-       switch (obj->tiling_mode) {
-       case I915_TILING_NONE:
+       switch (fb->modifier[0]) {
+       case DRM_FORMAT_MOD_NONE:
                if (INTEL_INFO(dev)->gen >= 9)
                        alignment = 256 * 1024;
                else if (IS_BROADWATER(dev) || IS_CRESTLINE(dev))
@@ -2222,7 +2261,7 @@ intel_pin_and_fence_fb_obj(struct drm_plane *plane,
                else
                        alignment = 64 * 1024;
                break;
-       case I915_TILING_X:
+       case I915_FORMAT_MOD_X_TILED:
                if (INTEL_INFO(dev)->gen >= 9)
                        alignment = 256 * 1024;
                else {
@@ -2230,11 +2269,16 @@ intel_pin_and_fence_fb_obj(struct drm_plane *plane,
                        alignment = 0;
                }
                break;
-       case I915_TILING_Y:
-               WARN(1, "Y tiled bo slipped through, driver bug!\n");
-               return -EINVAL;
+       case I915_FORMAT_MOD_Y_TILED:
+       case I915_FORMAT_MOD_Yf_TILED:
+               if (WARN_ONCE(INTEL_INFO(dev)->gen < 9,
+                         "Y tiling bo slipped through, driver bug!\n"))
+                       return -EINVAL;
+               alignment = 1 * 1024 * 1024;
+               break;
        default:
-               BUG();
+               MISSING_CASE(fb->modifier[0]);
+               return -EINVAL;
        }
 
        /* Note that the w/a also requires 64 PTE of padding following the
@@ -2282,7 +2326,7 @@ err_interruptible:
        return ret;
 }
 
-void intel_unpin_fb_obj(struct drm_i915_gem_object *obj)
+static void intel_unpin_fb_obj(struct drm_i915_gem_object *obj)
 {
        WARN_ON(!mutex_is_locked(&obj->base.dev->struct_mutex));
 
@@ -2371,6 +2415,7 @@ intel_alloc_plane_obj(struct intel_crtc *crtc,
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_gem_object *obj = NULL;
        struct drm_mode_fb_cmd2 mode_cmd = { 0 };
+       struct drm_framebuffer *fb = &plane_config->fb->base;
        u32 base = plane_config->base;
 
        if (plane_config->size == 0)
@@ -2383,16 +2428,18 @@ intel_alloc_plane_obj(struct intel_crtc *crtc,
 
        obj->tiling_mode = plane_config->tiling;
        if (obj->tiling_mode == I915_TILING_X)
-               obj->stride = crtc->base.primary->fb->pitches[0];
+               obj->stride = fb->pitches[0];
 
-       mode_cmd.pixel_format = crtc->base.primary->fb->pixel_format;
-       mode_cmd.width = crtc->base.primary->fb->width;
-       mode_cmd.height = crtc->base.primary->fb->height;
-       mode_cmd.pitches[0] = crtc->base.primary->fb->pitches[0];
+       mode_cmd.pixel_format = fb->pixel_format;
+       mode_cmd.width = fb->width;
+       mode_cmd.height = fb->height;
+       mode_cmd.pitches[0] = fb->pitches[0];
+       mode_cmd.modifier[0] = fb->modifier[0];
+       mode_cmd.flags = DRM_MODE_FB_MODIFIERS;
 
        mutex_lock(&dev->struct_mutex);
 
-       if (intel_framebuffer_init(dev, to_intel_framebuffer(crtc->base.primary->fb),
+       if (intel_framebuffer_init(dev, to_intel_framebuffer(fb),
                                   &mode_cmd, obj)) {
                DRM_DEBUG_KMS("intel fb init failed\n");
                goto out_unref_obj;
@@ -2410,6 +2457,20 @@ out_unref_obj:
        return false;
 }
 
+/* Update plane->state->fb to match plane->fb after driver-internal updates */
+static void
+update_state_fb(struct drm_plane *plane)
+{
+       if (plane->fb == plane->state->fb)
+               return;
+
+       if (plane->state->fb)
+               drm_framebuffer_unreference(plane->state->fb);
+       plane->state->fb = plane->fb;
+       if (plane->state->fb)
+               drm_framebuffer_reference(plane->state->fb);
+}
+
 static void
 intel_find_plane_obj(struct intel_crtc *intel_crtc,
                     struct intel_initial_plane_config *plane_config)
@@ -2420,14 +2481,20 @@ intel_find_plane_obj(struct intel_crtc *intel_crtc,
        struct intel_crtc *i;
        struct drm_i915_gem_object *obj;
 
-       if (!intel_crtc->base.primary->fb)
+       if (!plane_config->fb)
                return;
 
-       if (intel_alloc_plane_obj(intel_crtc, plane_config))
+       if (intel_alloc_plane_obj(intel_crtc, plane_config)) {
+               struct drm_plane *primary = intel_crtc->base.primary;
+
+               primary->fb = &plane_config->fb->base;
+               primary->state->crtc = &intel_crtc->base;
+               update_state_fb(primary);
+
                return;
+       }
 
-       kfree(intel_crtc->base.primary->fb);
-       intel_crtc->base.primary->fb = NULL;
+       kfree(plane_config->fb);
 
        /*
         * Failed to alloc the obj, check to see if we should share
@@ -2447,15 +2514,20 @@ intel_find_plane_obj(struct intel_crtc *intel_crtc,
                        continue;
 
                if (i915_gem_obj_ggtt_offset(obj) == plane_config->base) {
+                       struct drm_plane *primary = intel_crtc->base.primary;
+
                        if (obj->tiling_mode != I915_TILING_NONE)
                                dev_priv->preserve_bios_swizzle = true;
 
                        drm_framebuffer_reference(c->primary->fb);
-                       intel_crtc->base.primary->fb = c->primary->fb;
+                       primary->fb = c->primary->fb;
+                       primary->state->crtc = &intel_crtc->base;
+                       update_state_fb(intel_crtc->base.primary);
                        obj->frontbuffer_bits |= INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe);
                        break;
                }
        }
+
 }
 
 static void i9xx_update_primary_plane(struct drm_crtc *crtc,
@@ -2695,6 +2767,40 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
        POSTING_READ(reg);
 }
 
+u32 intel_fb_stride_alignment(struct drm_device *dev, uint64_t fb_modifier,
+                             uint32_t pixel_format)
+{
+       u32 bits_per_pixel = drm_format_plane_cpp(pixel_format, 0) * 8;
+
+       /*
+        * The stride is either expressed as a multiple of 64 bytes
+        * chunks for linear buffers or in number of tiles for tiled
+        * buffers.
+        */
+       switch (fb_modifier) {
+       case DRM_FORMAT_MOD_NONE:
+               return 64;
+       case I915_FORMAT_MOD_X_TILED:
+               if (INTEL_INFO(dev)->gen == 2)
+                       return 128;
+               return 512;
+       case I915_FORMAT_MOD_Y_TILED:
+               /* No need to check for old gens and Y tiling since this is
+                * about the display engine and those will be blocked before
+                * we get here.
+                */
+               return 128;
+       case I915_FORMAT_MOD_Yf_TILED:
+               if (bits_per_pixel == 8)
+                       return 64;
+               else
+                       return 128;
+       default:
+               MISSING_CASE(fb_modifier);
+               return 64;
+       }
+}
+
 static void skylake_update_primary_plane(struct drm_crtc *crtc,
                                         struct drm_framebuffer *fb,
                                         int x, int y)
@@ -2702,10 +2808,9 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc,
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       struct intel_framebuffer *intel_fb;
        struct drm_i915_gem_object *obj;
        int pipe = intel_crtc->pipe;
-       u32 plane_ctl, stride;
+       u32 plane_ctl, stride_div;
 
        if (!intel_crtc->primary_enabled) {
                I915_WRITE(PLANE_CTL(pipe, 0), 0);
@@ -2740,29 +2845,30 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc,
                BUG();
        }
 
-       intel_fb = to_intel_framebuffer(fb);
-       obj = intel_fb->obj;
-
-       /*
-        * The stride is either expressed as a multiple of 64 bytes chunks for
-        * linear buffers or in number of tiles for tiled buffers.
-        */
-       switch (obj->tiling_mode) {
-       case I915_TILING_NONE:
-               stride = fb->pitches[0] >> 6;
+       switch (fb->modifier[0]) {
+       case DRM_FORMAT_MOD_NONE:
                break;
-       case I915_TILING_X:
+       case I915_FORMAT_MOD_X_TILED:
                plane_ctl |= PLANE_CTL_TILED_X;
-               stride = fb->pitches[0] >> 9;
+               break;
+       case I915_FORMAT_MOD_Y_TILED:
+               plane_ctl |= PLANE_CTL_TILED_Y;
+               break;
+       case I915_FORMAT_MOD_Yf_TILED:
+               plane_ctl |= PLANE_CTL_TILED_YF;
                break;
        default:
-               BUG();
+               MISSING_CASE(fb->modifier[0]);
        }
 
        plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
        if (crtc->primary->state->rotation == BIT(DRM_ROTATE_180))
                plane_ctl |= PLANE_CTL_ROTATE_180;
 
+       obj = intel_fb_obj(fb);
+       stride_div = intel_fb_stride_alignment(dev, fb->modifier[0],
+                                              fb->pixel_format);
+
        I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
 
        DRM_DEBUG_KMS("Writing base %08lX %d,%d,%d,%d pitch=%d\n",
@@ -2775,7 +2881,7 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc,
        I915_WRITE(PLANE_SIZE(pipe, 0),
                   (intel_crtc->config->pipe_src_h - 1) << 16 |
                   (intel_crtc->config->pipe_src_w - 1));
-       I915_WRITE(PLANE_STRIDE(pipe, 0), stride);
+       I915_WRITE(PLANE_STRIDE(pipe, 0), fb->pitches[0] / stride_div);
        I915_WRITE(PLANE_SURF(pipe, 0), i915_gem_obj_ggtt_offset(obj));
 
        POSTING_READ(PLANE_SURF(pipe, 0));
@@ -3029,7 +3135,7 @@ static void intel_fdi_normal_train(struct drm_crtc *crtc)
 
 static bool pipe_has_enabled_pch(struct intel_crtc *crtc)
 {
-       return crtc->base.enabled && crtc->active &&
+       return crtc->base.state->enable && crtc->active &&
                crtc->config->has_pch_encoder;
 }
 
@@ -4167,7 +4273,7 @@ static void intel_crtc_load_lut(struct drm_crtc *crtc)
        bool reenable_ips = false;
 
        /* The clocks have to be on to load the palette. */
-       if (!crtc->enabled || !intel_crtc->active)
+       if (!crtc->state->enable || !intel_crtc->active)
                return;
 
        if (!HAS_PCH_SPLIT(dev_priv->dev)) {
@@ -4251,11 +4357,10 @@ static void intel_crtc_disable_planes(struct drm_crtc *crtc)
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        int pipe = intel_crtc->pipe;
-       int plane = intel_crtc->plane;
 
        intel_crtc_wait_for_pending_flips(crtc);
 
-       if (dev_priv->fbc.plane == plane)
+       if (dev_priv->fbc.crtc == intel_crtc)
                intel_fbc_disable(dev);
 
        hsw_disable_ips(intel_crtc);
@@ -4281,7 +4386,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
        struct intel_encoder *encoder;
        int pipe = intel_crtc->pipe;
 
-       WARN_ON(!crtc->enabled);
+       WARN_ON(!crtc->state->enable);
 
        if (intel_crtc->active)
                return;
@@ -4290,7 +4395,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
                intel_prepare_shared_dpll(intel_crtc);
 
        if (intel_crtc->config->has_dp_encoder)
-               intel_dp_set_m_n(intel_crtc);
+               intel_dp_set_m_n(intel_crtc, M1_N1);
 
        intel_set_pipe_timings(intel_crtc);
 
@@ -4389,7 +4494,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
        struct intel_encoder *encoder;
        int pipe = intel_crtc->pipe;
 
-       WARN_ON(!crtc->enabled);
+       WARN_ON(!crtc->state->enable);
 
        if (intel_crtc->active)
                return;
@@ -4398,7 +4503,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
                intel_enable_shared_dpll(intel_crtc);
 
        if (intel_crtc->config->has_dp_encoder)
-               intel_dp_set_m_n(intel_crtc);
+               intel_dp_set_m_n(intel_crtc, M1_N1);
 
        intel_set_pipe_timings(intel_crtc);
 
@@ -4736,7 +4841,7 @@ static void modeset_update_crtc_power_domains(struct drm_device *dev)
        for_each_intel_crtc(dev, crtc) {
                enum intel_display_power_domain domain;
 
-               if (!crtc->base.enabled)
+               if (!crtc->base.state->enable)
                        continue;
 
                pipe_domains[crtc->pipe] = get_crtc_power_domains(&crtc->base);
@@ -4957,7 +5062,7 @@ static void valleyview_modeset_global_pipes(struct drm_device *dev,
 
        /* disable/enable all currently active pipes while we change cdclk */
        for_each_intel_crtc(dev, intel_crtc)
-               if (intel_crtc->base.enabled)
+               if (intel_crtc->base.state->enable)
                        *prepare_pipes |= (1 << intel_crtc->pipe);
 }
 
@@ -4997,7 +5102,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
        int pipe = intel_crtc->pipe;
        bool is_dsi;
 
-       WARN_ON(!crtc->enabled);
+       WARN_ON(!crtc->state->enable);
 
        if (intel_crtc->active)
                return;
@@ -5012,7 +5117,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
        }
 
        if (intel_crtc->config->has_dp_encoder)
-               intel_dp_set_m_n(intel_crtc);
+               intel_dp_set_m_n(intel_crtc, M1_N1);
 
        intel_set_pipe_timings(intel_crtc);
 
@@ -5080,7 +5185,7 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
        struct intel_encoder *encoder;
        int pipe = intel_crtc->pipe;
 
-       WARN_ON(!crtc->enabled);
+       WARN_ON(!crtc->state->enable);
 
        if (intel_crtc->active)
                return;
@@ -5088,7 +5193,7 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
        i9xx_set_pll_dividers(intel_crtc);
 
        if (intel_crtc->config->has_dp_encoder)
-               intel_dp_set_m_n(intel_crtc);
+               intel_dp_set_m_n(intel_crtc, M1_N1);
 
        intel_set_pipe_timings(intel_crtc);
 
@@ -5279,7 +5384,7 @@ static void intel_crtc_disable(struct drm_crtc *crtc)
        struct drm_i915_private *dev_priv = dev->dev_private;
 
        /* crtc should still be enabled when we disable it. */
-       WARN_ON(!crtc->enabled);
+       WARN_ON(!crtc->state->enable);
 
        dev_priv->display.crtc_disable(crtc);
        dev_priv->display.off(crtc);
@@ -5357,7 +5462,8 @@ static void intel_connector_check_state(struct intel_connector *connector)
 
                        crtc = encoder->base.crtc;
 
-                       I915_STATE_WARN(!crtc->enabled, "crtc not enabled\n");
+                       I915_STATE_WARN(!crtc->state->enable,
+                                       "crtc not enabled\n");
                        I915_STATE_WARN(!to_intel_crtc(crtc)->active, "crtc not active\n");
                        I915_STATE_WARN(pipe != to_intel_crtc(crtc)->pipe,
                             "encoder active on the wrong pipe\n");
@@ -5544,7 +5650,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
         * - LVDS dual channel mode
         * - Double wide pipe
         */
-       if ((intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
+       if ((intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS) &&
             intel_is_dual_link_lvds(dev)) || pipe_config->double_wide)
                pipe_config->pipe_src_w &= ~1;
 
@@ -5847,7 +5953,7 @@ static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc,
                 * for gen < 8) and if DRRS is supported (to make sure the
                 * registers are not unnecessarily accessed).
                 */
-               if (m2_n2 && INTEL_INFO(dev)->gen < 8 &&
+               if (m2_n2 && (IS_CHERRYVIEW(dev) || INTEL_INFO(dev)->gen < 8) &&
                        crtc->config->has_drrs) {
                        I915_WRITE(PIPE_DATA_M2(transcoder),
                                        TU_SIZE(m2_n2->tu) | m2_n2->gmch_m);
@@ -5863,13 +5969,29 @@ static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc,
        }
 }
 
-void intel_dp_set_m_n(struct intel_crtc *crtc)
+void intel_dp_set_m_n(struct intel_crtc *crtc, enum link_m_n_set m_n)
 {
+       struct intel_link_m_n *dp_m_n, *dp_m2_n2 = NULL;
+
+       if (m_n == M1_N1) {
+               dp_m_n = &crtc->config->dp_m_n;
+               dp_m2_n2 = &crtc->config->dp_m2_n2;
+       } else if (m_n == M2_N2) {
+
+               /*
+                * M2_N2 registers are not supported. Hence m2_n2 divider value
+                * needs to be programmed into M1_N1.
+                */
+               dp_m_n = &crtc->config->dp_m2_n2;
+       } else {
+               DRM_ERROR("Unsupported divider value\n");
+               return;
+       }
+
        if (crtc->config->has_pch_encoder)
                intel_pch_transcoder_set_m_n(crtc, &crtc->config->dp_m_n);
        else
-               intel_cpu_transcoder_set_m_n(crtc, &crtc->config->dp_m_n,
-                                                  &crtc->config->dp_m2_n2);
+               intel_cpu_transcoder_set_m_n(crtc, dp_m_n, dp_m2_n2);
 }
 
 static void vlv_update_pll(struct intel_crtc *crtc,
@@ -6587,6 +6709,10 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
        struct drm_framebuffer *fb;
        struct intel_framebuffer *intel_fb;
 
+       val = I915_READ(DSPCNTR(plane));
+       if (!(val & DISPLAY_PLANE_ENABLE))
+               return;
+
        intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
        if (!intel_fb) {
                DRM_DEBUG_KMS("failed to alloc fb\n");
@@ -6595,11 +6721,12 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
 
        fb = &intel_fb->base;
 
-       val = I915_READ(DSPCNTR(plane));
-
-       if (INTEL_INFO(dev)->gen >= 4)
-               if (val & DISPPLANE_TILED)
+       if (INTEL_INFO(dev)->gen >= 4) {
+               if (val & DISPPLANE_TILED) {
                        plane_config->tiling = I915_TILING_X;
+                       fb->modifier[0] = I915_FORMAT_MOD_X_TILED;
+               }
+       }
 
        pixel_format = val & DISPPLANE_PIXFORMAT_MASK;
        fourcc = i9xx_format_to_fourcc(pixel_format);
@@ -6625,7 +6752,8 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
        fb->pitches[0] = val & 0xffffffc0;
 
        aligned_height = intel_fb_align_height(dev, fb->height,
-                                              plane_config->tiling);
+                                              fb->pixel_format,
+                                              fb->modifier[0]);
 
        plane_config->size = PAGE_ALIGN(fb->pitches[0] * aligned_height);
 
@@ -6634,7 +6762,7 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
                      fb->bits_per_pixel, base, fb->pitches[0],
                      plane_config->size);
 
-       crtc->base.primary->fb = fb;
+       plane_config->fb = intel_fb;
 }
 
 static void chv_crtc_clock_get(struct intel_crtc *crtc,
@@ -7612,7 +7740,7 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
 {
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       u32 val, base, offset, stride_mult;
+       u32 val, base, offset, stride_mult, tiling;
        int pipe = crtc->pipe;
        int fourcc, pixel_format;
        int aligned_height;
@@ -7628,8 +7756,8 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
        fb = &intel_fb->base;
 
        val = I915_READ(PLANE_CTL(pipe, 0));
-       if (val & PLANE_CTL_TILED_MASK)
-               plane_config->tiling = I915_TILING_X;
+       if (!(val & PLANE_CTL_ENABLE))
+               goto error;
 
        pixel_format = val & PLANE_CTL_FORMAT_MASK;
        fourcc = skl_format_to_fourcc(pixel_format,
@@ -7638,6 +7766,26 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
        fb->pixel_format = fourcc;
        fb->bits_per_pixel = drm_format_plane_cpp(fourcc, 0) * 8;
 
+       tiling = val & PLANE_CTL_TILED_MASK;
+       switch (tiling) {
+       case PLANE_CTL_TILED_LINEAR:
+               fb->modifier[0] = DRM_FORMAT_MOD_NONE;
+               break;
+       case PLANE_CTL_TILED_X:
+               plane_config->tiling = I915_TILING_X;
+               fb->modifier[0] = I915_FORMAT_MOD_X_TILED;
+               break;
+       case PLANE_CTL_TILED_Y:
+               fb->modifier[0] = I915_FORMAT_MOD_Y_TILED;
+               break;
+       case PLANE_CTL_TILED_YF:
+               fb->modifier[0] = I915_FORMAT_MOD_Yf_TILED;
+               break;
+       default:
+               MISSING_CASE(tiling);
+               goto error;
+       }
+
        base = I915_READ(PLANE_SURF(pipe, 0)) & 0xfffff000;
        plane_config->base = base;
 
@@ -7648,21 +7796,13 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
        fb->width = ((val >> 0) & 0x1fff) + 1;
 
        val = I915_READ(PLANE_STRIDE(pipe, 0));
-       switch (plane_config->tiling) {
-       case I915_TILING_NONE:
-               stride_mult = 64;
-               break;
-       case I915_TILING_X:
-               stride_mult = 512;
-               break;
-       default:
-               MISSING_CASE(plane_config->tiling);
-               goto error;
-       }
+       stride_mult = intel_fb_stride_alignment(dev, fb->modifier[0],
+                                               fb->pixel_format);
        fb->pitches[0] = (val & 0x3ff) * stride_mult;
 
        aligned_height = intel_fb_align_height(dev, fb->height,
-                                              plane_config->tiling);
+                                              fb->pixel_format,
+                                              fb->modifier[0]);
 
        plane_config->size = ALIGN(fb->pitches[0] * aligned_height, PAGE_SIZE);
 
@@ -7671,7 +7811,7 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
                      fb->bits_per_pixel, base, fb->pitches[0],
                      plane_config->size);
 
-       crtc->base.primary->fb = fb;
+       plane_config->fb = intel_fb;
        return;
 
 error:
@@ -7715,6 +7855,10 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc,
        struct drm_framebuffer *fb;
        struct intel_framebuffer *intel_fb;
 
+       val = I915_READ(DSPCNTR(pipe));
+       if (!(val & DISPLAY_PLANE_ENABLE))
+               return;
+
        intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
        if (!intel_fb) {
                DRM_DEBUG_KMS("failed to alloc fb\n");
@@ -7723,11 +7867,12 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc,
 
        fb = &intel_fb->base;
 
-       val = I915_READ(DSPCNTR(pipe));
-
-       if (INTEL_INFO(dev)->gen >= 4)
-               if (val & DISPPLANE_TILED)
+       if (INTEL_INFO(dev)->gen >= 4) {
+               if (val & DISPPLANE_TILED) {
                        plane_config->tiling = I915_TILING_X;
+                       fb->modifier[0] = I915_FORMAT_MOD_X_TILED;
+               }
+       }
 
        pixel_format = val & DISPPLANE_PIXFORMAT_MASK;
        fourcc = i9xx_format_to_fourcc(pixel_format);
@@ -7753,7 +7898,8 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc,
        fb->pitches[0] = val & 0xffffffc0;
 
        aligned_height = intel_fb_align_height(dev, fb->height,
-                                              plane_config->tiling);
+                                              fb->pixel_format,
+                                              fb->modifier[0]);
 
        plane_config->size = PAGE_ALIGN(fb->pitches[0] * aligned_height);
 
@@ -7762,7 +7908,7 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc,
                      fb->bits_per_pixel, base, fb->pitches[0],
                      plane_config->size);
 
-       crtc->base.primary->fb = fb;
+       plane_config->fb = intel_fb;
 }
 
 static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
@@ -8636,7 +8782,7 @@ retry:
                i++;
                if (!(encoder->possible_crtcs & (1 << i)))
                        continue;
-               if (possible_crtc->enabled)
+               if (possible_crtc->state->enable)
                        continue;
                /* This can occur when applying the pipe A quirk on resume. */
                if (to_intel_crtc(possible_crtc)->new_enabled)
@@ -8704,7 +8850,7 @@ retry:
        return true;
 
  fail:
-       intel_crtc->new_enabled = crtc->enabled;
+       intel_crtc->new_enabled = crtc->state->enable;
        if (intel_crtc->new_enabled)
                intel_crtc->new_config = intel_crtc->config;
        else
@@ -9055,9 +9201,9 @@ static void intel_unpin_work_fn(struct work_struct *__work)
        enum pipe pipe = to_intel_crtc(work->crtc)->pipe;
 
        mutex_lock(&dev->struct_mutex);
-       intel_unpin_fb_obj(work->old_fb_obj);
+       intel_unpin_fb_obj(intel_fb_obj(work->old_fb));
        drm_gem_object_unreference(&work->pending_flip_obj->base);
-       drm_gem_object_unreference(&work->old_fb_obj->base);
+       drm_framebuffer_unreference(work->old_fb);
 
        intel_fbc_update(dev);
 
@@ -9582,69 +9728,6 @@ static int intel_queue_mmio_flip(struct drm_device *dev,
        return 0;
 }
 
-static int intel_gen9_queue_flip(struct drm_device *dev,
-                                struct drm_crtc *crtc,
-                                struct drm_framebuffer *fb,
-                                struct drm_i915_gem_object *obj,
-                                struct intel_engine_cs *ring,
-                                uint32_t flags)
-{
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       uint32_t plane = 0, stride;
-       int ret;
-
-       switch(intel_crtc->pipe) {
-       case PIPE_A:
-               plane = MI_DISPLAY_FLIP_SKL_PLANE_1_A;
-               break;
-       case PIPE_B:
-               plane = MI_DISPLAY_FLIP_SKL_PLANE_1_B;
-               break;
-       case PIPE_C:
-               plane = MI_DISPLAY_FLIP_SKL_PLANE_1_C;
-               break;
-       default:
-               WARN_ONCE(1, "unknown plane in flip command\n");
-               return -ENODEV;
-       }
-
-       switch (obj->tiling_mode) {
-       case I915_TILING_NONE:
-               stride = fb->pitches[0] >> 6;
-               break;
-       case I915_TILING_X:
-               stride = fb->pitches[0] >> 9;
-               break;
-       default:
-               WARN_ONCE(1, "unknown tiling in flip command\n");
-               return -ENODEV;
-       }
-
-       ret = intel_ring_begin(ring, 10);
-       if (ret)
-               return ret;
-
-       intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
-       intel_ring_emit(ring, DERRMR);
-       intel_ring_emit(ring, ~(DERRMR_PIPEA_PRI_FLIP_DONE |
-                               DERRMR_PIPEB_PRI_FLIP_DONE |
-                               DERRMR_PIPEC_PRI_FLIP_DONE));
-       intel_ring_emit(ring, MI_STORE_REGISTER_MEM_GEN8(1) |
-                             MI_SRM_LRM_GLOBAL_GTT);
-       intel_ring_emit(ring, DERRMR);
-       intel_ring_emit(ring, ring->scratch.gtt_offset + 256);
-       intel_ring_emit(ring, 0);
-
-       intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane);
-       intel_ring_emit(ring, stride << 6 | obj->tiling_mode);
-       intel_ring_emit(ring, intel_crtc->unpin_work->gtt_offset);
-
-       intel_mark_page_flip_active(intel_crtc);
-       __intel_ring_advance(ring);
-
-       return 0;
-}
-
 static int intel_default_queue_flip(struct drm_device *dev,
                                    struct drm_crtc *crtc,
                                    struct drm_framebuffer *fb,
@@ -9674,10 +9757,10 @@ static bool __intel_pageflip_stall_check(struct drm_device *dev,
                    !i915_gem_request_completed(work->flip_queued_req, true))
                        return false;
 
-               work->flip_ready_vblank = drm_vblank_count(dev, intel_crtc->pipe);
+               work->flip_ready_vblank = drm_crtc_vblank_count(crtc);
        }
 
-       if (drm_vblank_count(dev, intel_crtc->pipe) - work->flip_ready_vblank < 3)
+       if (drm_crtc_vblank_count(crtc) - work->flip_ready_vblank < 3)
                return false;
 
        /* Potential stall - if we see that the flip has happened,
@@ -9708,7 +9791,8 @@ void intel_check_page_flip(struct drm_device *dev, int pipe)
        spin_lock(&dev->event_lock);
        if (intel_crtc->unpin_work && __intel_pageflip_stall_check(dev, crtc)) {
                WARN_ONCE(1, "Kicking stuck page flip: queued at %d, now %d\n",
-                        intel_crtc->unpin_work->flip_queued_vblank, drm_vblank_count(dev, pipe));
+                        intel_crtc->unpin_work->flip_queued_vblank,
+                        drm_vblank_count(dev, pipe));
                page_flip_completed(intel_crtc);
        }
        spin_unlock(&dev->event_lock);
@@ -9760,7 +9844,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 
        work->event = event;
        work->crtc = crtc;
-       work->old_fb_obj = intel_fb_obj(old_fb);
+       work->old_fb = old_fb;
        INIT_WORK(&work->work, intel_unpin_work_fn);
 
        ret = drm_crtc_vblank_get(crtc);
@@ -9796,10 +9880,11 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
                goto cleanup;
 
        /* Reference the objects for the scheduled work. */
-       drm_gem_object_reference(&work->old_fb_obj->base);
+       drm_framebuffer_reference(work->old_fb);
        drm_gem_object_reference(&obj->base);
 
        crtc->primary->fb = fb;
+       update_state_fb(crtc->primary);
 
        work->pending_flip_obj = obj;
 
@@ -9811,7 +9896,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 
        if (IS_VALLEYVIEW(dev)) {
                ring = &dev_priv->ring[BCS];
-               if (obj->tiling_mode != work->old_fb_obj->tiling_mode)
+               if (obj->tiling_mode != intel_fb_obj(work->old_fb)->tiling_mode)
                        /* vlv: DISPLAY_FLIP fails to change tiling */
                        ring = NULL;
        } else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) {
@@ -9849,10 +9934,10 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
                                        intel_ring_get_request(ring));
        }
 
-       work->flip_queued_vblank = drm_vblank_count(dev, intel_crtc->pipe);
+       work->flip_queued_vblank = drm_crtc_vblank_count(crtc);
        work->enable_stall_check = true;
 
-       i915_gem_track_fb(work->old_fb_obj, obj,
+       i915_gem_track_fb(intel_fb_obj(work->old_fb), obj,
                          INTEL_FRONTBUFFER_PRIMARY(pipe));
 
        intel_fbc_disable(dev);
@@ -9868,7 +9953,8 @@ cleanup_unpin:
 cleanup_pending:
        atomic_dec(&intel_crtc->unpin_work_count);
        crtc->primary->fb = old_fb;
-       drm_gem_object_unreference(&work->old_fb_obj->base);
+       update_state_fb(crtc->primary);
+       drm_framebuffer_unreference(work->old_fb);
        drm_gem_object_unreference(&obj->base);
        mutex_unlock(&dev->struct_mutex);
 
@@ -9924,7 +10010,7 @@ static void intel_modeset_update_staged_output_state(struct drm_device *dev)
        }
 
        for_each_intel_crtc(dev, crtc) {
-               crtc->new_enabled = crtc->base.enabled;
+               crtc->new_enabled = crtc->base.state->enable;
 
                if (crtc->new_enabled)
                        crtc->new_config = crtc->config;
@@ -9954,6 +10040,7 @@ static void intel_modeset_commit_output_state(struct drm_device *dev)
        }
 
        for_each_intel_crtc(dev, crtc) {
+               crtc->base.state->enable = crtc->new_enabled;
                crtc->base.enabled = crtc->new_enabled;
        }
 }
@@ -10217,6 +10304,7 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
        if (!pipe_config)
                return ERR_PTR(-ENOMEM);
 
+       pipe_config->base.crtc = crtc;
        drm_mode_copy(&pipe_config->base.adjusted_mode, mode);
        drm_mode_copy(&pipe_config->base.mode, mode);
 
@@ -10365,7 +10453,7 @@ intel_modeset_affected_pipes(struct drm_crtc *crtc, unsigned *modeset_pipes,
 
        /* Check for pipes that will be enabled/disabled ... */
        for_each_intel_crtc(dev, intel_crtc) {
-               if (intel_crtc->base.enabled == intel_crtc->new_enabled)
+               if (intel_crtc->base.state->enable == intel_crtc->new_enabled)
                        continue;
 
                if (!intel_crtc->new_enabled)
@@ -10440,10 +10528,10 @@ intel_modeset_update_state(struct drm_device *dev, unsigned prepare_pipes)
 
        /* Double check state. */
        for_each_intel_crtc(dev, intel_crtc) {
-               WARN_ON(intel_crtc->base.enabled != intel_crtc_in_use(&intel_crtc->base));
+               WARN_ON(intel_crtc->base.state->enable != intel_crtc_in_use(&intel_crtc->base));
                WARN_ON(intel_crtc->new_config &&
                        intel_crtc->new_config != intel_crtc->config);
-               WARN_ON(intel_crtc->base.enabled != !!intel_crtc->new_config);
+               WARN_ON(intel_crtc->base.state->enable != !!intel_crtc->new_config);
        }
 
        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
@@ -10830,7 +10918,7 @@ check_crtc_state(struct drm_device *dev)
                DRM_DEBUG_KMS("[CRTC:%d]\n",
                              crtc->base.base.id);
 
-               I915_STATE_WARN(crtc->active && !crtc->base.enabled,
+               I915_STATE_WARN(crtc->active && !crtc->base.state->enable,
                     "active crtc, but not enabled in sw tracking\n");
 
                for_each_intel_encoder(dev, encoder) {
@@ -10844,9 +10932,10 @@ check_crtc_state(struct drm_device *dev)
                I915_STATE_WARN(active != crtc->active,
                     "crtc's computed active state doesn't match tracked active state "
                     "(expected %i, found %i)\n", active, crtc->active);
-               I915_STATE_WARN(enabled != crtc->base.enabled,
+               I915_STATE_WARN(enabled != crtc->base.state->enable,
                     "crtc's computed enabled state doesn't match tracked enabled state "
-                    "(expected %i, found %i)\n", enabled, crtc->base.enabled);
+                    "(expected %i, found %i)\n", enabled,
+                               crtc->base.state->enable);
 
                active = dev_priv->display.get_pipe_config(crtc,
                                                           &pipe_config);
@@ -10910,7 +10999,7 @@ check_shared_dpll_state(struct drm_device *dev)
                     pll->on, active);
 
                for_each_intel_crtc(dev, crtc) {
-                       if (crtc->base.enabled && intel_crtc_to_shared_dpll(crtc) == pll)
+                       if (crtc->base.state->enable && intel_crtc_to_shared_dpll(crtc) == pll)
                                enabled_crtcs++;
                        if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll)
                                active_crtcs++;
@@ -11096,7 +11185,7 @@ static int __intel_set_mode(struct drm_crtc *crtc,
                intel_crtc_disable(&intel_crtc->base);
 
        for_each_intel_crtc_masked(dev, prepare_pipes, intel_crtc) {
-               if (intel_crtc->base.enabled)
+               if (intel_crtc->base.state->enable)
                        dev_priv->display.crtc_disable(&intel_crtc->base);
        }
 
@@ -11152,7 +11241,7 @@ static int __intel_set_mode(struct drm_crtc *crtc,
 
        /* FIXME: add subpixel order */
 done:
-       if (ret && crtc->enabled)
+       if (ret && crtc->state->enable)
                crtc->mode = *saved_mode;
 
        kfree(saved_mode);
@@ -11248,7 +11337,7 @@ static int intel_set_config_save_state(struct drm_device *dev,
         */
        count = 0;
        for_each_crtc(dev, crtc) {
-               config->save_crtc_enabled[count++] = crtc->enabled;
+               config->save_crtc_enabled[count++] = crtc->state->enable;
        }
 
        count = 0;
@@ -11482,7 +11571,7 @@ intel_modeset_stage_output_state(struct drm_device *dev,
                        }
                }
 
-               if (crtc->new_enabled != crtc->base.enabled) {
+               if (crtc->new_enabled != crtc->base.state->enable) {
                        DRM_DEBUG_KMS("crtc %sabled, full mode switch\n",
                                      crtc->new_enabled ? "en" : "dis");
                        config->mode_changed = true;
@@ -11787,7 +11876,8 @@ static void intel_shared_dpll_init(struct drm_device *dev)
  */
 int
 intel_prepare_plane_fb(struct drm_plane *plane,
-                      struct drm_framebuffer *fb)
+                      struct drm_framebuffer *fb,
+                      const struct drm_plane_state *new_state)
 {
        struct drm_device *dev = plane->dev;
        struct intel_plane *intel_plane = to_intel_plane(plane);
@@ -11841,7 +11931,8 @@ intel_prepare_plane_fb(struct drm_plane *plane,
  */
 void
 intel_cleanup_plane_fb(struct drm_plane *plane,
-                      struct drm_framebuffer *fb)
+                      struct drm_framebuffer *fb,
+                      const struct drm_plane_state *old_state)
 {
        struct drm_device *dev = plane->dev;
        struct drm_i915_gem_object *obj = intel_fb_obj(fb);
@@ -11897,7 +11988,7 @@ intel_check_primary_plane(struct drm_plane *plane,
                 */
                if (intel_crtc->primary_enabled &&
                    INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev) &&
-                   dev_priv->fbc.plane == intel_crtc->plane &&
+                   dev_priv->fbc.crtc == intel_crtc &&
                    state->base.rotation != BIT(DRM_ROTATE_0)) {
                        intel_crtc->atomic.disable_fbc = true;
                }
@@ -11916,6 +12007,12 @@ intel_check_primary_plane(struct drm_plane *plane,
                        INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe);
 
                intel_crtc->atomic.update_fbc = true;
+
+               /* Update watermarks on tiling changes. */
+               if (!plane->state->fb || !state->base.fb ||
+                   plane->state->fb->modifier[0] !=
+                   state->base.fb->modifier[0])
+                       intel_crtc->atomic.update_wm = true;
        }
 
        return 0;
@@ -12069,8 +12166,8 @@ void intel_plane_destroy(struct drm_plane *plane)
 }
 
 const struct drm_plane_funcs intel_plane_funcs = {
-       .update_plane = drm_plane_helper_update,
-       .disable_plane = drm_plane_helper_disable,
+       .update_plane = drm_atomic_helper_update_plane,
+       .disable_plane = drm_atomic_helper_disable_plane,
        .destroy = intel_plane_destroy,
        .set_property = drm_atomic_helper_plane_set_property,
        .atomic_get_property = intel_plane_atomic_get_property,
@@ -12185,13 +12282,10 @@ intel_check_cursor_plane(struct drm_plane *plane,
        if (fb == crtc->cursor->fb)
                return 0;
 
-       /* we only need to pin inside GTT if cursor is non-phy */
-       mutex_lock(&dev->struct_mutex);
-       if (!INTEL_INFO(dev)->cursor_needs_physical && obj->tiling_mode) {
+       if (fb->modifier[0] != DRM_FORMAT_MOD_NONE) {
                DRM_DEBUG_KMS("cursor cannot be tiled\n");
                ret = -EINVAL;
        }
-       mutex_unlock(&dev->struct_mutex);
 
 finish:
        if (intel_crtc->active) {
@@ -12309,6 +12403,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
        if (!crtc_state)
                goto fail;
        intel_crtc_set_state(intel_crtc, crtc_state);
+       crtc_state->base.crtc = &intel_crtc->base;
 
        primary = intel_primary_plane_create(dev, pipe);
        if (!primary)
@@ -12386,9 +12481,6 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
        struct drm_crtc *drmmode_crtc;
        struct intel_crtc *crtc;
 
-       if (!drm_core_check_feature(dev, DRIVER_MODESET))
-               return -ENODEV;
-
        drmmode_crtc = drm_crtc_find(dev, pipe_from_crtc_id->crtc_id);
 
        if (!drmmode_crtc) {
@@ -12661,52 +12753,100 @@ static const struct drm_framebuffer_funcs intel_fb_funcs = {
        .create_handle = intel_user_framebuffer_create_handle,
 };
 
+static
+u32 intel_fb_pitch_limit(struct drm_device *dev, uint64_t fb_modifier,
+                        uint32_t pixel_format)
+{
+       u32 gen = INTEL_INFO(dev)->gen;
+
+       if (gen >= 9) {
+               /* "The stride in bytes must not exceed the of the size of 8K
+                *  pixels and 32K bytes."
+                */
+                return min(8192*drm_format_plane_cpp(pixel_format, 0), 32768);
+       } else if (gen >= 5 && !IS_VALLEYVIEW(dev)) {
+               return 32*1024;
+       } else if (gen >= 4) {
+               if (fb_modifier == I915_FORMAT_MOD_X_TILED)
+                       return 16*1024;
+               else
+                       return 32*1024;
+       } else if (gen >= 3) {
+               if (fb_modifier == I915_FORMAT_MOD_X_TILED)
+                       return 8*1024;
+               else
+                       return 16*1024;
+       } else {
+               /* XXX DSPC is limited to 4k tiled */
+               return 8*1024;
+       }
+}
+
 static int intel_framebuffer_init(struct drm_device *dev,
                                  struct intel_framebuffer *intel_fb,
                                  struct drm_mode_fb_cmd2 *mode_cmd,
                                  struct drm_i915_gem_object *obj)
 {
        int aligned_height;
-       int pitch_limit;
        int ret;
+       u32 pitch_limit, stride_alignment;
 
        WARN_ON(!mutex_is_locked(&dev->struct_mutex));
 
-       if (obj->tiling_mode == I915_TILING_Y) {
-               DRM_DEBUG("hardware does not support tiling Y\n");
-               return -EINVAL;
+       if (mode_cmd->flags & DRM_MODE_FB_MODIFIERS) {
+               /* Enforce that fb modifier and tiling mode match, but only for
+                * X-tiled. This is needed for FBC. */
+               if (!!(obj->tiling_mode == I915_TILING_X) !=
+                   !!(mode_cmd->modifier[0] == I915_FORMAT_MOD_X_TILED)) {
+                       DRM_DEBUG("tiling_mode doesn't match fb modifier\n");
+                       return -EINVAL;
+               }
+       } else {
+               if (obj->tiling_mode == I915_TILING_X)
+                       mode_cmd->modifier[0] = I915_FORMAT_MOD_X_TILED;
+               else if (obj->tiling_mode == I915_TILING_Y) {
+                       DRM_DEBUG("No Y tiling for legacy addfb\n");
+                       return -EINVAL;
+               }
        }
 
-       if (mode_cmd->pitches[0] & 63) {
-               DRM_DEBUG("pitch (%d) must be at least 64 byte aligned\n",
-                         mode_cmd->pitches[0]);
+       /* Passed in modifier sanity checking. */
+       switch (mode_cmd->modifier[0]) {
+       case I915_FORMAT_MOD_Y_TILED:
+       case I915_FORMAT_MOD_Yf_TILED:
+               if (INTEL_INFO(dev)->gen < 9) {
+                       DRM_DEBUG("Unsupported tiling 0x%llx!\n",
+                                 mode_cmd->modifier[0]);
+                       return -EINVAL;
+               }
+       case DRM_FORMAT_MOD_NONE:
+       case I915_FORMAT_MOD_X_TILED:
+               break;
+       default:
+               DRM_ERROR("Unsupported fb modifier 0x%llx!\n",
+                               mode_cmd->modifier[0]);
                return -EINVAL;
        }
 
-       if (INTEL_INFO(dev)->gen >= 5 && !IS_VALLEYVIEW(dev)) {
-               pitch_limit = 32*1024;
-       } else if (INTEL_INFO(dev)->gen >= 4) {
-               if (obj->tiling_mode)
-                       pitch_limit = 16*1024;
-               else
-                       pitch_limit = 32*1024;
-       } else if (INTEL_INFO(dev)->gen >= 3) {
-               if (obj->tiling_mode)
-                       pitch_limit = 8*1024;
-               else
-                       pitch_limit = 16*1024;
-       } else
-               /* XXX DSPC is limited to 4k tiled */
-               pitch_limit = 8*1024;
+       stride_alignment = intel_fb_stride_alignment(dev, mode_cmd->modifier[0],
+                                                    mode_cmd->pixel_format);
+       if (mode_cmd->pitches[0] & (stride_alignment - 1)) {
+               DRM_DEBUG("pitch (%d) must be at least %u byte aligned\n",
+                         mode_cmd->pitches[0], stride_alignment);
+               return -EINVAL;
+       }
 
+       pitch_limit = intel_fb_pitch_limit(dev, mode_cmd->modifier[0],
+                                          mode_cmd->pixel_format);
        if (mode_cmd->pitches[0] > pitch_limit) {
-               DRM_DEBUG("%s pitch (%d) must be at less than %d\n",
-                         obj->tiling_mode ? "tiled" : "linear",
+               DRM_DEBUG("%s pitch (%u) must be at less than %d\n",
+                         mode_cmd->modifier[0] != DRM_FORMAT_MOD_NONE ?
+                         "tiled" : "linear",
                          mode_cmd->pitches[0], pitch_limit);
                return -EINVAL;
        }
 
-       if (obj->tiling_mode != I915_TILING_NONE &&
+       if (mode_cmd->modifier[0] == I915_FORMAT_MOD_X_TILED &&
            mode_cmd->pitches[0] != obj->stride) {
                DRM_DEBUG("pitch (%d) must match tiling stride (%d)\n",
                          mode_cmd->pitches[0], obj->stride);
@@ -12761,7 +12901,8 @@ static int intel_framebuffer_init(struct drm_device *dev,
                return -EINVAL;
 
        aligned_height = intel_fb_align_height(dev, mode_cmd->height,
-                                              obj->tiling_mode);
+                                              mode_cmd->pixel_format,
+                                              mode_cmd->modifier[0]);
        /* FIXME drm helper for size checks (especially planar formats)? */
        if (obj->base.size < aligned_height * mode_cmd->pitches[0])
                return -EINVAL;
@@ -12923,9 +13064,6 @@ static void intel_init_display(struct drm_device *dev)
                        valleyview_modeset_global_resources;
        }
 
-       /* Default just returns -ENODEV to indicate unsupported */
-       dev_priv->display.queue_flip = intel_default_queue_flip;
-
        switch (INTEL_INFO(dev)->gen) {
        case 2:
                dev_priv->display.queue_flip = intel_gen2_queue_flip;
@@ -12948,8 +13086,10 @@ static void intel_init_display(struct drm_device *dev)
                dev_priv->display.queue_flip = intel_gen7_queue_flip;
                break;
        case 9:
-               dev_priv->display.queue_flip = intel_gen9_queue_flip;
-               break;
+               /* Drop through - unsupported since execlist only. */
+       default:
+               /* Default just returns -ENODEV to indicate unsupported */
+               dev_priv->display.queue_flip = intel_default_queue_flip;
        }
 
        intel_panel_init_backlight_funcs(dev);
@@ -13165,6 +13305,8 @@ void intel_modeset_init(struct drm_device *dev)
        dev->mode_config.preferred_depth = 24;
        dev->mode_config.prefer_shadow = 1;
 
+       dev->mode_config.allow_fb_modifiers = true;
+
        dev->mode_config.funcs = &intel_mode_funcs;
 
        intel_init_quirks(dev);
@@ -13310,11 +13452,11 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
        I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
 
        /* restore vblank interrupts to correct state */
+       drm_crtc_vblank_reset(&crtc->base);
        if (crtc->active) {
                update_scanline_offset(crtc);
-               drm_vblank_on(dev, crtc->pipe);
-       } else
-               drm_vblank_off(dev, crtc->pipe);
+               drm_crtc_vblank_on(&crtc->base);
+       }
 
        /* We need to sanitize the plane -> pipe mapping first because this will
         * disable the crtc (and hence change the state) if it is wrong. Note
@@ -13354,6 +13496,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
                        }
 
                WARN_ON(crtc->active);
+               crtc->base.state->enable = false;
                crtc->base.enabled = false;
        }
 
@@ -13370,7 +13513,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
         * have active connectors/encoders. */
        intel_crtc_update_dpms(&crtc->base);
 
-       if (crtc->active != crtc->base.enabled) {
+       if (crtc->active != crtc->base.state->enable) {
                struct intel_encoder *encoder;
 
                /* This can happen either due to bugs in the get_hw_state
@@ -13378,9 +13521,10 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
                 * pipe A quirk. */
                DRM_DEBUG_KMS("[CRTC:%d] hw state adjusted, was %s, now %s\n",
                              crtc->base.base.id,
-                             crtc->base.enabled ? "enabled" : "disabled",
+                             crtc->base.state->enable ? "enabled" : "disabled",
                              crtc->active ? "enabled" : "disabled");
 
+               crtc->base.state->enable = crtc->active;
                crtc->base.enabled = crtc->active;
 
                /* Because we only establish the connector -> encoder ->
@@ -13517,6 +13661,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
                crtc->active = dev_priv->display.get_pipe_config(crtc,
                                                                 crtc->config);
 
+               crtc->base.state->enable = crtc->active;
                crtc->base.enabled = crtc->active;
                crtc->primary_enabled = primary_get_hw_state(crtc);
 
@@ -13702,6 +13847,7 @@ void intel_modeset_gem_init(struct drm_device *dev)
                                  to_intel_crtc(c)->pipe);
                        drm_framebuffer_unreference(c->primary->fb);
                        c->primary->fb = NULL;
+                       update_state_fb(c->primary);
                }
        }
        mutex_unlock(&dev->struct_mutex);