aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_ringbuffer.c
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/i915/intel_ringbuffer.c
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/i915/intel_ringbuffer.c')
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c22
1 files changed, 16 insertions, 6 deletions
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