aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_ringbuffer.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2013-01-17 05:34:08 -0500
committerDave Airlie <airlied@redhat.com>2013-01-17 05:34:08 -0500
commitb5cc6c0387b2f8d269c1df1e68c97c958dd22fed (patch)
tree697f2335b3a10f55e0ea226dcd044ee4ff3f0f7f /drivers/gpu/drm/i915/intel_ringbuffer.c
parent9931faca02c604c22335f5a935a501bb2ace6e20 (diff)
parentc0c36b941b6f0be6ac74f340040cbb29d6a0b06c (diff)
Merge tag 'drm-intel-next-2012-12-21' of git://people.freedesktop.org/~danvet/drm-intel into drm-next
Daniel writes: - seqno wrap fixes and debug infrastructure from Mika Kuoppala and Chris Wilson - some leftover kill-agp on gen6+ patches from Ben - hotplug improvements from Damien - clear fb when allocated from stolen, avoids dirt on the fbcon (Chris) - Stolen mem support from Chris Wilson, one of the many steps to get to real fastboot support. - Some DDI code cleanups from Paulo. - Some refactorings around lvds and dp code. - some random little bits&pieces * tag 'drm-intel-next-2012-12-21' of git://people.freedesktop.org/~danvet/drm-intel: (93 commits) drm/i915: Return the real error code from intel_set_mode() drm/i915: Make GSM void drm/i915: Move GSM mapping into dev_priv drm/i915: Move even more gtt code to i915_gem_gtt drm/i915: Make next_seqno debugs entry to use i915_gem_set_seqno drm/i915: Introduce i915_gem_set_seqno() drm/i915: Always clear semaphore mboxes on seqno wrap drm/i915: Initialize hardware semaphore state on ring init drm/i915: Introduce ring set_seqno drm/i915: Missed conversion to gtt_pte_t drm/i915: Bug on unsupported swizzled platforms drm/i915: BUG() if fences are used on unsupported platform drm/i915: fixup overlay stolen memory leak drm/i915: clean up PIPECONF bpc #defines drm/i915: add intel_dp_set_signal_levels drm/i915: remove leftover display.update_wm assignment drm/i915: check for the PCH when setting pch_transcoder drm/i915: Clear the stolen fb before enabling drm/i915: Access to snooped system memory through the GTT is incoherent drm/i915: Remove stale comment about intel_dp_detect() ... Conflicts: drivers/gpu/drm/i915/intel_display.c
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c')
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c99
1 files changed, 81 insertions, 18 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index ae253e04c391..59e02691baf3 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -601,6 +601,13 @@ gen6_add_request(struct intel_ring_buffer *ring)
601 return 0; 601 return 0;
602} 602}
603 603
604static inline bool i915_gem_has_seqno_wrapped(struct drm_device *dev,
605 u32 seqno)
606{
607 struct drm_i915_private *dev_priv = dev->dev_private;
608 return dev_priv->last_seqno < seqno;
609}
610
604/** 611/**
605 * intel_ring_sync - sync the waiter to the signaller on seqno 612 * intel_ring_sync - sync the waiter to the signaller on seqno
606 * 613 *
@@ -631,11 +638,20 @@ gen6_ring_sync(struct intel_ring_buffer *waiter,
631 if (ret) 638 if (ret)
632 return ret; 639 return ret;
633 640
634 intel_ring_emit(waiter, 641 /* If seqno wrap happened, omit the wait with no-ops */
635 dw1 | signaller->semaphore_register[waiter->id]); 642 if (likely(!i915_gem_has_seqno_wrapped(waiter->dev, seqno))) {
636 intel_ring_emit(waiter, seqno); 643 intel_ring_emit(waiter,
637 intel_ring_emit(waiter, 0); 644 dw1 |
638 intel_ring_emit(waiter, MI_NOOP); 645 signaller->semaphore_register[waiter->id]);
646 intel_ring_emit(waiter, seqno);
647 intel_ring_emit(waiter, 0);
648 intel_ring_emit(waiter, MI_NOOP);
649 } else {
650 intel_ring_emit(waiter, MI_NOOP);
651 intel_ring_emit(waiter, MI_NOOP);
652 intel_ring_emit(waiter, MI_NOOP);
653 intel_ring_emit(waiter, MI_NOOP);
654 }
639 intel_ring_advance(waiter); 655 intel_ring_advance(waiter);
640 656
641 return 0; 657 return 0;
@@ -716,6 +732,12 @@ ring_get_seqno(struct intel_ring_buffer *ring, bool lazy_coherency)
716 return intel_read_status_page(ring, I915_GEM_HWS_INDEX); 732 return intel_read_status_page(ring, I915_GEM_HWS_INDEX);
717} 733}
718 734
735static void
736ring_set_seqno(struct intel_ring_buffer *ring, u32 seqno)
737{
738 intel_write_status_page(ring, I915_GEM_HWS_INDEX, seqno);
739}
740
719static u32 741static u32
720pc_render_get_seqno(struct intel_ring_buffer *ring, bool lazy_coherency) 742pc_render_get_seqno(struct intel_ring_buffer *ring, bool lazy_coherency)
721{ 743{
@@ -723,6 +745,13 @@ pc_render_get_seqno(struct intel_ring_buffer *ring, bool lazy_coherency)
723 return pc->cpu_page[0]; 745 return pc->cpu_page[0];
724} 746}
725 747
748static void
749pc_render_set_seqno(struct intel_ring_buffer *ring, u32 seqno)
750{
751 struct pipe_control *pc = ring->private;
752 pc->cpu_page[0] = seqno;
753}
754
726static bool 755static bool
727gen5_ring_get_irq(struct intel_ring_buffer *ring) 756gen5_ring_get_irq(struct intel_ring_buffer *ring)
728{ 757{
@@ -1152,7 +1181,11 @@ static int intel_init_ring_buffer(struct drm_device *dev,
1152 return ret; 1181 return ret;
1153 } 1182 }
1154 1183
1155 obj = i915_gem_alloc_object(dev, ring->size); 1184 obj = NULL;
1185 if (!HAS_LLC(dev))
1186 obj = i915_gem_object_create_stolen(dev, ring->size);
1187 if (obj == NULL)
1188 obj = i915_gem_alloc_object(dev, ring->size);
1156 if (obj == NULL) { 1189 if (obj == NULL) {
1157 DRM_ERROR("Failed to allocate ringbuffer\n"); 1190 DRM_ERROR("Failed to allocate ringbuffer\n");
1158 ret = -ENOMEM; 1191 ret = -ENOMEM;
@@ -1190,6 +1223,8 @@ static int intel_init_ring_buffer(struct drm_device *dev,
1190 if (IS_I830(ring->dev) || IS_845G(ring->dev)) 1223 if (IS_I830(ring->dev) || IS_845G(ring->dev))
1191 ring->effective_size -= 128; 1224 ring->effective_size -= 128;
1192 1225
1226 intel_ring_init_seqno(ring, dev_priv->last_seqno);
1227
1193 return 0; 1228 return 0;
1194 1229
1195err_unmap: 1230err_unmap:
@@ -1398,11 +1433,31 @@ intel_ring_alloc_seqno(struct intel_ring_buffer *ring)
1398 return i915_gem_get_seqno(ring->dev, &ring->outstanding_lazy_request); 1433 return i915_gem_get_seqno(ring->dev, &ring->outstanding_lazy_request);
1399} 1434}
1400 1435
1436static int __intel_ring_begin(struct intel_ring_buffer *ring,
1437 int bytes)
1438{
1439 int ret;
1440
1441 if (unlikely(ring->tail + bytes > ring->effective_size)) {
1442 ret = intel_wrap_ring_buffer(ring);
1443 if (unlikely(ret))
1444 return ret;
1445 }
1446
1447 if (unlikely(ring->space < bytes)) {
1448 ret = ring_wait_for_space(ring, bytes);
1449 if (unlikely(ret))
1450 return ret;
1451 }
1452
1453 ring->space -= bytes;
1454 return 0;
1455}
1456
1401int intel_ring_begin(struct intel_ring_buffer *ring, 1457int intel_ring_begin(struct intel_ring_buffer *ring,
1402 int num_dwords) 1458 int num_dwords)
1403{ 1459{
1404 drm_i915_private_t *dev_priv = ring->dev->dev_private; 1460 drm_i915_private_t *dev_priv = ring->dev->dev_private;
1405 int n = 4*num_dwords;
1406 int ret; 1461 int ret;
1407 1462
1408 ret = i915_gem_check_wedge(dev_priv, dev_priv->mm.interruptible); 1463 ret = i915_gem_check_wedge(dev_priv, dev_priv->mm.interruptible);
@@ -1414,20 +1469,21 @@ int intel_ring_begin(struct intel_ring_buffer *ring,
1414 if (ret) 1469 if (ret)
1415 return ret; 1470 return ret;
1416 1471
1417 if (unlikely(ring->tail + n > ring->effective_size)) { 1472 return __intel_ring_begin(ring, num_dwords * sizeof(uint32_t));
1418 ret = intel_wrap_ring_buffer(ring); 1473}
1419 if (unlikely(ret))
1420 return ret;
1421 }
1422 1474
1423 if (unlikely(ring->space < n)) { 1475void intel_ring_init_seqno(struct intel_ring_buffer *ring, u32 seqno)
1424 ret = ring_wait_for_space(ring, n); 1476{
1425 if (unlikely(ret)) 1477 struct drm_i915_private *dev_priv = ring->dev->dev_private;
1426 return ret; 1478
1479 BUG_ON(ring->outstanding_lazy_request);
1480
1481 if (INTEL_INFO(ring->dev)->gen >= 6) {
1482 I915_WRITE(RING_SYNC_0(ring->mmio_base), 0);
1483 I915_WRITE(RING_SYNC_1(ring->mmio_base), 0);
1427 } 1484 }
1428 1485
1429 ring->space -= n; 1486 ring->set_seqno(ring, seqno);
1430 return 0;
1431} 1487}
1432 1488
1433void intel_ring_advance(struct intel_ring_buffer *ring) 1489void intel_ring_advance(struct intel_ring_buffer *ring)
@@ -1592,6 +1648,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
1592 ring->irq_put = gen6_ring_put_irq; 1648 ring->irq_put = gen6_ring_put_irq;
1593 ring->irq_enable_mask = GT_USER_INTERRUPT; 1649 ring->irq_enable_mask = GT_USER_INTERRUPT;
1594 ring->get_seqno = gen6_ring_get_seqno; 1650 ring->get_seqno = gen6_ring_get_seqno;
1651 ring->set_seqno = ring_set_seqno;
1595 ring->sync_to = gen6_ring_sync; 1652 ring->sync_to = gen6_ring_sync;
1596 ring->semaphore_register[0] = MI_SEMAPHORE_SYNC_INVALID; 1653 ring->semaphore_register[0] = MI_SEMAPHORE_SYNC_INVALID;
1597 ring->semaphore_register[1] = MI_SEMAPHORE_SYNC_RV; 1654 ring->semaphore_register[1] = MI_SEMAPHORE_SYNC_RV;
@@ -1602,6 +1659,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
1602 ring->add_request = pc_render_add_request; 1659 ring->add_request = pc_render_add_request;
1603 ring->flush = gen4_render_ring_flush; 1660 ring->flush = gen4_render_ring_flush;
1604 ring->get_seqno = pc_render_get_seqno; 1661 ring->get_seqno = pc_render_get_seqno;
1662 ring->set_seqno = pc_render_set_seqno;
1605 ring->irq_get = gen5_ring_get_irq; 1663 ring->irq_get = gen5_ring_get_irq;
1606 ring->irq_put = gen5_ring_put_irq; 1664 ring->irq_put = gen5_ring_put_irq;
1607 ring->irq_enable_mask = GT_USER_INTERRUPT | GT_PIPE_NOTIFY; 1665 ring->irq_enable_mask = GT_USER_INTERRUPT | GT_PIPE_NOTIFY;
@@ -1612,6 +1670,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
1612 else 1670 else
1613 ring->flush = gen4_render_ring_flush; 1671 ring->flush = gen4_render_ring_flush;
1614 ring->get_seqno = ring_get_seqno; 1672 ring->get_seqno = ring_get_seqno;
1673 ring->set_seqno = ring_set_seqno;
1615 if (IS_GEN2(dev)) { 1674 if (IS_GEN2(dev)) {
1616 ring->irq_get = i8xx_ring_get_irq; 1675 ring->irq_get = i8xx_ring_get_irq;
1617 ring->irq_put = i8xx_ring_put_irq; 1676 ring->irq_put = i8xx_ring_put_irq;
@@ -1683,6 +1742,7 @@ int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size)
1683 else 1742 else
1684 ring->flush = gen4_render_ring_flush; 1743 ring->flush = gen4_render_ring_flush;
1685 ring->get_seqno = ring_get_seqno; 1744 ring->get_seqno = ring_get_seqno;
1745 ring->set_seqno = ring_set_seqno;
1686 if (IS_GEN2(dev)) { 1746 if (IS_GEN2(dev)) {
1687 ring->irq_get = i8xx_ring_get_irq; 1747 ring->irq_get = i8xx_ring_get_irq;
1688 ring->irq_put = i8xx_ring_put_irq; 1748 ring->irq_put = i8xx_ring_put_irq;
@@ -1743,6 +1803,7 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev)
1743 ring->flush = gen6_ring_flush; 1803 ring->flush = gen6_ring_flush;
1744 ring->add_request = gen6_add_request; 1804 ring->add_request = gen6_add_request;
1745 ring->get_seqno = gen6_ring_get_seqno; 1805 ring->get_seqno = gen6_ring_get_seqno;
1806 ring->set_seqno = ring_set_seqno;
1746 ring->irq_enable_mask = GEN6_BSD_USER_INTERRUPT; 1807 ring->irq_enable_mask = GEN6_BSD_USER_INTERRUPT;
1747 ring->irq_get = gen6_ring_get_irq; 1808 ring->irq_get = gen6_ring_get_irq;
1748 ring->irq_put = gen6_ring_put_irq; 1809 ring->irq_put = gen6_ring_put_irq;
@@ -1758,6 +1819,7 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev)
1758 ring->flush = bsd_ring_flush; 1819 ring->flush = bsd_ring_flush;
1759 ring->add_request = i9xx_add_request; 1820 ring->add_request = i9xx_add_request;
1760 ring->get_seqno = ring_get_seqno; 1821 ring->get_seqno = ring_get_seqno;
1822 ring->set_seqno = ring_set_seqno;
1761 if (IS_GEN5(dev)) { 1823 if (IS_GEN5(dev)) {
1762 ring->irq_enable_mask = GT_BSD_USER_INTERRUPT; 1824 ring->irq_enable_mask = GT_BSD_USER_INTERRUPT;
1763 ring->irq_get = gen5_ring_get_irq; 1825 ring->irq_get = gen5_ring_get_irq;
@@ -1787,6 +1849,7 @@ int intel_init_blt_ring_buffer(struct drm_device *dev)
1787 ring->flush = blt_ring_flush; 1849 ring->flush = blt_ring_flush;
1788 ring->add_request = gen6_add_request; 1850 ring->add_request = gen6_add_request;
1789 ring->get_seqno = gen6_ring_get_seqno; 1851 ring->get_seqno = gen6_ring_get_seqno;
1852 ring->set_seqno = ring_set_seqno;
1790 ring->irq_enable_mask = GEN6_BLITTER_USER_INTERRUPT; 1853 ring->irq_enable_mask = GEN6_BLITTER_USER_INTERRUPT;
1791 ring->irq_get = gen6_ring_get_irq; 1854 ring->irq_get = gen6_ring_get_irq;
1792 ring->irq_put = gen6_ring_put_irq; 1855 ring->irq_put = gen6_ring_put_irq;