aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nv50_instmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv50_instmem.c')
-rw-r--r--drivers/gpu/drm/nouveau/nv50_instmem.c375
1 files changed, 164 insertions, 211 deletions
diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c
index b773229b7647..2e1b1cd19a4b 100644
--- a/drivers/gpu/drm/nouveau/nv50_instmem.c
+++ b/drivers/gpu/drm/nouveau/nv50_instmem.c
@@ -27,14 +27,20 @@
27 27
28#include "drmP.h" 28#include "drmP.h"
29#include "drm.h" 29#include "drm.h"
30
30#include "nouveau_drv.h" 31#include "nouveau_drv.h"
32#include "nouveau_vm.h"
33
34#define BAR1_VM_BASE 0x0020000000ULL
35#define BAR1_VM_SIZE pci_resource_len(dev->pdev, 1)
36#define BAR3_VM_BASE 0x0000000000ULL
37#define BAR3_VM_SIZE pci_resource_len(dev->pdev, 3)
31 38
32struct nv50_instmem_priv { 39struct nv50_instmem_priv {
33 uint32_t save1700[5]; /* 0x1700->0x1710 */ 40 uint32_t save1700[5]; /* 0x1700->0x1710 */
34 41
35 struct nouveau_gpuobj *pramin_pt; 42 struct nouveau_gpuobj *bar1_dmaobj;
36 struct nouveau_gpuobj *pramin_bar; 43 struct nouveau_gpuobj *bar3_dmaobj;
37 struct nouveau_gpuobj *fb_bar;
38}; 44};
39 45
40static void 46static void
@@ -48,6 +54,7 @@ nv50_channel_del(struct nouveau_channel **pchan)
48 return; 54 return;
49 55
50 nouveau_gpuobj_ref(NULL, &chan->ramfc); 56 nouveau_gpuobj_ref(NULL, &chan->ramfc);
57 nouveau_vm_ref(NULL, &chan->vm, chan->vm_pd);
51 nouveau_gpuobj_ref(NULL, &chan->vm_pd); 58 nouveau_gpuobj_ref(NULL, &chan->vm_pd);
52 if (chan->ramin_heap.free_stack.next) 59 if (chan->ramin_heap.free_stack.next)
53 drm_mm_takedown(&chan->ramin_heap); 60 drm_mm_takedown(&chan->ramin_heap);
@@ -56,14 +63,14 @@ nv50_channel_del(struct nouveau_channel **pchan)
56} 63}
57 64
58static int 65static int
59nv50_channel_new(struct drm_device *dev, u32 size, 66nv50_channel_new(struct drm_device *dev, u32 size, struct nouveau_vm *vm,
60 struct nouveau_channel **pchan) 67 struct nouveau_channel **pchan)
61{ 68{
62 struct drm_nouveau_private *dev_priv = dev->dev_private; 69 struct drm_nouveau_private *dev_priv = dev->dev_private;
63 u32 pgd = (dev_priv->chipset == 0x50) ? 0x1400 : 0x0200; 70 u32 pgd = (dev_priv->chipset == 0x50) ? 0x1400 : 0x0200;
64 u32 fc = (dev_priv->chipset == 0x50) ? 0x0000 : 0x4200; 71 u32 fc = (dev_priv->chipset == 0x50) ? 0x0000 : 0x4200;
65 struct nouveau_channel *chan; 72 struct nouveau_channel *chan;
66 int ret; 73 int ret, i;
67 74
68 chan = kzalloc(sizeof(*chan), GFP_KERNEL); 75 chan = kzalloc(sizeof(*chan), GFP_KERNEL);
69 if (!chan) 76 if (!chan)
@@ -92,6 +99,17 @@ nv50_channel_new(struct drm_device *dev, u32 size,
92 return ret; 99 return ret;
93 } 100 }
94 101
102 for (i = 0; i < 0x4000; i += 8) {
103 nv_wo32(chan->vm_pd, i + 0, 0x00000000);
104 nv_wo32(chan->vm_pd, i + 4, 0xdeadcafe);
105 }
106
107 ret = nouveau_vm_ref(vm, &chan->vm, chan->vm_pd);
108 if (ret) {
109 nv50_channel_del(&chan);
110 return ret;
111 }
112
95 ret = nouveau_gpuobj_new_fake(dev, chan->ramin->pinst == ~0 ? ~0 : 113 ret = nouveau_gpuobj_new_fake(dev, chan->ramin->pinst == ~0 ? ~0 :
96 chan->ramin->pinst + fc, 114 chan->ramin->pinst + fc,
97 chan->ramin->vinst + fc, 0x100, 115 chan->ramin->vinst + fc, 0x100,
@@ -111,6 +129,7 @@ nv50_instmem_init(struct drm_device *dev)
111 struct drm_nouveau_private *dev_priv = dev->dev_private; 129 struct drm_nouveau_private *dev_priv = dev->dev_private;
112 struct nv50_instmem_priv *priv; 130 struct nv50_instmem_priv *priv;
113 struct nouveau_channel *chan; 131 struct nouveau_channel *chan;
132 struct nouveau_vm *vm;
114 int ret, i; 133 int ret, i;
115 u32 tmp; 134 u32 tmp;
116 135
@@ -127,112 +146,87 @@ nv50_instmem_init(struct drm_device *dev)
127 ret = drm_mm_init(&dev_priv->ramin_heap, 0, dev_priv->ramin_size); 146 ret = drm_mm_init(&dev_priv->ramin_heap, 0, dev_priv->ramin_size);
128 if (ret) { 147 if (ret) {
129 NV_ERROR(dev, "Failed to init RAMIN heap\n"); 148 NV_ERROR(dev, "Failed to init RAMIN heap\n");
130 return -ENOMEM; 149 goto error;
131 } 150 }
132 151
133 /* we need a channel to plug into the hw to control the BARs */ 152 /* BAR3 */
134 ret = nv50_channel_new(dev, 128*1024, &dev_priv->fifos[0]); 153 ret = nouveau_vm_new(dev, BAR3_VM_BASE, BAR3_VM_SIZE, BAR3_VM_BASE,
154 &dev_priv->bar3_vm);
135 if (ret) 155 if (ret)
136 return ret; 156 goto error;
137 chan = dev_priv->fifos[127] = dev_priv->fifos[0];
138 157
139 /* allocate page table for PRAMIN BAR */ 158 ret = nouveau_gpuobj_new(dev, NULL, (BAR3_VM_SIZE >> 12) * 8,
140 ret = nouveau_gpuobj_new(dev, chan, (dev_priv->ramin_size >> 12) * 8, 159 0x1000, NVOBJ_FLAG_DONT_MAP |
141 0x1000, NVOBJ_FLAG_ZERO_ALLOC, 160 NVOBJ_FLAG_ZERO_ALLOC,
142 &priv->pramin_pt); 161 &dev_priv->bar3_vm->pgt[0].obj[0]);
143 if (ret) 162 if (ret)
144 return ret; 163 goto error;
164 dev_priv->bar3_vm->pgt[0].refcount[0] = 1;
145 165
146 nv_wo32(chan->vm_pd, 0x0000, priv->pramin_pt->vinst | 0x63); 166 nv50_instmem_map(dev_priv->bar3_vm->pgt[0].obj[0]);
147 nv_wo32(chan->vm_pd, 0x0004, 0);
148 167
149 /* DMA object for PRAMIN BAR */ 168 ret = nv50_channel_new(dev, 128 * 1024, dev_priv->bar3_vm, &chan);
150 ret = nouveau_gpuobj_new(dev, chan, 6*4, 16, 0, &priv->pramin_bar);
151 if (ret) 169 if (ret)
152 return ret; 170 goto error;
153 nv_wo32(priv->pramin_bar, 0x00, 0x7fc00000); 171 dev_priv->channels.ptr[0] = dev_priv->channels.ptr[127] = chan;
154 nv_wo32(priv->pramin_bar, 0x04, dev_priv->ramin_size - 1); 172
155 nv_wo32(priv->pramin_bar, 0x08, 0x00000000); 173 ret = nv50_gpuobj_dma_new(chan, 0x0000, BAR3_VM_BASE, BAR3_VM_SIZE,
156 nv_wo32(priv->pramin_bar, 0x0c, 0x00000000); 174 NV_MEM_TARGET_VM, NV_MEM_ACCESS_VM,
157 nv_wo32(priv->pramin_bar, 0x10, 0x00000000); 175 NV_MEM_TYPE_VM, NV_MEM_COMP_VM,
158 nv_wo32(priv->pramin_bar, 0x14, 0x00000000); 176 &priv->bar3_dmaobj);
159
160 /* map channel into PRAMIN, gpuobj didn't do it for us */
161 ret = nv50_instmem_bind(dev, chan->ramin);
162 if (ret) 177 if (ret)
163 return ret; 178 goto error;
164 179
165 /* poke regs... */
166 nv_wr32(dev, 0x001704, 0x00000000 | (chan->ramin->vinst >> 12)); 180 nv_wr32(dev, 0x001704, 0x00000000 | (chan->ramin->vinst >> 12));
167 nv_wr32(dev, 0x001704, 0x40000000 | (chan->ramin->vinst >> 12)); 181 nv_wr32(dev, 0x001704, 0x40000000 | (chan->ramin->vinst >> 12));
168 nv_wr32(dev, 0x00170c, 0x80000000 | (priv->pramin_bar->cinst >> 4)); 182 nv_wr32(dev, 0x00170c, 0x80000000 | (priv->bar3_dmaobj->cinst >> 4));
169
170 tmp = nv_ri32(dev, 0);
171 nv_wi32(dev, 0, ~tmp);
172 if (nv_ri32(dev, 0) != ~tmp) {
173 NV_ERROR(dev, "PRAMIN readback failed\n");
174 return -EIO;
175 }
176 nv_wi32(dev, 0, tmp);
177 183
184 dev_priv->engine.instmem.flush(dev);
178 dev_priv->ramin_available = true; 185 dev_priv->ramin_available = true;
179 186
180 /* Determine VM layout */ 187 tmp = nv_ro32(chan->ramin, 0);
181 dev_priv->vm_gart_base = roundup(NV50_VM_BLOCK, NV50_VM_BLOCK); 188 nv_wo32(chan->ramin, 0, ~tmp);
182 dev_priv->vm_gart_size = NV50_VM_BLOCK; 189 if (nv_ro32(chan->ramin, 0) != ~tmp) {
183 190 NV_ERROR(dev, "PRAMIN readback failed\n");
184 dev_priv->vm_vram_base = dev_priv->vm_gart_base + dev_priv->vm_gart_size; 191 ret = -EIO;
185 dev_priv->vm_vram_size = dev_priv->vram_size; 192 goto error;
186 if (dev_priv->vm_vram_size > NV50_VM_MAX_VRAM)
187 dev_priv->vm_vram_size = NV50_VM_MAX_VRAM;
188 dev_priv->vm_vram_size = roundup(dev_priv->vm_vram_size, NV50_VM_BLOCK);
189 dev_priv->vm_vram_pt_nr = dev_priv->vm_vram_size / NV50_VM_BLOCK;
190
191 dev_priv->vm_end = dev_priv->vm_vram_base + dev_priv->vm_vram_size;
192
193 NV_DEBUG(dev, "NV50VM: GART 0x%016llx-0x%016llx\n",
194 dev_priv->vm_gart_base,
195 dev_priv->vm_gart_base + dev_priv->vm_gart_size - 1);
196 NV_DEBUG(dev, "NV50VM: VRAM 0x%016llx-0x%016llx\n",
197 dev_priv->vm_vram_base,
198 dev_priv->vm_vram_base + dev_priv->vm_vram_size - 1);
199
200 /* VRAM page table(s), mapped into VM at +1GiB */
201 for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) {
202 ret = nouveau_gpuobj_new(dev, NULL, NV50_VM_BLOCK / 0x10000 * 8,
203 0, NVOBJ_FLAG_ZERO_ALLOC,
204 &chan->vm_vram_pt[i]);
205 if (ret) {
206 NV_ERROR(dev, "Error creating VRAM PGT: %d\n", ret);
207 dev_priv->vm_vram_pt_nr = i;
208 return ret;
209 }
210 dev_priv->vm_vram_pt[i] = chan->vm_vram_pt[i];
211
212 nv_wo32(chan->vm_pd, 0x10 + (i*8),
213 chan->vm_vram_pt[i]->vinst | 0x61);
214 nv_wo32(chan->vm_pd, 0x14 + (i*8), 0);
215 } 193 }
194 nv_wo32(chan->ramin, 0, tmp);
216 195
217 /* DMA object for FB BAR */ 196 /* BAR1 */
218 ret = nouveau_gpuobj_new(dev, chan, 6*4, 16, 0, &priv->fb_bar); 197 ret = nouveau_vm_new(dev, BAR1_VM_BASE, BAR1_VM_SIZE, BAR1_VM_BASE, &vm);
219 if (ret) 198 if (ret)
220 return ret; 199 goto error;
221 nv_wo32(priv->fb_bar, 0x00, 0x7fc00000);
222 nv_wo32(priv->fb_bar, 0x04, 0x40000000 +
223 pci_resource_len(dev->pdev, 1) - 1);
224 nv_wo32(priv->fb_bar, 0x08, 0x40000000);
225 nv_wo32(priv->fb_bar, 0x0c, 0x00000000);
226 nv_wo32(priv->fb_bar, 0x10, 0x00000000);
227 nv_wo32(priv->fb_bar, 0x14, 0x00000000);
228 200
229 dev_priv->engine.instmem.flush(dev); 201 ret = nouveau_vm_ref(vm, &dev_priv->bar1_vm, chan->vm_pd);
202 if (ret)
203 goto error;
204 nouveau_vm_ref(NULL, &vm, NULL);
205
206 ret = nv50_gpuobj_dma_new(chan, 0x0000, BAR1_VM_BASE, BAR1_VM_SIZE,
207 NV_MEM_TARGET_VM, NV_MEM_ACCESS_VM,
208 NV_MEM_TYPE_VM, NV_MEM_COMP_VM,
209 &priv->bar1_dmaobj);
210 if (ret)
211 goto error;
230 212
231 nv_wr32(dev, 0x001708, 0x80000000 | (priv->fb_bar->cinst >> 4)); 213 nv_wr32(dev, 0x001708, 0x80000000 | (priv->bar1_dmaobj->cinst >> 4));
232 for (i = 0; i < 8; i++) 214 for (i = 0; i < 8; i++)
233 nv_wr32(dev, 0x1900 + (i*4), 0); 215 nv_wr32(dev, 0x1900 + (i*4), 0);
234 216
217 /* Create shared channel VM, space is reserved at the beginning
218 * to catch "NULL pointer" references
219 */
220 ret = nouveau_vm_new(dev, 0, (1ULL << 40), 0x0020000000ULL,
221 &dev_priv->chan_vm);
222 if (ret)
223 return ret;
224
235 return 0; 225 return 0;
226
227error:
228 nv50_instmem_takedown(dev);
229 return ret;
236} 230}
237 231
238void 232void
@@ -240,7 +234,7 @@ nv50_instmem_takedown(struct drm_device *dev)
240{ 234{
241 struct drm_nouveau_private *dev_priv = dev->dev_private; 235 struct drm_nouveau_private *dev_priv = dev->dev_private;
242 struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; 236 struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv;
243 struct nouveau_channel *chan = dev_priv->fifos[0]; 237 struct nouveau_channel *chan = dev_priv->channels.ptr[0];
244 int i; 238 int i;
245 239
246 NV_DEBUG(dev, "\n"); 240 NV_DEBUG(dev, "\n");
@@ -250,23 +244,23 @@ nv50_instmem_takedown(struct drm_device *dev)
250 244
251 dev_priv->ramin_available = false; 245 dev_priv->ramin_available = false;
252 246
253 /* Restore state from before init */ 247 nouveau_vm_ref(NULL, &dev_priv->chan_vm, NULL);
248
254 for (i = 0x1700; i <= 0x1710; i += 4) 249 for (i = 0x1700; i <= 0x1710; i += 4)
255 nv_wr32(dev, i, priv->save1700[(i - 0x1700) / 4]); 250 nv_wr32(dev, i, priv->save1700[(i - 0x1700) / 4]);
256 251
257 nouveau_gpuobj_ref(NULL, &priv->fb_bar); 252 nouveau_gpuobj_ref(NULL, &priv->bar3_dmaobj);
258 nouveau_gpuobj_ref(NULL, &priv->pramin_bar); 253 nouveau_gpuobj_ref(NULL, &priv->bar1_dmaobj);
259 nouveau_gpuobj_ref(NULL, &priv->pramin_pt);
260 254
261 /* Destroy dummy channel */ 255 nouveau_vm_ref(NULL, &dev_priv->bar1_vm, chan->vm_pd);
262 if (chan) { 256 dev_priv->channels.ptr[127] = 0;
263 for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) 257 nv50_channel_del(&dev_priv->channels.ptr[0]);
264 nouveau_gpuobj_ref(NULL, &chan->vm_vram_pt[i]);
265 dev_priv->vm_vram_pt_nr = 0;
266 258
267 nv50_channel_del(&dev_priv->fifos[0]); 259 nouveau_gpuobj_ref(NULL, &dev_priv->bar3_vm->pgt[0].obj[0]);
268 dev_priv->fifos[127] = NULL; 260 nouveau_vm_ref(NULL, &dev_priv->bar3_vm, NULL);
269 } 261
262 if (dev_priv->ramin_heap.free_stack.next)
263 drm_mm_takedown(&dev_priv->ramin_heap);
270 264
271 dev_priv->engine.instmem.priv = NULL; 265 dev_priv->engine.instmem.priv = NULL;
272 kfree(priv); 266 kfree(priv);
@@ -276,16 +270,8 @@ int
276nv50_instmem_suspend(struct drm_device *dev) 270nv50_instmem_suspend(struct drm_device *dev)
277{ 271{
278 struct drm_nouveau_private *dev_priv = dev->dev_private; 272 struct drm_nouveau_private *dev_priv = dev->dev_private;
279 struct nouveau_channel *chan = dev_priv->fifos[0];
280 struct nouveau_gpuobj *ramin = chan->ramin;
281 int i;
282 273
283 ramin->im_backing_suspend = vmalloc(ramin->size); 274 dev_priv->ramin_available = false;
284 if (!ramin->im_backing_suspend)
285 return -ENOMEM;
286
287 for (i = 0; i < ramin->size; i += 4)
288 ramin->im_backing_suspend[i/4] = nv_ri32(dev, i);
289 return 0; 275 return 0;
290} 276}
291 277
@@ -294,146 +280,121 @@ nv50_instmem_resume(struct drm_device *dev)
294{ 280{
295 struct drm_nouveau_private *dev_priv = dev->dev_private; 281 struct drm_nouveau_private *dev_priv = dev->dev_private;
296 struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; 282 struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv;
297 struct nouveau_channel *chan = dev_priv->fifos[0]; 283 struct nouveau_channel *chan = dev_priv->channels.ptr[0];
298 struct nouveau_gpuobj *ramin = chan->ramin;
299 int i; 284 int i;
300 285
301 dev_priv->ramin_available = false;
302 dev_priv->ramin_base = ~0;
303 for (i = 0; i < ramin->size; i += 4)
304 nv_wo32(ramin, i, ramin->im_backing_suspend[i/4]);
305 dev_priv->ramin_available = true;
306 vfree(ramin->im_backing_suspend);
307 ramin->im_backing_suspend = NULL;
308
309 /* Poke the relevant regs, and pray it works :) */ 286 /* Poke the relevant regs, and pray it works :) */
310 nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->vinst >> 12)); 287 nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->vinst >> 12));
311 nv_wr32(dev, NV50_PUNK_UNK1710, 0); 288 nv_wr32(dev, NV50_PUNK_UNK1710, 0);
312 nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->vinst >> 12) | 289 nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->vinst >> 12) |
313 NV50_PUNK_BAR_CFG_BASE_VALID); 290 NV50_PUNK_BAR_CFG_BASE_VALID);
314 nv_wr32(dev, NV50_PUNK_BAR1_CTXDMA, (priv->fb_bar->cinst >> 4) | 291 nv_wr32(dev, NV50_PUNK_BAR1_CTXDMA, (priv->bar1_dmaobj->cinst >> 4) |
315 NV50_PUNK_BAR1_CTXDMA_VALID); 292 NV50_PUNK_BAR1_CTXDMA_VALID);
316 nv_wr32(dev, NV50_PUNK_BAR3_CTXDMA, (priv->pramin_bar->cinst >> 4) | 293 nv_wr32(dev, NV50_PUNK_BAR3_CTXDMA, (priv->bar3_dmaobj->cinst >> 4) |
317 NV50_PUNK_BAR3_CTXDMA_VALID); 294 NV50_PUNK_BAR3_CTXDMA_VALID);
318 295
319 for (i = 0; i < 8; i++) 296 for (i = 0; i < 8; i++)
320 nv_wr32(dev, 0x1900 + (i*4), 0); 297 nv_wr32(dev, 0x1900 + (i*4), 0);
298
299 dev_priv->ramin_available = true;
321} 300}
322 301
302struct nv50_gpuobj_node {
303 struct nouveau_vram *vram;
304 struct nouveau_vma chan_vma;
305 u32 align;
306};
307
308
323int 309int
324nv50_instmem_populate(struct drm_device *dev, struct nouveau_gpuobj *gpuobj, 310nv50_instmem_get(struct nouveau_gpuobj *gpuobj, u32 size, u32 align)
325 uint32_t *sz)
326{ 311{
312 struct drm_device *dev = gpuobj->dev;
313 struct drm_nouveau_private *dev_priv = dev->dev_private;
314 struct nouveau_vram_engine *vram = &dev_priv->engine.vram;
315 struct nv50_gpuobj_node *node = NULL;
327 int ret; 316 int ret;
328 317
329 if (gpuobj->im_backing) 318 node = kzalloc(sizeof(*node), GFP_KERNEL);
330 return -EINVAL; 319 if (!node)
320 return -ENOMEM;
321 node->align = align;
331 322
332 *sz = ALIGN(*sz, 4096); 323 size = (size + 4095) & ~4095;
333 if (*sz == 0) 324 align = max(align, (u32)4096);
334 return -EINVAL;
335 325
336 ret = nouveau_bo_new(dev, NULL, *sz, 0, TTM_PL_FLAG_VRAM, 0, 0x0000, 326 ret = vram->get(dev, size, align, 0, 0, &node->vram);
337 true, false, &gpuobj->im_backing);
338 if (ret) { 327 if (ret) {
339 NV_ERROR(dev, "error getting PRAMIN backing pages: %d\n", ret); 328 kfree(node);
340 return ret; 329 return ret;
341 } 330 }
342 331
343 ret = nouveau_bo_pin(gpuobj->im_backing, TTM_PL_FLAG_VRAM); 332 gpuobj->vinst = node->vram->offset;
344 if (ret) { 333
345 NV_ERROR(dev, "error pinning PRAMIN backing VRAM: %d\n", ret); 334 if (gpuobj->flags & NVOBJ_FLAG_VM) {
346 nouveau_bo_ref(NULL, &gpuobj->im_backing); 335 ret = nouveau_vm_get(dev_priv->chan_vm, size, 12,
347 return ret; 336 NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS,
337 &node->chan_vma);
338 if (ret) {
339 vram->put(dev, &node->vram);
340 kfree(node);
341 return ret;
342 }
343
344 nouveau_vm_map(&node->chan_vma, node->vram);
345 gpuobj->vinst = node->chan_vma.offset;
348 } 346 }
349 347
350 gpuobj->vinst = gpuobj->im_backing->bo.mem.start << PAGE_SHIFT; 348 gpuobj->size = size;
349 gpuobj->node = node;
351 return 0; 350 return 0;
352} 351}
353 352
354void 353void
355nv50_instmem_clear(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) 354nv50_instmem_put(struct nouveau_gpuobj *gpuobj)
356{ 355{
356 struct drm_device *dev = gpuobj->dev;
357 struct drm_nouveau_private *dev_priv = dev->dev_private; 357 struct drm_nouveau_private *dev_priv = dev->dev_private;
358 struct nouveau_vram_engine *vram = &dev_priv->engine.vram;
359 struct nv50_gpuobj_node *node;
360
361 node = gpuobj->node;
362 gpuobj->node = NULL;
358 363
359 if (gpuobj && gpuobj->im_backing) { 364 if (node->chan_vma.node) {
360 if (gpuobj->im_bound) 365 nouveau_vm_unmap(&node->chan_vma);
361 dev_priv->engine.instmem.unbind(dev, gpuobj); 366 nouveau_vm_put(&node->chan_vma);
362 nouveau_bo_unpin(gpuobj->im_backing);
363 nouveau_bo_ref(NULL, &gpuobj->im_backing);
364 gpuobj->im_backing = NULL;
365 } 367 }
368 vram->put(dev, &node->vram);
369 kfree(node);
366} 370}
367 371
368int 372int
369nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) 373nv50_instmem_map(struct nouveau_gpuobj *gpuobj)
370{ 374{
371 struct drm_nouveau_private *dev_priv = dev->dev_private; 375 struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private;
372 struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; 376 struct nv50_gpuobj_node *node = gpuobj->node;
373 struct nouveau_gpuobj *pramin_pt = priv->pramin_pt; 377 int ret;
374 uint32_t pte, pte_end;
375 uint64_t vram;
376
377 if (!gpuobj->im_backing || !gpuobj->im_pramin || gpuobj->im_bound)
378 return -EINVAL;
379
380 NV_DEBUG(dev, "st=0x%lx sz=0x%lx\n",
381 gpuobj->im_pramin->start, gpuobj->im_pramin->size);
382
383 pte = (gpuobj->im_pramin->start >> 12) << 1;
384 pte_end = ((gpuobj->im_pramin->size >> 12) << 1) + pte;
385 vram = gpuobj->vinst;
386
387 NV_DEBUG(dev, "pramin=0x%lx, pte=%d, pte_end=%d\n",
388 gpuobj->im_pramin->start, pte, pte_end);
389 NV_DEBUG(dev, "first vram page: 0x%010llx\n", gpuobj->vinst);
390
391 vram |= 1;
392 if (dev_priv->vram_sys_base) {
393 vram += dev_priv->vram_sys_base;
394 vram |= 0x30;
395 }
396
397 while (pte < pte_end) {
398 nv_wo32(pramin_pt, (pte * 4) + 0, lower_32_bits(vram));
399 nv_wo32(pramin_pt, (pte * 4) + 4, upper_32_bits(vram));
400 vram += 0x1000;
401 pte += 2;
402 }
403 dev_priv->engine.instmem.flush(dev);
404 378
405 nv50_vm_flush(dev, 6); 379 ret = nouveau_vm_get(dev_priv->bar3_vm, gpuobj->size, 12,
380 NV_MEM_ACCESS_RW, &node->vram->bar_vma);
381 if (ret)
382 return ret;
406 383
407 gpuobj->im_bound = 1; 384 nouveau_vm_map(&node->vram->bar_vma, node->vram);
385 gpuobj->pinst = node->vram->bar_vma.offset;
408 return 0; 386 return 0;
409} 387}
410 388
411int 389void
412nv50_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) 390nv50_instmem_unmap(struct nouveau_gpuobj *gpuobj)
413{ 391{
414 struct drm_nouveau_private *dev_priv = dev->dev_private; 392 struct nv50_gpuobj_node *node = gpuobj->node;
415 struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv;
416 uint32_t pte, pte_end;
417
418 if (gpuobj->im_bound == 0)
419 return -EINVAL;
420
421 /* can happen during late takedown */
422 if (unlikely(!dev_priv->ramin_available))
423 return 0;
424 393
425 pte = (gpuobj->im_pramin->start >> 12) << 1; 394 if (node->vram->bar_vma.node) {
426 pte_end = ((gpuobj->im_pramin->size >> 12) << 1) + pte; 395 nouveau_vm_unmap(&node->vram->bar_vma);
427 396 nouveau_vm_put(&node->vram->bar_vma);
428 while (pte < pte_end) {
429 nv_wo32(priv->pramin_pt, (pte * 4) + 0, 0x00000000);
430 nv_wo32(priv->pramin_pt, (pte * 4) + 4, 0x00000000);
431 pte += 2;
432 } 397 }
433 dev_priv->engine.instmem.flush(dev);
434
435 gpuobj->im_bound = 0;
436 return 0;
437} 398}
438 399
439void 400void
@@ -452,11 +413,3 @@ nv84_instmem_flush(struct drm_device *dev)
452 NV_ERROR(dev, "PRAMIN flush timeout\n"); 413 NV_ERROR(dev, "PRAMIN flush timeout\n");
453} 414}
454 415
455void
456nv50_vm_flush(struct drm_device *dev, int engine)
457{
458 nv_wr32(dev, 0x100c80, (engine << 16) | 1);
459 if (!nv_wait(dev, 0x100c80, 0x00000001, 0x00000000))
460 NV_ERROR(dev, "vm flush timeout: engine %d\n", engine);
461}
462