diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 123 |
1 files changed, 85 insertions, 38 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 8da1bde442dd..12e734b29463 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -28,9 +28,12 @@ | |||
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include <linux/log2.h> | 30 | #include <linux/log2.h> |
31 | |||
31 | #include <drm/drmP.h> | 32 | #include <drm/drmP.h> |
32 | #include "i915_drv.h" | ||
33 | #include <drm/i915_drm.h> | 33 | #include <drm/i915_drm.h> |
34 | |||
35 | #include "i915_drv.h" | ||
36 | #include "i915_gem_render_state.h" | ||
34 | #include "i915_trace.h" | 37 | #include "i915_trace.h" |
35 | #include "intel_drv.h" | 38 | #include "intel_drv.h" |
36 | 39 | ||
@@ -480,10 +483,14 @@ static bool stop_ring(struct intel_engine_cs *engine) | |||
480 | } | 483 | } |
481 | } | 484 | } |
482 | 485 | ||
483 | I915_WRITE_CTL(engine, 0); | 486 | I915_WRITE_HEAD(engine, I915_READ_TAIL(engine)); |
487 | |||
484 | I915_WRITE_HEAD(engine, 0); | 488 | I915_WRITE_HEAD(engine, 0); |
485 | I915_WRITE_TAIL(engine, 0); | 489 | I915_WRITE_TAIL(engine, 0); |
486 | 490 | ||
491 | /* The ring must be empty before it is disabled */ | ||
492 | I915_WRITE_CTL(engine, 0); | ||
493 | |||
487 | return (I915_READ_HEAD(engine) & HEAD_ADDR) == 0; | 494 | return (I915_READ_HEAD(engine) & HEAD_ADDR) == 0; |
488 | } | 495 | } |
489 | 496 | ||
@@ -1359,12 +1366,13 @@ static int context_pin(struct i915_gem_context *ctx) | |||
1359 | struct i915_vma *vma = ctx->engine[RCS].state; | 1366 | struct i915_vma *vma = ctx->engine[RCS].state; |
1360 | int ret; | 1367 | int ret; |
1361 | 1368 | ||
1362 | /* Clear this page out of any CPU caches for coherent swap-in/out. | 1369 | /* |
1370 | * Clear this page out of any CPU caches for coherent swap-in/out. | ||
1363 | * We only want to do this on the first bind so that we do not stall | 1371 | * We only want to do this on the first bind so that we do not stall |
1364 | * on an active context (which by nature is already on the GPU). | 1372 | * on an active context (which by nature is already on the GPU). |
1365 | */ | 1373 | */ |
1366 | if (!(vma->flags & I915_VMA_GLOBAL_BIND)) { | 1374 | if (!(vma->flags & I915_VMA_GLOBAL_BIND)) { |
1367 | ret = i915_gem_object_set_to_gtt_domain(vma->obj, false); | 1375 | ret = i915_gem_object_set_to_gtt_domain(vma->obj, true); |
1368 | if (ret) | 1376 | if (ret) |
1369 | return ret; | 1377 | return ret; |
1370 | } | 1378 | } |
@@ -1379,11 +1387,34 @@ alloc_context_vma(struct intel_engine_cs *engine) | |||
1379 | struct drm_i915_private *i915 = engine->i915; | 1387 | struct drm_i915_private *i915 = engine->i915; |
1380 | struct drm_i915_gem_object *obj; | 1388 | struct drm_i915_gem_object *obj; |
1381 | struct i915_vma *vma; | 1389 | struct i915_vma *vma; |
1390 | int err; | ||
1382 | 1391 | ||
1383 | obj = i915_gem_object_create(i915, engine->context_size); | 1392 | obj = i915_gem_object_create(i915, engine->context_size); |
1384 | if (IS_ERR(obj)) | 1393 | if (IS_ERR(obj)) |
1385 | return ERR_CAST(obj); | 1394 | return ERR_CAST(obj); |
1386 | 1395 | ||
1396 | if (engine->default_state) { | ||
1397 | void *defaults, *vaddr; | ||
1398 | |||
1399 | vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB); | ||
1400 | if (IS_ERR(vaddr)) { | ||
1401 | err = PTR_ERR(vaddr); | ||
1402 | goto err_obj; | ||
1403 | } | ||
1404 | |||
1405 | defaults = i915_gem_object_pin_map(engine->default_state, | ||
1406 | I915_MAP_WB); | ||
1407 | if (IS_ERR(defaults)) { | ||
1408 | err = PTR_ERR(defaults); | ||
1409 | goto err_map; | ||
1410 | } | ||
1411 | |||
1412 | memcpy(vaddr, defaults, engine->context_size); | ||
1413 | |||
1414 | i915_gem_object_unpin_map(engine->default_state); | ||
1415 | i915_gem_object_unpin_map(obj); | ||
1416 | } | ||
1417 | |||
1387 | /* | 1418 | /* |
1388 | * Try to make the context utilize L3 as well as LLC. | 1419 | * Try to make the context utilize L3 as well as LLC. |
1389 | * | 1420 | * |
@@ -1405,10 +1436,18 @@ alloc_context_vma(struct intel_engine_cs *engine) | |||
1405 | } | 1436 | } |
1406 | 1437 | ||
1407 | vma = i915_vma_instance(obj, &i915->ggtt.base, NULL); | 1438 | vma = i915_vma_instance(obj, &i915->ggtt.base, NULL); |
1408 | if (IS_ERR(vma)) | 1439 | if (IS_ERR(vma)) { |
1409 | i915_gem_object_put(obj); | 1440 | err = PTR_ERR(vma); |
1441 | goto err_obj; | ||
1442 | } | ||
1410 | 1443 | ||
1411 | return vma; | 1444 | return vma; |
1445 | |||
1446 | err_map: | ||
1447 | i915_gem_object_unpin_map(obj); | ||
1448 | err_obj: | ||
1449 | i915_gem_object_put(obj); | ||
1450 | return ERR_PTR(err); | ||
1412 | } | 1451 | } |
1413 | 1452 | ||
1414 | static struct intel_ring * | 1453 | static struct intel_ring * |
@@ -1441,20 +1480,9 @@ intel_ring_context_pin(struct intel_engine_cs *engine, | |||
1441 | if (ret) | 1480 | if (ret) |
1442 | goto err; | 1481 | goto err; |
1443 | 1482 | ||
1444 | ce->state->obj->mm.dirty = true; | ||
1445 | ce->state->obj->pin_global++; | 1483 | ce->state->obj->pin_global++; |
1446 | } | 1484 | } |
1447 | 1485 | ||
1448 | /* The kernel context is only used as a placeholder for flushing the | ||
1449 | * active context. It is never used for submitting user rendering and | ||
1450 | * as such never requires the golden render context, and so we can skip | ||
1451 | * emitting it when we switch to the kernel context. This is required | ||
1452 | * as during eviction we cannot allocate and pin the renderstate in | ||
1453 | * order to initialise the context. | ||
1454 | */ | ||
1455 | if (i915_gem_context_is_kernel(ctx)) | ||
1456 | ce->initialised = true; | ||
1457 | |||
1458 | i915_gem_context_get(ctx); | 1486 | i915_gem_context_get(ctx); |
1459 | 1487 | ||
1460 | out: | 1488 | out: |
@@ -1550,7 +1578,7 @@ void intel_legacy_submission_resume(struct drm_i915_private *dev_priv) | |||
1550 | 1578 | ||
1551 | static int ring_request_alloc(struct drm_i915_gem_request *request) | 1579 | static int ring_request_alloc(struct drm_i915_gem_request *request) |
1552 | { | 1580 | { |
1553 | u32 *cs; | 1581 | int ret; |
1554 | 1582 | ||
1555 | GEM_BUG_ON(!request->ctx->engine[request->engine->id].pin_count); | 1583 | GEM_BUG_ON(!request->ctx->engine[request->engine->id].pin_count); |
1556 | 1584 | ||
@@ -1560,37 +1588,24 @@ static int ring_request_alloc(struct drm_i915_gem_request *request) | |||
1560 | */ | 1588 | */ |
1561 | request->reserved_space += LEGACY_REQUEST_SIZE; | 1589 | request->reserved_space += LEGACY_REQUEST_SIZE; |
1562 | 1590 | ||
1563 | cs = intel_ring_begin(request, 0); | 1591 | ret = intel_ring_wait_for_space(request->ring, request->reserved_space); |
1564 | if (IS_ERR(cs)) | 1592 | if (ret) |
1565 | return PTR_ERR(cs); | 1593 | return ret; |
1566 | 1594 | ||
1567 | request->reserved_space -= LEGACY_REQUEST_SIZE; | 1595 | request->reserved_space -= LEGACY_REQUEST_SIZE; |
1568 | return 0; | 1596 | return 0; |
1569 | } | 1597 | } |
1570 | 1598 | ||
1571 | static noinline int wait_for_space(struct drm_i915_gem_request *req, | 1599 | static noinline int wait_for_space(struct intel_ring *ring, unsigned int bytes) |
1572 | unsigned int bytes) | ||
1573 | { | 1600 | { |
1574 | struct intel_ring *ring = req->ring; | ||
1575 | struct drm_i915_gem_request *target; | 1601 | struct drm_i915_gem_request *target; |
1576 | long timeout; | 1602 | long timeout; |
1577 | 1603 | ||
1578 | lockdep_assert_held(&req->i915->drm.struct_mutex); | 1604 | lockdep_assert_held(&ring->vma->vm->i915->drm.struct_mutex); |
1579 | 1605 | ||
1580 | if (intel_ring_update_space(ring) >= bytes) | 1606 | if (intel_ring_update_space(ring) >= bytes) |
1581 | return 0; | 1607 | return 0; |
1582 | 1608 | ||
1583 | /* | ||
1584 | * Space is reserved in the ringbuffer for finalising the request, | ||
1585 | * as that cannot be allowed to fail. During request finalisation, | ||
1586 | * reserved_space is set to 0 to stop the overallocation and the | ||
1587 | * assumption is that then we never need to wait (which has the | ||
1588 | * risk of failing with EINTR). | ||
1589 | * | ||
1590 | * See also i915_gem_request_alloc() and i915_add_request(). | ||
1591 | */ | ||
1592 | GEM_BUG_ON(!req->reserved_space); | ||
1593 | |||
1594 | list_for_each_entry(target, &ring->request_list, ring_link) { | 1609 | list_for_each_entry(target, &ring->request_list, ring_link) { |
1595 | /* Would completion of this request free enough space? */ | 1610 | /* Would completion of this request free enough space? */ |
1596 | if (bytes <= __intel_ring_space(target->postfix, | 1611 | if (bytes <= __intel_ring_space(target->postfix, |
@@ -1614,6 +1629,22 @@ static noinline int wait_for_space(struct drm_i915_gem_request *req, | |||
1614 | return 0; | 1629 | return 0; |
1615 | } | 1630 | } |
1616 | 1631 | ||
1632 | int intel_ring_wait_for_space(struct intel_ring *ring, unsigned int bytes) | ||
1633 | { | ||
1634 | GEM_BUG_ON(bytes > ring->effective_size); | ||
1635 | if (unlikely(bytes > ring->effective_size - ring->emit)) | ||
1636 | bytes += ring->size - ring->emit; | ||
1637 | |||
1638 | if (unlikely(bytes > ring->space)) { | ||
1639 | int ret = wait_for_space(ring, bytes); | ||
1640 | if (unlikely(ret)) | ||
1641 | return ret; | ||
1642 | } | ||
1643 | |||
1644 | GEM_BUG_ON(ring->space < bytes); | ||
1645 | return 0; | ||
1646 | } | ||
1647 | |||
1617 | u32 *intel_ring_begin(struct drm_i915_gem_request *req, | 1648 | u32 *intel_ring_begin(struct drm_i915_gem_request *req, |
1618 | unsigned int num_dwords) | 1649 | unsigned int num_dwords) |
1619 | { | 1650 | { |
@@ -1653,7 +1684,20 @@ u32 *intel_ring_begin(struct drm_i915_gem_request *req, | |||
1653 | } | 1684 | } |
1654 | 1685 | ||
1655 | if (unlikely(total_bytes > ring->space)) { | 1686 | if (unlikely(total_bytes > ring->space)) { |
1656 | int ret = wait_for_space(req, total_bytes); | 1687 | int ret; |
1688 | |||
1689 | /* | ||
1690 | * Space is reserved in the ringbuffer for finalising the | ||
1691 | * request, as that cannot be allowed to fail. During request | ||
1692 | * finalisation, reserved_space is set to 0 to stop the | ||
1693 | * overallocation and the assumption is that then we never need | ||
1694 | * to wait (which has the risk of failing with EINTR). | ||
1695 | * | ||
1696 | * See also i915_gem_request_alloc() and i915_add_request(). | ||
1697 | */ | ||
1698 | GEM_BUG_ON(!req->reserved_space); | ||
1699 | |||
1700 | ret = wait_for_space(ring, total_bytes); | ||
1657 | if (unlikely(ret)) | 1701 | if (unlikely(ret)) |
1658 | return ERR_PTR(ret); | 1702 | return ERR_PTR(ret); |
1659 | } | 1703 | } |
@@ -2028,12 +2072,15 @@ static void i9xx_set_default_submission(struct intel_engine_cs *engine) | |||
2028 | { | 2072 | { |
2029 | engine->submit_request = i9xx_submit_request; | 2073 | engine->submit_request = i9xx_submit_request; |
2030 | engine->cancel_requests = cancel_requests; | 2074 | engine->cancel_requests = cancel_requests; |
2075 | |||
2076 | engine->park = NULL; | ||
2077 | engine->unpark = NULL; | ||
2031 | } | 2078 | } |
2032 | 2079 | ||
2033 | static void gen6_bsd_set_default_submission(struct intel_engine_cs *engine) | 2080 | static void gen6_bsd_set_default_submission(struct intel_engine_cs *engine) |
2034 | { | 2081 | { |
2082 | i9xx_set_default_submission(engine); | ||
2035 | engine->submit_request = gen6_bsd_submit_request; | 2083 | engine->submit_request = gen6_bsd_submit_request; |
2036 | engine->cancel_requests = cancel_requests; | ||
2037 | } | 2084 | } |
2038 | 2085 | ||
2039 | static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv, | 2086 | static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv, |