Merge tag 'v3.5-rc4' into drm-intel-next-queued
authorDaniel Vetter <daniel.vetter@ffwll.ch>
Mon, 25 Jun 2012 17:06:12 +0000 (19:06 +0200)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Mon, 25 Jun 2012 17:10:36 +0000 (19:10 +0200)
I want to merge the "no more fake agp on gen6+" patches into
drm-intel-next (well, the last pieces). But a patch in 3.5-rc4 also
adds a new use of dev->agp. Hence the backmarge to sort this out, for
otherwise drm-intel-next merged into Linus' tree would conflict in the
relevant code, things would compile but nicely OOPS at driver load :(

Conflicts in this merge are just simple cases of "both branches
changed/added lines at the same place". The only tricky part is to
keep the order correct wrt the unwind code in case of errors in
intel_ringbuffer.c (and the MI_DISPLAY_FLIP #defines in i915_reg.h
together, obviously).

Conflicts:
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_ringbuffer.c

Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
1  2 
drivers/char/agp/intel-agp.c
drivers/char/agp/intel-agp.h
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_ringbuffer.c

index c98c5689bb0beec7d666f72eecb376dd8dc94fe2,0a41852794177636f62c91010430d85891f1425b..92622d44e12d294ef8014050836f4af4d1f9f2f3
@@@ -12,7 -12,6 +12,7 @@@
  #include <asm/smp.h>
  #include "agp.h"
  #include "intel-agp.h"
 +#include <drm/intel-gtt.h>
  
  int intel_agp_enabled;
  EXPORT_SYMBOL(intel_agp_enabled);
@@@ -748,7 -747,7 +748,7 @@@ static int __devinit agp_intel_probe(st
  
        bridge->capndx = cap_ptr;
  
 -      if (intel_gmch_probe(pdev, bridge))
 +      if (intel_gmch_probe(pdev, NULL, bridge))
                goto found_gmch;
  
        for (i = 0; intel_agp_chipsets[i].name != NULL; i++) {
@@@ -825,7 -824,7 +825,7 @@@ static void __devexit agp_intel_remove(
  
        agp_remove_bridge(bridge);
  
 -      intel_gmch_remove(pdev);
 +      intel_gmch_remove();
  
        agp_put_bridge(bridge);
  }
@@@ -899,6 -898,7 +899,7 @@@ static struct pci_device_id agp_intel_p
        ID(PCI_DEVICE_ID_INTEL_B43_HB),
        ID(PCI_DEVICE_ID_INTEL_B43_1_HB),
        ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB),
+       ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D2_HB),
        ID(PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB),
        ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB),
        ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB),
index cf2e764b1760d27870d0e93c4363abe749b285c4,8e2d9140f300291ae506741d1c7bb4135b728599..57226424690cb1f05ebfa560f776aa8adf967c55
  #define PCI_DEVICE_ID_INTEL_G41_HB          0x2E30
  #define PCI_DEVICE_ID_INTEL_G41_IG          0x2E32
  #define PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB         0x0040
+ #define PCI_DEVICE_ID_INTEL_IRONLAKE_D2_HB        0x0069
  #define PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG         0x0042
  #define PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB         0x0044
  #define PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB        0x0062
  #define PCI_DEVICE_ID_INTEL_HASWELL_SDV               0x0c16 /* SDV */
  #define PCI_DEVICE_ID_INTEL_HASWELL_E_HB                      0x0c04
  
 -int intel_gmch_probe(struct pci_dev *pdev,
 -                             struct agp_bridge_data *bridge);
 -void intel_gmch_remove(struct pci_dev *pdev);
  #endif
index 05adbf23951a79416c9f97ef555fc1fb9530879a,9fe9ebe52a7ade8424472b4388b903afb5f681c0..a378c0800304fbafd6b925312d3914763ca2d177
@@@ -233,6 -233,7 +233,7 @@@ static const struct intel_device_info i
        .has_blt_ring = 1,
        .has_llc = 1,
        .has_pch_split = 1,
+       .has_force_wake = 1,
  };
  
  static const struct intel_device_info intel_sandybridge_m_info = {
        .has_blt_ring = 1,
        .has_llc = 1,
        .has_pch_split = 1,
+       .has_force_wake = 1,
  };
  
  static const struct intel_device_info intel_ivybridge_d_info = {
        .has_blt_ring = 1,
        .has_llc = 1,
        .has_pch_split = 1,
+       .has_force_wake = 1,
  };
  
  static const struct intel_device_info intel_ivybridge_m_info = {
        .has_blt_ring = 1,
        .has_llc = 1,
        .has_pch_split = 1,
+       .has_force_wake = 1,
  };
  
  static const struct intel_device_info intel_valleyview_m_info = {
@@@ -289,6 -293,7 +293,7 @@@ static const struct intel_device_info i
        .has_blt_ring = 1,
        .has_llc = 1,
        .has_pch_split = 1,
+       .has_force_wake = 1,
  };
  
  static const struct intel_device_info intel_haswell_m_info = {
        .has_blt_ring = 1,
        .has_llc = 1,
        .has_pch_split = 1,
+       .has_force_wake = 1,
  };
  
  static const struct pci_device_id pciidlist[] = {             /* aka */
        INTEL_VGA_DEVICE(0x0406, &intel_haswell_m_info), /* GT1 mobile */
        INTEL_VGA_DEVICE(0x0416, &intel_haswell_m_info), /* GT2 mobile */
        INTEL_VGA_DEVICE(0x0c16, &intel_haswell_d_info), /* SDV */
 +      INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info),
 +      INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info),
 +      INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info),
        {0, 0, 0}
  };
  
@@@ -802,7 -805,7 +808,7 @@@ static int gen6_do_reset(struct drm_dev
        return ret;
  }
  
 -static int intel_gpu_reset(struct drm_device *dev)
 +int intel_gpu_reset(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
        int ret = -ENODEV;
@@@ -863,6 -866,8 +869,6 @@@ int i915_reset(struct drm_device *dev
        if (!mutex_trylock(&dev->struct_mutex))
                return -EBUSY;
  
 -      dev_priv->stop_rings = 0;
 -
        i915_gem_reset(dev);
  
        ret = -ENODEV;
                for_each_ring(ring, dev_priv, i)
                        ring->init(ring);
  
 +              i915_gem_context_init(dev);
                i915_gem_init_ppgtt(dev);
  
 -              mutex_unlock(&dev->struct_mutex);
 +              /*
 +               * It would make sense to re-init all the other hw state, at
 +               * least the rps/rc6/emon init done within modeset_init_hw. For
 +               * some unknown reason, this blows up my ilk, so don't.
 +               */
  
 -              if (drm_core_check_feature(dev, DRIVER_MODESET))
 -                      intel_modeset_init_hw(dev);
 +              mutex_unlock(&dev->struct_mutex);
  
                drm_irq_uninstall(dev);
                drm_irq_install(dev);
@@@ -1144,89 -1145,10 +1150,88 @@@ MODULE_LICENSE("GPL and additional righ
  
  /* We give fast paths for the really cool registers */
  #define NEEDS_FORCE_WAKE(dev_priv, reg) \
-        (((dev_priv)->info->gen >= 6) && \
-         ((reg) < 0x40000) &&            \
-         ((reg) != FORCEWAKE)) && \
-        (!IS_VALLEYVIEW((dev_priv)->dev))
+       ((HAS_FORCE_WAKE((dev_priv)->dev)) && \
+        ((reg) < 0x40000) &&            \
+        ((reg) != FORCEWAKE))
  
 +static bool IS_DISPLAYREG(u32 reg)
 +{
 +      /*
 +       * This should make it easier to transition modules over to the
 +       * new register block scheme, since we can do it incrementally.
 +       */
 +      if (reg >= 0x180000)
 +              return false;
 +
 +      if (reg >= RENDER_RING_BASE &&
 +          reg < RENDER_RING_BASE + 0xff)
 +              return false;
 +      if (reg >= GEN6_BSD_RING_BASE &&
 +          reg < GEN6_BSD_RING_BASE + 0xff)
 +              return false;
 +      if (reg >= BLT_RING_BASE &&
 +          reg < BLT_RING_BASE + 0xff)
 +              return false;
 +
 +      if (reg == PGTBL_ER)
 +              return false;
 +
 +      if (reg >= IPEIR_I965 &&
 +          reg < HWSTAM)
 +              return false;
 +
 +      if (reg == MI_MODE)
 +              return false;
 +
 +      if (reg == GFX_MODE_GEN7)
 +              return false;
 +
 +      if (reg == RENDER_HWS_PGA_GEN7 ||
 +          reg == BSD_HWS_PGA_GEN7 ||
 +          reg == BLT_HWS_PGA_GEN7)
 +              return false;
 +
 +      if (reg == GEN6_BSD_SLEEP_PSMI_CONTROL ||
 +          reg == GEN6_BSD_RNCID)
 +              return false;
 +
 +      if (reg == GEN6_BLITTER_ECOSKPD)
 +              return false;
 +
 +      if (reg >= 0x4000c &&
 +          reg <= 0x4002c)
 +              return false;
 +
 +      if (reg >= 0x4f000 &&
 +          reg <= 0x4f08f)
 +              return false;
 +
 +      if (reg >= 0x4f100 &&
 +          reg <= 0x4f11f)
 +              return false;
 +
 +      if (reg >= VLV_MASTER_IER &&
 +          reg <= GEN6_PMIER)
 +              return false;
 +
 +      if (reg >= FENCE_REG_SANDYBRIDGE_0 &&
 +          reg < (FENCE_REG_SANDYBRIDGE_0 + (16*8)))
 +              return false;
 +
 +      if (reg >= VLV_IIR_RW &&
 +          reg <= VLV_ISR)
 +              return false;
 +
 +      if (reg == FORCEWAKE_VLV ||
 +          reg == FORCEWAKE_ACK_VLV)
 +              return false;
 +
 +      if (reg == GEN6_GDRST)
 +              return false;
 +
 +      return true;
 +}
 +
  #define __i915_read(x, y) \
  u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \
        u##x val = 0; \
                if (dev_priv->forcewake_count == 0) \
                        dev_priv->display.force_wake_put(dev_priv); \
                spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); \
 +      } else if (IS_VALLEYVIEW(dev_priv->dev) && IS_DISPLAYREG(reg)) { \
 +              val = read##y(dev_priv->regs + reg + 0x180000);         \
        } else { \
                val = read##y(dev_priv->regs + reg); \
        } \
@@@ -1261,11 -1181,7 +1266,11 @@@ void i915_write##x(struct drm_i915_priv
        if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
                __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \
        } \
 -      write##y(val, dev_priv->regs + reg); \
 +      if (IS_VALLEYVIEW(dev_priv->dev) && IS_DISPLAYREG(reg)) { \
 +              write##y(val, dev_priv->regs + reg + 0x180000);         \
 +      } else {                                                        \
 +              write##y(val, dev_priv->regs + reg);                    \
 +      }                                                               \
        if (unlikely(__fifo_ret)) { \
                gen6_gt_check_fifodbg(dev_priv); \
        } \
index 24ef5d77927fb25b9548316b00eb56f9ebadc2d0,b0b676abde0de1314f1181f79f1667d35f8eee67..a0c15abbdceffec95a1f77060b3478ae1f133395
@@@ -176,7 -176,6 +176,7 @@@ struct drm_i915_error_state 
        u32 eir;
        u32 pgtbl_er;
        u32 ier;
 +      u32 ccid;
        bool waiting[I915_NUM_RINGS];
        u32 pipestat[I915_MAX_PIPES];
        u32 tail[I915_NUM_RINGS];
@@@ -286,6 -285,7 +286,7 @@@ struct intel_device_info 
        u8 is_ivybridge:1;
        u8 is_valleyview:1;
        u8 has_pch_split:1;
+       u8 has_force_wake:1;
        u8 is_haswell:1;
        u8 has_fbc:1;
        u8 has_pipe_cxsr:1;
