diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 119 |
1 files changed, 94 insertions, 25 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index ecbc5c5dbbbc..1aa76892a830 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -245,7 +245,7 @@ gen6_render_ring_flush(struct intel_ring_buffer *ring, | |||
245 | /* | 245 | /* |
246 | * TLB invalidate requires a post-sync write. | 246 | * TLB invalidate requires a post-sync write. |
247 | */ | 247 | */ |
248 | flags |= PIPE_CONTROL_QW_WRITE; | 248 | flags |= PIPE_CONTROL_QW_WRITE | PIPE_CONTROL_CS_STALL; |
249 | } | 249 | } |
250 | 250 | ||
251 | ret = intel_ring_begin(ring, 4); | 251 | ret = intel_ring_begin(ring, 4); |
@@ -964,7 +964,9 @@ gen6_ring_put_irq(struct intel_ring_buffer *ring) | |||
964 | } | 964 | } |
965 | 965 | ||
966 | static int | 966 | static int |
967 | i965_dispatch_execbuffer(struct intel_ring_buffer *ring, u32 offset, u32 length) | 967 | i965_dispatch_execbuffer(struct intel_ring_buffer *ring, |
968 | u32 offset, u32 length, | ||
969 | unsigned flags) | ||
968 | { | 970 | { |
969 | int ret; | 971 | int ret; |
970 | 972 | ||
@@ -975,7 +977,7 @@ i965_dispatch_execbuffer(struct intel_ring_buffer *ring, u32 offset, u32 length) | |||
975 | intel_ring_emit(ring, | 977 | intel_ring_emit(ring, |
976 | MI_BATCH_BUFFER_START | | 978 | MI_BATCH_BUFFER_START | |
977 | MI_BATCH_GTT | | 979 | MI_BATCH_GTT | |
978 | MI_BATCH_NON_SECURE_I965); | 980 | (flags & I915_DISPATCH_SECURE ? 0 : MI_BATCH_NON_SECURE_I965)); |
979 | intel_ring_emit(ring, offset); | 981 | intel_ring_emit(ring, offset); |
980 | intel_ring_advance(ring); | 982 | intel_ring_advance(ring); |
981 | 983 | ||
@@ -984,7 +986,8 @@ i965_dispatch_execbuffer(struct intel_ring_buffer *ring, u32 offset, u32 length) | |||
984 | 986 | ||
985 | static int | 987 | static int |
986 | i830_dispatch_execbuffer(struct intel_ring_buffer *ring, | 988 | i830_dispatch_execbuffer(struct intel_ring_buffer *ring, |
987 | u32 offset, u32 len) | 989 | u32 offset, u32 len, |
990 | unsigned flags) | ||
988 | { | 991 | { |
989 | int ret; | 992 | int ret; |
990 | 993 | ||
@@ -993,7 +996,7 @@ i830_dispatch_execbuffer(struct intel_ring_buffer *ring, | |||
993 | return ret; | 996 | return ret; |
994 | 997 | ||
995 | intel_ring_emit(ring, MI_BATCH_BUFFER); | 998 | intel_ring_emit(ring, MI_BATCH_BUFFER); |
996 | intel_ring_emit(ring, offset | MI_BATCH_NON_SECURE); | 999 | intel_ring_emit(ring, offset | (flags & I915_DISPATCH_SECURE ? 0 : MI_BATCH_NON_SECURE)); |
997 | intel_ring_emit(ring, offset + len - 8); | 1000 | intel_ring_emit(ring, offset + len - 8); |
998 | intel_ring_emit(ring, 0); | 1001 | intel_ring_emit(ring, 0); |
999 | intel_ring_advance(ring); | 1002 | intel_ring_advance(ring); |
@@ -1003,7 +1006,8 @@ i830_dispatch_execbuffer(struct intel_ring_buffer *ring, | |||
1003 | 1006 | ||
1004 | static int | 1007 | static int |
1005 | i915_dispatch_execbuffer(struct intel_ring_buffer *ring, | 1008 | i915_dispatch_execbuffer(struct intel_ring_buffer *ring, |
1006 | u32 offset, u32 len) | 1009 | u32 offset, u32 len, |
1010 | unsigned flags) | ||
1007 | { | 1011 | { |
1008 | int ret; | 1012 | int ret; |
1009 | 1013 | ||
@@ -1012,7 +1016,7 @@ i915_dispatch_execbuffer(struct intel_ring_buffer *ring, | |||
1012 | return ret; | 1016 | return ret; |
1013 | 1017 | ||
1014 | intel_ring_emit(ring, MI_BATCH_BUFFER_START | MI_BATCH_GTT); | 1018 | intel_ring_emit(ring, MI_BATCH_BUFFER_START | MI_BATCH_GTT); |
1015 | intel_ring_emit(ring, offset | MI_BATCH_NON_SECURE); | 1019 | intel_ring_emit(ring, offset | (flags & I915_DISPATCH_SECURE ? 0 : MI_BATCH_NON_SECURE)); |
1016 | intel_ring_advance(ring); | 1020 | intel_ring_advance(ring); |
1017 | 1021 | ||
1018 | return 0; | 1022 | return 0; |
@@ -1075,6 +1079,29 @@ err: | |||
1075 | return ret; | 1079 | return ret; |
1076 | } | 1080 | } |
1077 | 1081 | ||
1082 | static int init_phys_hws_pga(struct intel_ring_buffer *ring) | ||
1083 | { | ||
1084 | struct drm_i915_private *dev_priv = ring->dev->dev_private; | ||
1085 | u32 addr; | ||
1086 | |||
1087 | if (!dev_priv->status_page_dmah) { | ||
1088 | dev_priv->status_page_dmah = | ||
1089 | drm_pci_alloc(ring->dev, PAGE_SIZE, PAGE_SIZE); | ||
1090 | if (!dev_priv->status_page_dmah) | ||
1091 | return -ENOMEM; | ||
1092 | } | ||
1093 | |||
1094 | addr = dev_priv->status_page_dmah->busaddr; | ||
1095 | if (INTEL_INFO(ring->dev)->gen >= 4) | ||
1096 | addr |= (dev_priv->status_page_dmah->busaddr >> 28) & 0xf0; | ||
1097 | I915_WRITE(HWS_PGA, addr); | ||
1098 | |||
1099 | ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr; | ||
1100 | memset(ring->status_page.page_addr, 0, PAGE_SIZE); | ||
1101 | |||
1102 | return 0; | ||
1103 | } | ||
1104 | |||
1078 | static int intel_init_ring_buffer(struct drm_device *dev, | 1105 | static int intel_init_ring_buffer(struct drm_device *dev, |
1079 | struct intel_ring_buffer *ring) | 1106 | struct intel_ring_buffer *ring) |
1080 | { | 1107 | { |
@@ -1093,6 +1120,11 @@ static int intel_init_ring_buffer(struct drm_device *dev, | |||
1093 | ret = init_status_page(ring); | 1120 | ret = init_status_page(ring); |
1094 | if (ret) | 1121 | if (ret) |
1095 | return ret; | 1122 | return ret; |
1123 | } else { | ||
1124 | BUG_ON(ring->id != RCS); | ||
1125 | ret = init_phys_hws_pga(ring); | ||
1126 | if (ret) | ||
1127 | return ret; | ||
1096 | } | 1128 | } |
1097 | 1129 | ||
1098 | obj = i915_gem_alloc_object(dev, ring->size); | 1130 | obj = i915_gem_alloc_object(dev, ring->size); |
@@ -1391,10 +1423,17 @@ static int gen6_ring_flush(struct intel_ring_buffer *ring, | |||
1391 | return ret; | 1423 | return ret; |
1392 | 1424 | ||
1393 | cmd = MI_FLUSH_DW; | 1425 | cmd = MI_FLUSH_DW; |
1426 | /* | ||
1427 | * Bspec vol 1c.5 - video engine command streamer: | ||
1428 | * "If ENABLED, all TLBs will be invalidated once the flush | ||
1429 | * operation is complete. This bit is only valid when the | ||
1430 | * Post-Sync Operation field is a value of 1h or 3h." | ||
1431 | */ | ||
1394 | if (invalidate & I915_GEM_GPU_DOMAINS) | 1432 | if (invalidate & I915_GEM_GPU_DOMAINS) |
1395 | cmd |= MI_INVALIDATE_TLB | MI_INVALIDATE_BSD; | 1433 | cmd |= MI_INVALIDATE_TLB | MI_INVALIDATE_BSD | |
1434 | MI_FLUSH_DW_STORE_INDEX | MI_FLUSH_DW_OP_STOREDW; | ||
1396 | intel_ring_emit(ring, cmd); | 1435 | intel_ring_emit(ring, cmd); |
1397 | intel_ring_emit(ring, 0); | 1436 | intel_ring_emit(ring, I915_GEM_HWS_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT); |
1398 | intel_ring_emit(ring, 0); | 1437 | intel_ring_emit(ring, 0); |
1399 | intel_ring_emit(ring, MI_NOOP); | 1438 | intel_ring_emit(ring, MI_NOOP); |
1400 | intel_ring_advance(ring); | 1439 | intel_ring_advance(ring); |
@@ -1402,8 +1441,30 @@ static int gen6_ring_flush(struct intel_ring_buffer *ring, | |||
1402 | } | 1441 | } |
1403 | 1442 | ||
1404 | static int | 1443 | static int |
1444 | hsw_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, | ||
1445 | u32 offset, u32 len, | ||
1446 | unsigned flags) | ||
1447 | { | ||
1448 | int ret; | ||
1449 | |||
1450 | ret = intel_ring_begin(ring, 2); | ||
1451 | if (ret) | ||
1452 | return ret; | ||
1453 | |||
1454 | intel_ring_emit(ring, | ||
1455 | MI_BATCH_BUFFER_START | MI_BATCH_PPGTT_HSW | | ||
1456 | (flags & I915_DISPATCH_SECURE ? 0 : MI_BATCH_NON_SECURE_HSW)); | ||
1457 | /* bit0-7 is the length on GEN6+ */ | ||
1458 | intel_ring_emit(ring, offset); | ||
1459 | intel_ring_advance(ring); | ||
1460 | |||
1461 | return 0; | ||
1462 | } | ||
1463 | |||
1464 | static int | ||
1405 | gen6_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, | 1465 | gen6_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, |
1406 | u32 offset, u32 len) | 1466 | u32 offset, u32 len, |
1467 | unsigned flags) | ||
1407 | { | 1468 | { |
1408 | int ret; | 1469 | int ret; |
1409 | 1470 | ||
@@ -1411,7 +1472,9 @@ gen6_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, | |||
1411 | if (ret) | 1472 | if (ret) |
1412 | return ret; | 1473 | return ret; |
1413 | 1474 | ||
1414 | intel_ring_emit(ring, MI_BATCH_BUFFER_START | MI_BATCH_NON_SECURE_I965); | 1475 | intel_ring_emit(ring, |
1476 | MI_BATCH_BUFFER_START | | ||
1477 | (flags & I915_DISPATCH_SECURE ? 0 : MI_BATCH_NON_SECURE_I965)); | ||
1415 | /* bit0-7 is the length on GEN6+ */ | 1478 | /* bit0-7 is the length on GEN6+ */ |
1416 | intel_ring_emit(ring, offset); | 1479 | intel_ring_emit(ring, offset); |
1417 | intel_ring_advance(ring); | 1480 | intel_ring_advance(ring); |
@@ -1432,10 +1495,17 @@ static int blt_ring_flush(struct intel_ring_buffer *ring, | |||
1432 | return ret; | 1495 | return ret; |
1433 | 1496 | ||
1434 | cmd = MI_FLUSH_DW; | 1497 | cmd = MI_FLUSH_DW; |
1498 | /* | ||
1499 | * Bspec vol 1c.3 - blitter engine command streamer: | ||
1500 | * "If ENABLED, all TLBs will be invalidated once the flush | ||
1501 | * operation is complete. This bit is only valid when the | ||
1502 | * Post-Sync Operation field is a value of 1h or 3h." | ||
1503 | */ | ||
1435 | if (invalidate & I915_GEM_DOMAIN_RENDER) | 1504 | if (invalidate & I915_GEM_DOMAIN_RENDER) |
1436 | cmd |= MI_INVALIDATE_TLB; | 1505 | cmd |= MI_INVALIDATE_TLB | MI_FLUSH_DW_STORE_INDEX | |
1506 | MI_FLUSH_DW_OP_STOREDW; | ||
1437 | intel_ring_emit(ring, cmd); | 1507 | intel_ring_emit(ring, cmd); |
1438 | intel_ring_emit(ring, 0); | 1508 | intel_ring_emit(ring, I915_GEM_HWS_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT); |
1439 | intel_ring_emit(ring, 0); | 1509 | intel_ring_emit(ring, 0); |
1440 | intel_ring_emit(ring, MI_NOOP); | 1510 | intel_ring_emit(ring, MI_NOOP); |
1441 | intel_ring_advance(ring); | 1511 | intel_ring_advance(ring); |
@@ -1490,7 +1560,9 @@ int intel_init_render_ring_buffer(struct drm_device *dev) | |||
1490 | ring->irq_enable_mask = I915_USER_INTERRUPT; | 1560 | ring->irq_enable_mask = I915_USER_INTERRUPT; |
1491 | } | 1561 | } |
1492 | ring->write_tail = ring_write_tail; | 1562 | ring->write_tail = ring_write_tail; |
1493 | if (INTEL_INFO(dev)->gen >= 6) | 1563 | if (IS_HASWELL(dev)) |
1564 | ring->dispatch_execbuffer = hsw_ring_dispatch_execbuffer; | ||
1565 | else if (INTEL_INFO(dev)->gen >= 6) | ||
1494 | ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; | 1566 | ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; |
1495 | else if (INTEL_INFO(dev)->gen >= 4) | 1567 | else if (INTEL_INFO(dev)->gen >= 4) |
1496 | ring->dispatch_execbuffer = i965_dispatch_execbuffer; | 1568 | ring->dispatch_execbuffer = i965_dispatch_execbuffer; |
@@ -1501,12 +1573,6 @@ int intel_init_render_ring_buffer(struct drm_device *dev) | |||
1501 | ring->init = init_render_ring; | 1573 | ring->init = init_render_ring; |
1502 | ring->cleanup = render_ring_cleanup; | 1574 | ring->cleanup = render_ring_cleanup; |
1503 | 1575 | ||
1504 | |||
1505 | if (!I915_NEED_GFX_HWS(dev)) { | ||
1506 | ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr; | ||
1507 | memset(ring->status_page.page_addr, 0, PAGE_SIZE); | ||
1508 | } | ||
1509 | |||
1510 | return intel_init_ring_buffer(dev, ring); | 1576 | return intel_init_ring_buffer(dev, ring); |
1511 | } | 1577 | } |
1512 | 1578 | ||
@@ -1514,6 +1580,7 @@ int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size) | |||
1514 | { | 1580 | { |
1515 | drm_i915_private_t *dev_priv = dev->dev_private; | 1581 | drm_i915_private_t *dev_priv = dev->dev_private; |
1516 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; | 1582 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; |
1583 | int ret; | ||
1517 | 1584 | ||
1518 | ring->name = "render ring"; | 1585 | ring->name = "render ring"; |
1519 | ring->id = RCS; | 1586 | ring->id = RCS; |
@@ -1551,16 +1618,13 @@ int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size) | |||
1551 | ring->init = init_render_ring; | 1618 | ring->init = init_render_ring; |
1552 | ring->cleanup = render_ring_cleanup; | 1619 | ring->cleanup = render_ring_cleanup; |
1553 | 1620 | ||
1554 | if (!I915_NEED_GFX_HWS(dev)) | ||
1555 | ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr; | ||
1556 | |||
1557 | ring->dev = dev; | 1621 | ring->dev = dev; |
1558 | INIT_LIST_HEAD(&ring->active_list); | 1622 | INIT_LIST_HEAD(&ring->active_list); |
1559 | INIT_LIST_HEAD(&ring->request_list); | 1623 | INIT_LIST_HEAD(&ring->request_list); |
1560 | 1624 | ||
1561 | ring->size = size; | 1625 | ring->size = size; |
1562 | ring->effective_size = ring->size; | 1626 | ring->effective_size = ring->size; |
1563 | if (IS_I830(ring->dev)) | 1627 | if (IS_I830(ring->dev) || IS_845G(ring->dev)) |
1564 | ring->effective_size -= 128; | 1628 | ring->effective_size -= 128; |
1565 | 1629 | ||
1566 | ring->virtual_start = ioremap_wc(start, size); | 1630 | ring->virtual_start = ioremap_wc(start, size); |
@@ -1570,6 +1634,12 @@ int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size) | |||
1570 | return -ENOMEM; | 1634 | return -ENOMEM; |
1571 | } | 1635 | } |
1572 | 1636 | ||
1637 | if (!I915_NEED_GFX_HWS(dev)) { | ||
1638 | ret = init_phys_hws_pga(ring); | ||
1639 | if (ret) | ||
1640 | return ret; | ||
1641 | } | ||
1642 | |||
1573 | return 0; | 1643 | return 0; |
1574 | } | 1644 | } |
1575 | 1645 | ||
@@ -1618,7 +1688,6 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) | |||
1618 | } | 1688 | } |
1619 | ring->init = init_ring_common; | 1689 | ring->init = init_ring_common; |
1620 | 1690 | ||
1621 | |||
1622 | return intel_init_ring_buffer(dev, ring); | 1691 | return intel_init_ring_buffer(dev, ring); |
1623 | } | 1692 | } |
1624 | 1693 | ||