diff options
author | Dave Airlie <airlied@redhat.com> | 2012-05-02 09:21:50 +0100 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2012-05-02 09:22:29 +0100 |
commit | 5bc69bf9aeb73547cad8e1ce683a103fe9728282 (patch) | |
tree | d3ef275532fc4391cb645f8b4d45d39d7fbb73f4 /drivers/gpu/drm/i915/intel_ringbuffer.c | |
parent | c6543a6e64ad8e456674a1c4a01dd024e38b665f (diff) | |
parent | a85d4bcb8a0cd5b3c754f98ff91ef2b9b3a73bc5 (diff) |
Merge tag 'drm-intel-next-2012-04-23' of git://people.freedesktop.org/~danvet/drm-intel into drm-core-next
Daniel Vetter writes:
A new drm-intel-next pull. Highlights:
- More gmbus patches from Daniel Kurtz, I think gmbus is now ready, all
known issues fixed.
- Fencing cleanup and pipelined fencing removal from Chris.
- rc6 residency interface from Ben, useful for powertop.
- Cleanups and code reorg around the ringbuffer code (Ben&me).
- Use hw semaphores in the pageflip code from Ben.
- More vlv stuff from Jesse, unfortunately his vlv cpu is doa, so less
merged than I've hoped for - we still have the unused function warning :(
- More hsw patches from Eugeni, again, not yet enabled fully.
- intel_pm.c refactoring from Eugeni.
- Ironlake sprite support from Chris.
- And various smaller improvements/fixes all over the place.
Note that this pull request also contains a backmerge of -rc3 to sort out
a few things in -next. I've also had to frob the shortlog a bit to exclude
anything that -rc3 brings in with this pull.
Regression wise we have a few strange bugs going on, but for all of them
closer inspection revealed that they've been pre-existing, just now
slightly more likely to be hit. And for most of them we have a patch
already. Otherwise QA has not reported any regressions, and I'm also not
aware of anything bad happening in 3.4.
* tag 'drm-intel-next-2012-04-23' of git://people.freedesktop.org/~danvet/drm-intel: (420 commits)
drm/i915: rc6 residency (fix the fix)
drm/i915/tv: fix open-coded ARRAY_SIZE.
drm/i915: invalidate render cache on gen2
drm/i915: Silence the change of LVDS sync polarity
drm/i915: add generic power management initialization
drm/i915: move clock gating functionality into intel_pm module
drm/i915: move emon functionality into intel_pm module
drm/i915: move drps, rps and rc6-related functions to intel_pm
drm/i915: fix line breaks in intel_pm
drm/i915: move watermarks settings into intel_pm module
drm/i915: move fbc-related functionality into intel_pm module
drm/i915: Refactor get_fence() to use the common fence writing routine
drm/i915: Refactor fence clearing to use the common fence writing routine
drm/i915: Refactor put_fence() to use the common fence writing routine
drm/i915: Prepare to consolidate fence writing
drm/i915: Remove the unsightly "optimisation" from flush_fence()
drm/i915: Simplify fence finding
drm/i915: Discard the unused obj->last_fenced_ring
drm/i915: Remove unused ring->setup_seqno
drm/i915: Remove fence pipelining
...
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 528 |
1 files changed, 241 insertions, 287 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index dfdb613752c..12d9bc789df 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -53,9 +53,35 @@ static inline int ring_space(struct intel_ring_buffer *ring) } static int -render_ring_flush(struct intel_ring_buffer *ring, - u32 invalidate_domains, - u32 flush_domains) +gen2_render_ring_flush(struct intel_ring_buffer *ring, + u32 invalidate_domains, + u32 flush_domains) +{ + u32 cmd; + int ret; + + cmd = MI_FLUSH; + if (((invalidate_domains|flush_domains) & I915_GEM_DOMAIN_RENDER) == 0) + cmd |= MI_NO_WRITE_FLUSH; + + if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER) + cmd |= MI_READ_FLUSH; + + ret = intel_ring_begin(ring, 2); + if (ret) + return ret; + + intel_ring_emit(ring, cmd); + intel_ring_emit(ring, MI_NOOP); + intel_ring_advance(ring); + + return 0; +} + +static int +gen4_render_ring_flush(struct intel_ring_buffer *ring, + u32 invalidate_domains, + u32 flush_domains) { struct drm_device *dev = ring->dev; u32 cmd; @@ -90,17 +116,8 @@ render_ring_flush(struct intel_ring_buffer *ring, */ cmd = MI_FLUSH | MI_NO_WRITE_FLUSH; - if ((invalidate_domains|flush_domains) & - I915_GEM_DOMAIN_RENDER) + if ((invalidate_domains|flush_domains) & I915_GEM_DOMAIN_RENDER) cmd &= ~MI_NO_WRITE_FLUSH; - if (INTEL_INFO(dev)->gen < 4) { - /* - * On the 965, the sampler cache always gets flushed - * and this bit is reserved. - */ - if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER) - cmd |= MI_READ_FLUSH; - } if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION) cmd |= MI_EXE_FLUSH; @@ -472,21 +489,30 @@ gen6_add_request(struct intel_ring_buffer *ring, * @seqno - seqno which the waiter will block on */ static int -intel_ring_sync(struct intel_ring_buffer *waiter, - struct intel_ring_buffer *signaller, - int ring, - u32 seqno) +gen6_ring_sync(struct intel_ring_buffer *waiter, + struct intel_ring_buffer *signaller, + u32 seqno) { int ret; u32 dw1 = MI_SEMAPHORE_MBOX | MI_SEMAPHORE_COMPARE | MI_SEMAPHORE_REGISTER; + /* Throughout all of the GEM code, seqno passed implies our current + * seqno is >= the last seqno executed. However for hardware the + * comparison is strictly greater than. + */ + seqno -= 1; + + WARN_ON(signaller->semaphore_register[waiter->id] == + MI_SEMAPHORE_SYNC_INVALID); + ret = intel_ring_begin(waiter, 4); if (ret) return ret; - intel_ring_emit(waiter, dw1 | signaller->semaphore_register[ring]); + intel_ring_emit(waiter, + dw1 | signaller->semaphore_register[waiter->id]); intel_ring_emit(waiter, seqno); intel_ring_emit(waiter, 0); intel_ring_emit(waiter, MI_NOOP); @@ -495,47 +521,6 @@ intel_ring_sync(struct intel_ring_buffer *waiter, return 0; } -/* VCS->RCS (RVSYNC) or BCS->RCS (RBSYNC) */ -int -render_ring_sync_to(struct intel_ring_buffer *waiter, - struct intel_ring_buffer *signaller, - u32 seqno) -{ - WARN_ON(signaller->semaphore_register[RCS] == MI_SEMAPHORE_SYNC_INVALID); - return intel_ring_sync(waiter, - signaller, - RCS, - seqno); -} - -/* RCS->VCS (VRSYNC) or BCS->VCS (VBSYNC) */ -int -gen6_bsd_ring_sync_to(struct intel_ring_buffer *waiter, - struct intel_ring_buffer *signaller, - u32 seqno) -{ - WARN_ON(signaller->semaphore_register[VCS] == MI_SEMAPHORE_SYNC_INVALID); - return intel_ring_sync(waiter, - signaller, - VCS, - seqno); -} - -/* RCS->BCS (BRSYNC) or VCS->BCS (BVSYNC) */ -int -gen6_blt_ring_sync_to(struct intel_ring_buffer *waiter, - struct intel_ring_buffer *signaller, - u32 seqno) -{ - WARN_ON(signaller->semaphore_register[BCS] == MI_SEMAPHORE_SYNC_INVALID); - return intel_ring_sync(waiter, - signaller, - BCS, - seqno); -} - - - #define PIPE_CONTROL_FLUSH(ring__, addr__) \ do { \ intel_ring_emit(ring__, GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE | \ @@ -597,27 +582,6 @@ pc_render_add_request(struct intel_ring_buffer *ring, return 0; } -static int -render_ring_add_request(struct intel_ring_buffer *ring, - u32 *result) -{ - u32 seqno = i915_gem_next_request_seqno(ring); - int ret; - - ret = intel_ring_begin(ring, 4); - if (ret) - return ret; - - intel_ring_emit(ring, MI_STORE_DWORD_INDEX); - intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - intel_ring_emit(ring, seqno); - intel_ring_emit(ring, MI_USER_INTERRUPT); - intel_ring_advance(ring); - - *result = seqno; - return 0; -} - static u32 gen6_ring_get_seqno(struct intel_ring_buffer *ring) { @@ -644,40 +608,43 @@ pc_render_get_seqno(struct intel_ring_buffer *ring) return pc->cpu_page[0]; } -static void -ironlake_enable_irq(drm_i915_private_t *dev_priv, u32 mask) +static bool +gen5_ring_get_irq(struct intel_ring_buffer *ring) { - dev_priv->gt_irq_mask &= ~mask; - I915_WRITE(GTIMR, dev_priv->gt_irq_mask); - POSTING_READ(GTIMR); -} + struct drm_device *dev = ring->dev; + drm_i915_private_t *dev_priv = dev->dev_private; -static void -ironlake_disable_irq(drm_i915_private_t *dev_priv, u32 mask) -{ - dev_priv->gt_irq_mask |= mask; - I915_WRITE(GTIMR, dev_priv->gt_irq_mask); - POSTING_READ(GTIMR); -} + if (!dev->irq_enabled) + return false; -static void -i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask) -{ - dev_priv->irq_mask &= ~mask; - I915_WRITE(IMR, dev_priv->irq_mask); - POSTING_READ(IMR); + spin_lock(&ring->irq_lock); + if (ring->irq_refcount++ == 0) { + dev_priv->gt_irq_mask &= ~ring->irq_enable_mask; + I915_WRITE(GTIMR, dev_priv->gt_irq_mask); + POSTING_READ(GTIMR); + } + spin_unlock(&ring->irq_lock); + + return true; } static void -i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask) +gen5_ring_put_irq(struct intel_ring_buffer *ring) { - dev_priv->irq_mask |= mask; - I915_WRITE(IMR, dev_priv->irq_mask); - POSTING_READ(IMR); + struct drm_device *dev = ring->dev; + drm_i915_private_t *dev_priv = dev->dev_private; + + spin_lock(&ring->irq_lock); + if (--ring->irq_refcount == 0) { + dev_priv->gt_irq_mask |= ring->irq_enable_mask; + I915_WRITE(GTIMR, dev_priv->gt_irq_mask); + POSTING_READ(GTIMR); + } + spin_unlock(&ring->irq_lock); } static bool -render_ring_get_irq(struct intel_ring_buffer *ring) +i9xx_ring_get_irq(struct intel_ring_buffer *ring) { struct drm_device *dev = ring->dev; drm_i915_private_t *dev_priv = dev->dev_private; @@ -687,11 +654,9 @@ render_ring_get_irq(struct intel_ring_buffer *ring) spin_lock(&ring->irq_lock); if (ring->irq_refcount++ == 0) { - if (INTEL_INFO(dev)->gen >= 5) - ironlake_enable_irq(dev_priv, - GT_PIPE_NOTIFY | GT_USER_INTERRUPT); - else - i915_enable_irq(dev_priv, I915_USER_INTERRUPT); + dev_priv->irq_mask &= ~ring->irq_enable_mask; + I915_WRITE(IMR, dev_priv->irq_mask); + POSTING_READ(IMR); } spin_unlock(&ring->irq_lock); @@ -699,19 +664,16 @@ render_ring_get_irq(struct intel_ring_buffer *ring) } static void -render_ring_put_irq(struct intel_ring_buffer *ring) +i9xx_ring_put_irq(struct intel_ring_buffer *ring) { struct drm_device *dev = ring->dev; drm_i915_private_t *dev_priv = dev->dev_private; spin_lock(&ring->irq_lock); if (--ring->irq_refcount == 0) { - if (INTEL_INFO(dev)->gen >= 5) - ironlake_disable_irq(dev_priv, - GT_USER_INTERRUPT | - GT_PIPE_NOTIFY); - else - i915_disable_irq(dev_priv, I915_USER_INTERRUPT); + dev_priv->irq_mask |= ring->irq_enable_mask; + I915_WRITE(IMR, dev_priv->irq_mask); + POSTING_READ(IMR); } spin_unlock(&ring->irq_lock); } @@ -765,7 +727,7 @@ bsd_ring_flush(struct intel_ring_buffer *ring, } static int -ring_add_request(struct intel_ring_buffer *ring, +i9xx_add_request(struct intel_ring_buffer *ring, u32 *result) { u32 seqno; @@ -792,7 +754,6 @@ gen6_ring_get_irq(struct intel_ring_buffer *ring) { struct drm_device *dev = ring->dev; drm_i915_private_t *dev_priv = dev->dev_private; - u32 mask = ring->irq_enable; if (!dev->irq_enabled) return false; @@ -804,9 +765,10 @@ gen6_ring_get_irq(struct intel_ring_buffer *ring) spin_lock(&ring->irq_lock); if (ring->irq_refcount++ == 0) { - ring->irq_mask &= ~mask; - I915_WRITE_IMR(ring, ring->irq_mask); - ironlake_enable_irq(dev_priv, mask); + I915_WRITE_IMR(ring, ~ring->irq_enable_mask); + dev_priv->gt_irq_mask &= ~ring->irq_enable_mask; + I915_WRITE(GTIMR, dev_priv->gt_irq_mask); + POSTING_READ(GTIMR); } spin_unlock(&ring->irq_lock); @@ -818,105 +780,69 @@ gen6_ring_put_irq(struct intel_ring_buffer *ring) { struct drm_device *dev = ring->dev; drm_i915_private_t *dev_priv = dev->dev_private; - u32 mask = ring->irq_enable; spin_lock(&ring->irq_lock); if (--ring->irq_refcount == 0) { - ring->irq_mask |= mask; - I915_WRITE_IMR(ring, ring->irq_mask); - ironlake_disable_irq(dev_priv, mask); + I915_WRITE_IMR(ring, ~0); + dev_priv->gt_irq_mask |= ring->irq_enable_mask; + I915_WRITE(GTIMR, dev_priv->gt_irq_mask); + POSTING_READ(GTIMR); } spin_unlock(&ring->irq_lock); gen6_gt_force_wake_put(dev_priv); } -static bool -bsd_ring_get_irq(struct intel_ring_buffer *ring) +static int +i965_dispatch_execbuffer(struct intel_ring_buffer *ring, u32 offset, u32 length) { - struct drm_device *dev = ring->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - - if (!dev->irq_enabled) - return false; + int ret; - spin_lock(&ring->irq_lock); - if (ring->irq_refcount++ == 0) { - if (IS_G4X(dev)) - i915_enable_irq(dev_priv, I915_BSD_USER_INTERRUPT); - else - ironlake_enable_irq(dev_priv, GT_BSD_USER_INTERRUPT); - } - spin_unlock(&ring->irq_lock); + ret = intel_ring_begin(ring, 2); + if (ret) + return ret; - return true; -} -static void -bsd_ring_put_irq(struct intel_ring_buffer *ring) -{ - struct drm_device *dev = ring->dev; - drm_i915_private_t *dev_priv = dev->dev_private; + intel_ring_emit(ring, + MI_BATCH_BUFFER_START | + MI_BATCH_GTT | + MI_BATCH_NON_SECURE_I965); + intel_ring_emit(ring, offset); + intel_ring_advance(ring); - spin_lock(&ring->irq_lock); - if (--ring->irq_refcount == 0) { - if (IS_G4X(dev)) - i915_disable_irq(dev_priv, I915_BSD_USER_INTERRUPT); - else - ironlake_disable_irq(dev_priv, GT_BSD_USER_INTERRUPT); - } - spin_unlock(&ring->irq_lock); + return 0; } static int -ring_dispatch_execbuffer(struct intel_ring_buffer *ring, u32 offset, u32 length) +i830_dispatch_execbuffer(struct intel_ring_buffer *ring, + u32 offset, u32 len) { int ret; - ret = intel_ring_begin(ring, 2); + ret = intel_ring_begin(ring, 4); if (ret) return ret; - intel_ring_emit(ring, - MI_BATCH_BUFFER_START | (2 << 6) | - MI_BATCH_NON_SECURE_I965); - intel_ring_emit(ring, offset); + intel_ring_emit(ring, MI_BATCH_BUFFER); + intel_ring_emit(ring, offset | MI_BATCH_NON_SECURE); + intel_ring_emit(ring, offset + len - 8); + intel_ring_emit(ring, 0); intel_ring_advance(ring); return 0; } static int -render_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, +i915_dispatch_execbuffer(struct intel_ring_buffer *ring, u32 offset, u32 len) { - struct drm_device *dev = ring->dev; int ret; - if (IS_I830(dev) || IS_845G(dev)) { - ret = intel_ring_begin(ring, 4); - if (ret) - return ret; - - intel_ring_emit(ring, MI_BATCH_BUFFER); - intel_ring_emit(ring, offset | MI_BATCH_NON_SECURE); - intel_ring_emit(ring, offset + len - 8); - intel_ring_emit(ring, 0); - } else { - ret = intel_ring_begin(ring, 2); - if (ret) - return ret; + ret = intel_ring_begin(ring, 2); + if (ret) + return ret; - if (INTEL_INFO(dev)->gen >= 4) { - intel_ring_emit(ring, - MI_BATCH_BUFFER_START | (2 << 6) | - MI_BATCH_NON_SECURE_I965); - intel_ring_emit(ring, offset); - } else { - intel_ring_emit(ring, - MI_BATCH_BUFFER_START | (2 << 6)); - intel_ring_emit(ring, offset | MI_BATCH_NON_SECURE); - } - } + intel_ring_emit(ring, MI_BATCH_BUFFER_START | MI_BATCH_GTT); + intel_ring_emit(ring, offset | MI_BATCH_NON_SECURE); intel_ring_advance(ring); return 0; @@ -983,8 +909,8 @@ err: return ret; } -int intel_init_ring_buffer(struct drm_device *dev, - struct intel_ring_buffer *ring) +static int intel_init_ring_buffer(struct drm_device *dev, + struct intel_ring_buffer *ring) { struct drm_i915_gem_object *obj; int ret; @@ -993,10 +919,10 @@ int intel_init_ring_buffer(struct drm_device *dev, INIT_LIST_HEAD(&ring->active_list); INIT_LIST_HEAD(&ring->request_list); INIT_LIST_HEAD(&ring->gpu_write_list); + ring->size = 32 * PAGE_SIZE; init_waitqueue_head(&ring->irq_queue); spin_lock_init(&ring->irq_lock); - ring->irq_mask = ~0; if (I915_NEED_GFX_HWS(dev)) { ret = init_status_page(ring); @@ -1040,7 +966,7 @@ int intel_init_ring_buffer(struct drm_device *dev, * of the buffer. */ ring->effective_size = ring->size; - if (IS_I830(ring->dev)) + if (IS_I830(ring->dev) || IS_845G(ring->dev)) ring->effective_size -= 128; return 0; @@ -1263,44 +1189,6 @@ void intel_ring_advance(struct intel_ring_buffer *ring) ring->write_tail(ring, ring->tail); } -static const struct intel_ring_buffer render_ring = { - .name = "render ring", - .id = RCS, - .mmio_base = RENDER_RING_BASE, - .size = 32 * PAGE_SIZE, - .init = init_render_ring, - .write_tail = ring_write_tail, - .flush = render_ring_flush, - .add_request = render_ring_add_request, - .get_seqno = ring_get_seqno, - .irq_get = render_ring_get_irq, - .irq_put = render_ring_put_irq, - .dispatch_execbuffer = render_ring_dispatch_execbuffer, - .cleanup = render_ring_cleanup, - .sync_to = render_ring_sync_to, - .semaphore_register = {MI_SEMAPHORE_SYNC_INVALID, - MI_SEMAPHORE_SYNC_RV, - MI_SEMAPHORE_SYNC_RB}, - .signal_mbox = {GEN6_VRSYNC, GEN6_BRSYNC}, -}; - -/* ring buffer for bit-stream decoder */ - -static const struct intel_ring_buffer bsd_ring = { - .name = "bsd ring", - .id = VCS, - .mmio_base = BSD_RING_BASE, - .size = 32 * PAGE_SIZE, - .init = init_ring_common, - .write_tail = ring_write_tail, - .flush = bsd_ring_flush, - .add_request = ring_add_request, - .get_seqno = ring_get_seqno, - .irq_get = bsd_ring_get_irq, - .irq_put = bsd_ring_put_irq, - .dispatch_execbuffer = ring_dispatch_execbuffer, -}; - static void gen6_bsd_ring_write_tail(struct intel_ring_buffer *ring, u32 value) @@ -1363,28 +1251,6 @@ gen6_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, return 0; } -/* ring buffer for Video Codec for Gen6+ */ -static const struct intel_ring_buffer gen6_bsd_ring = { - .name = "gen6 bsd ring", - .id = VCS, - .mmio_base = GEN6_BSD_RING_BASE, - .size = 32 * PAGE_SIZE, - .init = init_ring_common, - .write_tail = gen6_bsd_ring_write_tail, - .flush = gen6_ring_flush, - .add_request = gen6_add_request, - .get_seqno = gen6_ring_get_seqno, - .irq_enable = GEN6_BSD_USER_INTERRUPT, - .irq_get = gen6_ring_get_irq, - .irq_put = gen6_ring_put_irq, - .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, - .sync_to = gen6_bsd_ring_sync_to, - .semaphore_register = {MI_SEMAPHORE_SYNC_VR, - MI_SEMAPHORE_SYNC_INVALID, - MI_SEMAPHORE_SYNC_VB}, - .signal_mbox = {GEN6_RVSYNC, GEN6_BVSYNC}, -}; - /* Blitter support (SandyBridge+) */ static int blt_ring_flush(struct intel_ring_buffer *ring, @@ -1408,44 +1274,58 @@ static int blt_ring_flush(struct intel_ring_buffer *ring, return 0; } -static const struct intel_ring_buffer gen6_blt_ring = { - .name = "blt ring", - .id = BCS, - .mmio_base = BLT_RING_BASE, - .size = 32 * PAGE_SIZE, - .init = init_ring_common, - .write_tail = ring_write_tail, - .flush = blt_ring_flush, - .add_request = gen6_add_request, - .get_seqno = gen6_ring_get_seqno, - .irq_get = gen6_ring_get_irq, - .irq_put = gen6_ring_put_irq, - .irq_enable = GEN6_BLITTER_USER_INTERRUPT, - .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, - .sync_to = gen6_blt_ring_sync_to, - .semaphore_register = {MI_SEMAPHORE_SYNC_BR, - MI_SEMAPHORE_SYNC_BV, - MI_SEMAPHORE_SYNC_INVALID}, - .signal_mbox = {GEN6_RBSYNC, GEN6_VBSYNC}, -}; - int intel_init_render_ring_buffer(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; - *ring = render_ring; + ring->name = "render ring"; + ring->id = RCS; + ring->mmio_base = RENDER_RING_BASE; + if (INTEL_INFO(dev)->gen >= 6) { ring->add_request = gen6_add_request; ring->flush = gen6_render_ring_flush; ring->irq_get = gen6_ring_get_irq; ring->irq_put = gen6_ring_put_irq; - ring->irq_enable = GT_USER_INTERRUPT; + ring->irq_enable_mask = GT_USER_INTERRUPT; ring->get_seqno = gen6_ring_get_seqno; + ring->sync_to = gen6_ring_sync; + ring->semaphore_register[0] = MI_SEMAPHORE_SYNC_INVALID; + ring->semaphore_register[1] = MI_SEMAPHORE_SYNC_RV; + ring->semaphore_register[2] = MI_SEMAPHORE_SYNC_RB; + ring->signal_mbox[0] = GEN6_VRSYNC; + ring->signal_mbox[1] = GEN6_BRSYNC; } else if (IS_GEN5(dev)) { ring->add_request = pc_render_add_request; + ring->flush = gen4_render_ring_flush; ring->get_seqno = pc_render_get_seqno; + ring->irq_get = gen5_ring_get_irq; + ring->irq_put = gen5_ring_put_irq; + ring->irq_enable_mask = GT_USER_INTERRUPT | GT_PIPE_NOTIFY; + } else { + ring->add_request = i9xx_add_request; + if (INTEL_INFO(dev)->gen < 4) + ring->flush = gen2_render_ring_flush; + else + ring->flush = gen4_render_ring_flush; + ring->get_seqno = ring_get_seqno; + ring->irq_get = i9xx_ring_get_irq; + ring->irq_put = i9xx_ring_put_irq; + ring->irq_enable_mask = I915_USER_INTERRUPT; } + ring->write_tail = ring_write_tail; + if (INTEL_INFO(dev)->gen >= 6) + ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; + else if (INTEL_INFO(dev)->gen >= 4) + ring->dispatch_execbuffer = i965_dispatch_execbuffer; + else if (IS_I830(dev) || IS_845G(dev)) + ring->dispatch_execbuffer = i830_dispatch_execbuffer; + else + ring->dispatch_execbuffer = i915_dispatch_execbuffer; + ring->init = init_render_ring; + ring->cleanup = render_ring_cleanup; + if (!I915_NEED_GFX_HWS(dev)) { ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr; @@ -1460,17 +1340,37 @@ int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size) drm_i915_private_t *dev_priv = dev->dev_private; struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; - *ring = render_ring; + ring->name = "render ring"; + ring->id = RCS; + ring->mmio_base = RENDER_RING_BASE; + if (INTEL_INFO(dev)->gen >= 6) { - ring->add_request = gen6_add_request; - ring->irq_get = gen6_ring_get_irq; - ring->irq_put = gen6_ring_put_irq; - ring->irq_enable = GT_USER_INTERRUPT; - } else if (IS_GEN5(dev)) { - ring->add_request = pc_render_add_request; - ring->get_seqno = pc_render_get_seqno; + /* non-kms not supported on gen6+ */ + return -ENODEV; } + /* Note: gem is not supported on gen5/ilk without kms (the corresponding + * gem_init ioctl returns with -ENODEV). Hence we do not need to set up + * the special gen5 functions. */ + ring->add_request = i9xx_add_request; + if (INTEL_INFO(dev)->gen < 4) + ring->flush = gen2_render_ring_flush; + else + ring->flush = gen4_render_ring_flush; + ring->get_seqno = ring_get_seqno; + ring->irq_get = i9xx_ring_get_irq; + ring->irq_put = i9xx_ring_put_irq; + ring->irq_enable_mask = I915_USER_INTERRUPT; + ring->write_tail = ring_write_tail; + if (INTEL_INFO(dev)->gen >= 4) + ring->dispatch_execbuffer = i965_dispatch_execbuffer; + else if (IS_I830(dev) || IS_845G(dev)) + ring->dispatch_execbuffer = i830_dispatch_execbuffer; + else + ring->dispatch_execbuffer = i915_dispatch_execbuffer; + ring->init = init_render_ring; + ring->cleanup = render_ring_cleanup; + if (!I915_NEED_GFX_HWS(dev)) ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr; @@ -1506,10 +1406,46 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) drm_i915_private_t *dev_priv = dev->dev_private; struct intel_ring_buffer *ring = &dev_priv->ring[VCS]; - if (IS_GEN6(dev) || IS_GEN7(dev)) - *ring = gen6_bsd_ring; - else - *ring = bsd_ring; + ring->name = "bsd ring"; + ring->id = VCS; + + ring->write_tail = ring_write_tail; + if (IS_GEN6(dev) || IS_GEN7(dev)) { + ring->mmio_base = GEN6_BSD_RING_BASE; + /* gen6 bsd needs a special wa for tail updates */ + if (IS_GEN6(dev)) + ring->write_tail = gen6_bsd_ring_write_tail; + ring->flush = gen6_ring_flush; + ring->add_request = gen6_add_request; + ring->get_seqno = gen6_ring_get_seqno; + ring->irq_enable_mask = GEN6_BSD_USER_INTERRUPT; + ring->irq_get = gen6_ring_get_irq; + ring->irq_put = gen6_ring_put_irq; + ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; + ring->sync_to = gen6_ring_sync; + ring->semaphore_register[0] = MI_SEMAPHORE_SYNC_VR; + ring->semaphore_register[1] = MI_SEMAPHORE_SYNC_INVALID; + ring->semaphore_register[2] = MI_SEMAPHORE_SYNC_VB; + ring->signal_mbox[0] = GEN6_RVSYNC; + ring->signal_mbox[1] = GEN6_BVSYNC; + } else { + ring->mmio_base = BSD_RING_BASE; + ring->flush = bsd_ring_flush; + ring->add_request = i9xx_add_request; + ring->get_seqno = ring_get_seqno; + if (IS_GEN5(dev)) { + ring->irq_enable_mask = GT_BSD_USER_INTERRUPT; + ring->irq_get = gen5_ring_get_irq; + ring->irq_put = gen5_ring_put_irq; + } else { + ring->irq_enable_mask = I915_BSD_USER_INTERRUPT; + ring->irq_get = i9xx_ring_get_irq; + ring->irq_put = i9xx_ring_put_irq; + } + ring->dispatch_execbuffer = i965_dispatch_execbuffer; + } + ring->init = init_ring_common; + return intel_init_ring_buffer(dev, ring); } @@ -1519,7 +1455,25 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) drm_i915_private_t *dev_priv = dev->dev_private; struct intel_ring_buffer *ring = &dev_priv->ring[BCS]; - *ring = gen6_blt_ring; + ring->name = "blitter ring"; + ring->id = BCS; + + ring->mmio_base = BLT_RING_BASE; + ring->write_tail = ring_write_tail; + ring->flush = blt_ring_flush; + ring->add_request = gen6_add_request; + ring->get_seqno = gen6_ring_get_seqno; + ring->irq_enable_mask = GEN6_BLITTER_USER_INTERRUPT; + ring->irq_get = gen6_ring_get_irq; + ring->irq_put = gen6_ring_put_irq; + ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; + ring->sync_to = gen6_ring_sync; + ring->semaphore_register[0] = MI_SEMAPHORE_SYNC_BR; + ring->semaphore_register[1] = MI_SEMAPHORE_SYNC_BV; + ring->semaphore_register[2] = MI_SEMAPHORE_SYNC_INVALID; + ring->signal_mbox[0] = GEN6_RBSYNC; + ring->signal_mbox[1] = GEN6_VBSYNC; + ring->init = init_ring_common; return intel_init_ring_buffer(dev, ring); } |