diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 369 |
1 files changed, 273 insertions, 96 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index c30626ea9f93..ca70e2f10445 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -34,6 +34,16 @@ | |||
34 | #include "i915_trace.h" | 34 | #include "i915_trace.h" |
35 | #include "intel_drv.h" | 35 | #include "intel_drv.h" |
36 | 36 | ||
37 | /* | ||
38 | * 965+ support PIPE_CONTROL commands, which provide finer grained control | ||
39 | * over cache flushing. | ||
40 | */ | ||
41 | struct pipe_control { | ||
42 | struct drm_i915_gem_object *obj; | ||
43 | volatile u32 *cpu_page; | ||
44 | u32 gtt_offset; | ||
45 | }; | ||
46 | |||
37 | static inline int ring_space(struct intel_ring_buffer *ring) | 47 | static inline int ring_space(struct intel_ring_buffer *ring) |
38 | { | 48 | { |
39 | int space = (ring->head & HEAD_ADDR) - (ring->tail + 8); | 49 | int space = (ring->head & HEAD_ADDR) - (ring->tail + 8); |
@@ -123,6 +133,118 @@ render_ring_flush(struct intel_ring_buffer *ring, | |||
123 | return 0; | 133 | return 0; |
124 | } | 134 | } |
125 | 135 | ||
136 | /** | ||
137 | * Emits a PIPE_CONTROL with a non-zero post-sync operation, for | ||
138 | * implementing two workarounds on gen6. From section 1.4.7.1 | ||
139 | * "PIPE_CONTROL" of the Sandy Bridge PRM volume 2 part 1: | ||
140 | * | ||
141 | * [DevSNB-C+{W/A}] Before any depth stall flush (including those | ||
142 | * produced by non-pipelined state commands), software needs to first | ||
143 | * send a PIPE_CONTROL with no bits set except Post-Sync Operation != | ||
144 | * 0. | ||
145 | * | ||
146 | * [Dev-SNB{W/A}]: Before a PIPE_CONTROL with Write Cache Flush Enable | ||
147 | * =1, a PIPE_CONTROL with any non-zero post-sync-op is required. | ||
148 | * | ||
149 | * And the workaround for these two requires this workaround first: | ||
150 | * | ||
151 | * [Dev-SNB{W/A}]: Pipe-control with CS-stall bit set must be sent | ||
152 | * BEFORE the pipe-control with a post-sync op and no write-cache | ||
153 | * flushes. | ||
154 | * | ||
155 | * And this last workaround is tricky because of the requirements on | ||
156 | * that bit. From section 1.4.7.2.3 "Stall" of the Sandy Bridge PRM | ||
157 | * volume 2 part 1: | ||
158 | * | ||
159 | * "1 of the following must also be set: | ||
160 | * - Render Target Cache Flush Enable ([12] of DW1) | ||
161 | * - Depth Cache Flush Enable ([0] of DW1) | ||
162 | * - Stall at Pixel Scoreboard ([1] of DW1) | ||
163 | * - Depth Stall ([13] of DW1) | ||
164 | * - Post-Sync Operation ([13] of DW1) | ||
165 | * - Notify Enable ([8] of DW1)" | ||
166 | * | ||
167 | * The cache flushes require the workaround flush that triggered this | ||
168 | * one, so we can't use it. Depth stall would trigger the same. | ||
169 | * Post-sync nonzero is what triggered this second workaround, so we | ||
170 | * can't use that one either. Notify enable is IRQs, which aren't | ||
171 | * really our business. That leaves only stall at scoreboard. | ||
172 | */ | ||
173 | static int | ||
174 | intel_emit_post_sync_nonzero_flush(struct intel_ring_buffer *ring) | ||
175 | { | ||
176 | struct pipe_control *pc = ring->private; | ||
177 | u32 scratch_addr = pc->gtt_offset + 128; | ||
178 | int ret; | ||
179 | |||
180 | |||
181 | ret = intel_ring_begin(ring, 6); | ||
182 | if (ret) | ||
183 | return ret; | ||
184 | |||
185 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(5)); | ||
186 | intel_ring_emit(ring, PIPE_CONTROL_CS_STALL | | ||
187 | PIPE_CONTROL_STALL_AT_SCOREBOARD); | ||
188 | intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); /* address */ | ||
189 | intel_ring_emit(ring, 0); /* low dword */ | ||
190 | intel_ring_emit(ring, 0); /* high dword */ | ||
191 | intel_ring_emit(ring, MI_NOOP); | ||
192 | intel_ring_advance(ring); | ||
193 | |||
194 | ret = intel_ring_begin(ring, 6); | ||
195 | if (ret) | ||
196 | return ret; | ||
197 | |||
198 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(5)); | ||
199 | intel_ring_emit(ring, PIPE_CONTROL_QW_WRITE); | ||
200 | intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); /* address */ | ||
201 | intel_ring_emit(ring, 0); | ||
202 | intel_ring_emit(ring, 0); | ||
203 | intel_ring_emit(ring, MI_NOOP); | ||
204 | intel_ring_advance(ring); | ||
205 | |||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | static int | ||
210 | gen6_render_ring_flush(struct intel_ring_buffer *ring, | ||
211 | u32 invalidate_domains, u32 flush_domains) | ||
212 | { | ||
213 | u32 flags = 0; | ||
214 | struct pipe_control *pc = ring->private; | ||
215 | u32 scratch_addr = pc->gtt_offset + 128; | ||
216 | int ret; | ||
217 | |||
218 | /* Force SNB workarounds for PIPE_CONTROL flushes */ | ||
219 | intel_emit_post_sync_nonzero_flush(ring); | ||
220 | |||
221 | /* Just flush everything. Experiments have shown that reducing the | ||
222 | * number of bits based on the write domains has little performance | ||
223 | * impact. | ||
224 | */ | ||
225 | flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH; | ||
226 | flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE; | ||
227 | flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE; | ||
228 | flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH; | ||
229 | flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE; | ||
230 | flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE; | ||
231 | flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE; | ||
232 | |||
233 | ret = intel_ring_begin(ring, 6); | ||
234 | if (ret) | ||
235 | return ret; | ||
236 | |||
237 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(5)); | ||
238 | intel_ring_emit(ring, flags); | ||
239 | intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); | ||
240 | intel_ring_emit(ring, 0); /* lower dword */ | ||
241 | intel_ring_emit(ring, 0); /* uppwer dword */ | ||
242 | intel_ring_emit(ring, MI_NOOP); | ||
243 | intel_ring_advance(ring); | ||
244 | |||
245 | return 0; | ||
246 | } | ||
247 | |||
126 | static void ring_write_tail(struct intel_ring_buffer *ring, | 248 | static void ring_write_tail(struct intel_ring_buffer *ring, |
127 | u32 value) | 249 | u32 value) |
128 | { | 250 | { |
@@ -206,16 +328,6 @@ static int init_ring_common(struct intel_ring_buffer *ring) | |||
206 | return 0; | 328 | return 0; |
207 | } | 329 | } |
208 | 330 | ||
209 | /* | ||
210 | * 965+ support PIPE_CONTROL commands, which provide finer grained control | ||
211 | * over cache flushing. | ||
212 | */ | ||
213 | struct pipe_control { | ||
214 | struct drm_i915_gem_object *obj; | ||
215 | volatile u32 *cpu_page; | ||
216 | u32 gtt_offset; | ||
217 | }; | ||
218 | |||
219 | static int | 331 | static int |
220 | init_pipe_control(struct intel_ring_buffer *ring) | 332 | init_pipe_control(struct intel_ring_buffer *ring) |
221 | { | 333 | { |
@@ -296,8 +408,7 @@ static int init_render_ring(struct intel_ring_buffer *ring) | |||
296 | GFX_MODE_ENABLE(GFX_REPLAY_MODE)); | 408 | GFX_MODE_ENABLE(GFX_REPLAY_MODE)); |
297 | } | 409 | } |
298 | 410 | ||
299 | if (INTEL_INFO(dev)->gen >= 6) { | 411 | if (INTEL_INFO(dev)->gen >= 5) { |
300 | } else if (IS_GEN5(dev)) { | ||
301 | ret = init_pipe_control(ring); | 412 | ret = init_pipe_control(ring); |
302 | if (ret) | 413 | if (ret) |
303 | return ret; | 414 | return ret; |
@@ -315,83 +426,131 @@ static void render_ring_cleanup(struct intel_ring_buffer *ring) | |||
315 | } | 426 | } |
316 | 427 | ||
317 | static void | 428 | static void |
318 | update_semaphore(struct intel_ring_buffer *ring, int i, u32 seqno) | 429 | update_mboxes(struct intel_ring_buffer *ring, |
430 | u32 seqno, | ||
431 | u32 mmio_offset) | ||
319 | { | 432 | { |
320 | struct drm_device *dev = ring->dev; | 433 | intel_ring_emit(ring, MI_SEMAPHORE_MBOX | |
321 | struct drm_i915_private *dev_priv = dev->dev_private; | 434 | MI_SEMAPHORE_GLOBAL_GTT | |
322 | int id; | 435 | MI_SEMAPHORE_REGISTER | |
323 | 436 | MI_SEMAPHORE_UPDATE); | |
324 | /* | ||
325 | * cs -> 1 = vcs, 0 = bcs | ||
326 | * vcs -> 1 = bcs, 0 = cs, | ||
327 | * bcs -> 1 = cs, 0 = vcs. | ||
328 | */ | ||
329 | id = ring - dev_priv->ring; | ||
330 | id += 2 - i; | ||
331 | id %= 3; | ||
332 | |||
333 | intel_ring_emit(ring, | ||
334 | MI_SEMAPHORE_MBOX | | ||
335 | MI_SEMAPHORE_REGISTER | | ||
336 | MI_SEMAPHORE_UPDATE); | ||
337 | intel_ring_emit(ring, seqno); | 437 | intel_ring_emit(ring, seqno); |
338 | intel_ring_emit(ring, | 438 | intel_ring_emit(ring, mmio_offset); |
339 | RING_SYNC_0(dev_priv->ring[id].mmio_base) + 4*i); | ||
340 | } | 439 | } |
341 | 440 | ||
441 | /** | ||
442 | * gen6_add_request - Update the semaphore mailbox registers | ||
443 | * | ||
444 | * @ring - ring that is adding a request | ||
445 | * @seqno - return seqno stuck into the ring | ||
446 | * | ||
447 | * Update the mailbox registers in the *other* rings with the current seqno. | ||
448 | * This acts like a signal in the canonical semaphore. | ||
449 | */ | ||
342 | static int | 450 | static int |
343 | gen6_add_request(struct intel_ring_buffer *ring, | 451 | gen6_add_request(struct intel_ring_buffer *ring, |
344 | u32 *result) | 452 | u32 *seqno) |
345 | { | 453 | { |
346 | u32 seqno; | 454 | u32 mbox1_reg; |
455 | u32 mbox2_reg; | ||
347 | int ret; | 456 | int ret; |
348 | 457 | ||
349 | ret = intel_ring_begin(ring, 10); | 458 | ret = intel_ring_begin(ring, 10); |
350 | if (ret) | 459 | if (ret) |
351 | return ret; | 460 | return ret; |
352 | 461 | ||
353 | seqno = i915_gem_get_seqno(ring->dev); | 462 | mbox1_reg = ring->signal_mbox[0]; |
354 | update_semaphore(ring, 0, seqno); | 463 | mbox2_reg = ring->signal_mbox[1]; |
355 | update_semaphore(ring, 1, seqno); | ||
356 | 464 | ||
465 | *seqno = i915_gem_get_seqno(ring->dev); | ||
466 | |||
467 | update_mboxes(ring, *seqno, mbox1_reg); | ||
468 | update_mboxes(ring, *seqno, mbox2_reg); | ||
357 | intel_ring_emit(ring, MI_STORE_DWORD_INDEX); | 469 | intel_ring_emit(ring, MI_STORE_DWORD_INDEX); |
358 | intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | 470 | intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); |
359 | intel_ring_emit(ring, seqno); | 471 | intel_ring_emit(ring, *seqno); |
360 | intel_ring_emit(ring, MI_USER_INTERRUPT); | 472 | intel_ring_emit(ring, MI_USER_INTERRUPT); |
361 | intel_ring_advance(ring); | 473 | intel_ring_advance(ring); |
362 | 474 | ||
363 | *result = seqno; | ||
364 | return 0; | 475 | return 0; |
365 | } | 476 | } |
366 | 477 | ||
367 | int | 478 | /** |
368 | intel_ring_sync(struct intel_ring_buffer *ring, | 479 | * intel_ring_sync - sync the waiter to the signaller on seqno |
369 | struct intel_ring_buffer *to, | 480 | * |
481 | * @waiter - ring that is waiting | ||
482 | * @signaller - ring which has, or will signal | ||
483 | * @seqno - seqno which the waiter will block on | ||
484 | */ | ||
485 | static int | ||
486 | intel_ring_sync(struct intel_ring_buffer *waiter, | ||
487 | struct intel_ring_buffer *signaller, | ||
488 | int ring, | ||
370 | u32 seqno) | 489 | u32 seqno) |
371 | { | 490 | { |
372 | int ret; | 491 | int ret; |
492 | u32 dw1 = MI_SEMAPHORE_MBOX | | ||
493 | MI_SEMAPHORE_COMPARE | | ||
494 | MI_SEMAPHORE_REGISTER; | ||
373 | 495 | ||
374 | ret = intel_ring_begin(ring, 4); | 496 | ret = intel_ring_begin(waiter, 4); |
375 | if (ret) | 497 | if (ret) |
376 | return ret; | 498 | return ret; |
377 | 499 | ||
378 | intel_ring_emit(ring, | 500 | intel_ring_emit(waiter, dw1 | signaller->semaphore_register[ring]); |
379 | MI_SEMAPHORE_MBOX | | 501 | intel_ring_emit(waiter, seqno); |
380 | MI_SEMAPHORE_REGISTER | | 502 | intel_ring_emit(waiter, 0); |
381 | intel_ring_sync_index(ring, to) << 17 | | 503 | intel_ring_emit(waiter, MI_NOOP); |
382 | MI_SEMAPHORE_COMPARE); | 504 | intel_ring_advance(waiter); |
383 | intel_ring_emit(ring, seqno); | ||
384 | intel_ring_emit(ring, 0); | ||
385 | intel_ring_emit(ring, MI_NOOP); | ||
386 | intel_ring_advance(ring); | ||
387 | 505 | ||
388 | return 0; | 506 | return 0; |
389 | } | 507 | } |
390 | 508 | ||
509 | /* VCS->RCS (RVSYNC) or BCS->RCS (RBSYNC) */ | ||
510 | int | ||
511 | render_ring_sync_to(struct intel_ring_buffer *waiter, | ||
512 | struct intel_ring_buffer *signaller, | ||
513 | u32 seqno) | ||
514 | { | ||
515 | WARN_ON(signaller->semaphore_register[RCS] == MI_SEMAPHORE_SYNC_INVALID); | ||
516 | return intel_ring_sync(waiter, | ||
517 | signaller, | ||
518 | RCS, | ||
519 | seqno); | ||
520 | } | ||
521 | |||
522 | /* RCS->VCS (VRSYNC) or BCS->VCS (VBSYNC) */ | ||
523 | int | ||
524 | gen6_bsd_ring_sync_to(struct intel_ring_buffer *waiter, | ||
525 | struct intel_ring_buffer *signaller, | ||
526 | u32 seqno) | ||
527 | { | ||
528 | WARN_ON(signaller->semaphore_register[VCS] == MI_SEMAPHORE_SYNC_INVALID); | ||
529 | return intel_ring_sync(waiter, | ||
530 | signaller, | ||
531 | VCS, | ||
532 | seqno); | ||
533 | } | ||
534 | |||
535 | /* RCS->BCS (BRSYNC) or VCS->BCS (BVSYNC) */ | ||
536 | int | ||
537 | gen6_blt_ring_sync_to(struct intel_ring_buffer *waiter, | ||
538 | struct intel_ring_buffer *signaller, | ||
539 | u32 seqno) | ||
540 | { | ||
541 | WARN_ON(signaller->semaphore_register[BCS] == MI_SEMAPHORE_SYNC_INVALID); | ||
542 | return intel_ring_sync(waiter, | ||
543 | signaller, | ||
544 | BCS, | ||
545 | seqno); | ||
546 | } | ||
547 | |||
548 | |||
549 | |||
391 | #define PIPE_CONTROL_FLUSH(ring__, addr__) \ | 550 | #define PIPE_CONTROL_FLUSH(ring__, addr__) \ |
392 | do { \ | 551 | do { \ |
393 | intel_ring_emit(ring__, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | \ | 552 | intel_ring_emit(ring__, GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE | \ |
394 | PIPE_CONTROL_DEPTH_STALL | 2); \ | 553 | PIPE_CONTROL_DEPTH_STALL); \ |
395 | intel_ring_emit(ring__, (addr__) | PIPE_CONTROL_GLOBAL_GTT); \ | 554 | intel_ring_emit(ring__, (addr__) | PIPE_CONTROL_GLOBAL_GTT); \ |
396 | intel_ring_emit(ring__, 0); \ | 555 | intel_ring_emit(ring__, 0); \ |
397 | intel_ring_emit(ring__, 0); \ | 556 | intel_ring_emit(ring__, 0); \ |
@@ -419,8 +578,9 @@ pc_render_add_request(struct intel_ring_buffer *ring, | |||
419 | if (ret) | 578 | if (ret) |
420 | return ret; | 579 | return ret; |
421 | 580 | ||
422 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | | 581 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE | |
423 | PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH); | 582 | PIPE_CONTROL_WRITE_FLUSH | |
583 | PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE); | ||
424 | intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); | 584 | intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); |
425 | intel_ring_emit(ring, seqno); | 585 | intel_ring_emit(ring, seqno); |
426 | intel_ring_emit(ring, 0); | 586 | intel_ring_emit(ring, 0); |
@@ -435,8 +595,9 @@ pc_render_add_request(struct intel_ring_buffer *ring, | |||
435 | PIPE_CONTROL_FLUSH(ring, scratch_addr); | 595 | PIPE_CONTROL_FLUSH(ring, scratch_addr); |
436 | scratch_addr += 128; | 596 | scratch_addr += 128; |
437 | PIPE_CONTROL_FLUSH(ring, scratch_addr); | 597 | PIPE_CONTROL_FLUSH(ring, scratch_addr); |
438 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | | 598 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE | |
439 | PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH | | 599 | PIPE_CONTROL_WRITE_FLUSH | |
600 | PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE | | ||
440 | PIPE_CONTROL_NOTIFY); | 601 | PIPE_CONTROL_NOTIFY); |
441 | intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); | 602 | intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); |
442 | intel_ring_emit(ring, seqno); | 603 | intel_ring_emit(ring, seqno); |
@@ -1026,7 +1187,12 @@ static const struct intel_ring_buffer render_ring = { | |||
1026 | .irq_get = render_ring_get_irq, | 1187 | .irq_get = render_ring_get_irq, |
1027 | .irq_put = render_ring_put_irq, | 1188 | .irq_put = render_ring_put_irq, |
1028 | .dispatch_execbuffer = render_ring_dispatch_execbuffer, | 1189 | .dispatch_execbuffer = render_ring_dispatch_execbuffer, |
1029 | .cleanup = render_ring_cleanup, | 1190 | .cleanup = render_ring_cleanup, |
1191 | .sync_to = render_ring_sync_to, | ||
1192 | .semaphore_register = {MI_SEMAPHORE_SYNC_INVALID, | ||
1193 | MI_SEMAPHORE_SYNC_RV, | ||
1194 | MI_SEMAPHORE_SYNC_RB}, | ||
1195 | .signal_mbox = {GEN6_VRSYNC, GEN6_BRSYNC}, | ||
1030 | }; | 1196 | }; |
1031 | 1197 | ||
1032 | /* ring buffer for bit-stream decoder */ | 1198 | /* ring buffer for bit-stream decoder */ |
@@ -1050,23 +1216,23 @@ static const struct intel_ring_buffer bsd_ring = { | |||
1050 | static void gen6_bsd_ring_write_tail(struct intel_ring_buffer *ring, | 1216 | static void gen6_bsd_ring_write_tail(struct intel_ring_buffer *ring, |
1051 | u32 value) | 1217 | u32 value) |
1052 | { | 1218 | { |
1053 | drm_i915_private_t *dev_priv = ring->dev->dev_private; | 1219 | drm_i915_private_t *dev_priv = ring->dev->dev_private; |
1054 | 1220 | ||
1055 | /* Every tail move must follow the sequence below */ | 1221 | /* Every tail move must follow the sequence below */ |
1056 | I915_WRITE(GEN6_BSD_SLEEP_PSMI_CONTROL, | 1222 | I915_WRITE(GEN6_BSD_SLEEP_PSMI_CONTROL, |
1057 | GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_MODIFY_MASK | | 1223 | GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_MODIFY_MASK | |
1058 | GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_DISABLE); | 1224 | GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_DISABLE); |
1059 | I915_WRITE(GEN6_BSD_RNCID, 0x0); | 1225 | I915_WRITE(GEN6_BSD_RNCID, 0x0); |
1060 | 1226 | ||
1061 | if (wait_for((I915_READ(GEN6_BSD_SLEEP_PSMI_CONTROL) & | 1227 | if (wait_for((I915_READ(GEN6_BSD_SLEEP_PSMI_CONTROL) & |
1062 | GEN6_BSD_SLEEP_PSMI_CONTROL_IDLE_INDICATOR) == 0, | 1228 | GEN6_BSD_SLEEP_PSMI_CONTROL_IDLE_INDICATOR) == 0, |
1063 | 50)) | 1229 | 50)) |
1064 | DRM_ERROR("timed out waiting for IDLE Indicator\n"); | 1230 | DRM_ERROR("timed out waiting for IDLE Indicator\n"); |
1065 | 1231 | ||
1066 | I915_WRITE_TAIL(ring, value); | 1232 | I915_WRITE_TAIL(ring, value); |
1067 | I915_WRITE(GEN6_BSD_SLEEP_PSMI_CONTROL, | 1233 | I915_WRITE(GEN6_BSD_SLEEP_PSMI_CONTROL, |
1068 | GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_MODIFY_MASK | | 1234 | GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_MODIFY_MASK | |
1069 | GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_ENABLE); | 1235 | GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_ENABLE); |
1070 | } | 1236 | } |
1071 | 1237 | ||
1072 | static int gen6_ring_flush(struct intel_ring_buffer *ring, | 1238 | static int gen6_ring_flush(struct intel_ring_buffer *ring, |
@@ -1094,18 +1260,18 @@ static int | |||
1094 | gen6_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, | 1260 | gen6_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, |
1095 | u32 offset, u32 len) | 1261 | u32 offset, u32 len) |
1096 | { | 1262 | { |
1097 | int ret; | 1263 | int ret; |
1098 | 1264 | ||
1099 | ret = intel_ring_begin(ring, 2); | 1265 | ret = intel_ring_begin(ring, 2); |
1100 | if (ret) | 1266 | if (ret) |
1101 | return ret; | 1267 | return ret; |
1102 | 1268 | ||
1103 | intel_ring_emit(ring, MI_BATCH_BUFFER_START | MI_BATCH_NON_SECURE_I965); | 1269 | intel_ring_emit(ring, MI_BATCH_BUFFER_START | MI_BATCH_NON_SECURE_I965); |
1104 | /* bit0-7 is the length on GEN6+ */ | 1270 | /* bit0-7 is the length on GEN6+ */ |
1105 | intel_ring_emit(ring, offset); | 1271 | intel_ring_emit(ring, offset); |
1106 | intel_ring_advance(ring); | 1272 | intel_ring_advance(ring); |
1107 | 1273 | ||
1108 | return 0; | 1274 | return 0; |
1109 | } | 1275 | } |
1110 | 1276 | ||
1111 | static bool | 1277 | static bool |
@@ -1154,6 +1320,11 @@ static const struct intel_ring_buffer gen6_bsd_ring = { | |||
1154 | .irq_get = gen6_bsd_ring_get_irq, | 1320 | .irq_get = gen6_bsd_ring_get_irq, |
1155 | .irq_put = gen6_bsd_ring_put_irq, | 1321 | .irq_put = gen6_bsd_ring_put_irq, |
1156 | .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, | 1322 | .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, |
1323 | .sync_to = gen6_bsd_ring_sync_to, | ||
1324 | .semaphore_register = {MI_SEMAPHORE_SYNC_VR, | ||
1325 | MI_SEMAPHORE_SYNC_INVALID, | ||
1326 | MI_SEMAPHORE_SYNC_VB}, | ||
1327 | .signal_mbox = {GEN6_RVSYNC, GEN6_BVSYNC}, | ||
1157 | }; | 1328 | }; |
1158 | 1329 | ||
1159 | /* Blitter support (SandyBridge+) */ | 1330 | /* Blitter support (SandyBridge+) */ |
@@ -1272,19 +1443,24 @@ static void blt_ring_cleanup(struct intel_ring_buffer *ring) | |||
1272 | } | 1443 | } |
1273 | 1444 | ||
1274 | static const struct intel_ring_buffer gen6_blt_ring = { | 1445 | static const struct intel_ring_buffer gen6_blt_ring = { |
1275 | .name = "blt ring", | 1446 | .name = "blt ring", |
1276 | .id = RING_BLT, | 1447 | .id = RING_BLT, |
1277 | .mmio_base = BLT_RING_BASE, | 1448 | .mmio_base = BLT_RING_BASE, |
1278 | .size = 32 * PAGE_SIZE, | 1449 | .size = 32 * PAGE_SIZE, |
1279 | .init = blt_ring_init, | 1450 | .init = blt_ring_init, |
1280 | .write_tail = ring_write_tail, | 1451 | .write_tail = ring_write_tail, |
1281 | .flush = blt_ring_flush, | 1452 | .flush = blt_ring_flush, |
1282 | .add_request = gen6_add_request, | 1453 | .add_request = gen6_add_request, |
1283 | .get_seqno = ring_get_seqno, | 1454 | .get_seqno = ring_get_seqno, |
1284 | .irq_get = blt_ring_get_irq, | 1455 | .irq_get = blt_ring_get_irq, |
1285 | .irq_put = blt_ring_put_irq, | 1456 | .irq_put = blt_ring_put_irq, |
1286 | .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, | 1457 | .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, |
1287 | .cleanup = blt_ring_cleanup, | 1458 | .cleanup = blt_ring_cleanup, |
1459 | .sync_to = gen6_blt_ring_sync_to, | ||
1460 | .semaphore_register = {MI_SEMAPHORE_SYNC_BR, | ||
1461 | MI_SEMAPHORE_SYNC_BV, | ||
1462 | MI_SEMAPHORE_SYNC_INVALID}, | ||
1463 | .signal_mbox = {GEN6_RBSYNC, GEN6_VBSYNC}, | ||
1288 | }; | 1464 | }; |
1289 | 1465 | ||
1290 | int intel_init_render_ring_buffer(struct drm_device *dev) | 1466 | int intel_init_render_ring_buffer(struct drm_device *dev) |
@@ -1295,6 +1471,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev) | |||
1295 | *ring = render_ring; | 1471 | *ring = render_ring; |
1296 | if (INTEL_INFO(dev)->gen >= 6) { | 1472 | if (INTEL_INFO(dev)->gen >= 6) { |
1297 | ring->add_request = gen6_add_request; | 1473 | ring->add_request = gen6_add_request; |
1474 | ring->flush = gen6_render_ring_flush; | ||
1298 | ring->irq_get = gen6_render_ring_get_irq; | 1475 | ring->irq_get = gen6_render_ring_get_irq; |
1299 | ring->irq_put = gen6_render_ring_put_irq; | 1476 | ring->irq_put = gen6_render_ring_put_irq; |
1300 | } else if (IS_GEN5(dev)) { | 1477 | } else if (IS_GEN5(dev)) { |