]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
Merge remote-tracking branch 'airlied/drm-next' into drm-intel-next
authorDaniel Vetter <daniel.vetter@ffwll.ch>
Wed, 30 Sep 2015 06:47:41 +0000 (08:47 +0200)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Wed, 30 Sep 2015 06:47:41 +0000 (08:47 +0200)
Backmerge to catch up with 4.3. slightly more involved conflict in the
irq code, but nothing beyond adjacent changes.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
17 files changed:
1  2 
Documentation/DocBook/drm.tmpl
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_execbuffer.c
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/intel_bios.c
drivers/gpu/drm/i915/intel_csr.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_dp_mst.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_dsi.c
drivers/gpu/drm/i915/intel_fbdev.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/i915/intel_tv.c
include/drm/drm_dp_helper.h

index 1f9dc3e97ab755745d1a0c501d533099402ea169,30401f927156ccc2fef86f27b48195ff260470fa..f78ca7f18bb2001bfad7b4cdbb7c7a962092853d
@@@ -3646,7 -3646,7 +3646,7 @@@ void (*postclose) (struct drm_device *
        plane properties to default value, so that a subsequent open of the
        device will not inherit state from the previous user. It can also be
        used to execute delayed power switching state changes, e.g. in
-       conjunction with the vga-switcheroo infrastructure. Beyond that KMS
+       conjunction with the vga_switcheroo infrastructure. Beyond that KMS
        drivers should not do any further cleanup. Only legacy UMS drivers might
        need to clean up device state so that the vga console or an independent
        fbdev driver could take over.
@@@ -4237,20 -4237,6 +4237,20 @@@ int num_ioctls;</synopsis
  !Idrivers/gpu/drm/i915/i915_gem_shrinker.c
        </sect2>
      </sect1>
 +    <sect1>
 +      <title>GuC-based Command Submission</title>
 +      <sect2>
 +        <title>GuC</title>
 +!Pdrivers/gpu/drm/i915/intel_guc_loader.c GuC-specific firmware loader
 +!Idrivers/gpu/drm/i915/intel_guc_loader.c
 +      </sect2>
 +      <sect2>
 +        <title>GuC Client</title>
 +!Pdrivers/gpu/drm/i915/i915_guc_submission.c GuC-based command submissison
 +!Idrivers/gpu/drm/i915/i915_guc_submission.c
 +      </sect2>
 +    </sect1>
 +
      <sect1>
        <title> Tracing </title>
        <para>
index 947bd4385292c9607d8d2319d632a7f17ff7cc0d,ab64d68388f232b543bf19c1726b44c7cd329eaa..e6d7a69ec1bfa01b2d0e008684bd72ac67579f29
@@@ -362,7 -362,6 +362,7 @@@ static const struct intel_device_info i
        .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
        .has_llc = 1,
        .has_ddi = 1,
 +      .has_fpga_dbg = 1,
        .has_fbc = 1,
        GEN_DEFAULT_PIPEOFFSETS,
        IVB_CURSOR_OFFSETS,
@@@ -375,7 -374,6 +375,7 @@@ static const struct intel_device_info i
        .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING,
        .has_llc = 1,
        .has_ddi = 1,
 +      .has_fpga_dbg = 1,
        .has_fbc = 1,
        GEN_DEFAULT_PIPEOFFSETS,
        IVB_CURSOR_OFFSETS,
@@@ -388,7 -386,6 +388,7 @@@ static const struct intel_device_info i
        .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
        .num_pipes = 3,
        .has_ddi = 1,
 +      .has_fpga_dbg = 1,
        .has_fbc = 1,
        GEN_DEFAULT_PIPEOFFSETS,
        IVB_CURSOR_OFFSETS,
@@@ -682,7 -679,7 +682,7 @@@ static int i915_drm_suspend_late(struc
        return 0;
  }
  
 -int i915_suspend_legacy(struct drm_device *dev, pm_message_t state)
 +int i915_suspend_switcheroo(struct drm_device *dev, pm_message_t state)
  {
        int error;
  
@@@ -733,7 -730,7 +733,7 @@@ static int i915_drm_resume(struct drm_d
        mutex_lock(&dev->struct_mutex);
        if (i915_gem_init_hw(dev)) {
                DRM_ERROR("failed to re-initialize GPU, declaring wedged!\n");
-               atomic_set_mask(I915_WEDGED, &dev_priv->gpu_error.reset_counter);
+                       atomic_or(I915_WEDGED, &dev_priv->gpu_error.reset_counter);
        }
        mutex_unlock(&dev->struct_mutex);
  
@@@ -815,7 -812,7 +815,7 @@@ static int i915_drm_resume_early(struc
        return ret;
  }
  
 -int i915_resume_legacy(struct drm_device *dev)
 +int i915_resume_switcheroo(struct drm_device *dev)
  {
        int ret;
  
@@@ -1120,7 -1117,7 +1120,7 @@@ static void vlv_save_gunit_s0ix_state(s
        s->gfx_pend_tlb1        = I915_READ(GEN7_GFX_PEND_TLB1);
  
        for (i = 0; i < ARRAY_SIZE(s->lra_limits); i++)
 -              s->lra_limits[i] = I915_READ(GEN7_LRA_LIMITS_BASE + i * 4);
 +              s->lra_limits[i] = I915_READ(GEN7_LRA_LIMITS(i));
  
        s->media_max_req_count  = I915_READ(GEN7_MEDIA_MAX_REQ_COUNT);
        s->gfx_max_req_count    = I915_READ(GEN7_GFX_MAX_REQ_COUNT);
        s->pm_ier               = I915_READ(GEN6_PMIER);
  
        for (i = 0; i < ARRAY_SIZE(s->gt_scratch); i++)
 -              s->gt_scratch[i] = I915_READ(GEN7_GT_SCRATCH_BASE + i * 4);
 +              s->gt_scratch[i] = I915_READ(GEN7_GT_SCRATCH(i));
  
        /* GT SA CZ domain, 0x100000-0x138124 */
        s->tilectl              = I915_READ(TILECTL);
@@@ -1202,7 -1199,7 +1202,7 @@@ static void vlv_restore_gunit_s0ix_stat
        I915_WRITE(GEN7_GFX_PEND_TLB1,  s->gfx_pend_tlb1);
  
        for (i = 0; i < ARRAY_SIZE(s->lra_limits); i++)
 -              I915_WRITE(GEN7_LRA_LIMITS_BASE + i * 4, s->lra_limits[i]);
 +              I915_WRITE(GEN7_LRA_LIMITS(i), s->lra_limits[i]);
  
        I915_WRITE(GEN7_MEDIA_MAX_REQ_COUNT, s->media_max_req_count);
        I915_WRITE(GEN7_GFX_MAX_REQ_COUNT, s->gfx_max_req_count);
        I915_WRITE(GEN6_PMIER,          s->pm_ier);
  
        for (i = 0; i < ARRAY_SIZE(s->gt_scratch); i++)
 -              I915_WRITE(GEN7_GT_SCRATCH_BASE + i * 4, s->gt_scratch[i]);
 +              I915_WRITE(GEN7_GT_SCRATCH(i), s->gt_scratch[i]);
  
        /* GT SA CZ domain, 0x100000-0x138124 */
        I915_WRITE(TILECTL,                     s->tilectl);
@@@ -1555,15 -1552,6 +1555,15 @@@ static int intel_runtime_resume(struct 
        gen6_update_ring_freq(dev);
  
        intel_runtime_pm_enable_interrupts(dev_priv);
 +
 +      /*
 +       * On VLV/CHV display interrupts are part of the display
 +       * power well, so hpd is reinitialized from there. For
 +       * everyone else do it here.
 +       */
 +      if (!IS_VALLEYVIEW(dev_priv))
 +              intel_hpd_init(dev_priv);
 +
        intel_enable_gt_powersave(dev);
  
        if (ret)
@@@ -1661,7 -1649,7 +1661,7 @@@ static struct drm_driver driver = 
         */
        .driver_features =
            DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | DRIVER_PRIME |
 -          DRIVER_RENDER,
 +          DRIVER_RENDER | DRIVER_MODESET,
        .load = i915_driver_load,
        .unload = i915_driver_unload,
        .open = i915_driver_open,
        .postclose = i915_driver_postclose,
        .set_busid = drm_pci_set_busid,
  
 -      /* Used in place of i915_pm_ops for non-DRIVER_MODESET */
 -      .suspend = i915_suspend_legacy,
 -      .resume = i915_resume_legacy,
 -
  #if defined(CONFIG_DEBUG_FS)
        .debugfs_init = i915_debugfs_init,
        .debugfs_cleanup = i915_debugfs_cleanup,
@@@ -1712,6 -1704,7 +1712,6 @@@ static int __init i915_init(void
         * either the i915.modeset prarameter or by the
         * vga_text_mode_force boot option.
         */
 -      driver.driver_features |= DRIVER_MODESET;
  
        if (i915.modeset == 0)
                driver.driver_features &= ~DRIVER_MODESET;
  #endif
  
        if (!(driver.driver_features & DRIVER_MODESET)) {
 -              driver.get_vblank_timestamp = NULL;
                /* Silently fail loading to not upset userspace. */
                DRM_DEBUG_DRIVER("KMS and UMS disabled.\n");
                return 0;
        }
  
 -      /*
 -       * FIXME: Note that we're lying to the DRM core here so that we can get access
 -       * to the atomic ioctl and the atomic properties.  Only plane operations on
 -       * a single CRTC will actually work.
 -       */
 -      if (driver.driver_features & DRIVER_MODESET)
 +      if (i915.nuclear_pageflip)
                driver.driver_features |= DRIVER_ATOMIC;
  
        return drm_pci_init(&driver, &i915_pci_driver);
index c20f2c77c10215d58ba1a1a0df90fb720ba4cddf,e1db8de52851b979c31607abf7b6995bd1febe0b..7d83f6741e33a4294001e2118a9f2aaa34cdb669
  #include <linux/intel-iommu.h>
  #include <linux/kref.h>
  #include <linux/pm_qos.h>
 +#include "intel_guc.h"
  
  /* General customization:
   */
  
  #define DRIVER_NAME           "i915"
  #define DRIVER_DESC           "Intel Graphics"
 -#define DRIVER_DATE           "20150731"
 +#define DRIVER_DATE           "20150928"
  
  #undef WARN_ON
  /* Many gcc seem to no see through this and fall over :( */
                BUILD_BUG_ON(__i915_warn_cond); \
        WARN(__i915_warn_cond, "WARN_ON(" #x ")"); })
  #else
 -#define WARN_ON(x) WARN((x), "WARN_ON(" #x ")")
 +#define WARN_ON(x) WARN((x), "WARN_ON(%s)", #x )
  #endif
  
  #undef WARN_ON_ONCE
 -#define WARN_ON_ONCE(x) WARN_ONCE((x), "WARN_ON_ONCE(" #x ")")
 +#define WARN_ON_ONCE(x) WARN_ONCE((x), "WARN_ON_ONCE(%s)", #x )
  
  #define MISSING_CASE(x) WARN(1, "Missing switch case (%lu) in %s\n", \
                             (long) (x), __func__);
        unlikely(__ret_warn_on);                                        \
  })
  
 +static inline const char *yesno(bool v)
 +{
 +      return v ? "yes" : "no";
 +}
 +
  enum pipe {
        INVALID_PIPE = -1,
        PIPE_A = 0,
@@@ -555,7 -549,7 +555,7 @@@ struct drm_i915_error_state 
  
                struct drm_i915_error_object {
                        int page_count;
 -                      u32 gtt_offset;
 +                      u64 gtt_offset;
                        u32 *pages[0];
                } *ringbuffer, *batchbuffer, *wa_batchbuffer, *ctx, *hws_page;
  
                u32 size;
                u32 name;
                u32 rseqno[I915_NUM_RINGS], wseqno;
 -              u32 gtt_offset;
 +              u64 gtt_offset;
                u32 read_domains;
                u32 write_domain;
                s32 fence_reg:I915_MAX_NUM_FENCE_BITS;
@@@ -671,8 -665,6 +671,8 @@@ struct drm_i915_display_funcs 
                              uint32_t level);
        void (*disable_backlight)(struct intel_connector *connector);
        void (*enable_backlight)(struct intel_connector *connector);
 +      uint32_t (*backlight_hz_to_pwm)(struct intel_connector *connector,
 +                                      uint32_t hz);
  };
  
  enum forcewake_domain_id {
@@@ -890,6 -882,7 +890,6 @@@ struct intel_context 
        } legacy_hw_ctx;
  
        /* Execlists */
 -      bool rcs_initialized;
        struct {
                struct drm_i915_gem_object *state;
                struct intel_ringbuffer *ringbuf;
@@@ -948,9 -941,6 +948,9 @@@ struct i915_fbc 
                FBC_CHIP_DEFAULT, /* disabled by default on this chip */
                FBC_ROTATION, /* rotation is not supported */
                FBC_IN_DBG_MASTER, /* kernel debugger is active */
 +              FBC_BAD_STRIDE, /* stride is not supported */
 +              FBC_PIXEL_RATE, /* pixel rate is too big */
 +              FBC_PIXEL_FORMAT /* pixel format is invalid */
        } no_fbc_reason;
  
        bool (*fbc_enabled)(struct drm_i915_private *dev_priv);
@@@ -1703,7 -1693,7 +1703,7 @@@ struct i915_execbuffer_params 
        struct drm_file                 *file;
        uint32_t                        dispatch_flags;
        uint32_t                        args_batch_start_offset;
 -      uint32_t                        batch_obj_vm_offset;
 +      uint64_t                        batch_obj_vm_offset;
        struct intel_engine_cs          *ring;
        struct drm_i915_gem_object      *batch_obj;
        struct intel_context            *ctx;
@@@ -1726,8 -1716,6 +1726,8 @@@ struct drm_i915_private 
  
        struct i915_virtual_gpu vgpu;
  
 +      struct intel_guc guc;
 +
        struct intel_csr csr;
  
        /* Display CSR-related protection */
        unsigned int fsb_freq, mem_freq, is_ddr3;
        unsigned int skl_boot_cdclk;
        unsigned int cdclk_freq, max_cdclk_freq;
 +      unsigned int max_dotclk_freq;
        unsigned int hpll_freq;
  
        /**
        struct drm_property *force_audio_property;
  
        /* hda/i915 audio component */
+       struct i915_audio_component *audio_component;
        bool audio_component_registered;
  
        uint32_t hw_context_size;
                        struct skl_wm_values skl_hw;
                        struct vlv_wm_values vlv;
                };
+               uint8_t max_level;
        } wm;
  
        struct i915_runtime_pm pm;
@@@ -1973,11 -1963,6 +1976,11 @@@ static inline struct drm_i915_private *
        return to_i915(dev_get_drvdata(dev));
  }
  
 +static inline struct drm_i915_private *guc_to_i915(struct intel_guc *guc)
 +{
 +      return container_of(guc, struct drm_i915_private, guc);
 +}
 +
  /* Iterate over initialised rings */
  #define for_each_ring(ring__, dev_priv__, i__) \
        for ((i__) = 0; (i__) < I915_NUM_RINGS; (i__)++) \
@@@ -2014,26 -1999,25 +2017,26 @@@ struct drm_i915_gem_object_ops 
  
  /*
   * Frontbuffer tracking bits. Set in obj->frontbuffer_bits while a gem bo is
 - * considered to be the frontbuffer for the given plane interface-vise. This
 + * considered to be the frontbuffer for the given plane interface-wise. This
   * doesn't mean that the hw necessarily already scans it out, but that any
   * rendering (by the cpu or gpu) will land in the frontbuffer eventually.
   *
   * We have one bit per pipe and per scanout plane type.
   */
 -#define INTEL_FRONTBUFFER_BITS_PER_PIPE 4
 +#define INTEL_MAX_SPRITE_BITS_PER_PIPE 5
 +#define INTEL_FRONTBUFFER_BITS_PER_PIPE 8
  #define INTEL_FRONTBUFFER_BITS \
        (INTEL_FRONTBUFFER_BITS_PER_PIPE * I915_MAX_PIPES)
  #define INTEL_FRONTBUFFER_PRIMARY(pipe) \
        (1 << (INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe)))
  #define INTEL_FRONTBUFFER_CURSOR(pipe) \
 -      (1 << (1 +(INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe))))
 -#define INTEL_FRONTBUFFER_SPRITE(pipe) \
 -      (1 << (2 +(INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe))))
 +      (1 << (1 + (INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe))))
 +#define INTEL_FRONTBUFFER_SPRITE(pipe, plane) \
 +      (1 << (2 + plane + (INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe))))
  #define INTEL_FRONTBUFFER_OVERLAY(pipe) \
 -      (1 << (3 +(INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe))))
 +      (1 << (2 + INTEL_MAX_SPRITE_BITS_PER_PIPE + (INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe))))
  #define INTEL_FRONTBUFFER_ALL_MASK(pipe) \
 -      (0xf << (INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe)))
 +      (0xff << (INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe)))
  
  struct drm_i915_gem_object {
        struct drm_gem_object base;
@@@ -2491,11 -2475,6 +2494,11 @@@ struct drm_i915_cmd_table 
  #define IS_SKL_ULX(dev)               (INTEL_DEVID(dev) == 0x190E || \
                                 INTEL_DEVID(dev) == 0x1915 || \
                                 INTEL_DEVID(dev) == 0x191E)
 +#define IS_SKL_GT3(dev)               (IS_SKYLAKE(dev) && \
 +                               (INTEL_DEVID(dev) & 0x00F0) == 0x0020)
 +#define IS_SKL_GT4(dev)               (IS_SKYLAKE(dev) && \
 +                               (INTEL_DEVID(dev) & 0x00F0) == 0x0030)
 +
  #define IS_PRELIMINARY_HW(intel_info) ((intel_info)->is_preliminary)
  
  #define SKL_REVID_A0          (0x0)
  
  #define BXT_REVID_A0          (0x0)
  #define BXT_REVID_B0          (0x3)
 -#define BXT_REVID_C0          (0x6)
 +#define BXT_REVID_C0          (0x9)
  
  /*
   * The genX designation typically refers to the render engine, so render
  #define HAS_HW_CONTEXTS(dev)  (INTEL_INFO(dev)->gen >= 6)
  #define HAS_LOGICAL_RING_CONTEXTS(dev)        (INTEL_INFO(dev)->gen >= 8)
  #define USES_PPGTT(dev)               (i915.enable_ppgtt)
 -#define USES_FULL_PPGTT(dev)  (i915.enable_ppgtt == 2)
 +#define USES_FULL_PPGTT(dev)  (i915.enable_ppgtt >= 2)
 +#define USES_FULL_48BIT_PPGTT(dev)    (i915.enable_ppgtt == 3)
  
  #define HAS_OVERLAY(dev)              (INTEL_INFO(dev)->has_overlay)
  #define OVERLAY_NEEDS_PHYSICAL(dev)   (INTEL_INFO(dev)->overlay_needs_physical)
  #define HAS_RC6(dev)          (INTEL_INFO(dev)->gen >= 6)
  #define HAS_RC6p(dev)         (INTEL_INFO(dev)->gen == 6 || IS_IVYBRIDGE(dev))
  
 -#define HAS_CSR(dev)  (IS_SKYLAKE(dev))
 +#define HAS_CSR(dev)  (IS_GEN9(dev))
 +
 +#define HAS_GUC_UCODE(dev)    (IS_GEN9(dev))
 +#define HAS_GUC_SCHED(dev)    (IS_GEN9(dev))
  
  #define HAS_RESOURCE_STREAMER(dev) (IS_HASWELL(dev) || \
                                    INTEL_INFO(dev)->gen >= 8)
  #define INTEL_PCH_TYPE(dev) (__I915__(dev)->pch_type)
  #define HAS_PCH_SPT(dev) (INTEL_PCH_TYPE(dev) == PCH_SPT)
  #define HAS_PCH_LPT(dev) (INTEL_PCH_TYPE(dev) == PCH_LPT)
 +#define HAS_PCH_LPT_LP(dev) (__I915__(dev)->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE)
  #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT)
  #define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX)
  #define HAS_PCH_NOP(dev) (INTEL_PCH_TYPE(dev) == PCH_NOP)
  extern const struct drm_ioctl_desc i915_ioctls[];
  extern int i915_max_ioctl;
  
 -extern int i915_suspend_legacy(struct drm_device *dev, pm_message_t state);
 -extern int i915_resume_legacy(struct drm_device *dev);
 +extern int i915_suspend_switcheroo(struct drm_device *dev, pm_message_t state);
 +extern int i915_resume_switcheroo(struct drm_device *dev);
  
  /* i915_params.c */
  struct i915_params {
        int enable_cmd_parser;
        /* leave bools at the end to not create holes */
        bool enable_hangcheck;
 -      bool fastboot;
        bool prefault_disable;
        bool load_detect_test;
        bool reset;
        int use_mmio_flip;
        int mmio_debug;
        bool verbose_state_checks;
 +      bool nuclear_pageflip;
        int edp_vswing;
  };
  extern struct i915_params i915 __read_mostly;
@@@ -2742,9 -2716,6 +2745,9 @@@ i915_disable_pipestat(struct drm_i915_p
  
  void valleyview_enable_display_irqs(struct drm_i915_private *dev_priv);
  void valleyview_disable_display_irqs(struct drm_i915_private *dev_priv);
 +void i915_hotplug_interrupt_update(struct drm_i915_private *dev_priv,
 +                                 uint32_t mask,
 +                                 uint32_t bits);
  void
  ironlake_enable_display_irq(struct drm_i915_private *dev_priv, u32 mask);
  void
@@@ -2812,6 -2783,8 +2815,6 @@@ struct drm_i915_gem_object *i915_gem_al
                                                  size_t size);
  struct drm_i915_gem_object *i915_gem_object_create_from_data(
                struct drm_device *dev, const void *data, size_t size);
 -void i915_init_vm(struct drm_i915_private *dev_priv,
 -                struct i915_address_space *vm);
  void i915_gem_free_object(struct drm_gem_object *obj);
  void i915_gem_vma_destroy(struct i915_vma *vma);
  
@@@ -3013,11 -2986,13 +3016,11 @@@ struct drm_gem_object *i915_gem_prime_i
  struct dma_buf *i915_gem_prime_export(struct drm_device *dev,
                                struct drm_gem_object *gem_obj, int flags);
  
 -unsigned long
 -i915_gem_obj_ggtt_offset_view(struct drm_i915_gem_object *o,
 -                            const struct i915_ggtt_view *view);
 -unsigned long
 -i915_gem_obj_offset(struct drm_i915_gem_object *o,
 -                  struct i915_address_space *vm);
 -static inline unsigned long
 +u64 i915_gem_obj_ggtt_offset_view(struct drm_i915_gem_object *o,
 +                                const struct i915_ggtt_view *view);
 +u64 i915_gem_obj_offset(struct drm_i915_gem_object *o,
 +                      struct i915_address_space *vm);
 +static inline u64
  i915_gem_obj_ggtt_offset(struct drm_i915_gem_object *o)
  {
        return i915_gem_obj_ggtt_offset_view(o, &i915_ggtt_view_normal);
@@@ -3178,10 -3153,6 +3181,10 @@@ static inline void i915_gem_chipset_flu
  int i915_gem_stolen_insert_node(struct drm_i915_private *dev_priv,
                                struct drm_mm_node *node, u64 size,
                                unsigned alignment);
 +int i915_gem_stolen_insert_node_in_range(struct drm_i915_private *dev_priv,
 +                                       struct drm_mm_node *node, u64 size,
 +                                       unsigned alignment, u64 start,
 +                                       u64 end);
  void i915_gem_stolen_remove_node(struct drm_i915_private *dev_priv,
                                 struct drm_mm_node *node);
  int i915_gem_init_stolen(struct drm_device *dev);
@@@ -3415,13 -3386,13 +3418,13 @@@ int intel_freq_opcode(struct drm_i915_p
  #define I915_READ64(reg)      dev_priv->uncore.funcs.mmio_readq(dev_priv, (reg), true)
  
  #define I915_READ64_2x32(lower_reg, upper_reg) ({                     \
-       u32 upper, lower, tmp;                                          \
-       tmp = I915_READ(upper_reg);                                     \
+       u32 upper, lower, old_upper, loop = 0;                          \
+       upper = I915_READ(upper_reg);                                   \
        do {                                                            \
-               upper = tmp;                                            \
+               old_upper = upper;                                      \
                lower = I915_READ(lower_reg);                           \
-               tmp = I915_READ(upper_reg);                             \
-       } while (upper != tmp);                                         \
+               upper = I915_READ(upper_reg);                           \
+       } while (upper != old_upper && loop++ < 2);                     \
        (u64)upper << 32 | lower; })
  
  #define POSTING_READ(reg)     (void)I915_READ_NOTRACE(reg)
index 58c7ad058c41b8b700bc5e15c20ab2a48663eb5e,4d631a94648194957512d096e89da0e5242bd822..bf5ef7a07878e1caff5e79792c0273f74f219d30
                if (!needs_clflush_after &&
                    obj->base.write_domain != I915_GEM_DOMAIN_CPU) {
                        if (i915_gem_clflush_object(obj, obj->pin_display))
 -                              i915_gem_chipset_flush(dev);
 +                              needs_clflush_after = true;
                }
        }
  
        if (needs_clflush_after)
                i915_gem_chipset_flush(dev);
 +      else
 +              obj->cache_dirty = true;
  
        intel_fb_obj_flush(obj, false, ORIGIN_CPU);
        return ret;
