Commit f49f0586 authored by Kenneth Graunke's avatar Kenneth Graunke Committed by Chris Wilson

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: default avatarKenneth Graunke <kenneth@whitecape.org>
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
parent a6c45cf0
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "drm.h" #include "drm.h"
#include "i915_drm.h" #include "i915_drm.h"
#include "i915_drv.h" #include "i915_drv.h"
#include "intel_drv.h"
#include <linux/console.h> #include <linux/console.h>
#include "drm_crtc_helper.h" #include "drm_crtc_helper.h"
...@@ -326,6 +327,13 @@ int i915_resume(struct drm_device *dev) ...@@ -326,6 +327,13 @@ int i915_resume(struct drm_device *dev)
return i915_drm_thaw(dev); return i915_drm_thaw(dev);
} }
static int i965_reset_complete(struct drm_device *dev)
{
u8 gdrst;
pci_read_config_byte(dev->pdev, GDRST, &gdrst);
return gdrst & 0x1;
}
/** /**
* i965_reset - reset chip after a hang * i965_reset - reset chip after a hang
* @dev: drm device to reset * @dev: drm device to reset
...@@ -345,7 +353,6 @@ int i915_resume(struct drm_device *dev) ...@@ -345,7 +353,6 @@ int i915_resume(struct drm_device *dev)
int i965_reset(struct drm_device *dev, u8 flags) int i965_reset(struct drm_device *dev, u8 flags)
{ {
drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_private_t *dev_priv = dev->dev_private;
unsigned long timeout;
u8 gdrst; u8 gdrst;
/* /*
* We really should only reset the display subsystem if we actually * 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,23 +371,15 @@ int i965_reset(struct drm_device *dev, u8 flags)
i915_save_display(dev); i915_save_display(dev);
/* /*
* Set the domains we want to reset, then the reset bit (bit 0). * Set the domains we want to reset (GRDOM/bits 2 and 3) as
* Clear the reset bit after a while and wait for hardware status * well as the reset bit (GR/bit 0). Setting the GR bit
* bit (bit 1) to be set * triggers the reset; when done, the hardware will clear it.
*/ */
pci_read_config_byte(dev->pdev, GDRST, &gdrst); pci_read_config_byte(dev->pdev, GDRST, &gdrst);
pci_write_config_byte(dev->pdev, GDRST, gdrst | flags | ((flags == GDRST_FULL) ? 0x1 : 0x0)); pci_write_config_byte(dev->pdev, GDRST, gdrst | flags | 0x1);
udelay(50);
pci_write_config_byte(dev->pdev, GDRST, gdrst & 0xfe);
/* ...we don't want to loop forever though, 500ms should be plenty */
timeout = jiffies + msecs_to_jiffies(500);
do {
udelay(100);
pci_read_config_byte(dev->pdev, GDRST, &gdrst);
} while ((gdrst & 0x1) && time_after(timeout, jiffies));
if (gdrst & 0x1) { /* Wait for the hardware to reset (but no more than 500 ms) */
if (wait_for(i965_reset_complete(dev), 500)) {
WARN(true, "i915: Failed to reset chip\n"); WARN(true, "i915: Failed to reset chip\n");
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
return -EIO; return -EIO;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment