diff options
author | Kenneth Graunke <kenneth@whitecape.org> | 2010-09-11 06:17:19 -0400 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-09-21 06:19:48 -0400 |
commit | 0573ed4a947d7a563db197511611d8a9039feb41 (patch) | |
tree | 21355b9a4ca6549eccad99b62e0f5addc38186c4 | |
parent | eeccdcac07c1e21d25e7d3cf70030059a3017f0c (diff) |
drm/i915: Add support for GPU soft reset on Ironlake.
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>
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.c | 30 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 3 |
3 files changed, 27 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 45027d5ad1e5..e88aabdfd1d9 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -334,6 +334,24 @@ static int i965_reset_complete(struct drm_device *dev) | |||
334 | return gdrst & 0x1; | 334 | return gdrst & 0x1; |
335 | } | 335 | } |
336 | 336 | ||
337 | static int i965_do_reset(struct drm_device *dev, u8 flags) | ||
338 | { | ||
339 | u8 gdrst; | ||
340 | |||
341 | pci_read_config_byte(dev->pdev, I965_GDRST, &gdrst); | ||
342 | pci_write_config_byte(dev->pdev, I965_GDRST, gdrst | flags | 0x1); | ||
343 | |||
344 | return wait_for(i965_reset_complete(dev), 500); | ||
345 | } | ||
346 | |||
347 | static int ironlake_do_reset(struct drm_device *dev, u8 flags) | ||
348 | { | ||
349 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
350 | u32 gdrst = I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR); | ||
351 | I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR, gdrst | flags | 0x1); | ||
352 | return wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500); | ||
353 | } | ||
354 | |||
337 | /** | 355 | /** |
338 | * i965_reset - reset chip after a hang | 356 | * i965_reset - reset chip after a hang |
339 | * @dev: drm device to reset | 357 | * @dev: drm device to reset |
@@ -353,12 +371,12 @@ static int i965_reset_complete(struct drm_device *dev) | |||
353 | int i965_reset(struct drm_device *dev, u8 flags) | 371 | int i965_reset(struct drm_device *dev, u8 flags) |
354 | { | 372 | { |
355 | drm_i915_private_t *dev_priv = dev->dev_private; | 373 | drm_i915_private_t *dev_priv = dev->dev_private; |
356 | u8 gdrst; | ||
357 | /* | 374 | /* |
358 | * We really should only reset the display subsystem if we actually | 375 | * We really should only reset the display subsystem if we actually |
359 | * need to | 376 | * need to |
360 | */ | 377 | */ |
361 | bool need_display = true; | 378 | bool need_display = true; |
379 | int ret; | ||
362 | 380 | ||
363 | mutex_lock(&dev->struct_mutex); | 381 | mutex_lock(&dev->struct_mutex); |
364 | 382 | ||
@@ -375,11 +393,11 @@ int i965_reset(struct drm_device *dev, u8 flags) | |||
375 | * well as the reset bit (GR/bit 0). Setting the GR bit | 393 | * well as the reset bit (GR/bit 0). Setting the GR bit |
376 | * triggers the reset; when done, the hardware will clear it. | 394 | * triggers the reset; when done, the hardware will clear it. |
377 | */ | 395 | */ |
378 | pci_read_config_byte(dev->pdev, I965_GDRST, &gdrst); | 396 | if (IS_IRONLAKE(dev)) |
379 | pci_write_config_byte(dev->pdev, I965_GDRST, gdrst | flags | 0x1); | 397 | ret = ironlake_do_reset(dev, flags); |
380 | 398 | else | |
381 | /* Wait for the hardware to reset (but no more than 500 ms) */ | 399 | ret = i965_do_reset(dev, flags); |
382 | if (wait_for(i965_reset_complete(dev), 500)) { | 400 | if (ret) { |
383 | WARN(true, "i915: Failed to reset chip\n"); | 401 | WARN(true, "i915: Failed to reset chip\n"); |
384 | mutex_unlock(&dev->struct_mutex); | 402 | mutex_unlock(&dev->struct_mutex); |
385 | return -EIO; | 403 | return -EIO; |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index b1dc943a02cc..a5197e13d942 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -398,6 +398,7 @@ static void i915_error_work_func(struct work_struct *work) | |||
398 | 398 | ||
399 | if (atomic_read(&dev_priv->mm.wedged)) { | 399 | if (atomic_read(&dev_priv->mm.wedged)) { |
400 | switch (INTEL_INFO(dev)->gen) { | 400 | switch (INTEL_INFO(dev)->gen) { |
401 | case 5: | ||
401 | case 4: | 402 | case 4: |
402 | DRM_DEBUG_DRIVER("resetting chip\n"); | 403 | DRM_DEBUG_DRIVER("resetting chip\n"); |
403 | kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_event); | 404 | kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_event); |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 565a7a3ccd4e..b46e580421e1 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -110,7 +110,8 @@ | |||
110 | #define LBB 0xf4 | 110 | #define LBB 0xf4 |
111 | 111 | ||
112 | /* Graphics reset regs */ | 112 | /* Graphics reset regs */ |
113 | #define I965_GDRST 0xc0 | 113 | #define I965_GDRST 0xc0 /* PCI config register */ |
114 | #define ILK_GDSR 0x2ca4 /* MCHBAR offset */ | ||
114 | #define GRDOM_FULL (0<<2) | 115 | #define GRDOM_FULL (0<<2) |
115 | #define GRDOM_RENDER (1<<2) | 116 | #define GRDOM_RENDER (1<<2) |
116 | #define GRDOM_MEDIA (3<<2) | 117 | #define GRDOM_MEDIA (3<<2) |