diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv84_fence.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nv84_fence.c | 106 |
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 | ||
33 | struct nv84_fence_chan { | 34 | struct nv84_fence_chan { |
34 | struct nouveau_fence_chan base; | 35 | struct nouveau_fence_chan base; |
@@ -43,13 +44,14 @@ static int | |||
43 | nv84_fence_emit(struct nouveau_fence *fence) | 44 | nv84_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 | |||
62 | nv84_fence_sync(struct nouveau_fence *fence, | 64 | nv84_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, | |||
79 | static u32 | 82 | static u32 |
80 | nv84_fence_read(struct nouveau_channel *chan) | 83 | nv84_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 | ||
87 | static void | 90 | static void |
@@ -96,10 +99,10 @@ nv84_fence_context_del(struct nouveau_channel *chan) | |||
96 | static int | 99 | static int |
97 | nv84_fence_context_new(struct nouveau_channel *chan) | 100 | nv84_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 | ||
143 | static void | 146 | static void |
144 | nv84_fence_destroy(struct drm_device *dev) | 147 | nv84_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 | ||
154 | int | 155 | int |
155 | nv84_fence_create(struct drm_device *dev) | 156 | nv84_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 | ||
179 | out: | 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 | } |