From: Dave Airlie Date: Wed, 20 Jun 2012 18:17:08 +0000 (+0100) Subject: Merge tag 'drm-intel-next-2012-06-04' of git://people.freedesktop.org/~danvet/drm... X-Git-Tag: v3.6-rc1~83^2~47 X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9c19415c233499c26081798b880910ec0e1d7bad;hp=-c;p=pandora-kernel.git Merge tag 'drm-intel-next-2012-06-04' of git://people.freedesktop.org/~danvet/drm-intel into drm-core-next 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 ... --- 9c19415c233499c26081798b880910ec0e1d7bad diff --combined drivers/gpu/drm/i915/i915_drv.h index b0b676abde0d,ccabadd2b6c3..7cc36dbffbd8 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@@ -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; /** @@@ -817,6 -818,8 +819,8 @@@ 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, diff --combined drivers/gpu/drm/i915/i915_irq.c index b1fe0edda955,0e876646d769..75e0b029e1fa --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@@ -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) @@@ -394,6 -474,9 +474,9 @@@ 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; @@@ -550,35 -633,6 +633,35 @@@ 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; @@@ -620,7 -674,7 +703,7 @@@ 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) @@@ -2345,11 -2393,13 +2425,13 @@@ 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 | @@@ -2365,13 -2415,6 +2447,6 @@@ 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. @@@ -2391,36 -2434,40 +2466,40 @@@ 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 */ diff --combined drivers/gpu/drm/i915/i915_reg.h index 48d5e8e051cf,7dcc04f2143e..35113d8d7b05 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@@ -210,14 -210,6 +210,14 @@@ #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) @@@ -1566,20 -1558,34 +1566,34 @@@ #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 @@@ -1711,8 -1717,10 +1725,10 @@@ #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) @@@ -1723,7 -1731,11 +1739,11 @@@ #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 */ @@@ -3321,7 -3333,7 +3341,7 @@@ /* 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) @@@ -3357,44 -3369,15 +3377,44 @@@ #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 @@@ -4111,6 -4094,26 +4131,26 @@@ #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 diff --combined drivers/gpu/drm/i915/intel_display.c index a7c727d0c105,0161d947ab81..add1a15dc8b3 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@@ -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); @@@ -4431,16 -4416,8 +4416,8 @@@ /* 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 @@@ -4451,6 -4428,14 +4428,14 @@@ 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; @@@ -4662,16 -4647,8 +4647,8 @@@ 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) diff --combined drivers/gpu/drm/i915/intel_dp.c index c0449324143c,6538c46fe959..76a708029dcb --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@@ -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); @@@ -239,8 -248,8 +251,8 @@@ 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, @@@ -394,11 -403,6 +406,11 @@@ 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]); @@@ -1990,8 -1987,6 +1997,8 @@@ 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); @@@ -2612,19 -2581,9 +2617,19 @@@ 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; diff --combined drivers/gpu/drm/i915/intel_ringbuffer.c index e5b84ff89ca5,89a5e7f89d7a..f30850b079e9 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@@ -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); @@@ -322,8 -317,7 +322,8 @@@ 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)) @@@ -332,14 -326,9 +332,14 @@@ 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)