diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 113 |
1 files changed, 90 insertions, 23 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 42ff97d667d2..1d5d613eb6be 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -318,6 +318,7 @@ gen7_render_ring_flush(struct intel_ring_buffer *ring, | |||
318 | * TLB invalidate requires a post-sync write. | 318 | * TLB invalidate requires a post-sync write. |
319 | */ | 319 | */ |
320 | flags |= PIPE_CONTROL_QW_WRITE; | 320 | flags |= PIPE_CONTROL_QW_WRITE; |
321 | flags |= PIPE_CONTROL_GLOBAL_GTT_IVB; | ||
321 | 322 | ||
322 | /* Workaround: we must issue a pipe_control with CS-stall bit | 323 | /* Workaround: we must issue a pipe_control with CS-stall bit |
323 | * set before a pipe_control command that has the state cache | 324 | * set before a pipe_control command that has the state cache |
@@ -331,7 +332,7 @@ gen7_render_ring_flush(struct intel_ring_buffer *ring, | |||
331 | 332 | ||
332 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(4)); | 333 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(4)); |
333 | intel_ring_emit(ring, flags); | 334 | intel_ring_emit(ring, flags); |
334 | intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); | 335 | intel_ring_emit(ring, scratch_addr); |
335 | intel_ring_emit(ring, 0); | 336 | intel_ring_emit(ring, 0); |
336 | intel_ring_advance(ring); | 337 | intel_ring_advance(ring); |
337 | 338 | ||
@@ -467,6 +468,9 @@ init_pipe_control(struct intel_ring_buffer *ring) | |||
467 | if (pc->cpu_page == NULL) | 468 | if (pc->cpu_page == NULL) |
468 | goto err_unpin; | 469 | goto err_unpin; |
469 | 470 | ||
471 | DRM_DEBUG_DRIVER("%s pipe control offset: 0x%08x\n", | ||
472 | ring->name, pc->gtt_offset); | ||
473 | |||
470 | pc->obj = obj; | 474 | pc->obj = obj; |
471 | ring->private = pc; | 475 | ring->private = pc; |
472 | return 0; | 476 | return 0; |
@@ -613,6 +617,13 @@ gen6_add_request(struct intel_ring_buffer *ring) | |||
613 | return 0; | 617 | return 0; |
614 | } | 618 | } |
615 | 619 | ||
620 | static inline bool i915_gem_has_seqno_wrapped(struct drm_device *dev, | ||
621 | u32 seqno) | ||
622 | { | ||
623 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
624 | return dev_priv->last_seqno < seqno; | ||
625 | } | ||
626 | |||
616 | /** | 627 | /** |
617 | * intel_ring_sync - sync the waiter to the signaller on seqno | 628 | * intel_ring_sync - sync the waiter to the signaller on seqno |
618 | * | 629 | * |
@@ -643,11 +654,20 @@ gen6_ring_sync(struct intel_ring_buffer *waiter, | |||
643 | if (ret) | 654 | if (ret) |
644 | return ret; | 655 | return ret; |
645 | 656 | ||
646 | intel_ring_emit(waiter, | 657 | /* If seqno wrap happened, omit the wait with no-ops */ |
647 | dw1 | signaller->semaphore_register[waiter->id]); | 658 | if (likely(!i915_gem_has_seqno_wrapped(waiter->dev, seqno))) { |
648 | intel_ring_emit(waiter, seqno); | 659 | intel_ring_emit(waiter, |
649 | intel_ring_emit(waiter, 0); | 660 | dw1 | |
650 | intel_ring_emit(waiter, MI_NOOP); | 661 | signaller->semaphore_register[waiter->id]); |
662 | intel_ring_emit(waiter, seqno); | ||
663 | intel_ring_emit(waiter, 0); | ||
664 | intel_ring_emit(waiter, MI_NOOP); | ||
665 | } else { | ||
666 | intel_ring_emit(waiter, MI_NOOP); | ||
667 | intel_ring_emit(waiter, MI_NOOP); | ||
668 | intel_ring_emit(waiter, MI_NOOP); | ||
669 | intel_ring_emit(waiter, MI_NOOP); | ||
670 | } | ||
651 | intel_ring_advance(waiter); | 671 | intel_ring_advance(waiter); |
652 | 672 | ||
653 | return 0; | 673 | return 0; |
@@ -728,6 +748,12 @@ ring_get_seqno(struct intel_ring_buffer *ring, bool lazy_coherency) | |||
728 | return intel_read_status_page(ring, I915_GEM_HWS_INDEX); | 748 | return intel_read_status_page(ring, I915_GEM_HWS_INDEX); |
729 | } | 749 | } |
730 | 750 | ||
751 | static void | ||
752 | ring_set_seqno(struct intel_ring_buffer *ring, u32 seqno) | ||
753 | { | ||
754 | intel_write_status_page(ring, I915_GEM_HWS_INDEX, seqno); | ||
755 | } | ||
756 | |||
731 | static u32 | 757 | static u32 |
732 | pc_render_get_seqno(struct intel_ring_buffer *ring, bool lazy_coherency) | 758 | pc_render_get_seqno(struct intel_ring_buffer *ring, bool lazy_coherency) |
733 | { | 759 | { |
@@ -735,6 +761,13 @@ pc_render_get_seqno(struct intel_ring_buffer *ring, bool lazy_coherency) | |||
735 | return pc->cpu_page[0]; | 761 | return pc->cpu_page[0]; |
736 | } | 762 | } |
737 | 763 | ||
764 | static void | ||
765 | pc_render_set_seqno(struct intel_ring_buffer *ring, u32 seqno) | ||
766 | { | ||
767 | struct pipe_control *pc = ring->private; | ||
768 | pc->cpu_page[0] = seqno; | ||
769 | } | ||
770 | |||
738 | static bool | 771 | static bool |
739 | gen5_ring_get_irq(struct intel_ring_buffer *ring) | 772 | gen5_ring_get_irq(struct intel_ring_buffer *ring) |
740 | { | 773 | { |
@@ -1164,7 +1197,11 @@ static int intel_init_ring_buffer(struct drm_device *dev, | |||
1164 | return ret; | 1197 | return ret; |
1165 | } | 1198 | } |
1166 | 1199 | ||
1167 | obj = i915_gem_alloc_object(dev, ring->size); | 1200 | obj = NULL; |
1201 | if (!HAS_LLC(dev)) | ||
1202 | obj = i915_gem_object_create_stolen(dev, ring->size); | ||
1203 | if (obj == NULL) | ||
1204 | obj = i915_gem_alloc_object(dev, ring->size); | ||
1168 | if (obj == NULL) { | 1205 | if (obj == NULL) { |
1169 | DRM_ERROR("Failed to allocate ringbuffer\n"); | 1206 | DRM_ERROR("Failed to allocate ringbuffer\n"); |
1170 | ret = -ENOMEM; | 1207 | ret = -ENOMEM; |
@@ -1182,7 +1219,7 @@ static int intel_init_ring_buffer(struct drm_device *dev, | |||
1182 | goto err_unpin; | 1219 | goto err_unpin; |
1183 | 1220 | ||
1184 | ring->virtual_start = | 1221 | ring->virtual_start = |
1185 | ioremap_wc(dev_priv->mm.gtt->gma_bus_addr + obj->gtt_offset, | 1222 | ioremap_wc(dev_priv->gtt.mappable_base + obj->gtt_offset, |
1186 | ring->size); | 1223 | ring->size); |
1187 | if (ring->virtual_start == NULL) { | 1224 | if (ring->virtual_start == NULL) { |
1188 | DRM_ERROR("Failed to map ringbuffer.\n"); | 1225 | DRM_ERROR("Failed to map ringbuffer.\n"); |
@@ -1348,7 +1385,8 @@ static int ring_wait_for_space(struct intel_ring_buffer *ring, int n) | |||
1348 | 1385 | ||
1349 | msleep(1); | 1386 | msleep(1); |
1350 | 1387 | ||
1351 | ret = i915_gem_check_wedge(dev_priv, dev_priv->mm.interruptible); | 1388 | ret = i915_gem_check_wedge(&dev_priv->gpu_error, |
1389 | dev_priv->mm.interruptible); | ||
1352 | if (ret) | 1390 | if (ret) |
1353 | return ret; | 1391 | return ret; |
1354 | } while (!time_after(jiffies, end)); | 1392 | } while (!time_after(jiffies, end)); |
@@ -1410,14 +1448,35 @@ intel_ring_alloc_seqno(struct intel_ring_buffer *ring) | |||
1410 | return i915_gem_get_seqno(ring->dev, &ring->outstanding_lazy_request); | 1448 | return i915_gem_get_seqno(ring->dev, &ring->outstanding_lazy_request); |
1411 | } | 1449 | } |
1412 | 1450 | ||
1451 | static int __intel_ring_begin(struct intel_ring_buffer *ring, | ||
1452 | int bytes) | ||
1453 | { | ||
1454 | int ret; | ||
1455 | |||
1456 | if (unlikely(ring->tail + bytes > ring->effective_size)) { | ||
1457 | ret = intel_wrap_ring_buffer(ring); | ||
1458 | if (unlikely(ret)) | ||
1459 | return ret; | ||
1460 | } | ||
1461 | |||
1462 | if (unlikely(ring->space < bytes)) { | ||
1463 | ret = ring_wait_for_space(ring, bytes); | ||
1464 | if (unlikely(ret)) | ||
1465 | return ret; | ||
1466 | } | ||
1467 | |||
1468 | ring->space -= bytes; | ||
1469 | return 0; | ||
1470 | } | ||
1471 | |||
1413 | int intel_ring_begin(struct intel_ring_buffer *ring, | 1472 | int intel_ring_begin(struct intel_ring_buffer *ring, |
1414 | int num_dwords) | 1473 | int num_dwords) |
1415 | { | 1474 | { |
1416 | drm_i915_private_t *dev_priv = ring->dev->dev_private; | 1475 | drm_i915_private_t *dev_priv = ring->dev->dev_private; |
1417 | int n = 4*num_dwords; | ||
1418 | int ret; | 1476 | int ret; |
1419 | 1477 | ||
1420 | ret = i915_gem_check_wedge(dev_priv, dev_priv->mm.interruptible); | 1478 | ret = i915_gem_check_wedge(&dev_priv->gpu_error, |
1479 | dev_priv->mm.interruptible); | ||
1421 | if (ret) | 1480 | if (ret) |
1422 | return ret; | 1481 | return ret; |
1423 | 1482 | ||
@@ -1426,20 +1485,21 @@ int intel_ring_begin(struct intel_ring_buffer *ring, | |||
1426 | if (ret) | 1485 | if (ret) |
1427 | return ret; | 1486 | return ret; |
1428 | 1487 | ||
1429 | if (unlikely(ring->tail + n > ring->effective_size)) { | 1488 | return __intel_ring_begin(ring, num_dwords * sizeof(uint32_t)); |
1430 | ret = intel_wrap_ring_buffer(ring); | 1489 | } |
1431 | if (unlikely(ret)) | ||
1432 | return ret; | ||
1433 | } | ||
1434 | 1490 | ||
1435 | if (unlikely(ring->space < n)) { | 1491 | void intel_ring_init_seqno(struct intel_ring_buffer *ring, u32 seqno) |
1436 | ret = ring_wait_for_space(ring, n); | 1492 | { |
1437 | if (unlikely(ret)) | 1493 | struct drm_i915_private *dev_priv = ring->dev->dev_private; |
1438 | return ret; | 1494 | |
1495 | BUG_ON(ring->outstanding_lazy_request); | ||
1496 | |||
1497 | if (INTEL_INFO(ring->dev)->gen >= 6) { | ||
1498 | I915_WRITE(RING_SYNC_0(ring->mmio_base), 0); | ||
1499 | I915_WRITE(RING_SYNC_1(ring->mmio_base), 0); | ||
1439 | } | 1500 | } |
1440 | 1501 | ||
1441 | ring->space -= n; | 1502 | ring->set_seqno(ring, seqno); |
1442 | return 0; | ||
1443 | } | 1503 | } |
1444 | 1504 | ||
1445 | void intel_ring_advance(struct intel_ring_buffer *ring) | 1505 | void intel_ring_advance(struct intel_ring_buffer *ring) |
@@ -1447,7 +1507,7 @@ void intel_ring_advance(struct intel_ring_buffer *ring) | |||
1447 | struct drm_i915_private *dev_priv = ring->dev->dev_private; | 1507 | struct drm_i915_private *dev_priv = ring->dev->dev_private; |
1448 | 1508 | ||
1449 | ring->tail &= ring->size - 1; | 1509 | ring->tail &= ring->size - 1; |
1450 | if (dev_priv->stop_rings & intel_ring_flag(ring)) | 1510 | if (dev_priv->gpu_error.stop_rings & intel_ring_flag(ring)) |
1451 | return; | 1511 | return; |
1452 | ring->write_tail(ring, ring->tail); | 1512 | ring->write_tail(ring, ring->tail); |
1453 | } | 1513 | } |
@@ -1604,6 +1664,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev) | |||
1604 | ring->irq_put = gen6_ring_put_irq; | 1664 | ring->irq_put = gen6_ring_put_irq; |
1605 | ring->irq_enable_mask = GT_USER_INTERRUPT; | 1665 | ring->irq_enable_mask = GT_USER_INTERRUPT; |
1606 | ring->get_seqno = gen6_ring_get_seqno; | 1666 | ring->get_seqno = gen6_ring_get_seqno; |
1667 | ring->set_seqno = ring_set_seqno; | ||
1607 | ring->sync_to = gen6_ring_sync; | 1668 | ring->sync_to = gen6_ring_sync; |
1608 | ring->semaphore_register[0] = MI_SEMAPHORE_SYNC_INVALID; | 1669 | ring->semaphore_register[0] = MI_SEMAPHORE_SYNC_INVALID; |
1609 | ring->semaphore_register[1] = MI_SEMAPHORE_SYNC_RV; | 1670 | ring->semaphore_register[1] = MI_SEMAPHORE_SYNC_RV; |
@@ -1614,6 +1675,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev) | |||
1614 | ring->add_request = pc_render_add_request; | 1675 | ring->add_request = pc_render_add_request; |
1615 | ring->flush = gen4_render_ring_flush; | 1676 | ring->flush = gen4_render_ring_flush; |
1616 | ring->get_seqno = pc_render_get_seqno; | 1677 | ring->get_seqno = pc_render_get_seqno; |
1678 | ring->set_seqno = pc_render_set_seqno; | ||
1617 | ring->irq_get = gen5_ring_get_irq; | 1679 | ring->irq_get = gen5_ring_get_irq; |
1618 | ring->irq_put = gen5_ring_put_irq; | 1680 | ring->irq_put = gen5_ring_put_irq; |
1619 | ring->irq_enable_mask = GT_USER_INTERRUPT | GT_PIPE_NOTIFY; | 1681 | ring->irq_enable_mask = GT_USER_INTERRUPT | GT_PIPE_NOTIFY; |
@@ -1624,6 +1686,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev) | |||
1624 | else | 1686 | else |
1625 | ring->flush = gen4_render_ring_flush; | 1687 | ring->flush = gen4_render_ring_flush; |
1626 | ring->get_seqno = ring_get_seqno; | 1688 | ring->get_seqno = ring_get_seqno; |
1689 | ring->set_seqno = ring_set_seqno; | ||
1627 | if (IS_GEN2(dev)) { | 1690 | if (IS_GEN2(dev)) { |
1628 | ring->irq_get = i8xx_ring_get_irq; | 1691 | ring->irq_get = i8xx_ring_get_irq; |
1629 | ring->irq_put = i8xx_ring_put_irq; | 1692 | ring->irq_put = i8xx_ring_put_irq; |
@@ -1695,6 +1758,7 @@ int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size) | |||
1695 | else | 1758 | else |
1696 | ring->flush = gen4_render_ring_flush; | 1759 | ring->flush = gen4_render_ring_flush; |
1697 | ring->get_seqno = ring_get_seqno; | 1760 | ring->get_seqno = ring_get_seqno; |
1761 | ring->set_seqno = ring_set_seqno; | ||
1698 | if (IS_GEN2(dev)) { | 1762 | if (IS_GEN2(dev)) { |
1699 | ring->irq_get = i8xx_ring_get_irq; | 1763 | ring->irq_get = i8xx_ring_get_irq; |
1700 | ring->irq_put = i8xx_ring_put_irq; | 1764 | ring->irq_put = i8xx_ring_put_irq; |
@@ -1755,6 +1819,7 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) | |||
1755 | ring->flush = gen6_ring_flush; | 1819 | ring->flush = gen6_ring_flush; |
1756 | ring->add_request = gen6_add_request; | 1820 | ring->add_request = gen6_add_request; |
1757 | ring->get_seqno = gen6_ring_get_seqno; | 1821 | ring->get_seqno = gen6_ring_get_seqno; |
1822 | ring->set_seqno = ring_set_seqno; | ||
1758 | ring->irq_enable_mask = GEN6_BSD_USER_INTERRUPT; | 1823 | ring->irq_enable_mask = GEN6_BSD_USER_INTERRUPT; |
1759 | ring->irq_get = gen6_ring_get_irq; | 1824 | ring->irq_get = gen6_ring_get_irq; |
1760 | ring->irq_put = gen6_ring_put_irq; | 1825 | ring->irq_put = gen6_ring_put_irq; |
@@ -1770,6 +1835,7 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) | |||
1770 | ring->flush = bsd_ring_flush; | 1835 | ring->flush = bsd_ring_flush; |
1771 | ring->add_request = i9xx_add_request; | 1836 | ring->add_request = i9xx_add_request; |
1772 | ring->get_seqno = ring_get_seqno; | 1837 | ring->get_seqno = ring_get_seqno; |
1838 | ring->set_seqno = ring_set_seqno; | ||
1773 | if (IS_GEN5(dev)) { | 1839 | if (IS_GEN5(dev)) { |
1774 | ring->irq_enable_mask = GT_BSD_USER_INTERRUPT; | 1840 | ring->irq_enable_mask = GT_BSD_USER_INTERRUPT; |
1775 | ring->irq_get = gen5_ring_get_irq; | 1841 | ring->irq_get = gen5_ring_get_irq; |
@@ -1799,6 +1865,7 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) | |||
1799 | ring->flush = blt_ring_flush; | 1865 | ring->flush = blt_ring_flush; |
1800 | ring->add_request = gen6_add_request; | 1866 | ring->add_request = gen6_add_request; |
1801 | ring->get_seqno = gen6_ring_get_seqno; | 1867 | ring->get_seqno = gen6_ring_get_seqno; |
1868 | ring->set_seqno = ring_set_seqno; | ||
1802 | ring->irq_enable_mask = GEN6_BLITTER_USER_INTERRUPT; | 1869 | ring->irq_enable_mask = GEN6_BLITTER_USER_INTERRUPT; |
1803 | ring->irq_get = gen6_ring_get_irq; | 1870 | ring->irq_get = gen6_ring_get_irq; |
1804 | ring->irq_put = gen6_ring_put_irq; | 1871 | ring->irq_put = gen6_ring_put_irq; |