Merge tag 'drm-intel-next-2012-06-04' of git://people.freedesktop.org/~danvet/drm...
authorDave Airlie <airlied@redhat.com>
Wed, 20 Jun 2012 18:17:08 +0000 (19:17 +0100)
committerDave Airlie <airlied@redhat.com>
Wed, 20 Jun 2012 18:17:08 +0000 (19:17 +0100)
Daniel Vetter writes:
rc2 is out the door so I've figured I'll annoy you with the first -next
pull request for 3.6 already. Highlights:
- new wait_rendring_timeout interface (Ben)
- l3 cache remapping and error uevent support (Ben)
- even more infoframes work from Paulo
- gen4 hotplug rework from Chris
- prep work to make Laurent Pincharts original mode constification for
 connector->mode_fixup possible

QA reported a few new bugs this time around, but no regressions afact. For
3.5 the only thing I'm aware of is the edp vdd dmesg spam Linus originally
reported - it looks like that might have been introduced in 3.5. But
somehow my brain is routinely offline when I work on that issue, so things
seem to take forever (and atm I'm at patch v4 for that little problem).

* tag 'drm-intel-next-2012-06-04' of git://people.freedesktop.org/~danvet/drm-intel: (39 commits)
  drm/i915: add min freq control to debugfs
  drm/i915: don't chnage the original mode in dp_mode_fixup
  drm/i915: adjusted_mode->clock in the dp mode_fixup
  drm/i915: compute the target_clock for edp directly
  drm/i915: extract object active state flushing code
  drm/i915: clarify IBX dp workaround
  drm/i915: simplify sysfs setup code
  drm/i915: initialize the parity work only once
  drm/i915: ivybridge_handle_parity_error should be static
  drm/i915: l3 parity sysfs interface
  drm/i915: remap l3 on hw init
  drm/i915: enable parity error interrupts
  drm/i915: Dynamic Parity Detection handling
  drm/i915: s/mdelay/msleep/ in the sdvo detect function
  drm/i915: reuse the sdvo tv clock adjustment in ilk mode_set
  drm/i915: there's no cxsr on ilk
  drm/i915: add some barriers when changing DIPs
  drm/i915: remove comment about HSW HDMI DIPs
  drm/i915: don't set SDVO_BORDER_ENABLE when we're HDMI
  drm/i915: don't write 0 to DIP control at HDMI init
  ...

1  2 
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

@@@ -285,7 -285,6 +285,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;
@@@ -657,6 -656,8 +657,8 @@@ typedef struct drm_i915_private 
                /** 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;
  } drm_i915_private_t;
  
  /* Iterate over initialised rings */
@@@ -1102,8 -1105,6 +1106,8 @@@ struct drm_i915_file_private 
  #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"
  
  /**
@@@ -1237,6 -1238,8 +1241,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,
@@@ -1315,6 -1318,7 +1321,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);
@@@ -1323,8 -1327,8 +1330,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,
@@@ -375,6 -375,86 +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,
@@@ -510,7 -593,7 +593,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);
@@@ -713,10 -767,7 +796,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) {
@@@ -1649,7 -1700,6 +1732,6 @@@ static void ironlake_irq_preinstall(str
  
        atomic_set(&dev_priv->irq_received, 0);
  
        I915_WRITE(HWSTAM, 0xeffe);
  
        /* XXX hotplug from PCH */
@@@ -1812,13 -1862,13 +1894,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);
  
@@@ -2167,9 -2217,9 +2249,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;
@@@ -2329,10 -2379,8 +2411,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);
  
@@@ -2478,8 -2525,7 +2557,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",
@@@ -2552,10 -2598,8 +2630,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)
@@@ -2576,6 -2620,7 +2652,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 */
  #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_SET_CONTEXT                MI_INSTR(0x18, 0)
  #define   MI_MM_SPACE_GTT             (1<<8)
  #define   MI_MM_SPACE_PHYSICAL                (0<<8)
  #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 */
  
  /* 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   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
@@@ -4405,25 -4405,10 +4405,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;
-                       }
                }
        }
  
@@@ -6158,34 -6135,17 +6135,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));
@@@ -6558,7 -6518,7 +6535,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)
@@@ -32,7 -32,6 +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"
@@@ -68,8 -67,6 +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;
  };
  
  /**
@@@ -155,6 -152,18 +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)
  {
@@@ -225,7 -234,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;
@@@ -263,7 -272,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)
@@@ -374,7 -383,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);
@@@ -706,25 -710,20 +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++) {
@@@ -1922,7 -1921,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;
  
@@@ -1981,8 -1980,6 +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
@@@ -2099,25 -2094,23 +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);
@@@ -2128,22 -2121,10 +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;
  }
  
@@@ -2153,17 -2134,9 +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;
  }
  
@@@ -2353,7 -2326,6 +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);
        }
@@@ -2520,31 -2492,28 +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;
  
@@@ -266,15 -266,10 +266,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
@@@ -438,6 -427,9 +438,9 @@@ static int init_render_ring(struct inte
        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,7 -817,11 +828,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);
@@@ -844,7 -840,10 +851,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);
@@@ -998,10 -997,6 +1008,10 @@@ static int intel_init_ring_buffer(struc
        if (ret)
                goto err_unref;
  
 +      ret = i915_gem_object_set_to_gtt_domain(obj, true);
 +      if (ret)
 +              goto err_unpin;
 +
        ring->virtual_start = ioremap_wc(dev->agp->base + obj->gtt_offset,
                                         ring->size);
        if (ring->virtual_start == NULL) {
@@@ -1100,7 -1095,7 +1110,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)