diff options
author | Dave Airlie <airlied@redhat.com> | 2013-01-17 05:34:08 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2013-01-17 05:34:08 -0500 |
commit | b5cc6c0387b2f8d269c1df1e68c97c958dd22fed (patch) | |
tree | 697f2335b3a10f55e0ea226dcd044ee4ff3f0f7f /drivers/gpu/drm/i915/intel_ringbuffer.c | |
parent | 9931faca02c604c22335f5a935a501bb2ace6e20 (diff) | |
parent | c0c36b941b6f0be6ac74f340040cbb29d6a0b06c (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.c | 99 |
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 | ||
604 | static 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 | ||
735 | static void | ||
736 | ring_set_seqno(struct intel_ring_buffer *ring, u32 seqno) | ||
737 | { | ||
738 | intel_write_status_page(ring, I915_GEM_HWS_INDEX, seqno); | ||
739 | } | ||
740 | |||
719 | static u32 | 741 | static u32 |
720 | pc_render_get_seqno(struct intel_ring_buffer *ring, bool lazy_coherency) | 742 | pc_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 | ||
748 | static void | ||
749 | pc_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 | |||
726 | static bool | 755 | static bool |
727 | gen5_ring_get_irq(struct intel_ring_buffer *ring) | 756 | gen5_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 | ||
1195 | err_unmap: | 1230 | err_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 | ||
1436 | static 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 | |||
1401 | int intel_ring_begin(struct intel_ring_buffer *ring, | 1457 | int 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)) { | 1475 | void 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 | ||
1433 | void intel_ring_advance(struct intel_ring_buffer *ring) | 1489 | void 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; |