@@@ -1713,8 -1711,8 +1713,8 @@@ i915_gem_mmap_ioctl(struct drm_device *
  
  /**
   * i915_gem_fault - fault a page into the GTT
 - * vma: VMA in question
 - * vmf: fault info
 + * @vma: VMA in question
 + * @vmf: fault info
   *
   * The fault handler is set up by drm_gem_mmap() when a object is GTT mapped
   * from userspace.  The fault handler takes care of binding the object to
@@@ -3230,6 -3228,10 +3230,6 @@@ int i915_vma_unbind(struct i915_vma *vm
        ret = i915_gem_object_wait_rendering(obj, false);
        if (ret)
                return ret;
 -      /* Continue on if we fail due to EIO, the GPU is hung so we
 -       * should be safe and we need to cleanup or else we might
 -       * cause memory corruption through use-after-free.
 -       */
  
        if (i915_is_ggtt(vma->vm) &&
            vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) {
@@@ -3353,8 -3355,7 +3353,8 @@@ i915_gem_object_bind_to_vm(struct drm_i
  {
        struct drm_device *dev = obj->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
 -      u32 size, fence_size, fence_alignment, unfenced_alignment;
 +      u32 fence_alignment, unfenced_alignment;
 +      u64 size, fence_size;
        u64 start =
                flags & PIN_OFFSET_BIAS ? flags & PIN_OFFSET_MASK : 0;
        u64 end =
         * attempt to find space.
         */
        if (size > end) {
 -              DRM_DEBUG("Attempting to bind an object (view type=%u) larger than the aperture: size=%u > %s aperture=%llu\n",
 +              DRM_DEBUG("Attempting to bind an object (view type=%u) larger than the aperture: size=%llu > %s aperture=%llu\n",
                          ggtt_view ? ggtt_view->type : 0,
                          size,
                          flags & PIN_MAPPABLE ? "mappable" : "total",
@@@ -3637,10 -3638,10 +3637,10 @@@ int i915_gem_object_set_cache_level(str
  {
        struct drm_device *dev = obj->base.dev;
        struct i915_vma *vma, *next;
 -      int ret;
 +      int ret = 0;
  
        if (obj->cache_level == cache_level)
 -              return 0;
 +              goto out;
  
        if (i915_gem_obj_is_pinned(obj)) {
                DRM_DEBUG("can not change the cache level of pinned objects\n");
                vma->node.color = cache_level;
        obj->cache_level = cache_level;
  
 +out:
        if (obj->cache_dirty &&
            obj->base.write_domain != I915_GEM_DOMAIN_CPU &&
            cpu_write_needs_clflush(obj)) {
@@@ -3738,15 -3738,6 +3738,15 @@@ int i915_gem_set_caching_ioctl(struct d
                level = I915_CACHE_NONE;
                break;
        case I915_CACHING_CACHED:
 +              /*
 +               * Due to a HW issue on BXT A stepping, GPU stores via a
 +               * snooped mapping may leave stale data in a corresponding CPU
 +               * cacheline, whereas normally such cachelines would get
 +               * invalidated.
 +               */
 +              if (IS_BROXTON(dev) && INTEL_REVID(dev) < BXT_REVID_B0)
 +                      return -ENODEV;
 +
                level = I915_CACHE_LLC;
                break;
        case I915_CACHING_DISPLAY:
@@@ -4020,13 -4011,15 +4020,13 @@@ i915_gem_object_do_pin(struct drm_i915_
                        return -EBUSY;
  
                if (i915_vma_misplaced(vma, alignment, flags)) {
 -                      unsigned long offset;
 -                      offset = ggtt_view ? i915_gem_obj_ggtt_offset_view(obj, ggtt_view) :
 -                                           i915_gem_obj_offset(obj, vm);
                        WARN(vma->pin_count,
                             "bo is already pinned in %s with incorrect alignment:"
 -                           " offset=%lx, req.alignment=%x, req.map_and_fenceable=%d,"
 +                           " offset=%08x %08x, req.alignment=%x, req.map_and_fenceable=%d,"
                             " obj->map_and_fenceable=%d\n",
                             ggtt_view ? "ggtt" : "ppgtt",
 -                           offset,
 +                           upper_32_bits(vma->node.start),
 +                           lower_32_bits(vma->node.start),
                             alignment,
                             !!(flags & PIN_MAPPABLE),
                             obj->map_and_fenceable);
@@@ -4609,8 -4602,14 +4609,8 @@@ int i915_gem_init_rings(struct drm_devi
                        goto cleanup_vebox_ring;
        }
  
 -      ret = i915_gem_set_seqno(dev, ((u32)~0 - 0x1000));
 -      if (ret)
 -              goto cleanup_bsd2_ring;
 -
        return 0;
  
 -cleanup_bsd2_ring:
 -      intel_cleanup_ring_buffer(&dev_priv->ring[VCS2]);
  cleanup_vebox_ring:
        intel_cleanup_ring_buffer(&dev_priv->ring[VECS]);
  cleanup_blt_ring:
@@@ -4680,33 -4679,6 +4680,33 @@@ i915_gem_init_hw(struct drm_device *dev
                        goto out;
        }
  
 +      /* We can't enable contexts until all firmware is loaded */
 +      if (HAS_GUC_UCODE(dev)) {
 +              ret = intel_guc_ucode_load(dev);
 +              if (ret) {
 +                      /*
 +                       * If we got an error and GuC submission is enabled, map
 +                       * the error to -EIO so the GPU will be declared wedged.
 +                       * OTOH, if we didn't intend to use the GuC anyway, just
 +                       * discard the error and carry on.
 +                       */
 +                      DRM_ERROR("Failed to initialize GuC, error %d%s\n", ret,
 +                                i915.enable_guc_submission ? "" :
 +                                " (ignored)");
 +                      ret = i915.enable_guc_submission ? -EIO : 0;
 +                      if (ret)
 +                              goto out;
 +              }
 +      }
 +
 +      /*
 +       * Increment the next seqno by 0x100 so we have a visible break
 +       * on re-initialisation
 +       */
 +      ret = i915_gem_set_seqno(dev, dev_priv->next_seqno+0x100);
 +      if (ret)
 +              goto out;
 +
        /* Now it is safe to go back round and do everything else: */
        for_each_ring(ring, dev_priv, i) {
                struct drm_i915_gem_request *req;
@@@ -4807,7 -4779,7 +4807,7 @@@ int i915_gem_init(struct drm_device *de
                 * for all other failure, such as an allocation failure, bail.
                 */
                DRM_ERROR("Failed to initialize GPU, declaring it wedged\n");
-               atomic_set_mask(I915_WEDGED, &dev_priv->gpu_error.reset_counter);
+               atomic_or(I915_WEDGED, &dev_priv->gpu_error.reset_counter);
                ret = 0;
        }
  
@@@ -4844,6 -4816,18 +4844,6 @@@ init_ring_lists(struct intel_engine_cs 
        INIT_LIST_HEAD(&ring->request_list);
  }
  
 -void i915_init_vm(struct drm_i915_private *dev_priv,
 -                struct i915_address_space *vm)
 -{
 -      if (!i915_is_ggtt(vm))
 -              drm_mm_init(&vm->mm, vm->start, vm->total);
 -      vm->dev = dev_priv->dev;
 -      INIT_LIST_HEAD(&vm->active_list);
 -      INIT_LIST_HEAD(&vm->inactive_list);
 -      INIT_LIST_HEAD(&vm->global_link);
 -      list_add_tail(&vm->global_link, &dev_priv->vm_list);
 -}
 -
  void
  i915_gem_load(struct drm_device *dev)
  {
                                  NULL);
  
        INIT_LIST_HEAD(&dev_priv->vm_list);
 -      i915_init_vm(dev_priv, &dev_priv->gtt.base);
 -
        INIT_LIST_HEAD(&dev_priv->context_list);
        INIT_LIST_HEAD(&dev_priv->mm.unbound_list);
        INIT_LIST_HEAD(&dev_priv->mm.bound_list);
                dev_priv->num_fence_regs =
                                I915_READ(vgtif_reg(avail_rs.fence_num));
  
 +      /*
 +       * Set initial sequence number for requests.
 +       * Using this number allows the wraparound to happen early,
 +       * catching any obvious problems.
 +       */
 +      dev_priv->next_seqno = ((u32)~0 - 0x1100);
 +      dev_priv->last_seqno = ((u32)~0 - 0x1101);
 +
        /* Initialize fence registers to zero */
        INIT_LIST_HEAD(&dev_priv->mm.fence_list);
        i915_gem_restore_fences(dev);
@@@ -4971,9 -4949,9 +4971,9 @@@ int i915_gem_open(struct drm_device *de
  
  /**
   * i915_gem_track_fb - update frontbuffer tracking
 - * old: current GEM buffer for the frontbuffer slots
 - * new: new GEM buffer for the frontbuffer slots
 - * frontbuffer_bits: bitmask of frontbuffer slots
 + * @old: current GEM buffer for the frontbuffer slots
 + * @new: new GEM buffer for the frontbuffer slots
 + * @frontbuffer_bits: bitmask of frontbuffer slots
   *
   * This updates the frontbuffer tracking bits @frontbuffer_bits by clearing them
   * from @old and setting them in @new. Both @old and @new can be NULL.
@@@ -4996,8 -4974,9 +4996,8 @@@ void i915_gem_track_fb(struct drm_i915_
  }
  
  /* All the new VM stuff */
 -unsigned long
 -i915_gem_obj_offset(struct drm_i915_gem_object *o,
 -                  struct i915_address_space *vm)
 +u64 i915_gem_obj_offset(struct drm_i915_gem_object *o,
 +                      struct i915_address_space *vm)
  {
        struct drm_i915_private *dev_priv = o->base.dev->dev_private;
        struct i915_vma *vma;
        return -1;
  }
  
 -unsigned long
 -i915_gem_obj_ggtt_offset_view(struct drm_i915_gem_object *o,
 -                            const struct i915_ggtt_view *view)
 +u64 i915_gem_obj_ggtt_offset_view(struct drm_i915_gem_object *o,
 +                                const struct i915_ggtt_view *view)
  {
        struct i915_address_space *ggtt = i915_obj_to_ggtt(o);
        struct i915_vma *vma;
index 98952b4b9e7f3259700146bf70cd40eff63e4165,a953d4975b8c08d237bac9aa4a7ecd3eaf29c28e..67ef118ee1605766362c06cad1cc1612ff1fd3e9
@@@ -1009,7 -1009,7 +1009,7 @@@ i915_gem_validate_context(struct drm_de
        }
  
        if (i915.enable_execlists && !ctx->engine[ring->id].state) {
 -              int ret = intel_lr_context_deferred_create(ctx, ring);
 +              int ret = intel_lr_context_deferred_alloc(ctx, ring);
                if (ret) {
                        DRM_DEBUG("Could not create LRC %u: %d\n", ctx_id, ret);
                        return ERR_PTR(ret);
@@@ -1032,6 -1032,7 +1032,7 @@@ i915_gem_execbuffer_move_to_active(stru
                u32 old_read = obj->base.read_domains;
                u32 old_write = obj->base.write_domain;
  
+               obj->dirty = 1; /* be paranoid  */
                obj->base.write_domain = obj->base.pending_write_domain;
                if (obj->base.write_domain == 0)
                        obj->base.pending_read_domains |= obj->base.read_domains;
  
                i915_vma_move_to_active(vma, req);
                if (obj->base.write_domain) {
-                       obj->dirty = 1;
                        i915_gem_request_assign(&obj->last_write_req, req);
  
                        intel_fb_obj_invalidate(obj, ORIGIN_CS);
index 6ca6c16fe500638159a55115a2c74b879498daf6,88d064e807830ab02b2367197d1fc6a674d8d262..ff85eae932bcdcd71d27a12c19f4ae8648724b60
   * and related files, but that will be described in separate chapters.
   */
  
 +static const u32 hpd_ilk[HPD_NUM_PINS] = {
 +      [HPD_PORT_A] = DE_DP_A_HOTPLUG,
 +};
 +
 +static const u32 hpd_ivb[HPD_NUM_PINS] = {
 +      [HPD_PORT_A] = DE_DP_A_HOTPLUG_IVB,
 +};
 +
 +static const u32 hpd_bdw[HPD_NUM_PINS] = {
 +      [HPD_PORT_A] = GEN8_PORT_DP_A_HOTPLUG,
 +};
 +
  static const u32 hpd_ibx[HPD_NUM_PINS] = {
        [HPD_CRT] = SDE_CRT_HOTPLUG,
        [HPD_SDVO_B] = SDE_SDVOB_HOTPLUG,
@@@ -74,7 -62,6 +74,7 @@@ static const u32 hpd_cpt[HPD_NUM_PINS] 
  };
  
  static const u32 hpd_spt[HPD_NUM_PINS] = {
 +      [HPD_PORT_A] = SDE_PORTA_HOTPLUG_SPT,
        [HPD_PORT_B] = SDE_PORTB_HOTPLUG_CPT,
        [HPD_PORT_C] = SDE_PORTC_HOTPLUG_CPT,
        [HPD_PORT_D] = SDE_PORTD_HOTPLUG_CPT,
@@@ -110,7 -97,6 +110,7 @@@ static const u32 hpd_status_i915[HPD_NU
  
  /* BXT hpd list */
  static const u32 hpd_bxt[HPD_NUM_PINS] = {
 +      [HPD_PORT_A] = BXT_DE_PORT_HP_DDIA,
        [HPD_PORT_B] = BXT_DE_PORT_HP_DDIB,
        [HPD_PORT_C] = BXT_DE_PORT_HP_DDIC
  };
  static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir);
  
  /* For display hotplug interrupt */
 -void
 -ironlake_enable_display_irq(struct drm_i915_private *dev_priv, u32 mask)
 +static inline void
 +i915_hotplug_interrupt_update_locked(struct drm_i915_private *dev_priv,
 +                                   uint32_t mask,
 +                                   uint32_t bits)
  {
 +      uint32_t val;
 +
        assert_spin_locked(&dev_priv->irq_lock);
 +      WARN_ON(bits & ~mask);
  
 -      if (WARN_ON(!intel_irqs_enabled(dev_priv)))
 -              return;
 +      val = I915_READ(PORT_HOTPLUG_EN);
 +      val &= ~mask;
 +      val |= bits;
 +      I915_WRITE(PORT_HOTPLUG_EN, val);
 +}
  
 -      if ((dev_priv->irq_mask & mask) != 0) {
 -              dev_priv->irq_mask &= ~mask;
 -              I915_WRITE(DEIMR, dev_priv->irq_mask);
 -              POSTING_READ(DEIMR);
 -      }
 +/**
 + * i915_hotplug_interrupt_update - update hotplug interrupt enable
 + * @dev_priv: driver private
 + * @mask: bits to update
 + * @bits: bits to enable
 + * NOTE: the HPD enable bits are modified both inside and outside
 + * of an interrupt context. To avoid that read-modify-write cycles
 + * interfer, these bits are protected by a spinlock. Since this
 + * function is usually not called from a context where the lock is
 + * held already, this function acquires the lock itself. A non-locking
 + * version is also available.
 + */
 +void i915_hotplug_interrupt_update(struct drm_i915_private *dev_priv,
 +                                 uint32_t mask,
 +                                 uint32_t bits)
 +{
 +      spin_lock_irq(&dev_priv->irq_lock);
 +      i915_hotplug_interrupt_update_locked(dev_priv, mask, bits);
 +      spin_unlock_irq(&dev_priv->irq_lock);
  }
  
 -void
 -ironlake_disable_display_irq(struct drm_i915_private *dev_priv, u32 mask)
 +/**
 + * ilk_update_display_irq - update DEIMR
 + * @dev_priv: driver private
 + * @interrupt_mask: mask of interrupt bits to update
 + * @enabled_irq_mask: mask of interrupt bits to enable
 + */
 +static void ilk_update_display_irq(struct drm_i915_private *dev_priv,
 +                                 uint32_t interrupt_mask,
 +                                 uint32_t enabled_irq_mask)
  {
 +      uint32_t new_val;
 +
        assert_spin_locked(&dev_priv->irq_lock);
  
 +      WARN_ON(enabled_irq_mask & ~interrupt_mask);
 +
        if (WARN_ON(!intel_irqs_enabled(dev_priv)))
                return;
  
 -      if ((dev_priv->irq_mask & mask) != mask) {
 -              dev_priv->irq_mask |= mask;
 +      new_val = dev_priv->irq_mask;
 +      new_val &= ~interrupt_mask;
 +      new_val |= (~enabled_irq_mask & interrupt_mask);
 +
 +      if (new_val != dev_priv->irq_mask) {
 +              dev_priv->irq_mask = new_val;
                I915_WRITE(DEIMR, dev_priv->irq_mask);
                POSTING_READ(DEIMR);
        }
  }
  
 +void
 +ironlake_enable_display_irq(struct drm_i915_private *dev_priv, u32 mask)
 +{
 +      ilk_update_display_irq(dev_priv, mask, mask);
 +}
 +
 +void
 +ironlake_disable_display_irq(struct drm_i915_private *dev_priv, u32 mask)
 +{
 +      ilk_update_display_irq(dev_priv, mask, 0);
 +}
 +
  /**
   * ilk_update_gt_irq - update GTIMR
   * @dev_priv: driver private
@@@ -413,38 -350,6 +413,38 @@@ void gen6_disable_rps_interrupts(struc
        synchronize_irq(dev->irq);
  }
  
 +/**
 +  * bdw_update_port_irq - update DE port interrupt
 +  * @dev_priv: driver private
 +  * @interrupt_mask: mask of interrupt bits to update
 +  * @enabled_irq_mask: mask of interrupt bits to enable
 +  */
 +static void bdw_update_port_irq(struct drm_i915_private *dev_priv,
 +                              uint32_t interrupt_mask,
 +                              uint32_t enabled_irq_mask)
 +{
 +      uint32_t new_val;
 +      uint32_t old_val;
 +
 +      assert_spin_locked(&dev_priv->irq_lock);
 +
 +      WARN_ON(enabled_irq_mask & ~interrupt_mask);
 +
 +      if (WARN_ON(!intel_irqs_enabled(dev_priv)))
 +              return;
 +
 +      old_val = I915_READ(GEN8_DE_PORT_IMR);
 +
 +      new_val = old_val;
 +      new_val &= ~interrupt_mask;
 +      new_val |= (~enabled_irq_mask & interrupt_mask);
 +
 +      if (new_val != old_val) {
 +              I915_WRITE(GEN8_DE_PORT_IMR, new_val);
 +              POSTING_READ(GEN8_DE_PORT_IMR);
 +      }
 +}
 +
  /**
   * ibx_display_interrupt_update - update SDEIMR
   * @dev_priv: driver private
@@@ -734,6 -639,32 +734,32 @@@ static int __intel_get_crtc_scanline(st
        else
                position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3;
  
+       /*
+        * On HSW, the DSL reg (0x70000) appears to return 0 if we
+        * read it just before the start of vblank.  So try it again
+        * so we don't accidentally end up spanning a vblank frame
+        * increment, causing the pipe_update_end() code to squak at us.
+        *
+        * The nature of this problem means we can't simply check the ISR
+        * bit and return the vblank start value; nor can we use the scanline
+        * debug register in the transcoder as it appears to have the same
+        * problem.  We may need to extend this to include other platforms,
+        * but so far testing only shows the problem on HSW.
+        */
+       if (IS_HASWELL(dev) && !position) {
+               int i, temp;
+               for (i = 0; i < 100; i++) {
+                       udelay(1);
+                       temp = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) &
+                               DSL_LINEMASK_GEN3;
+                       if (temp != position) {
+                               position = temp;
+                               break;
+                       }
+               }
+       }
        /*
         * See update_scanline_offset() for the details on the
         * scanline_offset adjustment.
  
  static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
                                    unsigned int flags, int *vpos, int *hpos,
-                                   ktime_t *stime, ktime_t *etime)
+                                   ktime_t *stime, ktime_t *etime,
+                                   const struct drm_display_mode *mode)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       const struct drm_display_mode *mode = &intel_crtc->base.hwmode;
        int position;
        int vbl_start, vbl_end, hsync_start, htotal, vtotal;
        bool in_vbl = true;
@@@ -905,7 -836,6 +931,6 @@@ static int i915_get_vblank_timestamp(st
        /* Helper routine in DRM core does all the work: */
        return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error,
                                                     vblank_time, flags,
-                                                    crtc,
                                                     &crtc->hwmode);
  }
  
@@@ -1333,31 -1263,7 +1358,31 @@@ static bool bxt_port_hotplug_long_detec
  {
        switch (port) {
        case PORT_A:
 -              return val & BXT_PORTA_HOTPLUG_LONG_DETECT;
 +              return val & PORTA_HOTPLUG_LONG_DETECT;
 +      case PORT_B:
 +              return val & PORTB_HOTPLUG_LONG_DETECT;
 +      case PORT_C:
 +              return val & PORTC_HOTPLUG_LONG_DETECT;
 +      default:
 +              return false;
 +      }
 +}
 +
 +static bool spt_port_hotplug2_long_detect(enum port port, u32 val)
 +{
 +      switch (port) {
 +      case PORT_E:
 +              return val & PORTE_HOTPLUG_LONG_DETECT;
 +      default:
 +              return false;
 +      }
 +}
 +
 +static bool spt_port_hotplug_long_detect(enum port port, u32 val)
 +{
 +      switch (port) {
 +      case PORT_A:
 +              return val & PORTA_HOTPLUG_LONG_DETECT;
        case PORT_B:
                return val & PORTB_HOTPLUG_LONG_DETECT;
        case PORT_C:
        }
  }
  
 +static bool ilk_port_hotplug_long_detect(enum port port, u32 val)
 +{
 +      switch (port) {
 +      case PORT_A:
 +              return val & DIGITAL_PORTA_HOTPLUG_LONG_DETECT;
 +      default:
 +              return false;
 +      }
 +}
 +
  static bool pch_port_hotplug_long_detect(enum port port, u32 val)
  {
        switch (port) {
                return val & PORTC_HOTPLUG_LONG_DETECT;
        case PORT_D:
                return val & PORTD_HOTPLUG_LONG_DETECT;
 -      case PORT_E:
 -              return val & PORTE_HOTPLUG_LONG_DETECT;
        default:
                return false;
        }
@@@ -1407,13 -1305,7 +1432,13 @@@ static bool i9xx_port_hotplug_long_dete
        }
  }
  
 -/* Get a bit mask of pins that have triggered, and which ones may be long. */
 +/*
 + * Get a bit mask of pins that have triggered, and which ones may be long.
 + * This can be called multiple times with the same masks to accumulate
 + * hotplug detection results from several registers.
 + *
 + * Note that the caller is expected to zero out the masks initially.
 + */
  static void intel_get_hpd_pins(u32 *pin_mask, u32 *long_mask,
                             u32 hotplug_trigger, u32 dig_hotplug_reg,
                             const u32 hpd[HPD_NUM_PINS],
        enum port port;
        int i;
  
 -      *pin_mask = 0;
 -      *long_mask = 0;
 -
        for_each_hpd_pin(i) {
                if ((hpd[i] & hotplug_trigger) == 0)
                        continue;
@@@ -1662,7 -1557,7 +1687,7 @@@ static void i9xx_hpd_irq_handler(struc
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
        u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT);
 -      u32 pin_mask, long_mask;
 +      u32 pin_mask = 0, long_mask = 0;
  
        if (!hotplug_status)
                return;
        if (IS_G4X(dev) || IS_VALLEYVIEW(dev)) {
                u32 hotplug_trigger = hotplug_status & HOTPLUG_INT_STATUS_G4X;
  
 -              intel_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger,
 -                                 hotplug_trigger, hpd_status_g4x,
 -                                 i9xx_port_hotplug_long_detect);
 -              intel_hpd_irq_handler(dev, pin_mask, long_mask);
 +              if (hotplug_trigger) {
 +                      intel_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger,
 +                                         hotplug_trigger, hpd_status_g4x,
 +                                         i9xx_port_hotplug_long_detect);
 +
 +                      intel_hpd_irq_handler(dev, pin_mask, long_mask);
 +              }
  
                if (hotplug_status & DP_AUX_CHANNEL_MASK_INT_STATUS_G4X)
                        dp_aux_irq_handler(dev);
        } else {
                u32 hotplug_trigger = hotplug_status & HOTPLUG_INT_STATUS_I915;
  
 -              intel_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger,
 -                                 hotplug_trigger, hpd_status_i915,
 -                                 i9xx_port_hotplug_long_detect);
 -              intel_hpd_irq_handler(dev, pin_mask, long_mask);
 +              if (hotplug_trigger) {
 +                      intel_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger,
-                                          hotplug_trigger, hpd_status_g4x,
++                                         hotplug_trigger, hpd_status_i915,
 +                                         i9xx_port_hotplug_long_detect);
 +                      intel_hpd_irq_handler(dev, pin_mask, long_mask);
 +              }
        }
  }
  
@@@ -1790,30 -1679,23 +1814,30 @@@ static irqreturn_t cherryview_irq_handl
        return ret;
  }
  
 +static void ibx_hpd_irq_handler(struct drm_device *dev, u32 hotplug_trigger,
 +                              const u32 hpd[HPD_NUM_PINS])
 +{
 +      struct drm_i915_private *dev_priv = to_i915(dev);
 +      u32 dig_hotplug_reg, pin_mask = 0, long_mask = 0;
 +
 +      dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG);
 +      I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg);
 +
 +      intel_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger,
 +                         dig_hotplug_reg, hpd,
 +                         pch_port_hotplug_long_detect);
 +
 +      intel_hpd_irq_handler(dev, pin_mask, long_mask);
 +}
 +
  static void ibx_irq_handler(struct drm_device *dev, u32 pch_iir)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
        int pipe;
        u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK;
  
 -      if (hotplug_trigger) {
 -              u32 dig_hotplug_reg, pin_mask, long_mask;
 -
 -              dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG);
 -              I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg);
 -
 -              intel_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger,
 -                                 dig_hotplug_reg, hpd_ibx,
 -                                 pch_port_hotplug_long_detect);
 -              intel_hpd_irq_handler(dev, pin_mask, long_mask);
 -      }
 +      if (hotplug_trigger)
 +              ibx_hpd_irq_handler(dev, hotplug_trigger, hpd_ibx);
  
        if (pch_iir & SDE_AUDIO_POWER_MASK) {
                int port = ffs((pch_iir & SDE_AUDIO_POWER_MASK) >>
@@@ -1904,10 -1786,38 +1928,10 @@@ static void cpt_irq_handler(struct drm_
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
        int pipe;
 -      u32 hotplug_trigger;
 -
 -      if (HAS_PCH_SPT(dev))
 -              hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_SPT;
 -      else
 -              hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_CPT;
 -
 -      if (hotplug_trigger) {
 -              u32 dig_hotplug_reg, pin_mask, long_mask;
 -
 -              dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG);
 -              I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg);
 -
 -              if (HAS_PCH_SPT(dev)) {
 -                      intel_get_hpd_pins(&pin_mask, &long_mask,
 -                                         hotplug_trigger,
 -                                         dig_hotplug_reg, hpd_spt,
 -                                         pch_port_hotplug_long_detect);
 -
 -                      /* detect PORTE HP event */
 -                      dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG2);
 -                      if (pch_port_hotplug_long_detect(PORT_E,
 -                                                       dig_hotplug_reg))
 -                              long_mask |= 1 << HPD_PORT_E;
 -              } else
 -                      intel_get_hpd_pins(&pin_mask, &long_mask,
 -                                         hotplug_trigger,
 -                                         dig_hotplug_reg, hpd_cpt,
 -                                         pch_port_hotplug_long_detect);
 +      u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_CPT;
  
 -              intel_hpd_irq_handler(dev, pin_mask, long_mask);
 -      }
 +      if (hotplug_trigger)
 +              ibx_hpd_irq_handler(dev, hotplug_trigger, hpd_cpt);
  
        if (pch_iir & SDE_AUDIO_POWER_MASK_CPT) {
                int port = ffs((pch_iir & SDE_AUDIO_POWER_MASK_CPT) >>
                cpt_serr_int_handler(dev);
  }
  
 +static void spt_irq_handler(struct drm_device *dev, u32 pch_iir)
 +{
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +      u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_SPT &
 +              ~SDE_PORTE_HOTPLUG_SPT;
 +      u32 hotplug2_trigger = pch_iir & SDE_PORTE_HOTPLUG_SPT;
 +      u32 pin_mask = 0, long_mask = 0;
 +
 +      if (hotplug_trigger) {
 +              u32 dig_hotplug_reg;
 +
 +              dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG);
 +              I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg);
 +
 +              intel_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger,
 +                                 dig_hotplug_reg, hpd_spt,
 +                                 spt_port_hotplug_long_detect);
 +      }
 +
 +      if (hotplug2_trigger) {
 +              u32 dig_hotplug_reg;
 +
 +              dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG2);
 +              I915_WRITE(PCH_PORT_HOTPLUG2, dig_hotplug_reg);
 +
 +              intel_get_hpd_pins(&pin_mask, &long_mask, hotplug2_trigger,
 +                                 dig_hotplug_reg, hpd_spt,
 +                                 spt_port_hotplug2_long_detect);
 +      }
 +
 +      if (pin_mask)
 +              intel_hpd_irq_handler(dev, pin_mask, long_mask);
 +
 +      if (pch_iir & SDE_GMBUS_CPT)
 +              gmbus_irq_handler(dev);
 +}
 +
 +static void ilk_hpd_irq_handler(struct drm_device *dev, u32 hotplug_trigger,
 +                              const u32 hpd[HPD_NUM_PINS])
 +{
 +      struct drm_i915_private *dev_priv = to_i915(dev);
 +      u32 dig_hotplug_reg, pin_mask = 0, long_mask = 0;
 +
 +      dig_hotplug_reg = I915_READ(DIGITAL_PORT_HOTPLUG_CNTRL);
 +      I915_WRITE(DIGITAL_PORT_HOTPLUG_CNTRL, dig_hotplug_reg);
 +
 +      intel_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger,
 +                         dig_hotplug_reg, hpd,
 +                         ilk_port_hotplug_long_detect);
 +
 +      intel_hpd_irq_handler(dev, pin_mask, long_mask);
 +}
 +
  static void ilk_display_irq_handler(struct drm_device *dev, u32 de_iir)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
        enum pipe pipe;
 +      u32 hotplug_trigger = de_iir & DE_DP_A_HOTPLUG;
 +
 +      if (hotplug_trigger)
 +              ilk_hpd_irq_handler(dev, hotplug_trigger, hpd_ilk);
  
        if (de_iir & DE_AUX_CHANNEL_A)
                dp_aux_irq_handler(dev);
@@@ -2048,10 -1901,6 +2072,10 @@@ static void ivb_display_irq_handler(str
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
        enum pipe pipe;
 +      u32 hotplug_trigger = de_iir & DE_DP_A_HOTPLUG_IVB;
 +
 +      if (hotplug_trigger)
 +              ilk_hpd_irq_handler(dev, hotplug_trigger, hpd_ivb);
  
        if (de_iir & DE_ERR_INT_IVB)
                ivb_err_int_handler(dev);
@@@ -2164,19 -2013,27 +2188,19 @@@ static irqreturn_t ironlake_irq_handler
        return ret;
  }
  
 -static void bxt_hpd_handler(struct drm_device *dev, uint32_t iir_status)
 +static void bxt_hpd_irq_handler(struct drm_device *dev, u32 hotplug_trigger,
 +                              const u32 hpd[HPD_NUM_PINS])
  {
 -      struct drm_i915_private *dev_priv = dev->dev_private;
 -      u32 hp_control, hp_trigger;
 -      u32 pin_mask, long_mask;
 -
 -      /* Get the status */
 -      hp_trigger = iir_status & BXT_DE_PORT_HOTPLUG_MASK;
 -      hp_control = I915_READ(BXT_HOTPLUG_CTL);
 +      struct drm_i915_private *dev_priv = to_i915(dev);
 +      u32 dig_hotplug_reg, pin_mask = 0, long_mask = 0;
  
 -      /* Hotplug not enabled ? */
 -      if (!(hp_control & BXT_HOTPLUG_CTL_MASK)) {
 -              DRM_ERROR("Interrupt when HPD disabled\n");
 -              return;
 -      }
 +      dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG);
 +      I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg);
  
 -      /* Clear sticky bits in hpd status */
 -      I915_WRITE(BXT_HOTPLUG_CTL, hp_control);
 +      intel_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger,
 +                         dig_hotplug_reg, hpd,
 +                         bxt_port_hotplug_long_detect);
  
 -      intel_get_hpd_pins(&pin_mask, &long_mask, hp_trigger, hp_control,
 -                         hpd_bxt, bxt_port_hotplug_long_detect);
        intel_hpd_irq_handler(dev, pin_mask, long_mask);
  }
  
@@@ -2193,7 -2050,7 +2217,7 @@@ static irqreturn_t gen8_irq_handler(in
        if (!intel_irqs_enabled(dev_priv))
                return IRQ_NONE;
  
 -      if (IS_GEN9(dev))
 +      if (INTEL_INFO(dev_priv)->gen >= 9)
                aux_mask |=  GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C |
                        GEN9_AUX_CHANNEL_D;
  
                tmp = I915_READ(GEN8_DE_PORT_IIR);
                if (tmp) {
                        bool found = false;
 +                      u32 hotplug_trigger = 0;
 +
 +                      if (IS_BROXTON(dev_priv))
 +                              hotplug_trigger = tmp & BXT_DE_PORT_HOTPLUG_MASK;
 +                      else if (IS_BROADWELL(dev_priv))
 +                              hotplug_trigger = tmp & GEN8_PORT_DP_A_HOTPLUG;
  
                        I915_WRITE(GEN8_DE_PORT_IIR, tmp);
                        ret = IRQ_HANDLED;
                                found = true;
                        }
  
 -                      if (IS_BROXTON(dev) && tmp & BXT_DE_PORT_HOTPLUG_MASK) {
 -                              bxt_hpd_handler(dev, tmp);
 +                      if (hotplug_trigger) {
 +                              if (IS_BROXTON(dev))
 +                                      bxt_hpd_irq_handler(dev, hotplug_trigger, hpd_bxt);
 +                              else
 +                                      ilk_hpd_irq_handler(dev, hotplug_trigger, hpd_bdw);
                                found = true;
                        }
  
                            intel_pipe_handle_vblank(dev, pipe))
                                intel_check_page_flip(dev, pipe);
  
 -                      if (IS_GEN9(dev))
 +                      if (INTEL_INFO(dev_priv)->gen >= 9)
                                flip_done = pipe_iir & GEN9_PIPE_PLANE1_FLIP_DONE;
                        else
                                flip_done = pipe_iir & GEN8_PIPE_PRIMARY_FLIP_DONE;
                                                                    pipe);
  
  
 -                      if (IS_GEN9(dev))
 +                      if (INTEL_INFO(dev_priv)->gen >= 9)
                                fault_errors = pipe_iir & GEN9_DE_PIPE_IRQ_FAULT_ERRORS;
                        else
                                fault_errors = pipe_iir & GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
                if (pch_iir) {
                        I915_WRITE(SDEIIR, pch_iir);
                        ret = IRQ_HANDLED;
 -                      cpt_irq_handler(dev, pch_iir);
 +
 +                      if (HAS_PCH_SPT(dev_priv))
 +                              spt_irq_handler(dev, pch_iir);
 +                      else
 +                              cpt_irq_handler(dev, pch_iir);
                } else
                        DRM_ERROR("The master control interrupt lied (SDE)!\n");
  
@@@ -2434,7 -2278,7 +2458,7 @@@ static void i915_reset_and_wakeup(struc
                        kobject_uevent_env(&dev->primary->kdev->kobj,
                                           KOBJ_CHANGE, reset_done_event);
                } else {
-                       atomic_set_mask(I915_WEDGED, &error->reset_counter);
+                       atomic_or(I915_WEDGED, &error->reset_counter);
                }
  
                /*
@@@ -2562,7 -2406,7 +2586,7 @@@ void i915_handle_error(struct drm_devic
        i915_report_and_clear_eir(dev);
  
        if (wedged) {
-               atomic_set_mask(I915_RESET_IN_PROGRESS_FLAG,
+               atomic_or(I915_RESET_IN_PROGRESS_FLAG,
                                &dev_priv->gpu_error.reset_counter);
  
                /*
@@@ -3088,7 -2932,7 +3112,7 @@@ static void vlv_display_irq_reset(struc
  {
        enum pipe pipe;
  
 -      I915_WRITE(PORT_HOTPLUG_EN, 0);
 +      i915_hotplug_interrupt_update(dev_priv, 0xFFFFFFFF, 0);
        I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
  
        for_each_pipe(dev_priv, pipe)
@@@ -3182,124 -3026,86 +3206,124 @@@ static void cherryview_irq_preinstall(s
        vlv_display_irq_reset(dev_priv);
  }
  
 +static u32 intel_hpd_enabled_irqs(struct drm_device *dev,
 +                                const u32 hpd[HPD_NUM_PINS])
 +{
 +      struct drm_i915_private *dev_priv = to_i915(dev);
 +      struct intel_encoder *encoder;
 +      u32 enabled_irqs = 0;
 +
 +      for_each_intel_encoder(dev, encoder)
 +              if (dev_priv->hotplug.stats[encoder->hpd_pin].state == HPD_ENABLED)
 +                      enabled_irqs |= hpd[encoder->hpd_pin];
 +
 +      return enabled_irqs;
 +}
 +
  static void ibx_hpd_irq_setup(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
 -      struct intel_encoder *intel_encoder;
 -      u32 hotplug_irqs, hotplug, enabled_irqs = 0;
 +      u32 hotplug_irqs, hotplug, enabled_irqs;
  
        if (HAS_PCH_IBX(dev)) {
                hotplug_irqs = SDE_HOTPLUG_MASK;
 -              for_each_intel_encoder(dev, intel_encoder)
 -                      if (dev_priv->hotplug.stats[intel_encoder->hpd_pin].state == HPD_ENABLED)
 -                              enabled_irqs |= hpd_ibx[intel_encoder->hpd_pin];
 -      } else if (HAS_PCH_SPT(dev)) {
 -              hotplug_irqs = SDE_HOTPLUG_MASK_SPT;
 -              for_each_intel_encoder(dev, intel_encoder)
 -                      if (dev_priv->hotplug.stats[intel_encoder->hpd_pin].state == HPD_ENABLED)
 -                              enabled_irqs |= hpd_spt[intel_encoder->hpd_pin];
 +              enabled_irqs = intel_hpd_enabled_irqs(dev, hpd_ibx);
        } else {
                hotplug_irqs = SDE_HOTPLUG_MASK_CPT;
 -              for_each_intel_encoder(dev, intel_encoder)
 -                      if (dev_priv->hotplug.stats[intel_encoder->hpd_pin].state == HPD_ENABLED)
 -                              enabled_irqs |= hpd_cpt[intel_encoder->hpd_pin];
 +              enabled_irqs = intel_hpd_enabled_irqs(dev, hpd_cpt);
        }
  
        ibx_display_interrupt_update(dev_priv, hotplug_irqs, enabled_irqs);
  
        /*
         * Enable digital hotplug on the PCH, and configure the DP short pulse
 -       * duration to 2ms (which is the minimum in the Display Port spec)
 -       *
 -       * This register is the same on all known PCH chips.
 +       * duration to 2ms (which is the minimum in the Display Port spec).
 +       * The pulse duration bits are reserved on LPT+.
         */
        hotplug = I915_READ(PCH_PORT_HOTPLUG);
        hotplug &= ~(PORTD_PULSE_DURATION_MASK|PORTC_PULSE_DURATION_MASK|PORTB_PULSE_DURATION_MASK);
        hotplug |= PORTD_HOTPLUG_ENABLE | PORTD_PULSE_DURATION_2ms;
        hotplug |= PORTC_HOTPLUG_ENABLE | PORTC_PULSE_DURATION_2ms;
        hotplug |= PORTB_HOTPLUG_ENABLE | PORTB_PULSE_DURATION_2ms;
 +      /*
 +       * When CPU and PCH are on the same package, port A
 +       * HPD must be enabled in both north and south.
 +       */
 +      if (HAS_PCH_LPT_LP(dev))
 +              hotplug |= PORTA_HOTPLUG_ENABLE;
        I915_WRITE(PCH_PORT_HOTPLUG, hotplug);
 +}
  
 -      /* enable SPT PORTE hot plug */
 -      if (HAS_PCH_SPT(dev)) {
 -              hotplug = I915_READ(PCH_PORT_HOTPLUG2);
 -              hotplug |= PORTE_HOTPLUG_ENABLE;
 -              I915_WRITE(PCH_PORT_HOTPLUG2, hotplug);
 -      }
 +static void spt_hpd_irq_setup(struct drm_device *dev)
 +{
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +      u32 hotplug_irqs, hotplug, enabled_irqs;
 +
 +      hotplug_irqs = SDE_HOTPLUG_MASK_SPT;
 +      enabled_irqs = intel_hpd_enabled_irqs(dev, hpd_spt);
 +
 +      ibx_display_interrupt_update(dev_priv, hotplug_irqs, enabled_irqs);
 +
 +      /* Enable digital hotplug on the PCH */
 +      hotplug = I915_READ(PCH_PORT_HOTPLUG);
 +      hotplug |= PORTD_HOTPLUG_ENABLE | PORTC_HOTPLUG_ENABLE |
 +              PORTB_HOTPLUG_ENABLE | PORTA_HOTPLUG_ENABLE;
 +      I915_WRITE(PCH_PORT_HOTPLUG, hotplug);
 +
 +      hotplug = I915_READ(PCH_PORT_HOTPLUG2);
 +      hotplug |= PORTE_HOTPLUG_ENABLE;
 +      I915_WRITE(PCH_PORT_HOTPLUG2, hotplug);
  }
  
 -static void bxt_hpd_irq_setup(struct drm_device *dev)
 +static void ilk_hpd_irq_setup(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
 -      struct intel_encoder *intel_encoder;
 -      u32 hotplug_port = 0;
 -      u32 hotplug_ctrl;
 -
 -      /* Now, enable HPD */
 -      for_each_intel_encoder(dev, intel_encoder) {
 -              if (dev_priv->hotplug.stats[intel_encoder->hpd_pin].state
 -                              == HPD_ENABLED)
 -                      hotplug_port |= hpd_bxt[intel_encoder->hpd_pin];
 +      u32 hotplug_irqs, hotplug, enabled_irqs;
 +
 +      if (INTEL_INFO(dev)->gen >= 8) {
 +              hotplug_irqs = GEN8_PORT_DP_A_HOTPLUG;
 +              enabled_irqs = intel_hpd_enabled_irqs(dev, hpd_bdw);
 +
 +              bdw_update_port_irq(dev_priv, hotplug_irqs, enabled_irqs);
 +      } else if (INTEL_INFO(dev)->gen >= 7) {
 +              hotplug_irqs = DE_DP_A_HOTPLUG_IVB;
 +              enabled_irqs = intel_hpd_enabled_irqs(dev, hpd_ivb);
 +
 +              ilk_update_display_irq(dev_priv, hotplug_irqs, enabled_irqs);
 +      } else {
 +              hotplug_irqs = DE_DP_A_HOTPLUG;
 +              enabled_irqs = intel_hpd_enabled_irqs(dev, hpd_ilk);
 +
 +              ilk_update_display_irq(dev_priv, hotplug_irqs, enabled_irqs);
        }
  
 -      /* Mask all HPD control bits */
 -      hotplug_ctrl = I915_READ(BXT_HOTPLUG_CTL) & ~BXT_HOTPLUG_CTL_MASK;
 +      /*
 +       * Enable digital hotplug on the CPU, and configure the DP short pulse
 +       * duration to 2ms (which is the minimum in the Display Port spec)
 +       * The pulse duration bits are reserved on HSW+.
 +       */
 +      hotplug = I915_READ(DIGITAL_PORT_HOTPLUG_CNTRL);
 +      hotplug &= ~DIGITAL_PORTA_PULSE_DURATION_MASK;
 +      hotplug |= DIGITAL_PORTA_HOTPLUG_ENABLE | DIGITAL_PORTA_PULSE_DURATION_2ms;
 +      I915_WRITE(DIGITAL_PORT_HOTPLUG_CNTRL, hotplug);
 +
 +      ibx_hpd_irq_setup(dev);
 +}
 +
 +static void bxt_hpd_irq_setup(struct drm_device *dev)
 +{
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +      u32 hotplug_irqs, hotplug, enabled_irqs;
  
 -      /* Enable requested port in hotplug control */
 -      /* TODO: implement (short) HPD support on port A */
 -      WARN_ON_ONCE(hotplug_port & BXT_DE_PORT_HP_DDIA);
 -      if (hotplug_port & BXT_DE_PORT_HP_DDIB)
 -              hotplug_ctrl |= BXT_DDIB_HPD_ENABLE;
 -      if (hotplug_port & BXT_DE_PORT_HP_DDIC)
 -              hotplug_ctrl |= BXT_DDIC_HPD_ENABLE;
 -      I915_WRITE(BXT_HOTPLUG_CTL, hotplug_ctrl);
 +      enabled_irqs = intel_hpd_enabled_irqs(dev, hpd_bxt);
 +      hotplug_irqs = BXT_DE_PORT_HOTPLUG_MASK;
  
 -      /* Unmask DDI hotplug in IMR */
 -      hotplug_ctrl = I915_READ(GEN8_DE_PORT_IMR) & ~hotplug_port;
 -      I915_WRITE(GEN8_DE_PORT_IMR, hotplug_ctrl);
 +      bdw_update_port_irq(dev_priv, hotplug_irqs, enabled_irqs);
  
 -      /* Enable DDI hotplug in IER */
 -      hotplug_ctrl = I915_READ(GEN8_DE_PORT_IER) | hotplug_port;
 -      I915_WRITE(GEN8_DE_PORT_IER, hotplug_ctrl);
 -      POSTING_READ(GEN8_DE_PORT_IER);
 +      hotplug = I915_READ(PCH_PORT_HOTPLUG);
 +      hotplug |= PORTC_HOTPLUG_ENABLE | PORTB_HOTPLUG_ENABLE |
 +              PORTA_HOTPLUG_ENABLE;
 +      I915_WRITE(PCH_PORT_HOTPLUG, hotplug);
  }
  
  static void ibx_irq_postinstall(struct drm_device *dev)
@@@ -3367,17 -3173,15 +3391,17 @@@ static int ironlake_irq_postinstall(str
                                DE_PLANEB_FLIP_DONE_IVB |
                                DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB);
                extra_mask = (DE_PIPEC_VBLANK_IVB | DE_PIPEB_VBLANK_IVB |
 -                            DE_PIPEA_VBLANK_IVB | DE_ERR_INT_IVB);
 +                            DE_PIPEA_VBLANK_IVB | DE_ERR_INT_IVB |
 +                            DE_DP_A_HOTPLUG_IVB);
        } else {
                display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT |
                                DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE |
                                DE_AUX_CHANNEL_A |
                                DE_PIPEB_CRC_DONE | DE_PIPEA_CRC_DONE |
                                DE_POISON);
 -              extra_mask = DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT |
 -                              DE_PIPEB_FIFO_UNDERRUN | DE_PIPEA_FIFO_UNDERRUN;
 +              extra_mask = (DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT |
 +                            DE_PIPEB_FIFO_UNDERRUN | DE_PIPEA_FIFO_UNDERRUN |
 +                            DE_DP_A_HOTPLUG);
        }
  
        dev_priv->irq_mask = ~display_mask;
