diff options
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_fence.c | 52 |
1 files changed, 40 insertions, 12 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 37bccd5c4122..1334868a3eeb 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c | |||
@@ -32,8 +32,7 @@ | |||
32 | #include "nouveau_dma.h" | 32 | #include "nouveau_dma.h" |
33 | 33 | ||
34 | #define USE_REFCNT(dev) (nouveau_private(dev)->chipset >= 0x10) | 34 | #define USE_REFCNT(dev) (nouveau_private(dev)->chipset >= 0x10) |
35 | #define USE_SEMA(dev) (nouveau_private(dev)->chipset >= 0x17 && \ | 35 | #define USE_SEMA(dev) (nouveau_private(dev)->chipset >= 0x17) |
36 | nouveau_private(dev)->card_type < NV_C0) | ||
37 | 36 | ||
38 | struct nouveau_fence { | 37 | struct nouveau_fence { |
39 | struct nouveau_channel *channel; | 38 | struct nouveau_channel *channel; |
@@ -338,7 +337,8 @@ semaphore_acquire(struct nouveau_channel *chan, struct nouveau_semaphore *sema) | |||
338 | BEGIN_RING(chan, NvSubSw, NV_SW_SEMAPHORE_OFFSET, 2); | 337 | BEGIN_RING(chan, NvSubSw, NV_SW_SEMAPHORE_OFFSET, 2); |
339 | OUT_RING (chan, sema->mem->start); | 338 | OUT_RING (chan, sema->mem->start); |
340 | OUT_RING (chan, 1); | 339 | OUT_RING (chan, 1); |
341 | } else { | 340 | } else |
341 | if (dev_priv->chipset < 0xc0) { | ||
342 | /* | 342 | /* |
343 | * NV50 tries to be too smart and context-switch | 343 | * NV50 tries to be too smart and context-switch |
344 | * between semaphores instead of doing a "first come, | 344 | * between semaphores instead of doing a "first come, |
@@ -367,6 +367,19 @@ semaphore_acquire(struct nouveau_channel *chan, struct nouveau_semaphore *sema) | |||
367 | OUT_RING (chan, lower_32_bits(sema->mem->start)); | 367 | OUT_RING (chan, lower_32_bits(sema->mem->start)); |
368 | OUT_RING (chan, 1); | 368 | OUT_RING (chan, 1); |
369 | OUT_RING (chan, 1); /* ACQUIRE_EQ */ | 369 | OUT_RING (chan, 1); /* ACQUIRE_EQ */ |
370 | } else { | ||
371 | struct nouveau_vma *vma = &dev_priv->fence.bo->vma; | ||
372 | u64 offset = vma->offset + sema->mem->start; | ||
373 | |||
374 | ret = RING_SPACE(chan, 5); | ||
375 | if (ret) | ||
376 | return ret; | ||
377 | |||
378 | BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0010, 4); | ||
379 | OUT_RING (chan, upper_32_bits(offset)); | ||
380 | OUT_RING (chan, lower_32_bits(offset)); | ||
381 | OUT_RING (chan, 1); | ||
382 | OUT_RING (chan, 0x1001); /* ACQUIRE_EQ */ | ||
370 | } | 383 | } |
371 | 384 | ||
372 | /* Delay semaphore destruction until its work is done */ | 385 | /* Delay semaphore destruction until its work is done */ |
@@ -396,7 +409,8 @@ semaphore_release(struct nouveau_channel *chan, struct nouveau_semaphore *sema) | |||
396 | OUT_RING (chan, sema->mem->start); | 409 | OUT_RING (chan, sema->mem->start); |
397 | BEGIN_RING(chan, NvSubSw, NV_SW_SEMAPHORE_RELEASE, 1); | 410 | BEGIN_RING(chan, NvSubSw, NV_SW_SEMAPHORE_RELEASE, 1); |
398 | OUT_RING (chan, 1); | 411 | OUT_RING (chan, 1); |
399 | } else { | 412 | } else |
413 | if (dev_priv->chipset < 0xc0) { | ||
400 | /* | 414 | /* |
401 | * Emits release and forces the card to context switch right | 415 | * Emits release and forces the card to context switch right |
402 | * afterwards, there may be another channel waiting for the | 416 | * afterwards, there may be another channel waiting for the |
@@ -414,6 +428,19 @@ semaphore_release(struct nouveau_channel *chan, struct nouveau_semaphore *sema) | |||
414 | OUT_RING (chan, 2); /* RELEASE */ | 428 | OUT_RING (chan, 2); /* RELEASE */ |
415 | BEGIN_RING(chan, NvSubSw, 0x0080, 1); | 429 | BEGIN_RING(chan, NvSubSw, 0x0080, 1); |
416 | OUT_RING (chan, 0); | 430 | OUT_RING (chan, 0); |
431 | } else { | ||
432 | struct nouveau_vma *vma = &dev_priv->fence.bo->vma; | ||
433 | u64 offset = vma->offset + sema->mem->start; | ||
434 | |||
435 | ret = RING_SPACE(chan, 5); | ||
436 | if (ret) | ||
437 | return ret; | ||
438 | |||
439 | BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0010, 4); | ||
440 | OUT_RING (chan, upper_32_bits(offset)); | ||
441 | OUT_RING (chan, lower_32_bits(offset)); | ||
442 | OUT_RING (chan, 1); | ||
443 | OUT_RING (chan, 0x1002); /* RELEASE */ | ||
417 | } | 444 | } |
418 | 445 | ||
419 | /* Delay semaphore destruction until its work is done */ | 446 | /* Delay semaphore destruction until its work is done */ |
@@ -489,19 +516,20 @@ nouveau_fence_channel_init(struct nouveau_channel *chan) | |||
489 | struct nouveau_gpuobj *obj = NULL; | 516 | struct nouveau_gpuobj *obj = NULL; |
490 | int ret; | 517 | int ret; |
491 | 518 | ||
519 | if (dev_priv->card_type >= NV_C0) | ||
520 | goto out_initialised; | ||
521 | |||
492 | /* Create an NV_SW object for various sync purposes */ | 522 | /* Create an NV_SW object for various sync purposes */ |
493 | ret = nouveau_gpuobj_gr_new(chan, NvSw, NV_SW); | 523 | ret = nouveau_gpuobj_gr_new(chan, NvSw, NV_SW); |
494 | if (ret) | 524 | if (ret) |
495 | return ret; | 525 | return ret; |
496 | 526 | ||
497 | /* we leave subchannel empty for nvc0 */ | 527 | /* we leave subchannel empty for nvc0 */ |
498 | if (dev_priv->card_type < NV_C0) { | 528 | ret = RING_SPACE(chan, 2); |
499 | ret = RING_SPACE(chan, 2); | 529 | if (ret) |
500 | if (ret) | 530 | return ret; |
501 | return ret; | 531 | BEGIN_RING(chan, NvSubSw, 0, 1); |
502 | BEGIN_RING(chan, NvSubSw, 0, 1); | 532 | OUT_RING(chan, NvSw); |
503 | OUT_RING(chan, NvSw); | ||
504 | } | ||
505 | 533 | ||
506 | /* Create a DMA object for the shared cross-channel sync area. */ | 534 | /* Create a DMA object for the shared cross-channel sync area. */ |
507 | if (USE_SEMA(dev)) { | 535 | if (USE_SEMA(dev)) { |
@@ -528,10 +556,10 @@ nouveau_fence_channel_init(struct nouveau_channel *chan) | |||
528 | 556 | ||
529 | FIRE_RING(chan); | 557 | FIRE_RING(chan); |
530 | 558 | ||
559 | out_initialised: | ||
531 | INIT_LIST_HEAD(&chan->fence.pending); | 560 | INIT_LIST_HEAD(&chan->fence.pending); |
532 | spin_lock_init(&chan->fence.lock); | 561 | spin_lock_init(&chan->fence.lock); |
533 | atomic_set(&chan->fence.last_sequence_irq, 0); | 562 | atomic_set(&chan->fence.last_sequence_irq, 0); |
534 | |||
535 | return 0; | 563 | return 0; |
536 | } | 564 | } |
537 | 565 | ||