diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 47 |
1 files changed, 33 insertions, 14 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index b3d8f766fa7f..16371a444426 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -380,6 +380,27 @@ gen7_render_ring_flush(struct intel_engine_cs *ring, | |||
380 | } | 380 | } |
381 | 381 | ||
382 | static int | 382 | static int |
383 | gen8_emit_pipe_control(struct intel_engine_cs *ring, | ||
384 | u32 flags, u32 scratch_addr) | ||
385 | { | ||
386 | int ret; | ||
387 | |||
388 | ret = intel_ring_begin(ring, 6); | ||
389 | if (ret) | ||
390 | return ret; | ||
391 | |||
392 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(6)); | ||
393 | intel_ring_emit(ring, flags); | ||
394 | intel_ring_emit(ring, scratch_addr); | ||
395 | intel_ring_emit(ring, 0); | ||
396 | intel_ring_emit(ring, 0); | ||
397 | intel_ring_emit(ring, 0); | ||
398 | intel_ring_advance(ring); | ||
399 | |||
400 | return 0; | ||
401 | } | ||
402 | |||
403 | static int | ||
383 | gen8_render_ring_flush(struct intel_engine_cs *ring, | 404 | gen8_render_ring_flush(struct intel_engine_cs *ring, |
384 | u32 invalidate_domains, u32 flush_domains) | 405 | u32 invalidate_domains, u32 flush_domains) |
385 | { | 406 | { |
@@ -402,22 +423,17 @@ gen8_render_ring_flush(struct intel_engine_cs *ring, | |||
402 | flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE; | 423 | flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE; |
403 | flags |= PIPE_CONTROL_QW_WRITE; | 424 | flags |= PIPE_CONTROL_QW_WRITE; |
404 | flags |= PIPE_CONTROL_GLOBAL_GTT_IVB; | 425 | flags |= PIPE_CONTROL_GLOBAL_GTT_IVB; |
405 | } | ||
406 | |||
407 | ret = intel_ring_begin(ring, 6); | ||
408 | if (ret) | ||
409 | return ret; | ||
410 | |||
411 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(6)); | ||
412 | intel_ring_emit(ring, flags); | ||
413 | intel_ring_emit(ring, scratch_addr); | ||
414 | intel_ring_emit(ring, 0); | ||
415 | intel_ring_emit(ring, 0); | ||
416 | intel_ring_emit(ring, 0); | ||
417 | intel_ring_advance(ring); | ||
418 | 426 | ||
419 | return 0; | 427 | /* WaCsStallBeforeStateCacheInvalidate:bdw,chv */ |
428 | ret = gen8_emit_pipe_control(ring, | ||
429 | PIPE_CONTROL_CS_STALL | | ||
430 | PIPE_CONTROL_STALL_AT_SCOREBOARD, | ||
431 | 0); | ||
432 | if (ret) | ||
433 | return ret; | ||
434 | } | ||
420 | 435 | ||
436 | return gen8_emit_pipe_control(ring, flags, scratch_addr); | ||
421 | } | 437 | } |
422 | 438 | ||
423 | static void ring_write_tail(struct intel_engine_cs *ring, | 439 | static void ring_write_tail(struct intel_engine_cs *ring, |
@@ -516,6 +532,9 @@ static int init_ring_common(struct intel_engine_cs *ring) | |||
516 | else | 532 | else |
517 | ring_setup_phys_status_page(ring); | 533 | ring_setup_phys_status_page(ring); |
518 | 534 | ||
535 | /* Enforce ordering by reading HEAD register back */ | ||
536 | I915_READ_HEAD(ring); | ||
537 | |||
519 | /* Initialize the ring. This must happen _after_ we've cleared the ring | 538 | /* Initialize the ring. This must happen _after_ we've cleared the ring |
520 | * registers with the above sequence (the readback of the HEAD registers | 539 | * registers with the above sequence (the readback of the HEAD registers |
521 | * also enforces ordering), otherwise the hw might lose the new ring | 540 | * also enforces ordering), otherwise the hw might lose the new ring |