@@@ -3504,7 -3308,7 +3528,7 @@@ static void vlv_display_irq_postinstall
  {
        dev_priv->irq_mask = ~0;
  
 -      I915_WRITE(PORT_HOTPLUG_EN, 0);
 +      i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0);
        POSTING_READ(PORT_HOTPLUG_EN);
  
        I915_WRITE(VLV_IIR, 0xffffffff);
@@@ -3573,31 -3377,24 +3597,31 @@@ static void gen8_de_irq_postinstall(str
  {
        uint32_t de_pipe_masked = GEN8_PIPE_CDCLK_CRC_DONE;
        uint32_t de_pipe_enables;
 -      int pipe;
 -      u32 de_port_en = GEN8_AUX_CHANNEL_A;
 +      u32 de_port_masked = GEN8_AUX_CHANNEL_A;
 +      u32 de_port_enables;
 +      enum pipe pipe;
  
 -      if (IS_GEN9(dev_priv)) {
 +      if (INTEL_INFO(dev_priv)->gen >= 9) {
                de_pipe_masked |= GEN9_PIPE_PLANE1_FLIP_DONE |
                                  GEN9_DE_PIPE_IRQ_FAULT_ERRORS;
 -              de_port_en |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C |
 -                      GEN9_AUX_CHANNEL_D;
 -
 +              de_port_masked |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C |
 +                                GEN9_AUX_CHANNEL_D;
                if (IS_BROXTON(dev_priv))
 -                      de_port_en |= BXT_DE_PORT_GMBUS;
 -      } else
 +                      de_port_masked |= BXT_DE_PORT_GMBUS;
 +      } else {
                de_pipe_masked |= GEN8_PIPE_PRIMARY_FLIP_DONE |
                                  GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
 +      }
  
        de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK |
                                           GEN8_PIPE_FIFO_UNDERRUN;
  
 +      de_port_enables = de_port_masked;
 +      if (IS_BROXTON(dev_priv))
 +              de_port_enables |= BXT_DE_PORT_HOTPLUG_MASK;
 +      else if (IS_BROADWELL(dev_priv))
 +              de_port_enables |= GEN8_PORT_DP_A_HOTPLUG;
 +
        dev_priv->de_irq_mask[PIPE_A] = ~de_pipe_masked;
        dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked;
        dev_priv->de_irq_mask[PIPE_C] = ~de_pipe_masked;
                                          dev_priv->de_irq_mask[pipe],
                                          de_pipe_enables);
  
 -      GEN5_IRQ_INIT(GEN8_DE_PORT_, ~de_port_en, de_port_en);
 +      GEN5_IRQ_INIT(GEN8_DE_PORT_, ~de_port_masked, de_port_enables);
  }
  
  static int gen8_irq_postinstall(struct drm_device *dev)
@@@ -3878,7 -3675,7 +3902,7 @@@ static void i915_irq_preinstall(struct 
        int pipe;
  
        if (I915_HAS_HOTPLUG(dev)) {
 -              I915_WRITE(PORT_HOTPLUG_EN, 0);
 +              i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0);
                I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
        }
  
