struct nouveau_channel *chan;
struct nouveau_vm *vm;
int ret, i;
- u64 nongart_o;
u32 tmp;
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
/* BAR3 */
ret = nouveau_vm_new(dev, BAR3_VM_BASE, BAR3_VM_SIZE, BAR3_VM_BASE,
- 29, 12, 16, &dev_priv->bar3_vm);
+ &dev_priv->bar3_vm);
if (ret)
goto error;
ret = nouveau_gpuobj_new(dev, NULL, (BAR3_VM_SIZE >> 12) * 8,
0x1000, NVOBJ_FLAG_DONT_MAP |
NVOBJ_FLAG_ZERO_ALLOC,
- &dev_priv->bar3_vm->pgt[0].obj);
+ &dev_priv->bar3_vm->pgt[0].obj[0]);
if (ret)
goto error;
- dev_priv->bar3_vm->pgt[0].page_shift = 12;
- dev_priv->bar3_vm->pgt[0].refcount = 1;
+ dev_priv->bar3_vm->pgt[0].refcount[0] = 1;
- nv50_instmem_map(dev_priv->bar3_vm->pgt[0].obj);
+ nv50_instmem_map(dev_priv->bar3_vm->pgt[0].obj[0]);
ret = nv50_channel_new(dev, 128 * 1024, dev_priv->bar3_vm, &chan);
if (ret)
nv_wr32(dev, 0x001704, 0x40000000 | (chan->ramin->vinst >> 12));
nv_wr32(dev, 0x00170c, 0x80000000 | (priv->bar3_dmaobj->cinst >> 4));
- tmp = nv_ri32(dev, 0);
- nv_wi32(dev, 0, ~tmp);
- if (nv_ri32(dev, 0) != ~tmp) {
+ dev_priv->engine.instmem.flush(dev);
+ dev_priv->ramin_available = true;
+
+ tmp = nv_ro32(chan->ramin, 0);
+ nv_wo32(chan->ramin, 0, ~tmp);
+ if (nv_ro32(chan->ramin, 0) != ~tmp) {
NV_ERROR(dev, "PRAMIN readback failed\n");
ret = -EIO;
goto error;
}
- nv_wi32(dev, 0, tmp);
-
- dev_priv->ramin_available = true;
+ nv_wo32(chan->ramin, 0, tmp);
/* BAR1 */
- ret = nouveau_vm_new(dev, BAR1_VM_BASE, BAR1_VM_SIZE, BAR1_VM_BASE,
- 29, 12, 16, &vm);
+ ret = nouveau_vm_new(dev, BAR1_VM_BASE, BAR1_VM_SIZE, BAR1_VM_BASE, &vm);
if (ret)
goto error;
for (i = 0; i < 8; i++)
nv_wr32(dev, 0x1900 + (i*4), 0);
- /* Create shared channel VM, space is reserved for GART mappings at
- * the beginning of this address space, it's managed separately
- * because TTM makes life painful
+ /* Create shared channel VM, space is reserved at the beginning
+ * to catch "NULL pointer" references
*/
- dev_priv->vm_gart_base = 0x0020000000ULL;
- dev_priv->vm_gart_size = 512 * 1024 * 1024;
- nongart_o = dev_priv->vm_gart_base + dev_priv->vm_gart_size;
-
- ret = nouveau_vm_new(dev, 0, (1ULL << 40), nongart_o,
- 29, 12, 16, &dev_priv->chan_vm);
+ ret = nouveau_vm_new(dev, 0, (1ULL << 40), 0x0020000000ULL,
+ &dev_priv->chan_vm);
if (ret)
return ret;
dev_priv->channels.ptr[127] = 0;
nv50_channel_del(&dev_priv->channels.ptr[0]);
- nouveau_gpuobj_ref(NULL, &dev_priv->bar3_vm->pgt[0].obj);
+ nouveau_gpuobj_ref(NULL, &dev_priv->bar3_vm->pgt[0].obj[0]);
nouveau_vm_ref(NULL, &dev_priv->bar3_vm, NULL);
if (dev_priv->ramin_heap.free_stack.next)
struct nv50_gpuobj_node {
struct nouveau_vram *vram;
+ struct nouveau_vma chan_vma;
u32 align;
};
nv50_instmem_get(struct nouveau_gpuobj *gpuobj, u32 size, u32 align)
{
struct drm_device *dev = gpuobj->dev;
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_vram_engine *vram = &dev_priv->engine.vram;
struct nv50_gpuobj_node *node = NULL;
int ret;
size = (size + 4095) & ~4095;
align = max(align, (u32)4096);
- ret = nv50_vram_new(dev, size, align, 0, 0, &node->vram);
+ ret = vram->get(dev, size, align, 0, 0, &node->vram);
if (ret) {
kfree(node);
return ret;
}
gpuobj->vinst = node->vram->offset;
- gpuobj->size = size;
- gpuobj->node = node;
+
+ if (gpuobj->flags & NVOBJ_FLAG_VM) {
+ u32 flags = NV_MEM_ACCESS_RW;
+ if (!(gpuobj->flags & NVOBJ_FLAG_VM_USER))
+ flags |= NV_MEM_ACCESS_SYS;
+
+ ret = nouveau_vm_get(dev_priv->chan_vm, size, 12, flags,
+ &node->chan_vma);
+ if (ret) {
+ vram->put(dev, &node->vram);
+ kfree(node);
+ return ret;
+ }
+
+ nouveau_vm_map(&node->chan_vma, node->vram);
+ gpuobj->vinst = node->chan_vma.offset;
+ }
+
+ gpuobj->size = size;
+ gpuobj->node = node;
return 0;
}
nv50_instmem_put(struct nouveau_gpuobj *gpuobj)
{
struct drm_device *dev = gpuobj->dev;
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_vram_engine *vram = &dev_priv->engine.vram;
struct nv50_gpuobj_node *node;
node = gpuobj->node;
gpuobj->node = NULL;
- nv50_vram_del(dev, &node->vram);
+ if (node->chan_vma.node) {
+ nouveau_vm_unmap(&node->chan_vma);
+ nouveau_vm_put(&node->chan_vma);
+ }
+ vram->put(dev, &node->vram);
kfree(node);
}