提交 cb1d771a 编写于 作者: B Ben Skeggs

drm/nvc0: implement semaphores for inter-channel sync

Signed-off-by: NBen Skeggs <bskeggs@redhat.com>
上级 cc8cd647
master alk-4.19.24 alk-4.19.30 alk-4.19.34 alk-4.19.36 alk-4.19.43 alk-4.19.48 alk-4.19.57 ck-4.19.67 ck-4.19.81 ck-4.19.91 github/fork/deepanshu1422/fix-typo-in-comment github/fork/haosdent/fix-typo linux-next v4.19.91 v4.19.90 v4.19.89 v4.19.88 v4.19.87 v4.19.86 v4.19.85 v4.19.84 v4.19.83 v4.19.82 v4.19.81 v4.19.80 v4.19.79 v4.19.78 v4.19.77 v4.19.76 v4.19.75 v4.19.74 v4.19.73 v4.19.72 v4.19.71 v4.19.70 v4.19.69 v4.19.68 v4.19.67 v4.19.66 v4.19.65 v4.19.64 v4.19.63 v4.19.62 v4.19.61 v4.19.60 v4.19.59 v4.19.58 v4.19.57 v4.19.56 v4.19.55 v4.19.54 v4.19.53 v4.19.52 v4.19.51 v4.19.50 v4.19.49 v4.19.48 v4.19.47 v4.19.46 v4.19.45 v4.19.44 v4.19.43 v4.19.42 v4.19.41 v4.19.40 v4.19.39 v4.19.38 v4.19.37 v4.19.36 v4.19.35 v4.19.34 v4.19.33 v4.19.32 v4.19.31 v4.19.30 v4.19.29 v4.19.28 v4.19.27 v4.19.26 v4.19.25 v4.19.24 v4.19.23 v4.19.22 v4.19.21 v4.19.20 v4.19.19 v4.19.18 v4.19.17 v4.19.16 v4.19.15 v4.19.14 v4.19.13 v4.19.12 v4.19.11 v4.19.10 v4.19.9 v4.19.8 v4.19.7 v4.19.6 v4.19.5 v4.19.4 v4.19.3 v4.19.2 v4.19.1 v4.19 v4.19-rc8 v4.19-rc7 v4.19-rc6 v4.19-rc5 v4.19-rc4 v4.19-rc3 v4.19-rc2 v4.19-rc1 ck-release-21 ck-release-20 ck-release-19.2 ck-release-19.1 ck-release-19 ck-release-18 ck-release-17.2 ck-release-17.1 ck-release-17 ck-release-16 ck-release-15.1 ck-release-15 ck-release-14 ck-release-13.2 ck-release-13 ck-release-12 ck-release-11 ck-release-10 ck-release-9 ck-release-7 alk-release-15 alk-release-14 alk-release-13.2 alk-release-13 alk-release-12 alk-release-11 alk-release-10 alk-release-9 alk-release-7
无相关合并请求
...@@ -32,8 +32,7 @@ ...@@ -32,8 +32,7 @@
#include "nouveau_dma.h" #include "nouveau_dma.h"
#define USE_REFCNT(dev) (nouveau_private(dev)->chipset >= 0x10) #define USE_REFCNT(dev) (nouveau_private(dev)->chipset >= 0x10)
#define USE_SEMA(dev) (nouveau_private(dev)->chipset >= 0x17 && \ #define USE_SEMA(dev) (nouveau_private(dev)->chipset >= 0x17)
nouveau_private(dev)->card_type < NV_C0)
struct nouveau_fence { struct nouveau_fence {
struct nouveau_channel *channel; struct nouveau_channel *channel;
...@@ -338,7 +337,8 @@ semaphore_acquire(struct nouveau_channel *chan, struct nouveau_semaphore *sema) ...@@ -338,7 +337,8 @@ semaphore_acquire(struct nouveau_channel *chan, struct nouveau_semaphore *sema)
BEGIN_RING(chan, NvSubSw, NV_SW_SEMAPHORE_OFFSET, 2); BEGIN_RING(chan, NvSubSw, NV_SW_SEMAPHORE_OFFSET, 2);
OUT_RING (chan, sema->mem->start); OUT_RING (chan, sema->mem->start);
OUT_RING (chan, 1); OUT_RING (chan, 1);
} else { } else
if (dev_priv->chipset < 0xc0) {
/* /*
* NV50 tries to be too smart and context-switch * NV50 tries to be too smart and context-switch
* between semaphores instead of doing a "first come, * between semaphores instead of doing a "first come,
...@@ -367,6 +367,19 @@ semaphore_acquire(struct nouveau_channel *chan, struct nouveau_semaphore *sema) ...@@ -367,6 +367,19 @@ semaphore_acquire(struct nouveau_channel *chan, struct nouveau_semaphore *sema)
OUT_RING (chan, lower_32_bits(sema->mem->start)); OUT_RING (chan, lower_32_bits(sema->mem->start));
OUT_RING (chan, 1); OUT_RING (chan, 1);
OUT_RING (chan, 1); /* ACQUIRE_EQ */ OUT_RING (chan, 1); /* ACQUIRE_EQ */
} else {
struct nouveau_vma *vma = &dev_priv->fence.bo->vma;
u64 offset = vma->offset + sema->mem->start;
ret = RING_SPACE(chan, 5);
if (ret)
return ret;
BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0010, 4);
OUT_RING (chan, upper_32_bits(offset));
OUT_RING (chan, lower_32_bits(offset));
OUT_RING (chan, 1);
OUT_RING (chan, 0x1001); /* ACQUIRE_EQ */
} }
/* Delay semaphore destruction until its work is done */ /* Delay semaphore destruction until its work is done */
...@@ -396,7 +409,8 @@ semaphore_release(struct nouveau_channel *chan, struct nouveau_semaphore *sema) ...@@ -396,7 +409,8 @@ semaphore_release(struct nouveau_channel *chan, struct nouveau_semaphore *sema)
OUT_RING (chan, sema->mem->start); OUT_RING (chan, sema->mem->start);
BEGIN_RING(chan, NvSubSw, NV_SW_SEMAPHORE_RELEASE, 1); BEGIN_RING(chan, NvSubSw, NV_SW_SEMAPHORE_RELEASE, 1);
OUT_RING (chan, 1); OUT_RING (chan, 1);
} else { } else
if (dev_priv->chipset < 0xc0) {
/* /*
* Emits release and forces the card to context switch right * Emits release and forces the card to context switch right
* afterwards, there may be another channel waiting for the * afterwards, there may be another channel waiting for the
...@@ -414,6 +428,19 @@ semaphore_release(struct nouveau_channel *chan, struct nouveau_semaphore *sema) ...@@ -414,6 +428,19 @@ semaphore_release(struct nouveau_channel *chan, struct nouveau_semaphore *sema)
OUT_RING (chan, 2); /* RELEASE */ OUT_RING (chan, 2); /* RELEASE */
BEGIN_RING(chan, NvSubSw, 0x0080, 1); BEGIN_RING(chan, NvSubSw, 0x0080, 1);
OUT_RING (chan, 0); OUT_RING (chan, 0);
} else {
struct nouveau_vma *vma = &dev_priv->fence.bo->vma;
u64 offset = vma->offset + sema->mem->start;
ret = RING_SPACE(chan, 5);
if (ret)
return ret;
BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0010, 4);
OUT_RING (chan, upper_32_bits(offset));
OUT_RING (chan, lower_32_bits(offset));
OUT_RING (chan, 1);
OUT_RING (chan, 0x1002); /* RELEASE */
} }
/* Delay semaphore destruction until its work is done */ /* Delay semaphore destruction until its work is done */
...@@ -489,19 +516,20 @@ nouveau_fence_channel_init(struct nouveau_channel *chan) ...@@ -489,19 +516,20 @@ nouveau_fence_channel_init(struct nouveau_channel *chan)
struct nouveau_gpuobj *obj = NULL; struct nouveau_gpuobj *obj = NULL;
int ret; int ret;
if (dev_priv->card_type >= NV_C0)
goto out_initialised;
/* Create an NV_SW object for various sync purposes */ /* Create an NV_SW object for various sync purposes */
ret = nouveau_gpuobj_gr_new(chan, NvSw, NV_SW); ret = nouveau_gpuobj_gr_new(chan, NvSw, NV_SW);
if (ret) if (ret)
return ret; return ret;
/* we leave subchannel empty for nvc0 */ /* we leave subchannel empty for nvc0 */
if (dev_priv->card_type < NV_C0) { ret = RING_SPACE(chan, 2);
ret = RING_SPACE(chan, 2); if (ret)
if (ret) return ret;
return ret; BEGIN_RING(chan, NvSubSw, 0, 1);
BEGIN_RING(chan, NvSubSw, 0, 1); OUT_RING(chan, NvSw);
OUT_RING(chan, NvSw);
}
/* Create a DMA object for the shared cross-channel sync area. */ /* Create a DMA object for the shared cross-channel sync area. */
if (USE_SEMA(dev)) { if (USE_SEMA(dev)) {
...@@ -528,10 +556,10 @@ nouveau_fence_channel_init(struct nouveau_channel *chan) ...@@ -528,10 +556,10 @@ nouveau_fence_channel_init(struct nouveau_channel *chan)
FIRE_RING(chan); FIRE_RING(chan);
out_initialised:
INIT_LIST_HEAD(&chan->fence.pending); INIT_LIST_HEAD(&chan->fence.pending);
spin_lock_init(&chan->fence.lock); spin_lock_init(&chan->fence.lock);
atomic_set(&chan->fence.last_sequence_irq, 0); atomic_set(&chan->fence.last_sequence_irq, 0);
return 0; return 0;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
反馈
建议
客服 返回
顶部