Merge branch 'for-linus' into for-next
authorTakashi Iwai <tiwai@suse.de>
Wed, 23 Dec 2015 07:33:34 +0000 (08:33 +0100)
committerTakashi Iwai <tiwai@suse.de>
Wed, 23 Dec 2015 07:33:34 +0000 (08:33 +0100)
Conflicts:
drivers/gpu/drm/i915/intel_pm.c

1  2 
drivers/gpu/drm/drm_probe_helper.c
drivers/gpu/drm/i915/i915_gem_context.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
sound/pci/hda/hda_intel.c

index eee3b6f38cfbb1779f953a1b1a80647c00507bf5,f8b5fcfa91a27521d40e52b818b15dc3c6a6bbaf..bfdf5bb223b9f14b35f4a67e56ceca018f548ca3
@@@ -147,8 -147,6 +147,8 @@@ static int drm_helper_probe_single_conn
        list_for_each_entry(mode, &connector->modes, head)
                mode->status = MODE_UNVERIFIED;
  
 +      old_status = connector->status;
 +
        if (connector->force) {
                if (connector->force == DRM_FORCE_ON ||
                    connector->force == DRM_FORCE_ON_DIGITAL)
                if (connector->funcs->force)
                        connector->funcs->force(connector);
        } else {
 -              old_status = connector->status;
 -
                connector->status = connector->funcs->detect(connector, true);
 +      }
 +
 +      /*
 +       * Normally either the driver's hpd code or the poll loop should
 +       * pick up any changes and fire the hotplug event. But if
 +       * userspace sneaks in a probe, we might miss a change. Hence
 +       * check here, and if anything changed start the hotplug code.
 +       */
 +      if (old_status != connector->status) {
 +              DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n",
 +                            connector->base.id,
 +                            connector->name,
 +                            drm_get_connector_status_name(old_status),
 +                            drm_get_connector_status_name(connector->status));
  
                /*
 -               * Normally either the driver's hpd code or the poll loop should
 -               * pick up any changes and fire the hotplug event. But if
 -               * userspace sneaks in a probe, we might miss a change. Hence
 -               * check here, and if anything changed start the hotplug code.
 +               * The hotplug event code might call into the fb
 +               * helpers, and so expects that we do not hold any
 +               * locks. Fire up the poll struct instead, it will
 +               * disable itself again.
                 */
 -              if (old_status != connector->status) {
 -                      DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
 -                                    connector->base.id,
 -                                    connector->name,
 -                                    old_status, connector->status);
 -
 -                      /*
 -                       * The hotplug event code might call into the fb
 -                       * helpers, and so expects that we do not hold any
 -                       * locks. Fire up the poll struct instead, it will
 -                       * disable itself again.
 -                       */
 -                      dev->mode_config.delayed_event = true;
 -                      if (dev->mode_config.poll_enabled)
 -                              schedule_delayed_work(&dev->mode_config.output_poll_work,
 -                                                    0);
 -              }
 +              dev->mode_config.delayed_event = true;
 +              if (dev->mode_config.poll_enabled)
 +                      schedule_delayed_work(&dev->mode_config.output_poll_work,
 +                                            0);
        }
  
        /* Re-enable polling in case the global poll config changed. */
                mode_flags |= DRM_MODE_FLAG_3D_MASK;
  
        list_for_each_entry(mode, &connector->modes, head) {
-               mode->status = drm_mode_validate_basic(mode);
+               if (mode->status == MODE_OK)
+                       mode->status = drm_mode_validate_basic(mode);
  
                if (mode->status == MODE_OK)
                        mode->status = drm_mode_validate_size(mode, maxX, maxY);
index 4b9400402aa3ed6aafdc0986b006cb8cad1fd924,02ceb7a4b4815e52a825a290aa8e6d2cd78d25b5..43761c5bcacadd33368c0de66d54cf94c2f5e361
@@@ -141,8 -141,6 +141,6 @@@ static void i915_gem_context_clean(stru
        if (!ppgtt)
                return;
  
-       WARN_ON(!list_empty(&ppgtt->base.active_list));
        list_for_each_entry_safe(vma, next, &ppgtt->base.inactive_list,
                                 mm_list) {
                if (WARN_ON(__i915_vma_unbind_no_wait(vma)))
@@@ -556,7 -554,7 +554,7 @@@ mi_set_context(struct drm_i915_gem_requ
                                if (signaller == ring)
                                        continue;
  
 -                              intel_ring_emit(ring, RING_PSMI_CTL(signaller->mmio_base));
 +                              intel_ring_emit_reg(ring, RING_PSMI_CTL(signaller->mmio_base));
                                intel_ring_emit(ring, _MASKED_BIT_ENABLE(GEN6_PSMI_SLEEP_MSG_DISABLE));
                        }
                }
                                if (signaller == ring)
                                        continue;
  
 -                              intel_ring_emit(ring, RING_PSMI_CTL(signaller->mmio_base));
 +                              intel_ring_emit_reg(ring, RING_PSMI_CTL(signaller->mmio_base));
                                intel_ring_emit(ring, _MASKED_BIT_DISABLE(GEN6_PSMI_SLEEP_MSG_DISABLE));
                        }
                }
