aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fence.c52
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
38struct nouveau_fence { 37struct 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
559out_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