aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2010-11-14 20:53:16 -0500
committerBen Skeggs <bskeggs@redhat.com>2010-12-07 22:48:12 -0500
commitf869ef882382a4b6cb42d259e399aeec3781d4bb (patch)
tree64c15a801acc45528fcc150becd797612acdd0fb /drivers/gpu/drm
parenta11c3198c9ba38d81e25b65e3908d531feba1372 (diff)
drm/nv50: implement BAR1/BAR3 management on top of new VM code
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c46
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h10
-rw-r--r--drivers/gpu/drm/nouveau/nv50_instmem.c258
-rw-r--r--drivers/gpu/drm/nouveau/nv50_vm.c1
4 files changed, 162 insertions, 153 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 5a71ca4346c8..4d142031d542 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -32,6 +32,8 @@
32#include "nouveau_drm.h" 32#include "nouveau_drm.h"
33#include "nouveau_drv.h" 33#include "nouveau_drv.h"
34#include "nouveau_dma.h" 34#include "nouveau_dma.h"
35#include "nouveau_mm.h"
36#include "nouveau_vm.h"
35 37
36#include <linux/log2.h> 38#include <linux/log2.h>
37#include <linux/slab.h> 39#include <linux/slab.h>
@@ -386,10 +388,13 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
386 man->default_caching = TTM_PL_FLAG_CACHED; 388 man->default_caching = TTM_PL_FLAG_CACHED;
387 break; 389 break;
388 case TTM_PL_VRAM: 390 case TTM_PL_VRAM:
389 if (dev_priv->card_type == NV_50) 391 if (dev_priv->card_type == NV_50) {
390 man->func = &nouveau_vram_manager; 392 man->func = &nouveau_vram_manager;
391 else 393 man->io_reserve_fastpath = false;
394 man->use_io_reserve_lru = true;
395 } else {
392 man->func = &ttm_bo_manager_func; 396 man->func = &ttm_bo_manager_func;
397 }
393 man->flags = TTM_MEMTYPE_FLAG_FIXED | 398 man->flags = TTM_MEMTYPE_FLAG_FIXED |
394 TTM_MEMTYPE_FLAG_MAPPABLE; 399 TTM_MEMTYPE_FLAG_MAPPABLE;
395 man->available_caching = TTM_PL_FLAG_UNCACHED | 400 man->available_caching = TTM_PL_FLAG_UNCACHED |
@@ -858,6 +863,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
858 struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; 863 struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
859 struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev); 864 struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev);
860 struct drm_device *dev = dev_priv->dev; 865 struct drm_device *dev = dev_priv->dev;
866 int ret;
861 867
862 mem->bus.addr = NULL; 868 mem->bus.addr = NULL;
863 mem->bus.offset = 0; 869 mem->bus.offset = 0;
@@ -880,9 +886,32 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
880#endif 886#endif
881 break; 887 break;
882 case TTM_PL_VRAM: 888 case TTM_PL_VRAM:
883 mem->bus.offset = mem->start << PAGE_SHIFT; 889 {
890 struct nouveau_vram *vram = mem->mm_node;
891
892 if (!dev_priv->bar1_vm) {
893 mem->bus.offset = mem->start << PAGE_SHIFT;
894 mem->bus.base = pci_resource_start(dev->pdev, 1);
895 mem->bus.is_iomem = true;
896 break;
897 }
898
899 ret = nouveau_vm_get(dev_priv->bar1_vm, mem->bus.size, 12,
900 NV_MEM_ACCESS_RW, &vram->bar_vma);
901 if (ret)
902 return ret;
903
904 nouveau_vm_map(&vram->bar_vma, vram);
905 if (ret) {
906 nouveau_vm_put(&vram->bar_vma);
907 return ret;
908 }
909
910 mem->bus.offset = vram->bar_vma.offset;
911 mem->bus.offset -= 0x0020000000ULL;
884 mem->bus.base = pci_resource_start(dev->pdev, 1); 912 mem->bus.base = pci_resource_start(dev->pdev, 1);
885 mem->bus.is_iomem = true; 913 mem->bus.is_iomem = true;
914 }
886 break; 915 break;
887 default: 916 default:
888 return -EINVAL; 917 return -EINVAL;
@@ -893,6 +922,17 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
893static void 922static void
894nouveau_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) 923nouveau_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
895{ 924{
925 struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev);
926 struct nouveau_vram *vram = mem->mm_node;
927
928 if (!dev_priv->bar1_vm || mem->mem_type != TTM_PL_VRAM)
929 return;
930
931 if (!vram->bar_vma.node)
932 return;
933
934 nouveau_vm_unmap(&vram->bar_vma);
935 nouveau_vm_put(&vram->bar_vma);
896} 936}
897 937
898static int 938static int
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index ce1dde4a65d6..452a8652a498 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -55,7 +55,10 @@ struct nouveau_fpriv {
55#include "nouveau_reg.h" 55#include "nouveau_reg.h"
56#include "nouveau_bios.h" 56#include "nouveau_bios.h"
57#include "nouveau_util.h" 57#include "nouveau_util.h"
58
58struct nouveau_grctx; 59struct nouveau_grctx;
60struct nouveau_vram;
61#include "nouveau_vm.h"
59 62
60#define MAX_NUM_DCB_ENTRIES 16 63#define MAX_NUM_DCB_ENTRIES 16
61 64
@@ -69,6 +72,8 @@ struct nouveau_grctx;
69struct nouveau_vram { 72struct nouveau_vram {
70 struct drm_device *dev; 73 struct drm_device *dev;
71 74
75 struct nouveau_vma bar_vma;
76
72 struct list_head regions; 77 struct list_head regions;
73 u32 memtype; 78 u32 memtype;
74 u64 offset; 79 u64 offset;
@@ -244,6 +249,7 @@ struct nouveau_channel {
244 void *pgraph_ctx; 249 void *pgraph_ctx;
245 250
246 /* NV50 VM */ 251 /* NV50 VM */
252 struct nouveau_vm *vm;
247 struct nouveau_gpuobj *vm_pd; 253 struct nouveau_gpuobj *vm_pd;
248 struct nouveau_gpuobj *vm_gart_pt; 254 struct nouveau_gpuobj *vm_gart_pt;
249 struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR]; 255 struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR];
@@ -701,6 +707,10 @@ struct drm_nouveau_private {
701 uint64_t fb_aper_free; 707 uint64_t fb_aper_free;
702 int fb_mtrr; 708 int fb_mtrr;
703 709
710 /* BAR control (NV50-) */
711 struct nouveau_vm *bar1_vm;
712 struct nouveau_vm *bar3_vm;
713
704 /* G8x/G9x virtual address space */ 714 /* G8x/G9x virtual address space */
705 uint64_t vm_gart_base; 715 uint64_t vm_gart_base;
706 uint64_t vm_gart_size; 716 uint64_t vm_gart_size;
diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c
index 4eb2f0835e27..4ba8f74e77b1 100644
--- a/drivers/gpu/drm/nouveau/nv50_instmem.c
+++ b/drivers/gpu/drm/nouveau/nv50_instmem.c
@@ -31,12 +31,16 @@
31#include "nouveau_drv.h" 31#include "nouveau_drv.h"
32#include "nouveau_vm.h" 32#include "nouveau_vm.h"
33 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)
38
34struct nv50_instmem_priv { 39struct nv50_instmem_priv {
35 uint32_t save1700[5]; /* 0x1700->0x1710 */ 40 uint32_t save1700[5]; /* 0x1700->0x1710 */
36 41
37 struct nouveau_gpuobj *pramin_pt; 42 struct nouveau_gpuobj *bar1_dmaobj;
38 struct nouveau_gpuobj *pramin_bar; 43 struct nouveau_gpuobj *bar3_dmaobj;
39 struct nouveau_gpuobj *fb_bar;
40}; 44};
41 45
42static void 46static void
@@ -50,6 +54,7 @@ nv50_channel_del(struct nouveau_channel **pchan)
50 return; 54 return;
51 55
52 nouveau_gpuobj_ref(NULL, &chan->ramfc); 56 nouveau_gpuobj_ref(NULL, &chan->ramfc);
57 nouveau_vm_ref(NULL, &chan->vm, chan->vm_pd);
53 nouveau_gpuobj_ref(NULL, &chan->vm_pd); 58 nouveau_gpuobj_ref(NULL, &chan->vm_pd);
54 if (chan->ramin_heap.free_stack.next) 59 if (chan->ramin_heap.free_stack.next)
55 drm_mm_takedown(&chan->ramin_heap); 60 drm_mm_takedown(&chan->ramin_heap);
@@ -58,14 +63,14 @@ nv50_channel_del(struct nouveau_channel **pchan)
58} 63}
59 64
60static int 65static int
61nv50_channel_new(struct drm_device *dev, u32 size, 66nv50_channel_new(struct drm_device *dev, u32 size, struct nouveau_vm *vm,
62 struct nouveau_channel **pchan) 67 struct nouveau_channel **pchan)
63{ 68{
64 struct drm_nouveau_private *dev_priv = dev->dev_private; 69 struct drm_nouveau_private *dev_priv = dev->dev_private;
65 u32 pgd = (dev_priv->chipset == 0x50) ? 0x1400 : 0x0200; 70 u32 pgd = (dev_priv->chipset == 0x50) ? 0x1400 : 0x0200;
66 u32 fc = (dev_priv->chipset == 0x50) ? 0x0000 : 0x4200; 71 u32 fc = (dev_priv->chipset == 0x50) ? 0x0000 : 0x4200;
67 struct nouveau_channel *chan; 72 struct nouveau_channel *chan;
68 int ret; 73 int ret, i;
69 74
70 chan = kzalloc(sizeof(*chan), GFP_KERNEL); 75 chan = kzalloc(sizeof(*chan), GFP_KERNEL);
71 if (!chan) 76 if (!chan)
@@ -94,6 +99,17 @@ nv50_channel_new(struct drm_device *dev, u32 size,
94 return ret; 99 return ret;
95 } 100 }
96 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
97 ret = nouveau_gpuobj_new_fake(dev, chan->ramin->pinst == ~0 ? ~0 : 113 ret = nouveau_gpuobj_new_fake(dev, chan->ramin->pinst == ~0 ? ~0 :
98 chan->ramin->pinst + fc, 114 chan->ramin->pinst + fc,
99 chan->ramin->vinst + fc, 0x100, 115 chan->ramin->vinst + fc, 0x100,
@@ -113,6 +129,7 @@ nv50_instmem_init(struct drm_device *dev)
113 struct drm_nouveau_private *dev_priv = dev->dev_private; 129 struct drm_nouveau_private *dev_priv = dev->dev_private;
114 struct nv50_instmem_priv *priv; 130 struct nv50_instmem_priv *priv;
115 struct nouveau_channel *chan; 131 struct nouveau_channel *chan;
132 struct nouveau_vm *vm;
116 int ret, i; 133 int ret, i;
117 u32 tmp; 134 u32 tmp;
118 135
@@ -129,53 +146,75 @@ nv50_instmem_init(struct drm_device *dev)
129 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);
130 if (ret) { 147 if (ret) {
131 NV_ERROR(dev, "Failed to init RAMIN heap\n"); 148 NV_ERROR(dev, "Failed to init RAMIN heap\n");
132 return -ENOMEM; 149 goto error;
133 } 150 }
134 151
135 /* we need a channel to plug into the hw to control the BARs */ 152 /* BAR3 */
136 ret = nv50_channel_new(dev, 128*1024, &dev_priv->channels.ptr[0]); 153 ret = nouveau_vm_new(dev, BAR3_VM_BASE, BAR3_VM_SIZE, BAR3_VM_BASE,
154 29, 12, 16, &dev_priv->bar3_vm);
137 if (ret) 155 if (ret)
138 return ret; 156 goto error;
139 chan = dev_priv->channels.ptr[127] = dev_priv->channels.ptr[0];
140 157
141 /* allocate page table for PRAMIN BAR */ 158 ret = nouveau_gpuobj_new(dev, NULL, (BAR3_VM_SIZE >> 12) * 8,
142 ret = nouveau_gpuobj_new(dev, chan, (dev_priv->ramin_size >> 12) * 8, 159 0x1000, NVOBJ_FLAG_DONT_MAP |
143 0x1000, NVOBJ_FLAG_ZERO_ALLOC, 160 NVOBJ_FLAG_ZERO_ALLOC,
144 &priv->pramin_pt); 161 &dev_priv->bar3_vm->pgt[0].obj);
145 if (ret) 162 if (ret)
146 return ret; 163 goto error;
164 dev_priv->bar3_vm->pgt[0].page_shift = 12;
165 dev_priv->bar3_vm->pgt[0].refcount = 1;
147 166
148 nv_wo32(chan->vm_pd, 0x0000, priv->pramin_pt->vinst | 0x63); 167 nv50_instmem_map(dev_priv->bar3_vm->pgt[0].obj);
149 nv_wo32(chan->vm_pd, 0x0004, 0);
150 168
151 /* DMA object for PRAMIN BAR */ 169 ret = nv50_channel_new(dev, 128 * 1024, dev_priv->bar3_vm, &chan);
152 ret = nouveau_gpuobj_new(dev, chan, 6*4, 16, 0, &priv->pramin_bar);
153 if (ret) 170 if (ret)
154 return ret; 171 goto error;
155 nv_wo32(priv->pramin_bar, 0x00, 0x7fc00000); 172 dev_priv->channels.ptr[0] = dev_priv->channels.ptr[127] = chan;
156 nv_wo32(priv->pramin_bar, 0x04, dev_priv->ramin_size - 1);
157 nv_wo32(priv->pramin_bar, 0x08, 0x00000000);
158 nv_wo32(priv->pramin_bar, 0x0c, 0x00000000);
159 nv_wo32(priv->pramin_bar, 0x10, 0x00000000);
160 nv_wo32(priv->pramin_bar, 0x14, 0x00000000);
161 173
162 nv50_instmem_map(chan->ramin); 174 ret = nv50_gpuobj_dma_new(chan, 0x0000, BAR3_VM_BASE, BAR3_VM_SIZE,
175 NV_MEM_TARGET_VM, NV_MEM_ACCESS_VM,
176 NV_MEM_TYPE_VM, NV_MEM_COMP_VM,
177 &priv->bar3_dmaobj);
178 if (ret)
179 goto error;
163 180
164 /* poke regs... */
165 nv_wr32(dev, 0x001704, 0x00000000 | (chan->ramin->vinst >> 12)); 181 nv_wr32(dev, 0x001704, 0x00000000 | (chan->ramin->vinst >> 12));
166 nv_wr32(dev, 0x001704, 0x40000000 | (chan->ramin->vinst >> 12)); 182 nv_wr32(dev, 0x001704, 0x40000000 | (chan->ramin->vinst >> 12));
167 nv_wr32(dev, 0x00170c, 0x80000000 | (priv->pramin_bar->cinst >> 4)); 183 nv_wr32(dev, 0x00170c, 0x80000000 | (priv->bar3_dmaobj->cinst >> 4));
168 184
169 tmp = nv_ri32(dev, 0); 185 tmp = nv_ri32(dev, 0);
170 nv_wi32(dev, 0, ~tmp); 186 nv_wi32(dev, 0, ~tmp);
171 if (nv_ri32(dev, 0) != ~tmp) { 187 if (nv_ri32(dev, 0) != ~tmp) {
172 NV_ERROR(dev, "PRAMIN readback failed\n"); 188 NV_ERROR(dev, "PRAMIN readback failed\n");
173 return -EIO; 189 ret = -EIO;
190 goto error;
174 } 191 }
175 nv_wi32(dev, 0, tmp); 192 nv_wi32(dev, 0, tmp);
176 193
177 dev_priv->ramin_available = true; 194 dev_priv->ramin_available = true;
178 195
196 /* BAR1 */
197 ret = nouveau_vm_new(dev, BAR1_VM_BASE, BAR1_VM_SIZE, BAR1_VM_BASE,
198 29, 12, 16, &vm);
199 if (ret)
200 goto error;
201
202 ret = nouveau_vm_ref(vm, &dev_priv->bar1_vm, chan->vm_pd);
203 if (ret)
204 goto error;
205 nouveau_vm_ref(NULL, &vm, NULL);
206
207 ret = nv50_gpuobj_dma_new(chan, 0x0000, BAR1_VM_BASE, BAR1_VM_SIZE,
208 NV_MEM_TARGET_VM, NV_MEM_ACCESS_VM,
209 NV_MEM_TYPE_VM, NV_MEM_COMP_VM,
210 &priv->bar1_dmaobj);
211 if (ret)
212 goto error;
213
214 nv_wr32(dev, 0x001708, 0x80000000 | (priv->bar1_dmaobj->cinst >> 4));
215 for (i = 0; i < 8; i++)
216 nv_wr32(dev, 0x1900 + (i*4), 0);
217
179 /* Determine VM layout */ 218 /* Determine VM layout */
180 dev_priv->vm_gart_base = roundup(NV50_VM_BLOCK, NV50_VM_BLOCK); 219 dev_priv->vm_gart_base = roundup(NV50_VM_BLOCK, NV50_VM_BLOCK);
181 dev_priv->vm_gart_size = NV50_VM_BLOCK; 220 dev_priv->vm_gart_size = NV50_VM_BLOCK;
@@ -200,38 +239,19 @@ nv50_instmem_init(struct drm_device *dev)
200 for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) { 239 for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) {
201 ret = nouveau_gpuobj_new(dev, NULL, NV50_VM_BLOCK / 0x10000 * 8, 240 ret = nouveau_gpuobj_new(dev, NULL, NV50_VM_BLOCK / 0x10000 * 8,
202 0, NVOBJ_FLAG_ZERO_ALLOC, 241 0, NVOBJ_FLAG_ZERO_ALLOC,
203 &chan->vm_vram_pt[i]); 242 &dev_priv->vm_vram_pt[i]);
204 if (ret) { 243 if (ret) {
205 NV_ERROR(dev, "Error creating VRAM PGT: %d\n", ret); 244 NV_ERROR(dev, "Error creating VRAM PGT: %d\n", ret);
206 dev_priv->vm_vram_pt_nr = i; 245 dev_priv->vm_vram_pt_nr = i;
207 return ret; 246 return ret;
208 } 247 }
209 dev_priv->vm_vram_pt[i] = chan->vm_vram_pt[i];
210
211 nv_wo32(chan->vm_pd, 0x10 + (i*8),
212 chan->vm_vram_pt[i]->vinst | 0x61);
213 nv_wo32(chan->vm_pd, 0x14 + (i*8), 0);
214 } 248 }
215 249
216 /* DMA object for FB BAR */
217 ret = nouveau_gpuobj_new(dev, chan, 6*4, 16, 0, &priv->fb_bar);
218 if (ret)
219 return ret;
220 nv_wo32(priv->fb_bar, 0x00, 0x7fc00000);
221 nv_wo32(priv->fb_bar, 0x04, 0x40000000 +
222 pci_resource_len(dev->pdev, 1) - 1);
223 nv_wo32(priv->fb_bar, 0x08, 0x40000000);
224 nv_wo32(priv->fb_bar, 0x0c, 0x00000000);
225 nv_wo32(priv->fb_bar, 0x10, 0x00000000);
226 nv_wo32(priv->fb_bar, 0x14, 0x00000000);
227
228 dev_priv->engine.instmem.flush(dev);
229
230 nv_wr32(dev, 0x001708, 0x80000000 | (priv->fb_bar->cinst >> 4));
231 for (i = 0; i < 8; i++)
232 nv_wr32(dev, 0x1900 + (i*4), 0);
233
234 return 0; 250 return 0;
251
252error:
253 nv50_instmem_takedown(dev);
254 return ret;
235} 255}
236 256
237void 257void
@@ -249,23 +269,25 @@ nv50_instmem_takedown(struct drm_device *dev)
249 269
250 dev_priv->ramin_available = false; 270 dev_priv->ramin_available = false;
251 271
252 /* Restore state from before init */ 272 for (i = 0; i < dev_priv->vm_vram_pt_nr; i++)
273 nouveau_gpuobj_ref(NULL, &dev_priv->vm_vram_pt[i]);
274 dev_priv->vm_vram_pt_nr = 0;
275
253 for (i = 0x1700; i <= 0x1710; i += 4) 276 for (i = 0x1700; i <= 0x1710; i += 4)
254 nv_wr32(dev, i, priv->save1700[(i - 0x1700) / 4]); 277 nv_wr32(dev, i, priv->save1700[(i - 0x1700) / 4]);
255 278
256 nouveau_gpuobj_ref(NULL, &priv->fb_bar); 279 nouveau_gpuobj_ref(NULL, &priv->bar3_dmaobj);
257 nouveau_gpuobj_ref(NULL, &priv->pramin_bar); 280 nouveau_gpuobj_ref(NULL, &priv->bar1_dmaobj);
258 nouveau_gpuobj_ref(NULL, &priv->pramin_pt);
259 281
260 /* Destroy dummy channel */ 282 nouveau_vm_ref(NULL, &dev_priv->bar1_vm, chan->vm_pd);
261 if (chan) { 283 dev_priv->channels.ptr[127] = 0;
262 for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) 284 nv50_channel_del(&dev_priv->channels.ptr[0]);
263 nouveau_gpuobj_ref(NULL, &chan->vm_vram_pt[i]);
264 dev_priv->vm_vram_pt_nr = 0;
265 285
266 nv50_channel_del(&dev_priv->channels.ptr[0]); 286 nouveau_gpuobj_ref(NULL, &dev_priv->bar3_vm->pgt[0].obj);
267 dev_priv->channels.ptr[127] = NULL; 287 nouveau_vm_ref(NULL, &dev_priv->bar3_vm, NULL);
268 } 288
289 if (dev_priv->ramin_heap.free_stack.next)
290 drm_mm_takedown(&dev_priv->ramin_heap);
269 291
270 dev_priv->engine.instmem.priv = NULL; 292 dev_priv->engine.instmem.priv = NULL;
271 kfree(priv); 293 kfree(priv);
@@ -293,9 +315,9 @@ nv50_instmem_resume(struct drm_device *dev)
293 nv_wr32(dev, NV50_PUNK_UNK1710, 0); 315 nv_wr32(dev, NV50_PUNK_UNK1710, 0);
294 nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->vinst >> 12) | 316 nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->vinst >> 12) |
295 NV50_PUNK_BAR_CFG_BASE_VALID); 317 NV50_PUNK_BAR_CFG_BASE_VALID);
296 nv_wr32(dev, NV50_PUNK_BAR1_CTXDMA, (priv->fb_bar->cinst >> 4) | 318 nv_wr32(dev, NV50_PUNK_BAR1_CTXDMA, (priv->bar1_dmaobj->cinst >> 4) |
297 NV50_PUNK_BAR1_CTXDMA_VALID); 319 NV50_PUNK_BAR1_CTXDMA_VALID);
298 nv_wr32(dev, NV50_PUNK_BAR3_CTXDMA, (priv->pramin_bar->cinst >> 4) | 320 nv_wr32(dev, NV50_PUNK_BAR3_CTXDMA, (priv->bar3_dmaobj->cinst >> 4) |
299 NV50_PUNK_BAR3_CTXDMA_VALID); 321 NV50_PUNK_BAR3_CTXDMA_VALID);
300 322
301 for (i = 0; i < 8; i++) 323 for (i = 0; i < 8; i++)
@@ -305,8 +327,7 @@ nv50_instmem_resume(struct drm_device *dev)
305} 327}
306 328
307struct nv50_gpuobj_node { 329struct nv50_gpuobj_node {
308 struct nouveau_bo *vram; 330 struct nouveau_vram *vram;
309 struct drm_mm_node *ramin;
310 u32 align; 331 u32 align;
311}; 332};
312 333
@@ -323,23 +344,17 @@ nv50_instmem_get(struct nouveau_gpuobj *gpuobj, u32 size, u32 align)
323 return -ENOMEM; 344 return -ENOMEM;
324 node->align = align; 345 node->align = align;
325 346
326 ret = nouveau_bo_new(dev, NULL, size, align, TTM_PL_FLAG_VRAM, 347 size = (size + 4095) & ~4095;
327 0, 0x0000, true, false, &node->vram); 348 align = max(align, (u32)4096);
328 if (ret) {
329 NV_ERROR(dev, "error getting PRAMIN backing pages: %d\n", ret);
330 WARN_ON(1);
331 return ret;
332 }
333 349
334 ret = nouveau_bo_pin(node->vram, TTM_PL_FLAG_VRAM); 350 ret = nv50_vram_new(dev, size, align, 0, 0, &node->vram);
335 if (ret) { 351 if (ret) {
336 NV_ERROR(dev, "error pinning PRAMIN backing VRAM: %d\n", ret); 352 kfree(node);
337 nouveau_bo_ref(NULL, &node->vram);
338 return ret; 353 return ret;
339 } 354 }
340 355
341 gpuobj->vinst = node->vram->bo.mem.start << PAGE_SHIFT; 356 gpuobj->vinst = node->vram->offset;
342 gpuobj->size = node->vram->bo.mem.num_pages << PAGE_SHIFT; 357 gpuobj->size = size;
343 gpuobj->node = node; 358 gpuobj->node = node;
344 return 0; 359 return 0;
345} 360}
@@ -347,13 +362,13 @@ nv50_instmem_get(struct nouveau_gpuobj *gpuobj, u32 size, u32 align)
347void 362void
348nv50_instmem_put(struct nouveau_gpuobj *gpuobj) 363nv50_instmem_put(struct nouveau_gpuobj *gpuobj)
349{ 364{
365 struct drm_device *dev = gpuobj->dev;
350 struct nv50_gpuobj_node *node; 366 struct nv50_gpuobj_node *node;
351 367
352 node = gpuobj->node; 368 node = gpuobj->node;
353 gpuobj->node = NULL; 369 gpuobj->node = NULL;
354 370
355 nouveau_bo_unpin(node->vram); 371 nv50_vram_del(dev, &node->vram);
356 nouveau_bo_ref(NULL, &node->vram);
357 kfree(node); 372 kfree(node);
358} 373}
359 374
@@ -361,83 +376,28 @@ int
361nv50_instmem_map(struct nouveau_gpuobj *gpuobj) 376nv50_instmem_map(struct nouveau_gpuobj *gpuobj)
362{ 377{
363 struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; 378 struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private;
364 struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv;
365 struct nv50_gpuobj_node *node = gpuobj->node; 379 struct nv50_gpuobj_node *node = gpuobj->node;
366 struct drm_device *dev = gpuobj->dev; 380 int ret;
367 struct drm_mm_node *ramin = NULL;
368 u32 pte, pte_end;
369 u64 vram;
370
371 do {
372 if (drm_mm_pre_get(&dev_priv->ramin_heap))
373 return -ENOMEM;
374
375 spin_lock(&dev_priv->ramin_lock);
376 ramin = drm_mm_search_free(&dev_priv->ramin_heap, gpuobj->size,
377 node->align, 0);
378 if (ramin == NULL) {
379 spin_unlock(&dev_priv->ramin_lock);
380 return -ENOMEM;
381 }
382
383 ramin = drm_mm_get_block_atomic(ramin, gpuobj->size, node->align);
384 spin_unlock(&dev_priv->ramin_lock);
385 } while (ramin == NULL);
386
387 pte = (ramin->start >> 12) << 1;
388 pte_end = ((ramin->size >> 12) << 1) + pte;
389 vram = gpuobj->vinst;
390
391 NV_DEBUG(dev, "pramin=0x%lx, pte=%d, pte_end=%d\n",
392 ramin->start, pte, pte_end);
393 NV_DEBUG(dev, "first vram page: 0x%010llx\n", gpuobj->vinst);
394
395 vram |= 1;
396 if (dev_priv->vram_sys_base) {
397 vram += dev_priv->vram_sys_base;
398 vram |= 0x30;
399 }
400
401 while (pte < pte_end) {
402 nv_wo32(priv->pramin_pt, (pte * 4) + 0, lower_32_bits(vram));
403 nv_wo32(priv->pramin_pt, (pte * 4) + 4, upper_32_bits(vram));
404 vram += 0x1000;
405 pte += 2;
406 }
407 dev_priv->engine.instmem.flush(dev);
408 381
409 nv50_vm_flush_engine(dev, 6); 382 ret = nouveau_vm_get(dev_priv->bar3_vm, gpuobj->size, 12,
383 NV_MEM_ACCESS_RW, &node->vram->bar_vma);
384 if (ret)
385 return ret;
410 386
411 node->ramin = ramin; 387 nouveau_vm_map(&node->vram->bar_vma, node->vram);
412 gpuobj->pinst = ramin->start; 388 gpuobj->pinst = node->vram->bar_vma.offset;
413 return 0; 389 return 0;
414} 390}
415 391
416void 392void
417nv50_instmem_unmap(struct nouveau_gpuobj *gpuobj) 393nv50_instmem_unmap(struct nouveau_gpuobj *gpuobj)
418{ 394{
419 struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private;
420 struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv;
421 struct nv50_gpuobj_node *node = gpuobj->node; 395 struct nv50_gpuobj_node *node = gpuobj->node;
422 u32 pte, pte_end;
423 396
424 if (!node->ramin || !dev_priv->ramin_available) 397 if (node->vram->bar_vma.node) {
425 return; 398 nouveau_vm_unmap(&node->vram->bar_vma);
426 399 nouveau_vm_put(&node->vram->bar_vma);
427 pte = (node->ramin->start >> 12) << 1;
428 pte_end = ((node->ramin->size >> 12) << 1) + pte;
429
430 while (pte < pte_end) {
431 nv_wo32(priv->pramin_pt, (pte * 4) + 0, 0x00000000);
432 nv_wo32(priv->pramin_pt, (pte * 4) + 4, 0x00000000);
433 pte += 2;
434 } 400 }
435 dev_priv->engine.instmem.flush(gpuobj->dev);
436
437 spin_lock(&dev_priv->ramin_lock);
438 drm_mm_put_block(node->ramin);
439 node->ramin = NULL;
440 spin_unlock(&dev_priv->ramin_lock);
441} 401}
442 402
443void 403void
diff --git a/drivers/gpu/drm/nouveau/nv50_vm.c b/drivers/gpu/drm/nouveau/nv50_vm.c
index ab6c3d0ce32e..efc63c0b0d92 100644
--- a/drivers/gpu/drm/nouveau/nv50_vm.c
+++ b/drivers/gpu/drm/nouveau/nv50_vm.c
@@ -151,7 +151,6 @@ nv50_vm_flush(struct nouveau_vm *vm)
151 struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; 151 struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem;
152 152
153 pinstmem->flush(vm->dev); 153 pinstmem->flush(vm->dev);
154
155 nv50_vm_flush_engine(vm->dev, 6); 154 nv50_vm_flush_engine(vm->dev, 6);
156} 155}
157 156