From fc61901373987ad61851ed001fe971f3ee8d96a3 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 2 Dec 2009 11:00:05 +0000 Subject: [PATCH 1/5] agp/intel-agp: Clear entire GTT on startup Some BIOSes fail to initialise the GTT, which will cause DMA faults when the IOMMU is enabled. We need to clear the whole thing to point at the scratch page, not just the part that Linux is going to use. Signed-off-by: David Woodhouse [anholt: Note that this may also help with stability in the presence of driver bugs, by not drawing to memory we don't own] Signed-off-by: Eric Anholt --- drivers/char/agp/intel-agp.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 37cb4e2b232..33b4853b135 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -176,6 +176,7 @@ static struct _intel_private { * popup and for the GTT. */ int gtt_entries; /* i830+ */ + int gtt_total_size; union { void __iomem *i9xx_flush_page; void *i8xx_flush_page; @@ -1151,7 +1152,7 @@ static int intel_i915_configure(void) readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */ if (agp_bridge->driver->needs_scratch_page) { - for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) { + for (i = intel_private.gtt_entries; i < intel_private.gtt_total_size; i++) { writel(agp_bridge->scratch_page, intel_private.gtt+i); } readl(intel_private.gtt+i-1); /* PCI Posting. */ @@ -1312,6 +1313,8 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) if (!intel_private.gtt) return -ENOMEM; + intel_private.gtt_total_size = gtt_map_size / 4; + temp &= 0xfff80000; intel_private.registers = ioremap(temp, 128 * 4096); @@ -1398,6 +1401,8 @@ static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge) if (!intel_private.gtt) return -ENOMEM; + intel_private.gtt_total_size = gtt_size / 4; + intel_private.registers = ioremap(temp, 128 * 4096); if (!intel_private.registers) { iounmap(intel_private.gtt); From fcffb947668073fd9c47da33f8e72add7f62163d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 2 Dec 2009 16:48:57 +0000 Subject: [PATCH 2/5] drm/i915: Report purgeable status in buffer lists. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_debugfs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index eeed4e34c75..18476bf0b58 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -97,13 +97,14 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) { struct drm_gem_object *obj = obj_priv->obj; - seq_printf(m, " %p: %s %8zd %08x %08x %d %s", + seq_printf(m, " %p: %s %8zd %08x %08x %d%s%s", obj, get_pin_flag(obj_priv), obj->size, obj->read_domains, obj->write_domain, obj_priv->last_rendering_seqno, - obj_priv->dirty ? "dirty" : ""); + obj_priv->dirty ? " dirty" : "", + obj_priv->madv == I915_MADV_DONTNEED ? " purgeable" : ""); if (obj->name) seq_printf(m, " (name: %d)", obj->name); From 5618ca6abc2d6f475b258badc017a5254cf43d1b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 2 Dec 2009 15:15:30 +0000 Subject: [PATCH 3/5] drm/i915: Set the error code after failing to insert new offset into mm ht. Signed-off-by: Chris Wilson Cc: stable@kernel.org Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_gem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 5b46623d62d..917b8377ae2 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1288,6 +1288,7 @@ i915_gem_create_mmap_offset(struct drm_gem_object *obj) list->hash.key = list->file_offset_node->start; if (drm_ht_insert_item(&mm->offset_hash, &list->hash)) { DRM_ERROR("failed to add to map hash\n"); + ret = -ENOMEM; goto out_free_mm; } From 7e8b60faea972604c315634cff62d44803731ea9 Mon Sep 17 00:00:00 2001 From: Andrew Lutomirski Date: Sun, 8 Nov 2009 13:49:51 -0500 Subject: [PATCH 4/5] drm/i915: restore render clock gating on resume Rather than restoring just a few clock gating registers on resume, just reinitialize the whole thing. Signed-off-by: Andy Lutomirski [anholt: Fixed up for RC6 support landed since the patch was written] Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_drv.h | 2 -- drivers/gpu/drm/i915/i915_suspend.c | 7 +---- drivers/gpu/drm/i915/intel_display.c | 39 ++++++++++++++++------------ drivers/gpu/drm/i915/intel_drv.h | 1 + 4 files changed, 24 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index e28d6c9a0ae..1d617108729 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -381,8 +381,6 @@ typedef struct drm_i915_private { u32 saveFDI_RXA_IMR; u32 saveFDI_RXB_IMR; u32 saveCACHE_MODE_0; - u32 saveD_STATE; - u32 saveDSPCLK_GATE_D; u32 saveMI_ARB_STATE; u32 saveSWF0[16]; u32 saveSWF1[16]; diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 402a7eb2922..00f6d97c7cc 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -722,10 +722,6 @@ int i915_save_state(struct drm_device *dev) dev_priv->saveIMR = I915_READ(IMR); } - /* Clock gating state */ - dev_priv->saveD_STATE = I915_READ(D_STATE); - dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D); /* Not sure about this */ - /* Cache mode state */ dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); @@ -800,8 +796,7 @@ int i915_restore_state(struct drm_device *dev) } /* Clock gating state */ - I915_WRITE (D_STATE, dev_priv->saveD_STATE); - I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D); + intel_init_clock_gating(dev); /* Cache mode state */ I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 902cc5386f1..279dc96e3eb 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4584,28 +4584,33 @@ void intel_init_clock_gating(struct drm_device *dev) struct drm_i915_gem_object *obj_priv; int ret; - pwrctx = drm_gem_object_alloc(dev, 4096); - if (!pwrctx) { - DRM_DEBUG("failed to alloc power context, RC6 disabled\n"); - goto out; + if (dev_priv->pwrctx) { + obj_priv = dev_priv->pwrctx->driver_private; + } else { + pwrctx = drm_gem_object_alloc(dev, 4096); + if (!pwrctx) { + DRM_DEBUG("failed to alloc power context, " + "RC6 disabled\n"); + goto out; + } + + ret = i915_gem_object_pin(pwrctx, 4096); + if (ret) { + DRM_ERROR("failed to pin power context: %d\n", + ret); + drm_gem_object_unreference(pwrctx); + goto out; + } + + i915_gem_object_set_to_gtt_domain(pwrctx, 1); + + dev_priv->pwrctx = pwrctx; + obj_priv = pwrctx->driver_private; } - ret = i915_gem_object_pin(pwrctx, 4096); - if (ret) { - DRM_ERROR("failed to pin power context: %d\n", ret); - drm_gem_object_unreference(pwrctx); - goto out; - } - - i915_gem_object_set_to_gtt_domain(pwrctx, 1); - - obj_priv = pwrctx->driver_private; - I915_WRITE(PWRCTXA, obj_priv->gtt_offset | PWRCTX_EN); I915_WRITE(MCHBAR_RENDER_STANDBY, I915_READ(MCHBAR_RENDER_STANDBY) & ~RCX_SW_EXIT); - - dev_priv->pwrctx = pwrctx; } out: diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 9ffa31e13eb..a51573da1ff 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -208,6 +208,7 @@ extern void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, u16 blue, int regno); extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, u16 *blue, int regno); +extern void intel_init_clock_gating(struct drm_device *dev); extern int intel_framebuffer_create(struct drm_device *dev, struct drm_mode_fb_cmd *mode_cmd, From 4f8d619cc3ab805aa1726c1dfe196a0705b955bd Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 8 Dec 2009 22:12:06 +0000 Subject: [PATCH 5/5] drm/i915: Remove a debugging printk from hangcheck A residual bare printk survived the merger of the hang detector, remove this debugging left-over. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_irq.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a31c9d5e29f..a1345d78e13 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -538,7 +538,6 @@ static void i915_handle_error(struct drm_device *dev, bool wedged) /* * Wakeup waiting processes so they don't hang */ - printk("i915: Waking up sleeping processes\n"); DRM_WAKEUP(&dev_priv->irq_queue); }