aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nv84_fence.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv84_fence.c')
-rw-r--r--drivers/gpu/drm/nouveau/nv84_fence.c106
1 files changed, 51 insertions, 55 deletions
diff --git a/drivers/gpu/drm/nouveau/nv84_fence.c b/drivers/gpu/drm/nouveau/nv84_fence.c
index 5ef87edb878d..b0d147a675c4 100644
--- a/drivers/gpu/drm/nouveau/nv84_fence.c
+++ b/drivers/gpu/drm/nouveau/nv84_fence.c
@@ -22,13 +22,14 @@
22 * Authors: Ben Skeggs 22 * Authors: Ben Skeggs
23 */ 23 */
24 24
25#include "drmP.h" 25#include <core/object.h>
26#include "nouveau_drv.h" 26#include <core/class.h>
27#include "nouveau_dma.h" 27
28#include <engine/fifo.h> 28#include <engine/fifo.h>
29#include <core/ramht.h> 29
30#include "nouveau_drm.h"
31#include "nouveau_dma.h"
30#include "nouveau_fence.h" 32#include "nouveau_fence.h"
31#include "nv50_display.h"
32 33
33struct nv84_fence_chan { 34struct nv84_fence_chan {
34 struct nouveau_fence_chan base; 35 struct nouveau_fence_chan base;
@@ -43,13 +44,14 @@ static int
43nv84_fence_emit(struct nouveau_fence *fence) 44nv84_fence_emit(struct nouveau_fence *fence)
44{ 45{
45 struct nouveau_channel *chan = fence->channel; 46 struct nouveau_channel *chan = fence->channel;
47 struct nouveau_fifo_chan *fifo = (void *)chan->object;
46 int ret = RING_SPACE(chan, 7); 48 int ret = RING_SPACE(chan, 7);
47 if (ret == 0) { 49 if (ret == 0) {
48 BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1); 50 BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1);
49 OUT_RING (chan, NvSema); 51 OUT_RING (chan, NvSema);
50 BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); 52 BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
51 OUT_RING (chan, upper_32_bits(chan->id * 16)); 53 OUT_RING (chan, upper_32_bits(fifo->chid * 16));
52 OUT_RING (chan, lower_32_bits(chan->id * 16)); 54 OUT_RING (chan, lower_32_bits(fifo->chid * 16));
53 OUT_RING (chan, fence->sequence); 55 OUT_RING (chan, fence->sequence);
54 OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG); 56 OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG);
55 FIRE_RING (chan); 57 FIRE_RING (chan);
@@ -62,13 +64,14 @@ static int
62nv84_fence_sync(struct nouveau_fence *fence, 64nv84_fence_sync(struct nouveau_fence *fence,
63 struct nouveau_channel *prev, struct nouveau_channel *chan) 65 struct nouveau_channel *prev, struct nouveau_channel *chan)
64{ 66{
67 struct nouveau_fifo_chan *fifo = (void *)prev->object;
65 int ret = RING_SPACE(chan, 7); 68 int ret = RING_SPACE(chan, 7);
66 if (ret == 0) { 69 if (ret == 0) {
67 BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1); 70 BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1);
68 OUT_RING (chan, NvSema); 71 OUT_RING (chan, NvSema);
69 BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); 72 BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
70 OUT_RING (chan, upper_32_bits(prev->id * 16)); 73 OUT_RING (chan, upper_32_bits(fifo->chid * 16));
71 OUT_RING (chan, lower_32_bits(prev->id * 16)); 74 OUT_RING (chan, lower_32_bits(fifo->chid * 16));
72 OUT_RING (chan, fence->sequence); 75 OUT_RING (chan, fence->sequence);
73 OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_GEQUAL); 76 OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_GEQUAL);
74 FIRE_RING (chan); 77 FIRE_RING (chan);
@@ -79,9 +82,9 @@ nv84_fence_sync(struct nouveau_fence *fence,
79static u32 82static u32
80nv84_fence_read(struct nouveau_channel *chan) 83nv84_fence_read(struct nouveau_channel *chan)
81{ 84{
82 struct drm_nouveau_private *dev_priv = chan->dev->dev_private; 85 struct nouveau_fifo_chan *fifo = (void *)chan->object;
83 struct nv84_fence_priv *priv = dev_priv->fence.func; 86 struct nv84_fence_priv *priv = chan->drm->fence;
84 return nv_ro32(priv->mem, chan->id * 16); 87 return nv_ro32(priv->mem, fifo->chid * 16);
85} 88}
86 89
87static void 90static void
@@ -96,10 +99,10 @@ nv84_fence_context_del(struct nouveau_channel *chan)
96static int 99static int
97nv84_fence_context_new(struct nouveau_channel *chan) 100nv84_fence_context_new(struct nouveau_channel *chan)
98{ 101{
99 struct drm_nouveau_private *dev_priv = chan->dev->dev_private; 102 struct nouveau_fifo_chan *fifo = (void *)chan->object;
100 struct nv84_fence_priv *priv = dev_priv->fence.func; 103 struct nv84_fence_priv *priv = chan->drm->fence;
101 struct nv84_fence_chan *fctx; 104 struct nv84_fence_chan *fctx;
102 struct nouveau_gpuobj *obj; 105 struct nouveau_object *object;
103 int ret, i; 106 int ret, i;
104 107
105 fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL); 108 fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL);
@@ -108,58 +111,56 @@ nv84_fence_context_new(struct nouveau_channel *chan)
108 111
109 nouveau_fence_context_new(&fctx->base); 112 nouveau_fence_context_new(&fctx->base);
110 113
111 ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_FROM_MEMORY, 114 ret = nouveau_object_new(nv_object(chan->cli), chan->handle,
112 priv->mem->addr, priv->mem->size, 115 NvSema, 0x0002,
113 NV_MEM_ACCESS_RW, 116 &(struct nv_dma_class) {
114 NV_MEM_TARGET_VRAM, &obj); 117 .flags = NV_DMA_TARGET_VRAM |
115 if (ret == 0) { 118 NV_DMA_ACCESS_RDWR,
116 ret = nouveau_ramht_insert(chan, NvSema, obj); 119 .start = priv->mem->addr,
117 nouveau_gpuobj_ref(NULL, &obj); 120 .limit = priv->mem->addr +
118 nv_wo32(priv->mem, chan->id * 16, 0x00000000); 121 priv->mem->size - 1,
119 } 122 }, sizeof(struct nv_dma_class),
123 &object);
120 124
121 /* dma objects for display sync channel semaphore blocks */ 125 /* dma objects for display sync channel semaphore blocks */
122 for (i = 0; i < chan->dev->mode_config.num_crtc; i++) { 126 for (i = 0; !ret && i < chan->drm->dev->mode_config.num_crtc; i++) {
123 struct nv50_display *pdisp = nv50_display(chan->dev); 127 struct nouveau_bo *bo = nv50sema(chan->drm->dev, i);
124 struct nv50_display_crtc *dispc = &pdisp->crtc[i]; 128
125 struct nouveau_gpuobj *obj = NULL; 129 ret = nouveau_object_new(nv_object(chan->cli), chan->handle,
126 130 NvEvoSema0 + i, 0x003d,
127 ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 131 &(struct nv_dma_class) {
128 dispc->sem.bo->bo.offset, 0x1000, 132 .flags = NV_DMA_TARGET_VRAM |
129 NV_MEM_ACCESS_RW, 133 NV_DMA_ACCESS_RDWR,
130 NV_MEM_TARGET_VRAM, &obj); 134 .start = bo->bo.offset,
131 if (ret) 135 .limit = bo->bo.offset + 0xfff,
132 break; 136 }, sizeof(struct nv_dma_class),
133 137 &object);
134 ret = nouveau_ramht_insert(chan, NvEvoSema0 + i, obj);
135 nouveau_gpuobj_ref(NULL, &obj);
136 } 138 }
137 139
138 if (ret) 140 if (ret)
139 nv84_fence_context_del(chan); 141 nv84_fence_context_del(chan);
142 nv_wo32(priv->mem, fifo->chid * 16, 0x00000000);
140 return ret; 143 return ret;
141} 144}
142 145
143static void 146static void
144nv84_fence_destroy(struct drm_device *dev) 147nv84_fence_destroy(struct nouveau_drm *drm)
145{ 148{
146 struct drm_nouveau_private *dev_priv = dev->dev_private; 149 struct nv84_fence_priv *priv = drm->fence;
147 struct nv84_fence_priv *priv = dev_priv->fence.func;
148
149 nouveau_gpuobj_ref(NULL, &priv->mem); 150 nouveau_gpuobj_ref(NULL, &priv->mem);
150 dev_priv->fence.func = NULL; 151 drm->fence = NULL;
151 kfree(priv); 152 kfree(priv);
152} 153}
153 154
154int 155int
155nv84_fence_create(struct drm_device *dev) 156nv84_fence_create(struct nouveau_drm *drm)
156{ 157{
157 struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO); 158 struct nouveau_fifo *pfifo = nouveau_fifo(drm->device);
158 struct drm_nouveau_private *dev_priv = dev->dev_private;
159 struct nv84_fence_priv *priv; 159 struct nv84_fence_priv *priv;
160 u32 chan = pfifo->max + 1;
160 int ret; 161 int ret;
161 162
162 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 163 priv = drm->fence = kzalloc(sizeof(*priv), GFP_KERNEL);
163 if (!priv) 164 if (!priv)
164 return -ENOMEM; 165 return -ENOMEM;
165 166
@@ -169,15 +170,10 @@ nv84_fence_create(struct drm_device *dev)
169 priv->base.emit = nv84_fence_emit; 170 priv->base.emit = nv84_fence_emit;
170 priv->base.sync = nv84_fence_sync; 171 priv->base.sync = nv84_fence_sync;
171 priv->base.read = nv84_fence_read; 172 priv->base.read = nv84_fence_read;
172 dev_priv->fence.func = priv;
173
174 ret = nouveau_gpuobj_new(dev, NULL, 16 * pfifo->channels,
175 0x1000, 0, &priv->mem);
176 if (ret)
177 goto out;
178 173
179out: 174 ret = nouveau_gpuobj_new(drm->device, NULL, chan * 16, 0x1000, 0,
175 &priv->mem);
180 if (ret) 176 if (ret)
181 nv84_fence_destroy(dev); 177 nv84_fence_destroy(drm);
182 return ret; 178 return ret;
183} 179}