aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-03-21 08:41:53 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-03-28 13:33:14 -0400
commit508774452d657e8d307e1c52682ffcdf743e992d (patch)
tree9d8c23de3d6aaa7f6de0fd18c85c0c8c324cf30e /drivers/gpu/drm
parent5d708680eac2a8e2a0981007278a759df738d15b (diff)
drm/i915: Broadwell expands ACTHD to 64bit
As Broadwell has an increased virtual address size, it requires more than 32 bits to store offsets into its address space. This includes the debug registers to track the current HEAD of the individual rings, which may be anywhere within the per-process address spaces. In order to find the full location, we need to read the high bits from a second register. We then also need to expand our storage to keep track of the larger address. v2: Carefully read the two registers to catch wraparound between the reads. v3: Use a WARN_ON rather than loop indefinitely on an unstable register read. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Ben Widawsky <benjamin.widawsky@intel.com> Cc: Timo Aaltonen <tjaalton@ubuntu.com> Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com> Reviewed-by: Ben Widawsky <ben@bwidawsk.net> [danvet: Drop spurious hunk which conflicted.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h13
-rw-r--r--drivers/gpu/drm/i915/i915_gpu_error.c2
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c5
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h1
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c22
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.h6
6 files changed, 36 insertions, 13 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 7b344c5300f0..537404b9f760 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -351,12 +351,12 @@ struct drm_i915_error_state {
351 u32 ipeir; 351 u32 ipeir;
352 u32 ipehr; 352 u32 ipehr;
353 u32 instdone; 353 u32 instdone;
354 u32 acthd;
355 u32 bbstate; 354 u32 bbstate;
356 u32 instpm; 355 u32 instpm;
357 u32 instps; 356 u32 instps;
358 u32 seqno; 357 u32 seqno;
359 u64 bbaddr; 358 u64 bbaddr;
359 u64 acthd;
360 u32 fault_reg; 360 u32 fault_reg;
361 u32 faddr; 361 u32 faddr;
362 u32 rc_psmi; /* sleep state */ 362 u32 rc_psmi; /* sleep state */
@@ -2746,6 +2746,17 @@ void vlv_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine);
2746#define I915_WRITE64(reg, val) dev_priv->uncore.funcs.mmio_writeq(dev_priv, (reg), (val), true) 2746#define I915_WRITE64(reg, val) dev_priv->uncore.funcs.mmio_writeq(dev_priv, (reg), (val), true)
2747#define I915_READ64(reg) dev_priv->uncore.funcs.mmio_readq(dev_priv, (reg), true) 2747#define I915_READ64(reg) dev_priv->uncore.funcs.mmio_readq(dev_priv, (reg), true)
2748 2748
2749#define I915_READ64_2x32(lower_reg, upper_reg) ({ \
2750 u32 upper = I915_READ(upper_reg); \
2751 u32 lower = I915_READ(lower_reg); \
2752 u32 tmp = I915_READ(upper_reg); \
2753 if (upper != tmp) { \
2754 upper = tmp; \
2755 lower = I915_READ(lower_reg); \
2756 WARN_ON(I915_READ(upper_reg) != upper); \
2757 } \
2758 (u64)upper << 32 | lower; })
2759
2749#define POSTING_READ(reg) (void)I915_READ_NOTRACE(reg) 2760#define POSTING_READ(reg) (void)I915_READ_NOTRACE(reg)
2750#define POSTING_READ16(reg) (void)I915_READ16_NOTRACE(reg) 2761#define POSTING_READ16(reg) (void)I915_READ16_NOTRACE(reg)
2751 2762
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index baf1ca690dc5..ed1fac7f945c 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -247,7 +247,7 @@ static void i915_ring_error_state(struct drm_i915_error_state_buf *m,
247 err_printf(m, " TAIL: 0x%08x\n", ring->tail); 247 err_printf(m, " TAIL: 0x%08x\n", ring->tail);
248 err_printf(m, " CTL: 0x%08x\n", ring->ctl); 248 err_printf(m, " CTL: 0x%08x\n", ring->ctl);
249 err_printf(m, " HWS: 0x%08x\n", ring->hws); 249 err_printf(m, " HWS: 0x%08x\n", ring->hws);
250 err_printf(m, " ACTHD: 0x%08x\n", ring->acthd); 250 err_printf(m, " ACTHD: 0x%08llx\n", ring->acthd);
251 err_printf(m, " IPEIR: 0x%08x\n", ring->ipeir); 251 err_printf(m, " IPEIR: 0x%08x\n", ring->ipeir);
252 err_printf(m, " IPEHR: 0x%08x\n", ring->ipehr); 252 err_printf(m, " IPEHR: 0x%08x\n", ring->ipehr);
253 err_printf(m, " INSTDONE: 0x%08x\n", ring->instdone); 253 err_printf(m, " INSTDONE: 0x%08x\n", ring->instdone);
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index df2f3007d8c5..5e353a4af921 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2600,7 +2600,7 @@ static void semaphore_clear_deadlocks(struct drm_i915_private *dev_priv)
2600} 2600}
2601 2601
2602static enum intel_ring_hangcheck_action 2602static enum intel_ring_hangcheck_action
2603ring_stuck(struct intel_ring_buffer *ring, u32 acthd) 2603ring_stuck(struct intel_ring_buffer *ring, u64 acthd)
2604{ 2604{
2605 struct drm_device *dev = ring->dev; 2605 struct drm_device *dev = ring->dev;
2606 struct drm_i915_private *dev_priv = dev->dev_private; 2606 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -2668,7 +2668,8 @@ static void i915_hangcheck_elapsed(unsigned long data)
2668 return; 2668 return;
2669 2669
2670 for_each_ring(ring, dev_priv, i) { 2670 for_each_ring(ring, dev_priv, i) {
2671 u32 seqno, acthd; 2671 u64 acthd;
2672 u32 seqno;
2672 bool busy = true; 2673 bool busy = true;
2673 2674
2674 semaphore_clear_deadlocks(dev_priv); 2675 semaphore_clear_deadlocks(dev_priv);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index d90dc20077e3..9f5b18d9d885 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -706,6 +706,7 @@ enum punit_power_well {
706#define BLT_HWS_PGA_GEN7 (0x04280) 706#define BLT_HWS_PGA_GEN7 (0x04280)
707#define VEBOX_HWS_PGA_GEN7 (0x04380) 707#define VEBOX_HWS_PGA_GEN7 (0x04380)
708#define RING_ACTHD(base) ((base)+0x74) 708#define RING_ACTHD(base) ((base)+0x74)
709#define RING_ACTHD_UDW(base) ((base)+0x5c)
709#define RING_NOPID(base) ((base)+0x94) 710#define RING_NOPID(base) ((base)+0x94)
710#define RING_IMR(base) ((base)+0xa8) 711#define RING_IMR(base) ((base)+0xa8)
711#define RING_TIMESTAMP(base) ((base)+0x358) 712#define RING_TIMESTAMP(base) ((base)+0x358)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index bfb5d75cc1c5..0cba12948915 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -410,13 +410,20 @@ static void ring_write_tail(struct intel_ring_buffer *ring,
410 I915_WRITE_TAIL(ring, value); 410 I915_WRITE_TAIL(ring, value);
411} 411}
412 412
413u32 intel_ring_get_active_head(struct intel_ring_buffer *ring) 413u64 intel_ring_get_active_head(struct intel_ring_buffer *ring)
414{ 414{
415 drm_i915_private_t *dev_priv = ring->dev->dev_private; 415 drm_i915_private_t *dev_priv = ring->dev->dev_private;
416 u32 acthd_reg = INTEL_INFO(ring->dev)->gen >= 4 ? 416 u64 acthd;
417 RING_ACTHD(ring->mmio_base) : ACTHD;
418 417
419 return I915_READ(acthd_reg); 418 if (INTEL_INFO(ring->dev)->gen >= 8)
419 acthd = I915_READ64_2x32(RING_ACTHD(ring->mmio_base),
420 RING_ACTHD_UDW(ring->mmio_base));
421 else if (INTEL_INFO(ring->dev)->gen >= 4)
422 acthd = I915_READ(RING_ACTHD(ring->mmio_base));
423 else
424 acthd = I915_READ(ACTHD);
425
426 return acthd;
420} 427}
421 428
422static void ring_setup_phys_status_page(struct intel_ring_buffer *ring) 429static void ring_setup_phys_status_page(struct intel_ring_buffer *ring)
@@ -814,8 +821,11 @@ gen6_ring_get_seqno(struct intel_ring_buffer *ring, bool lazy_coherency)
814 /* Workaround to force correct ordering between irq and seqno writes on 821 /* Workaround to force correct ordering between irq and seqno writes on
815 * ivb (and maybe also on snb) by reading from a CS register (like 822 * ivb (and maybe also on snb) by reading from a CS register (like
816 * ACTHD) before reading the status page. */ 823 * ACTHD) before reading the status page. */
817 if (!lazy_coherency) 824 if (!lazy_coherency) {
818 intel_ring_get_active_head(ring); 825 struct drm_i915_private *dev_priv = ring->dev->dev_private;
826 POSTING_READ(RING_ACTHD(ring->mmio_base));
827 }
828
819 return intel_read_status_page(ring, I915_GEM_HWS_INDEX); 829 return intel_read_status_page(ring, I915_GEM_HWS_INDEX);
820} 830}
821 831
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index f11ceb230db4..270a6a973438 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -46,11 +46,11 @@ enum intel_ring_hangcheck_action {
46#define HANGCHECK_SCORE_RING_HUNG 31 46#define HANGCHECK_SCORE_RING_HUNG 31
47 47
48struct intel_ring_hangcheck { 48struct intel_ring_hangcheck {
49 bool deadlock; 49 u64 acthd;
50 u32 seqno; 50 u32 seqno;
51 u32 acthd;
52 int score; 51 int score;
53 enum intel_ring_hangcheck_action action; 52 enum intel_ring_hangcheck_action action;
53 bool deadlock;
54}; 54};
55 55
56struct intel_ring_buffer { 56struct intel_ring_buffer {
@@ -292,7 +292,7 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev);
292int intel_init_blt_ring_buffer(struct drm_device *dev); 292int intel_init_blt_ring_buffer(struct drm_device *dev);
293int intel_init_vebox_ring_buffer(struct drm_device *dev); 293int intel_init_vebox_ring_buffer(struct drm_device *dev);
294 294
295u32 intel_ring_get_active_head(struct intel_ring_buffer *ring); 295u64 intel_ring_get_active_head(struct intel_ring_buffer *ring);
296void intel_ring_setup_status_page(struct intel_ring_buffer *ring); 296void intel_ring_setup_status_page(struct intel_ring_buffer *ring);
297 297
298static inline u32 intel_ring_get_tail(struct intel_ring_buffer *ring) 298static inline u32 intel_ring_get_tail(struct intel_ring_buffer *ring)