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 /drivers/gpu/drm/i915/i915_drv.c | |
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>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_drv.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.c | 30 |
1 files changed, 24 insertions, 6 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; |