diff options
| -rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 54 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.h | 1 |
3 files changed, 36 insertions, 20 deletions
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 9f5b18d9d885..c77af69c2d8f 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
| @@ -827,6 +827,7 @@ enum punit_power_well { | |||
| 827 | # define MI_FLUSH_ENABLE (1 << 12) | 827 | # define MI_FLUSH_ENABLE (1 << 12) |
| 828 | # define ASYNC_FLIP_PERF_DISABLE (1 << 14) | 828 | # define ASYNC_FLIP_PERF_DISABLE (1 << 14) |
| 829 | # define MODE_IDLE (1 << 9) | 829 | # define MODE_IDLE (1 << 9) |
| 830 | # define STOP_RING (1 << 8) | ||
| 830 | 831 | ||
| 831 | #define GEN6_GT_MODE 0x20d0 | 832 | #define GEN6_GT_MODE 0x20d0 |
| 832 | #define GEN7_GT_MODE 0x7008 | 833 | #define GEN7_GT_MODE 0x7008 |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 6bc68bdcf433..79fb4cc2137c 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
| @@ -437,32 +437,41 @@ static void ring_setup_phys_status_page(struct intel_ring_buffer *ring) | |||
| 437 | I915_WRITE(HWS_PGA, addr); | 437 | I915_WRITE(HWS_PGA, addr); |
| 438 | } | 438 | } |
| 439 | 439 | ||
| 440 | static int init_ring_common(struct intel_ring_buffer *ring) | 440 | static bool stop_ring(struct intel_ring_buffer *ring) |
| 441 | { | 441 | { |
| 442 | struct drm_device *dev = ring->dev; | 442 | struct drm_i915_private *dev_priv = to_i915(ring->dev); |
| 443 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 444 | struct drm_i915_gem_object *obj = ring->obj; | ||
| 445 | int ret = 0; | ||
| 446 | u32 head; | ||
| 447 | 443 | ||
| 448 | gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL); | 444 | if (!IS_GEN2(ring->dev)) { |
| 445 | I915_WRITE_MODE(ring, _MASKED_BIT_ENABLE(STOP_RING)); | ||
| 446 | if (wait_for_atomic((I915_READ_MODE(ring) & MODE_IDLE) != 0, 1000)) { | ||
| 447 | DRM_ERROR("%s :timed out trying to stop ring\n", ring->name); | ||
| 448 | return false; | ||
| 449 | } | ||
| 450 | } | ||
| 449 | 451 | ||
| 450 | /* Stop the ring if it's running. */ | ||
| 451 | I915_WRITE_CTL(ring, 0); | 452 | I915_WRITE_CTL(ring, 0); |
| 452 | I915_WRITE_HEAD(ring, 0); | 453 | I915_WRITE_HEAD(ring, 0); |
| 453 | ring->write_tail(ring, 0); | 454 | ring->write_tail(ring, 0); |
| 454 | if (wait_for_atomic((I915_READ_MODE(ring) & MODE_IDLE) != 0, 1000)) | ||
| 455 | DRM_ERROR("%s :timed out trying to stop ring\n", ring->name); | ||
| 456 | 455 | ||
| 457 | if (I915_NEED_GFX_HWS(dev)) | 456 | if (!IS_GEN2(ring->dev)) { |
| 458 | intel_ring_setup_status_page(ring); | 457 | (void)I915_READ_CTL(ring); |
| 459 | else | 458 | I915_WRITE_MODE(ring, _MASKED_BIT_DISABLE(STOP_RING)); |
| 460 | ring_setup_phys_status_page(ring); | 459 | } |
| 461 | 460 | ||
| 462 | head = I915_READ_HEAD(ring) & HEAD_ADDR; | 461 | return (I915_READ_HEAD(ring) & HEAD_ADDR) == 0; |
| 462 | } | ||
| 463 | 463 | ||
| 464 | /* G45 ring initialization fails to reset head to zero */ | 464 | static int init_ring_common(struct intel_ring_buffer *ring) |
| 465 | if (head != 0) { | 465 | { |
| 466 | struct drm_device *dev = ring->dev; | ||
| 467 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 468 | struct drm_i915_gem_object *obj = ring->obj; | ||
| 469 | int ret = 0; | ||
| 470 | |||
| 471 | gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL); | ||
| 472 | |||
| 473 | if (!stop_ring(ring)) { | ||
| 474 | /* G45 ring initialization often fails to reset head to zero */ | ||
| 466 | DRM_DEBUG_KMS("%s head not reset to zero " | 475 | DRM_DEBUG_KMS("%s head not reset to zero " |
| 467 | "ctl %08x head %08x tail %08x start %08x\n", | 476 | "ctl %08x head %08x tail %08x start %08x\n", |
| 468 | ring->name, | 477 | ring->name, |
| @@ -471,9 +480,7 @@ static int init_ring_common(struct intel_ring_buffer *ring) | |||
| 471 | I915_READ_TAIL(ring), | 480 | I915_READ_TAIL(ring), |
| 472 | I915_READ_START(ring)); | 481 | I915_READ_START(ring)); |
| 473 | 482 | ||
| 474 | I915_WRITE_HEAD(ring, 0); | 483 | if (!stop_ring(ring)) { |
| 475 | |||
| 476 | if (I915_READ_HEAD(ring) & HEAD_ADDR) { | ||
| 477 | DRM_ERROR("failed to set %s head to zero " | 484 | DRM_ERROR("failed to set %s head to zero " |
| 478 | "ctl %08x head %08x tail %08x start %08x\n", | 485 | "ctl %08x head %08x tail %08x start %08x\n", |
| 479 | ring->name, | 486 | ring->name, |
| @@ -481,9 +488,16 @@ static int init_ring_common(struct intel_ring_buffer *ring) | |||
| 481 | I915_READ_HEAD(ring), | 488 | I915_READ_HEAD(ring), |
| 482 | I915_READ_TAIL(ring), | 489 | I915_READ_TAIL(ring), |
| 483 | I915_READ_START(ring)); | 490 | I915_READ_START(ring)); |
| 491 | ret = -EIO; | ||
| 492 | goto out; | ||
| 484 | } | 493 | } |
| 485 | } | 494 | } |
| 486 | 495 | ||
| 496 | if (I915_NEED_GFX_HWS(dev)) | ||
| 497 | intel_ring_setup_status_page(ring); | ||
| 498 | else | ||
| 499 | ring_setup_phys_status_page(ring); | ||
| 500 | |||
| 487 | /* Initialize the ring. This must happen _after_ we've cleared the ring | 501 | /* Initialize the ring. This must happen _after_ we've cleared the ring |
| 488 | * registers with the above sequence (the readback of the HEAD registers | 502 | * registers with the above sequence (the readback of the HEAD registers |
| 489 | * also enforces ordering), otherwise the hw might lose the new ring | 503 | * also enforces ordering), otherwise the hw might lose the new ring |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 270a6a973438..2b91c4b4d34b 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h | |||
| @@ -34,6 +34,7 @@ struct intel_hw_status_page { | |||
| 34 | #define I915_WRITE_IMR(ring, val) I915_WRITE(RING_IMR((ring)->mmio_base), val) | 34 | #define I915_WRITE_IMR(ring, val) I915_WRITE(RING_IMR((ring)->mmio_base), val) |
| 35 | 35 | ||
| 36 | #define I915_READ_MODE(ring) I915_READ(RING_MI_MODE((ring)->mmio_base)) | 36 | #define I915_READ_MODE(ring) I915_READ(RING_MI_MODE((ring)->mmio_base)) |
| 37 | #define I915_WRITE_MODE(ring, val) I915_WRITE(RING_MI_MODE((ring)->mmio_base), val) | ||
| 37 | 38 | ||
| 38 | enum intel_ring_hangcheck_action { | 39 | enum intel_ring_hangcheck_action { |
| 39 | HANGCHECK_IDLE = 0, | 40 | HANGCHECK_IDLE = 0, |