@@@ -309,17 -309,6 +310,17 @@@ struct i915_hw_ppgtt 
        dma_addr_t scratch_page_dma_addr;
  };
  
 +
 +/* This must match up with the value previously used for execbuf2.rsvd1. */
 +#define DEFAULT_CONTEXT_ID 0
 +struct i915_hw_context {
 +      int id;
 +      bool is_initialized;
 +      struct drm_i915_file_private *file_priv;
 +      struct intel_ring_buffer *ring;
 +      struct drm_i915_gem_object *obj;
 +};
 +
  enum no_fbc_reason {
        FBC_NO_OUTPUT, /* no outputs enabled to compress */
        FBC_STOLEN_TOO_SMALL, /* not enough space to hold compressed buffers */
@@@ -663,14 -652,11 +664,14 @@@ typedef struct drm_i915_private 
                unsigned long gtt_end;
  
                struct io_mapping *gtt_mapping;
 +              phys_addr_t gtt_base_addr;
                int gtt_mtrr;
  
                /** PPGTT used for aliasing the PPGTT with the GTT */
                struct i915_hw_ppgtt *aliasing_ppgtt;
  
 +              u32 *l3_remap_info;
 +
                struct shrinker inactive_shrinker;
  
                /**
  
        struct drm_property *broadcast_rgb_property;
        struct drm_property *force_audio_property;
 +
 +      struct work_struct parity_error_work;
 +      bool hw_contexts_disabled;
 +      uint32_t hw_context_size;
  } drm_i915_private_t;
  
  /* Iterate over initialised rings */
@@@ -1044,7 -1026,6 +1045,7 @@@ struct drm_i915_file_private 
                struct spinlock lock;
                struct list_head request_list;
        } mm;
 +      struct idr context_idr;
  };
  
  #define INTEL_INFO(dev)       (((struct drm_i915_private *) (dev)->dev_private)->info)
  #define HAS_LLC(dev)            (INTEL_INFO(dev)->has_llc)
  #define I915_NEED_GFX_HWS(dev)        (INTEL_INFO(dev)->need_gfx_hws)
  
 -#define HAS_ALIASING_PPGTT(dev)       (INTEL_INFO(dev)->gen >=6)
 +#define HAS_HW_CONTEXTS(dev)  (INTEL_INFO(dev)->gen >= 6)
 +#define HAS_ALIASING_PPGTT(dev)       (INTEL_INFO(dev)->gen >=6 && !IS_VALLEYVIEW(dev))
  
  #define HAS_OVERLAY(dev)              (INTEL_INFO(dev)->has_overlay)
  #define OVERLAY_NEEDS_PHYSICAL(dev)   (INTEL_INFO(dev)->overlay_needs_physical)
  #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT)
  #define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX)
  
+ #define HAS_FORCE_WAKE(dev) (INTEL_INFO(dev)->has_force_wake)
  #include "i915_trace.h"
  
  /**
@@@ -1184,7 -1166,6 +1187,7 @@@ extern long i915_compat_ioctl(struct fi
  extern int i915_emit_box(struct drm_device *dev,
                         struct drm_clip_rect *box,
                         int DR1, int DR4);
 +extern int intel_gpu_reset(struct drm_device *dev);
  extern int i915_reset(struct drm_device *dev);
  extern unsigned long i915_chipset_val(struct drm_i915_private *dev_priv);
  extern unsigned long i915_mch_val(struct drm_i915_private *dev_priv);
@@@ -1256,8 -1237,6 +1259,8 @@@ int i915_gem_get_tiling(struct drm_devi
                        struct drm_file *file_priv);
  int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
                                struct drm_file *file_priv);
 +int i915_gem_wait_ioctl(struct drm_device *dev, void *data,
 +                      struct drm_file *file_priv);
  void i915_gem_load(struct drm_device *dev);
  int i915_gem_init_object(struct drm_gem_object *obj);
  int __must_check i915_gem_flush_ring(struct intel_ring_buffer *ring,
@@@ -1336,7 -1315,6 +1339,7 @@@ int __must_check i915_gem_object_set_do
  int __must_check i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj);
  int __must_check i915_gem_init(struct drm_device *dev);
  int __must_check i915_gem_init_hw(struct drm_device *dev);
 +void i915_gem_l3_remap(struct drm_device *dev);
  void i915_gem_init_swizzling(struct drm_device *dev);
  void i915_gem_init_ppgtt(struct drm_device *dev);
  void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
@@@ -1345,8 -1323,8 +1348,8 @@@ int __must_check i915_gem_idle(struct d
  int __must_check i915_add_request(struct intel_ring_buffer *ring,
                                  struct drm_file *file,
                                  struct drm_i915_gem_request *request);
 -int __must_check i915_wait_request(struct intel_ring_buffer *ring,
 -                                 uint32_t seqno);
 +int __must_check i915_wait_seqno(struct intel_ring_buffer *ring,
 +                               uint32_t seqno);
  int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
  int __must_check
  i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj,
@@@ -1380,16 -1358,6 +1383,16 @@@ 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);
  
 +/* i915_gem_context.c */
 +void i915_gem_context_init(struct drm_device *dev);
 +void i915_gem_context_fini(struct drm_device *dev);
 +void i915_gem_context_close(struct drm_device *dev, struct drm_file *file);
 +int i915_switch_context(struct intel_ring_buffer *ring,
 +                      struct drm_file *file, int to_id);
 +int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
 +                                struct drm_file *file);
 +int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data,
 +                                 struct drm_file *file);
  
  /* i915_gem_gtt.c */
  int __must_check i915_gem_init_aliasing_ppgtt(struct drm_device *dev);
index 84975e1e1f0579c3fd969fd4d87a91188a99e9e6,b1fe0edda955565d27026bccc52eb9e47358d2d5..23f2ea0f0651f8cf29e64a6a152d3f553a3fbd02
@@@ -375,86 -375,6 +375,86 @@@ static void gen6_pm_rps_work(struct wor
        mutex_unlock(&dev_priv->dev->struct_mutex);
  }
  
 +
 +/**
 + * ivybridge_parity_work - Workqueue called when a parity error interrupt
 + * occurred.
 + * @work: workqueue struct
 + *
 + * Doesn't actually do anything except notify userspace. As a consequence of
 + * this event, userspace should try to remap the bad rows since statistically
 + * it is likely the same row is more likely to go bad again.
 + */
 +static void ivybridge_parity_work(struct work_struct *work)
 +{
 +      drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
 +                                                  parity_error_work);
 +      u32 error_status, row, bank, subbank;
 +      char *parity_event[5];
 +      uint32_t misccpctl;
 +      unsigned long flags;
 +
 +      /* We must turn off DOP level clock gating to access the L3 registers.
 +       * In order to prevent a get/put style interface, acquire struct mutex
 +       * any time we access those registers.
 +       */
 +      mutex_lock(&dev_priv->dev->struct_mutex);
 +
 +      misccpctl = I915_READ(GEN7_MISCCPCTL);
 +      I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE);
 +      POSTING_READ(GEN7_MISCCPCTL);
 +
 +      error_status = I915_READ(GEN7_L3CDERRST1);
 +      row = GEN7_PARITY_ERROR_ROW(error_status);
 +      bank = GEN7_PARITY_ERROR_BANK(error_status);
 +      subbank = GEN7_PARITY_ERROR_SUBBANK(error_status);
 +
 +      I915_WRITE(GEN7_L3CDERRST1, GEN7_PARITY_ERROR_VALID |
 +                                  GEN7_L3CDERRST1_ENABLE);
 +      POSTING_READ(GEN7_L3CDERRST1);
 +
 +      I915_WRITE(GEN7_MISCCPCTL, misccpctl);
 +
 +      spin_lock_irqsave(&dev_priv->irq_lock, flags);
 +      dev_priv->gt_irq_mask &= ~GT_GEN7_L3_PARITY_ERROR_INTERRUPT;
 +      I915_WRITE(GTIMR, dev_priv->gt_irq_mask);
 +      spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
 +
 +      mutex_unlock(&dev_priv->dev->struct_mutex);
 +
 +      parity_event[0] = "L3_PARITY_ERROR=1";
 +      parity_event[1] = kasprintf(GFP_KERNEL, "ROW=%d", row);
 +      parity_event[2] = kasprintf(GFP_KERNEL, "BANK=%d", bank);
 +      parity_event[3] = kasprintf(GFP_KERNEL, "SUBBANK=%d", subbank);
 +      parity_event[4] = NULL;
 +
 +      kobject_uevent_env(&dev_priv->dev->primary->kdev.kobj,
 +                         KOBJ_CHANGE, parity_event);
 +
 +      DRM_DEBUG("Parity error: Row = %d, Bank = %d, Sub bank = %d.\n",
 +                row, bank, subbank);
 +
 +      kfree(parity_event[3]);
 +      kfree(parity_event[2]);
 +      kfree(parity_event[1]);
 +}
 +
 +static void ivybridge_handle_parity_error(struct drm_device *dev)
 +{
 +      drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 +      unsigned long flags;
 +
 +      if (!IS_IVYBRIDGE(dev))
 +              return;
 +
 +      spin_lock_irqsave(&dev_priv->irq_lock, flags);
 +      dev_priv->gt_irq_mask |= GT_GEN7_L3_PARITY_ERROR_INTERRUPT;
 +      I915_WRITE(GTIMR, dev_priv->gt_irq_mask);
 +      spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
 +
 +      queue_work(dev_priv->wq, &dev_priv->parity_error_work);
 +}
 +
  static void snb_gt_irq_handler(struct drm_device *dev,
                               struct drm_i915_private *dev_priv,
                               u32 gt_iir)
                DRM_ERROR("GT error interrupt 0x%08x\n", gt_iir);
                i915_handle_error(dev, false);
        }
 +
 +      if (gt_iir & GT_GEN7_L3_PARITY_ERROR_INTERRUPT)
 +              ivybridge_handle_parity_error(dev);
  }
  
  static void gen6_queue_rps_work(struct drm_i915_private *dev_priv,
@@@ -513,10 -430,15 +513,10 @@@ static irqreturn_t valleyview_irq_handl
        unsigned long irqflags;
        int pipe;
        u32 pipe_stats[I915_MAX_PIPES];
 -      u32 vblank_status;
 -      int vblank = 0;
        bool blc_event;
  
        atomic_inc(&dev_priv->irq_received);
  
 -      vblank_status = PIPE_START_VBLANK_INTERRUPT_STATUS |
 -              PIPE_VBLANK_INTERRUPT_STATUS;
 -
        while (true) {
                iir = I915_READ(VLV_IIR);
                gt_iir = I915_READ(GTIIR);
                }
                spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
  
 +              for_each_pipe(pipe) {
 +                      if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS)
 +                              drm_handle_vblank(dev, pipe);
 +
 +                      if (pipe_stats[pipe] & PLANE_FLIPDONE_INT_STATUS_VLV) {
 +                              intel_prepare_page_flip(dev, pipe);
 +                              intel_finish_page_flip(dev, pipe);
 +                      }
 +              }
 +
                /* Consume port.  Then clear IIR or we'll miss events */
                if (iir & I915_DISPLAY_PORT_INTERRUPT) {
                        u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT);
                        I915_READ(PORT_HOTPLUG_STAT);
                }
  
 -
 -              if (iir & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT) {
 -                      drm_handle_vblank(dev, 0);
 -                      vblank++;
 -                      intel_finish_page_flip(dev, 0);
 -              }
 -
 -              if (iir & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT) {
 -                      drm_handle_vblank(dev, 1);
 -                      vblank++;
 -                      intel_finish_page_flip(dev, 0);
 -              }
 -
                if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS)
                        blc_event = true;
  
@@@ -585,7 -510,7 +585,7 @@@ out
        return ret;
  }
  
- static void pch_irq_handler(struct drm_device *dev, u32 pch_iir)
+ static void ibx_irq_handler(struct drm_device *dev, u32 pch_iir)
  {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
        int pipe;
                DRM_DEBUG_DRIVER("PCH transcoder A underrun interrupt\n");
  }
  
+ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir)
+ {
+       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       int pipe;
+       if (pch_iir & SDE_AUDIO_POWER_MASK_CPT)
+               DRM_DEBUG_DRIVER("PCH audio power change on port %d\n",
+                                (pch_iir & SDE_AUDIO_POWER_MASK_CPT) >>
+                                SDE_AUDIO_POWER_SHIFT_CPT);
+       if (pch_iir & SDE_AUX_MASK_CPT)
+               DRM_DEBUG_DRIVER("AUX channel interrupt\n");
+       if (pch_iir & SDE_GMBUS_CPT)
+               DRM_DEBUG_DRIVER("PCH GMBUS interrupt\n");
+       if (pch_iir & SDE_AUDIO_CP_REQ_CPT)
+               DRM_DEBUG_DRIVER("Audio CP request interrupt\n");
+       if (pch_iir & SDE_AUDIO_CP_CHG_CPT)
+               DRM_DEBUG_DRIVER("Audio CP change interrupt\n");
+       if (pch_iir & SDE_FDI_MASK_CPT)
+               for_each_pipe(pipe)
+                       DRM_DEBUG_DRIVER("  pipe %c FDI IIR: 0x%08x\n",
+                                        pipe_name(pipe),
+                                        I915_READ(FDI_RX_IIR(pipe)));
+ }
  static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS)
  {
        struct drm_device *dev = (struct drm_device *) arg;
  
                        if (pch_iir & SDE_HOTPLUG_MASK_CPT)
                                queue_work(dev_priv->wq, &dev_priv->hotplug_work);
-                       pch_irq_handler(dev, pch_iir);
+                       cpt_irq_handler(dev, pch_iir);
  
                        /* clear PCH hotplug event before clear CPU irq */
                        I915_WRITE(SDEIIR, pch_iir);
@@@ -759,7 -713,10 +788,10 @@@ static irqreturn_t ironlake_irq_handler
        if (de_iir & DE_PCH_EVENT) {
                if (pch_iir & hotplug_mask)
                        queue_work(dev_priv->wq, &dev_priv->hotplug_work);
-               pch_irq_handler(dev, pch_iir);
+               if (HAS_PCH_CPT(dev))
+                       cpt_irq_handler(dev, pch_iir);
+               else
+                       ibx_irq_handler(dev, pch_iir);
        }
  
        if (de_iir & DE_PCU_EVENT) {
@@@ -1148,7 -1105,6 +1180,7 @@@ static void i915_capture_error_state(st
        kref_init(&error->ref);
        error->eir = I915_READ(EIR);
        error->pgtbl_er = I915_READ(PGTBL_ER);
 +      error->ccid = I915_READ(CCID);
  
        if (HAS_PCH_SPLIT(dev))
                error->ier = I915_READ(DEIER) | I915_READ(GTIER);
@@@ -1471,20 -1427,23 +1503,20 @@@ static int valleyview_enable_vblank(str
  {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
        unsigned long irqflags;
 -      u32 dpfl, imr;
 +      u32 imr;
  
        if (!i915_pipe_enabled(dev, pipe))
                return -EINVAL;
  
        spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
 -      dpfl = I915_READ(VLV_DPFLIPSTAT);
        imr = I915_READ(VLV_IMR);
 -      if (pipe == 0) {
 -              dpfl |= PIPEA_VBLANK_INT_EN;
 +      if (pipe == 0)
                imr &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
 -      } else {
 -              dpfl |= PIPEA_VBLANK_INT_EN;
 +      else
                imr &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
 -      }
 -      I915_WRITE(VLV_DPFLIPSTAT, dpfl);
        I915_WRITE(VLV_IMR, imr);
 +      i915_enable_pipestat(dev_priv, pipe,
 +                           PIPE_START_VBLANK_INTERRUPT_ENABLE);
        spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
  
        return 0;
@@@ -1534,17 -1493,20 +1566,17 @@@ static void valleyview_disable_vblank(s
  {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
        unsigned long irqflags;
 -      u32 dpfl, imr;
 +      u32 imr;
  
        spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
 -      dpfl = I915_READ(VLV_DPFLIPSTAT);
 +      i915_disable_pipestat(dev_priv, pipe,
 +                            PIPE_START_VBLANK_INTERRUPT_ENABLE);
        imr = I915_READ(VLV_IMR);
 -      if (pipe == 0) {
 -              dpfl &= ~PIPEA_VBLANK_INT_EN;
 +      if (pipe == 0)
                imr |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
 -      } else {
 -              dpfl &= ~PIPEB_VBLANK_INT_EN;
 +      else
                imr |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
 -      }
        I915_WRITE(VLV_IMR, imr);
 -      I915_WRITE(VLV_DPFLIPSTAT, dpfl);
        spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
  }
  
@@@ -1687,6 -1649,7 +1719,6 @@@ static void ironlake_irq_preinstall(str
  
        atomic_set(&dev_priv->irq_received, 0);
  
 -
        I915_WRITE(HWSTAM, 0xeffe);
  
        /* XXX hotplug from PCH */
@@@ -1849,13 -1812,13 +1881,13 @@@ static int ivybridge_irq_postinstall(st
                   DE_PIPEA_VBLANK_IVB);
        POSTING_READ(DEIER);
  
 -      dev_priv->gt_irq_mask = ~0;
 +      dev_priv->gt_irq_mask = ~GT_GEN7_L3_PARITY_ERROR_INTERRUPT;
  
        I915_WRITE(GTIIR, I915_READ(GTIIR));
        I915_WRITE(GTIMR, dev_priv->gt_irq_mask);
  
        render_irqs = GT_USER_INTERRUPT | GEN6_BSD_USER_INTERRUPT |
 -              GEN6_BLITTER_USER_INTERRUPT;
 +              GEN6_BLITTER_USER_INTERRUPT | GT_GEN7_L3_PARITY_ERROR_INTERRUPT;
        I915_WRITE(GTIER, render_irqs);
        POSTING_READ(GTIER);
  
  static int valleyview_irq_postinstall(struct drm_device *dev)
  {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 -      u32 render_irqs;
        u32 enable_mask;
        u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN);
 +      u32 pipestat_enable = PLANE_FLIP_DONE_INT_EN_VLV;
        u16 msid;
  
        enable_mask = I915_DISPLAY_PORT_INTERRUPT;
 -      enable_mask |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
 +      enable_mask |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT |
 +              I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
 +              I915_DISPLAY_PIPE_B_EVENT_INTERRUPT |
                I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
  
 -      dev_priv->irq_mask = ~enable_mask;
 +      /*
 +       *Leave vblank interrupts masked initially.  enable/disable will
 +       * toggle them based on usage.
 +       */
 +      dev_priv->irq_mask = (~enable_mask) |
 +              I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
 +              I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
  
        dev_priv->pipestat[0] = 0;
        dev_priv->pipestat[1] = 0;
        I915_WRITE(PIPESTAT(1), 0xffff);
        POSTING_READ(VLV_IER);
  
 +      i915_enable_pipestat(dev_priv, 0, pipestat_enable);
 +      i915_enable_pipestat(dev_priv, 1, pipestat_enable);
 +
        I915_WRITE(VLV_IIR, 0xffffffff);
        I915_WRITE(VLV_IIR, 0xffffffff);
  
 -      render_irqs = GT_GEN6_BLT_FLUSHDW_NOTIFY_INTERRUPT |
 -              GT_GEN6_BLT_CS_ERROR_INTERRUPT |
 -              GT_GEN6_BLT_USER_INTERRUPT |
 -              GT_GEN6_BSD_USER_INTERRUPT |
 -              GT_GEN6_BSD_CS_ERROR_INTERRUPT |
 -              GT_GEN7_L3_PARITY_ERROR_INTERRUPT |
 -              GT_PIPE_NOTIFY |
 -              GT_RENDER_CS_ERROR_INTERRUPT |
 -              GT_SYNC_STATUS |
 -              GT_USER_INTERRUPT;
 -
 -      dev_priv->gt_irq_mask = ~render_irqs;
 +      dev_priv->gt_irq_mask = ~0;
  
        I915_WRITE(GTIIR, I915_READ(GTIIR));
        I915_WRITE(GTIIR, I915_READ(GTIIR));
 -      I915_WRITE(GTIMR, 0);
 -      I915_WRITE(GTIER, render_irqs);
 +      I915_WRITE(GTIMR, dev_priv->gt_irq_mask);
 +      I915_WRITE(GTIER, GT_GEN6_BLT_FLUSHDW_NOTIFY_INTERRUPT |
 +                 GT_GEN6_BLT_CS_ERROR_INTERRUPT |
 +                 GT_GEN6_BLT_USER_INTERRUPT |
 +                 GT_GEN6_BSD_USER_INTERRUPT |
 +                 GT_GEN6_BSD_CS_ERROR_INTERRUPT |
 +                 GT_GEN7_L3_PARITY_ERROR_INTERRUPT |
 +                 GT_PIPE_NOTIFY |
 +                 GT_RENDER_CS_ERROR_INTERRUPT |
 +                 GT_SYNC_STATUS |
 +                 GT_USER_INTERRUPT);
        POSTING_READ(GTIER);
  
        /* ack & enable invalid PTE error interrupts */
@@@ -2213,9 -2167,9 +2245,9 @@@ static int i915_irq_postinstall(struct 
                        hotplug_en |= HDMIC_HOTPLUG_INT_EN;
                if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS)
                        hotplug_en |= HDMID_HOTPLUG_INT_EN;
 -              if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS)
 +              if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS_I915)
                        hotplug_en |= SDVOC_HOTPLUG_INT_EN;
 -              if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS)
 +              if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS_I915)
                        hotplug_en |= SDVOB_HOTPLUG_INT_EN;
                if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) {
                        hotplug_en |= CRT_HOTPLUG_INT_EN;
@@@ -2375,8 -2329,10 +2407,8 @@@ static void i965_irq_preinstall(struct 
  
        atomic_set(&dev_priv->irq_received, 0);
  
 -      if (I915_HAS_HOTPLUG(dev)) {
 -              I915_WRITE(PORT_HOTPLUG_EN, 0);
 -              I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
 -      }
 +      I915_WRITE(PORT_HOTPLUG_EN, 0);
 +      I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
  
        I915_WRITE(HWSTAM, 0xeffe);
        for_each_pipe(pipe)
  static int i965_irq_postinstall(struct drm_device *dev)
  {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 +      u32 hotplug_en;
        u32 enable_mask;
        u32 error_mask;
  
        /* Unmask the interrupts that we always want on. */
        dev_priv->irq_mask = ~(I915_ASLE_INTERRUPT |
 +                             I915_DISPLAY_PORT_INTERRUPT |
                               I915_DISPLAY_PIPE_A_EVENT_INTERRUPT |
                               I915_DISPLAY_PIPE_B_EVENT_INTERRUPT |
                               I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
        dev_priv->pipestat[0] = 0;
        dev_priv->pipestat[1] = 0;
  
 -      if (I915_HAS_HOTPLUG(dev)) {
 -              /* Enable in IER... */
 -              enable_mask |= I915_DISPLAY_PORT_INTERRUPT;
 -              /* and unmask in IMR */
 -              dev_priv->irq_mask &= ~I915_DISPLAY_PORT_INTERRUPT;
 -      }
 -
        /*
         * Enable some error detection, note the instruction error mask
         * bit is reserved, so we leave it masked.
        I915_WRITE(IER, enable_mask);
        POSTING_READ(IER);
  
 -      if (I915_HAS_HOTPLUG(dev)) {
 -              u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN);
 -
 -              /* Note HDMI and DP share bits */
 -              if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS)
 -                      hotplug_en |= HDMIB_HOTPLUG_INT_EN;
 -              if (dev_priv->hotplug_supported_mask & HDMIC_HOTPLUG_INT_STATUS)
 -                      hotplug_en |= HDMIC_HOTPLUG_INT_EN;
 -              if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS)
 -                      hotplug_en |= HDMID_HOTPLUG_INT_EN;
 -              if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS)
 +      /* Note HDMI and DP share hotplug bits */
 +      hotplug_en = 0;
 +      if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS)
 +              hotplug_en |= HDMIB_HOTPLUG_INT_EN;
 +      if (dev_priv->hotplug_supported_mask & HDMIC_HOTPLUG_INT_STATUS)
 +              hotplug_en |= HDMIC_HOTPLUG_INT_EN;
 +      if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS)
 +              hotplug_en |= HDMID_HOTPLUG_INT_EN;
 +      if (IS_G4X(dev)) {
 +              if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS_G4X)
                        hotplug_en |= SDVOC_HOTPLUG_INT_EN;
 -              if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS)
 +              if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS_G4X)
                        hotplug_en |= SDVOB_HOTPLUG_INT_EN;
 -              if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) {
 -                      hotplug_en |= CRT_HOTPLUG_INT_EN;
 +      } else {
 +              if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS_I965)
 +                      hotplug_en |= SDVOC_HOTPLUG_INT_EN;
 +              if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS_I965)
 +                      hotplug_en |= SDVOB_HOTPLUG_INT_EN;
 +      }
 +      if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) {
 +              hotplug_en |= CRT_HOTPLUG_INT_EN;
  
 -                      /* 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_50;
 -              }
 +              /* 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_50;
 +      }
  
 -              /* Ignore TV since it's buggy */
 +      /* Ignore TV since it's buggy */
  
 -              I915_WRITE(PORT_HOTPLUG_EN, hotplug_en);
 -      }
 +      I915_WRITE(PORT_HOTPLUG_EN, hotplug_en);
  
        intel_opregion_enable_asle(dev);
  
