Skip to content

Commit

Permalink
drm/i915: Add support for GPU soft reset on Ironlake.
Browse files Browse the repository at this point in the history
Ironlake's graphics reset register has to be accessed via the MCHBAR,
rather than via PCI config space, which requires some refactoring.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
  • Loading branch information
Kenneth Graunke authored and Chris Wilson committed Sep 21, 2010
1 parent eeccdca commit 0573ed4
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 7 deletions.
30 changes: 24 additions & 6 deletions drivers/gpu/drm/i915/i915_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,24 @@ static int i965_reset_complete(struct drm_device *dev)
return gdrst & 0x1;
}

static int i965_do_reset(struct drm_device *dev, u8 flags)
{
u8 gdrst;

pci_read_config_byte(dev->pdev, I965_GDRST, &gdrst);
pci_write_config_byte(dev->pdev, I965_GDRST, gdrst | flags | 0x1);

return wait_for(i965_reset_complete(dev), 500);
}

static int ironlake_do_reset(struct drm_device *dev, u8 flags)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u32 gdrst = I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR);
I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR, gdrst | flags | 0x1);
return wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500);
}

/**
* i965_reset - reset chip after a hang
* @dev: drm device to reset
Expand All @@ -353,12 +371,12 @@ static int i965_reset_complete(struct drm_device *dev)
int i965_reset(struct drm_device *dev, u8 flags)
{
drm_i915_private_t *dev_priv = dev->dev_private;
u8 gdrst;
/*
* We really should only reset the display subsystem if we actually
* need to
*/
bool need_display = true;
int ret;

mutex_lock(&dev->struct_mutex);

Expand All @@ -375,11 +393,11 @@ int i965_reset(struct drm_device *dev, u8 flags)
* well as the reset bit (GR/bit 0). Setting the GR bit
* triggers the reset; when done, the hardware will clear it.
*/
pci_read_config_byte(dev->pdev, I965_GDRST, &gdrst);
pci_write_config_byte(dev->pdev, I965_GDRST, gdrst | flags | 0x1);

/* Wait for the hardware to reset (but no more than 500 ms) */
if (wait_for(i965_reset_complete(dev), 500)) {
if (IS_IRONLAKE(dev))
ret = ironlake_do_reset(dev, flags);
else
ret = i965_do_reset(dev, flags);
if (ret) {
WARN(true, "i915: Failed to reset chip\n");
mutex_unlock(&dev->struct_mutex);
return -EIO;
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/i915_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@ static void i915_error_work_func(struct work_struct *work)

if (atomic_read(&dev_priv->mm.wedged)) {
switch (INTEL_INFO(dev)->gen) {
case 5:
case 4:
DRM_DEBUG_DRIVER("resetting chip\n");
kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_event);
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/i915/i915_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@
#define LBB 0xf4

/* Graphics reset regs */
#define I965_GDRST 0xc0
#define I965_GDRST 0xc0 /* PCI config register */
#define ILK_GDSR 0x2ca4 /* MCHBAR offset */
#define GRDOM_FULL (0<<2)
#define GRDOM_RENDER (1<<2)
#define GRDOM_MEDIA (3<<2)
Expand Down

0 comments on commit 0573ed4

Please sign in to comment.