@@@ -3912,7 -3709,7 +3936,7 @@@ static int i915_irq_postinstall(struct 
                I915_USER_INTERRUPT;
  
        if (I915_HAS_HOTPLUG(dev)) {
 -              I915_WRITE(PORT_HOTPLUG_EN, 0);
 +              i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0);
                POSTING_READ(PORT_HOTPLUG_EN);
  
                /* Enable in IER... */
@@@ -4074,7 -3871,7 +4098,7 @@@ static void i915_irq_uninstall(struct d
        int pipe;
  
        if (I915_HAS_HOTPLUG(dev)) {
 -              I915_WRITE(PORT_HOTPLUG_EN, 0);
 +              i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0);
                I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
        }
  
@@@ -4095,7 -3892,7 +4119,7 @@@ static void i965_irq_preinstall(struct 
        struct drm_i915_private *dev_priv = dev->dev_private;
        int pipe;
  
 -      I915_WRITE(PORT_HOTPLUG_EN, 0);
 +      i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0);
        I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
  
        I915_WRITE(HWSTAM, 0xeffe);
@@@ -4156,7 -3953,7 +4180,7 @@@ static int i965_irq_postinstall(struct 
        I915_WRITE(IER, enable_mask);
        POSTING_READ(IER);
  
 -      I915_WRITE(PORT_HOTPLUG_EN, 0);
 +      i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0);
        POSTING_READ(PORT_HOTPLUG_EN);
  
        i915_enable_asle_pipestat(dev);
  static void i915_hpd_irq_setup(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
 -      struct intel_encoder *intel_encoder;
        u32 hotplug_en;
  
        assert_spin_locked(&dev_priv->irq_lock);
  
 -      hotplug_en = I915_READ(PORT_HOTPLUG_EN);
 -      hotplug_en &= ~HOTPLUG_INT_EN_MASK;
        /* Note HDMI and DP share hotplug bits */
        /* enable bits are the same for all generations */
 -      for_each_intel_encoder(dev, intel_encoder)
 -              if (dev_priv->hotplug.stats[intel_encoder->hpd_pin].state == HPD_ENABLED)
 -                      hotplug_en |= hpd_mask_i915[intel_encoder->hpd_pin];
 +      hotplug_en = intel_hpd_enabled_irqs(dev, hpd_mask_i915);
        /* Programming the CRT detection parameters tends
           to generate a spurious hotplug event about three
           seconds later.  So just do it once.
        */
        if (IS_G4X(dev))
                hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64;
 -      hotplug_en &= ~CRT_HOTPLUG_VOLTAGE_COMPARE_MASK;
        hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50;
  
        /* Ignore TV since it's buggy */
 -      I915_WRITE(PORT_HOTPLUG_EN, hotplug_en);
 +      i915_hotplug_interrupt_update_locked(dev_priv,
 +                                    (HOTPLUG_INT_EN_MASK
 +                                     | CRT_HOTPLUG_VOLTAGE_COMPARE_MASK),
 +                                    hotplug_en);
  }
  
  static irqreturn_t i965_irq_handler(int irq, void *arg)
@@@ -4299,7 -4099,7 +4323,7 @@@ static void i965_irq_uninstall(struct d
        if (!dev_priv)
                return;
  
 -      I915_WRITE(PORT_HOTPLUG_EN, 0);
 +      i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0);
        I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
  
        I915_WRITE(HWSTAM, 0xffffffff);
@@@ -4387,12 -4187,10 +4411,12 @@@ void intel_irq_init(struct drm_i915_pri
                dev->driver->irq_uninstall = gen8_irq_uninstall;
                dev->driver->enable_vblank = gen8_enable_vblank;
                dev->driver->disable_vblank = gen8_disable_vblank;
 -              if (HAS_PCH_SPLIT(dev))
 -                      dev_priv->display.hpd_irq_setup = ibx_hpd_irq_setup;
 -              else
 +              if (IS_BROXTON(dev))
                        dev_priv->display.hpd_irq_setup = bxt_hpd_irq_setup;
 +              else if (HAS_PCH_SPT(dev))
 +                      dev_priv->display.hpd_irq_setup = spt_hpd_irq_setup;
 +              else
 +                      dev_priv->display.hpd_irq_setup = ilk_hpd_irq_setup;
        } else if (HAS_PCH_SPLIT(dev)) {
                dev->driver->irq_handler = ironlake_irq_handler;
                dev->driver->irq_preinstall = ironlake_irq_reset;
                dev->driver->irq_uninstall = ironlake_irq_uninstall;
                dev->driver->enable_vblank = ironlake_enable_vblank;
                dev->driver->disable_vblank = ironlake_disable_vblank;
 -              dev_priv->display.hpd_irq_setup = ibx_hpd_irq_setup;
 +              dev_priv->display.hpd_irq_setup = ilk_hpd_irq_setup;
        } else {
                if (INTEL_INFO(dev_priv)->gen == 2) {
                        dev->driver->irq_preinstall = i8xx_irq_preinstall;
index c8acc2952f82f042015888511a13455091aab132,c19e669ffe504e32218afd4aee47670afc3982c9..68421c273c8c146440199c12d7cc0834f989aaee
@@@ -42,7 -42,7 +42,7 @@@ find_section(const void *_bdb, int sect
        const struct bdb_header *bdb = _bdb;
        const u8 *base = _bdb;
        int index = 0;
-       u16 total, current_size;
+       u32 total, current_size;
        u8 current_id;
  
        /* skip to first section */
                current_size = *((const u16 *)(base + index));
                index += 2;
  
+               /* The MIPI Sequence Block v3+ has a separate size field. */
+               if (current_id == BDB_MIPI_SEQUENCE && *(base + index) >= 3)
+                       current_size = *((const u32 *)(base + index + 1));
                if (index + current_size > total)
                        return NULL;
  
@@@ -799,6 -803,12 +803,12 @@@ parse_mipi(struct drm_i915_private *dev
                return;
        }
  
+       /* Fail gracefully for forward incompatible sequence block. */
+       if (sequence->version >= 3) {
+               DRM_ERROR("Unable to parse MIPI Sequence Block v3+\n");
+               return;
+       }
        DRM_DEBUG_DRIVER("Found MIPI sequence block\n");
  
        block_size = get_blocksize(sequence);
@@@ -1340,3 -1350,21 +1350,3 @@@ intel_parse_bios(struct drm_device *dev
  
        return 0;
  }
 -
 -/* Ensure that vital registers have been initialised, even if the BIOS
 - * is absent or just failing to do its job.
 - */
 -void intel_setup_bios(struct drm_device *dev)
 -{
 -      struct drm_i915_private *dev_priv = dev->dev_private;
 -
 -       /* Set the Panel Power On/Off timings if uninitialized. */
 -      if (!HAS_PCH_SPLIT(dev) &&
 -          I915_READ(PP_ON_DELAYS) == 0 && I915_READ(PP_OFF_DELAYS) == 0) {
 -              /* Set T2 to 40ms and T5 to 200ms */
 -              I915_WRITE(PP_ON_DELAYS, 0x019007d0);
 -
 -              /* Set T3 to 35ms and Tx to 200ms */
 -              I915_WRITE(PP_OFF_DELAYS, 0x015e07d0);
 -      }
 -}
index 61b4a4744de5aa563d257879324032da0ceab558,d0f1b8d833cd2d890e0328df50cf5839cd3fba2f..3427dd41d682139cc3fcc4c19283f3a4c7f39b6a
   */
  
  #define I915_CSR_SKL "i915/skl_dmc_ver1.bin"
 +#define I915_CSR_BXT "i915/bxt_dmc_ver1.bin"
  
  MODULE_FIRMWARE(I915_CSR_SKL);
 +MODULE_FIRMWARE(I915_CSR_BXT);
  
  /*
  * SKL CSR registers for DC5 and DC6
  */
 -#define CSR_PROGRAM_BASE              0x80000
 +#define CSR_PROGRAM(i)                        (0x80000 + (i) * 4)
  #define CSR_SSP_BASE_ADDR_GEN9                0x00002FC0
  #define CSR_HTP_ADDR_SKL              0x00500034
  #define CSR_SSP_BASE                  0x8F074
@@@ -183,19 -181,11 +183,19 @@@ static const struct stepping_info skl_s
                {'G', '0'}, {'H', '0'}, {'I', '0'}
  };
  
 +static struct stepping_info bxt_stepping_info[] = {
 +      {'A', '0'}, {'A', '1'}, {'A', '2'},
 +      {'B', '0'}, {'B', '1'}, {'B', '2'}
 +};
 +
  static char intel_get_stepping(struct drm_device *dev)
  {
        if (IS_SKYLAKE(dev) && (dev->pdev->revision <
                        ARRAY_SIZE(skl_stepping_info)))
                return skl_stepping_info[dev->pdev->revision].stepping;
 +      else if (IS_BROXTON(dev) && (dev->pdev->revision <
 +                              ARRAY_SIZE(bxt_stepping_info)))
 +              return bxt_stepping_info[dev->pdev->revision].stepping;
        else
                return -ENODATA;
  }
@@@ -205,9 -195,6 +205,9 @@@ static char intel_get_substepping(struc
        if (IS_SKYLAKE(dev) && (dev->pdev->revision <
                        ARRAY_SIZE(skl_stepping_info)))
                return skl_stepping_info[dev->pdev->revision].substepping;
 +      else if (IS_BROXTON(dev) && (dev->pdev->revision <
 +                      ARRAY_SIZE(bxt_stepping_info)))
 +              return bxt_stepping_info[dev->pdev->revision].substepping;
        else
                return -ENODATA;
  }
@@@ -268,7 -255,8 +268,7 @@@ void intel_csr_load_program(struct drm_
        mutex_lock(&dev_priv->csr_lock);
        fw_size = dev_priv->csr.dmc_fw_size;
        for (i = 0; i < fw_size; i++)
 -              I915_WRITE(CSR_PROGRAM_BASE + i * 4,
 -                      payload[i]);
 +              I915_WRITE(CSR_PROGRAM(i), payload[i]);
  
        for (i = 0; i < dev_priv->csr.mmio_count; i++) {
                I915_WRITE(dev_priv->csr.mmioaddr[i],
@@@ -362,7 -350,7 +362,7 @@@ static void finish_csr_load(const struc
        }
        csr->mmio_count = dmc_header->mmio_count;
        for (i = 0; i < dmc_header->mmio_count; i++) {
-               if (dmc_header->mmioaddr[i] < CSR_MMIO_START_RANGE &&
+               if (dmc_header->mmioaddr[i] < CSR_MMIO_START_RANGE ||
                        dmc_header->mmioaddr[i] > CSR_MMIO_END_RANGE) {
                        DRM_ERROR(" Firmware has wrong mmio address 0x%x\n",
                                                dmc_header->mmioaddr[i]);
@@@ -421,8 -409,6 +421,8 @@@ void intel_csr_ucode_init(struct drm_de
  
        if (IS_SKYLAKE(dev))
                csr->fw_path = I915_CSR_SKL;
 +      else if (IS_BROXTON(dev_priv))
 +              csr->fw_path = I915_CSR_BXT;
        else {
                DRM_ERROR("Unexpected: no known CSR firmware for platform\n");
                intel_csr_load_status_set(dev_priv, FW_FAILED);
@@@ -468,10 -454,10 +468,10 @@@ void intel_csr_ucode_fini(struct drm_de
  
  void assert_csr_loaded(struct drm_i915_private *dev_priv)
  {
 -      WARN(intel_csr_load_status_get(dev_priv) != FW_LOADED,
 -           "CSR is not loaded.\n");
 -      WARN(!I915_READ(CSR_PROGRAM_BASE),
 -                              "CSR program storage start is NULL\n");
 -      WARN(!I915_READ(CSR_SSP_BASE), "CSR SSP Base Not fine\n");
 -      WARN(!I915_READ(CSR_HTP_SKL), "CSR HTP Not fine\n");
 +      WARN_ONCE(intel_csr_load_status_get(dev_priv) != FW_LOADED,
 +                "CSR is not loaded.\n");
 +      WARN_ONCE(!I915_READ(CSR_PROGRAM(0)),
 +                "CSR program storage start is NULL\n");
 +      WARN_ONCE(!I915_READ(CSR_SSP_BASE), "CSR SSP Base Not fine\n");
 +      WARN_ONCE(!I915_READ(CSR_HTP_SKL), "CSR HTP Not fine\n");
  }
index 9b1989166dbcd90b3e1cae5259ae256c890dd4c9,0379f14271de758a843712eb8f01ebd6b9a51586..184725770ae7ec19610149179e05b29e12d70581
@@@ -72,10 -72,6 +72,10 @@@ static const uint32_t skl_primary_forma
        DRM_FORMAT_ABGR8888,
        DRM_FORMAT_XRGB2101010,
        DRM_FORMAT_XBGR2101010,
 +      DRM_FORMAT_YUYV,
 +      DRM_FORMAT_YVYU,
 +      DRM_FORMAT_UYVY,
 +      DRM_FORMAT_VYUY,
  };
  
  /* Cursor formats */
@@@ -112,9 -108,6 +112,9 @@@ static void skl_init_scalers(struct drm
        struct intel_crtc_state *crtc_state);
  static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state,
                           int num_connectors);
 +static void skylake_pfit_enable(struct intel_crtc *crtc);
 +static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force);
 +static void ironlake_pfit_enable(struct intel_crtc *crtc);
  static void intel_modeset_setup_hw_state(struct drm_device *dev);
  
  typedef struct {
@@@ -142,39 -135,6 +142,39 @@@ intel_pch_rawclk(struct drm_device *dev
        return I915_READ(PCH_RAWCLK_FREQ) & RAWCLK_FREQ_MASK;
  }
  
 +/* hrawclock is 1/4 the FSB frequency */
 +int intel_hrawclk(struct drm_device *dev)
 +{
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +      uint32_t clkcfg;
 +
 +      /* There is no CLKCFG reg in Valleyview. VLV hrawclk is 200 MHz */
 +      if (IS_VALLEYVIEW(dev))
 +              return 200;
 +
 +      clkcfg = I915_READ(CLKCFG);
 +      switch (clkcfg & CLKCFG_FSB_MASK) {
 +      case CLKCFG_FSB_400:
 +              return 100;
 +      case CLKCFG_FSB_533:
 +              return 133;
 +      case CLKCFG_FSB_667:
 +              return 166;
 +      case CLKCFG_FSB_800:
 +              return 200;
 +      case CLKCFG_FSB_1067:
 +              return 266;
 +      case CLKCFG_FSB_1333:
 +              return 333;
 +      /* these two are just a guess; one of them might be right */
 +      case CLKCFG_FSB_1600:
 +      case CLKCFG_FSB_1600_ALT:
 +              return 400;
 +      default:
 +              return 133;
 +      }
 +}
 +
  static inline u32 /* units of 100MHz */
  intel_fdi_link_freq(struct drm_device *dev)
  {
@@@ -1101,6 -1061,54 +1101,6 @@@ static void intel_wait_for_pipe_off(str
        }
  }
  
 -/*
 - * ibx_digital_port_connected - is the specified port connected?
 - * @dev_priv: i915 private structure
 - * @port: the port to test
 - *
 - * Returns true if @port is connected, false otherwise.
 - */
 -bool ibx_digital_port_connected(struct drm_i915_private *dev_priv,
 -                              struct intel_digital_port *port)
 -{
 -      u32 bit;
 -
 -      if (HAS_PCH_IBX(dev_priv->dev)) {
 -              switch (port->port) {
 -              case PORT_B:
 -                      bit = SDE_PORTB_HOTPLUG;
 -                      break;
 -              case PORT_C:
 -                      bit = SDE_PORTC_HOTPLUG;
 -                      break;
 -              case PORT_D:
 -                      bit = SDE_PORTD_HOTPLUG;
 -                      break;
 -              default:
 -                      return true;
 -              }
 -      } else {
 -              switch (port->port) {
 -              case PORT_B:
 -                      bit = SDE_PORTB_HOTPLUG_CPT;
 -                      break;
 -              case PORT_C:
 -                      bit = SDE_PORTC_HOTPLUG_CPT;
 -                      break;
 -              case PORT_D:
 -                      bit = SDE_PORTD_HOTPLUG_CPT;
 -                      break;
 -              case PORT_E:
 -                      bit = SDE_PORTE_HOTPLUG_SPT;
 -                      break;
 -              default:
 -                      return true;
 -              }
 -      }
 -
 -      return I915_READ(SDEISR) & bit;
 -}
 -
  static const char *state_string(bool enabled)
  {
        return enabled ? "on" : "off";
@@@ -1577,6 -1585,26 +1577,6 @@@ static void assert_pch_ports_disabled(s
        assert_pch_hdmi_disabled(dev_priv, pipe, PCH_HDMID);
  }
  
 -static void intel_init_dpio(struct drm_device *dev)
 -{
 -      struct drm_i915_private *dev_priv = dev->dev_private;
 -
 -      if (!IS_VALLEYVIEW(dev))
 -              return;
 -
 -      /*
 -       * IOSF_PORT_DPIO is used for VLV x2 PHY (DP/HDMI B and C),
 -       * CHV x1 PHY (DP/HDMI D)
 -       * IOSF_PORT_DPIO_2 is used for CHV x2 PHY (DP/HDMI B and C)
 -       */
 -      if (IS_CHERRYVIEW(dev)) {
 -              DPIO_PHY_IOSF_PORT(DPIO_PHY0) = IOSF_PORT_DPIO_2;
 -              DPIO_PHY_IOSF_PORT(DPIO_PHY1) = IOSF_PORT_DPIO;
 -      } else {
 -              DPIO_PHY_IOSF_PORT(DPIO_PHY0) = IOSF_PORT_DPIO;
 -      }
 -}
 -
  static void vlv_enable_pll(struct intel_crtc *crtc,
                           const struct intel_crtc_state *pipe_config)
  {
@@@ -1803,6 -1831,17 +1803,6 @@@ static void chv_disable_pll(struct drm_
        val &= ~DPIO_DCLKP_EN;
        vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port), val);
  
 -      /* disable left/right clock distribution */
 -      if (pipe != PIPE_B) {
 -              val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW5_CH0);
 -              val &= ~(CHV_BUFLEFTENA1_MASK | CHV_BUFRIGHTENA1_MASK);
 -              vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW5_CH0, val);
 -      } else {
 -              val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW1_CH1);
 -              val &= ~(CHV_BUFLEFTENA2_MASK | CHV_BUFRIGHTENA2_MASK);
 -              vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW1_CH1, val);
 -      }
 -
        mutex_unlock(&dev_priv->sb_lock);
  }
  
@@@ -2190,7 -2229,7 +2190,7 @@@ static bool need_vtd_wa(struct drm_devi
  
  unsigned int
  intel_tile_height(struct drm_device *dev, uint32_t pixel_format,
 -                uint64_t fb_format_modifier)
 +                uint64_t fb_format_modifier, unsigned int plane)
  {
        unsigned int tile_height;
        uint32_t pixel_bytes;
                tile_height = 32;
                break;
        case I915_FORMAT_MOD_Yf_TILED:
 -              pixel_bytes = drm_format_plane_cpp(pixel_format, 0);
 +              pixel_bytes = drm_format_plane_cpp(pixel_format, plane);
                switch (pixel_bytes) {
                default:
                case 1:
@@@ -2240,7 -2279,7 +2240,7 @@@ intel_fb_align_height(struct drm_devic
                      uint32_t pixel_format, uint64_t fb_format_modifier)
  {
        return ALIGN(height, intel_tile_height(dev, pixel_format,
 -                                             fb_format_modifier));
 +                                             fb_format_modifier, 0));
  }
  
  static int
@@@ -2263,27 -2302,15 +2263,27 @@@ intel_fill_fb_ggtt_view(struct i915_ggt
        info->height = fb->height;
        info->pixel_format = fb->pixel_format;
        info->pitch = fb->pitches[0];
 +      info->uv_offset = fb->offsets[1];
        info->fb_modifier = fb->modifier[0];
  
        tile_height = intel_tile_height(fb->dev, fb->pixel_format,
 -                                      fb->modifier[0]);
 +                                      fb->modifier[0], 0);
        tile_pitch = PAGE_SIZE / tile_height;
        info->width_pages = DIV_ROUND_UP(fb->pitches[0], tile_pitch);
        info->height_pages = DIV_ROUND_UP(fb->height, tile_height);
        info->size = info->width_pages * info->height_pages * PAGE_SIZE;
  
 +      if (info->pixel_format == DRM_FORMAT_NV12) {
 +              tile_height = intel_tile_height(fb->dev, fb->pixel_format,
 +                                              fb->modifier[0], 1);
 +              tile_pitch = PAGE_SIZE / tile_height;
 +              info->width_pages_uv = DIV_ROUND_UP(fb->pitches[0], tile_pitch);
 +              info->height_pages_uv = DIV_ROUND_UP(fb->height / 2,
 +                                                   tile_height);
 +              info->size_uv = info->width_pages_uv * info->height_pages_uv *
 +                              PAGE_SIZE;
 +      }
 +
        return 0;
  }
  
@@@ -2742,9 -2769,6 +2742,9 @@@ static void i9xx_update_primary_plane(s
                        (intel_crtc->config->pipe_src_w - 1) * pixel_size;
        }
  
 +      intel_crtc->adjusted_x = x;
 +      intel_crtc->adjusted_y = y;
 +
        I915_WRITE(reg, dspcntr);
  
        I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]);
@@@ -2845,9 -2869,6 +2845,9 @@@ static void ironlake_update_primary_pla
                }
        }
  
 +      intel_crtc->adjusted_x = x;
 +      intel_crtc->adjusted_y = y;
 +
        I915_WRITE(reg, dspcntr);
  
        I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]);
@@@ -2897,29 -2918,14 +2897,29 @@@ u32 intel_fb_stride_alignment(struct dr
  }
  
  unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
 -                                   struct drm_i915_gem_object *obj)
 +                                   struct drm_i915_gem_object *obj,
 +                                   unsigned int plane)
  {
        const struct i915_ggtt_view *view = &i915_ggtt_view_normal;
 +      struct i915_vma *vma;
 +      unsigned char *offset;
  
        if (intel_rotation_90_or_270(intel_plane->base.state->rotation))
                view = &i915_ggtt_view_rotated;
  
 -      return i915_gem_obj_ggtt_offset_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))
 +              return -1;
 +
 +      offset = (unsigned char *)vma->node.start;
 +
 +      if (plane == 1) {
 +              offset += vma->ggtt_view.rotation_info.uv_start_page *
 +                        PAGE_SIZE;
 +      }
 +
 +      return (unsigned long)offset;
  }
  
  static void skl_detach_scaler(struct intel_crtc *intel_crtc, int id)
        I915_WRITE(SKL_PS_CTRL(intel_crtc->pipe, id), 0);
        I915_WRITE(SKL_PS_WIN_POS(intel_crtc->pipe, id), 0);
        I915_WRITE(SKL_PS_WIN_SZ(intel_crtc->pipe, id), 0);
 -      DRM_DEBUG_KMS("CRTC:%d Disabled scaler id %u.%u\n",
 -              intel_crtc->base.base.id, intel_crtc->pipe, id);
  }
  
  /*
@@@ -3075,7 -3083,7 +3075,7 @@@ static void skylake_update_primary_plan
        obj = intel_fb_obj(fb);
        stride_div = intel_fb_stride_alignment(dev, fb->modifier[0],
                                               fb->pixel_format);
 -      surf_addr = intel_plane_obj_offset(to_intel_plane(plane), obj);
 +      surf_addr = intel_plane_obj_offset(to_intel_plane(plane), obj, 0);
  
        /*
         * FIXME: intel_plane_state->src, dst aren't set when transitional
        if (intel_rotation_90_or_270(rotation)) {
                /* stride = Surface height in tiles */
                tile_height = intel_tile_height(dev, fb->pixel_format,
 -                                              fb->modifier[0]);
 +                                              fb->modifier[0], 0);
                stride = DIV_ROUND_UP(fb->height, tile_height);
                x_offset = stride * tile_height - y - src_h;
                y_offset = x;
        }
        plane_offset = y_offset << 16 | x_offset;
  
 +      intel_crtc->adjusted_x = x_offset;
 +      intel_crtc->adjusted_y = y_offset;
 +
        I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
        I915_WRITE(PLANE_OFFSET(pipe, 0), plane_offset);
        I915_WRITE(PLANE_SIZE(pipe, 0), plane_size);