@@@ -2521,7 -2478,8 +2553,7 @@@ static irqreturn_t i965_irq_handler(DRM
                ret = IRQ_HANDLED;
  
                /* Consume port.  Then clear IIR or we'll miss events */
 -              if ((I915_HAS_HOTPLUG(dev)) &&
 -                  (iir & I915_DISPLAY_PORT_INTERRUPT)) {
 +              if (iir & I915_DISPLAY_PORT_INTERRUPT) {
                        u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT);
  
                        DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n",
@@@ -2594,8 -2552,10 +2626,8 @@@ static void i965_irq_uninstall(struct d
        if (!dev_priv)
                return;
  
 -      if (I915_HAS_HOTPLUG(dev)) {
 -              I915_WRITE(PORT_HOTPLUG_EN, 0);
 -              I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
 -      }
 +      I915_WRITE(PORT_HOTPLUG_EN, 0);
 +      I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
  
        I915_WRITE(HWSTAM, 0xffffffff);
        for_each_pipe(pipe)
@@@ -2616,7 -2576,6 +2648,7 @@@ void intel_irq_init(struct drm_device *
        INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func);
        INIT_WORK(&dev_priv->error_work, i915_error_work_func);
        INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work);
 +      INIT_WORK(&dev_priv->parity_error_work, ivybridge_parity_work);
  
        dev->driver->get_vblank_counter = i915_get_vblank_counter;
        dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
index 0a61481cd2c2ad3396aec8ec3ac3a98a888173a4,48d5e8e051cf6a1057f247457e65045e679051ab..9dfc4c5ff31ea6fb399e0a03ee0a453f51d8190f
  #define MI_DISPLAY_FLIP               MI_INSTR(0x14, 2)
  #define MI_DISPLAY_FLIP_I915  MI_INSTR(0x14, 1)
  #define   MI_DISPLAY_FLIP_PLANE(n) ((n) << 20)
+ /* IVB has funny definitions for which plane to flip. */
+ #define   MI_DISPLAY_FLIP_IVB_PLANE_A  (0 << 19)
+ #define   MI_DISPLAY_FLIP_IVB_PLANE_B  (1 << 19)
+ #define   MI_DISPLAY_FLIP_IVB_SPRITE_A (2 << 19)
+ #define   MI_DISPLAY_FLIP_IVB_SPRITE_B (3 << 19)
+ #define   MI_DISPLAY_FLIP_IVB_PLANE_C  (4 << 19)
+ #define   MI_DISPLAY_FLIP_IVB_SPRITE_C (5 << 19)
 +#define MI_ARB_ON_OFF         MI_INSTR(0x08, 0)
 +#define   MI_ARB_ENABLE                       (1<<0)
 +#define   MI_ARB_DISABLE              (0<<0)
  #define MI_SET_CONTEXT                MI_INSTR(0x18, 0)
  #define   MI_MM_SPACE_GTT             (1<<8)
  #define   MI_MM_SPACE_PHYSICAL                (0<<8)
  #define   DISPLAY_PLANE_B           (1<<20)
  #define GFX_OP_PIPE_CONTROL(len)      ((0x3<<29)|(0x3<<27)|(0x2<<24)|(len-2))
  #define   PIPE_CONTROL_CS_STALL                               (1<<20)
 +#define   PIPE_CONTROL_TLB_INVALIDATE                 (1<<18)
  #define   PIPE_CONTROL_QW_WRITE                               (1<<14)
  #define   PIPE_CONTROL_DEPTH_STALL                    (1<<13)
  #define   PIPE_CONTROL_WRITE_FLUSH                    (1<<12)
  #define   DPLL_P2_CLOCK_DIV_MASK      0x03000000 /* i915 */
  #define   DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */
  #define   DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW        0x00ff8000 /* Pineview */
 +#define   DPLL_LOCK_VLV                       (1<<15)
  #define   DPLL_INTEGRATED_CLOCK_VLV   (1<<13)
  
  #define SRX_INDEX             0x3c4
   */
  #define CCID                  0x2180
  #define   CCID_EN             (1<<0)
 +#define CXT_SIZE              0x21a0
 +#define GEN6_CXT_POWER_SIZE(cxt_reg)  ((cxt_reg >> 24) & 0x3f)
 +#define GEN6_CXT_RING_SIZE(cxt_reg)   ((cxt_reg >> 18) & 0x3f)
 +#define GEN6_CXT_RENDER_SIZE(cxt_reg) ((cxt_reg >> 12) & 0x3f)
 +#define GEN6_CXT_EXTENDED_SIZE(cxt_reg)       ((cxt_reg >> 6) & 0x3f)
 +#define GEN6_CXT_PIPELINE_SIZE(cxt_reg)       ((cxt_reg >> 0) & 0x3f)
 +#define GEN6_CXT_TOTAL_SIZE(cxt_reg)  (GEN6_CXT_POWER_SIZE(cxt_reg) + \
 +                                      GEN6_CXT_RING_SIZE(cxt_reg) + \
 +                                      GEN6_CXT_RENDER_SIZE(cxt_reg) + \
 +                                      GEN6_CXT_EXTENDED_SIZE(cxt_reg) + \
 +                                      GEN6_CXT_PIPELINE_SIZE(cxt_reg))
 +#define GEN7_CTX_SIZE         0x21a8
 +#define GEN7_CTX_RENDER_SIZE(ctx_reg) ((ctx_reg >> 16) & 0x3f)
 +#define GEN7_CTX_EXTENDED_SIZE(ctx_reg)       ((ctx_reg >> 9) & 0x7f)
 +#define GEN7_CTX_GT1_SIZE(ctx_reg)    ((ctx_reg >> 6) & 0x7)
 +#define GEN7_CTX_VFSTATE_SIZE(ctx_reg)        ((ctx_reg >> 0) & 0x3f)
 +#define GEN7_CTX_TOTAL_SIZE(ctx_reg)  (GEN7_CTX_RENDER_SIZE(ctx_reg) + \
 +                                       GEN7_CTX_EXTENDED_SIZE(ctx_reg) + \
 +                                       GEN7_CTX_GT1_SIZE(ctx_reg) + \
 +                                       GEN7_CTX_VFSTATE_SIZE(ctx_reg))
 +
  /*
   * Overlay regs
   */
  #define CRT_HOTPLUG_DETECT_VOLTAGE_475MV      (1 << 2)
  
  #define PORT_HOTPLUG_STAT     0x61114
 -#define   HDMIB_HOTPLUG_INT_STATUS            (1 << 29)
 -#define   DPB_HOTPLUG_INT_STATUS              (1 << 29)
 -#define   HDMIC_HOTPLUG_INT_STATUS            (1 << 28)
 -#define   DPC_HOTPLUG_INT_STATUS              (1 << 28)
 -#define   HDMID_HOTPLUG_INT_STATUS            (1 << 27)
 -#define   DPD_HOTPLUG_INT_STATUS              (1 << 27)
 +/* HDMI/DP bits are gen4+ */
 +#define   DPB_HOTPLUG_LIVE_STATUS               (1 << 29)
 +#define   DPC_HOTPLUG_LIVE_STATUS               (1 << 28)
 +#define   DPD_HOTPLUG_LIVE_STATUS               (1 << 27)
 +#define   DPD_HOTPLUG_INT_STATUS              (3 << 21)
 +#define   DPC_HOTPLUG_INT_STATUS              (3 << 19)
 +#define   DPB_HOTPLUG_INT_STATUS              (3 << 17)
 +/* HDMI bits are shared with the DP bits */
 +#define   HDMIB_HOTPLUG_LIVE_STATUS             (1 << 29)
 +#define   HDMIC_HOTPLUG_LIVE_STATUS             (1 << 28)
 +#define   HDMID_HOTPLUG_LIVE_STATUS             (1 << 27)
 +#define   HDMID_HOTPLUG_INT_STATUS            (3 << 21)
 +#define   HDMIC_HOTPLUG_INT_STATUS            (3 << 19)
 +#define   HDMIB_HOTPLUG_INT_STATUS            (3 << 17)
 +/* CRT/TV common between gen3+ */
  #define   CRT_HOTPLUG_INT_STATUS              (1 << 11)
  #define   TV_HOTPLUG_INT_STATUS                       (1 << 10)
  #define   CRT_HOTPLUG_MONITOR_MASK            (3 << 8)
  #define   CRT_HOTPLUG_MONITOR_COLOR           (3 << 8)
  #define   CRT_HOTPLUG_MONITOR_MONO            (2 << 8)
  #define   CRT_HOTPLUG_MONITOR_NONE            (0 << 8)
 -#define   SDVOC_HOTPLUG_INT_STATUS            (1 << 7)
 -#define   SDVOB_HOTPLUG_INT_STATUS            (1 << 6)
 +/* SDVO is different across gen3/4 */
 +#define   SDVOC_HOTPLUG_INT_STATUS_G4X                (1 << 3)
 +#define   SDVOB_HOTPLUG_INT_STATUS_G4X                (1 << 2)
 +#define   SDVOC_HOTPLUG_INT_STATUS_I965               (3 << 4)
 +#define   SDVOB_HOTPLUG_INT_STATUS_I965               (3 << 2)
 +#define   SDVOC_HOTPLUG_INT_STATUS_I915               (1 << 7)
 +#define   SDVOB_HOTPLUG_INT_STATUS_I915               (1 << 6)
  
  /* SDVO port control */
  #define SDVOB                 0x61140
  #define   VIDEO_DIP_PORT_C            (2 << 29)
  #define   VIDEO_DIP_PORT_D            (3 << 29)
  #define   VIDEO_DIP_PORT_MASK         (3 << 29)
 +#define   VIDEO_DIP_ENABLE_GCP                (1 << 25)
  #define   VIDEO_DIP_ENABLE_AVI                (1 << 21)
  #define   VIDEO_DIP_ENABLE_VENDOR     (2 << 21)
 +#define   VIDEO_DIP_ENABLE_GAMUT      (4 << 21)
  #define   VIDEO_DIP_ENABLE_SPD                (8 << 21)
  #define   VIDEO_DIP_SELECT_AVI                (0 << 19)
  #define   VIDEO_DIP_SELECT_VENDOR     (1 << 19)
  #define   VIDEO_DIP_FREQ_2VSYNC               (2 << 16)
  #define   VIDEO_DIP_FREQ_MASK         (3 << 16)
  /* HSW and later: */
 +#define   VIDEO_DIP_ENABLE_VSC_HSW    (1 << 20)
 +#define   VIDEO_DIP_ENABLE_GCP_HSW    (1 << 16)
  #define   VIDEO_DIP_ENABLE_AVI_HSW    (1 << 12)
 +#define   VIDEO_DIP_ENABLE_VS_HSW     (1 << 8)
 +#define   VIDEO_DIP_ENABLE_GMP_HSW    (1 << 4)
  #define   VIDEO_DIP_ENABLE_SPD_HSW    (1 << 0)
  
  /* Panel power sequencing */
  #define PFIT_AUTO_RATIOS 0x61238
  
  /* Backlight control */
 -#define BLC_PWM_CTL           0x61254
 -#define   BACKLIGHT_MODULATION_FREQ_SHIFT             (17)
  #define BLC_PWM_CTL2          0x61250 /* 965+ only */
 -#define   BLM_COMBINATION_MODE (1 << 30)
 +#define   BLM_PWM_ENABLE              (1 << 31)
 +#define   BLM_COMBINATION_MODE                (1 << 30) /* gen4 only */
 +#define   BLM_PIPE_SELECT             (1 << 29)
 +#define   BLM_PIPE_SELECT_IVB         (3 << 29)
 +#define   BLM_PIPE_A                  (0 << 29)
 +#define   BLM_PIPE_B                  (1 << 29)
 +#define   BLM_PIPE_C                  (2 << 29) /* ivb + */
 +#define   BLM_PIPE(pipe)              ((pipe) << 29)
 +#define   BLM_POLARITY_I965           (1 << 28) /* gen4 only */
 +#define   BLM_PHASE_IN_INTERUPT_STATUS        (1 << 26)
 +#define   BLM_PHASE_IN_ENABLE         (1 << 25)
 +#define   BLM_PHASE_IN_INTERUPT_ENABL (1 << 24)
 +#define   BLM_PHASE_IN_TIME_BASE_SHIFT        (16)
 +#define   BLM_PHASE_IN_TIME_BASE_MASK (0xff << 16)
 +#define   BLM_PHASE_IN_COUNT_SHIFT    (8)
 +#define   BLM_PHASE_IN_COUNT_MASK     (0xff << 8)
 +#define   BLM_PHASE_IN_INCR_SHIFT     (0)
 +#define   BLM_PHASE_IN_INCR_MASK      (0xff << 0)
 +#define BLC_PWM_CTL           0x61254
  /*
   * This is the most significant 15 bits of the number of backlight cycles in a
   * complete cycle of the modulated backlight control.
   *
   * The actual value is this field multiplied by two.
   */
 -#define   BACKLIGHT_MODULATION_FREQ_MASK              (0x7fff << 17)
 -#define   BLM_LEGACY_MODE                             (1 << 16)
 +#define   BACKLIGHT_MODULATION_FREQ_SHIFT     (17)
 +#define   BACKLIGHT_MODULATION_FREQ_MASK      (0x7fff << 17)
 +#define   BLM_LEGACY_MODE                     (1 << 16) /* gen2 only */
  /*
   * This is the number of cycles out of the backlight modulation cycle for which
   * the backlight is on.
   */
  #define   BACKLIGHT_DUTY_CYCLE_SHIFT          (0)
  #define   BACKLIGHT_DUTY_CYCLE_MASK           (0xffff)
 +#define   BACKLIGHT_DUTY_CYCLE_MASK_PNV               (0xfffe)
 +#define   BLM_POLARITY_PNV                    (1 << 0) /* pnv only */
  
  #define BLC_HIST_CTL          0x61260
  
 +/* New registers for PCH-split platforms. Safe where new bits show up, the
 + * register layout machtes with gen4 BLC_PWM_CTL[12]. */
 +#define BLC_PWM_CPU_CTL2      0x48250
 +#define BLC_PWM_CPU_CTL               0x48254
 +
 +/* PCH CTL1 is totally different, all but the below bits are reserved. CTL2 is
 + * like the normal CTL from gen4 and earlier. Hooray for confusing naming. */
 +#define BLC_PWM_PCH_CTL1      0xc8250
 +#define   BLM_PCH_PWM_ENABLE                  (1 << 30)
 +#define   BLM_PCH_OVERRIDE_ENABLE             (1 << 30)
 +#define   BLM_PCH_POLARITY                    (1 << 29)
 +#define BLC_PWM_PCH_CTL2      0xc8254
 +
  /* TV port control */
  #define TV_CTL                        0x68000
  /** Enables the TV encoder */
  #define PIPESTAT(pipe) _PIPE(pipe, _PIPEASTAT, _PIPEBSTAT)
  
  #define VLV_DPFLIPSTAT                                0x70028
 -#define   PIPEB_LINE_COMPARE_STATUS           (1<<29)
 +#define   PIPEB_LINE_COMPARE_INT_EN           (1<<29)
  #define   PIPEB_HLINE_INT_EN                  (1<<28)
  #define   PIPEB_VBLANK_INT_EN                 (1<<27)
  #define   SPRITED_FLIPDONE_INT_EN             (1<<26)
  #define   SPRITEC_FLIPDONE_INT_EN             (1<<25)
  #define   PLANEB_FLIPDONE_INT_EN              (1<<24)
 -#define   PIPEA_LINE_COMPARE_STATUS           (1<<21)
 +#define   PIPEA_LINE_COMPARE_INT_EN           (1<<21)
  #define   PIPEA_HLINE_INT_EN                  (1<<20)
  #define   PIPEA_VBLANK_INT_EN                 (1<<19)
  #define   SPRITEB_FLIPDONE_INT_EN             (1<<18)
  
  /* PCH */
  
- /* south display engine interrupt */
+ /* south display engine interrupt: IBX */
  #define SDE_AUDIO_POWER_D     (1 << 27)
  #define SDE_AUDIO_POWER_C     (1 << 26)
  #define SDE_AUDIO_POWER_B     (1 << 25)
  #define SDE_TRANSA_CRC_ERR    (1 << 1)
  #define SDE_TRANSA_FIFO_UNDER (1 << 0)
  #define SDE_TRANS_MASK                (0x3f)
- /* CPT */
- #define SDE_CRT_HOTPLUG_CPT   (1 << 19)
+ /* south display engine interrupt: CPT/PPT */
+ #define SDE_AUDIO_POWER_D_CPT (1 << 31)
+ #define SDE_AUDIO_POWER_C_CPT (1 << 30)
+ #define SDE_AUDIO_POWER_B_CPT (1 << 29)
+ #define SDE_AUDIO_POWER_SHIFT_CPT   29
+ #define SDE_AUDIO_POWER_MASK_CPT    (7 << 29)
+ #define SDE_AUXD_CPT          (1 << 27)
+ #define SDE_AUXC_CPT          (1 << 26)
+ #define SDE_AUXB_CPT          (1 << 25)
+ #define SDE_AUX_MASK_CPT      (7 << 25)
  #define SDE_PORTD_HOTPLUG_CPT (1 << 23)
  #define SDE_PORTC_HOTPLUG_CPT (1 << 22)
  #define SDE_PORTB_HOTPLUG_CPT (1 << 21)
+ #define SDE_CRT_HOTPLUG_CPT   (1 << 19)
  #define SDE_HOTPLUG_MASK_CPT  (SDE_CRT_HOTPLUG_CPT |          \
                                 SDE_PORTD_HOTPLUG_CPT |        \
                                 SDE_PORTC_HOTPLUG_CPT |        \
                                 SDE_PORTB_HOTPLUG_CPT)
+ #define SDE_GMBUS_CPT         (1 << 17)
+ #define SDE_AUDIO_CP_REQ_C_CPT        (1 << 10)
+ #define SDE_AUDIO_CP_CHG_C_CPT        (1 << 9)
+ #define SDE_FDI_RXC_CPT               (1 << 8)
+ #define SDE_AUDIO_CP_REQ_B_CPT        (1 << 6)
+ #define SDE_AUDIO_CP_CHG_B_CPT        (1 << 5)
+ #define SDE_FDI_RXB_CPT               (1 << 4)
+ #define SDE_AUDIO_CP_REQ_A_CPT        (1 << 2)
+ #define SDE_AUDIO_CP_CHG_A_CPT        (1 << 1)
+ #define SDE_FDI_RXA_CPT               (1 << 0)
+ #define SDE_AUDIO_CP_REQ_CPT  (SDE_AUDIO_CP_REQ_C_CPT | \
+                                SDE_AUDIO_CP_REQ_B_CPT | \
+                                SDE_AUDIO_CP_REQ_A_CPT)
+ #define SDE_AUDIO_CP_CHG_CPT  (SDE_AUDIO_CP_CHG_C_CPT | \
+                                SDE_AUDIO_CP_CHG_B_CPT | \
+                                SDE_AUDIO_CP_CHG_A_CPT)
+ #define SDE_FDI_MASK_CPT      (SDE_FDI_RXC_CPT | \
+                                SDE_FDI_RXB_CPT | \
+                                SDE_FDI_RXA_CPT)
  
  #define SDEISR  0xc4000
  #define SDEIMR  0xc4004
  #define  ADPA_CRT_HOTPLUG_FORCE_TRIGGER (1<<16)
  
  /* or SDVOB */
 -#define VLV_HDMIB 0x61140
  #define HDMIB   0xe1140
  #define  PORT_ENABLE    (1 << 31)
  #define  TRANSCODER(pipe)       ((pipe) << 30)
  #define PCH_LVDS      0xe1180
  #define  LVDS_DETECTED        (1 << 1)
  
 -#define BLC_PWM_CPU_CTL2      0x48250
 -#define  PWM_ENABLE           (1 << 31)
 -#define  PWM_PIPE_A           (0 << 29)
 -#define  PWM_PIPE_B           (1 << 29)
 -#define BLC_PWM_CPU_CTL               0x48254
 -
 -#define BLC_PWM_PCH_CTL1      0xc8250
 -#define  PWM_PCH_ENABLE               (1 << 31)
 -#define  PWM_POLARITY_ACTIVE_LOW      (1 << 29)
 -#define  PWM_POLARITY_ACTIVE_HIGH     (0 << 29)
 -#define  PWM_POLARITY_ACTIVE_LOW2     (1 << 28)
 -#define  PWM_POLARITY_ACTIVE_HIGH2    (0 << 28)
 +/* vlv has 2 sets of panel control regs. */
 +#define PIPEA_PP_STATUS         0x61200
 +#define PIPEA_PP_CONTROL        0x61204
 +#define PIPEA_PP_ON_DELAYS      0x61208
 +#define PIPEA_PP_OFF_DELAYS     0x6120c
 +#define PIPEA_PP_DIVISOR        0x61210
  
 -#define BLC_PWM_PCH_CTL2      0xc8254
 +#define PIPEB_PP_STATUS         0x61300
 +#define PIPEB_PP_CONTROL        0x61304
 +#define PIPEB_PP_ON_DELAYS      0x61308
 +#define PIPEB_PP_OFF_DELAYS     0x6130c
 +#define PIPEB_PP_DIVISOR        0x61310
  
  #define PCH_PP_STATUS         0xc7200
  #define PCH_PP_CONTROL                0xc7204
  # define GEN6_CSUNIT_CLOCK_GATE_DISABLE                       (1 << 7)
  
  #define GEN6_UCGCTL2                          0x9404
 +# define GEN7_VDSUNIT_CLOCK_GATE_DISABLE              (1 << 30)
 +# define GEN7_TDLUNIT_CLOCK_GATE_DISABLE              (1 << 22)
  # define GEN6_RCZUNIT_CLOCK_GATE_DISABLE              (1 << 13)
  # define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE             (1 << 12)
  # define GEN6_RCCUNIT_CLOCK_GATE_DISABLE              (1 << 11)
  
 +#define GEN7_UCGCTL4                          0x940c
 +#define  GEN7_L3BANK2X_CLOCK_GATE_DISABLE     (1<<25)
 +
  #define GEN6_RPNSWREQ                         0xA008
  #define   GEN6_TURBO_DISABLE                  (1<<31)
  #define   GEN6_FREQUENCY(x)                   ((x)<<25)
  #define   GEN6_RC6                    3
  #define   GEN6_RC7                    4
  
 +#define GEN7_MISCCPCTL                        (0x9424)
 +#define   GEN7_DOP_CLOCK_GATE_ENABLE  (1<<0)
 +
 +/* IVYBRIDGE DPF */
 +#define GEN7_L3CDERRST1                       0xB008 /* L3CD Error Status 1 */
 +#define   GEN7_L3CDERRST1_ROW_MASK    (0x7ff<<14)
 +#define   GEN7_PARITY_ERROR_VALID     (1<<13)
 +#define   GEN7_L3CDERRST1_BANK_MASK   (3<<11)
 +#define   GEN7_L3CDERRST1_SUBBANK_MASK        (7<<8)
 +#define GEN7_PARITY_ERROR_ROW(reg) \
 +              ((reg & GEN7_L3CDERRST1_ROW_MASK) >> 14)
 +#define GEN7_PARITY_ERROR_BANK(reg) \
 +              ((reg & GEN7_L3CDERRST1_BANK_MASK) >> 11)
 +#define GEN7_PARITY_ERROR_SUBBANK(reg) \
 +              ((reg & GEN7_L3CDERRST1_SUBBANK_MASK) >> 8)
 +#define   GEN7_L3CDERRST1_ENABLE      (1<<7)
 +
 +#define GEN7_L3LOG_BASE                       0xB070
 +#define GEN7_L3LOG_SIZE                       0x80
 +
  #define G4X_AUD_VID_DID                       0x62020
  #define INTEL_AUDIO_DEVCL             0x808629FB
  #define INTEL_AUDIO_DEVBLC            0x80862801