@@@ -925,14 -923,6 +923,14 @@@ int i915_gem_context_getparam_ioctl(str
        case I915_CONTEXT_PARAM_NO_ZEROMAP:
                args->value = ctx->flags & CONTEXT_NO_ZEROMAP;
                break;
 +      case I915_CONTEXT_PARAM_GTT_SIZE:
 +              if (ctx->ppgtt)
 +                      args->value = ctx->ppgtt->base.total;
 +              else if (to_i915(dev)->mm.aliasing_ppgtt)
 +                      args->value = to_i915(dev)->mm.aliasing_ppgtt->base.total;
 +              else
 +                      args->value = to_i915(dev)->gtt.base.total;
 +              break;
        default:
                ret = -EINVAL;
                break;
index 696f7543d26498611ce5028c97db75e941af60b3,62211abe492265ce33cc5e04fbfdef71de398b8f..15a9ab428553c3cf6f481917f4375b171207fffe
@@@ -1095,7 -1095,7 +1095,7 @@@ enum transcoder intel_pipe_to_cpu_trans
  static bool pipe_dsl_stopped(struct drm_device *dev, enum pipe pipe)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
 -      u32 reg = PIPEDSL(pipe);
 +      i915_reg_t reg = PIPEDSL(pipe);
        u32 line1, line2;
        u32 line_mask;
  
@@@ -1135,7 -1135,7 +1135,7 @@@ static void intel_wait_for_pipe_off(str
        enum pipe pipe = crtc->pipe;
  
        if (INTEL_INFO(dev)->gen >= 4) {
 -              int reg = PIPECONF(cpu_transcoder);
 +              i915_reg_t reg = PIPECONF(cpu_transcoder);
  
                /* Wait for the Pipe State to go off */
                if (wait_for((I915_READ(reg) & I965_PIPECONF_ACTIVE) == 0,
@@@ -1285,7 -1285,7 +1285,7 @@@ void assert_panel_unlocked(struct drm_i
                           enum pipe pipe)
  {
        struct drm_device *dev = dev_priv->dev;
 -      int pp_reg;
 +      i915_reg_t pp_reg;
        u32 val;
        enum pipe panel_pipe = PIPE_A;
        bool locked = true;
@@@ -1480,7 -1480,8 +1480,7 @@@ static bool dp_pipe_enabled(struct drm_
                return false;
  
        if (HAS_PCH_CPT(dev_priv->dev)) {
 -              u32     trans_dp_ctl_reg = TRANS_DP_CTL(pipe);
 -              u32     trans_dp_ctl = I915_READ(trans_dp_ctl_reg);
 +              u32 trans_dp_ctl = I915_READ(TRANS_DP_CTL(pipe));
                if ((trans_dp_ctl & TRANS_DP_PORT_SEL_MASK) != port_sel)
                        return false;
        } else if (IS_CHERRYVIEW(dev_priv->dev)) {
@@@ -1544,13 -1545,12 +1544,13 @@@ static bool adpa_pipe_enabled(struct dr
  }
  
  static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv,
 -                                 enum pipe pipe, int reg, u32 port_sel)
 +                                 enum pipe pipe, i915_reg_t reg,
 +                                 u32 port_sel)
  {
        u32 val = I915_READ(reg);
        I915_STATE_WARN(dp_pipe_enabled(dev_priv, pipe, port_sel, val),
             "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n",
 -           reg, pipe_name(pipe));
 +           i915_mmio_reg_offset(reg), pipe_name(pipe));
  
        I915_STATE_WARN(HAS_PCH_IBX(dev_priv->dev) && (val & DP_PORT_EN) == 0
             && (val & DP_PIPEB_SELECT),
  }
  
  static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv,
 -                                   enum pipe pipe, int reg)
 +                                   enum pipe pipe, i915_reg_t reg)
  {
        u32 val = I915_READ(reg);
        I915_STATE_WARN(hdmi_pipe_enabled(dev_priv, pipe, val),
             "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n",
 -           reg, pipe_name(pipe));
 +           i915_mmio_reg_offset(reg), pipe_name(pipe));
  
        I915_STATE_WARN(HAS_PCH_IBX(dev_priv->dev) && (val & SDVO_ENABLE) == 0
             && (val & SDVO_PIPE_B_SELECT),
@@@ -1599,7 -1599,7 +1599,7 @@@ static void vlv_enable_pll(struct intel
  {
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
 -      int reg = DPLL(crtc->pipe);
 +      i915_reg_t reg = DPLL(crtc->pipe);
        u32 dpll = pipe_config->dpll_hw_state.dpll;
  
        assert_pipe_disabled(dev_priv, crtc->pipe);
@@@ -1688,7 -1688,7 +1688,7 @@@ static void i9xx_enable_pll(struct inte
  {
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
 -      int reg = DPLL(crtc->pipe);
 +      i915_reg_t reg = DPLL(crtc->pipe);
        u32 dpll = crtc->config->dpll_hw_state.dpll;
  
        assert_pipe_disabled(dev_priv, crtc->pipe);
@@@ -1837,7 -1837,7 +1837,7 @@@ void vlv_wait_port_ready(struct drm_i91
                         unsigned int expected_mask)
  {
        u32 port_mask;
 -      int dpll_reg;
 +      i915_reg_t dpll_reg;
  
        switch (dport->port) {
        case PORT_B:
@@@ -1962,8 -1962,7 +1962,8 @@@ static void ironlake_enable_pch_transco
        struct drm_device *dev = dev_priv->dev;
        struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 -      uint32_t reg, val, pipeconf_val;
 +      i915_reg_t reg;
 +      uint32_t val, pipeconf_val;
  
        /* PCH only available on ILK+ */
        BUG_ON(!HAS_PCH_SPLIT(dev));
@@@ -2052,8 -2051,7 +2052,8 @@@ static void ironlake_disable_pch_transc
                                            enum pipe pipe)
  {
        struct drm_device *dev = dev_priv->dev;
 -      uint32_t reg, val;
 +      i915_reg_t reg;
 +      uint32_t val;
  
        /* FDI relies on the transcoder */
        assert_fdi_tx_disabled(dev_priv, pipe);
        if (wait_for((I915_READ(reg) & TRANS_STATE_ENABLE) == 0, 50))
                DRM_ERROR("failed to disable transcoder %c\n", pipe_name(pipe));
  
 -      if (!HAS_PCH_IBX(dev)) {
 +      if (HAS_PCH_CPT(dev)) {
                /* Workaround: Clear the timing override chicken bit again. */
                reg = TRANS_CHICKEN2(pipe);
                val = I915_READ(reg);
@@@ -2108,9 -2106,10 +2108,9 @@@ static void intel_enable_pipe(struct in
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        enum pipe pipe = crtc->pipe;
 -      enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
 -                                                                    pipe);
 +      enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
        enum pipe pch_transcoder;
 -      int reg;
 +      i915_reg_t reg;
        u32 val;
  
        DRM_DEBUG_KMS("enabling pipe %c\n", pipe_name(pipe));
@@@ -2171,7 -2170,7 +2171,7 @@@ static void intel_disable_pipe(struct i
        struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
        enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
        enum pipe pipe = crtc->pipe;
 -      int reg;
 +      i915_reg_t reg;
        u32 val;
  
        DRM_DEBUG_KMS("disabling pipe %c\n", pipe_name(pipe));
@@@ -2270,20 -2269,20 +2270,20 @@@ intel_fb_align_height(struct drm_devic
                                               fb_format_modifier, 0));
  }
  
 -static int
 +static void
  intel_fill_fb_ggtt_view(struct i915_ggtt_view *view, struct drm_framebuffer *fb,
                        const struct drm_plane_state *plane_state)
  {
 -      struct intel_rotation_info *info = &view->rotation_info;
 +      struct intel_rotation_info *info = &view->params.rotation_info;
        unsigned int tile_height, tile_pitch;
  
        *view = i915_ggtt_view_normal;
  
        if (!plane_state)
 -              return 0;
 +              return;
  
        if (!intel_rotation_90_or_270(plane_state->rotation))
 -              return 0;
 +              return;
  
        *view = i915_ggtt_view_rotated;
  
                info->size_uv = info->width_pages_uv * info->height_pages_uv *
                                PAGE_SIZE;
        }
 -
 -      return 0;
  }
  
  static unsigned int intel_linear_alignment(struct drm_i915_private *dev_priv)
  int
  intel_pin_and_fence_fb_obj(struct drm_plane *plane,
                           struct drm_framebuffer *fb,
 -                         const struct drm_plane_state *plane_state,
 -                         struct intel_engine_cs *pipelined,
 -                         struct drm_i915_gem_request **pipelined_request)
 +                         const struct drm_plane_state *plane_state)
  {
        struct drm_device *dev = fb->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
                return -EINVAL;
        }
  
 -      ret = intel_fill_fb_ggtt_view(&view, fb, plane_state);
 -      if (ret)
 -              return ret;
 +      intel_fill_fb_ggtt_view(&view, fb, plane_state);
  
        /* Note that the w/a also requires 64 PTE of padding following the
         * bo. We currently fill all unused PTE with the shadow page and so
         */
        intel_runtime_pm_get(dev_priv);
  
 -      dev_priv->mm.interruptible = false;
 -      ret = i915_gem_object_pin_to_display_plane(obj, alignment, pipelined,
 -                                                 pipelined_request, &view);
 +      ret = i915_gem_object_pin_to_display_plane(obj, alignment,
 +                                                 &view);
        if (ret)
 -              goto err_interruptible;
 +              goto err_pm;
  
        /* Install a fence for tiled scan-out. Pre-i965 always needs a
         * fence, whereas 965+ only requires a fence if using
                i915_gem_object_pin_fence(obj);
        }
  
 -      dev_priv->mm.interruptible = true;
        intel_runtime_pm_put(dev_priv);
        return 0;
  
  err_unpin:
        i915_gem_object_unpin_from_display_plane(obj, &view);
 -err_interruptible:
 -      dev_priv->mm.interruptible = true;
 +err_pm:
        intel_runtime_pm_put(dev_priv);
        return ret;
  }
@@@ -2426,10 -2434,12 +2426,10 @@@ static void intel_unpin_fb_obj(struct d
  {
        struct drm_i915_gem_object *obj = intel_fb_obj(fb);
        struct i915_ggtt_view view;
 -      int ret;
  
        WARN_ON(!mutex_is_locked(&obj->base.dev->struct_mutex));
  
 -      ret = intel_fill_fb_ggtt_view(&view, fb, plane_state);
 -      WARN_ONCE(ret, "Couldn't get view from plane state!");
 +      intel_fill_fb_ggtt_view(&view, fb, plane_state);
  
        if (view.type == I915_GGTT_VIEW_NORMAL)
                i915_gem_object_unpin_fence(obj);
@@@ -2670,7 -2680,7 +2670,7 @@@ static void i9xx_update_primary_plane(s
        int plane = intel_crtc->plane;
        unsigned long linear_offset;
        u32 dspcntr;
 -      u32 reg = DSPCNTR(plane);
 +      i915_reg_t reg = DSPCNTR(plane);
        int pixel_size;
  
        if (!visible || !fb) {
@@@ -2800,7 -2810,7 +2800,7 @@@ static void ironlake_update_primary_pla
        int plane = intel_crtc->plane;
        unsigned long linear_offset;
        u32 dspcntr;
 -      u32 reg = DSPCNTR(plane);
 +      i915_reg_t reg = DSPCNTR(plane);
        int pixel_size;
  
        if (!visible || !fb) {
@@@ -2925,32 -2935,30 +2925,32 @@@ u32 intel_fb_stride_alignment(struct dr
        }
  }
  
 -unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
 -                                   struct drm_i915_gem_object *obj,
 -                                   unsigned int plane)
 +u32 intel_plane_obj_offset(struct intel_plane *intel_plane,
 +                         struct drm_i915_gem_object *obj,
 +                         unsigned int plane)
  {
 -      const struct i915_ggtt_view *view = &i915_ggtt_view_normal;
 +      struct i915_ggtt_view view;
        struct i915_vma *vma;
 -      unsigned char *offset;
 +      u64 offset;
  
 -      if (intel_rotation_90_or_270(intel_plane->base.state->rotation))
 -              view = &i915_ggtt_view_rotated;
 +      intel_fill_fb_ggtt_view(&view, intel_plane->base.fb,
 +                              intel_plane->base.state);
  
 -      vma = i915_gem_obj_to_ggtt_view(obj, view);
 +      vma = i915_gem_obj_to_ggtt_view(obj, &view);
        if (WARN(!vma, "ggtt vma for display object not found! (view=%u)\n",
 -              view->type))
 +              view.type))
                return -1;
  
 -      offset = (unsigned char *)vma->node.start;
 +      offset = vma->node.start;
  
        if (plane == 1) {
 -              offset += vma->ggtt_view.rotation_info.uv_start_page *
 +              offset += vma->ggtt_view.params.rotation_info.uv_start_page *
                          PAGE_SIZE;
        }
  
 -      return (unsigned long)offset;
 +      WARN_ON(upper_32_bits(offset));
 +
 +      return lower_32_bits(offset);
  }
  
  static void skl_detach_scaler(struct intel_crtc *intel_crtc, int id)
@@@ -3076,7 -3084,7 +3076,7 @@@ static void skylake_update_primary_plan
        u32 tile_height, plane_offset, plane_size;
        unsigned int rotation;
        int x_offset, y_offset;
 -      unsigned long surf_addr;
 +      u32 surf_addr;
        struct intel_crtc_state *crtc_state = intel_crtc->config;
        struct intel_plane_state *plane_state;
        int src_x = 0, src_y = 0, src_w = 0, src_h = 0;
@@@ -3204,9 -3212,10 +3204,9 @@@ static void intel_update_primary_planes
                struct intel_plane_state *plane_state;
  
                drm_modeset_lock_crtc(crtc, &plane->base);
 -
                plane_state = to_intel_plane_state(plane->base.state);
  
 -              if (plane_state->base.fb)
 +              if (crtc->state->active && plane_state->base.fb)
                        plane->commit_plane(&plane->base, plane_state);
  
                drm_modeset_unlock_crtc(crtc);
@@@ -3282,6 -3291,32 +3282,6 @@@ void intel_finish_reset(struct drm_devi
        drm_modeset_unlock_all(dev);
  }
  
 -static void
 -intel_finish_fb(struct drm_framebuffer *old_fb)
 -{
 -      struct drm_i915_gem_object *obj = intel_fb_obj(old_fb);
 -      struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
 -      bool was_interruptible = dev_priv->mm.interruptible;
 -      int ret;
 -
 -      /* Big Hammer, we also need to ensure that any pending
 -       * MI_WAIT_FOR_EVENT inside a user batch buffer on the
 -       * current scanout is retired before unpinning the old
 -       * framebuffer. Note that we rely on userspace rendering
 -       * into the buffer attached to the pipe they are waiting
 -       * on. If not, userspace generates a GPU hang with IPEHR
 -       * point to the MI_WAIT_FOR_EVENT.
 -       *
 -       * This should only fail upon a hung GPU, in which case we
 -       * can safely continue.
 -       */
 -      dev_priv->mm.interruptible = false;
 -      ret = i915_gem_object_wait_rendering(obj, true);
 -      dev_priv->mm.interruptible = was_interruptible;
 -
 -      WARN_ON(ret);
 -}
 -
  static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc)
  {
        struct drm_device *dev = crtc->dev;
@@@ -3351,8 -3386,7 +3351,8 @@@ static void intel_fdi_normal_train(stru
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        int pipe = intel_crtc->pipe;
 -      u32 reg, temp;
 +      i915_reg_t reg;
 +      u32 temp;
  
        /* enable normal train */
        reg = FDI_TX_CTL(pipe);
@@@ -3394,8 -3428,7 +3394,8 @@@ static void ironlake_fdi_link_train(str
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        int pipe = intel_crtc->pipe;
 -      u32 reg, temp, tries;
 +      i915_reg_t reg;
 +      u32 temp, tries;
  
        /* FDI needs bits from pipe first */
        assert_pipe_enabled(dev_priv, pipe);
@@@ -3495,8 -3528,7 +3495,8 @@@ static void gen6_fdi_link_train(struct 
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        int pipe = intel_crtc->pipe;
 -      u32 reg, temp, i, retry;
 +      i915_reg_t reg;
 +      u32 temp, i, retry;
  
        /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
           for train result */
@@@ -3628,8 -3660,7 +3628,8 @@@ static void ivb_manual_fdi_link_train(s
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        int pipe = intel_crtc->pipe;
 -      u32 reg, temp, i, j;
 +      i915_reg_t reg;
 +      u32 temp, i, j;
  
        /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
           for train result */
@@@ -3746,8 -3777,8 +3746,8 @@@ static void ironlake_fdi_pll_enable(str
        struct drm_device *dev = intel_crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        int pipe = intel_crtc->pipe;
 -      u32 reg, temp;
 -
 +      i915_reg_t reg;
 +      u32 temp;
  
        /* enable PCH FDI RX PLL, wait warmup plus DMI latency */
        reg = FDI_RX_CTL(pipe);
@@@ -3783,8 -3814,7 +3783,8 @@@ static void ironlake_fdi_pll_disable(st
        struct drm_device *dev = intel_crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        int pipe = intel_crtc->pipe;
 -      u32 reg, temp;
 +      i915_reg_t reg;
 +      u32 temp;
  
        /* Switch from PCDclk to Rawclk */
        reg = FDI_RX_CTL(pipe);
@@@ -3814,8 -3844,7 +3814,8 @@@ static void ironlake_fdi_disable(struc
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        int pipe = intel_crtc->pipe;
 -      u32 reg, temp;
 +      i915_reg_t reg;
 +      u32 temp;
  
        /* disable CPU FDI tx and PCH FDI rx */
        reg = FDI_TX_CTL(pipe);
@@@ -3908,23 -3937,15 +3908,23 @@@ static void page_flip_completed(struct 
                                 work->pending_flip_obj);
  }
  
 -void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc)
 +static int intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc)
  {
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
 +      long ret;
  
        WARN_ON(waitqueue_active(&dev_priv->pending_flip_queue));
 -      if (WARN_ON(wait_event_timeout(dev_priv->pending_flip_queue,
 -                                     !intel_crtc_has_pending_flip(crtc),
 -                                     60*HZ) == 0)) {
 +
 +      ret = wait_event_interruptible_timeout(
 +                                      dev_priv->pending_flip_queue,
 +                                      !intel_crtc_has_pending_flip(crtc),
 +                                      60*HZ);
 +
 +      if (ret < 0)
 +              return ret;
 +
 +      if (ret == 0) {
                struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  
                spin_lock_irq(&dev->event_lock);
                spin_unlock_irq(&dev->event_lock);
        }
  
 -      if (crtc->primary->fb) {
 -              mutex_lock(&dev->struct_mutex);
 -              intel_finish_fb(crtc->primary->fb);
 -              mutex_unlock(&dev->struct_mutex);
 -      }
 +      return 0;
  }
  
  /* Program iCLKIP clock to the desired frequency */
@@@ -4095,22 -4120,6 +4095,22 @@@ static void ivybridge_update_fdi_bc_bif
        }
  }
  
 +/* Return which DP Port should be selected for Transcoder DP control */
 +static enum port
 +intel_trans_dp_port_sel(struct drm_crtc *crtc)
 +{
 +      struct drm_device *dev = crtc->dev;
 +      struct intel_encoder *encoder;
 +
 +      for_each_encoder_on_crtc(dev, crtc, encoder) {
 +              if (encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
 +                  encoder->type == INTEL_OUTPUT_EDP)
 +                      return enc_to_dig_port(&encoder->base)->port;
 +      }
 +
 +      return -1;
 +}
 +
  /*
   * Enable PCH resources required for PCH ports:
   *   - PCH PLLs
@@@ -4125,7 -4134,7 +4125,7 @@@ static void ironlake_pch_enable(struct 
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        int pipe = intel_crtc->pipe;
 -      u32 reg, temp;
 +      u32 temp;
  
        assert_pch_transcoder_disabled(dev_priv, pipe);
  
  
        /* For PCH DP, enable TRANS_DP_CTL */
        if (HAS_PCH_CPT(dev) && intel_crtc->config->has_dp_encoder) {
 +              const struct drm_display_mode *adjusted_mode =
 +                      &intel_crtc->config->base.adjusted_mode;
                u32 bpc = (I915_READ(PIPECONF(pipe)) & PIPECONF_BPC_MASK) >> 5;
 -              reg = TRANS_DP_CTL(pipe);
 +              i915_reg_t reg = TRANS_DP_CTL(pipe);
                temp = I915_READ(reg);
                temp &= ~(TRANS_DP_PORT_SEL_MASK |
                          TRANS_DP_SYNC_MASK |
                temp |= TRANS_DP_OUTPUT_ENABLE;
                temp |= bpc << 9; /* same format but at 11:9 */
  
 -              if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC)
 +              if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
                        temp |= TRANS_DP_HSYNC_ACTIVE_HIGH;
 -              if (crtc->mode.flags & DRM_MODE_FLAG_PVSYNC)
 +              if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
                        temp |= TRANS_DP_VSYNC_ACTIVE_HIGH;
  
                switch (intel_trans_dp_port_sel(crtc)) {
 -              case PCH_DP_B:
 +              case PORT_B:
                        temp |= TRANS_DP_PORT_SEL_B;
                        break;
 -              case PCH_DP_C:
 +              case PORT_C:
                        temp |= TRANS_DP_PORT_SEL_C;
                        break;
 -              case PCH_DP_D:
 +              case PORT_D:
                        temp |= TRANS_DP_PORT_SEL_D;
                        break;
                default:
@@@ -4335,7 -4342,7 +4335,7 @@@ static void intel_shared_dpll_commit(st
  static void cpt_verify_modeset(struct drm_device *dev, int pipe)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
 -      int dslreg = PIPEDSL(pipe);
 +      i915_reg_t dslreg = PIPEDSL(pipe);
        u32 temp;
  
        temp = I915_READ(dslreg);
@@@ -4645,7 -4652,7 +4645,7 @@@ static void intel_crtc_load_lut(struct 
        }
  
        for (i = 0; i < 256; i++) {
 -              u32 palreg;
 +              i915_reg_t palreg;
  
                if (HAS_GMCH_DISPLAY(dev))
                        palreg = PALETTE(pipe, i);
@@@ -4724,9 -4731,9 +4724,9 @@@ intel_post_enable_primary(struct drm_cr
        if (IS_GEN2(dev))
                intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
  
 -      /* Underruns don't raise interrupts, so check manually. */
 -      if (HAS_GMCH_DISPLAY(dev))
 -              i9xx_check_fifo_underruns(dev_priv);
 +      /* Underruns don't always raise interrupts, so check manually. */
 +      intel_check_cpu_fifo_underruns(dev_priv);
 +      intel_check_pch_fifo_underruns(dev_priv);
  }
  
  /**
@@@ -4785,6 -4792,7 +4785,6 @@@ static void intel_post_plane_update(str
        struct intel_crtc_atomic_commit *atomic = &crtc->atomic;
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
 -      struct drm_plane *plane;
  
        if (atomic->wait_vblank)
                intel_wait_for_vblank(dev, crtc->pipe);
        if (atomic->post_enable_primary)
                intel_post_enable_primary(&crtc->base);
  
 -      drm_for_each_plane_mask(plane, dev, atomic->update_sprite_watermarks)
 -              intel_update_sprite_watermarks(plane, &crtc->base,
 -                                             0, 0, 0, false, false);
 -
        memset(atomic, 0, sizeof(*atomic));
  }
  
@@@ -4811,6 -4823,20 +4811,6 @@@ static void intel_pre_plane_update(stru
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc_atomic_commit *atomic = &crtc->atomic;
 -      struct drm_plane *p;
 -
 -      /* Track fb's for any planes being disabled */
 -      drm_for_each_plane_mask(p, dev, atomic->disabled_planes) {
 -              struct intel_plane *plane = to_intel_plane(p);
 -
 -              mutex_lock(&dev->struct_mutex);
 -              i915_gem_track_fb(intel_fb_obj(plane->base.fb), NULL,
 -                                plane->frontbuffer_bit);
 -              mutex_unlock(&dev->struct_mutex);
 -      }
 -
 -      if (atomic->wait_for_flips)
 -              intel_crtc_wait_for_pending_flips(&crtc->base);
  
        if (atomic->disable_fbc)
                intel_fbc_disable_crtc(crtc);
@@@ -4858,9 -4884,6 +4858,9 @@@ static void ironlake_crtc_enable(struc
        if (WARN_ON(intel_crtc->active))
                return;
  
 +      if (intel_crtc->config->has_pch_encoder)
 +              intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, false);
 +
        if (intel_crtc->config->has_pch_encoder)
                intel_prepare_shared_dpll(intel_crtc);
  
        intel_crtc->active = true;
  
        intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
 -      intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true);
  
        for_each_encoder_on_crtc(dev, crtc, encoder)
                if (encoder->pre_enable)
  
        if (HAS_PCH_CPT(dev))
                cpt_verify_modeset(dev, intel_crtc->pipe);
 +
 +      /* Must wait for vblank to avoid spurious PCH FIFO underruns */
 +      if (intel_crtc->config->has_pch_encoder)
 +              intel_wait_for_vblank(dev, pipe);
 +      intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true);
  }
  
  /* IPS only exists on ULT machines and is tied to pipe A. */
@@@ -4943,10 -4962,6 +4943,10 @@@ static void haswell_crtc_enable(struct 
        if (WARN_ON(intel_crtc->active))
                return;
  
 +      if (intel_crtc->config->has_pch_encoder)
 +              intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
 +                                                    false);
 +
        if (intel_crtc_to_shared_dpll(intel_crtc))
                intel_enable_shared_dpll(intel_crtc);
  
                        encoder->pre_enable(encoder);
        }
  
 -      if (intel_crtc->config->has_pch_encoder) {
 -              intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
 -                                                    true);
 +      if (intel_crtc->config->has_pch_encoder)
                dev_priv->display.fdi_link_train(crtc);
 -      }
  
        if (!is_dsi)
                intel_ddi_enable_pipe_clock(intel_crtc);
                intel_opregion_notify_encoder(encoder, true);
        }
  
 +      if (intel_crtc->config->has_pch_encoder)
 +              intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
 +                                                    true);
 +
        /* If we change the relative order between pipe/planes enabling, we need
         * to change the workaround. */
        hsw_workaround_pipe = pipe_config->hsw_workaround_pipe;
@@@ -5052,9 -5066,7 +5052,9 @@@ static void ironlake_crtc_disable(struc
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        struct intel_encoder *encoder;
        int pipe = intel_crtc->pipe;
 -      u32 reg, temp;
 +
 +      if (intel_crtc->config->has_pch_encoder)
 +              intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, false);
  
        for_each_encoder_on_crtc(dev, crtc, encoder)
                encoder->disable(encoder);
        drm_crtc_vblank_off(crtc);
        assert_vblank_disabled(crtc);
  
 -      if (intel_crtc->config->has_pch_encoder)
 -              intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, false);
 -
        intel_disable_pipe(intel_crtc);
  
        ironlake_pfit_disable(intel_crtc, false);
                ironlake_disable_pch_transcoder(dev_priv, pipe);
  
                if (HAS_PCH_CPT(dev)) {
 +                      i915_reg_t reg;
 +                      u32 temp;
 +
                        /* disable TRANS_DP_CTL */
                        reg = TRANS_DP_CTL(pipe);
                        temp = I915_READ(reg);
  
                ironlake_fdi_pll_disable(intel_crtc);
        }
 +
 +      intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true);
  }
  
  static void haswell_crtc_disable(struct drm_crtc *crtc)
        enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
        bool is_dsi = intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DSI);
  
 +      if (intel_crtc->config->has_pch_encoder)
 +              intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
 +                                                    false);
 +
        for_each_encoder_on_crtc(dev, crtc, encoder) {
                intel_opregion_notify_encoder(encoder, false);
                encoder->disable(encoder);
        drm_crtc_vblank_off(crtc);
        assert_vblank_disabled(crtc);
  
 -      if (intel_crtc->config->has_pch_encoder)
 -              intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
 -                                                    false);
        intel_disable_pipe(intel_crtc);
  
        if (intel_crtc->config->dp_encoder_is_mst)
        for_each_encoder_on_crtc(dev, crtc, encoder)
                if (encoder->post_disable)
                        encoder->post_disable(encoder);
 +
 +      if (intel_crtc->config->has_pch_encoder)
 +              intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
 +                                                    true);
  }
  
  static void i9xx_pfit_enable(struct intel_crtc *crtc)
@@@ -5179,15 -5184,15 +5179,15 @@@ static enum intel_display_power_domain 
  {
        switch (port) {
        case PORT_A:
 -              return POWER_DOMAIN_PORT_DDI_A_4_LANES;
 +              return POWER_DOMAIN_PORT_DDI_A_LANES;
        case PORT_B:
 -              return POWER_DOMAIN_PORT_DDI_B_4_LANES;
 +              return POWER_DOMAIN_PORT_DDI_B_LANES;
        case PORT_C:
 -              return POWER_DOMAIN_PORT_DDI_C_4_LANES;
 +              return POWER_DOMAIN_PORT_DDI_C_LANES;
        case PORT_D:
 -              return POWER_DOMAIN_PORT_DDI_D_4_LANES;
 +              return POWER_DOMAIN_PORT_DDI_D_LANES;
        case PORT_E:
 -              return POWER_DOMAIN_PORT_DDI_E_2_LANES;
 +              return POWER_DOMAIN_PORT_DDI_E_LANES;
        default:
                MISSING_CASE(port);
                return POWER_DOMAIN_PORT_OTHER;
@@@ -5282,11 -5287,13 +5282,11 @@@ static unsigned long get_crtc_power_dom
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        enum pipe pipe = intel_crtc->pipe;
        unsigned long mask;
 -      enum transcoder transcoder;
 +      enum transcoder transcoder = intel_crtc->config->cpu_transcoder;
  
        if (!crtc->state->active)
                return 0;
  
 -      transcoder = intel_pipe_to_cpu_transcoder(dev->dev_private, pipe);
 -
        mask = BIT(POWER_DOMAIN_PIPE(pipe));
        mask |= BIT(POWER_DOMAIN_TRANSCODER(transcoder));
        if (intel_crtc->config->pch_pfit.enabled ||
@@@ -5373,7 -5380,7 +5373,7 @@@ static void intel_update_max_cdclk(stru
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
  
 -      if (IS_SKYLAKE(dev)) {
 +      if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
                u32 limit = I915_READ(SKL_DFSM) & SKL_DFSM_CDCLK_LIMIT_MASK;
  
                if (limit == SKL_DFSM_CDCLK_LIMIT_675)
@@@ -5790,16 -5797,32 +5790,16 @@@ void skl_uninit_cdclk(struct drm_i915_p
        if (I915_READ(DBUF_CTL) & DBUF_POWER_STATE)
                DRM_ERROR("DBuf power disable timeout\n");
  
 -      /*
 -       * DMC assumes ownership of LCPLL and will get confused if we touch it.
 -       */
 -      if (dev_priv->csr.dmc_payload) {
 -              /* disable DPLL0 */
 -              I915_WRITE(LCPLL1_CTL, I915_READ(LCPLL1_CTL) &
 -                                      ~LCPLL_PLL_ENABLE);
 -              if (wait_for(!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_LOCK), 1))
 -                      DRM_ERROR("Couldn't disable DPLL0\n");
 -      }
 -
 -      intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
 +      /* disable DPLL0 */
 +      I915_WRITE(LCPLL1_CTL, I915_READ(LCPLL1_CTL) & ~LCPLL_PLL_ENABLE);
 +      if (wait_for(!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_LOCK), 1))
 +              DRM_ERROR("Couldn't disable DPLL0\n");
  }
  
  void skl_init_cdclk(struct drm_i915_private *dev_priv)
  {
 -      u32 val;
        unsigned int required_vco;
  
 -      /* enable PCH reset handshake */
 -      val = I915_READ(HSW_NDE_RSTWRN_OPT);
 -      I915_WRITE(HSW_NDE_RSTWRN_OPT, val | RESET_PCH_HANDSHAKE_ENABLE);
 -
 -      /* enable PG1 and Misc I/O */
 -      intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
 -
        /* DPLL0 not enabled (happens on early BIOS versions) */
        if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE)) {
                /* enable DPLL0 */
                DRM_ERROR("DBuf power enable timeout\n");
  }
  
 +int skl_sanitize_cdclk(struct drm_i915_private *dev_priv)
 +{
 +      uint32_t lcpll1 = I915_READ(LCPLL1_CTL);
 +      uint32_t cdctl = I915_READ(CDCLK_CTL);
 +      int freq = dev_priv->skl_boot_cdclk;
 +
 +      /*
 +       * check if the pre-os intialized the display
 +       * There is SWF18 scratchpad register defined which is set by the
 +       * pre-os which can be used by the OS drivers to check the status
 +       */
 +      if ((I915_READ(SWF_ILK(0x18)) & 0x00FFFFFF) == 0)
 +              goto sanitize;
 +
 +      /* Is PLL enabled and locked ? */
 +      if (!((lcpll1 & LCPLL_PLL_ENABLE) && (lcpll1 & LCPLL_PLL_LOCK)))
 +              goto sanitize;
 +
 +      /* DPLL okay; verify the cdclock
 +       *
 +       * Noticed in some instances that the freq selection is correct but
 +       * decimal part is programmed wrong from BIOS where pre-os does not
 +       * enable display. Verify the same as well.
 +       */
 +      if (cdctl == ((cdctl & CDCLK_FREQ_SEL_MASK) | skl_cdclk_decimal(freq)))
 +              /* All well; nothing to sanitize */
 +              return false;
 +sanitize:
 +      /*
 +       * As of now initialize with max cdclk till
 +       * we get dynamic cdclk support
 +       * */
 +      dev_priv->skl_boot_cdclk = dev_priv->max_cdclk_freq;
 +      skl_init_cdclk(dev_priv);
 +
 +      /* we did have to sanitize */
 +      return true;
 +}
 +
  /* Adjust CDclk dividers to allow high res or save power if possible */
  static void valleyview_set_cdclk(struct drm_device *dev, int cdclk)
  {
@@@ -6323,12 -6307,13 +6323,14 @@@ static void intel_crtc_disable_noatomic
                return;
  
        if (to_intel_plane_state(crtc->primary->state)->visible) {
 -              intel_crtc_wait_for_pending_flips(crtc);
 +              WARN_ON(intel_crtc->unpin_work);
 +
                intel_pre_disable_primary(crtc);
+               intel_crtc_disable_planes(crtc, 1 << drm_plane_index(crtc->primary));
+               to_intel_plane_state(crtc->primary->state)->visible = false;
        }
  
-       intel_crtc_disable_planes(crtc, crtc->state->plane_mask);
        dev_priv->display.crtc_disable(crtc);
        intel_crtc->active = false;
        intel_update_watermarks(crtc);
@@@ -6642,15 -6627,6 +6644,15 @@@ static void hsw_compute_ips_config(stru
                pipe_config_supports_ips(dev_priv, pipe_config);
  }
  
 +static bool intel_crtc_supports_double_wide(const struct intel_crtc *crtc)
 +{
 +      const struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 +
 +      /* GDG double wide on either pipe, otherwise pipe A only */
 +      return INTEL_INFO(dev_priv)->gen < 4 &&
 +              (crtc->pipe == PIPE_A || IS_I915G(dev_priv));
 +}
 +
  static int intel_crtc_compute_config(struct intel_crtc *crtc,
                                     struct intel_crtc_state *pipe_config)
  {
  
        /* FIXME should check pixel clock limits on all platforms */
        if (INTEL_INFO(dev)->gen < 4) {
 -              int clock_limit = dev_priv->max_cdclk_freq;
 +              int clock_limit = dev_priv->max_cdclk_freq * 9 / 10;
  
                /*
 -               * Enable pixel doubling when the dot clock
 +               * Enable double wide mode when the dot clock
                 * is > 90% of the (display) core speed.
 -               *
 -               * GDG double wide on either pipe,
 -               * otherwise pipe A only.
                 */
 -              if ((crtc->pipe == PIPE_A || IS_I915G(dev)) &&
 -                  adjusted_mode->crtc_clock > clock_limit * 9 / 10) {
 +              if (intel_crtc_supports_double_wide(crtc) &&
 +                  adjusted_mode->crtc_clock > clock_limit) {
                        clock_limit *= 2;
                        pipe_config->double_wide = true;
                }
  
 -              if (adjusted_mode->crtc_clock > clock_limit * 9 / 10)
 +              if (adjusted_mode->crtc_clock > clock_limit) {
 +                      DRM_DEBUG_KMS("requested pixel clock (%d kHz) too high (max: %d kHz, double wide: %s)\n",
 +                                    adjusted_mode->crtc_clock, clock_limit,
 +                                    yesno(pipe_config->double_wide));
                        return -EINVAL;
 +              }
        }
  
        /*
@@@ -7442,7 -7417,7 +7444,7 @@@ static void chv_prepare_pll(struct inte
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        int pipe = crtc->pipe;
 -      int dpll_reg = DPLL(crtc->pipe);
 +      i915_reg_t dpll_reg = DPLL(crtc->pipe);
        enum dpio_channel port = vlv_pipe_to_channel(pipe);
        u32 loopfilter, tribuf_calcntr;
        u32 bestn, bestm1, bestm2, bestp1, bestp2, bestm2_frac;
@@@ -9360,8 -9335,8 +9362,8 @@@ static void assert_can_disable_lcpll(st
  
        I915_STATE_WARN(I915_READ(HSW_PWR_WELL_DRIVER), "Power well on\n");
        I915_STATE_WARN(I915_READ(SPLL_CTL) & SPLL_PLL_ENABLE, "SPLL enabled\n");
 -      I915_STATE_WARN(I915_READ(WRPLL_CTL1) & WRPLL_PLL_ENABLE, "WRPLL1 enabled\n");
 -      I915_STATE_WARN(I915_READ(WRPLL_CTL2) & WRPLL_PLL_ENABLE, "WRPLL2 enabled\n");
 +      I915_STATE_WARN(I915_READ(WRPLL_CTL(0)) & WRPLL_PLL_ENABLE, "WRPLL1 enabled\n");
 +      I915_STATE_WARN(I915_READ(WRPLL_CTL(1)) & WRPLL_PLL_ENABLE, "WRPLL2 enabled\n");
        I915_STATE_WARN(I915_READ(PCH_PP_STATUS) & PP_ON, "Panel power on\n");
        I915_STATE_WARN(I915_READ(BLC_PWM_CPU_CTL2) & BLM_PWM_ENABLE,
             "CPU PWM1 enabled\n");
@@@ -9823,7 -9798,7 +9825,7 @@@ static void haswell_get_ddi_port_state(
  
        port = (tmp & TRANS_DDI_PORT_MASK) >> TRANS_DDI_PORT_SHIFT;
  
 -      if (IS_SKYLAKE(dev))
 +      if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
                skylake_get_ddi_pll(dev_priv, port, pipe_config);
        else if (IS_BROXTON(dev))
                bxt_get_ddi_pll(dev_priv, port, pipe_config);
@@@ -10169,17 -10144,20 +10171,17 @@@ __intel_framebuffer_create(struct drm_d
        int ret;
  
        intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
 -      if (!intel_fb) {
 -              drm_gem_object_unreference(&obj->base);
 +      if (!intel_fb)
                return ERR_PTR(-ENOMEM);
 -      }
  
        ret = intel_framebuffer_init(dev, intel_fb, mode_cmd, obj);
        if (ret)
                goto err;
  
        return &intel_fb->base;
 +
  err:
 -      drm_gem_object_unreference(&obj->base);
        kfree(intel_fb);
 -
        return ERR_PTR(ret);
  }
  
@@@ -10219,7 -10197,6 +10221,7 @@@ intel_framebuffer_create_for_mode(struc
                                  struct drm_display_mode *mode,
                                  int depth, int bpp)
  {
 +      struct drm_framebuffer *fb;
        struct drm_i915_gem_object *obj;
        struct drm_mode_fb_cmd2 mode_cmd = { 0 };
  
                                                                bpp);
        mode_cmd.pixel_format = drm_mode_legacy_fb_format(bpp, depth);
  
 -      return intel_framebuffer_create(dev, &mode_cmd, obj);
 +      fb = intel_framebuffer_create(dev, &mode_cmd, obj);
 +      if (IS_ERR(fb))
 +              drm_gem_object_unreference_unlocked(&obj->base);
 +
 +      return fb;
  }
  
  static struct drm_framebuffer *
@@@ -11141,7 -11114,7 +11143,7 @@@ static int intel_gen7_queue_flip(struc
         */
        if (ring->id == RCS) {
                intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
 -              intel_ring_emit(ring, DERRMR);
 +              intel_ring_emit_reg(ring, DERRMR);
                intel_ring_emit(ring, ~(DERRMR_PIPEA_PRI_FLIP_DONE |
                                        DERRMR_PIPEB_PRI_FLIP_DONE |
                                        DERRMR_PIPEC_PRI_FLIP_DONE));
                else
                        intel_ring_emit(ring, MI_STORE_REGISTER_MEM |
                                              MI_SRM_LRM_GLOBAL_GTT);
 -              intel_ring_emit(ring, DERRMR);
 +              intel_ring_emit_reg(ring, DERRMR);
                intel_ring_emit(ring, ring->scratch.gtt_offset + 256);
                if (IS_GEN8(dev)) {
                        intel_ring_emit(ring, 0);
@@@ -11196,14 -11169,13 +11198,14 @@@ static bool use_mmio_flip(struct intel_
  }
  
  static void skl_do_mmio_flip(struct intel_crtc *intel_crtc,
 +                           unsigned int rotation,
                             struct intel_unpin_work *work)
  {
        struct drm_device *dev = intel_crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_framebuffer *fb = intel_crtc->base.primary->fb;
        const enum pipe pipe = intel_crtc->pipe;
 -      u32 ctl, stride;
 +      u32 ctl, stride, tile_height;
  
        ctl = I915_READ(PLANE_CTL(pipe, 0));
        ctl &= ~PLANE_CTL_TILED_MASK;
         * The stride is either expressed as a multiple of 64 bytes chunks for
         * linear buffers or in number of tiles for tiled buffers.
         */
 -      stride = fb->pitches[0] /
 -               intel_fb_stride_alignment(dev, fb->modifier[0],
 -                                         fb->pixel_format);
 +      if (intel_rotation_90_or_270(rotation)) {
 +              /* stride = Surface height in tiles */
 +              tile_height = intel_tile_height(dev, fb->pixel_format,
 +                                              fb->modifier[0], 0);
 +              stride = DIV_ROUND_UP(fb->height, tile_height);
 +      } else {
 +              stride = fb->pitches[0] /
 +                              intel_fb_stride_alignment(dev, fb->modifier[0],
 +                                                        fb->pixel_format);
 +      }
  
        /*
         * Both PLANE_CTL and PLANE_STRIDE are not updated on vblank but on
@@@ -11257,9 -11222,10 +11259,9 @@@ static void ilk_do_mmio_flip(struct int
        struct intel_framebuffer *intel_fb =
                to_intel_framebuffer(intel_crtc->base.primary->fb);
        struct drm_i915_gem_object *obj = intel_fb->obj;
 +      i915_reg_t reg = DSPCNTR(intel_crtc->plane);
        u32 dspcntr;
 -      u32 reg;
  
 -      reg = DSPCNTR(intel_crtc->plane);
        dspcntr = I915_READ(reg);
  
        if (obj->tiling_mode != I915_TILING_NONE)
@@@ -11293,7 -11259,7 +11295,7 @@@ static void intel_do_mmio_flip(struct i
        intel_pipe_update_start(crtc);
  
        if (INTEL_INFO(mmio_flip->i915)->gen >= 9)
 -              skl_do_mmio_flip(crtc, work);
 +              skl_do_mmio_flip(crtc, mmio_flip->rotation, work);
        else
                /* use_mmio_flip() retricts MMIO flips to ilk+ */
                ilk_do_mmio_flip(crtc, work);
@@@ -11320,7 -11286,10 +11322,7 @@@ static void intel_mmio_flip_work_func(s
  
  static int intel_queue_mmio_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 drm_i915_gem_object *obj)
  {
        struct intel_mmio_flip *mmio_flip;
  
        mmio_flip->i915 = to_i915(dev);
        mmio_flip->req = i915_gem_request_reference(obj->last_write_req);
        mmio_flip->crtc = to_intel_crtc(crtc);
 +      mmio_flip->rotation = crtc->primary->state->rotation;
  
        INIT_WORK(&mmio_flip->work, intel_mmio_flip_work_func);
        schedule_work(&mmio_flip->work);
@@@ -11537,14 -11505,9 +11539,14 @@@ static int intel_crtc_page_flip(struct 
         * synchronisation, so all we want here is to pin the framebuffer
         * into the display plane and skip any waits.
         */
 +      if (!mmio_flip) {
 +              ret = i915_gem_object_sync(obj, ring, &request);
 +              if (ret)
 +                      goto cleanup_pending;
 +      }
 +
        ret = intel_pin_and_fence_fb_obj(crtc->primary, fb,
 -                                       crtc->primary->state,
 -                                       mmio_flip ? i915_gem_request_get_ring(obj->last_write_req) : ring, &request);
 +                                       crtc->primary->state);
        if (ret)
                goto cleanup_pending;
  
        work->gtt_offset += intel_crtc->dspaddr_offset;
  
        if (mmio_flip) {
 -              ret = intel_queue_mmio_flip(dev, crtc, fb, obj, ring,
 -                                          page_flip_flags);
 +              ret = intel_queue_mmio_flip(dev, crtc, obj);
                if (ret)
                        goto cleanup_unpin;
  
  static bool intel_wm_need_update(struct drm_plane *plane,
                                 struct drm_plane_state *state)
  {
 -      /* Update watermarks on tiling changes. */
 +      struct intel_plane_state *new = to_intel_plane_state(state);
 +      struct intel_plane_state *cur = to_intel_plane_state(plane->state);
 +
 +      /* Update watermarks on tiling or size changes. */
        if (!plane->state->fb || !state->fb ||
            plane->state->fb->modifier[0] != state->fb->modifier[0] ||
 -          plane->state->rotation != state->rotation)
 -              return true;
 -
 -      if (plane->state->crtc_w != state->crtc_w)
 +          plane->state->rotation != state->rotation ||
 +          drm_rect_width(&new->src) != drm_rect_width(&cur->src) ||
 +          drm_rect_height(&new->src) != drm_rect_height(&cur->src) ||
 +          drm_rect_width(&new->dst) != drm_rect_width(&cur->dst) ||
 +          drm_rect_height(&new->dst) != drm_rect_height(&cur->dst))
                return true;
  
        return false;
  }
  
 +static bool needs_scaling(struct intel_plane_state *state)
 +{
 +      int src_w = drm_rect_width(&state->src) >> 16;
 +      int src_h = drm_rect_height(&state->src) >> 16;
 +      int dst_w = drm_rect_width(&state->dst);
 +      int dst_h = drm_rect_height(&state->dst);
 +
 +      return (src_w != dst_w || src_h != dst_h);
 +}
 +
  int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
                                    struct drm_plane_state *plane_state)
  {
        bool mode_changed = needs_modeset(crtc_state);
        bool was_crtc_enabled = crtc->state->active;
        bool is_crtc_enabled = crtc_state->active;
 -
        bool turn_off, turn_on, visible, was_visible;
        struct drm_framebuffer *fb = plane_state->fb;
  
                        return ret;
        }
  
 -      /*
 -       * Disabling a plane is always okay; we just need to update
 -       * fb tracking in a special way since cleanup_fb() won't
 -       * get called by the plane helpers.
 -       */
 -      if (old_plane_state->base.fb && !fb)
 -              intel_crtc->atomic.disabled_planes |= 1 << i;
 -
        was_visible = old_plane_state->visible;
        visible = to_intel_plane_state(plane_state)->visible;
  
  
        switch (plane->type) {
        case DRM_PLANE_TYPE_PRIMARY:
 -              intel_crtc->atomic.wait_for_flips = true;
                intel_crtc->atomic.pre_disable_primary = turn_off;
                intel_crtc->atomic.post_enable_primary = turn_on;
  
        case DRM_PLANE_TYPE_CURSOR:
                break;
        case DRM_PLANE_TYPE_OVERLAY:
 -              if (turn_off && !mode_changed) {
 +              /*
 +               * WaCxSRDisabledForSpriteScaling:ivb
 +               *
 +               * cstate->update_wm was already set above, so this flag will
 +               * take effect when we commit and program watermarks.
 +               */
 +              if (IS_IVYBRIDGE(dev) &&
 +                  needs_scaling(to_intel_plane_state(plane_state)) &&
 +                  !needs_scaling(old_plane_state)) {
 +                      to_intel_crtc_state(crtc_state)->disable_lp_wm = true;
 +              } else if (turn_off && !mode_changed) {
                        intel_crtc->atomic.wait_vblank = true;
                        intel_crtc->atomic.update_sprite_watermarks |=
                                1 << i;
                }
 +
 +              break;
        }
        return 0;
  }
@@@ -11917,12 -11865,6 +11919,12 @@@ static int intel_crtc_atomic_check(stru
        }
  
        ret = 0;
 +      if (dev_priv->display.compute_pipe_wm) {
 +              ret = dev_priv->display.compute_pipe_wm(intel_crtc, state);
 +              if (ret)
 +                      return ret;
 +      }
 +
        if (INTEL_INFO(dev)->gen >= 9) {
                if (mode_changed)
                        ret = skl_update_scaler_crtc(pipe_config);
@@@ -12112,7 -12054,7 +12114,7 @@@ static void intel_dump_pipe_config(stru
                              pipe_config->dpll_hw_state.pll9,
                              pipe_config->dpll_hw_state.pll10,
                              pipe_config->dpll_hw_state.pcsdw12);
 -      } else if (IS_SKYLAKE(dev)) {
 +      } else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
                DRM_DEBUG_KMS("ddi_pll_sel: %u; dpll_hw_state: "
                              "ctrl1: 0x%x, cfgcr1: 0x%x, cfgcr2: 0x%x\n",
                              pipe_config->ddi_pll_sel,
@@@ -12366,18 -12308,6 +12368,18 @@@ intel_modeset_update_crtc_state(struct 
                        crtc->hwmode = crtc->state->adjusted_mode;
                else
                        crtc->hwmode.crtc_clock = 0;
 +
 +              /*
 +               * Update legacy state to satisfy fbc code. This can
 +               * be removed when fbc uses the atomic state.
 +               */
 +              if (drm_atomic_get_existing_plane_state(state, crtc->primary)) {
 +                      struct drm_plane_state *plane_state = crtc->primary->state;
 +
 +                      crtc->primary->fb = plane_state->fb;
 +                      crtc->x = plane_state->src_x >> 16;
 +                      crtc->y = plane_state->src_y >> 16;
 +              }
        }
  }
  
@@@ -12403,7 -12333,7 +12405,7 @@@ static bool intel_fuzzy_clock_check(in
        list_for_each_entry((intel_crtc), \
                            &(dev)->mode_config.crtc_list, \
                            base.head) \
 -              if (mask & (1 <<(intel_crtc)->pipe))
 +              for_each_if (mask & (1 <<(intel_crtc)->pipe))
  
  static bool
  intel_compare_m_n(unsigned int m, unsigned int n,
@@@ -13141,45 -13071,6 +13143,45 @@@ static int intel_modeset_checks(struct 
        return 0;
  }
  
 +/*
 + * Handle calculation of various watermark data at the end of the atomic check
 + * phase.  The code here should be run after the per-crtc and per-plane 'check'
 + * handlers to ensure that all derived state has been updated.
 + */
 +static void calc_watermark_data(struct drm_atomic_state *state)
 +{
 +      struct drm_device *dev = state->dev;
 +      struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
 +      struct drm_crtc *crtc;
 +      struct drm_crtc_state *cstate;
 +      struct drm_plane *plane;
 +      struct drm_plane_state *pstate;
 +
 +      /*
 +       * Calculate watermark configuration details now that derived
 +       * plane/crtc state is all properly updated.
 +       */
 +      drm_for_each_crtc(crtc, dev) {
 +              cstate = drm_atomic_get_existing_crtc_state(state, crtc) ?:
 +                      crtc->state;
 +
 +              if (cstate->active)
 +                      intel_state->wm_config.num_pipes_active++;
 +      }
 +      drm_for_each_legacy_plane(plane, dev) {
 +              pstate = drm_atomic_get_existing_plane_state(state, plane) ?:
 +                      plane->state;
 +
 +              if (!to_intel_plane_state(pstate)->visible)
 +                      continue;
 +
 +              intel_state->wm_config.sprites_enabled = true;
 +              if (pstate->crtc_w != pstate->src_w >> 16 ||
 +                  pstate->crtc_h != pstate->src_h >> 16)
 +                      intel_state->wm_config.sprites_scaled = true;
 +      }
 +}
 +
  /**
   * intel_atomic_check - validate state object
   * @dev: drm device
  static int intel_atomic_check(struct drm_device *dev,
                              struct drm_atomic_state *state)
  {
 +      struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
        struct drm_crtc *crtc;
        struct drm_crtc_state *crtc_state;
        int ret, i;
                if (ret)
                        return ret;
        } else
 -              to_intel_atomic_state(state)->cdclk =
 -                      to_i915(state->dev)->cdclk_freq;
 +              intel_state->cdclk = to_i915(state->dev)->cdclk_freq;
 +
 +      ret = drm_atomic_helper_check_planes(state->dev, state);
 +      if (ret)
 +              return ret;
 +
 +      calc_watermark_data(state);
 +
 +      return 0;
 +}
 +
 +static int intel_atomic_prepare_commit(struct drm_device *dev,
 +                                     struct drm_atomic_state *state,
 +                                     bool async)
 +{
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct drm_plane_state *plane_state;
 +      struct drm_crtc_state *crtc_state;
 +      struct drm_plane *plane;
 +      struct drm_crtc *crtc;
 +      int i, ret;
 +
 +      if (async) {
 +              DRM_DEBUG_KMS("i915 does not yet support async commit\n");
 +              return -EINVAL;
 +      }
 +
 +      for_each_crtc_in_state(state, crtc, crtc_state, i) {
 +              ret = intel_crtc_wait_for_pending_flips(crtc);
 +              if (ret)
 +                      return ret;
 +
 +              if (atomic_read(&to_intel_crtc(crtc)->unpin_work_count) >= 2)
 +                      flush_workqueue(dev_priv->wq);
 +      }
 +
 +      ret = mutex_lock_interruptible(&dev->struct_mutex);
 +      if (ret)
 +              return ret;
 +
 +      ret = drm_atomic_helper_prepare_planes(dev, state);
 +      if (!ret && !async && !i915_reset_in_progress(&dev_priv->gpu_error)) {
 +              u32 reset_counter;
 +
 +              reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
 +              mutex_unlock(&dev->struct_mutex);
 +
 +              for_each_plane_in_state(state, plane, plane_state, i) {
 +                      struct intel_plane_state *intel_plane_state =
 +                              to_intel_plane_state(plane_state);
 +
 +                      if (!intel_plane_state->wait_req)
 +                              continue;
 +
 +                      ret = __i915_wait_request(intel_plane_state->wait_req,
 +                                                reset_counter, true,
 +                                                NULL, NULL);
 +
 +                      /* Swallow -EIO errors to allow updates during hw lockup. */
 +                      if (ret == -EIO)
 +                              ret = 0;
 +
 +                      if (ret)
 +                              break;
 +              }
 +
 +              if (!ret)
 +                      return 0;
 +
 +              mutex_lock(&dev->struct_mutex);
 +              drm_atomic_helper_cleanup_planes(dev, state);
 +      }
  
 -      return drm_atomic_helper_check_planes(state->dev, state);
 +      mutex_unlock(&dev->struct_mutex);
 +      return ret;
  }
  
  /**
@@@ -13354,20 -13173,22 +13356,20 @@@ static int intel_atomic_commit(struct d
                               bool async)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
 -      struct drm_crtc *crtc;
        struct drm_crtc_state *crtc_state;
 +      struct drm_crtc *crtc;
        int ret = 0;
        int i;
        bool any_ms = false;
  
 -      if (async) {
 -              DRM_DEBUG_KMS("i915 does not yet support async commit\n");
 -              return -EINVAL;
 -      }
 -
 -      ret = drm_atomic_helper_prepare_planes(dev, state);
 -      if (ret)
 +      ret = intel_atomic_prepare_commit(dev, state, async);
 +      if (ret) {
 +              DRM_DEBUG_ATOMIC("Preparing state failed with %i\n", ret);
                return ret;
 +      }
  
        drm_atomic_helper_swap_state(dev, state);
 +      dev_priv->wm.config = to_intel_atomic_state(state)->wm_config;
  
        for_each_crtc_in_state(state, crtc, crtc_state, i) {
                struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
                        to_intel_crtc_state(crtc->state)->update_pipe;
                unsigned long put_domains = 0;
  
 +              if (modeset)
 +                      intel_display_power_get(dev_priv, POWER_DOMAIN_MODESET);
 +
                if (modeset && crtc->state->active) {
                        update_scanline_offset(to_intel_crtc(crtc));
                        dev_priv->display.crtc_enable(crtc);
                if (!modeset)
                        intel_pre_plane_update(intel_crtc);
  
 -              drm_atomic_helper_commit_planes_on_crtc(crtc_state);
 +              if (crtc->state->active &&
 +                  (crtc->state->planes_changed || update_pipe))
 +                      drm_atomic_helper_commit_planes_on_crtc(crtc_state);
  
                if (put_domains)
                        modeset_put_power_domains(dev_priv, put_domains);
  
                intel_post_plane_update(intel_crtc);
 +
 +              if (modeset)
 +                      intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET);
        }
  
        /* FIXME: add subpixel order */
  
        drm_atomic_helper_wait_for_vblanks(dev, state);
 +
 +      mutex_lock(&dev->struct_mutex);
        drm_atomic_helper_cleanup_planes(dev, state);
 +      mutex_unlock(&dev->struct_mutex);
  
        if (any_ms)
                intel_modeset_check_state(dev, state);
@@@ -13611,8 -13421,6 +13613,8 @@@ static void intel_shared_dpll_init(stru
   * bits.  Some older platforms need special physical address handling for
   * cursor planes.
   *
 + * Must be called with struct_mutex held.
 + *
   * Returns 0 on success, negative error code on failure.
   */
  int
@@@ -13623,58 -13431,28 +13625,58 @@@ intel_prepare_plane_fb(struct drm_plan
        struct drm_framebuffer *fb = new_state->fb;
        struct intel_plane *intel_plane = to_intel_plane(plane);
        struct drm_i915_gem_object *obj = intel_fb_obj(fb);
 -      struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->fb);
 +      struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->state->fb);
        int ret = 0;
  
 -      if (!obj)
 +      if (!obj && !old_obj)
                return 0;
  
 -      mutex_lock(&dev->struct_mutex);
 +      if (old_obj) {
 +              struct drm_crtc_state *crtc_state =
 +                      drm_atomic_get_existing_crtc_state(new_state->state, plane->state->crtc);
 +
 +              /* Big Hammer, we also need to ensure that any pending
 +               * MI_WAIT_FOR_EVENT inside a user batch buffer on the
 +               * current scanout is retired before unpinning the old
 +               * framebuffer. Note that we rely on userspace rendering
 +               * into the buffer attached to the pipe they are waiting
 +               * on. If not, userspace generates a GPU hang with IPEHR
 +               * point to the MI_WAIT_FOR_EVENT.
 +               *
 +               * This should only fail upon a hung GPU, in which case we
 +               * can safely continue.
 +               */
 +              if (needs_modeset(crtc_state))
 +                      ret = i915_gem_object_wait_rendering(old_obj, true);
 +
 +              /* Swallow -EIO errors to allow updates during hw lockup. */
 +              if (ret && ret != -EIO)
 +                      return ret;
 +      }
  
 -      if (plane->type == DRM_PLANE_TYPE_CURSOR &&
 +      if (!obj) {
 +              ret = 0;
 +      } else if (plane->type == DRM_PLANE_TYPE_CURSOR &&
            INTEL_INFO(dev)->cursor_needs_physical) {
                int align = IS_I830(dev) ? 16 * 1024 : 256;
                ret = i915_gem_object_attach_phys(obj, align);
                if (ret)
                        DRM_DEBUG_KMS("failed to attach phys object\n");
        } else {
 -              ret = intel_pin_and_fence_fb_obj(plane, fb, new_state, NULL, NULL);
 +              ret = intel_pin_and_fence_fb_obj(plane, fb, new_state);
        }
  
 -      if (ret == 0)
 -              i915_gem_track_fb(old_obj, obj, intel_plane->frontbuffer_bit);
 +      if (ret == 0) {
 +              if (obj) {
 +                      struct intel_plane_state *plane_state =
 +                              to_intel_plane_state(new_state);
  
 -      mutex_unlock(&dev->struct_mutex);
 +                      i915_gem_request_assign(&plane_state->wait_req,
 +                                              obj->last_write_req);
 +              }
 +
 +              i915_gem_track_fb(old_obj, obj, intel_plane->frontbuffer_bit);
 +      }
  
        return ret;
  }
   * @fb: old framebuffer that was on plane
   *
   * Cleans up a framebuffer that has just been removed from a plane.
 + *
 + * Must be called with struct_mutex held.
   */
  void
  intel_cleanup_plane_fb(struct drm_plane *plane,
                       const struct drm_plane_state *old_state)
  {
        struct drm_device *dev = plane->dev;
 -      struct drm_i915_gem_object *obj = intel_fb_obj(old_state->fb);
 +      struct intel_plane *intel_plane = to_intel_plane(plane);
 +      struct intel_plane_state *old_intel_state;
 +      struct drm_i915_gem_object *old_obj = intel_fb_obj(old_state->fb);
 +      struct drm_i915_gem_object *obj = intel_fb_obj(plane->state->fb);
  
 -      if (!obj)
 +      old_intel_state = to_intel_plane_state(old_state);
 +
 +      if (!obj && !old_obj)
                return;
  
 -      if (plane->type != DRM_PLANE_TYPE_CURSOR ||
 -          !INTEL_INFO(dev)->cursor_needs_physical) {
 -              mutex_lock(&dev->struct_mutex);
 +      if (old_obj && (plane->type != DRM_PLANE_TYPE_CURSOR ||
 +          !INTEL_INFO(dev)->cursor_needs_physical))
                intel_unpin_fb_obj(old_state->fb, old_state);
 -              mutex_unlock(&dev->struct_mutex);
 -      }
 +
 +      /* prepare_fb aborted? */
 +      if ((old_obj && (old_obj->frontbuffer_bits & intel_plane->frontbuffer_bit)) ||
 +          (obj && !(obj->frontbuffer_bits & intel_plane->frontbuffer_bit)))
 +              i915_gem_track_fb(old_obj, obj, intel_plane->frontbuffer_bit);
 +
 +      i915_gem_request_assign(&old_intel_state->wait_req, NULL);
 +
  }
  
  int
@@@ -13732,7 -13498,7 +13734,7 @@@ skl_max_scale(struct intel_crtc *intel_
        crtc_clock = crtc_state->base.adjusted_mode.crtc_clock;
        cdclk = to_intel_atomic_state(crtc_state->base.state)->cdclk;
  
 -      if (!crtc_clock || !cdclk)
 +      if (WARN_ON_ONCE(!crtc_clock || cdclk < crtc_clock))
                return DRM_PLANE_HELPER_NO_SCALING;
  
        /*
@@@ -13780,8 -13546,18 +13782,8 @@@ intel_commit_primary_plane(struct drm_p
        struct drm_framebuffer *fb = state->base.fb;
        struct drm_device *dev = plane->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
 -      struct intel_crtc *intel_crtc;
 -      struct drm_rect *src = &state->src;
  
        crtc = crtc ? crtc : plane->crtc;
 -      intel_crtc = to_intel_crtc(crtc);
 -
 -      plane->fb = fb;
 -      crtc->x = src->x1 >> 16;
 -      crtc->y = src->y1 >> 16;
 -
 -      if (!crtc->state->active)
 -              return;
  
        dev_priv->display.update_primary_plane(crtc, fb,
                                               state->src.x1 >> 16,
@@@ -13811,7 -13587,8 +13813,7 @@@ static void intel_begin_crtc_commit(str
                intel_update_watermarks(crtc);
  
        /* Perform vblank evasion around commit operation */
 -      if (crtc->state->active)
 -              intel_pipe_update_start(intel_crtc);
 +      intel_pipe_update_start(intel_crtc);
  
        if (modeset)
                return;
@@@ -13827,7 -13604,8 +13829,7 @@@ static void intel_finish_crtc_commit(st
  {
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  
 -      if (crtc->state->active)
 -              intel_pipe_update_end(intel_crtc);
 +      intel_pipe_update_end(intel_crtc);
  }
  
  /**
@@@ -14010,7 -13788,8 +14012,7 @@@ intel_commit_cursor_plane(struct drm_pl
        intel_crtc->cursor_bo = obj;
  
  update:
 -      if (crtc->state->active)
 -              intel_crtc_update_cursor(crtc, state->visible);
 +      intel_crtc_update_cursor(crtc, state->visible);
  }
  
  static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev,
@@@ -14282,7 -14061,7 +14284,7 @@@ static void intel_setup_outputs(struct 
                 */
                found = I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_INIT_DISPLAY_DETECTED;
                /* WaIgnoreDDIAStrap: skl */
 -              if (found || IS_SKYLAKE(dev))
 +              if (found || IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
                        intel_ddi_init(dev, PORT_A);
  
                /* DDI B, C and D detection is indicated by the SFUSE_STRAP
                /*
                 * On SKL we don't have a way to detect DDI-E so we rely on VBT.
                 */
 -              if (IS_SKYLAKE(dev) &&
 +              if ((IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) &&
                    (dev_priv->vbt.ddi_port_info[PORT_E].supports_dp ||
                     dev_priv->vbt.ddi_port_info[PORT_E].supports_dvi ||
                     dev_priv->vbt.ddi_port_info[PORT_E].supports_hdmi))
  
                if (I915_READ(PCH_HDMIB) & SDVO_DETECTED) {
                        /* PCH SDVOB multiplex with HDMIB */
 -                      found = intel_sdvo_init(dev, PCH_SDVOB, true);
 +                      found = intel_sdvo_init(dev, PCH_SDVOB, PORT_B);
                        if (!found)
                                intel_hdmi_init(dev, PCH_HDMIB, PORT_B);
                        if (!found && (I915_READ(PCH_DP_B) & DP_DETECTED))
  
                if (I915_READ(GEN3_SDVOB) & SDVO_DETECTED) {
                        DRM_DEBUG_KMS("probing SDVOB\n");
 -                      found = intel_sdvo_init(dev, GEN3_SDVOB, true);
 +                      found = intel_sdvo_init(dev, GEN3_SDVOB, PORT_B);
                        if (!found && IS_G4X(dev)) {
                                DRM_DEBUG_KMS("probing HDMI on SDVOB\n");
                                intel_hdmi_init(dev, GEN4_HDMIB, PORT_B);
  
                if (I915_READ(GEN3_SDVOB) & SDVO_DETECTED) {
                        DRM_DEBUG_KMS("probing SDVOC\n");
 -                      found = intel_sdvo_init(dev, GEN3_SDVOC, false);
 +                      found = intel_sdvo_init(dev, GEN3_SDVOC, PORT_C);
                }
  
                if (!found && (I915_READ(GEN3_SDVOC) & SDVO_DETECTED)) {
@@@ -14649,9 -14428,8 +14651,9 @@@ static int intel_framebuffer_init(struc
  static struct drm_framebuffer *
  intel_user_framebuffer_create(struct drm_device *dev,
                              struct drm_file *filp,
 -                            struct drm_mode_fb_cmd2 *user_mode_cmd)
 +                            const struct drm_mode_fb_cmd2 *user_mode_cmd)
  {
 +      struct drm_framebuffer *fb;
        struct drm_i915_gem_object *obj;
        struct drm_mode_fb_cmd2 mode_cmd = *user_mode_cmd;
  
        if (&obj->base == NULL)
                return ERR_PTR(-ENOENT);
  
 -      return intel_framebuffer_create(dev, &mode_cmd, obj);
 +      fb = intel_framebuffer_create(dev, &mode_cmd, obj);
 +      if (IS_ERR(fb))
 +              drm_gem_object_unreference_unlocked(&obj->base);
 +
 +      return fb;
  }
  
  #ifndef CONFIG_DRM_FBDEV_EMULATION
@@@ -14749,7 -14523,7 +14751,7 @@@ static void intel_init_display(struct d
        }
  
        /* Returns the core display clock speed */
 -      if (IS_SKYLAKE(dev))
 +      if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
                dev_priv->display.get_display_clock_speed =
                        skylake_get_display_clock_speed;
        else if (IS_BROXTON(dev))
@@@ -15038,7 -14812,7 +15040,7 @@@ static void i915_disable_vga(struct drm
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
        u8 sr1;
 -      u32 vga_reg = i915_vgacntrl_reg(dev);
 +      i915_reg_t vga_reg = i915_vgacntrl_reg(dev);
  
        /* WaEnableVGAAccessThroughIOPort:ctg,elk,ilk,snb,ivb,vlv,hsw */
        vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO);
@@@ -15154,6 -14928,9 +15156,6 @@@ void intel_modeset_init(struct drm_devi
        i915_disable_vga(dev);
        intel_setup_outputs(dev);
  
 -      /* Just in case the BIOS is doing something questionable. */
 -      intel_fbc_disable(dev_priv);
 -
        drm_modeset_lock_all(dev);
        intel_modeset_setup_hw_state(dev);
        drm_modeset_unlock_all(dev);
@@@ -15240,9 -15017,10 +15242,9 @@@ static void intel_sanitize_crtc(struct 
  {
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
 -      u32 reg;
 +      i915_reg_t reg = PIPECONF(crtc->config->cpu_transcoder);
  
        /* Clear any frame start delays used for debugging left by the BIOS */
 -      reg = PIPECONF(crtc->config->cpu_transcoder);
        I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
  
        /* restore vblank interrupts to correct state */
@@@ -15396,7 -15174,7 +15398,7 @@@ static void intel_sanitize_encoder(stru
  void i915_redisable_vga_power_on(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
 -      u32 vga_reg = i915_vgacntrl_reg(dev);
 +      i915_reg_t vga_reg = i915_vgacntrl_reg(dev);
  
        if (!(I915_READ(vga_reg) & VGA_DISP_DISABLE)) {
                DRM_DEBUG_KMS("Something enabled VGA plane, disabling it\n");
@@@ -15435,7 -15213,7 +15437,7 @@@ static void readout_plane_state(struct 
        struct intel_plane_state *plane_state =
                to_intel_plane_state(primary->state);
  
 -      plane_state->visible =
 +      plane_state->visible = crtc->active &&
                primary_get_hw_state(to_intel_plane(primary));
  
        if (plane_state->visible)
@@@ -15692,7 -15470,8 +15694,7 @@@ void intel_modeset_gem_init(struct drm_
                mutex_lock(&dev->struct_mutex);
                ret = intel_pin_and_fence_fb_obj(c->primary,
                                                 c->primary->fb,
 -                                               c->primary->state,
 -                                               NULL, NULL);
 +                                               c->primary->state);
                mutex_unlock(&dev->struct_mutex);
                if (ret) {
                        DRM_ERROR("failed to pin boot fb on pipe %d\n",
index 96f45d7b3e4b9f57365f279c48a934069fe8c114,f091ad12d694a43ebb0dce69b31089ffd4abe366..038a81d03b17d77fa8bcae25b93bb240e5e24087
@@@ -1708,6 -1708,13 +1708,6 @@@ static uint32_t ilk_wm_fbc(uint32_t pri
        return DIV_ROUND_UP(pri_val * 64, horiz_pixels * bytes_per_pixel) + 2;
  }
  
 -struct skl_pipe_wm_parameters {
 -      bool active;
 -      uint32_t pipe_htotal;
 -      uint32_t pixel_rate; /* in KHz */
 -      struct intel_plane_wm_parameters plane[I915_MAX_PLANES];
 -};
 -
  struct ilk_wm_maximums {
        uint16_t pri;
        uint16_t spr;
        uint16_t fbc;
  };
  
 -/* used in computing the new watermarks state */
 -struct intel_wm_config {
 -      unsigned int num_pipes_active;
 -      bool sprites_enabled;
 -      bool sprites_scaled;
 -};
 -
  /*
   * For both WM_PIPE and WM_LP.
   * mem_value must be in 0.1us units.
@@@ -1965,11 -1979,9 +1965,11 @@@ static void ilk_compute_wm_level(const 
                                 const struct intel_crtc *intel_crtc,
                                 int level,
                                 struct intel_crtc_state *cstate,
 +                               struct intel_plane_state *pristate,
 +                               struct intel_plane_state *sprstate,
 +                               struct intel_plane_state *curstate,
                                 struct intel_wm_level *result)
  {
 -      struct intel_plane *intel_plane;
        uint16_t pri_latency = dev_priv->wm.pri_latency[level];
        uint16_t spr_latency = dev_priv->wm.spr_latency[level];
        uint16_t cur_latency = dev_priv->wm.cur_latency[level];
                cur_latency *= 5;
        }
  
 -      for_each_intel_plane_on_crtc(dev_priv->dev, intel_crtc, intel_plane) {
 -              struct intel_plane_state *pstate =
 -                      to_intel_plane_state(intel_plane->base.state);
 -
 -              switch (intel_plane->base.type) {
 -              case DRM_PLANE_TYPE_PRIMARY:
 -                      result->pri_val = ilk_compute_pri_wm(cstate, pstate,
 -                                                           pri_latency,
 -                                                           level);
 -                      result->fbc_val = ilk_compute_fbc_wm(cstate, pstate,
 -                                                           result->pri_val);
 -                      break;
 -              case DRM_PLANE_TYPE_OVERLAY:
 -                      result->spr_val = ilk_compute_spr_wm(cstate, pstate,
 -                                                           spr_latency);
 -                      break;
 -              case DRM_PLANE_TYPE_CURSOR:
 -                      result->cur_val = ilk_compute_cur_wm(cstate, pstate,
 -                                                           cur_latency);
 -                      break;
 -              }
 -      }
 -
 +      result->pri_val = ilk_compute_pri_wm(cstate, pristate,
 +                                           pri_latency, level);
 +      result->spr_val = ilk_compute_spr_wm(cstate, sprstate, spr_latency);
 +      result->cur_val = ilk_compute_cur_wm(cstate, curstate, cur_latency);
 +      result->fbc_val = ilk_compute_fbc_wm(cstate, pristate, result->pri_val);
        result->enable = true;
  }
  
@@@ -2244,19 -2274,34 +2244,19 @@@ static void skl_setup_wm_latency(struc
        intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency);
  }
  
 -static void ilk_compute_wm_config(struct drm_device *dev,
 -                                struct intel_wm_config *config)
 -{
 -      struct intel_crtc *intel_crtc;
 -
 -      /* Compute the currently _active_ config */
 -      for_each_intel_crtc(dev, intel_crtc) {
 -              const struct intel_pipe_wm *wm = &intel_crtc->wm.active;
 -
 -              if (!wm->pipe_enabled)
 -                      continue;
 -
 -              config->sprites_enabled |= wm->sprites_enabled;
 -              config->sprites_scaled |= wm->sprites_scaled;
 -              config->num_pipes_active++;
 -      }
 -}
 -
  /* Compute new watermarks for the pipe */
 -static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate,
 -                                struct intel_pipe_wm *pipe_wm)
 +static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc,
 +                             struct drm_atomic_state *state)
  {
 -      struct drm_crtc *crtc = cstate->base.crtc;
 -      struct drm_device *dev = crtc->dev;
 +      struct intel_pipe_wm *pipe_wm;
 +      struct drm_device *dev = intel_crtc->base.dev;
        const struct drm_i915_private *dev_priv = dev->dev_private;
 -      struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 +      struct intel_crtc_state *cstate = NULL;
        struct intel_plane *intel_plane;
 +      struct drm_plane_state *ps;
 +      struct intel_plane_state *pristate = NULL;
        struct intel_plane_state *sprstate = NULL;
 +      struct intel_plane_state *curstate = NULL;
        int level, max_level = ilk_wm_max_level(dev);
        /* LP0 watermark maximums depend on this pipe alone */
        struct intel_wm_config config = {
        };
        struct ilk_wm_maximums max;
  
 +      cstate = intel_atomic_get_crtc_state(state, intel_crtc);
 +      if (IS_ERR(cstate))
 +              return PTR_ERR(cstate);
 +
 +      pipe_wm = &cstate->wm.optimal.ilk;
 +
        for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
 -              if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY) {
 -                      sprstate = to_intel_plane_state(intel_plane->base.state);
 -                      break;
 -              }
 +              ps = drm_atomic_get_plane_state(state,
 +                                              &intel_plane->base);
 +              if (IS_ERR(ps))
 +                      return PTR_ERR(ps);
 +
 +              if (intel_plane->base.type == DRM_PLANE_TYPE_PRIMARY)
 +                      pristate = to_intel_plane_state(ps);
 +              else if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY)
 +                      sprstate = to_intel_plane_state(ps);
 +              else if (intel_plane->base.type == DRM_PLANE_TYPE_CURSOR)
 +                      curstate = to_intel_plane_state(ps);
        }
  
        config.sprites_enabled = sprstate->visible;
                drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16);
  
        pipe_wm->pipe_enabled = cstate->base.active;
 -      pipe_wm->sprites_enabled = sprstate->visible;
 +      pipe_wm->sprites_enabled = config.sprites_enabled;
        pipe_wm->sprites_scaled = config.sprites_scaled;
  
        /* ILK/SNB: LP2+ watermarks only w/o sprites */
        if (config.sprites_scaled)
                max_level = 0;
  
 -      ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate, &pipe_wm->wm[0]);
 +      ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate,
 +                           pristate, sprstate, curstate, &pipe_wm->wm[0]);
  
        if (IS_HASWELL(dev) || IS_BROADWELL(dev))
 -              pipe_wm->linetime = hsw_compute_linetime_wm(dev, crtc);
 +              pipe_wm->linetime = hsw_compute_linetime_wm(dev,
 +                                                          &intel_crtc->base);
  
        /* LP0 watermarks always use 1/2 DDB partitioning */
        ilk_compute_wm_maximums(dev, 0, &config, INTEL_DDB_PART_1_2, &max);
  
        /* At least LP0 must be valid */
        if (!ilk_validate_wm_level(0, &max, &pipe_wm->wm[0]))
 -              return false;
 +              return -EINVAL;
  
        ilk_compute_wm_reg_maximums(dev, 1, &max);
  
        for (level = 1; level <= max_level; level++) {
                struct intel_wm_level wm = {};
  
 -              ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate, &wm);
 +              ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate,
 +                                   pristate, sprstate, curstate, &wm);
  
                /*
                 * Disable any watermark level that exceeds the
                pipe_wm->wm[level] = wm;
        }
  
 -      return true;
 +      return 0;
  }
  
  /*
@@@ -2349,9 -2378,7 +2349,9 @@@ static void ilk_merge_wm_level(struct d
        ret_wm->enable = true;
  
        for_each_intel_crtc(dev, intel_crtc) {
 -              const struct intel_pipe_wm *active = &intel_crtc->wm.active;
 +              const struct intel_crtc_state *cstate =
 +                      to_intel_crtc_state(intel_crtc->base.state);
 +              const struct intel_pipe_wm *active = &cstate->wm.optimal.ilk;
                const struct intel_wm_level *wm = &active->wm[level];
  
                if (!active->pipe_enabled)
@@@ -2499,15 -2526,14 +2499,15 @@@ static void ilk_compute_wm_results(stru
  
        /* LP0 register values */
        for_each_intel_crtc(dev, intel_crtc) {
 +              const struct intel_crtc_state *cstate =
 +                      to_intel_crtc_state(intel_crtc->base.state);
                enum pipe pipe = intel_crtc->pipe;
 -              const struct intel_wm_level *r =
 -                      &intel_crtc->wm.active.wm[0];
 +              const struct intel_wm_level *r = &cstate->wm.optimal.ilk.wm[0];
  
                if (WARN_ON(!r->enable))
                        continue;
  
 -              results->wm_linetime[pipe] = intel_crtc->wm.active.linetime;
 +              results->wm_linetime[pipe] = cstate->wm.optimal.ilk.linetime;
  
                results->wm_pipe[pipe] =
                        (r->pri_val << WM0_PIPE_PLANE_SHIFT) |
@@@ -2729,40 -2755,18 +2729,40 @@@ static bool ilk_disable_lp_wm(struct dr
  #define SKL_DDB_SIZE          896     /* in blocks */
  #define BXT_DDB_SIZE          512
  
 +/*
 + * Return the index of a plane in the SKL DDB and wm result arrays.  Primary
 + * plane is always in slot 0, cursor is always in slot I915_MAX_PLANES-1, and
 + * other universal planes are in indices 1..n.  Note that this may leave unused
 + * indices between the top "sprite" plane and the cursor.
 + */
 +static int
 +skl_wm_plane_id(const struct intel_plane *plane)
 +{
 +      switch (plane->base.type) {
 +      case DRM_PLANE_TYPE_PRIMARY:
 +              return 0;
 +      case DRM_PLANE_TYPE_CURSOR:
 +              return PLANE_CURSOR;
 +      case DRM_PLANE_TYPE_OVERLAY:
 +              return plane->plane + 1;
 +      default:
 +              MISSING_CASE(plane->base.type);
 +              return plane->plane;
 +      }
 +}
 +
  static void
  skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
 -                                 struct drm_crtc *for_crtc,
 +                                 const struct intel_crtc_state *cstate,
                                   const struct intel_wm_config *config,
 -                                 const struct skl_pipe_wm_parameters *params,
                                   struct skl_ddb_entry *alloc /* out */)
  {
 +      struct drm_crtc *for_crtc = cstate->base.crtc;
        struct drm_crtc *crtc;
        unsigned int pipe_size, ddb_size;
        int nth_active_pipe;
  
 -      if (!params->active) {
 +      if (!cstate->base.active) {
                alloc->start = 0;
                alloc->end = 0;
                return;
@@@ -2833,29 -2837,19 +2833,29 @@@ void skl_ddb_get_hw_state(struct drm_i9
  }
  
  static unsigned int
 -skl_plane_relative_data_rate(const struct intel_plane_wm_parameters *p, int y)
 +skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
 +                           const struct drm_plane_state *pstate,
 +                           int y)
  {
 +      struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
 +      struct drm_framebuffer *fb = pstate->fb;
  
        /* for planar format */
 -      if (p->y_bytes_per_pixel) {
 +      if (fb->pixel_format == DRM_FORMAT_NV12) {
                if (y)  /* y-plane data rate */
 -                      return p->horiz_pixels * p->vert_pixels * p->y_bytes_per_pixel;
 +                      return intel_crtc->config->pipe_src_w *
 +                              intel_crtc->config->pipe_src_h *
 +                              drm_format_plane_cpp(fb->pixel_format, 0);
                else    /* uv-plane data rate */
 -                      return (p->horiz_pixels/2) * (p->vert_pixels/2) * p->bytes_per_pixel;
 +                      return (intel_crtc->config->pipe_src_w/2) *
 +                              (intel_crtc->config->pipe_src_h/2) *
 +                              drm_format_plane_cpp(fb->pixel_format, 1);
        }
  
        /* for packed formats */
 -      return p->horiz_pixels * p->vert_pixels * p->bytes_per_pixel;
 +      return intel_crtc->config->pipe_src_w *
 +              intel_crtc->config->pipe_src_h *
 +              drm_format_plane_cpp(fb->pixel_format, 0);
  }
  
  /*
   *   3 * 4096 * 8192  * 4 < 2^32
   */
  static unsigned int
 -skl_get_total_relative_data_rate(struct intel_crtc *intel_crtc,
 -                               const struct skl_pipe_wm_parameters *params)
 +skl_get_total_relative_data_rate(const struct intel_crtc_state *cstate)
  {
 +      struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
 +      struct drm_device *dev = intel_crtc->base.dev;
 +      const struct intel_plane *intel_plane;
        unsigned int total_data_rate = 0;
 -      int plane;
  
 -      for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) {
 -              const struct intel_plane_wm_parameters *p;
 +      for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
 +              const struct drm_plane_state *pstate = intel_plane->base.state;
  
 -              p = &params->plane[plane];
 -              if (!p->enabled)
 +              if (pstate->fb == NULL)
                        continue;
  
 -              total_data_rate += skl_plane_relative_data_rate(p, 0); /* packed/uv */
 -              if (p->y_bytes_per_pixel) {
 -                      total_data_rate += skl_plane_relative_data_rate(p, 1); /* y-plane */
 -              }
 +              if (intel_plane->base.type == DRM_PLANE_TYPE_CURSOR)
 +                      continue;
 +
 +              /* packed/uv */
 +              total_data_rate += skl_plane_relative_data_rate(cstate,
 +                                                              pstate,
 +                                                              0);
 +
 +              if (pstate->fb->pixel_format == DRM_FORMAT_NV12)
 +                      /* y-plane */
 +                      total_data_rate += skl_plane_relative_data_rate(cstate,
 +                                                                      pstate,
 +                                                                      1);
        }
  
        return total_data_rate;
  }
  
  static void
 -skl_allocate_pipe_ddb(struct drm_crtc *crtc,
 -                    const struct intel_wm_config *config,
 -                    const struct skl_pipe_wm_parameters *params,
 +skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
                      struct skl_ddb_allocation *ddb /* out */)
  {
 +      struct drm_crtc *crtc = cstate->base.crtc;
        struct drm_device *dev = crtc->dev;
 -      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct drm_i915_private *dev_priv = to_i915(dev);
 +      struct intel_wm_config *config = &dev_priv->wm.config;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 +      struct intel_plane *intel_plane;
        enum pipe pipe = intel_crtc->pipe;
        struct skl_ddb_entry *alloc = &ddb->pipe[pipe];
        uint16_t alloc_size, start, cursor_blocks;
        uint16_t minimum[I915_MAX_PLANES];
        uint16_t y_minimum[I915_MAX_PLANES];
        unsigned int total_data_rate;
 -      int plane;
  
 -      skl_ddb_get_pipe_allocation_limits(dev, crtc, config, params, alloc);
 +      skl_ddb_get_pipe_allocation_limits(dev, cstate, config, alloc);
        alloc_size = skl_ddb_entry_size(alloc);
        if (alloc_size == 0) {
                memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
        alloc->end -= cursor_blocks;
  
        /* 1. Allocate the mininum required blocks for each active plane */
 -      for_each_plane(dev_priv, pipe, plane) {
 -              const struct intel_plane_wm_parameters *p;
 +      for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
 +              struct drm_plane *plane = &intel_plane->base;
 +              struct drm_framebuffer *fb = plane->state->fb;
 +              int id = skl_wm_plane_id(intel_plane);
  
 -              p = &params->plane[plane];
 -              if (!p->enabled)
 +              if (fb == NULL)
 +                      continue;
 +              if (plane->type == DRM_PLANE_TYPE_CURSOR)
                        continue;
  
 -              minimum[plane] = 8;
 -              alloc_size -= minimum[plane];
 -              y_minimum[plane] = p->y_bytes_per_pixel ? 8 : 0;
 -              alloc_size -= y_minimum[plane];
 +              minimum[id] = 8;
 +              alloc_size -= minimum[id];
 +              y_minimum[id] = (fb->pixel_format == DRM_FORMAT_NV12) ? 8 : 0;
 +              alloc_size -= y_minimum[id];
        }
  
        /*
         *
         * FIXME: we may not allocate every single block here.
         */
 -      total_data_rate = skl_get_total_relative_data_rate(intel_crtc, params);
 +      total_data_rate = skl_get_total_relative_data_rate(cstate);
  
        start = alloc->start;
 -      for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) {
 -              const struct intel_plane_wm_parameters *p;
 +      for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
 +              struct drm_plane *plane = &intel_plane->base;
 +              struct drm_plane_state *pstate = intel_plane->base.state;
                unsigned int data_rate, y_data_rate;
                uint16_t plane_blocks, y_plane_blocks = 0;
 +              int id = skl_wm_plane_id(intel_plane);
  
 -              p = &params->plane[plane];
 -              if (!p->enabled)
 +              if (pstate->fb == NULL)
 +                      continue;
 +              if (plane->type == DRM_PLANE_TYPE_CURSOR)
                        continue;
  
 -              data_rate = skl_plane_relative_data_rate(p, 0);
 +              data_rate = skl_plane_relative_data_rate(cstate, pstate, 0);
  
                /*
                 * allocation for (packed formats) or (uv-plane part of planar format):
                 * promote the expression to 64 bits to avoid overflowing, the
                 * result is < available as data_rate / total_data_rate < 1
                 */
 -              plane_blocks = minimum[plane];
 +              plane_blocks = minimum[id];
                plane_blocks += div_u64((uint64_t)alloc_size * data_rate,
                                        total_data_rate);
  
 -              ddb->plane[pipe][plane].start = start;
 -              ddb->plane[pipe][plane].end = start + plane_blocks;
 +              ddb->plane[pipe][id].start = start;
 +              ddb->plane[pipe][id].end = start + plane_blocks;
  
                start += plane_blocks;
  
                /*
                 * allocation for y_plane part of planar format:
                 */
 -              if (p->y_bytes_per_pixel) {
 -                      y_data_rate = skl_plane_relative_data_rate(p, 1);
 -                      y_plane_blocks = y_minimum[plane];
 +              if (pstate->fb->pixel_format == DRM_FORMAT_NV12) {
 +                      y_data_rate = skl_plane_relative_data_rate(cstate,
 +                                                                 pstate,
 +                                                                 1);
 +                      y_plane_blocks = y_minimum[id];
                        y_plane_blocks += div_u64((uint64_t)alloc_size * y_data_rate,
                                                total_data_rate);
  
 -                      ddb->y_plane[pipe][plane].start = start;
 -                      ddb->y_plane[pipe][plane].end = start + y_plane_blocks;
 +                      ddb->y_plane[pipe][id].start = start;
 +                      ddb->y_plane[pipe][id].end = start + y_plane_blocks;
  
                        start += y_plane_blocks;
                }
@@@ -3064,27 -3041,104 +3064,27 @@@ static bool skl_ddb_allocation_changed(
        struct drm_device *dev = intel_crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        const struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb;
 -      enum pipe pipe = intel_crtc->pipe;
 -
 -      if (memcmp(new_ddb->plane[pipe], cur_ddb->plane[pipe],
 -                 sizeof(new_ddb->plane[pipe])))
 -              return true;
  
 -      if (memcmp(&new_ddb->plane[pipe][PLANE_CURSOR], &cur_ddb->plane[pipe][PLANE_CURSOR],
 -                  sizeof(new_ddb->plane[pipe][PLANE_CURSOR])))
 +      /*
 +       * If ddb allocation of pipes changed, it may require recalculation of
 +       * watermarks
 +       */
 +      if (memcmp(new_ddb->pipe, cur_ddb->pipe, sizeof(new_ddb->pipe)))
                return true;
  
        return false;
  }
  
 -static void skl_compute_wm_global_parameters(struct drm_device *dev,
 -                                           struct intel_wm_config *config)
 -{
 -      struct drm_crtc *crtc;
 -      struct drm_plane *plane;
 -
 -      list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
 -              config->num_pipes_active += to_intel_crtc(crtc)->active;
 -
 -      /* FIXME: I don't think we need those two global parameters on SKL */
 -      list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
 -              struct intel_plane *intel_plane = to_intel_plane(plane);
 -
 -              config->sprites_enabled |= intel_plane->wm.enabled;
 -              config->sprites_scaled |= intel_plane->wm.scaled;
 -      }
 -}
 -
 -static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc,
 -                                         struct skl_pipe_wm_parameters *p)
 -{
 -      struct drm_device *dev = crtc->dev;
 -      struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 -      enum pipe pipe = intel_crtc->pipe;
 -      struct drm_plane *plane;
 -      struct drm_framebuffer *fb;
 -      int i = 1; /* Index for sprite planes start */
 -
 -      p->active = intel_crtc->active;
 -      if (p->active) {
 -              p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal;
 -              p->pixel_rate = skl_pipe_pixel_rate(intel_crtc->config);
 -
 -              fb = crtc->primary->state->fb;
 -              /* For planar: Bpp is for uv plane, y_Bpp is for y plane */
 -              if (fb) {
 -                      p->plane[0].enabled = true;
 -                      p->plane[0].bytes_per_pixel = fb->pixel_format == DRM_FORMAT_NV12 ?
 -                              drm_format_plane_cpp(fb->pixel_format, 1) :
 -                              drm_format_plane_cpp(fb->pixel_format, 0);
 -                      p->plane[0].y_bytes_per_pixel = fb->pixel_format == DRM_FORMAT_NV12 ?
 -                              drm_format_plane_cpp(fb->pixel_format, 0) : 0;
 -                      p->plane[0].tiling = fb->modifier[0];
 -              } else {
 -                      p->plane[0].enabled = false;
 -                      p->plane[0].bytes_per_pixel = 0;
 -                      p->plane[0].y_bytes_per_pixel = 0;
 -                      p->plane[0].tiling = DRM_FORMAT_MOD_NONE;
 -              }
 -              p->plane[0].horiz_pixels = intel_crtc->config->pipe_src_w;
 -              p->plane[0].vert_pixels = intel_crtc->config->pipe_src_h;
 -              p->plane[0].rotation = crtc->primary->state->rotation;
 -
 -              fb = crtc->cursor->state->fb;
 -              p->plane[PLANE_CURSOR].y_bytes_per_pixel = 0;
 -              if (fb) {
 -                      p->plane[PLANE_CURSOR].enabled = true;
 -                      p->plane[PLANE_CURSOR].bytes_per_pixel = fb->bits_per_pixel / 8;
 -                      p->plane[PLANE_CURSOR].horiz_pixels = crtc->cursor->state->crtc_w;
 -                      p->plane[PLANE_CURSOR].vert_pixels = crtc->cursor->state->crtc_h;
 -              } else {
 -                      p->plane[PLANE_CURSOR].enabled = false;
 -                      p->plane[PLANE_CURSOR].bytes_per_pixel = 0;
 -                      p->plane[PLANE_CURSOR].horiz_pixels = 64;
 -                      p->plane[PLANE_CURSOR].vert_pixels = 64;
 -              }
 -      }
 -
 -      list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
 -              struct intel_plane *intel_plane = to_intel_plane(plane);
 -
 -              if (intel_plane->pipe == pipe &&
 -                      plane->type == DRM_PLANE_TYPE_OVERLAY)
 -                      p->plane[i++] = intel_plane->wm;
 -      }
 -}
 -
  static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 -                               struct skl_pipe_wm_parameters *p,
 -                               struct intel_plane_wm_parameters *p_params,
 +                               struct intel_crtc_state *cstate,
 +                               struct intel_plane *intel_plane,
                                 uint16_t ddb_allocation,
                                 int level,
                                 uint16_t *out_blocks, /* out */
                                 uint8_t *out_lines /* out */)
  {
 +      struct drm_plane *plane = &intel_plane->base;
 +      struct drm_framebuffer *fb = plane->state->fb;
        uint32_t latency = dev_priv->wm.skl_latency[level];
        uint32_t method1, method2;
        uint32_t plane_bytes_per_line, plane_blocks_per_line;
        uint32_t selected_result;
        uint8_t bytes_per_pixel;
  
 -      if (latency == 0 || !p->active || !p_params->enabled)
 +      if (latency == 0 || !cstate->base.active || !fb)
                return false;
  
 -      bytes_per_pixel = p_params->y_bytes_per_pixel ?
 -              p_params->y_bytes_per_pixel :
 -              p_params->bytes_per_pixel;
 -      method1 = skl_wm_method1(p->pixel_rate,
 +      bytes_per_pixel = drm_format_plane_cpp(fb->pixel_format, 0);
 +      method1 = skl_wm_method1(skl_pipe_pixel_rate(cstate),
                                 bytes_per_pixel,
                                 latency);
 -      method2 = skl_wm_method2(p->pixel_rate,
 -                               p->pipe_htotal,
 -                               p_params->horiz_pixels,
 +      method2 = skl_wm_method2(skl_pipe_pixel_rate(cstate),
 +                               cstate->base.adjusted_mode.crtc_htotal,
 +                               cstate->pipe_src_w,
                                 bytes_per_pixel,
 -                               p_params->tiling,
 +                               fb->modifier[0],
                                 latency);
  
 -      plane_bytes_per_line = p_params->horiz_pixels * bytes_per_pixel;
 +      plane_bytes_per_line = cstate->pipe_src_w * bytes_per_pixel;
        plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
  
 -      if (p_params->tiling == I915_FORMAT_MOD_Y_TILED ||
 -          p_params->tiling == I915_FORMAT_MOD_Yf_TILED) {
 +      if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
 +          fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
                uint32_t min_scanlines = 4;
                uint32_t y_tile_minimum;
 -              if (intel_rotation_90_or_270(p_params->rotation)) {
 -                      switch (p_params->bytes_per_pixel) {
 +              if (intel_rotation_90_or_270(plane->state->rotation)) {
 +                      int bpp = (fb->pixel_format == DRM_FORMAT_NV12) ?
 +                              drm_format_plane_cpp(fb->pixel_format, 1) :
 +                              drm_format_plane_cpp(fb->pixel_format, 0);
 +
 +                      switch (bpp) {
                        case 1:
                                min_scanlines = 16;
                                break;
        res_lines = DIV_ROUND_UP(selected_result, plane_blocks_per_line);
  
        if (level >= 1 && level <= 7) {
 -              if (p_params->tiling == I915_FORMAT_MOD_Y_TILED ||
 -                  p_params->tiling == I915_FORMAT_MOD_Yf_TILED)
 +              if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
 +                  fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED)
                        res_lines += 4;
                else
                        res_blocks++;
  
  static void skl_compute_wm_level(const struct drm_i915_private *dev_priv,
                                 struct skl_ddb_allocation *ddb,
 -                               struct skl_pipe_wm_parameters *p,
 -                               enum pipe pipe,
 +                               struct intel_crtc_state *cstate,
                                 int level,
 -                               int num_planes,
                                 struct skl_wm_level *result)
  {
 +      struct drm_device *dev = dev_priv->dev;
 +      struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
 +      struct intel_plane *intel_plane;
        uint16_t ddb_blocks;
 -      int i;
 +      enum pipe pipe = intel_crtc->pipe;
 +
 +      for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
 +              int i = skl_wm_plane_id(intel_plane);
  
 -      for (i = 0; i < num_planes; i++) {
                ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]);
  
                result->plane_en[i] = skl_compute_plane_wm(dev_priv,
 -                                              p, &p->plane[i],
 +                                              cstate,
 +                                              intel_plane,
                                                ddb_blocks,
                                                level,
                                                &result->plane_res_b[i],
                                                &result->plane_res_l[i]);
        }
 -
 -      ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][PLANE_CURSOR]);
 -      result->plane_en[PLANE_CURSOR] = skl_compute_plane_wm(dev_priv, p,
 -                                               &p->plane[PLANE_CURSOR],
 -                                               ddb_blocks, level,
 -                                               &result->plane_res_b[PLANE_CURSOR],
 -                                               &result->plane_res_l[PLANE_CURSOR]);
  }
  
  static uint32_t
 -skl_compute_linetime_wm(struct drm_crtc *crtc, struct skl_pipe_wm_parameters *p)
 +skl_compute_linetime_wm(struct intel_crtc_state *cstate)
  {
 -      if (!to_intel_crtc(crtc)->active)
 +      if (!cstate->base.active)
                return 0;
  
 -      if (WARN_ON(p->pixel_rate == 0))
 +      if (WARN_ON(skl_pipe_pixel_rate(cstate) == 0))
                return 0;
  
 -      return DIV_ROUND_UP(8 * p->pipe_htotal * 1000, p->pixel_rate);
 +      return DIV_ROUND_UP(8 * cstate->base.adjusted_mode.crtc_htotal * 1000,
 +                          skl_pipe_pixel_rate(cstate));
  }
  
 -static void skl_compute_transition_wm(struct drm_crtc *crtc,
 -                                    struct skl_pipe_wm_parameters *params,
 +static void skl_compute_transition_wm(struct intel_crtc_state *cstate,
                                      struct skl_wm_level *trans_wm /* out */)
  {
 +      struct drm_crtc *crtc = cstate->base.crtc;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 -      int i;
 +      struct intel_plane *intel_plane;
  
 -      if (!params->active)
 +      if (!cstate->base.active)
                return;
  
        /* Until we know more, just disable transition WMs */
 -      for (i = 0; i < intel_num_planes(intel_crtc); i++)
 +      for_each_intel_plane_on_crtc(crtc->dev, intel_crtc, intel_plane) {
 +              int i = skl_wm_plane_id(intel_plane);
 +
                trans_wm->plane_en[i] = false;
 -      trans_wm->plane_en[PLANE_CURSOR] = false;
 +      }
  }
  
 -static void skl_compute_pipe_wm(struct drm_crtc *crtc,
 +static void skl_compute_pipe_wm(struct intel_crtc_state *cstate,
                                struct skl_ddb_allocation *ddb,
 -                              struct skl_pipe_wm_parameters *params,
                                struct skl_pipe_wm *pipe_wm)
  {
 -      struct drm_device *dev = crtc->dev;
 +      struct drm_device *dev = cstate->base.crtc->dev;
        const struct drm_i915_private *dev_priv = dev->dev_private;
 -      struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        int level, max_level = ilk_wm_max_level(dev);
  
        for (level = 0; level <= max_level; level++) {
 -              skl_compute_wm_level(dev_priv, ddb, params, intel_crtc->pipe,
 -                                   level, intel_num_planes(intel_crtc),
 -                                   &pipe_wm->wm[level]);
 +              skl_compute_wm_level(dev_priv, ddb, cstate,
 +                                   level, &pipe_wm->wm[level]);
        }
 -      pipe_wm->linetime = skl_compute_linetime_wm(crtc, params);
 +      pipe_wm->linetime = skl_compute_linetime_wm(cstate);
  
 -      skl_compute_transition_wm(crtc, params, &pipe_wm->trans_wm);
 +      skl_compute_transition_wm(cstate, &pipe_wm->trans_wm);
  }
  
  static void skl_compute_wm_results(struct drm_device *dev,
 -                                 struct skl_pipe_wm_parameters *p,
                                   struct skl_pipe_wm *p_wm,
                                   struct skl_wm_values *r,
                                   struct intel_crtc *intel_crtc)
        r->wm_linetime[pipe] = p_wm->linetime;
  }
  
 -static void skl_ddb_entry_write(struct drm_i915_private *dev_priv, uint32_t reg,
 +static void skl_ddb_entry_write(struct drm_i915_private *dev_priv,
 +                              i915_reg_t reg,
                                const struct skl_ddb_entry *entry)
  {
        if (entry->end)
@@@ -3478,25 -3533,28 +3478,25 @@@ static void skl_flush_wm_values(struct 
  }
  
  static bool skl_update_pipe_wm(struct drm_crtc *crtc,
 -                             struct skl_pipe_wm_parameters *params,
 -                             struct intel_wm_config *config,
                               struct skl_ddb_allocation *ddb, /* out */
                               struct skl_pipe_wm *pipe_wm /* out */)
  {
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 +      struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
  
 -      skl_compute_wm_pipe_parameters(crtc, params);
 -      skl_allocate_pipe_ddb(crtc, config, params, ddb);
 -      skl_compute_pipe_wm(crtc, ddb, params, pipe_wm);
 +      skl_allocate_pipe_ddb(cstate, ddb);
 +      skl_compute_pipe_wm(cstate, ddb, pipe_wm);
  
 -      if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm)))
 +      if (!memcmp(&intel_crtc->wm.active.skl, pipe_wm, sizeof(*pipe_wm)))
                return false;
  
 -      intel_crtc->wm.skl_active = *pipe_wm;
 +      intel_crtc->wm.active.skl = *pipe_wm;
  
        return true;
  }
  
  static void skl_update_other_pipe_wm(struct drm_device *dev,
                                     struct drm_crtc *crtc,
 -                                   struct intel_wm_config *config,
                                     struct skl_wm_values *r)
  {
        struct intel_crtc *intel_crtc;
         */
        list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list,
                                base.head) {
 -              struct skl_pipe_wm_parameters params = {};
                struct skl_pipe_wm pipe_wm = {};
                bool wm_changed;
  
                        continue;
  
                wm_changed = skl_update_pipe_wm(&intel_crtc->base,
 -                                              &params, config,
                                                &r->ddb, &pipe_wm);
  
                /*
                 */
                WARN_ON(!wm_changed);
  
 -              skl_compute_wm_results(dev, &params, &pipe_wm, r, intel_crtc);
 +              skl_compute_wm_results(dev, &pipe_wm, r, intel_crtc);
                r->dirty[intel_crtc->pipe] = true;
        }
  }
@@@ -3566,9 -3626,10 +3566,9 @@@ static void skl_update_wm(struct drm_cr
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
 -      struct skl_pipe_wm_parameters params = {};
        struct skl_wm_values *results = &dev_priv->wm.skl_results;
 -      struct skl_pipe_wm pipe_wm = {};
 -      struct intel_wm_config config = {};
 +      struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
 +      struct skl_pipe_wm *pipe_wm = &cstate->wm.optimal.skl;
  
  
        /* Clear all dirty flags */
  
        skl_clear_wm(results, intel_crtc->pipe);
  
 -      skl_compute_wm_global_parameters(dev, &config);
 -
 -      if (!skl_update_pipe_wm(crtc, &params, &config,
 -                              &results->ddb, &pipe_wm))
 +      if (!skl_update_pipe_wm(crtc, &results->ddb, pipe_wm))
                return;
  
 -      skl_compute_wm_results(dev, &params, &pipe_wm, results, intel_crtc);
 +      skl_compute_wm_results(dev, pipe_wm, results, intel_crtc);
        results->dirty[intel_crtc->pipe] = true;
  
 -      skl_update_other_pipe_wm(dev, crtc, &config, results);
 +      skl_update_other_pipe_wm(dev, crtc, results);
        skl_write_wm_values(dev_priv, results);
        skl_flush_wm_values(dev_priv, results);
  
        dev_priv->wm.skl_hw = *results;
  }
  
 -static void
 -skl_update_sprite_wm(struct drm_plane *plane, struct drm_crtc *crtc,
 -                   uint32_t sprite_width, uint32_t sprite_height,
 -                   int pixel_size, bool enabled, bool scaled)
 +static void ilk_program_watermarks(struct drm_i915_private *dev_priv)
  {
 -      struct intel_plane *intel_plane = to_intel_plane(plane);
 -      struct drm_framebuffer *fb = plane->state->fb;
 -
 -      intel_plane->wm.enabled = enabled;
 -      intel_plane->wm.scaled = scaled;
 -      intel_plane->wm.horiz_pixels = sprite_width;
 -      intel_plane->wm.vert_pixels = sprite_height;
 -      intel_plane->wm.tiling = DRM_FORMAT_MOD_NONE;
 -
 -      /* For planar: Bpp is for UV plane, y_Bpp is for Y plane */
 -      intel_plane->wm.bytes_per_pixel =
 -              (fb && fb->pixel_format == DRM_FORMAT_NV12) ?
 -              drm_format_plane_cpp(plane->state->fb->pixel_format, 1) : pixel_size;
 -      intel_plane->wm.y_bytes_per_pixel =
 -              (fb && fb->pixel_format == DRM_FORMAT_NV12) ?
 -              drm_format_plane_cpp(plane->state->fb->pixel_format, 0) : 0;
 -
 -      /*
 -       * Framebuffer can be NULL on plane disable, but it does not
 -       * matter for watermarks if we assume no tiling in that case.
 -       */
 -      if (fb)
 -              intel_plane->wm.tiling = fb->modifier[0];
 -      intel_plane->wm.rotation = plane->state->rotation;
 -
 -      skl_update_wm(crtc);
 -}
 -
 -static void ilk_update_wm(struct drm_crtc *crtc)
 -{
 -      struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 -      struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
 -      struct drm_device *dev = crtc->dev;
 -      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct drm_device *dev = dev_priv->dev;
 +      struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm;
        struct ilk_wm_maximums max;
 +      struct intel_wm_config *config = &dev_priv->wm.config;
        struct ilk_wm_values results = {};
        enum intel_ddb_partitioning partitioning;
 -      struct intel_pipe_wm pipe_wm = {};
 -      struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm;
 -      struct intel_wm_config config = {};
 -
 -      WARN_ON(cstate->base.active != intel_crtc->active);
  
 -      intel_compute_pipe_wm(cstate, &pipe_wm);
 -
 -      if (!memcmp(&intel_crtc->wm.active, &pipe_wm, sizeof(pipe_wm)))
 -              return;
 -
 -      intel_crtc->wm.active = pipe_wm;
 -
 -      ilk_compute_wm_config(dev, &config);
 -
 -      ilk_compute_wm_maximums(dev, 1, &config, INTEL_DDB_PART_1_2, &max);
 -      ilk_wm_merge(dev, &config, &max, &lp_wm_1_2);
 +      ilk_compute_wm_maximums(dev, 1, config, INTEL_DDB_PART_1_2, &max);
 +      ilk_wm_merge(dev, config, &max, &lp_wm_1_2);
  
        /* 5/6 split only in single pipe config on IVB+ */
        if (INTEL_INFO(dev)->gen >= 7 &&
 -          config.num_pipes_active == 1 && config.sprites_enabled) {
 -              ilk_compute_wm_maximums(dev, 1, &config, INTEL_DDB_PART_5_6, &max);
 -              ilk_wm_merge(dev, &config, &max, &lp_wm_5_6);
 +          config->num_pipes_active == 1 && config->sprites_enabled) {
 +              ilk_compute_wm_maximums(dev, 1, config, INTEL_DDB_PART_5_6, &max);
 +              ilk_wm_merge(dev, config, &max, &lp_wm_5_6);
  
                best_lp_wm = ilk_find_best_result(dev, &lp_wm_1_2, &lp_wm_5_6);
        } else {
        ilk_write_wm_values(dev_priv, &results);
  }
  
 -static void
 -ilk_update_sprite_wm(struct drm_plane *plane,
 -                   struct drm_crtc *crtc,
 -                   uint32_t sprite_width, uint32_t sprite_height,
 -                   int pixel_size, bool enabled, bool scaled)
 +static void ilk_update_wm(struct drm_crtc *crtc)
  {
 -      struct drm_device *dev = plane->dev;
 -      struct intel_plane *intel_plane = to_intel_plane(plane);
 +      struct drm_i915_private *dev_priv = to_i915(crtc->dev);
 +      struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 +      struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
 +
 +      WARN_ON(cstate->base.active != intel_crtc->active);
  
        /*
         * IVB workaround: must disable low power watermarks for at least
         *
         * WaCxSRDisabledForSpriteScaling:ivb
         */
 -      if (IS_IVYBRIDGE(dev) && scaled && ilk_disable_lp_wm(dev))
 -              intel_wait_for_vblank(dev, intel_plane->pipe);
 +      if (cstate->disable_lp_wm) {
 +              ilk_disable_lp_wm(crtc->dev);
 +              intel_wait_for_vblank(crtc->dev, intel_crtc->pipe);
 +      }
  
 -      ilk_update_wm(crtc);
 +      intel_crtc->wm.active.ilk = cstate->wm.optimal.ilk;
 +
 +      ilk_program_watermarks(dev_priv);
  }
  
  static void skl_pipe_wm_active_state(uint32_t val,
@@@ -3696,8 -3805,7 +3696,8 @@@ static void skl_pipe_wm_get_hw_state(st
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct skl_wm_values *hw = &dev_priv->wm.skl_hw;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 -      struct skl_pipe_wm *active = &intel_crtc->wm.skl_active;
 +      struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
 +      struct skl_pipe_wm *active = &cstate->wm.optimal.skl;
        enum pipe pipe = intel_crtc->pipe;
        int level, i, max_level;
        uint32_t temp;
  
        temp = hw->plane_trans[pipe][PLANE_CURSOR];
        skl_pipe_wm_active_state(temp, active, true, true, i, 0);
 +
 +      intel_crtc->wm.active.skl = *active;
  }
  
  void skl_wm_get_hw_state(struct drm_device *dev)
@@@ -3762,10 -3868,9 +3762,10 @@@ static void ilk_pipe_wm_get_hw_state(st
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct ilk_wm_values *hw = &dev_priv->wm.hw;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 -      struct intel_pipe_wm *active = &intel_crtc->wm.active;
 +      struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
 +      struct intel_pipe_wm *active = &cstate->wm.optimal.ilk;
        enum pipe pipe = intel_crtc->pipe;
 -      static const unsigned int wm0_pipe_reg[] = {
 +      static const i915_reg_t wm0_pipe_reg[] = {
                [PIPE_A] = WM0_PIPEA_ILK,
                [PIPE_B] = WM0_PIPEB_ILK,
                [PIPE_C] = WM0_PIPEC_IVB,
                for (level = 0; level <= max_level; level++)
                        active->wm[level].enable = true;
        }
 +
 +      intel_crtc->wm.active.ilk = *active;
  }
  
  #define _FW_WM(value, plane) \
@@@ -4029,6 -4132,21 +4029,6 @@@ void intel_update_watermarks(struct drm
                dev_priv->display.update_wm(crtc);
  }
  
 -void intel_update_sprite_watermarks(struct drm_plane *plane,
 -                                  struct drm_crtc *crtc,
 -                                  uint32_t sprite_width,
 -                                  uint32_t sprite_height,
 -                                  int pixel_size,
 -                                  bool enabled, bool scaled)
 -{
 -      struct drm_i915_private *dev_priv = plane->dev->dev_private;
 -
 -      if (dev_priv->display.update_sprite_wm)
 -              dev_priv->display.update_sprite_wm(plane, crtc,
 -                                                 sprite_width, sprite_height,
 -                                                 pixel_size, enabled, scaled);
 -}
 -
  /**
   * Lock protecting IPS related data structures
   */
@@@ -4296,7 -4414,7 +4296,7 @@@ static void gen6_set_rps(struct drm_dev
        struct drm_i915_private *dev_priv = dev->dev_private;
  
        /* WaGsvDisableTurbo: Workaround to disable turbo on BXT A* */
 -      if (IS_BROXTON(dev) && (INTEL_REVID(dev) < BXT_REVID_B0))
 +      if (IS_BXT_REVID(dev, 0, BXT_REVID_A1))
                return;
  
        WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
@@@ -4571,8 -4689,7 +4571,8 @@@ static void gen6_init_rps_frequencies(s
        dev_priv->rps.max_freq          = dev_priv->rps.rp0_freq;
  
        dev_priv->rps.efficient_freq = dev_priv->rps.rp1_freq;
 -      if (IS_HASWELL(dev) || IS_BROADWELL(dev) || IS_SKYLAKE(dev)) {
 +      if (IS_HASWELL(dev) || IS_BROADWELL(dev) ||
 +          IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
                ret = sandybridge_pcode_read(dev_priv,
                                        HSW_PCODE_DYNAMIC_DUTY_CYCLE_CONTROL,
                                        &ddcc_status);
                                        dev_priv->rps.max_freq);
        }
  
 -      if (IS_SKYLAKE(dev)) {
 +      if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
                /* Store the frequency values in 16.66 MHZ units, which is
                   the natural hardware unit for SKL */
                dev_priv->rps.rp0_freq *= GEN9_FREQ_SCALER;
@@@ -4621,7 -4738,7 +4621,7 @@@ static void gen9_enable_rps(struct drm_
        gen6_init_rps_frequencies(dev);
  
        /* WaGsvDisableTurbo: Workaround to disable turbo on BXT A* */
 -      if (IS_BROXTON(dev) && (INTEL_REVID(dev) < BXT_REVID_B0)) {
 +      if (IS_BXT_REVID(dev, 0, BXT_REVID_A1)) {
                intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
                return;
        }
@@@ -4665,8 -4782,7 +4665,7 @@@ static void gen9_enable_rc6(struct drm_
        /* 2b: Program RC6 thresholds.*/
  
        /* WaRsDoubleRc6WrlWithCoarsePowerGating: Doubling WRL only when CPG is enabled */
-       if (IS_SKYLAKE(dev) && !((IS_SKL_GT3(dev) || IS_SKL_GT4(dev)) &&
-                                IS_SKL_REVID(dev, 0, SKL_REVID_E0)))
+       if (IS_SKYLAKE(dev))
                I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 108 << 16);
        else
                I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16);
        DRM_INFO("RC6 %s\n", (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ?
                        "on" : "off");
        /* WaRsUseTimeoutMode */
 -      if ((IS_SKYLAKE(dev) && INTEL_REVID(dev) <= SKL_REVID_D0) ||
 -          (IS_BROXTON(dev) && INTEL_REVID(dev) <= BXT_REVID_A0)) {
 +      if (IS_SKL_REVID(dev, 0, SKL_REVID_D0) ||
 +          IS_BXT_REVID(dev, 0, BXT_REVID_A1)) {
                I915_WRITE(GEN6_RC6_THRESHOLD, 625); /* 800us */
                I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
                           GEN7_RC_CTL_TO_MODE |
         * 3b: Enable Coarse Power Gating only when RC6 is enabled.
         * WaRsDisableCoarsePowerGating:skl,bxt - Render/Media PG need to be disabled with RC6.
         */
-       if (IS_BXT_REVID(dev, 0, BXT_REVID_A1) ||
-           ((IS_SKL_GT3(dev) || IS_SKL_GT4(dev)) &&
-            IS_SKL_REVID(dev, 0, SKL_REVID_E0)))
+       if ((IS_BROXTON(dev) && (INTEL_REVID(dev) < BXT_REVID_B0)) ||
+           ((IS_SKL_GT3(dev) || IS_SKL_GT4(dev)) && (INTEL_REVID(dev) <= SKL_REVID_F0)))
                I915_WRITE(GEN9_PG_ENABLE, 0);
        else
                I915_WRITE(GEN9_PG_ENABLE, (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ?
@@@ -4940,7 -5055,7 +4938,7 @@@ static void __gen6_update_ring_freq(str
        /* convert DDR frequency from units of 266.6MHz to bandwidth */
        min_ring_freq = mult_frac(min_ring_freq, 8, 3);
  
 -      if (IS_SKYLAKE(dev)) {
 +      if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
                /* Convert GT frequency to 50 HZ units */
                min_gpu_freq = dev_priv->rps.min_freq / GEN9_FREQ_SCALER;
                max_gpu_freq = dev_priv->rps.max_freq / GEN9_FREQ_SCALER;
                int diff = max_gpu_freq - gpu_freq;
                unsigned int ia_freq = 0, ring_freq = 0;
  
 -              if (IS_SKYLAKE(dev)) {
 +              if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
                        /*
                         * ring_freq = 2 * GT. ring_freq is in 100MHz units
                         * No floor required for ring frequency on SKL.
@@@ -6086,7 -6201,7 +6084,7 @@@ static void intel_gen6_powersave_work(s
        } else if (INTEL_INFO(dev)->gen >= 9) {
                gen9_enable_rc6(dev);
                gen9_enable_rps(dev);
 -              if (IS_SKYLAKE(dev))
 +              if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
                        __gen6_update_ring_freq(dev);
        } else if (IS_BROADWELL(dev)) {
                gen8_enable_rps(dev);
@@@ -6942,6 -7057,7 +6940,6 @@@ void intel_init_pm(struct drm_device *d
                        dev_priv->display.init_clock_gating =
                                bxt_init_clock_gating;
                dev_priv->display.update_wm = skl_update_wm;
 -              dev_priv->display.update_sprite_wm = skl_update_sprite_wm;
        } else if (HAS_PCH_SPLIT(dev)) {
                ilk_setup_wm_latency(dev);
  
                    (!IS_GEN5(dev) && dev_priv->wm.pri_latency[0] &&
                     dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) {
                        dev_priv->display.update_wm = ilk_update_wm;
 -                      dev_priv->display.update_sprite_wm = ilk_update_sprite_wm;
 +                      dev_priv->display.compute_pipe_wm = ilk_compute_pipe_wm;
                } else {
                        DRM_DEBUG_KMS("Failed to read display plane latency. "
                                      "Disable CxSR\n");
index e38db35132ed0bbc00603041dbd51d12eaa769df,9b4bb9e74d7300793f3ecb1c0feef42085780819..27652b08c2e449f662632e4a6a54f74e4aeea7a8
@@@ -133,13 -133,19 +133,19 @@@ void vmw_cursor_update_position(struct 
        vmw_mmio_write(++count, fifo_mem + SVGA_FIFO_CURSOR_COUNT);
  }
  
- int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
-                          uint32_t handle, uint32_t width, uint32_t height)
+ /*
+  * vmw_du_crtc_cursor_set2 - Driver cursor_set2 callback.
+  */
+ int vmw_du_crtc_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv,
+                           uint32_t handle, uint32_t width, uint32_t height,
+                           int32_t hot_x, int32_t hot_y)
  {
        struct vmw_private *dev_priv = vmw_priv(crtc->dev);
        struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
        struct vmw_surface *surface = NULL;
        struct vmw_dma_buffer *dmabuf = NULL;
+       s32 hotspot_x, hotspot_y;
        int ret;
  
        /*
         */
        drm_modeset_unlock_crtc(crtc);
        drm_modeset_lock_all(dev_priv->dev);
+       hotspot_x = hot_x + du->hotspot_x;
+       hotspot_y = hot_y + du->hotspot_y;
  
        /* A lot of the code assumes this */
        if (handle && (width != 64 || height != 64)) {
                vmw_dmabuf_unreference(&du->cursor_dmabuf);
  
        /* setup new image */
+       ret = 0;
        if (surface) {
                /* vmw_user_surface_lookup takes one reference */
                du->cursor_surface = surface;
  
                du->cursor_surface->snooper.crtc = crtc;
                du->cursor_age = du->cursor_surface->snooper.age;
-               vmw_cursor_update_image(dev_priv, surface->snooper.image,
-                                       64, 64, du->hotspot_x, du->hotspot_y);
+               ret = vmw_cursor_update_image(dev_priv, surface->snooper.image,
+                                             64, 64, hotspot_x, hotspot_y);
        } else if (dmabuf) {
                /* vmw_user_surface_lookup takes one reference */
                du->cursor_dmabuf = dmabuf;
  
                ret = vmw_cursor_update_dmabuf(dev_priv, dmabuf, width, height,
-                                              du->hotspot_x, du->hotspot_y);
+                                              hotspot_x, hotspot_y);
        } else {
                vmw_cursor_update_position(dev_priv, false, 0, 0);
-               ret = 0;
                goto out;
        }
  
-       vmw_cursor_update_position(dev_priv, true,
-                                  du->cursor_x + du->hotspot_x,
-                                  du->cursor_y + du->hotspot_y);
+       if (!ret) {
+               vmw_cursor_update_position(dev_priv, true,
+                                          du->cursor_x + hotspot_x,
+                                          du->cursor_y + hotspot_y);
+               du->core_hotspot_x = hot_x;
+               du->core_hotspot_y = hot_y;
+       }
  
-       ret = 0;
  out:
        drm_modeset_unlock_all(dev_priv->dev);
        drm_modeset_lock_crtc(crtc, crtc->cursor);
@@@ -239,8 -250,10 +250,10 @@@ int vmw_du_crtc_cursor_move(struct drm_
        drm_modeset_lock_all(dev_priv->dev);
  
        vmw_cursor_update_position(dev_priv, shown,
-                                  du->cursor_x + du->hotspot_x,
-                                  du->cursor_y + du->hotspot_y);
+                                  du->cursor_x + du->hotspot_x +
+                                  du->core_hotspot_x,
+                                  du->cursor_y + du->hotspot_y +
+                                  du->core_hotspot_y);
  
        drm_modeset_unlock_all(dev_priv->dev);
        drm_modeset_lock_crtc(crtc, crtc->cursor);
@@@ -334,6 -347,29 +347,29 @@@ err_unreserve
        ttm_bo_unreserve(bo);
  }
  
+ /**
+  * vmw_kms_legacy_hotspot_clear - Clear legacy hotspots
+  *
+  * @dev_priv: Pointer to the device private struct.
+  *
+  * Clears all legacy hotspots.
+  */
+ void vmw_kms_legacy_hotspot_clear(struct vmw_private *dev_priv)
+ {
+       struct drm_device *dev = dev_priv->dev;
+       struct vmw_display_unit *du;
+       struct drm_crtc *crtc;
+       drm_modeset_lock_all(dev);
+       drm_for_each_crtc(crtc, dev) {
+               du = vmw_crtc_to_du(crtc);
+               du->hotspot_x = 0;
+               du->hotspot_y = 0;
+       }
+       drm_modeset_unlock_all(dev);
+ }
  void vmw_kms_cursor_post_execbuf(struct vmw_private *dev_priv)
  {
        struct drm_device *dev = dev_priv->dev;
                du->cursor_age = du->cursor_surface->snooper.age;
                vmw_cursor_update_image(dev_priv,
                                        du->cursor_surface->snooper.image,
-                                       64, 64, du->hotspot_x, du->hotspot_y);
+                                       64, 64,
+                                       du->hotspot_x + du->core_hotspot_x,
+                                       du->hotspot_y + du->core_hotspot_y);
        }
  
        mutex_unlock(&dev->mode_config.mutex);
@@@ -930,7 -968,7 +968,7 @@@ vmw_kms_new_framebuffer(struct vmw_priv
  
  static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
                                                 struct drm_file *file_priv,
 -                                               struct drm_mode_fb_cmd2 *mode_cmd2)
 +                                               const struct drm_mode_fb_cmd2 *mode_cmd2)
  {
        struct vmw_private *dev_priv = vmw_priv(dev);
        struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
index 1465f6a0e0107e7fc9f9a0a7348f08e1d282db10,3b36582970702219f0e1b28f16093b4de6425b48..83800ac6ebd782512d004311ee5004dc4fa097de
@@@ -284,19 -284,13 +284,19 @@@ enum 
        (AZX_DCAPS_OLD_SSYNC | AZX_DCAPS_NO_ALIGN_BUFSIZE)
  
  /* quirks for Intel PCH */
 -#define AZX_DCAPS_INTEL_PCH_NOPM \
 +#define AZX_DCAPS_INTEL_PCH_BASE \
        (AZX_DCAPS_NO_ALIGN_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY |\
 -       AZX_DCAPS_REVERSE_ASSIGN | AZX_DCAPS_SNOOP_TYPE(SCH))
 +       AZX_DCAPS_SNOOP_TYPE(SCH))
 +
 +/* PCH up to IVB; no runtime PM */
 +#define AZX_DCAPS_INTEL_PCH_NOPM \
 +      (AZX_DCAPS_INTEL_PCH_BASE)
  
 +/* PCH for HSW/BDW; with runtime PM */
  #define AZX_DCAPS_INTEL_PCH \
 -      (AZX_DCAPS_INTEL_PCH_NOPM | AZX_DCAPS_PM_RUNTIME)
 +      (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME)
  
 +/* HSW HDMI */
  #define AZX_DCAPS_INTEL_HASWELL \
        (/*AZX_DCAPS_ALIGN_BUFSIZE |*/ AZX_DCAPS_COUNT_LPIB_DELAY |\
         AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_POWERWELL |\
  
  /* quirks for Nvidia */
  #define AZX_DCAPS_PRESET_NVIDIA \
 -      (AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI | /*AZX_DCAPS_ALIGN_BUFSIZE |*/ \
 +      (AZX_DCAPS_NO_MSI | /*AZX_DCAPS_ALIGN_BUFSIZE |*/ \
         AZX_DCAPS_NO_64BIT | AZX_DCAPS_CORBRP_SELF_CLEAR |\
         AZX_DCAPS_SNOOP_TYPE(NVIDIA))
  
                                        ((pci)->device == 0x0d0c) || \
                                        ((pci)->device == 0x160c))
  
+ #define IS_BROXTON(pci)       ((pci)->device == 0x5a98)
  static char *driver_short_names[] = {
        [AZX_DRIVER_ICH] = "HDA Intel",
        [AZX_DRIVER_PCH] = "HDA Intel PCH",
@@@ -512,15 -508,36 +514,36 @@@ static void azx_init_pci(struct azx *ch
          }
  }
  
+ /*
+  * In BXT-P A0, HD-Audio DMA requests is later than expected,
+  * and makes an audio stream sensitive to system latencies when
+  * 24/32 bits are playing.
+  * Adjusting threshold of DMA fifo to force the DMA request
+  * sooner to improve latency tolerance at the expense of power.
+  */
+ static void bxt_reduce_dma_latency(struct azx *chip)
+ {
+       u32 val;
+       val = azx_readl(chip, SKL_EM4L);
+       val &= (0x3 << 20);
+       azx_writel(chip, SKL_EM4L, val);
+ }
  static void hda_intel_init_chip(struct azx *chip, bool full_reset)
  {
        struct hdac_bus *bus = azx_bus(chip);
+       struct pci_dev *pci = chip->pci;
  
        if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
                snd_hdac_set_codec_wakeup(bus, true);
        azx_init_chip(chip, full_reset);
        if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
                snd_hdac_set_codec_wakeup(bus, false);
+       /* reduce dma latency to avoid noise */
+       if (IS_BROXTON(pci))
+               bxt_reduce_dma_latency(chip);
  }
  
  /* calculate runtime delay from LPIB */
@@@ -632,7 -649,7 +655,7 @@@ static int azx_position_ok(struct azx *
        if (wallclk < (azx_dev->core.period_wallclk * 5) / 4 &&
            pos % azx_dev->core.period_bytes > azx_dev->core.period_bytes / 2)
                /* NG - it's below the first next period boundary */
 -              return chip->bdl_pos_adj[chip->dev_index] ? 0 : -1;
 +              return chip->bdl_pos_adj ? 0 : -1;
        azx_dev->core.start_wallclk += wallclk;
        return 1; /* OK, it's fine */
  }
@@@ -937,6 -954,36 +960,36 @@@ static int azx_resume(struct device *de
  }
  #endif /* CONFIG_PM_SLEEP || SUPPORT_VGA_SWITCHEROO */
  
+ #ifdef CONFIG_PM_SLEEP
+ /* put codec down to D3 at hibernation for Intel SKL+;
+  * otherwise BIOS may still access the codec and screw up the driver
+  */
+ #define IS_SKL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa170)
+ #define IS_SKL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d70)
+ #define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
+ #define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci))
+ static int azx_freeze_noirq(struct device *dev)
+ {
+       struct pci_dev *pci = to_pci_dev(dev);
+       if (IS_SKL_PLUS(pci))
+               pci_set_power_state(pci, PCI_D3hot);
+       return 0;
+ }
+ static int azx_thaw_noirq(struct device *dev)
+ {
+       struct pci_dev *pci = to_pci_dev(dev);
+       if (IS_SKL_PLUS(pci))
+               pci_set_power_state(pci, PCI_D0);
+       return 0;
+ }
+ #endif /* CONFIG_PM_SLEEP */
  #ifdef CONFIG_PM
  static int azx_runtime_suspend(struct device *dev)
  {
@@@ -1046,6 -1093,10 +1099,10 @@@ static int azx_runtime_idle(struct devi
  
  static const struct dev_pm_ops azx_pm = {
        SET_SYSTEM_SLEEP_PM_OPS(azx_suspend, azx_resume)
+ #ifdef CONFIG_PM_SLEEP
+       .freeze_noirq = azx_freeze_noirq,
+       .thaw_noirq = azx_thaw_noirq,
+ #endif
        SET_RUNTIME_PM_OPS(azx_runtime_suspend, azx_runtime_resume, azx_runtime_idle)
  };
  
@@@ -1325,7 -1376,7 +1382,7 @@@ static int check_position_fix(struct az
        }
  
        /* Check VIA/ATI HD Audio Controller exist */
 -      if (chip->driver_caps & AZX_DCAPS_POSFIX_VIA) {
 +      if (chip->driver_type == AZX_DRIVER_VIA) {
                dev_dbg(chip->card->dev, "Using VIACOMBO position fix\n");
                return POS_FIX_VIACOMBO;
        }
@@@ -1488,26 -1539,6 +1545,26 @@@ static void azx_probe_work(struct work_
        azx_probe_continue(&hda->chip);
  }
  
 +static int default_bdl_pos_adj(struct azx *chip)
 +{
 +      /* some exceptions: Atoms seem problematic with value 1 */
 +      if (chip->pci->vendor == PCI_VENDOR_ID_INTEL) {
 +              switch (chip->pci->device) {
 +              case 0x0f04: /* Baytrail */
 +              case 0x2284: /* Braswell */
 +                      return 32;
 +              }
 +      }
 +
 +      switch (chip->driver_type) {
 +      case AZX_DRIVER_ICH:
 +      case AZX_DRIVER_PCH:
 +              return 1;
 +      default:
 +              return 32;
 +      }
 +}
 +
  /*
   * constructor
   */
@@@ -1561,10 -1592,18 +1618,10 @@@ static int azx_create(struct snd_card *
        chip->single_cmd = single_cmd;
        azx_check_snoop_available(chip);
  
 -      if (bdl_pos_adj[dev] < 0) {
 -              switch (chip->driver_type) {
 -              case AZX_DRIVER_ICH:
 -              case AZX_DRIVER_PCH:
 -                      bdl_pos_adj[dev] = 1;
 -                      break;
 -              default:
 -                      bdl_pos_adj[dev] = 32;
 -                      break;
 -              }
 -      }
 -      chip->bdl_pos_adj = bdl_pos_adj;
 +      if (bdl_pos_adj[dev] < 0)
 +              chip->bdl_pos_adj = default_bdl_pos_adj(chip);
 +      else
 +              chip->bdl_pos_adj = bdl_pos_adj[dev];
  
        err = azx_bus_init(chip, model[dev], &pci_hda_io_ops);
        if (err < 0) {
                return err;
        }
  
 +      if (chip->driver_type == AZX_DRIVER_NVIDIA) {
 +              dev_dbg(chip->card->dev, "Enable delay in RIRB handling\n");
 +              chip->bus.needs_damn_long_delay = 1;
 +      }
 +
        err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
        if (err < 0) {
                dev_err(card->dev, "Error creating device [card]!\n");
@@@ -1971,8 -2005,8 +2028,8 @@@ static int azx_probe(struct pci_dev *pc
  #endif /* CONFIG_SND_HDA_PATCH_LOADER */
  
  #ifndef CONFIG_SND_HDA_I915
 -      if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
 -              dev_err(card->dev, "Haswell must build in CONFIG_SND_HDA_I915\n");
 +      if (CONTROLLER_IN_GPU(pci))
 +              dev_err(card->dev, "Haswell/Broadwell HDMI/DP must build in CONFIG_SND_HDA_I915\n");
  #endif
  
        if (schedule_probe)
@@@ -2169,10 -2203,10 +2226,10 @@@ static const struct pci_device_id azx_i
          .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM },
        /* Poulsbo */
        { PCI_DEVICE(0x8086, 0x811b),
 -        .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM },
 +        .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_BASE },
        /* Oaktrail */
        { PCI_DEVICE(0x8086, 0x080a),
 -        .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM },
 +        .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_BASE },
        /* BayTrail */
        { PCI_DEVICE(0x8086, 0x0f04),
          .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BAYTRAIL },
        { PCI_DEVICE(0x1002, 0xaae8),
          .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
        /* VIA VT8251/VT8237A */
 -      { PCI_DEVICE(0x1106, 0x3288),
 -        .driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA },
 +      { PCI_DEVICE(0x1106, 0x3288), .driver_data = AZX_DRIVER_VIA },
        /* VIA GFX VT7122/VX900 */
        { PCI_DEVICE(0x1106, 0x9170), .driver_data = AZX_DRIVER_GENERIC },
        /* VIA GFX VT6122/VX11 */
          .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
          .class_mask = 0xffffff,
          .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
 -        AZX_DCAPS_NO_64BIT |
 -        AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB },
 +        AZX_DCAPS_NO_64BIT | AZX_DCAPS_POSFIX_LPIB },
  #else
        /* this entry seems still valid -- i.e. without emu20kx chip */
        { PCI_DEVICE(0x1102, 0x0009),
          .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
 -        AZX_DCAPS_NO_64BIT |
 -        AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB },
 +        AZX_DCAPS_NO_64BIT | AZX_DCAPS_POSFIX_LPIB },
  #endif
        /* CM8888 */
        { PCI_DEVICE(0x13f6, 0x5011),
This page took 0.162607 seconds and 5 git commands to generate.