@@@ -3174,20 -3179,24 +3174,20 @@@ static void intel_complete_page_flips(s
  
  static void intel_update_primary_planes(struct drm_device *dev)
  {
 -      struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_crtc *crtc;
  
        for_each_crtc(dev, crtc) {
 -              struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 +              struct intel_plane *plane = to_intel_plane(crtc->primary);
 +              struct intel_plane_state *plane_state;
  
 -              drm_modeset_lock(&crtc->mutex, NULL);
 -              /*
 -               * FIXME: Once we have proper support for primary planes (and
 -               * disabling them without disabling the entire crtc) allow again
 -               * a NULL crtc->primary->fb.
 -               */
 -              if (intel_crtc->active && crtc->primary->fb)
 -                      dev_priv->display.update_primary_plane(crtc,
 -                                                             crtc->primary->fb,
 -                                                             crtc->x,
 -                                                             crtc->y);
 -              drm_modeset_unlock(&crtc->mutex);
 +              drm_modeset_lock_crtc(crtc, &plane->base);
 +
 +              plane_state = to_intel_plane_state(plane->base.state);
 +
 +              if (plane_state->base.fb)
 +                      plane->commit_plane(&plane->base, plane_state);
 +
 +              drm_modeset_unlock_crtc(crtc);
        }
  }
  
@@@ -3231,9 -3240,6 +3231,9 @@@ void intel_finish_reset(struct drm_devi
                 * so update the base address of all primary
                 * planes to the the last fb to make sure we're
                 * showing the correct fb after a reset.
 +               *
 +               * FIXME: Atomic will make this obsolete since we won't schedule
 +               * CS-based flips (which might get lost in gpu resets) any more.
                 */
                intel_update_primary_planes(dev);
                return;
@@@ -3304,23 -3310,14 +3304,23 @@@ static bool intel_crtc_has_pending_flip
        return pending;
  }
  
 -static void intel_update_pipe_size(struct intel_crtc *crtc)
 +static void intel_update_pipe_config(struct intel_crtc *crtc,
 +                                   struct intel_crtc_state *old_crtc_state)
  {
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
 -      const struct drm_display_mode *adjusted_mode;
 +      struct intel_crtc_state *pipe_config =
 +              to_intel_crtc_state(crtc->base.state);
  
 -      if (!i915.fastboot)
 -              return;
 +      /* drm_atomic_helper_update_legacy_modeset_state might not be called. */
 +      crtc->base.mode = crtc->base.state->mode;
 +
 +      DRM_DEBUG_KMS("Updating pipe size %ix%i -> %ix%i\n",
 +                    old_crtc_state->pipe_src_w, old_crtc_state->pipe_src_h,
 +                    pipe_config->pipe_src_w, pipe_config->pipe_src_h);
 +
 +      if (HAS_DDI(dev))
 +              intel_set_pipe_csc(&crtc->base);
  
        /*
         * Update pipe size and adjust fitter if needed: the reason for this is
         * fastboot case, we'll flip, but if we don't update the pipesrc and
         * pfit state, we'll end up with a big fb scanned out into the wrong
         * sized surface.
 -       *
 -       * To fix this properly, we need to hoist the checks up into
 -       * compute_mode_changes (or above), check the actual pfit state and
 -       * whether the platform allows pfit disable with pipe active, and only
 -       * then update the pipesrc and pfit state, even on the flip path.
         */
  
 -      adjusted_mode = &crtc->config->base.adjusted_mode;
 -
        I915_WRITE(PIPESRC(crtc->pipe),
 -                 ((adjusted_mode->crtc_hdisplay - 1) << 16) |
 -                 (adjusted_mode->crtc_vdisplay - 1));
 -      if (!crtc->config->pch_pfit.enabled &&
 -          (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) ||
 -           intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) {
 -              I915_WRITE(PF_CTL(crtc->pipe), 0);
 -              I915_WRITE(PF_WIN_POS(crtc->pipe), 0);
 -              I915_WRITE(PF_WIN_SZ(crtc->pipe), 0);
 +                 ((pipe_config->pipe_src_w - 1) << 16) |
 +                 (pipe_config->pipe_src_h - 1));
 +
 +      /* on skylake this is done by detaching scalers */
 +      if (INTEL_INFO(dev)->gen >= 9) {
 +              skl_detach_scalers(crtc);
 +
 +              if (pipe_config->pch_pfit.enabled)
 +                      skylake_pfit_enable(crtc);
 +      } else if (HAS_PCH_SPLIT(dev)) {
 +              if (pipe_config->pch_pfit.enabled)
 +                      ironlake_pfit_enable(crtc);
 +              else if (old_crtc_state->pch_pfit.enabled)
 +                      ironlake_pfit_disable(crtc, true);
        }
 -      crtc->config->pipe_src_w = adjusted_mode->crtc_hdisplay;
 -      crtc->config->pipe_src_h = adjusted_mode->crtc_vdisplay;
  }
  
  static void intel_fdi_normal_train(struct drm_crtc *crtc)
@@@ -4963,10 -4963,12 +4963,10 @@@ static void haswell_crtc_enable(struct 
  
        intel_ddi_enable_pipe_clock(intel_crtc);
  
 -      if (INTEL_INFO(dev)->gen == 9)
 +      if (INTEL_INFO(dev)->gen >= 9)
                skylake_pfit_enable(intel_crtc);
 -      else if (INTEL_INFO(dev)->gen < 9)
 -              ironlake_pfit_enable(intel_crtc);
        else
 -              MISSING_CASE(INTEL_INFO(dev)->gen);
 +              ironlake_pfit_enable(intel_crtc);
  
        /*
         * On ILK+ LUT must be loaded before the pipe is running but with
        }
  }
  
 -static void ironlake_pfit_disable(struct intel_crtc *crtc)
 +static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force)
  {
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
  
        /* To avoid upsetting the power well on haswell only disable the pfit if
         * it's in use. The hw state code will make sure we get this right. */
 -      if (crtc->config->pch_pfit.enabled) {
 +      if (force || crtc->config->pch_pfit.enabled) {
                I915_WRITE(PF_CTL(pipe), 0);
                I915_WRITE(PF_WIN_POS(pipe), 0);
                I915_WRITE(PF_WIN_SZ(pipe), 0);
@@@ -5038,7 -5040,7 +5038,7 @@@ static void ironlake_crtc_disable(struc
  
        intel_disable_pipe(intel_crtc);
  
 -      ironlake_pfit_disable(intel_crtc);
 +      ironlake_pfit_disable(intel_crtc, false);
  
        if (intel_crtc->config->has_pch_encoder)
                ironlake_fdi_disable(crtc);
@@@ -5098,10 -5100,12 +5098,10 @@@ static void haswell_crtc_disable(struc
  
        intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder);
  
 -      if (INTEL_INFO(dev)->gen == 9)
 +      if (INTEL_INFO(dev)->gen >= 9)
                skylake_scaler_disable(intel_crtc);
 -      else if (INTEL_INFO(dev)->gen < 9)
 -              ironlake_pfit_disable(intel_crtc);
        else
 -              MISSING_CASE(INTEL_INFO(dev)->gen);
 +              ironlake_pfit_disable(intel_crtc, false);
  
        intel_ddi_disable_pipe_clock(intel_crtc);
  
@@@ -5273,21 -5277,6 +5273,21 @@@ static void modeset_update_crtc_power_d
                        modeset_put_power_domains(dev_priv, put_domains[i]);
  }
  
 +static int intel_compute_max_dotclk(struct drm_i915_private *dev_priv)
 +{
 +      int max_cdclk_freq = dev_priv->max_cdclk_freq;
 +
 +      if (INTEL_INFO(dev_priv)->gen >= 9 ||
 +          IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
 +              return max_cdclk_freq;
 +      else if (IS_CHERRYVIEW(dev_priv))
 +              return max_cdclk_freq*95/100;
 +      else if (INTEL_INFO(dev_priv)->gen < 4)
 +              return 2*max_cdclk_freq*90/100;
 +      else
 +              return max_cdclk_freq*90/100;
 +}
 +
  static void intel_update_max_cdclk(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
                dev_priv->max_cdclk_freq = dev_priv->cdclk_freq;
        }
  
 +      dev_priv->max_dotclk_freq = intel_compute_max_dotclk(dev_priv);
 +
        DRM_DEBUG_DRIVER("Max CD clock rate: %d kHz\n",
                         dev_priv->max_cdclk_freq);
 +
 +      DRM_DEBUG_DRIVER("Max dotclock rate: %d kHz\n",
 +                       dev_priv->max_dotclk_freq);
  }
  
  static void intel_update_cdclk(struct drm_device *dev)
@@@ -6051,6 -6035,13 +6051,6 @@@ static void valleyview_crtc_enable(stru
  
        is_dsi = intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DSI);
  
 -      if (!is_dsi) {
 -              if (IS_CHERRYVIEW(dev))
 -                      chv_prepare_pll(intel_crtc, intel_crtc->config);
 -              else
 -                      vlv_prepare_pll(intel_crtc, intel_crtc->config);
 -      }
 -
        if (intel_crtc->config->has_dp_encoder)
                intel_dp_set_m_n(intel_crtc, M1_N1);
  
                        encoder->pre_pll_enable(encoder);
  
        if (!is_dsi) {
 -              if (IS_CHERRYVIEW(dev))
 +              if (IS_CHERRYVIEW(dev)) {
 +                      chv_prepare_pll(intel_crtc, intel_crtc->config);
                        chv_enable_pll(intel_crtc, intel_crtc->config);
 -              else
 +              } else {
 +                      vlv_prepare_pll(intel_crtc, intel_crtc->config);
                        vlv_enable_pll(intel_crtc, intel_crtc->config);
 +              }
        }
  
        for_each_encoder_on_crtc(dev, crtc, encoder)
@@@ -6208,10 -6196,6 +6208,10 @@@ static void i9xx_crtc_disable(struct dr
                        i9xx_disable_pll(intel_crtc);
        }
  
 +      for_each_encoder_on_crtc(dev, crtc, encoder)
 +              if (encoder->post_pll_disable)
 +                      encoder->post_pll_disable(encoder);
 +
        if (!IS_GEN2(dev))
                intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
  
@@@ -6321,7 -6305,7 +6321,7 @@@ static void intel_connector_check_state
                      connector->base.name);
  
        if (connector->get_hw_state(connector)) {
-               struct drm_encoder *encoder = &connector->encoder->base;
+               struct intel_encoder *encoder = connector->encoder;
                struct drm_connector_state *conn_state = connector->base.state;
  
                I915_STATE_WARN(!crtc,
                I915_STATE_WARN(!crtc->state->active,
                      "connector is active, but attached crtc isn't\n");
  
-               if (!encoder)
+               if (!encoder || encoder->type == INTEL_OUTPUT_DP_MST)
                        return;
  
-               I915_STATE_WARN(conn_state->best_encoder != encoder,
+               I915_STATE_WARN(conn_state->best_encoder != &encoder->base,
                        "atomic encoder doesn't match attached encoder\n");
  
-               I915_STATE_WARN(conn_state->crtc != encoder->crtc,
+               I915_STATE_WARN(conn_state->crtc != encoder->base.crtc,
                        "attached encoder crtc differs from connector crtc\n");
        } else {
                I915_STATE_WARN(crtc && crtc->state->active,
@@@ -7393,7 -7377,8 +7393,7 @@@ static void chv_prepare_pll(struct inte
                        1 << DPIO_CHV_N_DIV_SHIFT);
  
        /* M2 fraction division */
 -      if (bestm2_frac)
 -              vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW2(port), bestm2_frac);
 +      vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW2(port), bestm2_frac);
  
        /* M2 fraction division enable */
        dpio_val = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW3(port));
@@@ -8134,14 -8119,6 +8134,14 @@@ static bool i9xx_get_pipe_config(struc
        else
                i9xx_crtc_clock_get(crtc, pipe_config);
  
 +      /*
 +       * Normally the dotclock is filled in by the encoder .get_config()
 +       * but in case the pipe is enabled w/o any ports we need a sane
 +       * default.
 +       */
 +      pipe_config->base.adjusted_mode.crtc_clock =
 +              pipe_config->port_clock / pipe_config->pixel_multiplier;
 +
        return true;
  }
  
@@@ -8403,7 -8380,8 +8403,7 @@@ static void lpt_enable_clkout_dp(struc
  
        if (WARN(with_fdi && !with_spread, "FDI requires downspread\n"))
                with_spread = true;
 -      if (WARN(dev_priv->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE &&
 -               with_fdi, "LP PCH doesn't have FDI\n"))
 +      if (WARN(HAS_PCH_LPT_LP(dev) && with_fdi, "LP PCH doesn't have FDI\n"))
                with_fdi = false;
  
        mutex_lock(&dev_priv->sb_lock);
                }
        }
  
 -      reg = (dev_priv->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) ?
 -             SBI_GEN0 : SBI_DBUFF0;
 +      reg = HAS_PCH_LPT_LP(dev) ? SBI_GEN0 : SBI_DBUFF0;
        tmp = intel_sbi_read(dev_priv, reg, SBI_ICLK);
        tmp |= SBI_GEN0_CFG_BUFFENABLE_DISABLE;
        intel_sbi_write(dev_priv, reg, tmp, SBI_ICLK);
@@@ -8442,7 -8421,8 +8442,7 @@@ static void lpt_disable_clkout_dp(struc
  
        mutex_lock(&dev_priv->sb_lock);
  
 -      reg = (dev_priv->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) ?
 -             SBI_GEN0 : SBI_DBUFF0;
 +      reg = HAS_PCH_LPT_LP(dev) ? SBI_GEN0 : SBI_DBUFF0;
        tmp = intel_sbi_read(dev_priv, reg, SBI_ICLK);
        tmp &= ~SBI_GEN0_CFG_BUFFENABLE_DISABLE;
        intel_sbi_write(dev_priv, reg, tmp, SBI_ICLK);
@@@ -9454,7 -9434,7 +9454,7 @@@ void hsw_enable_pc8(struct drm_i915_pri
  
        DRM_DEBUG_KMS("Enabling package C8+\n");
  
 -      if (dev_priv->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) {
 +      if (HAS_PCH_LPT_LP(dev)) {
                val = I915_READ(SOUTH_DSPCLK_GATE_D);
                val &= ~PCH_LP_PARTITION_LEVEL_DISABLE;
                I915_WRITE(SOUTH_DSPCLK_GATE_D, val);
@@@ -9474,7 -9454,7 +9474,7 @@@ void hsw_disable_pc8(struct drm_i915_pr
        hsw_restore_lcpll(dev_priv);
        lpt_init_pch_refclk(dev);
  
 -      if (dev_priv->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) {
 +      if (HAS_PCH_LPT_LP(dev)) {
                val = I915_READ(SOUTH_DSPCLK_GATE_D);
                val |= PCH_LP_PARTITION_LEVEL_DISABLE;
                I915_WRITE(SOUTH_DSPCLK_GATE_D, val);
@@@ -9824,10 -9804,12 +9824,10 @@@ static bool haswell_get_pipe_config(str
        }
  
        if (intel_display_power_is_enabled(dev_priv, pfit_domain)) {
 -              if (INTEL_INFO(dev)->gen == 9)
 +              if (INTEL_INFO(dev)->gen >= 9)
                        skylake_get_pfit_config(crtc, pipe_config);
 -              else if (INTEL_INFO(dev)->gen < 9)
 -                      ironlake_get_pfit_config(crtc, pipe_config);
                else
 -                      MISSING_CASE(INTEL_INFO(dev)->gen);
 +                      ironlake_get_pfit_config(crtc, pipe_config);
        }
  
        if (IS_HASWELL(dev))
@@@ -9961,9 -9943,8 +9961,9 @@@ static void intel_crtc_update_cursor(st
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        int pipe = intel_crtc->pipe;
 -      int x = crtc->cursor_x;
 -      int y = crtc->cursor_y;
 +      struct drm_plane_state *cursor_state = crtc->cursor->state;
 +      int x = cursor_state->crtc_x;
 +      int y = cursor_state->crtc_y;
        u32 base = 0, pos = 0;
  
        if (on)
                base = 0;
  
        if (x < 0) {
 -              if (x + intel_crtc->base.cursor->state->crtc_w <= 0)
 +              if (x + cursor_state->crtc_w <= 0)
                        base = 0;
  
                pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
        pos |= x << CURSOR_X_SHIFT;
  
        if (y < 0) {
 -              if (y + intel_crtc->base.cursor->state->crtc_h <= 0)
 +              if (y + cursor_state->crtc_h <= 0)
                        base = 0;
  
                pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT;
        /* ILK+ do this automagically */
        if (HAS_GMCH_DISPLAY(dev) &&
            crtc->cursor->state->rotation == BIT(DRM_ROTATE_180)) {
 -              base += (intel_crtc->base.cursor->state->crtc_h *
 -                      intel_crtc->base.cursor->state->crtc_w - 1) * 4;
 +              base += (cursor_state->crtc_h *
 +                       cursor_state->crtc_w - 1) * 4;
        }
  
        if (IS_845G(dev) || IS_I865G(dev))
@@@ -11053,10 -11034,10 +11053,10 @@@ static int intel_gen7_queue_flip(struc
                                        DERRMR_PIPEB_PRI_FLIP_DONE |
                                        DERRMR_PIPEC_PRI_FLIP_DONE));
                if (IS_GEN8(dev))
 -                      intel_ring_emit(ring, MI_STORE_REGISTER_MEM_GEN8(1) |
 +                      intel_ring_emit(ring, MI_STORE_REGISTER_MEM_GEN8 |
                                              MI_SRM_LRM_GLOBAL_GTT);
                else
 -                      intel_ring_emit(ring, MI_STORE_REGISTER_MEM(1) |
 +                      intel_ring_emit(ring, MI_STORE_REGISTER_MEM |
                                              MI_SRM_LRM_GLOBAL_GTT);
                intel_ring_emit(ring, DERRMR);
                intel_ring_emit(ring, ring->scratch.gtt_offset + 256);
@@@ -11180,10 -11161,11 +11180,10 @@@ static void ilk_do_mmio_flip(struct int
  static void intel_do_mmio_flip(struct intel_crtc *intel_crtc)
  {
        struct drm_device *dev = intel_crtc->base.dev;
 -      u32 start_vbl_count;
  
        intel_mark_page_flip_active(intel_crtc);
  
 -      intel_pipe_update_start(intel_crtc, &start_vbl_count);
 +      intel_pipe_update_start(intel_crtc);
  
        if (INTEL_INFO(dev)->gen >= 9)
                skl_do_mmio_flip(intel_crtc);
                /* use_mmio_flip() retricts MMIO flips to ilk+ */
                ilk_do_mmio_flip(intel_crtc);
  
 -      intel_pipe_update_end(intel_crtc, start_vbl_count);
 +      intel_pipe_update_end(intel_crtc);
  }
  
  static void intel_mmio_flip_work_func(struct work_struct *work)
@@@ -11255,9 -11237,6 +11255,9 @@@ static bool __intel_pageflip_stall_chec
        if (atomic_read(&work->pending) >= INTEL_FLIP_COMPLETE)
                return true;
  
 +      if (atomic_read(&work->pending) < INTEL_FLIP_PENDING)
 +              return false;
 +
        if (!work->enable_stall_check)
                return false;
  
@@@ -11438,9 -11417,8 +11438,9 @@@ static int intel_crtc_page_flip(struct 
        if (ret)
                goto cleanup_pending;
  
 -      work->gtt_offset = intel_plane_obj_offset(to_intel_plane(primary), obj)
 -                                                + intel_crtc->dspaddr_offset;
 +      work->gtt_offset = intel_plane_obj_offset(to_intel_plane(primary),
 +                                                obj, 0);
 +      work->gtt_offset += intel_crtc->dspaddr_offset;
  
        if (mmio_flip) {
                ret = intel_queue_mmio_flip(dev, crtc, fb, obj, ring,
@@@ -11649,7 -11627,7 +11649,7 @@@ int intel_plane_atomic_calc_changes(str
                intel_crtc->atomic.update_wm_pre = true;
        }
  
 -      if (visible)
 +      if (visible || was_visible)
                intel_crtc->atomic.fb_bits |=
                        to_intel_plane(plane)->frontbuffer_bit;
  
@@@ -11922,16 -11900,14 +11922,16 @@@ static void intel_dump_pipe_config(stru
                      pipe_config->fdi_m_n.gmch_m, pipe_config->fdi_m_n.gmch_n,
                      pipe_config->fdi_m_n.link_m, pipe_config->fdi_m_n.link_n,
                      pipe_config->fdi_m_n.tu);
 -      DRM_DEBUG_KMS("dp: %i, gmch_m: %u, gmch_n: %u, link_m: %u, link_n: %u, tu: %u\n",
 +      DRM_DEBUG_KMS("dp: %i, lanes: %i, gmch_m: %u, gmch_n: %u, link_m: %u, link_n: %u, tu: %u\n",
                      pipe_config->has_dp_encoder,
 +                    pipe_config->lane_count,
                      pipe_config->dp_m_n.gmch_m, pipe_config->dp_m_n.gmch_n,
                      pipe_config->dp_m_n.link_m, pipe_config->dp_m_n.link_n,
                      pipe_config->dp_m_n.tu);
  
 -      DRM_DEBUG_KMS("dp: %i, gmch_m2: %u, gmch_n2: %u, link_m2: %u, link_n2: %u, tu2: %u\n",
 +      DRM_DEBUG_KMS("dp: %i, lanes: %i, gmch_m2: %u, gmch_n2: %u, link_m2: %u, link_n2: %u, tu2: %u\n",
                      pipe_config->has_dp_encoder,
 +                    pipe_config->lane_count,
                      pipe_config->dp_m2_n2.gmch_m,
                      pipe_config->dp_m2_n2.gmch_n,
                      pipe_config->dp_m2_n2.link_m,
@@@ -12143,6 -12119,10 +12143,6 @@@ intel_modeset_pipe_config(struct drm_cr
              (DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC)))
                pipe_config->base.adjusted_mode.flags |= DRM_MODE_FLAG_NVSYNC;
  
 -      /* Compute a starting value for pipe_config->pipe_bpp taking the source
 -       * plane pixel format and any sink constraints into account. Returns the
 -       * source plane bpp so that dithering can be selected on mismatches
 -       * after encoders and crtc also have had their say. */
        base_bpp = compute_baseline_pipe_bpp(to_intel_crtc(crtc),
                                             pipe_config);
        if (base_bpp < 0)
@@@ -12211,7 -12191,7 +12211,7 @@@ encoder_retry
        /* Dithering seems to not pass-through bits correctly when it should, so
         * only enable it on 6bpc panels. */
        pipe_config->dither = pipe_config->pipe_bpp == 6*3;
 -      DRM_DEBUG_KMS("plane bpp: %i, pipe bpp: %i, dithering: %i\n",
 +      DRM_DEBUG_KMS("hw max bpp: %i, pipe bpp: %i, dithering: %i\n",
                      base_bpp, pipe_config->pipe_bpp, pipe_config->dither);
  
  fail:
@@@ -12261,6 -12241,7 +12261,6 @@@ static bool intel_fuzzy_clock_check(in
                            base.head) \
                if (mask & (1 <<(intel_crtc)->pipe))
  
 -
  static bool
  intel_compare_m_n(unsigned int m, unsigned int n,
                  unsigned int m2, unsigned int n2,
@@@ -12433,7 -12414,6 +12433,7 @@@ intel_pipe_config_compare(struct drm_de
        PIPE_CONF_CHECK_M_N(fdi_m_n);
  
        PIPE_CONF_CHECK_I(has_dp_encoder);
 +      PIPE_CONF_CHECK_I(lane_count);
  
        if (INTEL_INFO(dev)->gen < 8) {
                PIPE_CONF_CHECK_M_N(dp_m_n);
                                      DRM_MODE_FLAG_NVSYNC);
        }
  
 -      PIPE_CONF_CHECK_I(pipe_src_w);
 -      PIPE_CONF_CHECK_I(pipe_src_h);
 -
 -      PIPE_CONF_CHECK_I(gmch_pfit.control);
 +      PIPE_CONF_CHECK_X(gmch_pfit.control);
        /* pfit ratios are autocomputed by the hw on gen4+ */
        if (INTEL_INFO(dev)->gen < 4)
                PIPE_CONF_CHECK_I(gmch_pfit.pgm_ratios);
 -      PIPE_CONF_CHECK_I(gmch_pfit.lvds_border_bits);
 +      PIPE_CONF_CHECK_X(gmch_pfit.lvds_border_bits);
  
 -      PIPE_CONF_CHECK_I(pch_pfit.enabled);
 -      if (current_config->pch_pfit.enabled) {
 -              PIPE_CONF_CHECK_I(pch_pfit.pos);
 -              PIPE_CONF_CHECK_I(pch_pfit.size);
 -      }
 +      if (!adjust) {
 +              PIPE_CONF_CHECK_I(pipe_src_w);
 +              PIPE_CONF_CHECK_I(pipe_src_h);
 +
 +              PIPE_CONF_CHECK_I(pch_pfit.enabled);
 +              if (current_config->pch_pfit.enabled) {
 +                      PIPE_CONF_CHECK_X(pch_pfit.pos);
 +                      PIPE_CONF_CHECK_X(pch_pfit.size);
 +              }
  
 -      PIPE_CONF_CHECK_I(scaler_state.scaler_id);
 +              PIPE_CONF_CHECK_I(scaler_state.scaler_id);
 +      }
  
        /* BDW+ don't expose a synchronous way to read the state */
        if (IS_HASWELL(dev))
@@@ -12660,8 -12638,7 +12660,8 @@@ check_crtc_state(struct drm_device *dev
                struct intel_crtc_state *pipe_config, *sw_config;
                bool active;
  
 -              if (!needs_modeset(crtc->state))
 +              if (!needs_modeset(crtc->state) &&
 +                  !to_intel_crtc_state(crtc->state)->update_pipe)
                        continue;
  
                __drm_atomic_helper_crtc_destroy_state(crtc, old_crtc_state);
@@@ -12957,6 -12934,7 +12957,6 @@@ static int intel_modeset_all_pipes(stru
        return ret;
  }
  
 -
  static int intel_modeset_checks(struct drm_atomic_state *state)
  {
        struct drm_device *dev = state->dev;
@@@ -13042,11 -13020,11 +13042,11 @@@ static int intel_atomic_check(struct dr
                if (ret)
                        return ret;
  
 -              if (i915.fastboot &&
 -                  intel_pipe_config_compare(state->dev,
 +              if (intel_pipe_config_compare(state->dev,
                                        to_intel_crtc_state(crtc->state),
                                        pipe_config, true)) {
                        crtc_state->mode_changed = false;
 +                      to_intel_crtc_state(crtc_state)->update_pipe = true;
                }
  
                if (needs_modeset(crtc_state)) {
@@@ -13144,30 -13122,16 +13144,30 @@@ static int intel_atomic_commit(struct d
        for_each_crtc_in_state(state, crtc, crtc_state, i) {
                struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
                bool modeset = needs_modeset(crtc->state);
 +              bool update_pipe = !modeset &&
 +                      to_intel_crtc_state(crtc->state)->update_pipe;
 +              unsigned long put_domains = 0;
  
                if (modeset && crtc->state->active) {
                        update_scanline_offset(to_intel_crtc(crtc));
                        dev_priv->display.crtc_enable(crtc);
                }
  
 +              if (update_pipe) {
 +                      put_domains = modeset_get_crtc_power_domains(crtc);
 +
 +                      /* make sure intel_modeset_check_state runs */
 +                      any_ms = true;
 +              }
 +
                if (!modeset)
                        intel_pre_plane_update(intel_crtc);
  
                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);
        }
  
@@@ -13349,10 -13313,10 +13349,10 @@@ static void intel_shared_dpll_init(stru
   */
  int
  intel_prepare_plane_fb(struct drm_plane *plane,
-                      struct drm_framebuffer *fb,
                       const struct drm_plane_state *new_state)
  {
        struct drm_device *dev = plane->dev;
+       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);
   */
  void
  intel_cleanup_plane_fb(struct drm_plane *plane,
-                      struct drm_framebuffer *fb,
                       const struct drm_plane_state *old_state)
  {
        struct drm_device *dev = plane->dev;
-       struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+       struct drm_i915_gem_object *obj = intel_fb_obj(old_state->fb);
  
-       if (WARN_ON(!obj))
+       if (!obj)
                return;
  
        if (plane->type != DRM_PLANE_TYPE_CURSOR ||
            !INTEL_INFO(dev)->cursor_needs_physical) {
                mutex_lock(&dev->struct_mutex);
-               intel_unpin_fb_obj(fb, old_state);
+               intel_unpin_fb_obj(old_state->fb, old_state);
                mutex_unlock(&dev->struct_mutex);
        }
  }
@@@ -13484,9 -13447,11 +13483,9 @@@ intel_commit_primary_plane(struct drm_p
        if (!crtc->state->active)
                return;
  
 -      if (state->visible)
 -              /* FIXME: kill this fastboot hack */
 -              intel_update_pipe_size(intel_crtc);
 -
 -      dev_priv->display.update_primary_plane(crtc, fb, crtc->x, crtc->y);
 +      dev_priv->display.update_primary_plane(crtc, fb,
 +                                             state->src.x1 >> 16,
 +                                             state->src.y1 >> 16);
  }
  
  static void
@@@ -13504,23 -13469,15 +13503,23 @@@ static void intel_begin_crtc_commit(str
  {
        struct drm_device *dev = crtc->dev;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 +      struct intel_crtc_state *old_intel_state =
 +              to_intel_crtc_state(old_crtc_state);
 +      bool modeset = needs_modeset(crtc->state);
  
        if (intel_crtc->atomic.update_wm_pre)
                intel_update_watermarks(crtc);
  
        /* Perform vblank evasion around commit operation */
        if (crtc->state->active)
 -              intel_pipe_update_start(intel_crtc, &intel_crtc->start_vbl_count);
 +              intel_pipe_update_start(intel_crtc);
  
 -      if (!needs_modeset(crtc->state) && INTEL_INFO(dev)->gen >= 9)
 +      if (modeset)
 +              return;
 +
 +      if (to_intel_crtc_state(crtc->state)->update_pipe)
 +              intel_update_pipe_config(intel_crtc, old_intel_state);
 +      else if (INTEL_INFO(dev)->gen >= 9)
                skl_detach_scalers(intel_crtc);
  }
  
@@@ -13530,7 -13487,7 +13529,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_crtc->start_vbl_count);
 +              intel_pipe_update_end(intel_crtc);
  }
  
  /**
@@@ -13699,6 -13656,10 +13698,6 @@@ intel_commit_cursor_plane(struct drm_pl
        crtc = crtc ? crtc : plane->crtc;
        intel_crtc = to_intel_crtc(crtc);
  
 -      plane->fb = state->base.fb;
 -      crtc->cursor_x = state->base.crtc_x;
 -      crtc->cursor_y = state->base.crtc_y;
 -
        if (intel_crtc->cursor_bo == obj)
                goto update;
  
@@@ -14837,6 -14798,8 +14836,6 @@@ void intel_modeset_init(struct drm_devi
                }
        }
  
 -      intel_init_dpio(dev);
 -
        intel_shared_dpll_init(dev);
  
        /* Just disable it once at startup */
@@@ -14918,22 -14881,13 +14917,22 @@@ intel_check_plane_mapping(struct intel_
        return true;
  }
  
 +static bool intel_crtc_has_encoders(struct intel_crtc *crtc)
 +{
 +      struct drm_device *dev = crtc->base.dev;
 +      struct intel_encoder *encoder;
 +
 +      for_each_encoder_on_crtc(dev, &crtc->base, encoder)
 +              return true;
 +
 +      return false;
 +}
 +
  static void intel_sanitize_crtc(struct intel_crtc *crtc)
  {
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
 -      struct intel_encoder *encoder;
        u32 reg;
 -      bool enable;
  
        /* Clear any frame start delays used for debugging left by the BIOS */
        reg = PIPECONF(crtc->config->cpu_transcoder);
        /* restore vblank interrupts to correct state */
        drm_crtc_vblank_reset(&crtc->base);
        if (crtc->active) {
 -              drm_calc_timestamping_constants(&crtc->base, &crtc->base.hwmode);
 -              update_scanline_offset(crtc);
 +              struct intel_plane *plane;
 +
                drm_crtc_vblank_on(&crtc->base);
 +
 +              /* Disable everything but the primary plane */
 +              for_each_intel_plane_on_crtc(dev, crtc, plane) {
 +                      if (plane->base.type == DRM_PLANE_TYPE_PRIMARY)
 +                              continue;
 +
 +                      plane->disable_plane(&plane->base, &crtc->base);
 +              }
        }
  
        /* We need to sanitize the plane -> pipe mapping first because this will
  
        /* Adjust the state of the output pipe according to whether we
         * have active connectors/encoders. */
 -      enable = false;
 -      for_each_encoder_on_crtc(dev, &crtc->base, encoder) {
 -              enable = true;
 -              break;
 -      }
 -
 -      if (!enable)
 +      if (!intel_crtc_has_encoders(crtc))
                intel_crtc_disable_noatomic(&crtc->base);
  
        if (crtc->active != crtc->base.state->active) {
 +              struct intel_encoder *encoder;
  
                /* This can happen either due to bugs in the get_hw_state
                 * functions or because of calls to intel_crtc_disable_noatomic,
@@@ -15115,21 -15066,38 +15114,21 @@@ void i915_redisable_vga(struct drm_devi
        i915_redisable_vga_power_on(dev);
  }
  
 -static bool primary_get_hw_state(struct intel_crtc *crtc)
 +static bool primary_get_hw_state(struct intel_plane *plane)
  {
 -      struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
 +      struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  
 -      return !!(I915_READ(DSPCNTR(crtc->plane)) & DISPLAY_PLANE_ENABLE);
 +      return I915_READ(DSPCNTR(plane->plane)) & DISPLAY_PLANE_ENABLE;
  }
  
 -static void readout_plane_state(struct intel_crtc *crtc,
 -                              struct intel_crtc_state *crtc_state)
 +/* FIXME read out full plane state for all planes */
 +static void readout_plane_state(struct intel_crtc *crtc)
  {
 -      struct intel_plane *p;
 -      struct intel_plane_state *plane_state;
 -      bool active = crtc_state->base.active;
 -
 -      for_each_intel_plane(crtc->base.dev, p) {
 -              if (crtc->pipe != p->pipe)
 -                      continue;
 -
 -              plane_state = to_intel_plane_state(p->base.state);
 -
 -              if (p->base.type == DRM_PLANE_TYPE_PRIMARY) {
 -                      plane_state->visible = primary_get_hw_state(crtc);
 -                      if (plane_state->visible)
 -                              crtc->base.state->plane_mask |=
 -                                      1 << drm_plane_index(&p->base);
 -              } else {
 -                      if (active)
 -                              p->disable_plane(&p->base, &crtc->base);
 +      struct intel_plane_state *plane_state =
 +              to_intel_plane_state(crtc->base.primary->state);
  
 -                      plane_state->visible = false;
 -              }
 -      }
 +      plane_state->visible =
 +              primary_get_hw_state(to_intel_plane(crtc->base.primary));
  }
  
  static void intel_modeset_readout_hw_state(struct drm_device *dev)
                crtc->base.state->active = crtc->active;
                crtc->base.enabled = crtc->active;
  
 -              memset(&crtc->base.mode, 0, sizeof(crtc->base.mode));
 -              if (crtc->base.state->active) {
 -                      intel_mode_from_pipe_config(&crtc->base.mode, crtc->config);
 -                      intel_mode_from_pipe_config(&crtc->base.state->adjusted_mode, crtc->config);
 -                      WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode));
 -
 -                      /*
 -                       * The initial mode needs to be set in order to keep
 -                       * the atomic core happy. It wants a valid mode if the
 -                       * crtc's enabled, so we do the above call.
 -                       *
 -                       * At this point some state updated by the connectors
 -                       * in their ->detect() callback has not run yet, so
 -                       * no recalculation can be done yet.
 -                       *
 -                       * Even if we could do a recalculation and modeset
 -                       * right now it would cause a double modeset if
 -                       * fbdev or userspace chooses a different initial mode.
 -                       *
 -                       * If that happens, someone indicated they wanted a
 -                       * mode change, which means it's safe to do a full
 -                       * recalculation.
 -                       */
 -                      crtc->base.state->mode.private_flags = I915_MODE_FLAG_INHERITED;
 -              }
 -
 -              crtc->base.hwmode = crtc->config->base.adjusted_mode;
 -              readout_plane_state(crtc, to_intel_crtc_state(crtc->base.state));
 +              readout_plane_state(crtc);
  
                DRM_DEBUG_KMS("[CRTC:%d] hw state readout: %s\n",
                              crtc->base.base.id,
                              connector->base.name,
                              connector->base.encoder ? "enabled" : "disabled");
        }
 +
 +      for_each_intel_crtc(dev, crtc) {
 +              crtc->base.hwmode = crtc->config->base.adjusted_mode;
 +
 +              memset(&crtc->base.mode, 0, sizeof(crtc->base.mode));
 +              if (crtc->base.state->active) {
 +                      intel_mode_from_pipe_config(&crtc->base.mode, crtc->config);
 +                      intel_mode_from_pipe_config(&crtc->base.state->adjusted_mode, crtc->config);
 +                      WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode));
 +
 +                      /*
 +                       * The initial mode needs to be set in order to keep
 +                       * the atomic core happy. It wants a valid mode if the
 +                       * crtc's enabled, so we do the above call.
 +                       *
 +                       * At this point some state updated by the connectors
 +                       * in their ->detect() callback has not run yet, so
 +                       * no recalculation can be done yet.
 +                       *
 +                       * Even if we could do a recalculation and modeset
 +                       * right now it would cause a double modeset if
 +                       * fbdev or userspace chooses a different initial mode.
 +                       *
 +                       * If that happens, someone indicated they wanted a
 +                       * mode change, which means it's safe to do a full
 +                       * recalculation.
 +                       */
 +                      crtc->base.state->mode.private_flags = I915_MODE_FLAG_INHERITED;
 +
 +                      drm_calc_timestamping_constants(&crtc->base, &crtc->base.hwmode);
 +                      update_scanline_offset(crtc);
 +              }
 +      }
  }
  
  /* Scan out the current hw modeset state,
index 5fe1648cd9c8ee1d2a70e36fa35c2382f06acc5f,7bb96d5850de3d6e6e05b55b5d234fc5e5f4f56b..06a2b1046daf73bf06a3bed1d66a57d9f1750b4e
@@@ -130,11 -130,6 +130,11 @@@ static void vlv_init_panel_power_sequen
  static void vlv_steal_power_sequencer(struct drm_device *dev,
                                      enum pipe pipe);
  
 +static unsigned int intel_dp_unused_lane_mask(int lane_count)
 +{
 +      return ~((1 << lane_count) - 1) & 0xf;
 +}
 +
  static int
  intel_dp_max_link_bw(struct intel_dp  *intel_dp)
  {
@@@ -258,6 -253,40 +258,6 @@@ static void intel_dp_unpack_aux(uint32_
                dst[i] = src >> ((3-i) * 8);
  }
  
 -/* hrawclock is 1/4 the FSB frequency */
 -static int
 -intel_hrawclk(struct drm_device *dev)
 -{
 -      struct drm_i915_private *dev_priv = dev->dev_private;
 -      uint32_t clkcfg;
 -
 -      /* There is no CLKCFG reg in Valleyview. VLV hrawclk is 200 MHz */
 -      if (IS_VALLEYVIEW(dev))
 -              return 200;
 -
 -      clkcfg = I915_READ(CLKCFG);
 -      switch (clkcfg & CLKCFG_FSB_MASK) {
 -      case CLKCFG_FSB_400:
 -              return 100;
 -      case CLKCFG_FSB_533:
 -              return 133;
 -      case CLKCFG_FSB_667:
 -              return 166;
 -      case CLKCFG_FSB_800:
 -              return 200;
 -      case CLKCFG_FSB_1067:
 -              return 266;
 -      case CLKCFG_FSB_1333:
 -              return 333;
 -      /* these two are just a guess; one of them might be right */
 -      case CLKCFG_FSB_1600:
 -      case CLKCFG_FSB_1600_ALT:
 -              return 400;
 -      default:
 -              return 133;
 -      }
 -}
 -
  static void
  intel_dp_init_panel_power_sequencer(struct drm_device *dev,
                                    struct intel_dp *intel_dp);
@@@ -304,9 -333,7 +304,9 @@@ vlv_power_sequencer_kick(struct intel_d
        struct drm_device *dev = intel_dig_port->base.base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        enum pipe pipe = intel_dp->pps_pipe;
 -      bool pll_enabled;
 +      bool pll_enabled, release_cl_override = false;
 +      enum dpio_phy phy = DPIO_PHY(pipe);
 +      enum dpio_channel ch = vlv_pipe_to_channel(pipe);
        uint32_t DP;
  
        if (WARN(I915_READ(intel_dp->output_reg) & DP_PORT_EN,
         * The DPLL for the pipe must be enabled for this to work.
         * So enable temporarily it if it's not already enabled.
         */
 -      if (!pll_enabled)
 +      if (!pll_enabled) {
 +              release_cl_override = IS_CHERRYVIEW(dev) &&
 +                      !chv_phy_powergate_ch(dev_priv, phy, ch, true);
 +
                vlv_force_pll_on(dev, pipe, IS_CHERRYVIEW(dev) ?
                                 &chv_dpll[0].dpll : &vlv_dpll[0].dpll);
 +      }
  
        /*
         * Similar magic as in intel_dp_enable_port().
        I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN);
        POSTING_READ(intel_dp->output_reg);
  
 -      if (!pll_enabled)
 +      if (!pll_enabled) {
                vlv_force_pll_off(dev, pipe);
 +
 +              if (release_cl_override)
 +                      chv_phy_powergate_ch(dev_priv, phy, ch, false);
 +      }
  }
  
  static enum pipe
@@@ -955,6 -974,7 +955,7 @@@ intel_dp_aux_transfer(struct drm_dp_au
        switch (msg->request & ~DP_AUX_I2C_MOT) {
        case DP_AUX_NATIVE_WRITE:
        case DP_AUX_I2C_WRITE:
+       case DP_AUX_I2C_WRITE_STATUS_UPDATE:
                txsize = msg->size ? HEADER_SIZE + msg->size : BARE_ADDRESS_SIZE;
                rxsize = 2; /* 0 or 1 data bytes */
  
@@@ -1364,19 -1384,6 +1365,19 @@@ int intel_dp_rate_select(struct intel_d
        return rate_to_index(rate, intel_dp->sink_rates);
  }
  
 +static void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
 +                                uint8_t *link_bw, uint8_t *rate_select)
 +{
 +      if (intel_dp->num_sink_rates) {
 +              *link_bw = 0;
 +              *rate_select =
 +                      intel_dp_rate_select(intel_dp, port_clock);
 +      } else {
 +              *link_bw = drm_dp_link_rate_to_bw_code(port_clock);
 +              *rate_select = 0;
 +      }
 +}
 +
  bool
  intel_dp_compute_config(struct intel_encoder *encoder,
                        struct intel_crtc_state *pipe_config)
        int link_avail, link_clock;
        int common_rates[DP_MAX_SUPPORTED_RATES] = {};
        int common_len;
 +      uint8_t link_bw, rate_select;
  
        common_len = intel_dp_common_rates(intel_dp, common_rates);
  
@@@ -1494,23 -1500,32 +1495,23 @@@ found
                 * CEA-861-E - 5.1 Default Encoding Parameters
                 * VESA DisplayPort Ver.1.2a - 5.1.1.1 Video Colorimetry
                 */
 -              if (bpp != 18 && drm_match_cea_mode(adjusted_mode) > 1)
 -                      intel_dp->color_range = DP_COLOR_RANGE_16_235;
 -              else
 -                      intel_dp->color_range = 0;
 -      }
 -
 -      if (intel_dp->color_range)
 -              pipe_config->limited_color_range = true;
 -
 -      intel_dp->lane_count = lane_count;
 -
 -      if (intel_dp->num_sink_rates) {
 -              intel_dp->link_bw = 0;
 -              intel_dp->rate_select =
 -                      intel_dp_rate_select(intel_dp, common_rates[clock]);
 +              pipe_config->limited_color_range =
 +                      bpp != 18 && drm_match_cea_mode(adjusted_mode) > 1;
        } else {
 -              intel_dp->link_bw =
 -                      drm_dp_link_rate_to_bw_code(common_rates[clock]);
 -              intel_dp->rate_select = 0;
 +              pipe_config->limited_color_range =
 +                      intel_dp->limited_color_range;
        }
  
 +      pipe_config->lane_count = lane_count;
 +
        pipe_config->pipe_bpp = bpp;
        pipe_config->port_clock = common_rates[clock];
  
 -      DRM_DEBUG_KMS("DP link bw %02x lane count %d clock %d bpp %d\n",
 -                    intel_dp->link_bw, intel_dp->lane_count,
 +      intel_dp_compute_rate(intel_dp, pipe_config->port_clock,
 +                            &link_bw, &rate_select);
 +
 +      DRM_DEBUG_KMS("DP link bw %02x rate select %02x lane count %d clock %d bpp %d\n",
 +                    link_bw, rate_select, pipe_config->lane_count,
                      pipe_config->port_clock, bpp);
        DRM_DEBUG_KMS("DP link bw required %i available %i\n",
                      mode_rate, link_avail);
@@@ -1572,13 -1587,6 +1573,13 @@@ static void ironlake_set_pll_cpu_edp(st
        udelay(500);
  }
  
 +void intel_dp_set_link_params(struct intel_dp *intel_dp,
 +                            const struct intel_crtc_state *pipe_config)
 +{
 +      intel_dp->link_rate = pipe_config->port_clock;
 +      intel_dp->lane_count = pipe_config->lane_count;
 +}
 +
  static void intel_dp_prepare(struct intel_encoder *encoder)
  {
        struct drm_device *dev = encoder->base.dev;
        struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
        struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
  
 +      intel_dp_set_link_params(intel_dp, crtc->config);
 +
        /*
         * There are four kinds of DP registers:
         *
  
        /* Handle DP bits in common between all three register formats */
        intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
 -      intel_dp->DP |= DP_PORT_WIDTH(intel_dp->lane_count);
 +      intel_dp->DP |= DP_PORT_WIDTH(crtc->config->lane_count);
  
        if (crtc->config->has_audio)
                intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE;
                        trans_dp &= ~TRANS_DP_ENH_FRAMING;
                I915_WRITE(TRANS_DP_CTL(crtc->pipe), trans_dp);
        } else {
 -              if (!HAS_PCH_SPLIT(dev) && !IS_VALLEYVIEW(dev))
 -                      intel_dp->DP |= intel_dp->color_range;
 +              if (!HAS_PCH_SPLIT(dev) && !IS_VALLEYVIEW(dev) &&
 +                  crtc->config->limited_color_range)
 +                      intel_dp->DP |= DP_COLOR_RANGE_16_235;
  
                if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
                        intel_dp->DP |= DP_SYNC_HS_HIGH;
@@@ -2286,14 -2291,13 +2287,14 @@@ static void intel_dp_get_config(struct 
        pipe_config->has_audio = tmp & DP_AUDIO_OUTPUT_ENABLE && port != PORT_A;
  
        if (HAS_PCH_CPT(dev) && port != PORT_A) {
 -              tmp = I915_READ(TRANS_DP_CTL(crtc->pipe));
 -              if (tmp & TRANS_DP_HSYNC_ACTIVE_HIGH)
 +              u32 trans_dp = I915_READ(TRANS_DP_CTL(crtc->pipe));
 +
 +              if (trans_dp & TRANS_DP_HSYNC_ACTIVE_HIGH)
                        flags |= DRM_MODE_FLAG_PHSYNC;
                else
                        flags |= DRM_MODE_FLAG_NHSYNC;
  
 -              if (tmp & TRANS_DP_VSYNC_ACTIVE_HIGH)
 +              if (trans_dp & TRANS_DP_VSYNC_ACTIVE_HIGH)
                        flags |= DRM_MODE_FLAG_PVSYNC;
                else
                        flags |= DRM_MODE_FLAG_NVSYNC;
  
        pipe_config->has_dp_encoder = true;
  
 +      pipe_config->lane_count =
 +              ((tmp & DP_PORT_WIDTH_MASK) >> DP_PORT_WIDTH_SHIFT) + 1;
 +
        intel_dp_get_m_n(crtc, pipe_config);
  
        if (port == PORT_A) {
@@@ -2399,62 -2400,38 +2400,62 @@@ static void vlv_post_disable_dp(struct 
        intel_dp_link_down(intel_dp);
  }
  
 -static void chv_post_disable_dp(struct intel_encoder *encoder)
 +static void chv_data_lane_soft_reset(struct intel_encoder *encoder,
 +                                   bool reset)
  {
 -      struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
 -      struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
 -      struct drm_device *dev = encoder->base.dev;
 -      struct drm_i915_private *dev_priv = dev->dev_private;
 -      struct intel_crtc *intel_crtc =
 -              to_intel_crtc(encoder->base.crtc);
 -      enum dpio_channel ch = vlv_dport_to_channel(dport);
 -      enum pipe pipe = intel_crtc->pipe;
 -      u32 val;
 +      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 +      enum dpio_channel ch = vlv_dport_to_channel(enc_to_dig_port(&encoder->base));
 +      struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
 +      enum pipe pipe = crtc->pipe;
 +      uint32_t val;
  
 -      intel_dp_link_down(intel_dp);
 +      val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW0(ch));
 +      if (reset)
 +              val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
 +      else
 +              val |= DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET;
 +      vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW0(ch), val);
  
 -      mutex_lock(&dev_priv->sb_lock);
 +      if (crtc->config->lane_count > 2) {
 +              val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW0(ch));
 +              if (reset)
 +                      val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
 +              else
 +                      val |= DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET;
 +              vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW0(ch), val);
 +      }
  
 -      /* Propagate soft reset to data lane reset */
        val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW1(ch));
        val |= CHV_PCS_REQ_SOFTRESET_EN;
 +      if (reset)
 +              val &= ~DPIO_PCS_CLK_SOFT_RESET;
 +      else
 +              val |= DPIO_PCS_CLK_SOFT_RESET;
        vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW1(ch), val);
  
 -      val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW1(ch));
 -      val |= CHV_PCS_REQ_SOFTRESET_EN;
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW1(ch), val);
 +      if (crtc->config->lane_count > 2) {
 +              val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW1(ch));
 +              val |= CHV_PCS_REQ_SOFTRESET_EN;
 +              if (reset)
 +                      val &= ~DPIO_PCS_CLK_SOFT_RESET;
 +              else
 +                      val |= DPIO_PCS_CLK_SOFT_RESET;
 +              vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW1(ch), val);
 +      }
 +}
  
 -      val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW0(ch));
 -      val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW0(ch), val);
 +static void chv_post_disable_dp(struct intel_encoder *encoder)
 +{
 +      struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
 +      struct drm_device *dev = encoder->base.dev;
 +      struct drm_i915_private *dev_priv = dev->dev_private;
  
 -      val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW0(ch));
 -      val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW0(ch), val);
 +      intel_dp_link_down(intel_dp);
 +
 +      mutex_lock(&dev_priv->sb_lock);
 +
 +      /* Assert data lane reset */
 +      chv_data_lane_soft_reset(encoder, true);
  
        mutex_unlock(&dev_priv->sb_lock);
  }
@@@ -2574,6 -2551,7 +2575,6 @@@ static void intel_enable_dp(struct inte
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
        uint32_t dp_reg = I915_READ(intel_dp->output_reg);
 -      unsigned int lane_mask = 0x0;
  
        if (WARN_ON(dp_reg & DP_PORT_EN))
                return;
  
        pps_unlock(intel_dp);
  
 -      if (IS_VALLEYVIEW(dev))
 +      if (IS_VALLEYVIEW(dev)) {
 +              unsigned int lane_mask = 0x0;
 +
 +              if (IS_CHERRYVIEW(dev))
 +                      lane_mask = intel_dp_unused_lane_mask(crtc->config->lane_count);
 +
                vlv_wait_port_ready(dev_priv, dp_to_dig_port(intel_dp),
                                    lane_mask);
 +      }
  
        intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
        intel_dp_start_link_train(intel_dp);
@@@ -2826,19 -2798,31 +2827,19 @@@ static void chv_pre_enable_dp(struct in
        val &= ~DPIO_LANEDESKEW_STRAP_OVRD;
        vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW11(ch), val);
  
 -      val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW11(ch));
 -      val &= ~DPIO_LANEDESKEW_STRAP_OVRD;
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW11(ch), val);
 -
 -      /* Deassert soft data lane reset*/
 -      val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW1(ch));
 -      val |= CHV_PCS_REQ_SOFTRESET_EN;
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW1(ch), val);
 -
 -      val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW1(ch));
 -      val |= CHV_PCS_REQ_SOFTRESET_EN;
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW1(ch), val);
 -
 -      val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW0(ch));
 -      val |= (DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW0(ch), val);
 -
 -      val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW0(ch));
 -      val |= (DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW0(ch), val);
 +      if (intel_crtc->config->lane_count > 2) {
 +              val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW11(ch));
 +              val &= ~DPIO_LANEDESKEW_STRAP_OVRD;
 +              vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW11(ch), val);
 +      }
  
        /* Program Tx lane latency optimal setting*/
 -      for (i = 0; i < 4; i++) {
 +      for (i = 0; i < intel_crtc->config->lane_count; i++) {
                /* Set the upar bit */
 -              data = (i == 1) ? 0x0 : 0x1;
 +              if (intel_crtc->config->lane_count == 1)
 +                      data = 0x0;
 +              else
 +                      data = (i == 1) ? 0x0 : 0x1;
                vlv_dpio_write(dev_priv, pipe, CHV_TX_DW14(ch, i),
                                data << DPIO_UPAR_SHIFT);
        }
        val |= DPIO_TX2_STAGGER_MASK(0x1f);
        vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW11(ch), val);
  
 -      val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW11(ch));
 -      val |= DPIO_TX2_STAGGER_MASK(0x1f);
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW11(ch), val);
 +      if (intel_crtc->config->lane_count > 2) {
 +              val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW11(ch));
 +              val |= DPIO_TX2_STAGGER_MASK(0x1f);
 +              vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW11(ch), val);
 +      }
  
        vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW12(ch),
                       DPIO_LANESTAGGER_STRAP(stagger) |
                       DPIO_TX1_STAGGER_MULT(6) |
                       DPIO_TX2_STAGGER_MULT(0));
  
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW12(ch),
 -                     DPIO_LANESTAGGER_STRAP(stagger) |
 -                     DPIO_LANESTAGGER_STRAP_OVRD |
 -                     DPIO_TX1_STAGGER_MASK(0x1f) |
 -                     DPIO_TX1_STAGGER_MULT(7) |
 -                     DPIO_TX2_STAGGER_MULT(5));
 +      if (intel_crtc->config->lane_count > 2) {
 +              vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW12(ch),
 +                             DPIO_LANESTAGGER_STRAP(stagger) |
 +                             DPIO_LANESTAGGER_STRAP_OVRD |
 +                             DPIO_TX1_STAGGER_MASK(0x1f) |
 +                             DPIO_TX1_STAGGER_MULT(7) |
 +                             DPIO_TX2_STAGGER_MULT(5));
 +      }
 +
 +      /* Deassert data lane reset */
 +      chv_data_lane_soft_reset(encoder, false);
  
        mutex_unlock(&dev_priv->sb_lock);
  
        intel_enable_dp(encoder);
 +
 +      /* Second common lane will stay alive on its own now */
 +      if (dport->release_cl2_override) {
 +              chv_phy_powergate_ch(dev_priv, DPIO_PHY0, DPIO_CH1, false);
 +              dport->release_cl2_override = false;
 +      }
  }
  
  static void chv_dp_pre_pll_enable(struct intel_encoder *encoder)
                to_intel_crtc(encoder->base.crtc);
        enum dpio_channel ch = vlv_dport_to_channel(dport);
        enum pipe pipe = intel_crtc->pipe;
 +      unsigned int lane_mask =
 +              intel_dp_unused_lane_mask(intel_crtc->config->lane_count);
        u32 val;
  
        intel_dp_prepare(encoder);
  
 +      /*
 +       * Must trick the second common lane into life.
 +       * Otherwise we can't even access the PLL.
 +       */
 +      if (ch == DPIO_CH0 && pipe == PIPE_B)
 +              dport->release_cl2_override =
 +                      !chv_phy_powergate_ch(dev_priv, DPIO_PHY0, DPIO_CH1, true);
 +
 +      chv_phy_powergate_lanes(encoder, true, lane_mask);
 +
        mutex_lock(&dev_priv->sb_lock);
  
 +      /* Assert data lane reset */
 +      chv_data_lane_soft_reset(encoder, true);
 +
        /* program left/right clock distribution */
        if (pipe != PIPE_B) {
                val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW5_CH0);
                val |= CHV_PCS_USEDCLKCHANNEL;
        vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW8(ch), val);
  
 -      val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW8(ch));
 -      val |= CHV_PCS_USEDCLKCHANNEL_OVRRIDE;
 -      if (pipe != PIPE_B)
 -              val &= ~CHV_PCS_USEDCLKCHANNEL;
 -      else
 -              val |= CHV_PCS_USEDCLKCHANNEL;
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW8(ch), val);
 +      if (intel_crtc->config->lane_count > 2) {
 +              val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW8(ch));
 +              val |= CHV_PCS_USEDCLKCHANNEL_OVRRIDE;
 +              if (pipe != PIPE_B)
 +                      val &= ~CHV_PCS_USEDCLKCHANNEL;
 +              else
 +                      val |= CHV_PCS_USEDCLKCHANNEL;
 +              vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW8(ch), val);
 +      }
  
        /*
         * This a a bit weird since generally CL
        mutex_unlock(&dev_priv->sb_lock);
  }
  
 +static void chv_dp_post_pll_disable(struct intel_encoder *encoder)
 +{
 +      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 +      enum pipe pipe = to_intel_crtc(encoder->base.crtc)->pipe;
 +      u32 val;
 +
 +      mutex_lock(&dev_priv->sb_lock);
 +
 +      /* disable left/right clock distribution */
 +      if (pipe != PIPE_B) {
 +              val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW5_CH0);
 +              val &= ~(CHV_BUFLEFTENA1_MASK | CHV_BUFRIGHTENA1_MASK);
 +              vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW5_CH0, val);
 +      } else {
 +              val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW1_CH1);
 +              val &= ~(CHV_BUFLEFTENA2_MASK | CHV_BUFRIGHTENA2_MASK);
 +              vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW1_CH1, val);
 +      }
 +
 +      mutex_unlock(&dev_priv->sb_lock);
 +
 +      /*
 +       * Leave the power down bit cleared for at least one
 +       * lane so that chv_powergate_phy_ch() will power
 +       * on something when the channel is otherwise unused.
 +       * When the port is off and the override is removed
 +       * the lanes power down anyway, so otherwise it doesn't
 +       * really matter what the state of power down bits is
 +       * after this.
 +       */
 +      chv_phy_powergate_lanes(encoder, false, 0x0);
 +}
 +
  /*
   * Native read with retry for link status and receiver capability reads for
   * cases where the sink may still be asleep.
@@@ -3247,12 -3168,6 +3248,12 @@@ static uint32_t vlv_signal_levels(struc
        return 0;
  }
  
 +static bool chv_need_uniq_trans_scale(uint8_t train_set)
 +{
 +      return (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) == DP_TRAIN_PRE_EMPH_LEVEL_0 &&
 +              (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) == DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
 +}
 +
  static uint32_t chv_signal_levels(struct intel_dp *intel_dp)
  {
        struct drm_device *dev = intel_dp_to_dev(intel_dp);
        val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5;
        vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val);
  
 -      val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch));
 -      val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);
 -      val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK);
 -      val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5;
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val);
 +      if (intel_crtc->config->lane_count > 2) {
 +              val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch));
 +              val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);
 +              val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK);
 +              val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5;
 +              vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val);
 +      }
  
        val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW9(ch));
        val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK);
        val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000;
        vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW9(ch), val);
  
 -      val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW9(ch));
 -      val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK);
 -      val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000;
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW9(ch), val);
 +      if (intel_crtc->config->lane_count > 2) {
 +              val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW9(ch));
 +              val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK);
 +              val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000;
 +              vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW9(ch), val);
 +      }
  
        /* Program swing deemph */
 -      for (i = 0; i < 4; i++) {
 +      for (i = 0; i < intel_crtc->config->lane_count; i++) {
                val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW4(ch, i));
                val &= ~DPIO_SWING_DEEMPH9P5_MASK;
                val |= deemph_reg_value << DPIO_SWING_DEEMPH9P5_SHIFT;
        }
  
        /* Program swing margin */
 -      for (i = 0; i < 4; i++) {
 +      for (i = 0; i < intel_crtc->config->lane_count; i++) {
                val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW2(ch, i));
 +
                val &= ~DPIO_SWING_MARGIN000_MASK;
                val |= margin_reg_value << DPIO_SWING_MARGIN000_SHIFT;
 +
 +              /*
 +               * Supposedly this value shouldn't matter when unique transition
 +               * scale is disabled, but in fact it does matter. Let's just
 +               * always program the same value and hope it's OK.
 +               */
 +              val &= ~(0xff << DPIO_UNIQ_TRANS_SCALE_SHIFT);
 +              val |= 0x9a << DPIO_UNIQ_TRANS_SCALE_SHIFT;
 +
                vlv_dpio_write(dev_priv, pipe, CHV_TX_DW2(ch, i), val);
        }
  
 -      /* Disable unique transition scale */
 -      for (i = 0; i < 4; i++) {
 +      /*
 +       * The document said it needs to set bit 27 for ch0 and bit 26
 +       * for ch1. Might be a typo in the doc.
 +       * For now, for this unique transition scale selection, set bit
 +       * 27 for ch0 and ch1.
 +       */
 +      for (i = 0; i < intel_crtc->config->lane_count; i++) {
                val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW3(ch, i));
 -              val &= ~DPIO_TX_UNIQ_TRANS_SCALE_EN;
 -              vlv_dpio_write(dev_priv, pipe, CHV_TX_DW3(ch, i), val);
 -      }
 -
 -      if (((train_set & DP_TRAIN_PRE_EMPHASIS_MASK)
 -                      == DP_TRAIN_PRE_EMPH_LEVEL_0) &&
 -              ((train_set & DP_TRAIN_VOLTAGE_SWING_MASK)
 -                      == DP_TRAIN_VOLTAGE_SWING_LEVEL_3)) {
 -
 -              /*
 -               * The document said it needs to set bit 27 for ch0 and bit 26
 -               * for ch1. Might be a typo in the doc.
 -               * For now, for this unique transition scale selection, set bit
 -               * 27 for ch0 and ch1.
 -               */
 -              for (i = 0; i < 4; i++) {
 -                      val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW3(ch, i));
 +              if (chv_need_uniq_trans_scale(train_set))
                        val |= DPIO_TX_UNIQ_TRANS_SCALE_EN;
 -                      vlv_dpio_write(dev_priv, pipe, CHV_TX_DW3(ch, i), val);
 -              }
 -
 -              for (i = 0; i < 4; i++) {
 -                      val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW2(ch, i));
 -                      val &= ~(0xff << DPIO_UNIQ_TRANS_SCALE_SHIFT);
 -                      val |= (0x9a << DPIO_UNIQ_TRANS_SCALE_SHIFT);
 -                      vlv_dpio_write(dev_priv, pipe, CHV_TX_DW2(ch, i), val);
 -              }
 +              else
 +                      val &= ~DPIO_TX_UNIQ_TRANS_SCALE_EN;
 +              vlv_dpio_write(dev_priv, pipe, CHV_TX_DW3(ch, i), val);
        }
  
        /* Start swing calculation */
        val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3;
        vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val);
  
 -      val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch));
 -      val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3;
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val);
 +      if (intel_crtc->config->lane_count > 2) {
 +              val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch));
 +              val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3;
 +              vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val);
 +      }
  
        /* LRC Bypass */
        val = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW30);