index 06721c0e9f98fdf5fcd9cfa1665da26595efb0a6,a7c727d0c1050d1669bd602d40ab3a517b52f8b2..b3052ef70d16dfc9a0cac0d8a391a1afb68a100f
@@@ -98,11 -98,6 +98,11 @@@ intel_find_pll_ironlake_dp(const intel_
                           int target, int refclk, intel_clock_t *match_clock,
                           intel_clock_t *best_clock);
  
 +static bool
 +intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc,
 +                      int target, int refclk, intel_clock_t *match_clock,
 +                      intel_clock_t *best_clock);
 +
  static inline u32 /* units of 100MHz */
  intel_fdi_link_freq(struct drm_device *dev)
  {
@@@ -364,48 -359,6 +364,48 @@@ static const intel_limit_t intel_limits
        .find_pll = intel_find_pll_ironlake_dp,
  };
  
 +static const intel_limit_t intel_limits_vlv_dac = {
 +      .dot = { .min = 25000, .max = 270000 },
 +      .vco = { .min = 4000000, .max = 6000000 },
 +      .n = { .min = 1, .max = 7 },
 +      .m = { .min = 22, .max = 450 }, /* guess */
 +      .m1 = { .min = 2, .max = 3 },
 +      .m2 = { .min = 11, .max = 156 },
 +      .p = { .min = 10, .max = 30 },
 +      .p1 = { .min = 2, .max = 3 },
 +      .p2 = { .dot_limit = 270000,
 +              .p2_slow = 2, .p2_fast = 20 },
 +      .find_pll = intel_vlv_find_best_pll,
 +};
 +
 +static const intel_limit_t intel_limits_vlv_hdmi = {
 +      .dot = { .min = 20000, .max = 165000 },
 +      .vco = { .min = 5994000, .max = 4000000 },
 +      .n = { .min = 1, .max = 7 },
 +      .m = { .min = 60, .max = 300 }, /* guess */
 +      .m1 = { .min = 2, .max = 3 },
 +      .m2 = { .min = 11, .max = 156 },
 +      .p = { .min = 10, .max = 30 },
 +      .p1 = { .min = 2, .max = 3 },
 +      .p2 = { .dot_limit = 270000,
 +              .p2_slow = 2, .p2_fast = 20 },
 +      .find_pll = intel_vlv_find_best_pll,
 +};
 +
 +static const intel_limit_t intel_limits_vlv_dp = {
 +      .dot = { .min = 162000, .max = 270000 },
 +      .vco = { .min = 5994000, .max = 4000000 },
 +      .n = { .min = 1, .max = 7 },
 +      .m = { .min = 60, .max = 300 }, /* guess */
 +      .m1 = { .min = 2, .max = 3 },
 +      .m2 = { .min = 11, .max = 156 },
 +      .p = { .min = 10, .max = 30 },
 +      .p1 = { .min = 2, .max = 3 },
 +      .p2 = { .dot_limit = 270000,
 +              .p2_slow = 2, .p2_fast = 20 },
 +      .find_pll = intel_vlv_find_best_pll,
 +};
 +
  u32 intel_dpio_read(struct drm_i915_private *dev_priv, int reg)
  {
        unsigned long flags;
@@@ -431,28 -384,6 +431,28 @@@ out_unlock
        return val;
  }
  
 +static void intel_dpio_write(struct drm_i915_private *dev_priv, int reg,
 +                           u32 val)
 +{
 +      unsigned long flags;
 +
 +      spin_lock_irqsave(&dev_priv->dpio_lock, flags);
 +      if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) {
 +              DRM_ERROR("DPIO idle wait timed out\n");
 +              goto out_unlock;
 +      }
 +
 +      I915_WRITE(DPIO_DATA, val);
 +      I915_WRITE(DPIO_REG, reg);
 +      I915_WRITE(DPIO_PKT, DPIO_RID | DPIO_OP_WRITE | DPIO_PORTID |
 +                 DPIO_BYTE);
 +      if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100))
 +              DRM_ERROR("DPIO write wait timed out\n");
 +
 +out_unlock:
 +       spin_unlock_irqrestore(&dev_priv->dpio_lock, flags);
 +}
 +
  static void vlv_init_dpio(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
@@@ -503,7 -434,7 +503,7 @@@ static bool is_dual_link_lvds(struct dr
                 * register is uninitialized.
                 */
                val = I915_READ(reg);
 -              if (!(val & ~LVDS_DETECTED))
 +              if (!(val & ~(LVDS_PIPE_MASK | LVDS_DETECTED)))
                        val = dev_priv->bios_lvds_val;
                dev_priv->lvds_val = val;
        }
@@@ -579,13 -510,6 +579,13 @@@ static const intel_limit_t *intel_limit
                        limit = &intel_limits_pineview_lvds;
                else
                        limit = &intel_limits_pineview_sdvo;
 +      } else if (IS_VALLEYVIEW(dev)) {
 +              if (intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG))
 +                      limit = &intel_limits_vlv_dac;
 +              else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI))
 +                      limit = &intel_limits_vlv_hdmi;
 +              else
 +                      limit = &intel_limits_vlv_dp;
        } else if (!IS_GEN2(dev)) {
                if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
                        limit = &intel_limits_i9xx_lvds;
@@@ -859,73 -783,6 +859,73 @@@ intel_find_pll_g4x_dp(const intel_limit
        memcpy(best_clock, &clock, sizeof(intel_clock_t));
        return true;
  }
 +static bool
 +intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc,
 +                      int target, int refclk, intel_clock_t *match_clock,
 +                      intel_clock_t *best_clock)
 +{
 +      u32 p1, p2, m1, m2, vco, bestn, bestm1, bestm2, bestp1, bestp2;
 +      u32 m, n, fastclk;
 +      u32 updrate, minupdate, fracbits, p;
 +      unsigned long bestppm, ppm, absppm;
 +      int dotclk, flag;
 +
 +      dotclk = target * 1000;
 +      bestppm = 1000000;
 +      ppm = absppm = 0;
 +      fastclk = dotclk / (2*100);
 +      updrate = 0;
 +      minupdate = 19200;
 +      fracbits = 1;
 +      n = p = p1 = p2 = m = m1 = m2 = vco = bestn = 0;
 +      bestm1 = bestm2 = bestp1 = bestp2 = 0;
 +
 +      /* based on hardware requirement, prefer smaller n to precision */
 +      for (n = limit->n.min; n <= ((refclk) / minupdate); n++) {
 +              updrate = refclk / n;
 +              for (p1 = limit->p1.max; p1 > limit->p1.min; p1--) {
 +                      for (p2 = limit->p2.p2_fast+1; p2 > 0; p2--) {
 +                              if (p2 > 10)
 +                                      p2 = p2 - 1;
 +                              p = p1 * p2;
 +                              /* based on hardware requirement, prefer bigger m1,m2 values */
 +                              for (m1 = limit->m1.min; m1 <= limit->m1.max; m1++) {
 +                                      m2 = (((2*(fastclk * p * n / m1 )) +
 +                                             refclk) / (2*refclk));
 +                                      m = m1 * m2;
 +                                      vco = updrate * m;
 +                                      if (vco >= limit->vco.min && vco < limit->vco.max) {
 +                                              ppm = 1000000 * ((vco / p) - fastclk) / fastclk;
 +                                              absppm = (ppm > 0) ? ppm : (-ppm);
 +                                              if (absppm < 100 && ((p1 * p2) > (bestp1 * bestp2))) {
 +                                                      bestppm = 0;
 +                                                      flag = 1;
 +                                              }
 +                                              if (absppm < bestppm - 10) {
 +                                                      bestppm = absppm;
 +                                                      flag = 1;
 +                                              }
 +                                              if (flag) {
 +                                                      bestn = n;
 +                                                      bestm1 = m1;
 +                                                      bestm2 = m2;
 +                                                      bestp1 = p1;
 +                                                      bestp2 = p2;
 +                                                      flag = 0;
 +                                              }
 +                                      }
 +                              }
 +                      }
 +              }
 +      }
 +      best_clock->n = bestn;
 +      best_clock->m1 = bestm1;
 +      best_clock->m2 = bestm2;
 +      best_clock->p1 = bestp1;
 +      best_clock->p2 = bestp2;
 +
 +      return true;
 +}
  
  static void ironlake_wait_for_vblank(struct drm_device *dev, int pipe)
  {
@@@ -1375,9 -1232,6 +1375,9 @@@ static void assert_pch_dp_disabled(stru
        WARN(dp_pipe_enabled(dev_priv, pipe, port_sel, val),
             "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n",
             reg, pipe_name(pipe));
 +
 +      WARN(HAS_PCH_IBX(dev_priv->dev) && (val & SDVO_PIPE_B_SELECT),
 +           "IBX PCH dp port still using transcoder B\n");
  }
  
  static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv,
        WARN(hdmi_pipe_enabled(dev_priv, val, pipe),
             "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n",
             reg, pipe_name(pipe));
 +
 +      WARN(HAS_PCH_IBX(dev_priv->dev) && (val & SDVO_PIPE_B_SELECT),
 +           "IBX PCH hdmi port still using transcoder B\n");
  }
  
  static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,
