diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index d0ef50bf930a..87eebc13c0d8 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -91,6 +91,7 @@ static int | |||
91 | gen4_render_ring_flush(struct i915_request *rq, u32 mode) | 91 | gen4_render_ring_flush(struct i915_request *rq, u32 mode) |
92 | { | 92 | { |
93 | u32 cmd, *cs; | 93 | u32 cmd, *cs; |
94 | int i; | ||
94 | 95 | ||
95 | /* | 96 | /* |
96 | * read/write caches: | 97 | * read/write caches: |
@@ -127,12 +128,45 @@ gen4_render_ring_flush(struct i915_request *rq, u32 mode) | |||
127 | cmd |= MI_INVALIDATE_ISP; | 128 | cmd |= MI_INVALIDATE_ISP; |
128 | } | 129 | } |
129 | 130 | ||
130 | cs = intel_ring_begin(rq, 2); | 131 | i = 2; |
132 | if (mode & EMIT_INVALIDATE) | ||
133 | i += 20; | ||
134 | |||
135 | cs = intel_ring_begin(rq, i); | ||
131 | if (IS_ERR(cs)) | 136 | if (IS_ERR(cs)) |
132 | return PTR_ERR(cs); | 137 | return PTR_ERR(cs); |
133 | 138 | ||
134 | *cs++ = cmd; | 139 | *cs++ = cmd; |
135 | *cs++ = MI_NOOP; | 140 | |
141 | /* | ||
142 | * A random delay to let the CS invalidate take effect? Without this | ||
143 | * delay, the GPU relocation path fails as the CS does not see | ||
144 | * the updated contents. Just as important, if we apply the flushes | ||
145 | * to the EMIT_FLUSH branch (i.e. immediately after the relocation | ||
146 | * write and before the invalidate on the next batch), the relocations | ||
147 | * still fail. This implies that is a delay following invalidation | ||
148 | * that is required to reset the caches as opposed to a delay to | ||
149 | * ensure the memory is written. | ||
150 | */ | ||
151 | if (mode & EMIT_INVALIDATE) { | ||
152 | *cs++ = GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE; | ||
153 | *cs++ = i915_ggtt_offset(rq->engine->scratch) | | ||
154 | PIPE_CONTROL_GLOBAL_GTT; | ||
155 | *cs++ = 0; | ||
156 | *cs++ = 0; | ||
157 | |||
158 | for (i = 0; i < 12; i++) | ||
159 | *cs++ = MI_FLUSH; | ||
160 | |||
161 | *cs++ = GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE; | ||
162 | *cs++ = i915_ggtt_offset(rq->engine->scratch) | | ||
163 | PIPE_CONTROL_GLOBAL_GTT; | ||
164 | *cs++ = 0; | ||
165 | *cs++ = 0; | ||
166 | } | ||
167 | |||
168 | *cs++ = cmd; | ||
169 | |||
136 | intel_ring_advance(rq, cs); | 170 | intel_ring_advance(rq, cs); |
137 | 171 | ||
138 | return 0; | 172 | return 0; |
@@ -574,7 +608,9 @@ static void skip_request(struct i915_request *rq) | |||
574 | 608 | ||
575 | static void reset_ring(struct intel_engine_cs *engine, struct i915_request *rq) | 609 | static void reset_ring(struct intel_engine_cs *engine, struct i915_request *rq) |
576 | { | 610 | { |
577 | GEM_TRACE("%s seqno=%x\n", engine->name, rq ? rq->global_seqno : 0); | 611 | GEM_TRACE("%s request global=%d, current=%d\n", |
612 | engine->name, rq ? rq->global_seqno : 0, | ||
613 | intel_engine_get_seqno(engine)); | ||
578 | 614 | ||
579 | /* | 615 | /* |
580 | * Try to restore the logical GPU state to match the continuation | 616 | * Try to restore the logical GPU state to match the continuation |
@@ -1021,8 +1057,7 @@ i915_emit_bb_start(struct i915_request *rq, | |||
1021 | int intel_ring_pin(struct intel_ring *ring) | 1057 | int intel_ring_pin(struct intel_ring *ring) |
1022 | { | 1058 | { |
1023 | struct i915_vma *vma = ring->vma; | 1059 | struct i915_vma *vma = ring->vma; |
1024 | enum i915_map_type map = | 1060 | enum i915_map_type map = i915_coherent_map_type(vma->vm->i915); |
1025 | HAS_LLC(vma->vm->i915) ? I915_MAP_WB : I915_MAP_WC; | ||
1026 | unsigned int flags; | 1061 | unsigned int flags; |
1027 | void *addr; | 1062 | void *addr; |
1028 | int ret; | 1063 | int ret; |