@@@ -3605,8 -3521,8 +3606,8 @@@ intel_dp_set_link_train(struct intel_d
                        uint8_t dp_train_pat)
  {
        struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 -      struct drm_device *dev = intel_dig_port->base.base.dev;
 -      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct drm_i915_private *dev_priv =
 +              to_i915(intel_dig_port->base.base.dev);
        uint8_t buf[sizeof(intel_dp->train_set) + 1];
        int ret, len;
  
@@@ -3647,8 -3563,8 +3648,8 @@@ intel_dp_update_link_train(struct intel
                           const uint8_t link_status[DP_LINK_STATUS_SIZE])
  {
        struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 -      struct drm_device *dev = intel_dig_port->base.base.dev;
 -      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct drm_i915_private *dev_priv =
 +              to_i915(intel_dig_port->base.base.dev);
        int ret;
  
        intel_get_adjust_train(intel_dp, link_status);
@@@ -3705,23 -3621,19 +3706,23 @@@ intel_dp_start_link_train(struct intel_
        int voltage_tries, loop_tries;
        uint32_t DP = intel_dp->DP;
        uint8_t link_config[2];
 +      uint8_t link_bw, rate_select;
  
        if (HAS_DDI(dev))
                intel_ddi_prepare_link_retrain(encoder);
  
 +      intel_dp_compute_rate(intel_dp, intel_dp->link_rate,
 +                            &link_bw, &rate_select);
 +
        /* Write the link configuration data */
 -      link_config[0] = intel_dp->link_bw;
 +      link_config[0] = link_bw;
        link_config[1] = intel_dp->lane_count;
        if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
                link_config[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
        drm_dp_dpcd_write(&intel_dp->aux, DP_LINK_BW_SET, link_config, 2);
        if (intel_dp->num_sink_rates)
                drm_dp_dpcd_write(&intel_dp->aux, DP_LINK_RATE_SET,
 -                              &intel_dp->rate_select, 1);
 +                                &rate_select, 1);
  
        link_config[0] = 0;
        link_config[1] = DP_SET_ANSI_8B10B;
  void
  intel_dp_complete_link_train(struct intel_dp *intel_dp)
  {
 +      struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
 +      struct drm_device *dev = dig_port->base.base.dev;
        bool channel_eq = false;
        int tries, cr_tries;
        uint32_t DP = intel_dp->DP;
        uint32_t training_pattern = DP_TRAINING_PATTERN_2;
  
 -      /* Training Pattern 3 for HBR2 ot 1.2 devices that support it*/
 -      if (intel_dp->link_bw == DP_LINK_BW_5_4 || intel_dp->use_tps3)
 +      /*
 +       * Training Pattern 3 for HBR2 or 1.2 devices that support it.
 +       *
 +       * Intel platforms that support HBR2 also support TPS3. TPS3 support is
 +       * also mandatory for downstream devices that support HBR2.
 +       *
 +       * Due to WaDisableHBR2 SKL < B0 is the only exception where TPS3 is
 +       * supported but still not enabled.
 +       */
 +      if (intel_dp_source_supports_hbr2(dev) &&
 +          drm_dp_tps3_supported(intel_dp->dpcd))
                training_pattern = DP_TRAINING_PATTERN_3;
 +      else if (intel_dp->link_rate == 540000)
 +              DRM_ERROR("5.4 Gbps link rate without HBR2/TPS3 support\n");
  
        /* channel equalization */
        if (!intel_dp_set_link_train(intel_dp, &DP,
                }
  
                /* Make sure clock is still ok */
 -              if (!drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count)) {
 +              if (!drm_dp_clock_recovery_ok(link_status,
 +                                            intel_dp->lane_count)) {
                        intel_dp->train_set_valid = false;
                        intel_dp_start_link_train(intel_dp);
                        intel_dp_set_link_train(intel_dp, &DP,
                        continue;
                }
  
 -              if (drm_dp_channel_eq_ok(link_status, intel_dp->lane_count)) {
 +              if (drm_dp_channel_eq_ok(link_status,
 +                                       intel_dp->lane_count)) {
                        channel_eq = true;
                        break;
                }
@@@ -4013,9 -3910,19 +4014,9 @@@ intel_dp_get_dpcd(struct intel_dp *inte
                }
        }
  
 -      /* Training Pattern 3 support, Intel platforms that support HBR2 alone
 -       * have support for TP3 hence that check is used along with dpcd check
 -       * to ensure TP3 can be enabled.
 -       * SKL < B0: due it's WaDisableHBR2 is the only exception where TP3 is
 -       * supported but still not enabled.
 -       */
 -      if (intel_dp->dpcd[DP_DPCD_REV] >= 0x12 &&
 -          intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_TPS3_SUPPORTED &&
 -          intel_dp_source_supports_hbr2(dev)) {
 -              intel_dp->use_tps3 = true;
 -              DRM_DEBUG_KMS("Displayport TPS3 supported\n");
 -      } else
 -              intel_dp->use_tps3 = false;
 +      DRM_DEBUG_KMS("Display Port TPS3 support: source %s, sink %s\n",
 +                    yesno(intel_dp_source_supports_hbr2(dev)),
 +                    yesno(drm_dp_tps3_supported(intel_dp->dpcd)));
  
        /* Intermediate frequency support */
        if (is_edp(intel_dp) &&
@@@ -4101,30 -4008,22 +4102,30 @@@ intel_dp_probe_mst(struct intel_dp *int
        return intel_dp->is_mst;
  }
  
 -static void intel_dp_sink_crc_stop(struct intel_dp *intel_dp)
 +static int intel_dp_sink_crc_stop(struct intel_dp *intel_dp)
  {
        struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
        struct intel_crtc *intel_crtc = to_intel_crtc(dig_port->base.base.crtc);
        u8 buf;
 +      int ret = 0;
  
        if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK, &buf) < 0) {
                DRM_DEBUG_KMS("Sink CRC couldn't be stopped properly\n");
 -              return;
 +              ret = -EIO;
 +              goto out;
        }
  
        if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_SINK,
 -                             buf & ~DP_TEST_SINK_START) < 0)
 +                             buf & ~DP_TEST_SINK_START) < 0) {
                DRM_DEBUG_KMS("Sink CRC couldn't be stopped properly\n");
 +              ret = -EIO;
 +              goto out;
 +      }
  
 +      intel_dp->sink_crc.started = false;
 + out:
        hsw_enable_ips(intel_crtc);
 +      return ret;
  }
  
  static int intel_dp_sink_crc_start(struct intel_dp *intel_dp)
        struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
        struct intel_crtc *intel_crtc = to_intel_crtc(dig_port->base.base.crtc);
        u8 buf;
 +      int ret;
 +
 +      if (intel_dp->sink_crc.started) {
 +              ret = intel_dp_sink_crc_stop(intel_dp);
 +              if (ret)
 +                      return ret;
 +      }
  
        if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK_MISC, &buf) < 0)
                return -EIO;
        if (!(buf & DP_TEST_CRC_SUPPORTED))
                return -ENOTTY;
  
 +      intel_dp->sink_crc.last_count = buf & DP_TEST_COUNT_MASK;
 +
        if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK, &buf) < 0)
                return -EIO;
  
                return -EIO;
        }
  
 +      intel_dp->sink_crc.started = true;
        return 0;
  }
  