@@@ -1436,7 -1287,7 +1436,7 @@@ static void intel_enable_pll(struct drm
        u32 val;
  
        /* No really, not for ILK+ */
 -      BUG_ON(dev_priv->info->gen >= 5);
 +      BUG_ON(!IS_VALLEYVIEW(dev_priv->dev) && dev_priv->info->gen >= 5);
  
        /* PLL is protected by panel, make sure we can write it */
        if (IS_MOBILE(dev_priv->dev) && !IS_I830(dev_priv->dev))
@@@ -1493,7 -1344,7 +1493,7 @@@ intel_sbi_write(struct drm_i915_privat
        unsigned long flags;
  
        spin_lock_irqsave(&dev_priv->dpio_lock, flags);
 -      if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_READY) == 0,
 +      if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0,
                                100)) {
                DRM_ERROR("timeout waiting for SBI to become ready\n");
                goto out_unlock;
                        SBI_BUSY |
                        SBI_CTL_OP_CRWR);
  
 -      if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_READY | SBI_RESPONSE_SUCCESS)) == 0,
 +      if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0,
                                100)) {
                DRM_ERROR("timeout waiting for SBI to complete write transaction\n");
                goto out_unlock;
@@@ -1521,10 -1372,10 +1521,10 @@@ static u3
  intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg)
  {
        unsigned long flags;
 -      u32 value;
 +      u32 value = 0;
  
        spin_lock_irqsave(&dev_priv->dpio_lock, flags);
 -      if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_READY) == 0,
 +      if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0,
                                100)) {
                DRM_ERROR("timeout waiting for SBI to become ready\n");
                goto out_unlock;
                        SBI_BUSY |
                        SBI_CTL_OP_CRRD);
  
 -      if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_READY | SBI_RESPONSE_SUCCESS)) == 0,
 +      if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0,
                                100)) {
                DRM_ERROR("timeout waiting for SBI to complete read transaction\n");
                goto out_unlock;
@@@ -3815,37 -3666,13 +3815,37 @@@ static bool intel_choose_pipe_bpp_dithe
        return display_bpc != bpc;
  }
  
 +static int vlv_get_refclk(struct drm_crtc *crtc)
 +{
 +      struct drm_device *dev = crtc->dev;
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +      int refclk = 27000; /* for DP & HDMI */
 +
 +      return 100000; /* only one validated so far */
 +
 +      if (intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) {
 +              refclk = 96000;
 +      } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
 +              if (intel_panel_use_ssc(dev_priv))
 +                      refclk = 100000;
 +              else
 +                      refclk = 96000;
 +      } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) {
 +              refclk = 100000;
 +      }
 +
 +      return refclk;
 +}
 +
  static int i9xx_get_refclk(struct drm_crtc *crtc, int num_connectors)
  {
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        int refclk;
  
 -      if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
 +      if (IS_VALLEYVIEW(dev)) {
 +              refclk = vlv_get_refclk(crtc);
 +      } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
            intel_panel_use_ssc(dev_priv) && num_connectors < 2) {
                refclk = dev_priv->lvds_ssc_freq * 1000;
                DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n",
@@@ -3960,72 -3787,6 +3960,72 @@@ static void intel_update_lvds(struct dr
        I915_WRITE(LVDS, temp);
  }
  
 +static void vlv_update_pll(struct drm_crtc *crtc,
 +                         struct drm_display_mode *mode,
 +                         struct drm_display_mode *adjusted_mode,
 +                         intel_clock_t *clock, intel_clock_t *reduced_clock,
 +                         int refclk, int num_connectors)
 +{
 +      struct drm_device *dev = crtc->dev;
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 +      int pipe = intel_crtc->pipe;
 +      u32 dpll, mdiv, pdiv;
 +      u32 bestn, bestm1, bestm2, bestp1, bestp2;
 +      bool is_hdmi;
 +
 +      is_hdmi = intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI);
 +
 +      bestn = clock->n;
 +      bestm1 = clock->m1;
 +      bestm2 = clock->m2;
 +      bestp1 = clock->p1;
 +      bestp2 = clock->p2;
 +
 +      /* Enable DPIO clock input */
 +      dpll = DPLL_EXT_BUFFER_ENABLE_VLV | DPLL_REFA_CLK_ENABLE_VLV |
 +              DPLL_VGA_MODE_DIS | DPLL_INTEGRATED_CLOCK_VLV;
 +      I915_WRITE(DPLL(pipe), dpll);
 +      POSTING_READ(DPLL(pipe));
 +
 +      mdiv = ((bestm1 << DPIO_M1DIV_SHIFT) | (bestm2 & DPIO_M2DIV_MASK));
 +      mdiv |= ((bestp1 << DPIO_P1_SHIFT) | (bestp2 << DPIO_P2_SHIFT));
 +      mdiv |= ((bestn << DPIO_N_SHIFT));
 +      mdiv |= (1 << DPIO_POST_DIV_SHIFT);
 +      mdiv |= (1 << DPIO_K_SHIFT);
 +      mdiv |= DPIO_ENABLE_CALIBRATION;
 +      intel_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv);
 +
 +      intel_dpio_write(dev_priv, DPIO_CORE_CLK(pipe), 0x01000000);
 +
 +      pdiv = DPIO_REFSEL_OVERRIDE | (5 << DPIO_PLL_MODESEL_SHIFT) |
 +              (3 << DPIO_BIAS_CURRENT_CTL_SHIFT) | (1<<20) |
 +              (8 << DPIO_DRIVER_CTL_SHIFT) | (5 << DPIO_CLK_BIAS_CTL_SHIFT);
 +      intel_dpio_write(dev_priv, DPIO_REFSFR(pipe), pdiv);
 +
 +      intel_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe), 0x009f0051);
 +
 +      dpll |= DPLL_VCO_ENABLE;
 +      I915_WRITE(DPLL(pipe), dpll);
 +      POSTING_READ(DPLL(pipe));
 +      if (wait_for(((I915_READ(DPLL(pipe)) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1))
 +              DRM_ERROR("DPLL %d failed to lock\n", pipe);
 +
 +      if (is_hdmi) {
 +              u32 temp = intel_mode_get_pixel_multiplier(adjusted_mode);
 +
 +              if (temp > 1)
 +                      temp = (temp - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT;
 +              else
 +                      temp = 0;
 +
 +              I915_WRITE(DPLL_MD(pipe), temp);
 +              POSTING_READ(DPLL_MD(pipe));
 +      }
 +
 +      intel_dpio_write(dev_priv, DPIO_FASTCLK_DISABLE, 0x641); /* ??? */
 +}
 +
  static void i9xx_update_pll(struct drm_crtc *crtc,
                            struct drm_display_mode *mode,
                            struct drm_display_mode *adjusted_mode,
@@@ -4283,9 -4044,6 +4283,9 @@@ static int i9xx_crtc_mode_set(struct dr
  
        if (IS_GEN2(dev))
                i8xx_update_pll(crtc, adjusted_mode, &clock, num_connectors);
 +      else if (IS_VALLEYVIEW(dev))
 +              vlv_update_pll(crtc, mode,adjusted_mode, &clock, NULL,
 +                             refclk, num_connectors);
        else
                i9xx_update_pll(crtc, mode, adjusted_mode, &clock,
                                has_reduced_clock ? &reduced_clock : NULL,
@@@ -4647,10 -4405,25 +4647,10 @@@ static int ironlake_crtc_mode_set(struc
                                                    &clock,
                                                    &reduced_clock);
        }
 -      /* SDVO TV has fixed PLL values depend on its clock range,
 -         this mirrors vbios setting. */
 -      if (is_sdvo && is_tv) {
 -              if (adjusted_mode->clock >= 100000
 -                  && adjusted_mode->clock < 140500) {
 -                      clock.p1 = 2;
 -                      clock.p2 = 10;
 -                      clock.n = 3;
 -                      clock.m1 = 16;
 -                      clock.m2 = 8;
 -              } else if (adjusted_mode->clock >= 140500
 -                         && adjusted_mode->clock <= 200000) {
 -                      clock.p1 = 1;
 -                      clock.p2 = 10;
 -                      clock.n = 6;
 -                      clock.m1 = 12;
 -                      clock.m2 = 8;
 -              }
 -      }
 +
 +      if (is_sdvo && is_tv)
 +              i9xx_adjust_sdvo_tv_clock(adjusted_mode, &clock);
 +
  
        /* FDI link */
        pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
        /* CPU eDP doesn't require FDI link, so just set DP M/N
           according to current link config */
        if (is_cpu_edp) {
 -              target_clock = mode->clock;
                intel_edp_link_config(edp_encoder, &lane, &link_bw);
        } else {
 -              /* [e]DP over FDI requires target mode clock
 -                 instead of link clock */
 -              if (is_dp)
 -                      target_clock = mode->clock;
 -              else
 -                      target_clock = adjusted_mode->clock;
 -
                /* FDI is a binary signal running at ~2.7GHz, encoding
                 * each output octet as 10 bits. The actual frequency
                 * is stored as a divider into a 100MHz clock, and the
                link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10;
        }
  
 +      /* [e]DP over FDI requires target mode clock instead of link clock. */
 +      if (edp_encoder)
 +              target_clock = intel_edp_target_clock(edp_encoder, mode);
 +      else if (is_dp)
 +              target_clock = mode->clock;
 +      else
 +              target_clock = adjusted_mode->clock;
 +
        /* determine panel color depth */
        temp = I915_READ(PIPECONF(pipe));
        temp &= ~PIPE_BPC_MASK;
                if (is_lvds && has_reduced_clock && i915_powersave) {
                        I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp2);
                        intel_crtc->lowfreq_avail = true;
 -                      if (HAS_PIPE_CXSR(dev)) {
 -                              DRM_DEBUG_KMS("enabling CxSR downclocking\n");
 -                              pipeconf |= PIPECONF_CXSR_DOWNCLOCK;
 -                      }
                } else {
                        I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp);
 -                      if (HAS_PIPE_CXSR(dev)) {
 -                              DRM_DEBUG_KMS("disabling CxSR downclocking\n");
 -                              pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK;
 -                      }
                }
        }
  
@@@ -6377,17 -6158,34 +6377,34 @@@ static int intel_gen7_queue_flip(struc
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        struct intel_ring_buffer *ring = &dev_priv->ring[BCS];
+       uint32_t plane_bit = 0;
        int ret;
  
        ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
        if (ret)
                goto err;
  
+       switch(intel_crtc->plane) {
+       case PLANE_A:
+               plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_A;
+               break;
+       case PLANE_B:
+               plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_B;
+               break;
+       case PLANE_C:
+               plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_C;
+               break;
+       default:
+               WARN_ONCE(1, "unknown plane in flip command\n");
+               ret = -ENODEV;
+               goto err;
+       }
        ret = intel_ring_begin(ring, 4);
        if (ret)
                goto err_unpin;
  
-       intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | (intel_crtc->plane << 19));
+       intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane_bit);
        intel_ring_emit(ring, (fb->pitches[0] | obj->tiling_mode));
        intel_ring_emit(ring, (obj->gtt_offset));
        intel_ring_emit(ring, (MI_NOOP));
@@@ -6760,7 -6558,7 +6777,7 @@@ static void intel_setup_outputs(struct 
                if (I915_READ(HDMIC) & PORT_DETECTED)
                        intel_hdmi_init(dev, HDMIC);
  
-               if (I915_READ(HDMID) & PORT_DETECTED)
+               if (!dpd_is_edp && I915_READ(HDMID) & PORT_DETECTED)
                        intel_hdmi_init(dev, HDMID);
  
                if (I915_READ(PCH_DP_C) & DP_DETECTED)
  
                if (!dpd_is_edp && (I915_READ(PCH_DP_D) & DP_DETECTED))
                        intel_dp_init(dev, PCH_DP_D);
 +      } else if (IS_VALLEYVIEW(dev)) {
 +              int found;
 +
 +              if (I915_READ(SDVOB) & PORT_DETECTED) {
 +                      /* SDVOB multiplex with HDMIB */
 +                      found = intel_sdvo_init(dev, SDVOB, true);
 +                      if (!found)
 +                              intel_hdmi_init(dev, SDVOB);
 +                      if (!found && (I915_READ(DP_B) & DP_DETECTED))
 +                              intel_dp_init(dev, DP_B);
 +              }
 +
 +              if (I915_READ(SDVOC) & PORT_DETECTED)
 +                      intel_hdmi_init(dev, SDVOC);
  
 +              /* Shares lanes with HDMI on SDVOC */
 +              if (I915_READ(DP_C) & DP_DETECTED)
 +                      intel_dp_init(dev, DP_C);
        } else if (SUPPORTS_DIGITAL_OUTPUTS(dev)) {
                bool found = false;
  
@@@ -7148,9 -6929,9 +7165,9 @@@ static void ivb_pch_pwm_override(struc
         * IVB has CPU eDP backlight regs too, set things up to let the
         * PCH regs control the backlight
         */
 -      I915_WRITE(BLC_PWM_CPU_CTL2, PWM_ENABLE);
 +      I915_WRITE(BLC_PWM_CPU_CTL2, BLM_PWM_ENABLE);
        I915_WRITE(BLC_PWM_CPU_CTL, 0);
 -      I915_WRITE(BLC_PWM_PCH_CTL1, PWM_ENABLE | (1<<30));
 +      I915_WRITE(BLC_PWM_PCH_CTL1, BLM_PCH_PWM_ENABLE | BLM_PCH_OVERRIDE_ENABLE);
  }
  
  void intel_modeset_init_hw(struct drm_device *dev)
@@@ -7207,7 -6988,7 +7224,7 @@@ void intel_modeset_init(struct drm_devi
                dev->mode_config.max_width = 8192;
                dev->mode_config.max_height = 8192;
        }
 -      dev->mode_config.fb_base = dev->agp->base;
 +      dev->mode_config.fb_base = dev_priv->mm.gtt_base_addr;
  
        DRM_DEBUG_KMS("%d display pipe%s available.\n",
                      dev_priv->num_pipe, dev_priv->num_pipe > 1 ? "s" : "");
index 6538c46fe9598c967311bff3227002c90f4f0658,c0449324143cb62f1ecd837e042f28af39682d77..76a708029dcb9fb94abaf5c13b75c633df474c04
@@@ -32,6 -32,7 +32,7 @@@
  #include "drm.h"
  #include "drm_crtc.h"
  #include "drm_crtc_helper.h"
+ #include "drm_edid.h"
  #include "intel_drv.h"
  #include "i915_drm.h"
  #include "i915_drv.h"
@@@ -67,6 -68,8 +68,8 @@@ struct intel_dp 
        struct drm_display_mode *panel_fixed_mode;  /* for eDP */
        struct delayed_work panel_vdd_work;
        bool want_panel_vdd;
+       struct edid *edid; /* cached EDID for eDP */
+       int edid_mode_count;
  };
  
  /**
@@@ -152,18 -155,6 +155,18 @@@ intel_edp_link_config(struct intel_enco
                *link_bw = 270000;
  }
  
 +int
 +intel_edp_target_clock(struct intel_encoder *intel_encoder,
 +                     struct drm_display_mode *mode)
 +{
 +      struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base);
 +
 +      if (intel_dp->panel_fixed_mode)
 +              return intel_dp->panel_fixed_mode->clock;
 +      else
 +              return mode->clock;
 +}
 +
  static int
  intel_dp_max_lane_count(struct intel_dp *intel_dp)
  {
@@@ -234,7 -225,7 +237,7 @@@ intel_dp_max_data_rate(int max_link_clo
  static bool
  intel_dp_adjust_dithering(struct intel_dp *intel_dp,
                          struct drm_display_mode *mode,
 -                        struct drm_display_mode *adjusted_mode)
 +                        bool adjust_mode)
  {
        int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp));
        int max_lanes = intel_dp_max_lane_count(intel_dp);
                if (mode_rate > max_rate)
                        return false;
  
 -              if (adjusted_mode)
 -                      adjusted_mode->private_flags
 +              if (adjust_mode)
 +                      mode->private_flags
                                |= INTEL_MODE_DP_FORCE_6BPC;
  
                return true;
@@@ -272,7 -263,7 +275,7 @@@ intel_dp_mode_valid(struct drm_connecto
                        return MODE_PANEL;
        }
  
 -      if (!intel_dp_adjust_dithering(intel_dp, mode, NULL))
 +      if (!intel_dp_adjust_dithering(intel_dp, mode, false))
                return MODE_CLOCK_HIGH;
  
        if (mode->clock < 10000)
@@@ -383,7 -374,7 +386,7 @@@ intel_dp_aux_ch(struct intel_dp *intel_
        int recv_bytes;
        uint32_t status;
        uint32_t aux_clock_divider;
-       int try, precharge = 5;
+       int try, precharge;
  
        intel_dp_check_edp(intel_dp);
        /* The clock divider is based off the hrawclk,
        else
                aux_clock_divider = intel_hrawclk(dev) / 2;
  
+       if (IS_GEN6(dev))
+               precharge = 3;
+       else
+               precharge = 5;
        /* Try to wait for any previous AUX channel activity */
        for (try = 0; try < 3; try++) {
                status = I915_READ(ch_ctl);
@@@ -710,20 -706,25 +718,20 @@@ intel_dp_mode_fixup(struct drm_encoder 
                intel_fixed_panel_mode(intel_dp->panel_fixed_mode, adjusted_mode);
                intel_pch_panel_fitting(dev, DRM_MODE_SCALE_FULLSCREEN,
                                        mode, adjusted_mode);
 -              /*
 -               * the mode->clock is used to calculate the Data&Link M/N
 -               * of the pipe. For the eDP the fixed clock should be used.
 -               */
 -              mode->clock = intel_dp->panel_fixed_mode->clock;
        }
  
 -      if (mode->flags & DRM_MODE_FLAG_DBLCLK)
 +      if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
                return false;
  
        DRM_DEBUG_KMS("DP link computation with max lane count %i "
                      "max bw %02x pixel clock %iKHz\n",
 -                    max_lane_count, bws[max_clock], mode->clock);
 +                    max_lane_count, bws[max_clock], adjusted_mode->clock);
  
 -      if (!intel_dp_adjust_dithering(intel_dp, mode, adjusted_mode))
 +      if (!intel_dp_adjust_dithering(intel_dp, adjusted_mode, true))
                return false;
  
        bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24;
 -      mode_rate = intel_dp_link_required(mode->clock, bpp);
 +      mode_rate = intel_dp_link_required(adjusted_mode->clock, bpp);
  
        for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
                for (clock = 0; clock <= max_clock; clock++) {
@@@ -1921,7 -1922,7 +1929,7 @@@ intel_dp_link_down(struct intel_dp *int
                        DP |= DP_LINK_TRAIN_OFF;
        }
  
 -      if (!HAS_PCH_CPT(dev) &&
 +      if (HAS_PCH_IBX(dev) &&
            I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) {
                struct drm_crtc *crtc = intel_dp->base.base.crtc;
  
@@@ -1980,6 -1981,8 +1988,8 @@@ intel_dp_probe_oui(struct intel_dp *int
        if (!(intel_dp->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT))
                return;
  
+       ironlake_edp_panel_vdd_on(intel_dp);
        if (intel_dp_aux_native_read_retry(intel_dp, DP_SINK_OUI, buf, 3))
                DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n",
                              buf[0], buf[1], buf[2]);
        if (intel_dp_aux_native_read_retry(intel_dp, DP_BRANCH_OUI, buf, 3))
                DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n",
                              buf[0], buf[1], buf[2]);
+       ironlake_edp_panel_vdd_off(intel_dp, false);
  }
  
  static bool
@@@ -2094,23 -2099,25 +2106,23 @@@ g4x_dp_detect(struct intel_dp *intel_dp
  {
        struct drm_device *dev = intel_dp->base.base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
 -      uint32_t temp, bit;
 +      uint32_t bit;
  
        switch (intel_dp->output_reg) {
        case DP_B:
 -              bit = DPB_HOTPLUG_INT_STATUS;
 +              bit = DPB_HOTPLUG_LIVE_STATUS;
                break;
        case DP_C:
 -              bit = DPC_HOTPLUG_INT_STATUS;
 +              bit = DPC_HOTPLUG_LIVE_STATUS;
                break;
        case DP_D:
 -              bit = DPD_HOTPLUG_INT_STATUS;
 +              bit = DPD_HOTPLUG_LIVE_STATUS;
                break;
        default:
                return connector_status_unknown;
        }
  
 -      temp = I915_READ(PORT_HOTPLUG_STAT);
 -
 -      if ((temp & bit) == 0)
 +      if ((I915_READ(PORT_HOTPLUG_STAT) & bit) == 0)
                return connector_status_disconnected;
  
        return intel_dp_detect_dpcd(intel_dp);
@@@ -2121,10 -2128,22 +2133,22 @@@ intel_dp_get_edid(struct drm_connector 
  {
        struct intel_dp *intel_dp = intel_attached_dp(connector);
        struct edid     *edid;
+       int size;
+       if (is_edp(intel_dp)) {
+               if (!intel_dp->edid)
+                       return NULL;
+               size = (intel_dp->edid->extensions + 1) * EDID_LENGTH;
+               edid = kmalloc(size, GFP_KERNEL);
+               if (!edid)
+                       return NULL;
+               memcpy(edid, intel_dp->edid, size);
+               return edid;
+       }
  
-       ironlake_edp_panel_vdd_on(intel_dp);
        edid = drm_get_edid(connector, adapter);
-       ironlake_edp_panel_vdd_off(intel_dp, false);
        return edid;
  }
  
@@@ -2134,9 -2153,17 +2158,17 @@@ intel_dp_get_edid_modes(struct drm_conn
        struct intel_dp *intel_dp = intel_attached_dp(connector);
        int     ret;
  
-       ironlake_edp_panel_vdd_on(intel_dp);
+       if (is_edp(intel_dp)) {
+               drm_mode_connector_update_edid_property(connector,
+                                                       intel_dp->edid);
+               ret = drm_add_edid_modes(connector, intel_dp->edid);
+               drm_edid_to_eld(connector,
+                               intel_dp->edid);
+               connector->display_info.raw_edid = NULL;
+               return intel_dp->edid_mode_count;
+       }
        ret = intel_ddc_get_modes(connector, adapter);
-       ironlake_edp_panel_vdd_off(intel_dp, false);
        return ret;
  }
  
@@@ -2326,6 -2353,7 +2358,7 @@@ static void intel_dp_encoder_destroy(st
        i2c_del_adapter(&intel_dp->adapter);
        drm_encoder_cleanup(encoder);
        if (is_edp(intel_dp)) {
+               kfree(intel_dp->edid);
                cancel_delayed_work_sync(&intel_dp->panel_vdd_work);
                ironlake_panel_vdd_off_sync(intel_dp);
        }
@@@ -2492,28 -2520,31 +2525,31 @@@ intel_dp_init(struct drm_device *dev, i
                case DP_B:
                case PCH_DP_B:
                        dev_priv->hotplug_supported_mask |=
 -                              HDMIB_HOTPLUG_INT_STATUS;
 +                              DPB_HOTPLUG_INT_STATUS;
                        name = "DPDDC-B";
                        break;
                case DP_C:
                case PCH_DP_C:
                        dev_priv->hotplug_supported_mask |=
 -                              HDMIC_HOTPLUG_INT_STATUS;
 +                              DPC_HOTPLUG_INT_STATUS;
                        name = "DPDDC-C";
                        break;
                case DP_D:
                case PCH_DP_D:
                        dev_priv->hotplug_supported_mask |=
 -                              HDMID_HOTPLUG_INT_STATUS;
 +                              DPD_HOTPLUG_INT_STATUS;
                        name = "DPDDC-D";
                        break;
        }
  
+       intel_dp_i2c_init(intel_dp, intel_connector, name);
        /* Cache some DPCD data in the eDP case */
        if (is_edp(intel_dp)) {
                bool ret;
                struct edp_power_seq    cur, vbt;
                u32 pp_on, pp_off, pp_div;
+               struct edid *edid;
  
                pp_on = I915_READ(PCH_PP_ON_DELAYS);
                pp_off = I915_READ(PCH_PP_OFF_DELAYS);
                        intel_dp_destroy(&intel_connector->base);
                        return;
                }
-       }
  
-       intel_dp_i2c_init(intel_dp, intel_connector, name);
+               ironlake_edp_panel_vdd_on(intel_dp);
+               edid = drm_get_edid(connector, &intel_dp->adapter);
+               if (edid) {
+                       drm_mode_connector_update_edid_property(connector,
+                                                               edid);
+                       intel_dp->edid_mode_count =
+                               drm_add_edid_modes(connector, edid);
+                       drm_edid_to_eld(connector, edid);
+                       intel_dp->edid = edid;
+               }
+               ironlake_edp_panel_vdd_off(intel_dp, false);
+       }
  
        intel_encoder->hot_plug = intel_dp_hot_plug;
  
index 7a16f16371e63a9eae2120f70fae45192d855130,e5b84ff89ca58234b5c7e0d30fa8e97583d6357d..f30a53a8917e6f229b1bd986d23a4e65b41f28fc
@@@ -226,7 -226,6 +226,7 @@@ gen6_render_ring_flush(struct intel_rin
         * impact.
         */
        flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
 +      flags |= PIPE_CONTROL_TLB_INVALIDATE;
        flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE;
        flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE;
        flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
@@@ -267,10 -266,15 +267,15 @@@ u32 intel_ring_get_active_head(struct i
  
  static int init_ring_common(struct intel_ring_buffer *ring)
  {
-       drm_i915_private_t *dev_priv = ring->dev->dev_private;
+       struct drm_device *dev = ring->dev;
+       drm_i915_private_t *dev_priv = dev->dev_private;
        struct drm_i915_gem_object *obj = ring->obj;
+       int ret = 0;
        u32 head;
  
+       if (HAS_FORCE_WAKE(dev))
+               gen6_gt_force_wake_get(dev_priv);
        /* Stop the ring if it's running. */
        I915_WRITE_CTL(ring, 0);
        I915_WRITE_HEAD(ring, 0);
                                I915_READ_HEAD(ring),
                                I915_READ_TAIL(ring),
                                I915_READ_START(ring));
-               return -EIO;
+               ret = -EIO;
+               goto out;
        }
  
        if (!drm_core_check_feature(ring->dev, DRIVER_MODESET))
                ring->head = I915_READ_HEAD(ring);
                ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR;
                ring->space = ring_space(ring);
+               ring->last_retired_head = -1;
        }
  
-       return 0;
+ out:
+       if (HAS_FORCE_WAKE(dev))
+               gen6_gt_force_wake_put(dev_priv);
+       return ret;
  }
  
  static int
@@@ -423,21 -433,11 +434,21 @@@ static int init_render_ring(struct inte
                 */
                I915_WRITE(CACHE_MODE_0,
                           _MASKED_BIT_DISABLE(CM0_STC_EVICT_DISABLE_LRA_SNB));
 +
 +              /* This is not explicitly set for GEN6, so read the register.
 +               * see intel_ring_mi_set_context() for why we care.
 +               * TODO: consider explicitly setting the bit for GEN5
 +               */
 +              ring->itlb_before_ctx_switch =
 +                      !!(I915_READ(GFX_MODE) & GFX_TLB_INVALIDATE_ALWAYS);
        }
  
        if (INTEL_INFO(dev)->gen >= 6)
                I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_FORCE_ORDERING));
  
 +      if (IS_IVYBRIDGE(dev))
 +              I915_WRITE_IMR(ring, ~GEN6_RENDER_L3_PARITY_ERROR);
 +
        return ret;
  }
  
