diff options
author | Dave Airlie <airlied@redhat.com> | 2017-12-03 18:40:35 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2017-12-03 19:56:53 -0500 |
commit | ca797d29cd63e7b71b4eea29aff3b1cefd1ecb59 (patch) | |
tree | db1ada69f713da68b43c828bd15f90e250f86ab7 /drivers/gpu/drm/i915/intel_ringbuffer.c | |
parent | 2c1c55cb75a9c72f9726fabb8c3607947711a8df (diff) | |
parent | 010d118c20617021025a930bc8e90f371ab99da5 (diff) |
Merge tag 'drm-intel-next-2017-11-17-1' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
More change sets for 4.16:
- Many improvements for selftests and other igt tests (Chris)
- Forcewake with PUNIT->PMIC bus fixes and robustness (Hans)
- Define an engine class for uABI (Tvrtko)
- Context switch fixes and improvements (Chris)
- GT powersavings and power gating simplification and fixes (Chris)
- Other general driver clean-ups (Chris, Lucas, Ville)
- Removing old, useless and/or bad workarounds (Chris, Oscar, Radhakrishna)
- IPS, pipe config, etc in preparation for another Fast Boot attempt (Maarten)
- OA perf fixes and support to Coffee Lake and Cannonlake (Lionel)
- Fixes around GPU fault registers (Michel)
- GEM Proxy (Tina)
- Refactor of Geminilake and Cannonlake plane color handling (James)
- Generalize transcoder loop (Mika Kahola)
- New HW Workaround for Cannonlake and Geminilake (Rodrigo)
- Resume GuC before using GEM (Chris)
- Stolen Memory handling improvements (Ville)
- Initialize entry in PPAT for older compilers (Chris)
- Other fixes and robustness improvements on execbuf (Chris)
- Improve logs of GEM_BUG_ON (Mika Kuoppala)
- Rework with massive rename of GuC functions and files (Sagar)
- Don't sanitize frame start delay if pipe is off (Ville)
- Cannonlake clock fixes (Rodrigo)
- Cannonlake HDMI 2.0 support (Rodrigo)
- Add a GuC doorbells selftest (Michel)
- Add might_sleep() check to our wait_for() (Chris)
Many GVT changes for 4.16:
- CSB HWSP update support (Weinan)
- GVT debug helpers, dyndbg and debugfs (Chuanxiao, Shuo)
- full virtualized opregion (Xiaolin)
- VM health check for sane fallback (Fred)
- workload submission code refactor for future enabling (Zhi)
- Updated repo URL in MAINTAINERS (Zhenyu)
- other many misc fixes
* tag 'drm-intel-next-2017-11-17-1' of git://anongit.freedesktop.org/drm/drm-intel: (260 commits)
drm/i915: Update DRIVER_DATE to 20171117
drm/i915: Add a policy note for removing workarounds
drm/i915/selftests: Report ENOMEM clearly for an allocation failure
Revert "drm/i915: Display WA #1133 WaFbcSkipSegments:cnl, glk"
drm/i915: Calculate g4x intermediate watermarks correctly
drm/i915: Calculate vlv/chv intermediate watermarks correctly, v3.
drm/i915: Pass crtc_state to ips toggle functions, v2
drm/i915: Pass idle crtc_state to intel_dp_sink_crc
drm/i915: Enable FIFO underrun reporting after initial fastset, v4.
drm/i915: Mark the userptr invalidate workqueue as WQ_MEM_RECLAIM
drm/i915: Add might_sleep() check to wait_for()
drm/i915/selftests: Add a GuC doorbells selftest
drm/i915/cnl: Extend HDMI 2.0 support to CNL.
drm/i915/cnl: Simplify dco_fraction calculation.
drm/i915/cnl: Don't blindly replace qdiv.
drm/i915/cnl: Fix wrpll math for higher freqs.
drm/i915/cnl: Fix, simplify and unify wrpll variable sizes.
drm/i915/cnl: Remove useless conversion.
drm/i915/cnl: Remove spurious central_freq.
drm/i915/selftests: exercise_ggtt may have nothing to do
...
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, |