@@@ -4169,55 -4058,38 +4170,55 @@@ int intel_dp_sink_crc(struct intel_dp *
        struct drm_device *dev = dig_port->base.base.dev;
        struct intel_crtc *intel_crtc = to_intel_crtc(dig_port->base.base.crtc);
        u8 buf;
 -      int test_crc_count;
 +      int count, ret;
        int attempts = 6;
 -      int ret;
 +      bool old_equal_new;
  
        ret = intel_dp_sink_crc_start(intel_dp);
        if (ret)
                return ret;
  
 -      if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK_MISC, &buf) < 0) {
 -              ret = -EIO;
 -              goto stop;
 -      }
 -
 -      test_crc_count = buf & DP_TEST_COUNT_MASK;
 -
        do {
 +              intel_wait_for_vblank(dev, intel_crtc->pipe);
 +
                if (drm_dp_dpcd_readb(&intel_dp->aux,
                                      DP_TEST_SINK_MISC, &buf) < 0) {
                        ret = -EIO;
                        goto stop;
                }
 -              intel_wait_for_vblank(dev, intel_crtc->pipe);
 -      } while (--attempts && (buf & DP_TEST_COUNT_MASK) == test_crc_count);
 +              count = buf & DP_TEST_COUNT_MASK;
 +
 +              /*
 +               * Count might be reset during the loop. In this case
 +               * last known count needs to be reset as well.
 +               */
 +              if (count == 0)
 +                      intel_dp->sink_crc.last_count = 0;
 +
 +              if (drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_CRC_R_CR, crc, 6) < 0) {
 +                      ret = -EIO;
 +                      goto stop;
 +              }
 +
 +              old_equal_new = (count == intel_dp->sink_crc.last_count &&
 +                               !memcmp(intel_dp->sink_crc.last_crc, crc,
 +                                       6 * sizeof(u8)));
 +
 +      } while (--attempts && (count == 0 || old_equal_new));
 +
 +      intel_dp->sink_crc.last_count = buf & DP_TEST_COUNT_MASK;
 +      memcpy(intel_dp->sink_crc.last_crc, crc, 6 * sizeof(u8));
  
        if (attempts == 0) {
 -              DRM_DEBUG_KMS("Panel is unable to calculate CRC after 6 vblanks\n");
 -              ret = -ETIMEDOUT;
 -              goto stop;
 +              if (old_equal_new) {
 +                      DRM_DEBUG_KMS("Unreliable Sink CRC counter: Current returned CRC is identical to the previous one\n");
 +              } else {
 +                      DRM_ERROR("Panel is unable to calculate any CRC after 6 vblanks\n");
 +                      ret = -ETIMEDOUT;
 +                      goto stop;
 +              }
        }
  
 -      if (drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_CRC_R_CR, crc, 6) < 0)
 -              ret = -EIO;
  stop:
        intel_dp_sink_crc_stop(intel_dp);
        return ret;
