From 254f965c39e3918544395f4ebac8c589d890bae6 Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Mon, 4 Jun 2012 14:42:42 -0700 Subject: drm/i915: preliminary context support Very basic code for context setup/destruction in the driver. Adds the file i915_gem_context.c This file implements HW context support. On gen5+ a HW context consists of an opaque GPU object which is referenced at times of context saves and restores. With RC6 enabled, the context is also referenced as the GPU enters and exists from RC6 (GPU has it's own internal power context, except on gen5). Though something like a context does exist for the media ring, the code only supports contexts for the render ring. In software, there is a distinction between contexts created by the user, and the default HW context. The default HW context is used by GPU clients that do not request setup of their own hardware context. The default context's state is never restored to help prevent programming errors. This would happen if a client ran and piggy-backed off another clients GPU state. The default context only exists to give the GPU some offset to load as the current to invoke a save of the context we actually care about. In fact, the code could likely be constructed, albeit in a more complicated fashion, to never use the default context, though that limits the driver's ability to swap out, and/or destroy other contexts. All other contexts are created as a request by the GPU client. These contexts store GPU state, and thus allow GPU clients to not re-emit state (and potentially query certain state) at any time. The kernel driver makes certain that the appropriate commands are inserted. There are 4 entry points into the contexts, init, fini, open, close. The names are self-explanatory except that init can be called during reset, and also during pm thaw/resume. As we expect our context to be preserved across these events, we do not reinitialize in this case. As Adam Jackson pointed out, The cutoff of 1MB where a HW context is considered too big is arbitrary. The reason for this is even though context sizes are increasing with every generation, they have yet to eclipse even 32k. If we somehow read back way more than that, it probably means BIOS has done something strange, or we're running on a platform that wasn't designed for this. v2: rename load/unload to init/fini (daniel) remove ILK support for get_size() (indirectly daniel) add HAS_HW_CONTEXTS macro to clarify supported platforms (daniel) added comments (Ben) Signed-off-by: Ben Widawsky --- drivers/gpu/drm/i915/i915_drv.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/i915/i915_drv.c') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 238a5216583..5d9e07ece3c 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -903,6 +903,7 @@ int i915_reset(struct drm_device *dev) 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); -- cgit v1.2.3-70-g09d2 From 8e96d9c4d9843f00ebeb4a9b33596d96602ea101 Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Mon, 4 Jun 2012 14:42:56 -0700 Subject: drm/i915: reset the GPU on context fini It's the only way we know how to make the GPU actually forget about the default context. Signed-off-by: Ben Widawsky --- drivers/gpu/drm/i915/i915_drv.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_gem_context.c | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/i915_drv.c') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 5d9e07ece3c..f0bd30ab155 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -799,7 +799,7 @@ static int gen6_do_reset(struct drm_device *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; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 03e7f9e683e..6f29fd141ab 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1184,6 +1184,7 @@ extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, 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); diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 5642c4019b5..6dc426a48b2 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -278,6 +278,8 @@ void i915_gem_context_fini(struct drm_device *dev) i915_gem_object_unpin(dev_priv->ring[RCS].default_context->obj); do_destroy(dev_priv->ring[RCS].default_context); + + intel_gpu_reset(dev); } void i915_gem_context_open(struct drm_device *dev, struct drm_file *file) -- cgit v1.2.3-70-g09d2 From e080b915ecea3fff3e0d8d380a221677add419a5 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sat, 16 Jun 2012 18:29:44 +0200 Subject: drm/i915: fixup hangman rebase goof-up I've added a bit of logic such that running the hangman test on chips without any hw reset support at all doesn't wedge the gpu because the reset failed. This relied on checking for non-null stop_rings. Unfortunately I've botched a rebase somewhere and stop_rings is still cleared at the old place before the reset code. Fix this up so that running the i-g-t tests on gen2/3 doesn't result in a wedged gpu. v2: Actually remove the lines instead of adding them twice ... my git license should be revoked immediately. Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/gpu/drm/i915/i915_drv.c') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index f0bd30ab155..e41aadef993 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -860,8 +860,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; -- cgit v1.2.3-70-g09d2 From 8e88a2bd5987178d16d53686197404e149e996d9 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 19 Jun 2012 18:40:00 +0200 Subject: drm/i915: don't call modeset_init_hw in i915_reset It seems to blow up my ilk in all kinds of strange ways. And now that we're no longer resetting the entire modeset state, it shouldn't be necessary any longer. This essentially reverts commit f817586cebf1b946d1f327f9a596048efd6b64e9 Author: Daniel Vetter Date: Tue Apr 10 15:50:11 2012 +0200 drm/i915: re-init modeset hw state after gpu reset safe for the introduction of modeset_init_hw, that one is nice to prevent code duplication between driver load and resume. v2: Add a comment to the code to warn future travellers of the dragon dungeon ahead, suggested by Chris Wilson. Acked-by: Chris Wilson Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/i915/i915_drv.c') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index e41aadef993..d7dd60bb274 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -904,10 +904,13 @@ int i915_reset(struct drm_device *dev) 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); -- cgit v1.2.3-70-g09d2 From f7dff0c9cbb89e9c406c0ca47f32129b61721174 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 15 Jun 2012 11:55:17 -0700 Subject: drm/i915: access VLV regs through read/write switch Since the offsets have all moved around. v2: switch IS_DISPLAYREG and IS_VALLEYVIEW checks around since the latter is cheaper (Daniel) bail out early in IS_DISPLAYREG if the reg is in the new range (Daniel) Signed-off-by: Jesse Barnes [danvet: Fixup if cascading fail that broke HAS_FORCEWAKE machines.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 86 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/i915_drv.c') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index d7dd60bb274..d1306c0f44f 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1146,6 +1146,84 @@ MODULE_LICENSE("GPL and additional rights"); ((reg) != FORCEWAKE)) && \ (!IS_VALLEYVIEW((dev_priv)->dev)) +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; \ @@ -1158,6 +1236,8 @@ u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ 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); \ } \ @@ -1178,7 +1258,11 @@ void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \ 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); \ } \ -- cgit v1.2.3-70-g09d2 From ff049b6ce21d2814451afd4a116d001712e0116b Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 20 Jun 2012 10:53:13 -0700 Subject: drm/i915: bind driver to ValleyView chipsets With the code in place, we can bind the driver, should make bisect possible. Signed-off-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/gpu/drm/i915/i915_drv.c') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index d1306c0f44f..05adbf23951 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -352,6 +352,9 @@ 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} }; -- cgit v1.2.3-70-g09d2 From 01a06850fb45ace55ed67d1d9da2df553a041e40 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 25 Jun 2012 15:58:49 +0200 Subject: drm/i915: disable drm agp support for !gen3 with kms enabled This is the quick&dirty way Dave Airlie suggested to workaround the midlayer drm agp brain-damange. Note that i915_probe is only called when the driver has ksm enabled, so no need to check for that. We also need to move the intel_agp_enabled check at the right place. Note that the only thing this does is enforce the correct module load order (by using a symbol from intel-agp.ko) to ensure that the fake agp driver is ready before the drm core tries to set up the agp stuff. v2: Add a comment to explain why gen3 needs all this legacy fake agp stuff - we've shipped an XvMC library with a kms-enabled ddx that requires it (but only on gen3). v3: Make it clear that this is only a gen3 issue in the comment. Reviewed-by: Chris Wilson Reviewed-by: Eugeni Dodonov Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm/i915/i915_drv.c') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index a378c080030..79be8799ea6 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -930,10 +930,12 @@ int i915_reset(struct drm_device *dev) return 0; } - static int __devinit i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { + struct intel_device_info *intel_info = + (struct intel_device_info *) ent->driver_data; + /* Only bind to function 0 of the device. Early generations * used function 1 as a placeholder for multi-head. This causes * us confusion instead, especially on the systems where both @@ -942,6 +944,18 @@ i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (PCI_FUNC(pdev->devfn)) return -ENODEV; + /* We've managed to ship a kms-enabled ddx that shipped with an XvMC + * implementation for gen3 (and only gen3) that used legacy drm maps + * (gasp!) to share buffers between X and the client. Hence we need to + * keep around the fake agp stuff for gen3, even when kms is enabled. */ + if (intel_info->gen != 3) { + driver.driver_features &= + ~(DRIVER_USE_AGP | DRIVER_REQUIRE_AGP); + } else if (!intel_agp_enabled) { + DRM_ERROR("drm/i915 can't work without intel_agp module!\n"); + return -ENODEV; + } + return drm_get_pci_dev(pdev, ent, &driver); } @@ -1102,11 +1116,6 @@ static struct pci_driver i915_pci_driver = { static int __init i915_init(void) { - if (!intel_agp_enabled) { - DRM_ERROR("drm/i915 can't work without intel_agp module!\n"); - return -ENODEV; - } - driver.num_ioctls = i915_max_ioctl; /* -- cgit v1.2.3-70-g09d2 From 990bbdadabaa51828e475eda86ee5720a4910cc3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 2 Jul 2012 11:51:02 -0300 Subject: drm/i915: Group the GT routines together in both code and vtable Tidy up the routines for interacting with the GT (in particular the forcewake dance) which are scattered throughout the code in a single structure. v2: use wait_for_atomic for polling. v3: *really* use wait_for_atomic for polling. Signed-off-by: Chris Wilson Signed-off-by: Eugeni Dodonov Reviewed-by: Ben Widawsky Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 2 +- drivers/gpu/drm/i915/i915_drv.c | 101 ++++++++++++++++++++++------------- drivers/gpu/drm/i915/i915_drv.h | 17 +++--- drivers/gpu/drm/i915/intel_display.c | 3 -- drivers/gpu/drm/i915/intel_pm.c | 30 ----------- 5 files changed, 73 insertions(+), 80 deletions(-) (limited to 'drivers/gpu/drm/i915/i915_drv.c') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 216651917fd..4dc76976c0d 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1548,6 +1548,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) } intel_irq_init(dev); + intel_gt_init(dev); /* Try to make sure MCHBAR is enabled before poking at it */ intel_setup_mchbar(dev); @@ -1580,7 +1581,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) if (!IS_I945G(dev) && !IS_I945GM(dev)) pci_enable_msi(dev->pdev); - spin_lock_init(&dev_priv->gt_lock); spin_lock_init(&dev_priv->irq_lock); spin_lock_init(&dev_priv->error_lock); spin_lock_init(&dev_priv->rps_lock); diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 79be8799ea6..928b6677759 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -32,6 +32,7 @@ #include "drm.h" #include "i915_drm.h" #include "i915_drv.h" +#include "i915_trace.h" #include "intel_drv.h" #include @@ -432,36 +433,26 @@ bool i915_semaphore_is_enabled(struct drm_device *dev) return 1; } -void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) +static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) { - int count; - - count = 0; - while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1)) - udelay(10); + if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_ACK) & 1) == 0, 500)) + DRM_ERROR("Force wake wait timed out\n"); I915_WRITE_NOTRACE(FORCEWAKE, 1); - POSTING_READ(FORCEWAKE); - count = 0; - while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1) == 0) - udelay(10); + if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_ACK) & 1), 500)) + DRM_ERROR("Force wake wait timed out\n"); } -void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) +static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) { - int count; - - count = 0; - while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1)) - udelay(10); + if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1) == 0, 500)) + DRM_ERROR("Force wake wait timed out\n"); I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_ENABLE(1)); - POSTING_READ(FORCEWAKE_MT); - count = 0; - while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1) == 0) - udelay(10); + if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1), 500)) + DRM_ERROR("Force wake wait timed out\n"); } /* @@ -476,7 +467,7 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) spin_lock_irqsave(&dev_priv->gt_lock, irqflags); if (dev_priv->forcewake_count++ == 0) - dev_priv->display.force_wake_get(dev_priv); + dev_priv->gt.force_wake_get(dev_priv); spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); } @@ -489,14 +480,14 @@ static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv) I915_WRITE_NOTRACE(GTFIFODBG, GT_FIFO_CPU_ERROR_MASK); } -void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) +static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) { I915_WRITE_NOTRACE(FORCEWAKE, 0); /* The below doubles as a POSTING_READ */ gen6_gt_check_fifodbg(dev_priv); } -void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) +static void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) { I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(1)); /* The below doubles as a POSTING_READ */ @@ -512,7 +503,7 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) spin_lock_irqsave(&dev_priv->gt_lock, irqflags); if (--dev_priv->forcewake_count == 0) - dev_priv->display.force_wake_put(dev_priv); + dev_priv->gt.force_wake_put(dev_priv); spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); } @@ -536,12 +527,8 @@ int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) return ret; } -void vlv_force_wake_get(struct drm_i915_private *dev_priv) +static void vlv_force_wake_get(struct drm_i915_private *dev_priv) { - int count; - - count = 0; - /* Already awake? */ if ((I915_READ(0x130094) & 0xa1) == 0xa1) return; @@ -549,18 +536,58 @@ void vlv_force_wake_get(struct drm_i915_private *dev_priv) I915_WRITE_NOTRACE(FORCEWAKE_VLV, 0xffffffff); POSTING_READ(FORCEWAKE_VLV); - count = 0; - while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK_VLV) & 1) == 0) - udelay(10); + if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_ACK_VLV) & 1), 500)) + DRM_ERROR("Force wake wait timed out\n"); } -void vlv_force_wake_put(struct drm_i915_private *dev_priv) +static void vlv_force_wake_put(struct drm_i915_private *dev_priv) { I915_WRITE_NOTRACE(FORCEWAKE_VLV, 0xffff0000); /* FIXME: confirm VLV behavior with Punit folks */ POSTING_READ(FORCEWAKE_VLV); } +void intel_gt_init(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + spin_lock_init(&dev_priv->gt_lock); + + if (IS_VALLEYVIEW(dev)) { + dev_priv->gt.force_wake_get = vlv_force_wake_get; + dev_priv->gt.force_wake_put = vlv_force_wake_put; + } else if (INTEL_INFO(dev)->gen >= 6) { + dev_priv->gt.force_wake_get = __gen6_gt_force_wake_get; + dev_priv->gt.force_wake_put = __gen6_gt_force_wake_put; + + /* IVB configs may use multi-threaded forcewake */ + if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) { + u32 ecobus; + + /* A small trick here - if the bios hasn't configured + * MT forcewake, and if the device is in RC6, then + * force_wake_mt_get will not wake the device and the + * ECOBUS read will return zero. Which will be + * (correctly) interpreted by the test below as MT + * forcewake being disabled. + */ + mutex_lock(&dev->struct_mutex); + __gen6_gt_force_wake_mt_get(dev_priv); + ecobus = I915_READ_NOTRACE(ECOBUS); + __gen6_gt_force_wake_mt_put(dev_priv); + mutex_unlock(&dev->struct_mutex); + + if (ecobus & FORCEWAKE_MT_ENABLE) { + DRM_DEBUG_KMS("Using MT version of forcewake\n"); + dev_priv->gt.force_wake_get = + __gen6_gt_force_wake_mt_get; + dev_priv->gt.force_wake_put = + __gen6_gt_force_wake_mt_put; + } + } + } +} + static int i915_drm_freeze(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -797,9 +824,9 @@ static int gen6_do_reset(struct drm_device *dev) /* If reset with a user forcewake, try to restore, otherwise turn it off */ if (dev_priv->forcewake_count) - dev_priv->display.force_wake_get(dev_priv); + dev_priv->gt.force_wake_get(dev_priv); else - dev_priv->display.force_wake_put(dev_priv); + dev_priv->gt.force_wake_put(dev_priv); /* Restore fifo count */ dev_priv->gt_fifo_count = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); @@ -1248,10 +1275,10 @@ u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ unsigned long irqflags; \ spin_lock_irqsave(&dev_priv->gt_lock, irqflags); \ if (dev_priv->forcewake_count == 0) \ - dev_priv->display.force_wake_get(dev_priv); \ + dev_priv->gt.force_wake_get(dev_priv); \ val = read##y(dev_priv->regs + reg); \ if (dev_priv->forcewake_count == 0) \ - dev_priv->display.force_wake_put(dev_priv); \ + dev_priv->gt.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); \ diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index a0c15abbdce..60f6974d20d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -262,8 +262,6 @@ struct drm_i915_display_funcs { struct drm_i915_gem_object *obj); int (*update_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb, int x, int y); - void (*force_wake_get)(struct drm_i915_private *dev_priv); - void (*force_wake_put)(struct drm_i915_private *dev_priv); /* clock updates for mode set */ /* cursor updates */ /* render clock increase/decrease */ @@ -271,6 +269,11 @@ struct drm_i915_display_funcs { /* pll clock increase/decrease */ }; +struct drm_i915_gt_funcs { + void (*force_wake_get)(struct drm_i915_private *dev_priv); + void (*force_wake_put)(struct drm_i915_private *dev_priv); +}; + struct intel_device_info { u8 gen; u8 is_mobile:1; @@ -362,6 +365,8 @@ typedef struct drm_i915_private { int relative_constants_mode; void __iomem *regs; + + struct drm_i915_gt_funcs gt; /** gt_fifo_count and the subsequent register write are synchronized * with dev->struct_mutex. */ unsigned gt_fifo_count; @@ -1200,6 +1205,7 @@ void i915_hangcheck_elapsed(unsigned long data); void i915_handle_error(struct drm_device *dev, bool wedged); extern void intel_irq_init(struct drm_device *dev); +extern void intel_gt_init(struct drm_device *dev); void i915_error_state_free(struct kref *error_ref); @@ -1517,13 +1523,6 @@ extern int intel_trans_dp_port_sel(struct drm_crtc *crtc); extern int intel_enable_rc6(const struct drm_device *dev); extern bool i915_semaphore_is_enabled(struct drm_device *dev); -extern void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv); -extern void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv); -extern void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv); -extern void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv); - -extern void vlv_force_wake_get(struct drm_i915_private *dev_priv); -extern void vlv_force_wake_put(struct drm_i915_private *dev_priv); /* overlay */ #ifdef CONFIG_DEBUG_FS diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3fbc802b494..342f18e9cbe 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -7013,9 +7013,6 @@ static void intel_init_display(struct drm_device *dev) dev_priv->display.write_eld = ironlake_write_eld; } else dev_priv->display.update_wm = NULL; - } else if (IS_VALLEYVIEW(dev)) { - dev_priv->display.force_wake_get = vlv_force_wake_get; - dev_priv->display.force_wake_put = vlv_force_wake_put; } else if (IS_G4X(dev)) { dev_priv->display.write_eld = g4x_write_eld; } diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 99bc1f33bfc..ed9912ca1f8 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3765,34 +3765,6 @@ void intel_init_pm(struct drm_device *dev) /* For FIFO watermark updates */ if (HAS_PCH_SPLIT(dev)) { - dev_priv->display.force_wake_get = __gen6_gt_force_wake_get; - dev_priv->display.force_wake_put = __gen6_gt_force_wake_put; - - /* IVB configs may use multi-threaded forcewake */ - if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) { - u32 ecobus; - - /* A small trick here - if the bios hasn't configured MT forcewake, - * and if the device is in RC6, then force_wake_mt_get will not wake - * the device and the ECOBUS read will return zero. Which will be - * (correctly) interpreted by the test below as MT forcewake being - * disabled. - */ - mutex_lock(&dev->struct_mutex); - __gen6_gt_force_wake_mt_get(dev_priv); - ecobus = I915_READ_NOTRACE(ECOBUS); - __gen6_gt_force_wake_mt_put(dev_priv); - mutex_unlock(&dev->struct_mutex); - - if (ecobus & FORCEWAKE_MT_ENABLE) { - DRM_DEBUG_KMS("Using MT version of forcewake\n"); - dev_priv->display.force_wake_get = - __gen6_gt_force_wake_mt_get; - dev_priv->display.force_wake_put = - __gen6_gt_force_wake_mt_put; - } - } - if (HAS_PCH_IBX(dev)) dev_priv->display.init_pch_clock_gating = ibx_init_clock_gating; else if (HAS_PCH_CPT(dev)) @@ -3848,8 +3820,6 @@ void intel_init_pm(struct drm_device *dev) dev_priv->display.update_wm = valleyview_update_wm; dev_priv->display.init_clock_gating = valleyview_init_clock_gating; - dev_priv->display.force_wake_get = vlv_force_wake_get; - dev_priv->display.force_wake_put = vlv_force_wake_put; } else if (IS_PINEVIEW(dev)) { if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->is_ddr3, -- cgit v1.2.3-70-g09d2 From c4de7b0ffda2bb4843fd7f1052d0a2bb90bd08a5 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 2 Jul 2012 11:51:03 -0300 Subject: drm/i915: Implement w/a for sporadic read failures on waking from rc6 As a w/a to prevent reads sporadically returning 0, we need to wait for the GT thread to return to TC0 before proceeding to read the registers. v2: adapt for Haswell changes (Eugeni). v3: use wait_for_atomic_us for thread status polling. v3: *really* use wait_for_atomic for polling. References: https://bugs.freedesktop.org/show_bug.cgi?id=50243 Signed-off-by: Chris Wilson Signed-off-by: Eugeni Dodonov Acked-by: Ben Widawsky Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 22 ++++++++++++++++++++++ drivers/gpu/drm/i915/i915_reg.h | 4 ++++ 2 files changed, 26 insertions(+) (limited to 'drivers/gpu/drm/i915/i915_drv.c') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 928b6677759..a4ea4a9fc42 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -433,6 +433,22 @@ bool i915_semaphore_is_enabled(struct drm_device *dev) return 1; } +static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv) +{ + u32 gt_thread_status_mask; + + if (IS_HASWELL(dev_priv->dev)) + gt_thread_status_mask = GEN6_GT_THREAD_STATUS_CORE_MASK_HSW; + else + gt_thread_status_mask = GEN6_GT_THREAD_STATUS_CORE_MASK; + + /* w/a for a sporadic read returning 0 by waiting for the GT + * thread to wake up. + */ + if (wait_for_atomic_us((I915_READ_NOTRACE(GEN6_GT_THREAD_STATUS_REG) & gt_thread_status_mask) == 0, 500)) + DRM_ERROR("GT thread status wait timed out\n"); +} + static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) { if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_ACK) & 1) == 0, 500)) @@ -442,6 +458,8 @@ static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_ACK) & 1), 500)) DRM_ERROR("Force wake wait timed out\n"); + + __gen6_gt_wait_for_thread_c0(dev_priv); } static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) @@ -453,6 +471,8 @@ static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1), 500)) DRM_ERROR("Force wake wait timed out\n"); + + __gen6_gt_wait_for_thread_c0(dev_priv); } /* @@ -538,6 +558,8 @@ static void vlv_force_wake_get(struct drm_i915_private *dev_priv) if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_ACK_VLV) & 1), 500)) DRM_ERROR("Force wake wait timed out\n"); + + __gen6_gt_wait_for_thread_c0(dev_priv); } static void vlv_force_wake_put(struct drm_i915_private *dev_priv) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index ac65e96ea98..8b400e96de1 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1458,6 +1458,10 @@ #define DDRMPLL1 0X12c20 #define PEG_BAND_GAP_DATA 0x14d68 +#define GEN6_GT_THREAD_STATUS_REG 0x13805c +#define GEN6_GT_THREAD_STATUS_CORE_MASK 0x7 +#define GEN6_GT_THREAD_STATUS_CORE_MASK_HSW (0x7 | (0x07 << 16)) + #define GEN6_GT_PERF_STATUS 0x145948 #define GEN6_RP_STATE_LIMITS 0x145994 #define GEN6_RP_STATE_CAP 0x145998 -- cgit v1.2.3-70-g09d2 From e7911c48a05bc0002616a51e99761dec36110b04 Mon Sep 17 00:00:00 2001 From: Eugeni Dodonov Date: Mon, 2 Jul 2012 11:51:04 -0300 Subject: drm/i915: support Haswell force waking There is a different ACK register for force wake on Haswell, so account for that. Signed-off-by: Eugeni Dodonov Reviewed-by: Ben Widawsky Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 22 ++++++++++++++++++---- drivers/gpu/drm/i915/i915_reg.h | 1 + 2 files changed, 19 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/i915/i915_drv.c') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index a4ea4a9fc42..3ac414ff7f8 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -451,12 +451,19 @@ static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv) static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) { - if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_ACK) & 1) == 0, 500)) + u32 forcewake_ack; + + if (IS_HASWELL(dev_priv->dev)) + forcewake_ack = FORCEWAKE_ACK_HSW; + else + forcewake_ack = FORCEWAKE_ACK; + + if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1) == 0, 500)) DRM_ERROR("Force wake wait timed out\n"); I915_WRITE_NOTRACE(FORCEWAKE, 1); - if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_ACK) & 1), 500)) + if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500)) DRM_ERROR("Force wake wait timed out\n"); __gen6_gt_wait_for_thread_c0(dev_priv); @@ -464,12 +471,19 @@ static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) { - if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1) == 0, 500)) + u32 forcewake_ack; + + if (IS_HASWELL(dev_priv->dev)) + forcewake_ack = FORCEWAKE_ACK_HSW; + else + forcewake_ack = FORCEWAKE_MT_ACK; + + if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1) == 0, 500)) DRM_ERROR("Force wake wait timed out\n"); I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_ENABLE(1)); - if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1), 500)) + if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500)) DRM_ERROR("Force wake wait timed out\n"); __gen6_gt_wait_for_thread_c0(dev_priv); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 8b400e96de1..40000841b39 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4071,6 +4071,7 @@ #define FORCEWAKE 0xA18C #define FORCEWAKE_VLV 0x1300b0 #define FORCEWAKE_ACK_VLV 0x1300b4 +#define FORCEWAKE_ACK_HSW 0x130044 #define FORCEWAKE_ACK 0x130090 #define FORCEWAKE_MT 0xa188 /* multi-threaded */ #define FORCEWAKE_MT_ACK 0x130040 -- cgit v1.2.3-70-g09d2 From 6590190d12442b94e83f4f4590f3bb5d2848dd07 Mon Sep 17 00:00:00 2001 From: Eugeni Dodonov Date: Mon, 2 Jul 2012 11:51:11 -0300 Subject: drm/i915: move force wake support into intel_pm This commit moves force wake support routines into intel_pm modules, and exports the gen6_gt_check_fifodbg routine (used in I915_READ). Signed-off-by: Eugeni Dodonov Acked-by: Ben Widawsky Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 191 --------------------------------------- drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_pm.c | 191 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 192 insertions(+), 191 deletions(-) (limited to 'drivers/gpu/drm/i915/i915_drv.c') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 3ac414ff7f8..c7e76e03a68 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -433,197 +433,6 @@ bool i915_semaphore_is_enabled(struct drm_device *dev) return 1; } -static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv) -{ - u32 gt_thread_status_mask; - - if (IS_HASWELL(dev_priv->dev)) - gt_thread_status_mask = GEN6_GT_THREAD_STATUS_CORE_MASK_HSW; - else - gt_thread_status_mask = GEN6_GT_THREAD_STATUS_CORE_MASK; - - /* w/a for a sporadic read returning 0 by waiting for the GT - * thread to wake up. - */ - if (wait_for_atomic_us((I915_READ_NOTRACE(GEN6_GT_THREAD_STATUS_REG) & gt_thread_status_mask) == 0, 500)) - DRM_ERROR("GT thread status wait timed out\n"); -} - -static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) -{ - u32 forcewake_ack; - - if (IS_HASWELL(dev_priv->dev)) - forcewake_ack = FORCEWAKE_ACK_HSW; - else - forcewake_ack = FORCEWAKE_ACK; - - if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1) == 0, 500)) - DRM_ERROR("Force wake wait timed out\n"); - - I915_WRITE_NOTRACE(FORCEWAKE, 1); - - if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500)) - DRM_ERROR("Force wake wait timed out\n"); - - __gen6_gt_wait_for_thread_c0(dev_priv); -} - -static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) -{ - u32 forcewake_ack; - - if (IS_HASWELL(dev_priv->dev)) - forcewake_ack = FORCEWAKE_ACK_HSW; - else - forcewake_ack = FORCEWAKE_MT_ACK; - - if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1) == 0, 500)) - DRM_ERROR("Force wake wait timed out\n"); - - I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_ENABLE(1)); - - if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500)) - DRM_ERROR("Force wake wait timed out\n"); - - __gen6_gt_wait_for_thread_c0(dev_priv); -} - -/* - * Generally this is called implicitly by the register read function. However, - * if some sequence requires the GT to not power down then this function should - * be called at the beginning of the sequence followed by a call to - * gen6_gt_force_wake_put() at the end of the sequence. - */ -void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) -{ - unsigned long irqflags; - - spin_lock_irqsave(&dev_priv->gt_lock, irqflags); - if (dev_priv->forcewake_count++ == 0) - dev_priv->gt.force_wake_get(dev_priv); - spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); -} - -static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv) -{ - u32 gtfifodbg; - gtfifodbg = I915_READ_NOTRACE(GTFIFODBG); - if (WARN(gtfifodbg & GT_FIFO_CPU_ERROR_MASK, - "MMIO read or write has been dropped %x\n", gtfifodbg)) - I915_WRITE_NOTRACE(GTFIFODBG, GT_FIFO_CPU_ERROR_MASK); -} - -static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) -{ - I915_WRITE_NOTRACE(FORCEWAKE, 0); - /* The below doubles as a POSTING_READ */ - gen6_gt_check_fifodbg(dev_priv); -} - -static void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) -{ - I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(1)); - /* The below doubles as a POSTING_READ */ - gen6_gt_check_fifodbg(dev_priv); -} - -/* - * see gen6_gt_force_wake_get() - */ -void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) -{ - unsigned long irqflags; - - spin_lock_irqsave(&dev_priv->gt_lock, irqflags); - if (--dev_priv->forcewake_count == 0) - dev_priv->gt.force_wake_put(dev_priv); - spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); -} - -int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) -{ - int ret = 0; - - if (dev_priv->gt_fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) { - int loop = 500; - u32 fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); - while (fifo <= GT_FIFO_NUM_RESERVED_ENTRIES && loop--) { - udelay(10); - fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); - } - if (WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES)) - ++ret; - dev_priv->gt_fifo_count = fifo; - } - dev_priv->gt_fifo_count--; - - return ret; -} - -static void vlv_force_wake_get(struct drm_i915_private *dev_priv) -{ - /* Already awake? */ - if ((I915_READ(0x130094) & 0xa1) == 0xa1) - return; - - I915_WRITE_NOTRACE(FORCEWAKE_VLV, 0xffffffff); - POSTING_READ(FORCEWAKE_VLV); - - if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_ACK_VLV) & 1), 500)) - DRM_ERROR("Force wake wait timed out\n"); - - __gen6_gt_wait_for_thread_c0(dev_priv); -} - -static void vlv_force_wake_put(struct drm_i915_private *dev_priv) -{ - I915_WRITE_NOTRACE(FORCEWAKE_VLV, 0xffff0000); - /* FIXME: confirm VLV behavior with Punit folks */ - POSTING_READ(FORCEWAKE_VLV); -} - -void intel_gt_init(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - spin_lock_init(&dev_priv->gt_lock); - - if (IS_VALLEYVIEW(dev)) { - dev_priv->gt.force_wake_get = vlv_force_wake_get; - dev_priv->gt.force_wake_put = vlv_force_wake_put; - } else if (INTEL_INFO(dev)->gen >= 6) { - dev_priv->gt.force_wake_get = __gen6_gt_force_wake_get; - dev_priv->gt.force_wake_put = __gen6_gt_force_wake_put; - - /* IVB configs may use multi-threaded forcewake */ - if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) { - u32 ecobus; - - /* A small trick here - if the bios hasn't configured - * MT forcewake, and if the device is in RC6, then - * force_wake_mt_get will not wake the device and the - * ECOBUS read will return zero. Which will be - * (correctly) interpreted by the test below as MT - * forcewake being disabled. - */ - mutex_lock(&dev->struct_mutex); - __gen6_gt_force_wake_mt_get(dev_priv); - ecobus = I915_READ_NOTRACE(ECOBUS); - __gen6_gt_force_wake_mt_put(dev_priv); - mutex_unlock(&dev->struct_mutex); - - if (ecobus & FORCEWAKE_MT_ENABLE) { - DRM_DEBUG_KMS("Using MT version of forcewake\n"); - dev_priv->gt.force_wake_get = - __gen6_gt_force_wake_mt_get; - dev_priv->gt.force_wake_put = - __gen6_gt_force_wake_mt_put; - } - } - } -} - static int i915_drm_freeze(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index cc1573b2b60..7d521aa5154 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -493,6 +493,7 @@ extern void intel_gpu_ips_teardown(void); extern void intel_enable_gt_powersave(struct drm_device *dev); extern void intel_disable_gt_powersave(struct drm_device *dev); +extern void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv); extern void intel_ddi_dpms(struct drm_encoder *encoder, int mode); extern void intel_ddi_mode_set(struct drm_encoder *encoder, diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 6e02698e9a3..3f58d7aeb70 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3948,3 +3948,194 @@ void intel_init_pm(struct drm_device *dev) intel_init_power_wells(dev); } +static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv) +{ + u32 gt_thread_status_mask; + + if (IS_HASWELL(dev_priv->dev)) + gt_thread_status_mask = GEN6_GT_THREAD_STATUS_CORE_MASK_HSW; + else + gt_thread_status_mask = GEN6_GT_THREAD_STATUS_CORE_MASK; + + /* w/a for a sporadic read returning 0 by waiting for the GT + * thread to wake up. + */ + if (wait_for_atomic_us((I915_READ_NOTRACE(GEN6_GT_THREAD_STATUS_REG) & gt_thread_status_mask) == 0, 500)) + DRM_ERROR("GT thread status wait timed out\n"); +} + +static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) +{ + u32 forcewake_ack; + + if (IS_HASWELL(dev_priv->dev)) + forcewake_ack = FORCEWAKE_ACK_HSW; + else + forcewake_ack = FORCEWAKE_ACK; + + if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1) == 0, 500)) + DRM_ERROR("Force wake wait timed out\n"); + + I915_WRITE_NOTRACE(FORCEWAKE, 1); + + if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500)) + DRM_ERROR("Force wake wait timed out\n"); + + __gen6_gt_wait_for_thread_c0(dev_priv); +} + +static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) +{ + u32 forcewake_ack; + + if (IS_HASWELL(dev_priv->dev)) + forcewake_ack = FORCEWAKE_ACK_HSW; + else + forcewake_ack = FORCEWAKE_MT_ACK; + + if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1) == 0, 500)) + DRM_ERROR("Force wake wait timed out\n"); + + I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_ENABLE(1)); + + if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500)) + DRM_ERROR("Force wake wait timed out\n"); + + __gen6_gt_wait_for_thread_c0(dev_priv); +} + +/* + * Generally this is called implicitly by the register read function. However, + * if some sequence requires the GT to not power down then this function should + * be called at the beginning of the sequence followed by a call to + * gen6_gt_force_wake_put() at the end of the sequence. + */ +void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) +{ + unsigned long irqflags; + + spin_lock_irqsave(&dev_priv->gt_lock, irqflags); + if (dev_priv->forcewake_count++ == 0) + dev_priv->gt.force_wake_get(dev_priv); + spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); +} + +void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv) +{ + u32 gtfifodbg; + gtfifodbg = I915_READ_NOTRACE(GTFIFODBG); + if (WARN(gtfifodbg & GT_FIFO_CPU_ERROR_MASK, + "MMIO read or write has been dropped %x\n", gtfifodbg)) + I915_WRITE_NOTRACE(GTFIFODBG, GT_FIFO_CPU_ERROR_MASK); +} + +static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) +{ + I915_WRITE_NOTRACE(FORCEWAKE, 0); + /* The below doubles as a POSTING_READ */ + gen6_gt_check_fifodbg(dev_priv); +} + +static void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) +{ + I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(1)); + /* The below doubles as a POSTING_READ */ + gen6_gt_check_fifodbg(dev_priv); +} + +/* + * see gen6_gt_force_wake_get() + */ +void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) +{ + unsigned long irqflags; + + spin_lock_irqsave(&dev_priv->gt_lock, irqflags); + if (--dev_priv->forcewake_count == 0) + dev_priv->gt.force_wake_put(dev_priv); + spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); +} + +int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) +{ + int ret = 0; + + if (dev_priv->gt_fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) { + int loop = 500; + u32 fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); + while (fifo <= GT_FIFO_NUM_RESERVED_ENTRIES && loop--) { + udelay(10); + fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); + } + if (WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES)) + ++ret; + dev_priv->gt_fifo_count = fifo; + } + dev_priv->gt_fifo_count--; + + return ret; +} + +static void vlv_force_wake_get(struct drm_i915_private *dev_priv) +{ + /* Already awake? */ + if ((I915_READ(0x130094) & 0xa1) == 0xa1) + return; + + I915_WRITE_NOTRACE(FORCEWAKE_VLV, 0xffffffff); + POSTING_READ(FORCEWAKE_VLV); + + if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_ACK_VLV) & 1), 500)) + DRM_ERROR("Force wake wait timed out\n"); + + __gen6_gt_wait_for_thread_c0(dev_priv); +} + +static void vlv_force_wake_put(struct drm_i915_private *dev_priv) +{ + I915_WRITE_NOTRACE(FORCEWAKE_VLV, 0xffff0000); + /* FIXME: confirm VLV behavior with Punit folks */ + POSTING_READ(FORCEWAKE_VLV); +} + +void intel_gt_init(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + spin_lock_init(&dev_priv->gt_lock); + + if (IS_VALLEYVIEW(dev)) { + dev_priv->gt.force_wake_get = vlv_force_wake_get; + dev_priv->gt.force_wake_put = vlv_force_wake_put; + } else if (INTEL_INFO(dev)->gen >= 6) { + dev_priv->gt.force_wake_get = __gen6_gt_force_wake_get; + dev_priv->gt.force_wake_put = __gen6_gt_force_wake_put; + + /* IVB configs may use multi-threaded forcewake */ + if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) { + u32 ecobus; + + /* A small trick here - if the bios hasn't configured + * MT forcewake, and if the device is in RC6, then + * force_wake_mt_get will not wake the device and the + * ECOBUS read will return zero. Which will be + * (correctly) interpreted by the test below as MT + * forcewake being disabled. + */ + mutex_lock(&dev->struct_mutex); + __gen6_gt_force_wake_mt_get(dev_priv); + ecobus = I915_READ_NOTRACE(ECOBUS); + __gen6_gt_force_wake_mt_put(dev_priv); + mutex_unlock(&dev->struct_mutex); + + if (ecobus & FORCEWAKE_MT_ENABLE) { + DRM_DEBUG_KMS("Using MT version of forcewake\n"); + dev_priv->gt.force_wake_get = + __gen6_gt_force_wake_mt_get; + dev_priv->gt.force_wake_put = + __gen6_gt_force_wake_mt_put; + } + } + } +} + -- cgit v1.2.3-70-g09d2 From 45e6e3a1cd2f53fd5996e75b4029defed97ca585 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Tue, 3 Jul 2012 15:57:32 -0300 Subject: drm/i915: get rid of dev_priv->info->has_pch_split Previously we had has_pch_split to tell us whether we had a PCH or not and we also had dev_priv->pch_type to tell us which kind of PCH it was, but it could only be used if we were 100% sure we did have a PCH. Now that PCH_NONE was added to dev_priv->pch_type we don't need has_pch_split anymore: we can just check for pch_type != PCH_NONE. The HAS_PCH_{IBX,CPT,LPT} macros use dev_priv->pch_type, so they can only be called after intel_detect_pch. The HAS_PCH_SPLIT macro looks at dev_priv->info->has_pch_split, which is available earlier. Since the goal is to implement HAS_PCH_SPLIT using dev_priv->pch_type instead of dev_priv->info->has_pch_split, we need to make sure that intel_detect_pch is called before any calls to HAS_PCH_SPLIT are made. So we moved the intel_detect_pch call to an earlier stage. Signed-off-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 5 +++-- drivers/gpu/drm/i915/i915_drv.c | 8 -------- drivers/gpu/drm/i915/i915_drv.h | 3 +-- 3 files changed, 4 insertions(+), 12 deletions(-) (limited to 'drivers/gpu/drm/i915/i915_drv.c') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 4dc76976c0d..f64ef4b723f 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1547,6 +1547,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) goto out_mtrrfree; } + /* This must be called before any calls to HAS_PCH_* */ + intel_detect_pch(dev); + intel_irq_init(dev); intel_gt_init(dev); @@ -1599,8 +1602,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) /* Start out suspended */ dev_priv->mm.suspended = 1; - intel_detect_pch(dev); - if (drm_core_check_feature(dev, DRIVER_MODESET)) { ret = i915_load_modeset_init(dev); if (ret < 0) { diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index c7e76e03a68..f2c0100e063 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -216,7 +216,6 @@ static const struct intel_device_info intel_ironlake_d_info = { .gen = 5, .need_gfx_hws = 1, .has_hotplug = 1, .has_bsd_ring = 1, - .has_pch_split = 1, }; static const struct intel_device_info intel_ironlake_m_info = { @@ -224,7 +223,6 @@ static const struct intel_device_info intel_ironlake_m_info = { .need_gfx_hws = 1, .has_hotplug = 1, .has_fbc = 1, .has_bsd_ring = 1, - .has_pch_split = 1, }; static const struct intel_device_info intel_sandybridge_d_info = { @@ -233,7 +231,6 @@ static const struct intel_device_info intel_sandybridge_d_info = { .has_bsd_ring = 1, .has_blt_ring = 1, .has_llc = 1, - .has_pch_split = 1, .has_force_wake = 1, }; @@ -244,7 +241,6 @@ static const struct intel_device_info intel_sandybridge_m_info = { .has_bsd_ring = 1, .has_blt_ring = 1, .has_llc = 1, - .has_pch_split = 1, .has_force_wake = 1, }; @@ -254,7 +250,6 @@ static const struct intel_device_info intel_ivybridge_d_info = { .has_bsd_ring = 1, .has_blt_ring = 1, .has_llc = 1, - .has_pch_split = 1, .has_force_wake = 1, }; @@ -265,7 +260,6 @@ static const struct intel_device_info intel_ivybridge_m_info = { .has_bsd_ring = 1, .has_blt_ring = 1, .has_llc = 1, - .has_pch_split = 1, .has_force_wake = 1, }; @@ -293,7 +287,6 @@ static const struct intel_device_info intel_haswell_d_info = { .has_bsd_ring = 1, .has_blt_ring = 1, .has_llc = 1, - .has_pch_split = 1, .has_force_wake = 1, }; @@ -303,7 +296,6 @@ static const struct intel_device_info intel_haswell_m_info = { .has_bsd_ring = 1, .has_blt_ring = 1, .has_llc = 1, - .has_pch_split = 1, .has_force_wake = 1, }; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 57d05c798c4..d839e4c24d6 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -288,7 +288,6 @@ struct intel_device_info { u8 is_crestline:1; 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; @@ -1121,13 +1120,13 @@ struct drm_i915_file_private { #define HAS_PIPE_CXSR(dev) (INTEL_INFO(dev)->has_pipe_cxsr) #define I915_HAS_FBC(dev) (INTEL_INFO(dev)->has_fbc) -#define HAS_PCH_SPLIT(dev) (INTEL_INFO(dev)->has_pch_split) #define HAS_PIPE_CONTROL(dev) (INTEL_INFO(dev)->gen >= 5) #define INTEL_PCH_TYPE(dev) (((struct drm_i915_private *)(dev)->dev_private)->pch_type) #define HAS_PCH_LPT(dev) (INTEL_PCH_TYPE(dev) == PCH_LPT) #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT) #define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX) +#define HAS_PCH_SPLIT(dev) (INTEL_PCH_TYPE(dev) != PCH_NONE) #define HAS_FORCE_WAKE(dev) (INTEL_INFO(dev)->has_force_wake) -- cgit v1.2.3-70-g09d2 From 40579abed0624ce1dd0e54da312566dcc5f0622a Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Tue, 3 Jul 2012 15:57:33 -0300 Subject: drm/i915: don't ironlake_init_pch_refclk() on LPT This function is used to set the PCH_DREF_CONTROL register, which does not exist on LPT anymore. Signed-off-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 2 +- drivers/gpu/drm/i915/intel_display.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/i915_drv.c') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index f2c0100e063..6edb2d5ec13 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -504,7 +504,7 @@ static int i915_drm_thaw(struct drm_device *dev) /* KMS EnterVT equivalent */ if (drm_core_check_feature(dev, DRIVER_MODESET)) { - if (HAS_PCH_SPLIT(dev)) + if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) ironlake_init_pch_refclk(dev); mutex_lock(&dev->struct_mutex); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index bd3366e755e..b5ee440cd62 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6859,7 +6859,7 @@ static void intel_setup_outputs(struct drm_device *dev) /* disable all the possible outputs/crtcs before entering KMS mode */ drm_helper_disable_unused_functions(dev); - if (HAS_PCH_SPLIT(dev)) + if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) ironlake_init_pch_refclk(dev); } -- cgit v1.2.3-70-g09d2 From d54a02c041ccfdcfe3efcd1e5b90c6e8d5e7a8d9 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 4 Jul 2012 22:18:39 +0200 Subject: drm/i915: don't trylock in the gpu reset code Simply failing to reset the gpu because someone else might still hold the mutex isn't a great idea - I see reliable silent reset failures. And gpu reset simply needs to be reliable and Just Work. "But ... the deadlocks!" We already kick all processes waiting for the gpu before launching the reset work item. New waiters need to check the wedging state anyway and then bail out. If we have places that can deadlock, we simply need to fix them. "But ... testing!" We have the gpu hangman, and if the current gpu load gem_exec_nop isn't good enough to hit a specific case, we can add a new one. "But ... don't we return -EAGAIN for non-interruptible calls to wait_seqno now?" Yep, but this problem already exists in the current code. A follow up patch will remedy this by returning -EIO for non-interruptible sleeps if the gpu died and the low-level wait bails out with -EAGAIN. Reviewed-by: Chris Wilson Tested-by: Chris Wilson Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/i915_drv.c') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 6edb2d5ec13..e754cdfaec7 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -730,8 +730,7 @@ int i915_reset(struct drm_device *dev) if (!i915_try_reset) return 0; - if (!mutex_trylock(&dev->struct_mutex)) - return -EBUSY; + mutex_lock(&dev->struct_mutex); i915_gem_reset(dev); -- cgit v1.2.3-70-g09d2 From b0071efe827f68cf173e1a8868b70618e9aca7d7 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 26 Oct 2011 00:20:57 +0200 Subject: drm: kill reclaim_buffers callback All leftover users either haven't set DRIVER_HAVE_DMA, in which case this will never be called, or use the drm_core implementation. Call that directly in the only callsite. Signed-off-by: Daniel Vetter Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_fops.c | 5 ++--- drivers/gpu/drm/gma500/psb_drv.c | 1 - drivers/gpu/drm/i915/i915_drv.c | 1 - drivers/gpu/drm/mga/mga_drv.c | 1 - drivers/gpu/drm/nouveau/nouveau_drv.c | 1 - drivers/gpu/drm/r128/r128_drv.c | 1 - drivers/gpu/drm/radeon/radeon_drv.c | 2 -- drivers/gpu/drm/tdfx/tdfx_drv.c | 1 - include/drm/drmP.h | 2 -- 9 files changed, 2 insertions(+), 13 deletions(-) (limited to 'drivers/gpu/drm/i915/i915_drv.c') diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 6cf9369e8cd..96b8c8f9c02 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -381,9 +381,8 @@ static void drm_master_release(struct drm_device *dev, struct file *filp) _DRM_LOCKING_CONTEXT(file_priv->master->lock.hw_lock->lock)); } - if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) { - dev->driver->reclaim_buffers(dev, file_priv); - } + if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) + drm_core_reclaim_buffers(dev, file_priv); } static void drm_events_release(struct drm_file *file_priv) diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c index caba6e08693..cd1dd1b14c7 100644 --- a/drivers/gpu/drm/gma500/psb_drv.c +++ b/drivers/gpu/drm/gma500/psb_drv.c @@ -632,7 +632,6 @@ static struct drm_driver driver = { .open = psb_driver_open, .preclose = psb_driver_preclose, .postclose = psb_driver_close, - .reclaim_buffers = drm_core_reclaim_buffers, .gem_init_object = psb_gem_init_object, .gem_free_object = psb_gem_free_object, diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index e754cdfaec7..ed22612bc84 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -940,7 +940,6 @@ static struct drm_driver driver = { .resume = i915_resume, .device_is_agp = i915_driver_device_is_agp, - .reclaim_buffers = drm_core_reclaim_buffers, .master_create = i915_master_create, .master_destroy = i915_master_destroy, #if defined(CONFIG_DEBUG_FS) diff --git a/drivers/gpu/drm/mga/mga_drv.c b/drivers/gpu/drm/mga/mga_drv.c index f9a925d5881..b1bb46de3f5 100644 --- a/drivers/gpu/drm/mga/mga_drv.c +++ b/drivers/gpu/drm/mga/mga_drv.c @@ -75,7 +75,6 @@ static struct drm_driver driver = { .irq_postinstall = mga_driver_irq_postinstall, .irq_uninstall = mga_driver_irq_uninstall, .irq_handler = mga_driver_irq_handler, - .reclaim_buffers = drm_core_reclaim_buffers, .ioctls = mga_ioctls, .dma_ioctl = mga_dma_buffers, .fops = &mga_driver_fops, diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index cad254c8e38..b4d1b4afcac 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -422,7 +422,6 @@ static struct drm_driver driver = { .get_vblank_counter = drm_vblank_count, .enable_vblank = nouveau_vblank_enable, .disable_vblank = nouveau_vblank_disable, - .reclaim_buffers = drm_core_reclaim_buffers, .ioctls = nouveau_ioctls, .fops = &nouveau_driver_fops, diff --git a/drivers/gpu/drm/r128/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c index 88718fad5d6..2666a5308ab 100644 --- a/drivers/gpu/drm/r128/r128_drv.c +++ b/drivers/gpu/drm/r128/r128_drv.c @@ -71,7 +71,6 @@ static struct drm_driver driver = { .irq_postinstall = r128_driver_irq_postinstall, .irq_uninstall = r128_driver_irq_uninstall, .irq_handler = r128_driver_irq_handler, - .reclaim_buffers = drm_core_reclaim_buffers, .ioctls = r128_ioctls, .dma_ioctl = r128_cce_buffers, .fops = &r128_driver_fops, diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 042fcfff3bc..dcea6f01ae4 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -262,7 +262,6 @@ static struct drm_driver driver_old = { .irq_postinstall = radeon_driver_irq_postinstall, .irq_uninstall = radeon_driver_irq_uninstall, .irq_handler = radeon_driver_irq_handler, - .reclaim_buffers = drm_core_reclaim_buffers, .ioctls = radeon_ioctls, .dma_ioctl = radeon_cp_buffers, .fops = &radeon_driver_old_fops, @@ -365,7 +364,6 @@ static struct drm_driver kms_driver = { .irq_postinstall = radeon_driver_irq_postinstall_kms, .irq_uninstall = radeon_driver_irq_uninstall_kms, .irq_handler = radeon_driver_irq_handler_kms, - .reclaim_buffers = drm_core_reclaim_buffers, .ioctls = radeon_ioctls_kms, .gem_init_object = radeon_gem_object_init, .gem_free_object = radeon_gem_object_free, diff --git a/drivers/gpu/drm/tdfx/tdfx_drv.c b/drivers/gpu/drm/tdfx/tdfx_drv.c index 1613c78544c..90f6b13acfa 100644 --- a/drivers/gpu/drm/tdfx/tdfx_drv.c +++ b/drivers/gpu/drm/tdfx/tdfx_drv.c @@ -54,7 +54,6 @@ static const struct file_operations tdfx_driver_fops = { static struct drm_driver driver = { .driver_features = DRIVER_USE_MTRR, - .reclaim_buffers = drm_core_reclaim_buffers, .fops = &tdfx_driver_fops, .name = DRIVER_NAME, .desc = DRIVER_DESC, diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 259a7619c46..022db5a768a 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -876,8 +876,6 @@ struct drm_driver { void (*irq_preinstall) (struct drm_device *dev); int (*irq_postinstall) (struct drm_device *dev); void (*irq_uninstall) (struct drm_device *dev); - void (*reclaim_buffers) (struct drm_device *dev, - struct drm_file * file_priv); void (*set_version) (struct drm_device *dev, struct drm_set_version *sv); -- cgit v1.2.3-70-g09d2 From da612d880fbc598ac0efcef579355fb90d4bca4e Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Mon, 6 Aug 2012 18:45:01 -0300 Subject: drm/i915: add more Haswell PCI IDs Also properly indent the HB IDs. Reviewed-by: Rodrigo Vivi Signed-off-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/char/agp/intel-agp.h | 39 +++++++++++++++++++++++---- drivers/char/agp/intel-gtt.c | 60 ++++++++++++++++++++++++++++++++++++++++- drivers/gpu/drm/i915/i915_drv.c | 31 ++++++++++++++++++++- 3 files changed, 123 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/drm/i915/i915_drv.c') diff --git a/drivers/char/agp/intel-agp.h b/drivers/char/agp/intel-agp.h index 57226424690..6f007b6c240 100644 --- a/drivers/char/agp/intel-agp.h +++ b/drivers/char/agp/intel-agp.h @@ -239,16 +239,45 @@ #define PCI_DEVICE_ID_INTEL_IVYBRIDGE_S_GT2_IG 0x016A #define PCI_DEVICE_ID_INTEL_VALLEYVIEW_HB 0x0F00 /* VLV1 */ #define PCI_DEVICE_ID_INTEL_VALLEYVIEW_IG 0x0F30 -#define PCI_DEVICE_ID_INTEL_HASWELL_HB 0x0400 /* Desktop */ +#define PCI_DEVICE_ID_INTEL_HASWELL_HB 0x0400 /* Desktop */ #define PCI_DEVICE_ID_INTEL_HASWELL_D_GT1_IG 0x0402 #define PCI_DEVICE_ID_INTEL_HASWELL_D_GT2_IG 0x0412 -#define PCI_DEVICE_ID_INTEL_HASWELL_M_HB 0x0404 /* Mobile */ +#define PCI_DEVICE_ID_INTEL_HASWELL_D_GT2_PLUS_IG 0x0422 +#define PCI_DEVICE_ID_INTEL_HASWELL_M_HB 0x0404 /* Mobile */ #define PCI_DEVICE_ID_INTEL_HASWELL_M_GT1_IG 0x0406 #define PCI_DEVICE_ID_INTEL_HASWELL_M_GT2_IG 0x0416 -#define PCI_DEVICE_ID_INTEL_HASWELL_S_HB 0x0408 /* Server */ +#define PCI_DEVICE_ID_INTEL_HASWELL_M_GT2_PLUS_IG 0x0426 +#define PCI_DEVICE_ID_INTEL_HASWELL_S_HB 0x0408 /* Server */ #define PCI_DEVICE_ID_INTEL_HASWELL_S_GT1_IG 0x040a #define PCI_DEVICE_ID_INTEL_HASWELL_S_GT2_IG 0x041a -#define PCI_DEVICE_ID_INTEL_HASWELL_SDV 0x0c16 /* SDV */ -#define PCI_DEVICE_ID_INTEL_HASWELL_E_HB 0x0c04 +#define PCI_DEVICE_ID_INTEL_HASWELL_S_GT2_PLUS_IG 0x042a +#define PCI_DEVICE_ID_INTEL_HASWELL_E_HB 0x0c04 +#define PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT1_IG 0x0C02 +#define PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT2_IG 0x0C12 +#define PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT2_PLUS_IG 0x0C22 +#define PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT1_IG 0x0C06 +#define PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT2_IG 0x0C16 +#define PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT2_PLUS_IG 0x0C26 +#define PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT1_IG 0x0C0A +#define PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT2_IG 0x0C1A +#define PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT2_PLUS_IG 0x0C2A +#define PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT1_IG 0x0A02 +#define PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT2_IG 0x0A12 +#define PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT2_PLUS_IG 0x0A22 +#define PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT1_IG 0x0A06 +#define PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT2_IG 0x0A16 +#define PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT2_PLUS_IG 0x0A26 +#define PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT1_IG 0x0A0A +#define PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT2_IG 0x0A1A +#define PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT2_PLUS_IG 0x0A2A +#define PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT1_IG 0x0D12 +#define PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT2_IG 0x0D22 +#define PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT2_PLUS_IG 0x0D32 +#define PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT1_IG 0x0D16 +#define PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT2_IG 0x0D26 +#define PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT2_PLUS_IG 0x0D36 +#define PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT1_IG 0x0D1A +#define PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT2_IG 0x0D2A +#define PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT2_PLUS_IG 0x0D3A #endif diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 9ed92ef5829..08fc5cbb13c 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -1502,15 +1502,73 @@ static const struct intel_gtt_driver_description { "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_D_GT2_IG, "Haswell", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_HASWELL_D_GT2_PLUS_IG, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_M_GT1_IG, "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_M_GT2_IG, "Haswell", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_HASWELL_M_GT2_PLUS_IG, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_S_GT1_IG, "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_S_GT2_IG, "Haswell", &sandybridge_gtt_driver }, - { PCI_DEVICE_ID_INTEL_HASWELL_SDV, + { PCI_DEVICE_ID_INTEL_HASWELL_S_GT2_PLUS_IG, + "Haswell", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT1_IG, + "Haswell", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT2_IG, + "Haswell", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT2_PLUS_IG, + "Haswell", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT1_IG, + "Haswell", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT2_IG, + "Haswell", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT2_PLUS_IG, + "Haswell", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT1_IG, + "Haswell", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT2_IG, + "Haswell", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT2_PLUS_IG, + "Haswell", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT1_IG, + "Haswell", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT2_IG, + "Haswell", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT2_PLUS_IG, + "Haswell", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT1_IG, + "Haswell", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT2_IG, + "Haswell", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT2_PLUS_IG, + "Haswell", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT1_IG, + "Haswell", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT2_IG, + "Haswell", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT2_PLUS_IG, + "Haswell", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT1_IG, + "Haswell", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT2_IG, + "Haswell", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT2_PLUS_IG, + "Haswell", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT1_IG, + "Haswell", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT2_IG, + "Haswell", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT2_PLUS_IG, + "Haswell", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT1_IG, + "Haswell", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT2_IG, + "Haswell", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT2_PLUS_IG, "Haswell", &sandybridge_gtt_driver }, { 0, NULL, NULL } }; diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index ed22612bc84..a24ffbe97c0 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -346,11 +346,40 @@ static const struct pci_device_id pciidlist[] = { /* aka */ INTEL_VGA_DEVICE(0x016a, &intel_ivybridge_d_info), /* GT2 server */ INTEL_VGA_DEVICE(0x0402, &intel_haswell_d_info), /* GT1 desktop */ INTEL_VGA_DEVICE(0x0412, &intel_haswell_d_info), /* GT2 desktop */ + INTEL_VGA_DEVICE(0x0422, &intel_haswell_d_info), /* GT2 desktop */ INTEL_VGA_DEVICE(0x040a, &intel_haswell_d_info), /* GT1 server */ INTEL_VGA_DEVICE(0x041a, &intel_haswell_d_info), /* GT2 server */ + INTEL_VGA_DEVICE(0x042a, &intel_haswell_d_info), /* GT2 server */ 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(0x0426, &intel_haswell_m_info), /* GT2 mobile */ + INTEL_VGA_DEVICE(0x0C02, &intel_haswell_d_info), /* SDV GT1 desktop */ + INTEL_VGA_DEVICE(0x0C12, &intel_haswell_d_info), /* SDV GT2 desktop */ + INTEL_VGA_DEVICE(0x0C22, &intel_haswell_d_info), /* SDV GT2 desktop */ + INTEL_VGA_DEVICE(0x0C0A, &intel_haswell_d_info), /* SDV GT1 server */ + INTEL_VGA_DEVICE(0x0C1A, &intel_haswell_d_info), /* SDV GT2 server */ + INTEL_VGA_DEVICE(0x0C2A, &intel_haswell_d_info), /* SDV GT2 server */ + INTEL_VGA_DEVICE(0x0C06, &intel_haswell_m_info), /* SDV GT1 mobile */ + INTEL_VGA_DEVICE(0x0C16, &intel_haswell_m_info), /* SDV GT2 mobile */ + INTEL_VGA_DEVICE(0x0C26, &intel_haswell_m_info), /* SDV GT2 mobile */ + INTEL_VGA_DEVICE(0x0A02, &intel_haswell_d_info), /* ULT GT1 desktop */ + INTEL_VGA_DEVICE(0x0A12, &intel_haswell_d_info), /* ULT GT2 desktop */ + INTEL_VGA_DEVICE(0x0A22, &intel_haswell_d_info), /* ULT GT2 desktop */ + INTEL_VGA_DEVICE(0x0A0A, &intel_haswell_d_info), /* ULT GT1 server */ + INTEL_VGA_DEVICE(0x0A1A, &intel_haswell_d_info), /* ULT GT2 server */ + INTEL_VGA_DEVICE(0x0A2A, &intel_haswell_d_info), /* ULT GT2 server */ + INTEL_VGA_DEVICE(0x0A06, &intel_haswell_m_info), /* ULT GT1 mobile */ + INTEL_VGA_DEVICE(0x0A16, &intel_haswell_m_info), /* ULT GT2 mobile */ + INTEL_VGA_DEVICE(0x0A26, &intel_haswell_m_info), /* ULT GT2 mobile */ + INTEL_VGA_DEVICE(0x0D12, &intel_haswell_d_info), /* CRW GT1 desktop */ + INTEL_VGA_DEVICE(0x0D22, &intel_haswell_d_info), /* CRW GT2 desktop */ + INTEL_VGA_DEVICE(0x0D32, &intel_haswell_d_info), /* CRW GT2 desktop */ + INTEL_VGA_DEVICE(0x0D1A, &intel_haswell_d_info), /* CRW GT1 server */ + INTEL_VGA_DEVICE(0x0D2A, &intel_haswell_d_info), /* CRW GT2 server */ + INTEL_VGA_DEVICE(0x0D3A, &intel_haswell_d_info), /* CRW GT2 server */ + INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT1 mobile */ + INTEL_VGA_DEVICE(0x0D26, &intel_haswell_m_info), /* CRW GT2 mobile */ + INTEL_VGA_DEVICE(0x0D36, &intel_haswell_m_info), /* CRW GT2 mobile */ INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info), INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info), INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info), -- cgit v1.2.3-70-g09d2