@@@ -825,11 -825,7 +836,11 @@@ gen6_ring_get_irq(struct intel_ring_buf
  
        spin_lock_irqsave(&dev_priv->irq_lock, flags);
        if (ring->irq_refcount++ == 0) {
 -              I915_WRITE_IMR(ring, ~ring->irq_enable_mask);
 +              if (IS_IVYBRIDGE(dev) && ring->id == RCS)
 +                      I915_WRITE_IMR(ring, ~(ring->irq_enable_mask |
 +                                              GEN6_RENDER_L3_PARITY_ERROR));
 +              else
 +                      I915_WRITE_IMR(ring, ~ring->irq_enable_mask);
                dev_priv->gt_irq_mask &= ~ring->irq_enable_mask;
                I915_WRITE(GTIMR, dev_priv->gt_irq_mask);
                POSTING_READ(GTIMR);
@@@ -848,10 -844,7 +859,10 @@@ gen6_ring_put_irq(struct intel_ring_buf
  
        spin_lock_irqsave(&dev_priv->irq_lock, flags);
        if (--ring->irq_refcount == 0) {
 -              I915_WRITE_IMR(ring, ~0);
 +              if (IS_IVYBRIDGE(dev) && ring->id == RCS)
 +                      I915_WRITE_IMR(ring, ~GEN6_RENDER_L3_PARITY_ERROR);
 +              else
 +                      I915_WRITE_IMR(ring, ~0);
                dev_priv->gt_irq_mask |= ring->irq_enable_mask;
                I915_WRITE(GTIMR, dev_priv->gt_irq_mask);
                POSTING_READ(GTIMR);
@@@ -976,7 -969,6 +987,7 @@@ static int intel_init_ring_buffer(struc
                                  struct intel_ring_buffer *ring)
  {
        struct drm_i915_gem_object *obj;
 +      struct drm_i915_private *dev_priv = dev->dev_private;
        int ret;
  
        ring->dev = dev;
        if (ret)
                goto err_unref;
  
 -      ring->virtual_start = ioremap_wc(dev->agp->base + obj->gtt_offset,
 -                                       ring->size);
+       ret = i915_gem_object_set_to_gtt_domain(obj, true);
+       if (ret)
+               goto err_unpin;
 +      ring->virtual_start =
 +              ioremap_wc(dev_priv->mm.gtt->gma_bus_addr + obj->gtt_offset,
 +                         ring->size);
        if (ring->virtual_start == NULL) {
                DRM_ERROR("Failed to map ringbuffer.\n");
                ret = -EINVAL;
@@@ -1105,7 -1100,7 +1120,7 @@@ static int intel_ring_wait_seqno(struc
        was_interruptible = dev_priv->mm.interruptible;
        dev_priv->mm.interruptible = false;
  
 -      ret = i915_wait_request(ring, seqno);
 +      ret = i915_wait_seqno(ring, seqno);
  
        dev_priv->mm.interruptible = was_interruptible;
        if (!ret)