@@@ -4377,8 -4249,7 +4378,8 @@@ go_again
                if (bret == true) {
  
                        /* check link status - esi[10] = 0x200c */
 -                      if (intel_dp->active_mst_links && !drm_dp_channel_eq_ok(&esi[10], intel_dp->lane_count)) {
 +                      if (intel_dp->active_mst_links &&
 +                          !drm_dp_channel_eq_ok(&esi[10], intel_dp->lane_count)) {
                                DRM_DEBUG_KMS("channel EQ not ok, retraining\n");
                                intel_dp_start_link_train(intel_dp);
                                intel_dp_complete_link_train(intel_dp);
@@@ -4540,164 -4411,58 +4541,164 @@@ edp_detect(struct intel_dp *intel_dp
        return status;
  }
  
 -static enum drm_connector_status
 -ironlake_dp_detect(struct intel_dp *intel_dp)
 +static bool ibx_digital_port_connected(struct drm_i915_private *dev_priv,
 +                                     struct intel_digital_port *port)
  {
 -      struct drm_device *dev = intel_dp_to_dev(intel_dp);
 -      struct drm_i915_private *dev_priv = dev->dev_private;
 -      struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 +      u32 bit;
  
 -      if (!ibx_digital_port_connected(dev_priv, intel_dig_port))
 -              return connector_status_disconnected;
 +      switch (port->port) {
 +      case PORT_A:
 +              return true;
 +      case PORT_B:
 +              bit = SDE_PORTB_HOTPLUG;
 +              break;
 +      case PORT_C:
 +              bit = SDE_PORTC_HOTPLUG;
 +              break;
 +      case PORT_D:
 +              bit = SDE_PORTD_HOTPLUG;
 +              break;
 +      default:
 +              MISSING_CASE(port->port);
 +              return false;
 +      }
  
 -      return intel_dp_detect_dpcd(intel_dp);
 +      return I915_READ(SDEISR) & bit;
 +}
 +
 +static bool cpt_digital_port_connected(struct drm_i915_private *dev_priv,
 +                                     struct intel_digital_port *port)
 +{
 +      u32 bit;
 +
 +      switch (port->port) {
 +      case PORT_A:
 +              return true;
 +      case PORT_B:
 +              bit = SDE_PORTB_HOTPLUG_CPT;
 +              break;
 +      case PORT_C:
 +              bit = SDE_PORTC_HOTPLUG_CPT;
 +              break;
 +      case PORT_D:
 +              bit = SDE_PORTD_HOTPLUG_CPT;
 +              break;
 +      case PORT_E:
 +              bit = SDE_PORTE_HOTPLUG_SPT;
 +              break;
 +      default:
 +              MISSING_CASE(port->port);
 +              return false;
 +      }
 +
 +      return I915_READ(SDEISR) & bit;
  }
  
 -static int g4x_digital_port_connected(struct drm_device *dev,
 +static bool g4x_digital_port_connected(struct drm_i915_private *dev_priv,
 +                                     struct intel_digital_port *port)
 +{
 +      u32 bit;
 +
 +      switch (port->port) {
 +      case PORT_B:
 +              bit = PORTB_HOTPLUG_LIVE_STATUS_G4X;
 +              break;
 +      case PORT_C:
 +              bit = PORTC_HOTPLUG_LIVE_STATUS_G4X;
 +              break;
 +      case PORT_D:
 +              bit = PORTD_HOTPLUG_LIVE_STATUS_G4X;
 +              break;
 +      default:
 +              MISSING_CASE(port->port);
 +              return false;
 +      }
 +
 +      return I915_READ(PORT_HOTPLUG_STAT) & bit;
 +}
 +
 +static bool vlv_digital_port_connected(struct drm_i915_private *dev_priv,
 +                                     struct intel_digital_port *port)
 +{
 +      u32 bit;
 +
 +      switch (port->port) {
 +      case PORT_B:
 +              bit = PORTB_HOTPLUG_LIVE_STATUS_VLV;
 +              break;
 +      case PORT_C:
 +              bit = PORTC_HOTPLUG_LIVE_STATUS_VLV;
 +              break;
 +      case PORT_D:
 +              bit = PORTD_HOTPLUG_LIVE_STATUS_VLV;
 +              break;
 +      default:
 +              MISSING_CASE(port->port);
 +              return false;
 +      }
 +
 +      return I915_READ(PORT_HOTPLUG_STAT) & bit;
 +}
 +
 +static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv,
                                       struct intel_digital_port *intel_dig_port)
  {
 -      struct drm_i915_private *dev_priv = dev->dev_private;
 -      uint32_t bit;
 +      struct intel_encoder *intel_encoder = &intel_dig_port->base;
 +      enum port port;
 +      u32 bit;
  
 -      if (IS_VALLEYVIEW(dev)) {
 -              switch (intel_dig_port->port) {
 -              case PORT_B:
 -                      bit = PORTB_HOTPLUG_LIVE_STATUS_VLV;
 -                      break;
 -              case PORT_C:
 -                      bit = PORTC_HOTPLUG_LIVE_STATUS_VLV;
 -                      break;
 -              case PORT_D:
 -                      bit = PORTD_HOTPLUG_LIVE_STATUS_VLV;
 -                      break;
 -              default:
 -                      return -EINVAL;
 -              }
 -      } else {
 -              switch (intel_dig_port->port) {
 -              case PORT_B:
 -                      bit = PORTB_HOTPLUG_LIVE_STATUS_G4X;
 -                      break;
 -              case PORT_C:
 -                      bit = PORTC_HOTPLUG_LIVE_STATUS_G4X;
 -                      break;
 -              case PORT_D:
 -                      bit = PORTD_HOTPLUG_LIVE_STATUS_G4X;
 -                      break;
 -              default:
 -                      return -EINVAL;
 -              }
 +      intel_hpd_pin_to_port(intel_encoder->hpd_pin, &port);
 +      switch (port) {
 +      case PORT_A:
 +              bit = BXT_DE_PORT_HP_DDIA;
 +              break;
 +      case PORT_B:
 +              bit = BXT_DE_PORT_HP_DDIB;
 +              break;
 +      case PORT_C:
 +              bit = BXT_DE_PORT_HP_DDIC;
 +              break;
 +      default:
 +              MISSING_CASE(port);
 +              return false;
        }
  
 -      if ((I915_READ(PORT_HOTPLUG_STAT) & bit) == 0)
 -              return 0;
 -      return 1;
 +      return I915_READ(GEN8_DE_PORT_ISR) & bit;
 +}
 +
 +/*
 + * intel_digital_port_connected - is the specified port connected?
 + * @dev_priv: i915 private structure
 + * @port: the port to test
 + *
 + * Return %true if @port is connected, %false otherwise.
 + */
 +bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
 +                                       struct intel_digital_port *port)
 +{
 +      if (HAS_PCH_IBX(dev_priv))
 +              return ibx_digital_port_connected(dev_priv, port);
 +      if (HAS_PCH_SPLIT(dev_priv))
 +              return cpt_digital_port_connected(dev_priv, port);
 +      else if (IS_BROXTON(dev_priv))
 +              return bxt_digital_port_connected(dev_priv, port);
 +      else if (IS_VALLEYVIEW(dev_priv))
 +              return vlv_digital_port_connected(dev_priv, port);
 +      else
 +              return g4x_digital_port_connected(dev_priv, port);
 +}
 +
 +static enum drm_connector_status
 +ironlake_dp_detect(struct intel_dp *intel_dp)
 +{
 +      struct drm_device *dev = intel_dp_to_dev(intel_dp);
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 +
 +      if (!intel_digital_port_connected(dev_priv, intel_dig_port))
 +              return connector_status_disconnected;
 +
 +      return intel_dp_detect_dpcd(intel_dp);
  }
  
  static enum drm_connector_status
@@@ -4705,6 -4470,7 +4706,6 @@@ g4x_dp_detect(struct intel_dp *intel_dp
  {
        struct drm_device *dev = intel_dp_to_dev(intel_dp);
        struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 -      int ret;
  
        /* Can't disconnect eDP, but you can close the lid... */
        if (is_edp(intel_dp)) {
                return status;
        }
  
 -      ret = g4x_digital_port_connected(dev, intel_dig_port);
 -      if (ret == -EINVAL)
 -              return connector_status_unknown;
 -      else if (ret == 0)
 +      if (!intel_digital_port_connected(dev->dev_private, intel_dig_port))
                return connector_status_disconnected;
  
        return intel_dp_detect_dpcd(intel_dp);
@@@ -4960,7 -4729,7 +4961,7 @@@ intel_dp_set_property(struct drm_connec
  
        if (property == dev_priv->broadcast_rgb_property) {
                bool old_auto = intel_dp->color_range_auto;
 -              uint32_t old_range = intel_dp->color_range;
 +              bool old_range = intel_dp->limited_color_range;
  
                switch (val) {
                case INTEL_BROADCAST_RGB_AUTO:
                        break;
                case INTEL_BROADCAST_RGB_FULL:
                        intel_dp->color_range_auto = false;
 -                      intel_dp->color_range = 0;
 +                      intel_dp->limited_color_range = false;
                        break;
                case INTEL_BROADCAST_RGB_LIMITED:
                        intel_dp->color_range_auto = false;
 -                      intel_dp->color_range = DP_COLOR_RANGE_16_235;
 +                      intel_dp->limited_color_range = true;
                        break;
                default:
                        return -EINVAL;
                }
  
                if (old_auto == intel_dp->color_range_auto &&
 -                  old_range == intel_dp->color_range)
 +                  old_range == intel_dp->limited_color_range)
                        return 0;
  
                goto done;
@@@ -5179,8 -4948,13 +5180,8 @@@ intel_dp_hpd_pulse(struct intel_digital
                /* indicate that we need to restart link training */
                intel_dp->train_set_valid = false;
  
 -              if (HAS_PCH_SPLIT(dev)) {
 -                      if (!ibx_digital_port_connected(dev_priv, intel_dig_port))
 -                              goto mst_fail;
 -              } else {
 -                      if (g4x_digital_port_connected(dev, intel_dig_port) != 1)
 -                              goto mst_fail;
 -              }
 +              if (!intel_digital_port_connected(dev_priv, intel_dig_port))
 +                      goto mst_fail;
  
                if (!intel_dp_get_dpcd(intel_dp)) {
                        goto mst_fail;
@@@ -5255,13 -5029,6 +5256,13 @@@ bool intel_dp_is_edp(struct drm_device 
                [PORT_E] = DVO_PORT_DPE,
        };
  
 +      /*
 +       * eDP not supported on g4x. so bail out early just
 +       * for a bit extra safety in case the VBT is bonkers.
 +       */
 +      if (INTEL_INFO(dev)->gen < 5)
 +              return false;
 +
        if (port == PORT_A)
                return true;
  
@@@ -6087,8 -5854,6 +6088,8 @@@ intel_dp_init_connector(struct intel_di
                break;
        case PORT_B:
                intel_encoder->hpd_pin = HPD_PORT_B;
 +              if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0))
 +                      intel_encoder->hpd_pin = HPD_PORT_A;
                break;
        case PORT_C:
                intel_encoder->hpd_pin = HPD_PORT_C;
@@@ -6189,7 -5954,6 +6190,7 @@@ intel_dp_init(struct drm_device *dev, i
                intel_encoder->pre_enable = chv_pre_enable_dp;
                intel_encoder->enable = vlv_enable_dp;
                intel_encoder->post_disable = chv_post_disable_dp;
 +              intel_encoder->post_pll_disable = chv_dp_post_pll_disable;
        } else if (IS_VALLEYVIEW(dev)) {
                intel_encoder->pre_pll_enable = vlv_dp_pre_pll_enable;
                intel_encoder->pre_enable = vlv_pre_enable_dp;
index 677d70e4d36340a7046669788c0f5cc82bad48a4,3e4be5a3becdddf9fd2a23e6be26f02da90a28f2..ff8ba55853be1cc6ef924a2c2ab2d15a1001634a
@@@ -39,7 -39,7 +39,7 @@@ static bool intel_dp_mst_compute_config
        struct intel_dp *intel_dp = &intel_dig_port->dp;
        struct drm_atomic_state *state;
        int bpp, i;
 -      int lane_count, slots, rate;
 +      int lane_count, slots;
        struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
        struct drm_connector *drm_connector;
        struct intel_connector *connector, *found = NULL;
         */
        lane_count = drm_dp_max_lane_count(intel_dp->dpcd);
  
 -      rate = intel_dp_max_link_rate(intel_dp);
  
 -      if (intel_dp->num_sink_rates) {
 -              intel_dp->link_bw = 0;
 -              intel_dp->rate_select = intel_dp_rate_select(intel_dp, rate);
 -      } else {
 -              intel_dp->link_bw = drm_dp_link_rate_to_bw_code(rate);
 -              intel_dp->rate_select = 0;
 -      }
 -
 -      intel_dp->lane_count = lane_count;
 +      pipe_config->lane_count = lane_count;
  
        pipe_config->pipe_bpp = 24;
 -      pipe_config->port_clock = rate;
 +      pipe_config->port_clock = intel_dp_max_link_rate(intel_dp);
  
        state = pipe_config->base.state;
  
@@@ -164,14 -173,17 +164,19 @@@ static void intel_mst_pre_enable_dp(str
                return;
        }
  
+       /* MST encoders are bound to a crtc, not to a connector,
+        * force the mapping here for get_hw_state.
+        */
+       found->encoder = encoder;
        DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links);
        intel_mst->port = found->port;
  
        if (intel_dp->active_mst_links == 0) {
                enum port port = intel_ddi_get_encoder_port(encoder);
  
 +              intel_dp_set_link_params(intel_dp, intel_crtc->config);
 +
                /* FIXME: add support for SKL */
                if (INTEL_INFO(dev)->gen < 9)
                        I915_WRITE(PORT_CLK_SEL(port),
@@@ -274,10 -286,6 +279,10 @@@ static void intel_dp_mst_enc_get_config
                break;
        }
        pipe_config->base.adjusted_mode.flags |= flags;
 +
 +      pipe_config->lane_count =
 +              ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
 +
        intel_dp_get_m_n(crtc, pipe_config);
  
        intel_ddi_clock_get(&intel_dig_port->base, pipe_config);
@@@ -397,7 -405,7 +402,7 @@@ static const struct drm_encoder_funcs i
  
  static bool intel_dp_mst_get_hw_state(struct intel_connector *connector)
  {
-       if (connector->encoder) {
+       if (connector->encoder && connector->base.state->crtc) {
                enum pipe pipe;
                if (!connector->encoder->get_hw_state(connector->encoder, &pipe))
                        return false;
index bc674aac59cb3ce5fc4621d7b1fdb8e3c7990b01,354432fdfcf087559cc084bf09be3cd71d4df420..c96289dba380328a01bfb1d9d6b58302891488a1
@@@ -142,7 -142,6 +142,7 @@@ struct intel_encoder 
        void (*mode_set)(struct intel_encoder *intel_encoder);
        void (*disable)(struct intel_encoder *);
        void (*post_disable)(struct intel_encoder *);
 +      void (*post_pll_disable)(struct intel_encoder *);
        /* Read out the current hw state of this connector, returning true if
         * the encoder is active. If the encoder is enabled it also set the pipe
         * it is connected to in the pipe parameter. */
@@@ -338,8 -337,6 +338,8 @@@ struct intel_crtc_state 
  #define PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS     (1<<0) /* unreliable sync mode.flags */
        unsigned long quirks;
  
 +      bool update_pipe;
 +
        /* Pipe source size (ie. panel fitter input size)
         * All planes will be positioned inside this space,
         * and get clipped at the edges. */
        /* Used by SDVO (and if we ever fix it, HDMI). */
        unsigned pixel_multiplier;
  
 +      uint8_t lane_count;
 +
        /* Panel fitter controls for gen2-gen4 + VLV */
        struct {
                u32 control;
@@@ -537,8 -532,6 +537,8 @@@ struct intel_crtc 
         * gen4+ this only adjusts up to a tile, offsets within a tile are
         * handled in the hw itself (with the TILEOFF register). */
        unsigned long dspaddr_offset;
 +      int adjusted_x;
 +      int adjusted_y;
  
        struct drm_i915_gem_object *cursor_bo;
        uint32_t cursor_addr;
  
        int scanline_offset;
  
 -      unsigned start_vbl_count;
 +      struct {
 +              unsigned start_vbl_count;
 +              ktime_t start_vbl_time;
 +              int min_vbl, max_vbl;
 +              int scanline_start;
 +      } debug;
 +
        struct intel_crtc_atomic_commit atomic;
  
        /* scalers available on this crtc */
@@@ -670,14 -657,13 +670,14 @@@ struct cxsr_latency 
  struct intel_hdmi {
        u32 hdmi_reg;
        int ddc_bus;
 -      uint32_t color_range;
 +      bool limited_color_range;
        bool color_range_auto;
        bool has_hdmi_sink;
        bool has_audio;
        enum hdmi_force_audio force_audio;
        bool rgb_quant_range_selectable;
        enum hdmi_picture_aspect aspect_ratio;
 +      struct intel_connector *attached_connector;
        void (*write_infoframe)(struct drm_encoder *encoder,
                                enum hdmi_infoframe_type type,
                                const void *frame, ssize_t len);
@@@ -710,29 -696,23 +710,29 @@@ enum link_m_n_set 
        M2_N2
  };
  
 +struct sink_crc {
 +      bool started;
 +      u8 last_crc[6];
 +      int last_count;
 +};
 +
  struct intel_dp {
        uint32_t output_reg;
        uint32_t aux_ch_ctl_reg;
        uint32_t DP;
 +      int link_rate;
 +      uint8_t lane_count;
        bool has_audio;
        enum hdmi_force_audio force_audio;
 -      uint32_t color_range;
 +      bool limited_color_range;
        bool color_range_auto;
 -      uint8_t link_bw;
 -      uint8_t rate_select;
 -      uint8_t lane_count;
        uint8_t dpcd[DP_RECEIVER_CAP_SIZE];
        uint8_t psr_dpcd[EDP_PSR_RECEIVER_CAP_SIZE];
        uint8_t downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
        /* sink rates as reported by DP_SUPPORTED_LINK_RATES */
        uint8_t num_sink_rates;
        int sink_rates[DP_MAX_SUPPORTED_RATES];
 +      struct sink_crc sink_crc;
        struct drm_dp_aux aux;
        uint8_t train_set[4];
        int panel_power_up_delay;
        enum pipe pps_pipe;
        struct edp_power_seq pps_delays;
  
 -      bool use_tps3;
        bool can_mst; /* this port supports mst */
        bool is_mst;
        int active_mst_links;
@@@ -789,7 -770,6 +789,7 @@@ struct intel_digital_port 
        struct intel_dp dp;
        struct intel_hdmi hdmi;
        enum irqreturn (*hpd_pulse)(struct intel_digital_port *, bool);
 +      bool release_cl2_override;
  };
  
  struct intel_dp_mst_encoder {
        void *port; /* store this opaque as its illegal to dereference it */
  };
  
 -static inline int
 +static inline enum dpio_channel
  vlv_dport_to_channel(struct intel_digital_port *dport)
  {
        switch (dport->port) {
        }
  }
  
 -static inline int
 +static inline enum dpio_phy
 +vlv_dport_to_phy(struct intel_digital_port *dport)
 +{
 +      switch (dport->port) {
 +      case PORT_B:
 +      case PORT_C:
 +              return DPIO_PHY0;
 +      case PORT_D:
 +              return DPIO_PHY1;
 +      default:
 +              BUG();
 +      }
 +}
 +
 +static inline enum dpio_channel
  vlv_pipe_to_channel(enum pipe pipe)
  {
        switch (pipe) {
@@@ -868,8 -834,8 +868,8 @@@ struct intel_unpin_work 
        u32 flip_count;
        u32 gtt_offset;
        struct drm_i915_gem_request *flip_queued_req;
-       int flip_queued_vblank;
-       int flip_ready_vblank;
+       u32 flip_queued_vblank;
+       u32 flip_ready_vblank;
        bool enable_stall_check;
  };
  
@@@ -1021,7 -987,6 +1021,7 @@@ void i915_audio_component_cleanup(struc
  extern const struct drm_plane_funcs intel_plane_funcs;
  bool intel_has_pending_fb_unpin(struct drm_device *dev);
  int intel_pch_rawclk(struct drm_device *dev);
 +int intel_hrawclk(struct drm_device *dev);
  void intel_mark_busy(struct drm_device *dev);
  void intel_mark_idle(struct drm_device *dev);
  void intel_crtc_restore_mode(struct drm_crtc *crtc);
@@@ -1030,6 -995,8 +1030,6 @@@ void intel_encoder_destroy(struct drm_e
  int intel_connector_init(struct intel_connector *);
  struct intel_connector *intel_connector_alloc(void);
  bool intel_connector_get_hw_state(struct intel_connector *connector);
 -bool ibx_digital_port_connected(struct drm_i915_private *dev_priv,
 -                              struct intel_digital_port *port);
  void intel_connector_attach_encoder(struct intel_connector *connector,
                                    struct intel_encoder *encoder);
  struct drm_encoder *intel_best_encoder(struct drm_connector *connector);
@@@ -1071,10 -1038,8 +1071,8 @@@ void intel_finish_page_flip(struct drm_
  void intel_finish_page_flip_plane(struct drm_device *dev, int plane);
  void intel_check_page_flip(struct drm_device *dev, int pipe);
  int intel_prepare_plane_fb(struct drm_plane *plane,
-                          struct drm_framebuffer *fb,
                           const struct drm_plane_state *new_state);
  void intel_cleanup_plane_fb(struct drm_plane *plane,
-                           struct drm_framebuffer *fb,
                            const struct drm_plane_state *old_state);
  int intel_plane_atomic_get_property(struct drm_plane *plane,
                                    const struct drm_plane_state *state,
@@@ -1089,7 -1054,7 +1087,7 @@@ int intel_plane_atomic_calc_changes(str
  
  unsigned int
  intel_tile_height(struct drm_device *dev, uint32_t pixel_format,
 -                uint64_t fb_format_modifier);
 +                uint64_t fb_format_modifier, unsigned int plane);
  
  static inline bool
  intel_rotation_90_or_270(unsigned int rotation)
@@@ -1170,9 -1135,7 +1168,9 @@@ int skl_update_scaler_crtc(struct intel
  int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state);
  
  unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
 -                                   struct drm_i915_gem_object *obj);
 +                                   struct drm_i915_gem_object *obj,
 +                                   unsigned int plane);
 +
  u32 skl_plane_ctl_format(uint32_t pixel_format);
  u32 skl_plane_ctl_tiling(uint64_t fb_modifier);
  u32 skl_plane_ctl_rotation(unsigned int rotation);
@@@ -1190,8 -1153,6 +1188,8 @@@ void assert_csr_loaded(struct drm_i915_
  void intel_dp_init(struct drm_device *dev, int output_reg, enum port port);
  bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
                             struct intel_connector *intel_connector);
 +void intel_dp_set_link_params(struct intel_dp *intel_dp,
 +                            const struct intel_crtc_state *pipe_config);
  void intel_dp_start_link_train(struct intel_dp *intel_dp);
  void intel_dp_complete_link_train(struct intel_dp *intel_dp);
  void intel_dp_stop_link_train(struct intel_dp *intel_dp);
@@@ -1222,8 -1183,6 +1220,8 @@@ void intel_edp_drrs_disable(struct inte
  void intel_edp_drrs_invalidate(struct drm_device *dev,
                unsigned frontbuffer_bits);
  void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits);
 +bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
 +                                       struct intel_digital_port *port);
  void hsw_dp_set_ddi_pll_sel(struct intel_crtc_state *pipe_config);
  
  /* intel_dp_mst.c */
@@@ -1378,12 -1337,6 +1376,12 @@@ void intel_runtime_pm_put(struct drm_i9
  
  void intel_display_set_init_power(struct drm_i915_private *dev, bool enable);
  
 +void chv_phy_powergate_lanes(struct intel_encoder *encoder,
 +                           bool override, unsigned int mask);
 +bool chv_phy_powergate_ch(struct drm_i915_private *dev_priv, enum dpio_phy phy,
 +                        enum dpio_channel ch, bool override);
 +
 +
  /* intel_pm.c */
  void intel_init_clock_gating(struct drm_device *dev);
  void intel_suspend_hw(struct drm_device *dev);
@@@ -1429,8 -1382,9 +1427,8 @@@ bool intel_sdvo_init(struct drm_device 
  int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane);
  int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
                              struct drm_file *file_priv);
 -void intel_pipe_update_start(struct intel_crtc *crtc,
 -                           uint32_t *start_vbl_count);
 -void intel_pipe_update_end(struct intel_crtc *crtc, u32 start_vbl_count);
 +void intel_pipe_update_start(struct intel_crtc *crtc);
 +void intel_pipe_update_end(struct intel_crtc *crtc);
  
  /* intel_tv.c */
  void intel_tv_init(struct drm_device *dev);
index 5b69b412628233175fa14f976cf7b021e164d5de,32a6c7184ca4fcbcc73786e678f634a22453224d..61d69c214508e68fe61a349d3bd4a60c132bffb7
@@@ -557,7 -557,7 +557,7 @@@ static void intel_dsi_clear_device_read
                usleep_range(2000, 2500);
        }
  
 -      vlv_disable_dsi_pll(encoder);
 +      intel_disable_dsi_pll(encoder);
  }
  
  static void intel_dsi_post_disable(struct intel_encoder *encoder)
@@@ -654,7 -654,6 +654,7 @@@ intel_dsi_mode_valid(struct drm_connect
  {
        struct intel_connector *intel_connector = to_intel_connector(connector);
        struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
 +      int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
  
        DRM_DEBUG_KMS("\n");
  
                        return MODE_PANEL;
                if (mode->vdisplay > fixed_mode->vdisplay)
                        return MODE_PANEL;
 +              if (fixed_mode->clock > max_dotclk)
 +                      return MODE_CLOCK_HIGH;
        }
  
        return MODE_OK;
@@@ -737,21 -734,6 +737,21 @@@ static void set_dsi_timings(struct drm_
        hbp = txbyteclkhs(hbp, bpp, lane_count, intel_dsi->burst_mode_ratio);
  
        for_each_dsi_port(port, intel_dsi->ports) {
 +              if (IS_BROXTON(dev)) {
 +                      /*
 +                       * Program hdisplay and vdisplay on MIPI transcoder.
 +                       * This is different from calculated hactive and
 +                       * vactive, as they are calculated per channel basis,
 +                       * whereas these values should be based on resolution.
 +                       */
 +                      I915_WRITE(BXT_MIPI_TRANS_HACTIVE(port),
 +                                      mode->hdisplay);
 +                      I915_WRITE(BXT_MIPI_TRANS_VACTIVE(port),
 +                                      mode->vdisplay);
 +                      I915_WRITE(BXT_MIPI_TRANS_VTOTAL(port),
 +                                      mode->vtotal);
 +              }
 +
                I915_WRITE(MIPI_HACTIVE_AREA_COUNT(port), hactive);
                I915_WRITE(MIPI_HFP_COUNT(port), hfp);
  
@@@ -792,39 -774,16 +792,39 @@@ static void intel_dsi_prepare(struct in
        }
  
        for_each_dsi_port(port, intel_dsi->ports) {
 -              /* escape clock divider, 20MHz, shared for A and C.
 -               * device ready must be off when doing this! txclkesc? */
 -              tmp = I915_READ(MIPI_CTRL(PORT_A));
 -              tmp &= ~ESCAPE_CLOCK_DIVIDER_MASK;
 -              I915_WRITE(MIPI_CTRL(PORT_A), tmp | ESCAPE_CLOCK_DIVIDER_1);
 -
 -              /* read request priority is per pipe */
 -              tmp = I915_READ(MIPI_CTRL(port));
 -              tmp &= ~READ_REQUEST_PRIORITY_MASK;
 -              I915_WRITE(MIPI_CTRL(port), tmp | READ_REQUEST_PRIORITY_HIGH);
 +              if (IS_VALLEYVIEW(dev)) {
 +                      /*
 +                       * escape clock divider, 20MHz, shared for A and C.
 +                       * device ready must be off when doing this! txclkesc?
 +                       */
 +                      tmp = I915_READ(MIPI_CTRL(PORT_A));
 +                      tmp &= ~ESCAPE_CLOCK_DIVIDER_MASK;
 +                      I915_WRITE(MIPI_CTRL(PORT_A), tmp |
 +                                      ESCAPE_CLOCK_DIVIDER_1);
 +
 +                      /* read request priority is per pipe */
 +                      tmp = I915_READ(MIPI_CTRL(port));
 +                      tmp &= ~READ_REQUEST_PRIORITY_MASK;
 +                      I915_WRITE(MIPI_CTRL(port), tmp |
 +                                      READ_REQUEST_PRIORITY_HIGH);
 +              } else if (IS_BROXTON(dev)) {
 +                      /*
 +                       * FIXME:
 +                       * BXT can connect any PIPE to any MIPI port.
 +                       * Select the pipe based on the MIPI port read from
 +                       * VBT for now. Pick PIPE A for MIPI port A and C
 +                       * for port C.
 +                       */
 +                      tmp = I915_READ(MIPI_CTRL(port));
 +                      tmp &= ~BXT_PIPE_SELECT_MASK;
 +
 +                      if (port == PORT_A)
 +                              tmp |= BXT_PIPE_SELECT_A;
 +                      else if (port == PORT_C)
 +                              tmp |= BXT_PIPE_SELECT_C;
 +
 +                      I915_WRITE(MIPI_CTRL(port), tmp);
 +              }
  
                /* XXX: why here, why like this? handling in irq handler?! */
                I915_WRITE(MIPI_INTR_STAT(port), 0xffffffff);
                I915_WRITE(MIPI_INIT_COUNT(port),
                                txclkesc(intel_dsi->escape_clk_div, 100));
  
 +              if (IS_BROXTON(dev) && (!intel_dsi->dual_link)) {
 +                      /*
 +                       * BXT spec says write MIPI_INIT_COUNT for
 +                       * both the ports, even if only one is
 +                       * getting used. So write the other port
 +                       * if not in dual link mode.
 +                       */
 +                      I915_WRITE(MIPI_INIT_COUNT(port ==
 +                                              PORT_A ? PORT_C : PORT_A),
 +                                      intel_dsi->init_count);
 +              }
  
                /* recovery disables */
                I915_WRITE(MIPI_EOT_DISABLE(port), tmp);
@@@ -963,8 -911,8 +963,8 @@@ static void intel_dsi_pre_pll_enable(st
        DRM_DEBUG_KMS("\n");
  
        intel_dsi_prepare(encoder);
 +      intel_enable_dsi_pll(encoder);
  
 -      vlv_enable_dsi_pll(encoder);
  }
  
  static enum drm_connector_status
@@@ -1100,11 -1048,7 +1100,7 @@@ void intel_dsi_init(struct drm_device *
        intel_connector->unregister = intel_connector_unregister;
  
        /* Pipe A maps to MIPI DSI port A, pipe B maps to MIPI DSI port C */
-       if (dev_priv->vbt.dsi.config->dual_link) {
-               /* XXX: does dual link work on either pipe? */
-               intel_encoder->crtc_mask = (1 << PIPE_A);
-               intel_dsi->ports = ((1 << PORT_A) | (1 << PORT_C));
-       } else if (dev_priv->vbt.dsi.port == DVO_PORT_MIPIA) {
+       if (dev_priv->vbt.dsi.port == DVO_PORT_MIPIA) {
                intel_encoder->crtc_mask = (1 << PIPE_A);
                intel_dsi->ports = (1 << PORT_A);
        } else if (dev_priv->vbt.dsi.port == DVO_PORT_MIPIC) {
                intel_dsi->ports = (1 << PORT_C);
        }
  
+       if (dev_priv->vbt.dsi.config->dual_link)
+               intel_dsi->ports = ((1 << PORT_A) | (1 << PORT_C));
        /* Create a DSI host (and a device) for each port. */
        for_each_dsi_port(port, intel_dsi->ports) {
                struct intel_dsi_host *host;
index 73a14e86a127578b2861425010b059cb6a6175de,ab2b856d91c3f4209425df0439d72b8ecc72000e..65329127f0b9a2eed2ff29178c4fbd2265840aa5
@@@ -263,7 -263,7 +263,7 @@@ static int intelfb_create(struct drm_fb
  
        /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
  
 -      DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08lx, bo %p\n",
 +      DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08llx, bo %p\n",
                      fb->width, fb->height,
                      i915_gem_obj_ggtt_offset(obj), obj);
  
@@@ -541,13 -541,16 +541,13 @@@ static bool intel_fbdev_init_bios(struc
        struct intel_crtc *intel_crtc;
        unsigned int max_size = 0;
  
 -      if (!i915.fastboot)
 -              return false;
 -
        /* Find the largest fb */
        for_each_crtc(dev, crtc) {
                struct drm_i915_gem_object *obj =
                        intel_fb_obj(crtc->primary->state->fb);
                intel_crtc = to_intel_crtc(crtc);
  
 -              if (!intel_crtc->active || !obj) {
 +              if (!crtc->state->active || !obj) {
                        DRM_DEBUG_KMS("pipe %c not active or no fb, skipping\n",
                                      pipe_name(intel_crtc->pipe));
                        continue;
  
                intel_crtc = to_intel_crtc(crtc);
  
 -              if (!intel_crtc->active) {
 +              if (!crtc->state->active) {
                        DRM_DEBUG_KMS("pipe %c not active, skipping\n",
                                      pipe_name(intel_crtc->pipe));
                        continue;
        for_each_crtc(dev, crtc) {
                intel_crtc = to_intel_crtc(crtc);
  
 -              if (!intel_crtc->active)
 +              if (!crtc->state->active)
                        continue;
  
                WARN(!crtc->primary->fb,
@@@ -686,6 -689,8 +686,8 @@@ int intel_fbdev_init(struct drm_device 
                return ret;
        }
  
+       ifbdev->helper.atomic = true;
        dev_priv->fbdev = ifbdev;
        INIT_WORK(&dev_priv->fbdev_suspend_work, intel_fbdev_suspend_worker);
  
index 68700692127dee10e487d000e362245df5f79e72,ddbb7ed0a193229355700926006578ca5f06b937..ab5ac5ee18257d8b05ee175dfd474e39fb61731c
@@@ -116,30 -116,18 +116,30 @@@ static void bxt_init_clock_gating(struc
  
        gen9_init_clock_gating(dev);
  
 +      /* WaDisableSDEUnitClockGating:bxt */
 +      I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
 +                 GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
 +
        /*
         * FIXME:
 -       * GEN8_SDEUNIT_CLOCK_GATE_DISABLE applies on A0 only.
         * GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ applies on 3x6 GT SKUs only.
         */
 -       /* WaDisableSDEUnitClockGating:bxt */
        I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
 -                 GEN8_SDEUNIT_CLOCK_GATE_DISABLE |
                   GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ);
  
 -      /* FIXME: apply on A0 only */
 -      I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_TLBPF);
 +      if (INTEL_REVID(dev) == BXT_REVID_A0) {
 +              /*
 +               * Hardware specification requires this bit to be
 +               * set to 1 for A0
 +               */
 +              I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_TLBPF);
 +      }
 +
 +      /* WaSetClckGatingDisableMedia:bxt */
 +      if (INTEL_REVID(dev) == BXT_REVID_A0) {
 +              I915_WRITE(GEN7_MISCCPCTL, (I915_READ(GEN7_MISCCPCTL) &
 +                                          ~GEN8_DOP_CLOCK_GATE_MEDIA_ENABLE));
 +      }
  }
  
  static void i915_pineview_get_mem_freq(struct drm_device *dev)
@@@ -967,8 -955,6 +967,6 @@@ enum vlv_wm_level 
        VLV_WM_LEVEL_PM2,
        VLV_WM_LEVEL_PM5,
        VLV_WM_LEVEL_DDR_DVFS,
-       CHV_WM_NUM_LEVELS,
-       VLV_WM_NUM_LEVELS = 1,
  };
  
  /* latency must be in 0.1us units. */
@@@ -994,9 -980,13 +992,13 @@@ static void vlv_setup_wm_latency(struc
        /* all latencies in usec */
        dev_priv->wm.pri_latency[VLV_WM_LEVEL_PM2] = 3;
  
+       dev_priv->wm.max_level = VLV_WM_LEVEL_PM2;
        if (IS_CHERRYVIEW(dev_priv)) {
                dev_priv->wm.pri_latency[VLV_WM_LEVEL_PM5] = 12;
                dev_priv->wm.pri_latency[VLV_WM_LEVEL_DDR_DVFS] = 33;
+               dev_priv->wm.max_level = VLV_WM_LEVEL_DDR_DVFS;
        }
  }
  
@@@ -1149,10 -1139,7 +1151,7 @@@ static void vlv_compute_wm(struct intel
        memset(wm_state, 0, sizeof(*wm_state));
  
        wm_state->cxsr = crtc->pipe != PIPE_C && crtc->wm.cxsr_allowed;
-       if (IS_CHERRYVIEW(dev))
-               wm_state->num_levels = CHV_WM_NUM_LEVELS;
-       else
-               wm_state->num_levels = VLV_WM_NUM_LEVELS;
+       wm_state->num_levels = to_i915(dev)->wm.max_level + 1;
  
        wm_state->num_active_planes = 0;
  
        }
  
        /* clear any (partially) filled invalid levels */
-       for (level = wm_state->num_levels; level < CHV_WM_NUM_LEVELS; level++) {
+       for (level = wm_state->num_levels; level < to_i915(dev)->wm.max_level + 1; level++) {
                memset(&wm_state->wm[level], 0, sizeof(wm_state->wm[level]));
                memset(&wm_state->sr[level], 0, sizeof(wm_state->sr[level]));
        }
@@@ -1336,10 -1323,7 +1335,7 @@@ static void vlv_merge_wm(struct drm_dev
        struct intel_crtc *crtc;
        int num_active_crtcs = 0;
  
-       if (IS_CHERRYVIEW(dev))
-               wm->level = VLV_WM_LEVEL_DDR_DVFS;
-       else
-               wm->level = VLV_WM_LEVEL_PM2;
+       wm->level = to_i915(dev)->wm.max_level;
        wm->cxsr = true;
  
        for_each_intel_crtc(dev, crtc) {
@@@ -3182,8 -3166,7 +3178,8 @@@ static void skl_compute_wm_pipe_paramet
                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) : fb->bits_per_pixel / 8;
 +                              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];
@@@ -3689,26 -3672,6 +3685,26 @@@ static void skl_update_other_pipe_wm(st
        }
  }
  
 +static void skl_clear_wm(struct skl_wm_values *watermarks, enum pipe pipe)
 +{
 +      watermarks->wm_linetime[pipe] = 0;
 +      memset(watermarks->plane[pipe], 0,
 +             sizeof(uint32_t) * 8 * I915_MAX_PLANES);
 +      memset(watermarks->cursor[pipe], 0, sizeof(uint32_t) * 8);
 +      memset(watermarks->plane_trans[pipe],
 +             0, sizeof(uint32_t) * I915_MAX_PLANES);
 +      watermarks->cursor_trans[pipe] = 0;
 +
 +      /* Clear ddb entries for pipe */
 +      memset(&watermarks->ddb.pipe[pipe], 0, sizeof(struct skl_ddb_entry));
 +      memset(&watermarks->ddb.plane[pipe], 0,
 +             sizeof(struct skl_ddb_entry) * I915_MAX_PLANES);
 +      memset(&watermarks->ddb.y_plane[pipe], 0,
 +             sizeof(struct skl_ddb_entry) * I915_MAX_PLANES);
 +      memset(&watermarks->ddb.cursor[pipe], 0, sizeof(struct skl_ddb_entry));
 +
 +}
 +
  static void skl_update_wm(struct drm_crtc *crtc)
  {
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        struct skl_pipe_wm pipe_wm = {};
        struct intel_wm_config config = {};
  
 -      memset(results, 0, sizeof(*results));
 +
 +      /* Clear all dirty flags */
 +      memset(results->dirty, 0, sizeof(bool) * I915_MAX_PIPES);
 +
 +      skl_clear_wm(results, intel_crtc->pipe);
  
        skl_compute_wm_global_parameters(dev, &config);
  
@@@ -4120,9 -4079,29 +4116,29 @@@ void vlv_wm_get_hw_state(struct drm_dev
                if (val & DSP_MAXFIFO_PM5_ENABLE)
                        wm->level = VLV_WM_LEVEL_PM5;
  
+               /*
+                * If DDR DVFS is disabled in the BIOS, Punit
+                * will never ack the request. So if that happens
+                * assume we don't have to enable/disable DDR DVFS
+                * dynamically. To test that just set the REQ_ACK
+                * bit to poke the Punit, but don't change the
+                * HIGH/LOW bits so that we don't actually change
+                * the current state.
+                */
                val = vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2);
-               if ((val & FORCE_DDR_HIGH_FREQ) == 0)
-                       wm->level = VLV_WM_LEVEL_DDR_DVFS;
+               val |= FORCE_DDR_FREQ_REQ_ACK;
+               vlv_punit_write(dev_priv, PUNIT_REG_DDR_SETUP2, val);
+               if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2) &
+                             FORCE_DDR_FREQ_REQ_ACK) == 0, 3)) {
+                       DRM_DEBUG_KMS("Punit not acking DDR DVFS request, "
+                                     "assuming DDR DVFS is disabled\n");
+                       dev_priv->wm.max_level = VLV_WM_LEVEL_PM5;
+               } else {
+                       val = vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2);
+                       if ((val & FORCE_DDR_HIGH_FREQ) == 0)
+                               wm->level = VLV_WM_LEVEL_DDR_DVFS;
+               }
  
                mutex_unlock(&dev_priv->rps.hw_lock);
        }
@@@ -4282,7 -4261,7 +4298,7 @@@ static void ironlake_enable_drps(struc
        fstart = (rgvmodectl & MEMMODE_FSTART_MASK) >>
                MEMMODE_FSTART_SHIFT;
  
 -      vstart = (I915_READ(PXVFREQ_BASE + (fstart * 4)) & PXVFREQ_PX_MASK) >>
 +      vstart = (I915_READ(PXVFREQ(fstart)) & PXVFREQ_PX_MASK) >>
                PXVFREQ_PX_SHIFT;
  
        dev_priv->ips.fmax = fmax; /* IPS callback will increase this */
  
        ironlake_set_drps(dev, fstart);
  
 -      dev_priv->ips.last_count1 = I915_READ(0x112e4) + I915_READ(0x112e8) +
 -              I915_READ(0x112e0);
 +      dev_priv->ips.last_count1 = I915_READ(DMIEC) +
 +              I915_READ(DDREC) + I915_READ(CSIEC);
        dev_priv->ips.last_time1 = jiffies_to_msecs(jiffies);
 -      dev_priv->ips.last_count2 = I915_READ(0x112f4);
 +      dev_priv->ips.last_count2 = I915_READ(GFXEC);
        dev_priv->ips.last_time2 = ktime_get_raw_ns();
  
        spin_unlock_irq(&mchdev_lock);
@@@ -4487,10 -4466,6 +4503,10 @@@ 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))
 +              return;
 +
        WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
        WARN_ON(val > dev_priv->rps.max_freq);
        WARN_ON(val < dev_priv->rps.min_freq);
@@@ -4811,12 -4786,6 +4827,12 @@@ 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)) {
 +              intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 +              return;
 +      }
 +
        /* Program defaults and thresholds for RPS*/
        I915_WRITE(GEN6_RC_VIDEO_FREQ,
                GEN9_FREQUENCY(dev_priv->rps.rp1_freq));
@@@ -4854,21 -4823,11 +4870,21 @@@ static void gen9_enable_rc6(struct drm_
        I915_WRITE(GEN6_RC_CONTROL, 0);
  
        /* 2b: Program RC6 thresholds.*/
 -      I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16);
 +
 +      /* WaRsDoubleRc6WrlWithCoarsePowerGating: Doubling WRL only when CPG is enabled */
 +      if (IS_SKYLAKE(dev) && !((IS_SKL_GT3(dev) || IS_SKL_GT4(dev)) &&
 +                               (INTEL_REVID(dev) <= SKL_REVID_E0)))
 +              I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 108 << 16);
 +      else
 +              I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16);
        I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
        I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
        for_each_ring(ring, dev_priv, unused)
                I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10);
 +
 +      if (HAS_GUC_UCODE(dev))
 +              I915_WRITE(GUC_MAX_IDLE_COUNT, 0xA);
 +
        I915_WRITE(GEN6_RC_SLEEP, 0);
        I915_WRITE(GEN6_RC6_THRESHOLD, 37500); /* 37.5/125ms per EI */
  
                rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
        DRM_INFO("RC6 %s\n", (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ?
                        "on" : "off");
 -      I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
 -                                 GEN6_RC_CTL_EI_MODE(1) |
 -                                 rc6_mask);
 +
 +      if ((IS_SKYLAKE(dev) && INTEL_REVID(dev) <= SKL_REVID_D0) ||
 +          (IS_BROXTON(dev) && INTEL_REVID(dev) <= BXT_REVID_A0))
 +              I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
 +                         GEN7_RC_CTL_TO_MODE |
 +                         rc6_mask);
 +      else
 +              I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
 +                         GEN6_RC_CTL_EI_MODE(1) |
 +                         rc6_mask);
  
        /*
         * 3b: Enable Coarse Power Gating only when RC6 is enabled.
 -       * WaDisableRenderPowerGating:skl,bxt - Render PG need to be disabled with RC6.
 +       * WaRsDisableCoarsePowerGating:skl,bxt - Render/Media PG need to be disabled with RC6.
         */
 -      I915_WRITE(GEN9_PG_ENABLE, (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ?
 -                      GEN9_MEDIA_PG_ENABLE : 0);
 -
 +      if ((IS_BROXTON(dev) && (INTEL_REVID(dev) < BXT_REVID_B0)) ||
 +          ((IS_SKL_GT3(dev) || IS_SKL_GT4(dev)) && (INTEL_REVID(dev) <= SKL_REVID_E0)))
 +              I915_WRITE(GEN9_PG_ENABLE, 0);
 +      else
 +              I915_WRITE(GEN9_PG_ENABLE, (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ?
 +                              (GEN9_RENDER_PG_ENABLE | GEN9_MEDIA_PG_ENABLE) : 0);
  
        intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
  
@@@ -5616,7 -5565,7 +5632,7 @@@ static void cherryview_enable_rps(struc
        /* RPS code assumes GPLL is used */
        WARN_ONCE((val & GPLLENABLE) == 0, "GPLL not enabled\n");
  
 -      DRM_DEBUG_DRIVER("GPLL enabled? %s\n", val & GPLLENABLE ? "yes" : "no");
 +      DRM_DEBUG_DRIVER("GPLL enabled? %s\n", yesno(val & GPLLENABLE));
        DRM_DEBUG_DRIVER("GPU status: 0x%08x\n", val);
  
        dev_priv->rps.cur_freq = (val >> 8) & 0xff;
@@@ -5706,7 -5655,7 +5722,7 @@@ static void valleyview_enable_rps(struc
        /* RPS code assumes GPLL is used */
        WARN_ONCE((val & GPLLENABLE) == 0, "GPLL not enabled\n");
  
 -      DRM_DEBUG_DRIVER("GPLL enabled? %s\n", val & GPLLENABLE ? "yes" : "no");
 +      DRM_DEBUG_DRIVER("GPLL enabled? %s\n", yesno(val & GPLLENABLE));
        DRM_DEBUG_DRIVER("GPU status: 0x%08x\n", val);
  
        dev_priv->rps.cur_freq = (val >> 8) & 0xff;
@@@ -5915,7 -5864,7 +5931,7 @@@ static unsigned long __i915_gfx_val(str
  
        assert_spin_locked(&mchdev_lock);
  
 -      pxvid = I915_READ(PXVFREQ_BASE + (dev_priv->rps.cur_freq * 4));
 +      pxvid = I915_READ(PXVFREQ(dev_priv->rps.cur_freq));
        pxvid = (pxvid >> 24) & 0x7f;
        ext_v = pvid_to_extvid(dev_priv, pxvid);
  
@@@ -6158,13 -6107,13 +6174,13 @@@ static void intel_init_emon(struct drm_
        I915_WRITE(CSIEW2, 0x04000004);
  
        for (i = 0; i < 5; i++)
 -              I915_WRITE(PEW + (i * 4), 0);
 +              I915_WRITE(PEW(i), 0);
        for (i = 0; i < 3; i++)
 -              I915_WRITE(DEW + (i * 4), 0);
 +              I915_WRITE(DEW(i), 0);
  
        /* Program P-state weights to account for frequency power adjustment */
        for (i = 0; i < 16; i++) {
 -              u32 pxvidfreq = I915_READ(PXVFREQ_BASE + (i * 4));
 +              u32 pxvidfreq = I915_READ(PXVFREQ(i));
                unsigned long freq = intel_pxfreq(pxvidfreq);
                unsigned long vid = (pxvidfreq & PXVFREQ_PX_MASK) >>
                        PXVFREQ_PX_SHIFT;
        for (i = 0; i < 4; i++) {
                u32 val = (pxw[i*4] << 24) | (pxw[(i*4)+1] << 16) |
                        (pxw[(i*4)+2] << 8) | (pxw[(i*4)+3]);
 -              I915_WRITE(PXW + (i * 4), val);
 +              I915_WRITE(PXW(i), val);
        }
  
        /* Adjust magic regs to magic values (more experimental results) */
        I915_WRITE(EG7, 0);
  
        for (i = 0; i < 8; i++)
 -              I915_WRITE(PXWL + (i * 4), 0);
 +              I915_WRITE(PXWL(i), 0);
  
        /* Enable PMON + select events */
        I915_WRITE(ECR, 0x80000019);
@@@ -6655,7 -6604,7 +6671,7 @@@ static void lpt_init_clock_gating(struc
         * TODO: this bit should only be enabled when really needed, then
         * disabled when not needed anymore in order to save power.
         */
 -      if (dev_priv->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE)
 +      if (HAS_PCH_LPT_LP(dev))
                I915_WRITE(SOUTH_DSPCLK_GATE_D,
                           I915_READ(SOUTH_DSPCLK_GATE_D) |
                           PCH_LP_PARTITION_LEVEL_DISABLE);
@@@ -6670,7 -6619,7 +6686,7 @@@ static void lpt_suspend_hw(struct drm_d
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
  
 -      if (dev_priv->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) {
 +      if (HAS_PCH_LPT_LP(dev)) {
                uint32_t val = I915_READ(SOUTH_DSPCLK_GATE_D);
  
                val &= ~PCH_LP_PARTITION_LEVEL_DISABLE;
index c69e1af37ca8cf8f7a50cb9f1530c5bf67b50053,590ceabe2d5e320f66942dcd466f04e18c7b146b..6bea78944cd680056c0c9006937e4b4d1f61e4f8
@@@ -1138,13 -1138,13 +1138,13 @@@ static void intel_tv_pre_enable(struct 
  
        j = 0;
        for (i = 0; i < 60; i++)
 -              I915_WRITE(TV_H_LUMA_0 + (i<<2), tv_mode->filter_table[j++]);
 +              I915_WRITE(TV_H_LUMA(i), tv_mode->filter_table[j++]);
        for (i = 0; i < 60; i++)
 -              I915_WRITE(TV_H_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]);
 +              I915_WRITE(TV_H_CHROMA(i), tv_mode->filter_table[j++]);
        for (i = 0; i < 43; i++)
 -              I915_WRITE(TV_V_LUMA_0 + (i<<2), tv_mode->filter_table[j++]);
 +              I915_WRITE(TV_V_LUMA(i), tv_mode->filter_table[j++]);
        for (i = 0; i < 43; i++)
 -              I915_WRITE(TV_V_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]);
 +              I915_WRITE(TV_V_CHROMA(i), tv_mode->filter_table[j++]);
        I915_WRITE(TV_DAC, I915_READ(TV_DAC) & TV_DAC_SAVE);
        I915_WRITE(TV_CTL, tv_ctl);
  }
@@@ -1291,7 -1291,7 +1291,7 @@@ static void intel_tv_find_better_format
                return;
  
  
 -      for (i = 0; i < sizeof(tv_modes) / sizeof(*tv_modes); i++) {
 +      for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
                tv_mode = tv_modes + i;
  
                if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) ==
@@@ -1579,7 -1579,7 +1579,7 @@@ intel_tv_init(struct drm_device *dev
        struct intel_encoder *intel_encoder;
        struct intel_connector *intel_connector;
        u32 tv_dac_on, tv_dac_off, save_tv_dac;
-       char *tv_format_names[ARRAY_SIZE(tv_modes)];
+       const char *tv_format_names[ARRAY_SIZE(tv_modes)];
        int i, initial_mode = 0;
  
        if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
  
        /* Create TV properties then attach current values */
        for (i = 0; i < ARRAY_SIZE(tv_modes); i++)
-               tv_format_names[i] = (char *)tv_modes[i].name;
+               tv_format_names[i] = tv_modes[i].name;
        drm_mode_create_tv_properties(dev,
                                      ARRAY_SIZE(tv_modes),
                                      tv_format_names);
index 8c52d0ef1fc909cc6fba4a3b8b08fa00eaec23f9,d0c88107996ade0a8b7eb776814ad483232a47a5..9ec4716df7b554bd44eb12ed614cb67569ff8004
@@@ -46,7 -46,7 +46,7 @@@
  
  #define DP_AUX_I2C_WRITE              0x0
  #define DP_AUX_I2C_READ                       0x1
- #define DP_AUX_I2C_STATUS             0x2
+ #define DP_AUX_I2C_WRITE_STATUS_UPDATE        0x2
  #define DP_AUX_I2C_MOT                        0x4
  #define DP_AUX_NATIVE_WRITE           0x8
  #define DP_AUX_NATIVE_READ            0x9
@@@ -634,13 -634,6 +634,13 @@@ drm_dp_enhanced_frame_cap(const u8 dpcd
                (dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP);
  }
  
 +static inline bool
 +drm_dp_tps3_supported(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
 +{
 +      return dpcd[DP_DPCD_REV] >= 0x12 &&
 +              dpcd[DP_MAX_LANE_COUNT] & DP_TPS3_SUPPORTED;
 +}
 +
  /*
   * DisplayPort AUX channel
   */