aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorKenneth Graunke <kenneth@whitecape.org>2010-09-11 04:19:14 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2010-09-21 06:19:46 -0400
commitf49f0586191fe16140410db0a46d43bdc690d6af (patch)
tree7a0b0022678af746c6f3f6378334ae856c0b8728 /drivers/gpu/drm
parenta6c45cf013a57e32ddae43dd4ac911eb4a3919fd (diff)
drm/i915: Actually set the reset bit in i965_reset.
Previously, it was only being set if passed GDRST_FULL - but the only caller passed GDRST_RENDER. So the hardware never actually reset. The comments also did not match the code. Instead, just set the reset bit regardless of what flags were passed. The GPU now resets correctly on my GM45. Signed-off-by: Kenneth Graunke <kenneth@whitecape.org> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c31
1 files changed, 15 insertions, 16 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 87c6b5f81fea..7209997f18fe 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -32,6 +32,7 @@
32#include "drm.h" 32#include "drm.h"
33#include "i915_drm.h" 33#include "i915_drm.h"
34#include "i915_drv.h" 34#include "i915_drv.h"
35#include "intel_drv.h"
35 36
36#include <linux/console.h> 37#include <linux/console.h>
37#include "drm_crtc_helper.h" 38#include "drm_crtc_helper.h"
@@ -326,6 +327,13 @@ int i915_resume(struct drm_device *dev)
326 return i915_drm_thaw(dev); 327 return i915_drm_thaw(dev);
327} 328}
328 329
330static int i965_reset_complete(struct drm_device *dev)
331{
332 u8 gdrst;
333 pci_read_config_byte(dev->pdev, GDRST, &gdrst);
334 return gdrst & 0x1;
335}
336
329/** 337/**
330 * i965_reset - reset chip after a hang 338 * i965_reset - reset chip after a hang
331 * @dev: drm device to reset 339 * @dev: drm device to reset
@@ -345,7 +353,6 @@ int i915_resume(struct drm_device *dev)
345int i965_reset(struct drm_device *dev, u8 flags) 353int i965_reset(struct drm_device *dev, u8 flags)
346{ 354{
347 drm_i915_private_t *dev_priv = dev->dev_private; 355 drm_i915_private_t *dev_priv = dev->dev_private;
348 unsigned long timeout;
349 u8 gdrst; 356 u8 gdrst;
350 /* 357 /*
351 * We really should only reset the display subsystem if we actually 358 * We really should only reset the display subsystem if we actually
@@ -364,23 +371,15 @@ int i965_reset(struct drm_device *dev, u8 flags)
364 i915_save_display(dev); 371 i915_save_display(dev);
365 372
366 /* 373 /*
367 * Set the domains we want to reset, then the reset bit (bit 0). 374 * Set the domains we want to reset (GRDOM/bits 2 and 3) as
368 * Clear the reset bit after a while and wait for hardware status 375 * well as the reset bit (GR/bit 0). Setting the GR bit
369 * bit (bit 1) to be set 376 * triggers the reset; when done, the hardware will clear it.
370 */ 377 */
371 pci_read_config_byte(dev->pdev, GDRST, &gdrst); 378 pci_read_config_byte(dev->pdev, GDRST, &gdrst);
372 pci_write_config_byte(dev->pdev, GDRST, gdrst | flags | ((flags == GDRST_FULL) ? 0x1 : 0x0)); 379 pci_write_config_byte(dev->pdev, GDRST, gdrst | flags | 0x1);
373 udelay(50); 380
374 pci_write_config_byte(dev->pdev, GDRST, gdrst & 0xfe); 381 /* Wait for the hardware to reset (but no more than 500 ms) */
375 382 if (wait_for(i965_reset_complete(dev), 500)) {
376 /* ...we don't want to loop forever though, 500ms should be plenty */
377 timeout = jiffies + msecs_to_jiffies(500);
378 do {
379 udelay(100);
380 pci_read_config_byte(dev->pdev, GDRST, &gdrst);
381 } while ((gdrst & 0x1) && time_after(timeout, jiffies));
382
383 if (gdrst & 0x1) {
384 WARN(true, "i915: Failed to reset chip\n"); 383 WARN(true, "i915: Failed to reset chip\n");
385 mutex_unlock(&dev->struct_mutex); 384 mutex_unlock(&dev->struct_mutex);
386 return -EIO; 385 return -EIO;