diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 194 |
1 files changed, 54 insertions, 140 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index cdf084ef5aae..8da1bde442dd 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -402,17 +402,18 @@ static void intel_ring_setup_status_page(struct intel_engine_cs *engine) | |||
402 | */ | 402 | */ |
403 | if (IS_GEN7(dev_priv)) { | 403 | if (IS_GEN7(dev_priv)) { |
404 | switch (engine->id) { | 404 | switch (engine->id) { |
405 | /* | ||
406 | * No more rings exist on Gen7. Default case is only to shut up | ||
407 | * gcc switch check warning. | ||
408 | */ | ||
409 | default: | ||
410 | GEM_BUG_ON(engine->id); | ||
405 | case RCS: | 411 | case RCS: |
406 | mmio = RENDER_HWS_PGA_GEN7; | 412 | mmio = RENDER_HWS_PGA_GEN7; |
407 | break; | 413 | break; |
408 | case BCS: | 414 | case BCS: |
409 | mmio = BLT_HWS_PGA_GEN7; | 415 | mmio = BLT_HWS_PGA_GEN7; |
410 | break; | 416 | break; |
411 | /* | ||
412 | * VCS2 actually doesn't exist on Gen7. Only shut up | ||
413 | * gcc switch check warning | ||
414 | */ | ||
415 | case VCS2: | ||
416 | case VCS: | 417 | case VCS: |
417 | mmio = BSD_HWS_PGA_GEN7; | 418 | mmio = BSD_HWS_PGA_GEN7; |
418 | break; | 419 | break; |
@@ -427,6 +428,9 @@ static void intel_ring_setup_status_page(struct intel_engine_cs *engine) | |||
427 | mmio = RING_HWS_PGA(engine->mmio_base); | 428 | mmio = RING_HWS_PGA(engine->mmio_base); |
428 | } | 429 | } |
429 | 430 | ||
431 | if (INTEL_GEN(dev_priv) >= 6) | ||
432 | I915_WRITE(RING_HWSTAM(engine->mmio_base), 0xffffffff); | ||
433 | |||
430 | I915_WRITE(mmio, engine->status_page.ggtt_offset); | 434 | I915_WRITE(mmio, engine->status_page.ggtt_offset); |
431 | POSTING_READ(mmio); | 435 | POSTING_READ(mmio); |
432 | 436 | ||
@@ -480,11 +484,6 @@ static bool stop_ring(struct intel_engine_cs *engine) | |||
480 | I915_WRITE_HEAD(engine, 0); | 484 | I915_WRITE_HEAD(engine, 0); |
481 | I915_WRITE_TAIL(engine, 0); | 485 | I915_WRITE_TAIL(engine, 0); |
482 | 486 | ||
483 | if (INTEL_GEN(dev_priv) > 2) { | ||
484 | (void)I915_READ_CTL(engine); | ||
485 | I915_WRITE_MODE(engine, _MASKED_BIT_DISABLE(STOP_RING)); | ||
486 | } | ||
487 | |||
488 | return (I915_READ_HEAD(engine) & HEAD_ADDR) == 0; | 487 | return (I915_READ_HEAD(engine) & HEAD_ADDR) == 0; |
489 | } | 488 | } |
490 | 489 | ||
@@ -566,6 +565,9 @@ static int init_ring_common(struct intel_engine_cs *engine) | |||
566 | 565 | ||
567 | intel_engine_init_hangcheck(engine); | 566 | intel_engine_init_hangcheck(engine); |
568 | 567 | ||
568 | if (INTEL_GEN(dev_priv) > 2) | ||
569 | I915_WRITE_MODE(engine, _MASKED_BIT_DISABLE(STOP_RING)); | ||
570 | |||
569 | out: | 571 | out: |
570 | intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); | 572 | intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); |
571 | 573 | ||
@@ -575,7 +577,16 @@ out: | |||
575 | static void reset_ring_common(struct intel_engine_cs *engine, | 577 | static void reset_ring_common(struct intel_engine_cs *engine, |
576 | struct drm_i915_gem_request *request) | 578 | struct drm_i915_gem_request *request) |
577 | { | 579 | { |
578 | /* Try to restore the logical GPU state to match the continuation | 580 | /* |
581 | * RC6 must be prevented until the reset is complete and the engine | ||
582 | * reinitialised. If it occurs in the middle of this sequence, the | ||
583 | * state written to/loaded from the power context is ill-defined (e.g. | ||
584 | * the PP_BASE_DIR may be lost). | ||
585 | */ | ||
586 | assert_forcewakes_active(engine->i915, FORCEWAKE_ALL); | ||
587 | |||
588 | /* | ||
589 | * Try to restore the logical GPU state to match the continuation | ||
579 | * of the request queue. If we skip the context/PD restore, then | 590 | * of the request queue. If we skip the context/PD restore, then |
580 | * the next request may try to execute assuming that its context | 591 | * the next request may try to execute assuming that its context |
581 | * is valid and loaded on the GPU and so may try to access invalid | 592 | * is valid and loaded on the GPU and so may try to access invalid |
@@ -778,6 +789,24 @@ static u32 *gen6_signal(struct drm_i915_gem_request *req, u32 *cs) | |||
778 | return cs; | 789 | return cs; |
779 | } | 790 | } |
780 | 791 | ||
792 | static void cancel_requests(struct intel_engine_cs *engine) | ||
793 | { | ||
794 | struct drm_i915_gem_request *request; | ||
795 | unsigned long flags; | ||
796 | |||
797 | spin_lock_irqsave(&engine->timeline->lock, flags); | ||
798 | |||
799 | /* Mark all submitted requests as skipped. */ | ||
800 | list_for_each_entry(request, &engine->timeline->requests, link) { | ||
801 | GEM_BUG_ON(!request->global_seqno); | ||
802 | if (!i915_gem_request_completed(request)) | ||
803 | dma_fence_set_error(&request->fence, -EIO); | ||
804 | } | ||
805 | /* Remaining _unready_ requests will be nop'ed when submitted */ | ||
806 | |||
807 | spin_unlock_irqrestore(&engine->timeline->lock, flags); | ||
808 | } | ||
809 | |||
781 | static void i9xx_submit_request(struct drm_i915_gem_request *request) | 810 | static void i9xx_submit_request(struct drm_i915_gem_request *request) |
782 | { | 811 | { |
783 | struct drm_i915_private *dev_priv = request->i915; | 812 | struct drm_i915_private *dev_priv = request->i915; |
@@ -1174,113 +1203,7 @@ i915_emit_bb_start(struct drm_i915_gem_request *req, | |||
1174 | return 0; | 1203 | return 0; |
1175 | } | 1204 | } |
1176 | 1205 | ||
1177 | static void cleanup_phys_status_page(struct intel_engine_cs *engine) | ||
1178 | { | ||
1179 | struct drm_i915_private *dev_priv = engine->i915; | ||
1180 | |||
1181 | if (!dev_priv->status_page_dmah) | ||
1182 | return; | ||
1183 | |||
1184 | drm_pci_free(&dev_priv->drm, dev_priv->status_page_dmah); | ||
1185 | engine->status_page.page_addr = NULL; | ||
1186 | } | ||
1187 | |||
1188 | static void cleanup_status_page(struct intel_engine_cs *engine) | ||
1189 | { | ||
1190 | struct i915_vma *vma; | ||
1191 | struct drm_i915_gem_object *obj; | ||
1192 | |||
1193 | vma = fetch_and_zero(&engine->status_page.vma); | ||
1194 | if (!vma) | ||
1195 | return; | ||
1196 | |||
1197 | obj = vma->obj; | ||
1198 | |||
1199 | i915_vma_unpin(vma); | ||
1200 | i915_vma_close(vma); | ||
1201 | |||
1202 | i915_gem_object_unpin_map(obj); | ||
1203 | __i915_gem_object_release_unless_active(obj); | ||
1204 | } | ||
1205 | |||
1206 | static int init_status_page(struct intel_engine_cs *engine) | ||
1207 | { | ||
1208 | struct drm_i915_gem_object *obj; | ||
1209 | struct i915_vma *vma; | ||
1210 | unsigned int flags; | ||
1211 | void *vaddr; | ||
1212 | int ret; | ||
1213 | |||
1214 | obj = i915_gem_object_create_internal(engine->i915, PAGE_SIZE); | ||
1215 | if (IS_ERR(obj)) { | ||
1216 | DRM_ERROR("Failed to allocate status page\n"); | ||
1217 | return PTR_ERR(obj); | ||
1218 | } | ||
1219 | |||
1220 | ret = i915_gem_object_set_cache_level(obj, I915_CACHE_LLC); | ||
1221 | if (ret) | ||
1222 | goto err; | ||
1223 | |||
1224 | vma = i915_vma_instance(obj, &engine->i915->ggtt.base, NULL); | ||
1225 | if (IS_ERR(vma)) { | ||
1226 | ret = PTR_ERR(vma); | ||
1227 | goto err; | ||
1228 | } | ||
1229 | |||
1230 | flags = PIN_GLOBAL; | ||
1231 | if (!HAS_LLC(engine->i915)) | ||
1232 | /* On g33, we cannot place HWS above 256MiB, so | ||
1233 | * restrict its pinning to the low mappable arena. | ||
1234 | * Though this restriction is not documented for | ||
1235 | * gen4, gen5, or byt, they also behave similarly | ||
1236 | * and hang if the HWS is placed at the top of the | ||
1237 | * GTT. To generalise, it appears that all !llc | ||
1238 | * platforms have issues with us placing the HWS | ||
1239 | * above the mappable region (even though we never | ||
1240 | * actualy map it). | ||
1241 | */ | ||
1242 | flags |= PIN_MAPPABLE; | ||
1243 | ret = i915_vma_pin(vma, 0, 4096, flags); | ||
1244 | if (ret) | ||
1245 | goto err; | ||
1246 | |||
1247 | vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB); | ||
1248 | if (IS_ERR(vaddr)) { | ||
1249 | ret = PTR_ERR(vaddr); | ||
1250 | goto err_unpin; | ||
1251 | } | ||
1252 | |||
1253 | engine->status_page.vma = vma; | ||
1254 | engine->status_page.ggtt_offset = i915_ggtt_offset(vma); | ||
1255 | engine->status_page.page_addr = memset(vaddr, 0, PAGE_SIZE); | ||
1256 | |||
1257 | DRM_DEBUG_DRIVER("%s hws offset: 0x%08x\n", | ||
1258 | engine->name, i915_ggtt_offset(vma)); | ||
1259 | return 0; | ||
1260 | |||
1261 | err_unpin: | ||
1262 | i915_vma_unpin(vma); | ||
1263 | err: | ||
1264 | i915_gem_object_put(obj); | ||
1265 | return ret; | ||
1266 | } | ||
1267 | |||
1268 | static int init_phys_status_page(struct intel_engine_cs *engine) | ||
1269 | { | ||
1270 | struct drm_i915_private *dev_priv = engine->i915; | ||
1271 | |||
1272 | GEM_BUG_ON(engine->id != RCS); | ||
1273 | |||
1274 | dev_priv->status_page_dmah = | ||
1275 | drm_pci_alloc(&dev_priv->drm, PAGE_SIZE, PAGE_SIZE); | ||
1276 | if (!dev_priv->status_page_dmah) | ||
1277 | return -ENOMEM; | ||
1278 | |||
1279 | engine->status_page.page_addr = dev_priv->status_page_dmah->vaddr; | ||
1280 | memset(engine->status_page.page_addr, 0, PAGE_SIZE); | ||
1281 | 1206 | ||
1282 | return 0; | ||
1283 | } | ||
1284 | 1207 | ||
1285 | int intel_ring_pin(struct intel_ring *ring, | 1208 | int intel_ring_pin(struct intel_ring *ring, |
1286 | struct drm_i915_private *i915, | 1209 | struct drm_i915_private *i915, |
@@ -1321,6 +1244,8 @@ int intel_ring_pin(struct intel_ring *ring, | |||
1321 | if (IS_ERR(addr)) | 1244 | if (IS_ERR(addr)) |
1322 | goto err; | 1245 | goto err; |
1323 | 1246 | ||
1247 | vma->obj->pin_global++; | ||
1248 | |||
1324 | ring->vaddr = addr; | 1249 | ring->vaddr = addr; |
1325 | return 0; | 1250 | return 0; |
1326 | 1251 | ||
@@ -1352,6 +1277,7 @@ void intel_ring_unpin(struct intel_ring *ring) | |||
1352 | i915_gem_object_unpin_map(ring->vma->obj); | 1277 | i915_gem_object_unpin_map(ring->vma->obj); |
1353 | ring->vaddr = NULL; | 1278 | ring->vaddr = NULL; |
1354 | 1279 | ||
1280 | ring->vma->obj->pin_global--; | ||
1355 | i915_vma_unpin(ring->vma); | 1281 | i915_vma_unpin(ring->vma); |
1356 | } | 1282 | } |
1357 | 1283 | ||
@@ -1516,6 +1442,7 @@ intel_ring_context_pin(struct intel_engine_cs *engine, | |||
1516 | goto err; | 1442 | goto err; |
1517 | 1443 | ||
1518 | ce->state->obj->mm.dirty = true; | 1444 | ce->state->obj->mm.dirty = true; |
1445 | ce->state->obj->pin_global++; | ||
1519 | } | 1446 | } |
1520 | 1447 | ||
1521 | /* The kernel context is only used as a placeholder for flushing the | 1448 | /* The kernel context is only used as a placeholder for flushing the |
@@ -1550,8 +1477,10 @@ static void intel_ring_context_unpin(struct intel_engine_cs *engine, | |||
1550 | if (--ce->pin_count) | 1477 | if (--ce->pin_count) |
1551 | return; | 1478 | return; |
1552 | 1479 | ||
1553 | if (ce->state) | 1480 | if (ce->state) { |
1481 | ce->state->obj->pin_global--; | ||
1554 | i915_vma_unpin(ce->state); | 1482 | i915_vma_unpin(ce->state); |
1483 | } | ||
1555 | 1484 | ||
1556 | i915_gem_context_put(ctx); | 1485 | i915_gem_context_put(ctx); |
1557 | } | 1486 | } |
@@ -1567,17 +1496,10 @@ static int intel_init_ring_buffer(struct intel_engine_cs *engine) | |||
1567 | if (err) | 1496 | if (err) |
1568 | goto err; | 1497 | goto err; |
1569 | 1498 | ||
1570 | if (HWS_NEEDS_PHYSICAL(engine->i915)) | ||
1571 | err = init_phys_status_page(engine); | ||
1572 | else | ||
1573 | err = init_status_page(engine); | ||
1574 | if (err) | ||
1575 | goto err; | ||
1576 | |||
1577 | ring = intel_engine_create_ring(engine, 32 * PAGE_SIZE); | 1499 | ring = intel_engine_create_ring(engine, 32 * PAGE_SIZE); |
1578 | if (IS_ERR(ring)) { | 1500 | if (IS_ERR(ring)) { |
1579 | err = PTR_ERR(ring); | 1501 | err = PTR_ERR(ring); |
1580 | goto err_hws; | 1502 | goto err; |
1581 | } | 1503 | } |
1582 | 1504 | ||
1583 | /* Ring wraparound at offset 0 sometimes hangs. No idea why. */ | 1505 | /* Ring wraparound at offset 0 sometimes hangs. No idea why. */ |
@@ -1592,11 +1514,6 @@ static int intel_init_ring_buffer(struct intel_engine_cs *engine) | |||
1592 | 1514 | ||
1593 | err_ring: | 1515 | err_ring: |
1594 | intel_ring_free(ring); | 1516 | intel_ring_free(ring); |
1595 | err_hws: | ||
1596 | if (HWS_NEEDS_PHYSICAL(engine->i915)) | ||
1597 | cleanup_phys_status_page(engine); | ||
1598 | else | ||
1599 | cleanup_status_page(engine); | ||
1600 | err: | 1517 | err: |
1601 | intel_engine_cleanup_common(engine); | 1518 | intel_engine_cleanup_common(engine); |
1602 | return err; | 1519 | return err; |
@@ -1615,11 +1532,6 @@ void intel_engine_cleanup(struct intel_engine_cs *engine) | |||
1615 | if (engine->cleanup) | 1532 | if (engine->cleanup) |
1616 | engine->cleanup(engine); | 1533 | engine->cleanup(engine); |
1617 | 1534 | ||
1618 | if (HWS_NEEDS_PHYSICAL(dev_priv)) | ||
1619 | cleanup_phys_status_page(engine); | ||
1620 | else | ||
1621 | cleanup_status_page(engine); | ||
1622 | |||
1623 | intel_engine_cleanup_common(engine); | 1535 | intel_engine_cleanup_common(engine); |
1624 | 1536 | ||
1625 | dev_priv->engine[engine->id] = NULL; | 1537 | dev_priv->engine[engine->id] = NULL; |
@@ -1983,7 +1895,7 @@ static void intel_ring_init_semaphores(struct drm_i915_private *dev_priv, | |||
1983 | struct drm_i915_gem_object *obj; | 1895 | struct drm_i915_gem_object *obj; |
1984 | int ret, i; | 1896 | int ret, i; |
1985 | 1897 | ||
1986 | if (!i915.semaphores) | 1898 | if (!i915_modparams.semaphores) |
1987 | return; | 1899 | return; |
1988 | 1900 | ||
1989 | if (INTEL_GEN(dev_priv) >= 8 && !dev_priv->semaphore) { | 1901 | if (INTEL_GEN(dev_priv) >= 8 && !dev_priv->semaphore) { |
@@ -2083,7 +1995,7 @@ err_obj: | |||
2083 | i915_gem_object_put(obj); | 1995 | i915_gem_object_put(obj); |
2084 | err: | 1996 | err: |
2085 | DRM_DEBUG_DRIVER("Failed to allocate space for semaphores, disabling\n"); | 1997 | DRM_DEBUG_DRIVER("Failed to allocate space for semaphores, disabling\n"); |
2086 | i915.semaphores = 0; | 1998 | i915_modparams.semaphores = 0; |
2087 | } | 1999 | } |
2088 | 2000 | ||
2089 | static void intel_ring_init_irq(struct drm_i915_private *dev_priv, | 2001 | static void intel_ring_init_irq(struct drm_i915_private *dev_priv, |
@@ -2115,11 +2027,13 @@ static void intel_ring_init_irq(struct drm_i915_private *dev_priv, | |||
2115 | static void i9xx_set_default_submission(struct intel_engine_cs *engine) | 2027 | static void i9xx_set_default_submission(struct intel_engine_cs *engine) |
2116 | { | 2028 | { |
2117 | engine->submit_request = i9xx_submit_request; | 2029 | engine->submit_request = i9xx_submit_request; |
2030 | engine->cancel_requests = cancel_requests; | ||
2118 | } | 2031 | } |
2119 | 2032 | ||
2120 | static void gen6_bsd_set_default_submission(struct intel_engine_cs *engine) | 2033 | static void gen6_bsd_set_default_submission(struct intel_engine_cs *engine) |
2121 | { | 2034 | { |
2122 | engine->submit_request = gen6_bsd_submit_request; | 2035 | engine->submit_request = gen6_bsd_submit_request; |
2036 | engine->cancel_requests = cancel_requests; | ||
2123 | } | 2037 | } |
2124 | 2038 | ||
2125 | static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv, | 2039 | static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv, |
@@ -2138,7 +2052,7 @@ static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv, | |||
2138 | 2052 | ||
2139 | engine->emit_breadcrumb = i9xx_emit_breadcrumb; | 2053 | engine->emit_breadcrumb = i9xx_emit_breadcrumb; |
2140 | engine->emit_breadcrumb_sz = i9xx_emit_breadcrumb_sz; | 2054 | engine->emit_breadcrumb_sz = i9xx_emit_breadcrumb_sz; |
2141 | if (i915.semaphores) { | 2055 | if (i915_modparams.semaphores) { |
2142 | int num_rings; | 2056 | int num_rings; |
2143 | 2057 | ||
2144 | engine->emit_breadcrumb = gen6_sema_emit_breadcrumb; | 2058 | engine->emit_breadcrumb = gen6_sema_emit_breadcrumb; |
@@ -2182,7 +2096,7 @@ int intel_init_render_ring_buffer(struct intel_engine_cs *engine) | |||
2182 | engine->emit_breadcrumb = gen8_render_emit_breadcrumb; | 2096 | engine->emit_breadcrumb = gen8_render_emit_breadcrumb; |
2183 | engine->emit_breadcrumb_sz = gen8_render_emit_breadcrumb_sz; | 2097 | engine->emit_breadcrumb_sz = gen8_render_emit_breadcrumb_sz; |
2184 | engine->emit_flush = gen8_render_ring_flush; | 2098 | engine->emit_flush = gen8_render_ring_flush; |
2185 | if (i915.semaphores) { | 2099 | if (i915_modparams.semaphores) { |
2186 | int num_rings; | 2100 | int num_rings; |
2187 | 2101 | ||
2188 | engine->semaphore.signal = gen8_rcs_signal; | 2102 | engine->semaphore.signal = gen8_rcs_signal; |