From 73a60c0d218a292f8ef29d3467726ff26ed366fc Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 13 Jul 2012 17:21:22 +1000 Subject: [PATCH] drm/nouveau/gpuobj: remove flags for vm-mappings Having GPUOBJ and VM intertwined like this makes it *really* hard to continue porting to the new driver architecture, split it out in favour of requiring explit maps be the caller. It's more flexible and obvious this way anyway... Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/core/engine/copy/nvc0.c | 36 +++++++--- .../gpu/drm/nouveau/core/engine/graph/nvc0.c | 71 +++++++++++++------ .../gpu/drm/nouveau/core/engine/graph/nvc0.h | 5 ++ .../gpu/drm/nouveau/core/engine/graph/nve0.c | 70 ++++++++++++------ .../gpu/drm/nouveau/core/engine/graph/nve0.h | 5 ++ .../drm/nouveau/core/subdev/instmem/nv50.c | 18 ----- drivers/gpu/drm/nouveau/nouveau_drv.h | 3 - drivers/gpu/drm/nouveau/nouveau_gpuobj.c | 2 +- 8 files changed, 136 insertions(+), 74 deletions(-) diff --git a/drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c index 90a069b46a9d..926f21c0ebce 100644 --- a/drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c @@ -38,27 +38,38 @@ struct nvc0_copy_engine { u32 ctx; }; +struct nvc0_copy_chan { + struct nouveau_gpuobj *mem; + struct nouveau_vma vma; +}; + static int nvc0_copy_context_new(struct nouveau_channel *chan, int engine) { struct nvc0_copy_engine *pcopy = nv_engine(chan->dev, engine); + struct nvc0_copy_chan *cctx; struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_gpuobj *ramin = chan->ramin; - struct nouveau_gpuobj *ctx = NULL; int ret; - ret = nouveau_gpuobj_new(dev, chan, 256, 256, - NVOBJ_FLAG_VM | NVOBJ_FLAG_VM_USER | - NVOBJ_FLAG_ZERO_ALLOC, &ctx); + cctx = chan->engctx[engine] = kzalloc(sizeof(*cctx), GFP_KERNEL); + if (!cctx) + return -ENOMEM; + + ret = nouveau_gpuobj_new(dev, NULL, 256, 256, + NVOBJ_FLAG_ZERO_ALLOC, &cctx->mem); if (ret) return ret; - nv_wo32(ramin, pcopy->ctx + 0, lower_32_bits(ctx->linst)); - nv_wo32(ramin, pcopy->ctx + 4, upper_32_bits(ctx->linst)); - dev_priv->engine.instmem.flush(dev); + ret = nouveau_gpuobj_map_vm(cctx->mem, NV_MEM_ACCESS_RW, chan->vm, + &cctx->vma); + if (ret) + return ret; - chan->engctx[engine] = ctx; + nv_wo32(ramin, pcopy->ctx + 0, lower_32_bits(cctx->vma.offset)); + nv_wo32(ramin, pcopy->ctx + 4, upper_32_bits(cctx->vma.offset)); + dev_priv->engine.instmem.flush(dev); return 0; } @@ -73,7 +84,7 @@ static void nvc0_copy_context_del(struct nouveau_channel *chan, int engine) { struct nvc0_copy_engine *pcopy = nv_engine(chan->dev, engine); - struct nouveau_gpuobj *ctx = chan->engctx[engine]; + struct nvc0_copy_chan *cctx = chan->engctx[engine]; struct drm_device *dev = chan->dev; u32 inst; @@ -93,9 +104,12 @@ nvc0_copy_context_del(struct nouveau_channel *chan, int engine) nv_wo32(chan->ramin, pcopy->ctx + 0, 0x00000000); nv_wo32(chan->ramin, pcopy->ctx + 4, 0x00000000); - nouveau_gpuobj_ref(NULL, &ctx); - chan->engctx[engine] = ctx; + nouveau_gpuobj_unmap(&cctx->vma); + nouveau_gpuobj_ref(NULL, &cctx->mem); + + kfree(cctx); + chan->engctx[engine] = NULL; } static int diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c index 8f515dcb63c0..8d6eb89b8117 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c @@ -161,50 +161,68 @@ nvc0_graph_create_context_mmio_list(struct nouveau_channel *chan) struct drm_nouveau_private *dev_priv = dev->dev_private; int i = 0, gpc, tp, ret; - ret = nouveau_gpuobj_new(dev, chan, 0x2000, 256, NVOBJ_FLAG_VM, - &grch->unk408004); + ret = nouveau_gpuobj_new(dev, NULL, 0x2000, 256, 0, &grch->unk408004); if (ret) return ret; - ret = nouveau_gpuobj_new(dev, chan, 0x8000, 256, NVOBJ_FLAG_VM, - &grch->unk40800c); + ret = nouveau_gpuobj_map_vm(grch->unk408004, NV_MEM_ACCESS_RW | + NV_MEM_ACCESS_SYS, chan->vm, + &grch->unk408004_vma); if (ret) return ret; - ret = nouveau_gpuobj_new(dev, chan, 384 * 1024, 4096, - NVOBJ_FLAG_VM | NVOBJ_FLAG_VM_USER, + ret = nouveau_gpuobj_new(dev, NULL, 0x8000, 256, 0, &grch->unk40800c); + if (ret) + return ret; + + ret = nouveau_gpuobj_map_vm(grch->unk40800c, NV_MEM_ACCESS_RW | + NV_MEM_ACCESS_SYS, chan->vm, + &grch->unk40800c_vma); + if (ret) + return ret; + + ret = nouveau_gpuobj_new(dev, NULL, 384 * 1024, 4096, 0, &grch->unk418810); if (ret) return ret; - ret = nouveau_gpuobj_new(dev, chan, 0x1000, 0, NVOBJ_FLAG_VM, - &grch->mmio); + ret = nouveau_gpuobj_map_vm(grch->unk418810, NV_MEM_ACCESS_RW, + chan->vm, &grch->unk418810_vma); if (ret) return ret; + ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 0, 0, &grch->mmio); + if (ret) + return ret; + + ret = nouveau_gpuobj_map_vm(grch->mmio, NV_MEM_ACCESS_RW | + NV_MEM_ACCESS_SYS, chan->vm, + &grch->mmio_vma); + if (ret) + return ret; nv_wo32(grch->mmio, i++ * 4, 0x00408004); - nv_wo32(grch->mmio, i++ * 4, grch->unk408004->linst >> 8); + nv_wo32(grch->mmio, i++ * 4, grch->unk408004_vma.offset >> 8); nv_wo32(grch->mmio, i++ * 4, 0x00408008); nv_wo32(grch->mmio, i++ * 4, 0x80000018); nv_wo32(grch->mmio, i++ * 4, 0x0040800c); - nv_wo32(grch->mmio, i++ * 4, grch->unk40800c->linst >> 8); + nv_wo32(grch->mmio, i++ * 4, grch->unk40800c_vma.offset >> 8); nv_wo32(grch->mmio, i++ * 4, 0x00408010); nv_wo32(grch->mmio, i++ * 4, 0x80000000); nv_wo32(grch->mmio, i++ * 4, 0x00418810); - nv_wo32(grch->mmio, i++ * 4, 0x80000000 | grch->unk418810->linst >> 12); + nv_wo32(grch->mmio, i++ * 4, 0x80000000 | grch->unk418810_vma.offset >> 12); nv_wo32(grch->mmio, i++ * 4, 0x00419848); - nv_wo32(grch->mmio, i++ * 4, 0x10000000 | grch->unk418810->linst >> 12); + nv_wo32(grch->mmio, i++ * 4, 0x10000000 | grch->unk418810_vma.offset >> 12); nv_wo32(grch->mmio, i++ * 4, 0x00419004); - nv_wo32(grch->mmio, i++ * 4, grch->unk40800c->linst >> 8); + nv_wo32(grch->mmio, i++ * 4, grch->unk40800c_vma.offset >> 8); nv_wo32(grch->mmio, i++ * 4, 0x00419008); nv_wo32(grch->mmio, i++ * 4, 0x00000000); nv_wo32(grch->mmio, i++ * 4, 0x00418808); - nv_wo32(grch->mmio, i++ * 4, grch->unk408004->linst >> 8); + nv_wo32(grch->mmio, i++ * 4, grch->unk408004_vma.offset >> 8); nv_wo32(grch->mmio, i++ * 4, 0x0041880c); nv_wo32(grch->mmio, i++ * 4, 0x80000018); @@ -262,19 +280,25 @@ nvc0_graph_context_new(struct nouveau_channel *chan, int engine) return -ENOMEM; chan->engctx[NVOBJ_ENGINE_GR] = grch; - ret = nouveau_gpuobj_new(dev, chan, priv->grctx_size, 256, - NVOBJ_FLAG_VM | NVOBJ_FLAG_ZERO_ALLOC, + ret = nouveau_gpuobj_new(dev, NULL, priv->grctx_size, 256, 0, &grch->grctx); if (ret) goto error; + + ret = nouveau_gpuobj_map_vm(grch->grctx, NV_MEM_ACCESS_RW | + NV_MEM_ACCESS_SYS, chan->vm, + &grch->grctx_vma); + if (ret) + return ret; + grctx = grch->grctx; ret = nvc0_graph_create_context_mmio_list(chan); if (ret) goto error; - nv_wo32(chan->ramin, 0x0210, lower_32_bits(grctx->linst) | 4); - nv_wo32(chan->ramin, 0x0214, upper_32_bits(grctx->linst)); + nv_wo32(chan->ramin, 0x0210, lower_32_bits(grch->grctx_vma.offset) | 4); + nv_wo32(chan->ramin, 0x0214, upper_32_bits(grch->grctx_vma.offset)); pinstmem->flush(dev); if (!priv->grctx_vals) { @@ -288,13 +312,13 @@ nvc0_graph_context_new(struct nouveau_channel *chan, int engine) if (!nouveau_ctxfw) { nv_wo32(grctx, 0x00, grch->mmio_nr); - nv_wo32(grctx, 0x04, grch->mmio->linst >> 8); + nv_wo32(grctx, 0x04, grch->mmio_vma.offset >> 8); } else { nv_wo32(grctx, 0xf4, 0); nv_wo32(grctx, 0xf8, 0); nv_wo32(grctx, 0x10, grch->mmio_nr); - nv_wo32(grctx, 0x14, lower_32_bits(grch->mmio->linst)); - nv_wo32(grctx, 0x18, upper_32_bits(grch->mmio->linst)); + nv_wo32(grctx, 0x14, lower_32_bits(grch->mmio_vma.offset)); + nv_wo32(grctx, 0x18, upper_32_bits(grch->mmio_vma.offset)); nv_wo32(grctx, 0x1c, 1); nv_wo32(grctx, 0x20, 0); nv_wo32(grctx, 0x28, 0); @@ -313,6 +337,11 @@ nvc0_graph_context_del(struct nouveau_channel *chan, int engine) { struct nvc0_graph_chan *grch = chan->engctx[engine]; + nouveau_gpuobj_unmap(&grch->mmio_vma); + nouveau_gpuobj_unmap(&grch->unk418810_vma); + nouveau_gpuobj_unmap(&grch->unk40800c_vma); + nouveau_gpuobj_unmap(&grch->unk408004_vma); + nouveau_gpuobj_unmap(&grch->grctx_vma); nouveau_gpuobj_ref(NULL, &grch->mmio); nouveau_gpuobj_ref(NULL, &grch->unk418810); nouveau_gpuobj_ref(NULL, &grch->unk40800c); diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h index 91d44ea662d9..ffeb4a02e9ff 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h @@ -62,10 +62,15 @@ struct nvc0_graph_priv { struct nvc0_graph_chan { struct nouveau_gpuobj *grctx; + struct nouveau_vma grctx_vma; struct nouveau_gpuobj *unk408004; /* 0x418810 too */ + struct nouveau_vma unk408004_vma; struct nouveau_gpuobj *unk40800c; /* 0x419004 too */ + struct nouveau_vma unk40800c_vma; struct nouveau_gpuobj *unk418810; /* 0x419848 too */ + struct nouveau_vma unk418810_vma; struct nouveau_gpuobj *mmio; + struct nouveau_vma mmio_vma; int mmio_nr; }; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c index a8364b1236a0..5f671a21b8bb 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c @@ -137,24 +137,43 @@ nve0_graph_create_context_mmio_list(struct nouveau_channel *chan) int gpc; int ret; - ret = nouveau_gpuobj_new(dev, chan, 0x3000, 256, NVOBJ_FLAG_VM, - &grch->unk408004); + ret = nouveau_gpuobj_new(dev, NULL, 0x3000, 256, 0, &grch->unk408004); if (ret) return ret; - ret = nouveau_gpuobj_new(dev, chan, 0x8000, 256, NVOBJ_FLAG_VM, - &grch->unk40800c); + ret = nouveau_gpuobj_map_vm(grch->unk408004, NV_MEM_ACCESS_RW | + NV_MEM_ACCESS_SYS, chan->vm, + &grch->unk408004_vma); if (ret) return ret; - ret = nouveau_gpuobj_new(dev, chan, 384 * 1024, 4096, - NVOBJ_FLAG_VM | NVOBJ_FLAG_VM_USER, + ret = nouveau_gpuobj_new(dev, NULL, 0x8000, 256, 0, &grch->unk40800c); + if (ret) + return ret; + + ret = nouveau_gpuobj_map_vm(grch->unk40800c, NV_MEM_ACCESS_RW | + NV_MEM_ACCESS_SYS, chan->vm, + &grch->unk40800c_vma); + if (ret) + return ret; + + ret = nouveau_gpuobj_new(dev, NULL, 384 * 1024, 4096, 0, &grch->unk418810); if (ret) return ret; - ret = nouveau_gpuobj_new(dev, chan, 0x1000, 0, NVOBJ_FLAG_VM, - &grch->mmio); + ret = nouveau_gpuobj_map_vm(grch->unk418810, NV_MEM_ACCESS_RW, + chan->vm, &grch->unk418810_vma); + if (ret) + return ret; + + ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 0, 0, &grch->mmio); + if (ret) + return ret; + + ret = nouveau_gpuobj_map_vm(grch->mmio, NV_MEM_ACCESS_RW | + NV_MEM_ACCESS_SYS, chan->vm, + &grch->mmio_vma); if (ret) return ret; @@ -163,18 +182,18 @@ nve0_graph_create_context_mmio_list(struct nouveau_channel *chan) nv_wo32(grch->mmio, (grch->mmio_nr * 8) + 4, (v)); \ grch->mmio_nr++; \ } while (0) - mmio(0x40800c, grch->unk40800c->linst >> 8); + mmio(0x40800c, grch->unk40800c_vma.offset >> 8); mmio(0x408010, 0x80000000); - mmio(0x419004, grch->unk40800c->linst >> 8); + mmio(0x419004, grch->unk40800c_vma.offset >> 8); mmio(0x419008, 0x00000000); mmio(0x4064cc, 0x80000000); - mmio(0x408004, grch->unk408004->linst >> 8); + mmio(0x408004, grch->unk408004_vma.offset >> 8); mmio(0x408008, 0x80000030); - mmio(0x418808, grch->unk408004->linst >> 8); + mmio(0x418808, grch->unk408004_vma.offset >> 8); mmio(0x41880c, 0x80000030); mmio(0x4064c8, 0x01800600); - mmio(0x418810, 0x80000000 | grch->unk418810->linst >> 12); - mmio(0x419848, 0x10000000 | grch->unk418810->linst >> 12); + mmio(0x418810, 0x80000000 | grch->unk418810_vma.offset >> 12); + mmio(0x419848, 0x10000000 | grch->unk418810_vma.offset >> 12); mmio(0x405830, 0x02180648); mmio(0x4064c4, 0x0192ffff); @@ -214,19 +233,25 @@ nve0_graph_context_new(struct nouveau_channel *chan, int engine) return -ENOMEM; chan->engctx[NVOBJ_ENGINE_GR] = grch; - ret = nouveau_gpuobj_new(dev, chan, priv->grctx_size, 256, - NVOBJ_FLAG_VM | NVOBJ_FLAG_ZERO_ALLOC, + ret = nouveau_gpuobj_new(dev, NULL, priv->grctx_size, 256, 0, &grch->grctx); if (ret) goto error; + + ret = nouveau_gpuobj_map_vm(grch->grctx, NV_MEM_ACCESS_RW | + NV_MEM_ACCESS_SYS, chan->vm, + &grch->grctx_vma); + if (ret) + return ret; + grctx = grch->grctx; ret = nve0_graph_create_context_mmio_list(chan); if (ret) goto error; - nv_wo32(chan->ramin, 0x0210, lower_32_bits(grctx->linst) | 4); - nv_wo32(chan->ramin, 0x0214, upper_32_bits(grctx->linst)); + nv_wo32(chan->ramin, 0x0210, lower_32_bits(grch->grctx_vma.offset) | 4); + nv_wo32(chan->ramin, 0x0214, upper_32_bits(grch->grctx_vma.offset)); pinstmem->flush(dev); if (!priv->grctx_vals) { @@ -240,8 +265,8 @@ nve0_graph_context_new(struct nouveau_channel *chan, int engine) nv_wo32(grctx, 0xf4, 0); nv_wo32(grctx, 0xf8, 0); nv_wo32(grctx, 0x10, grch->mmio_nr); - nv_wo32(grctx, 0x14, lower_32_bits(grch->mmio->linst)); - nv_wo32(grctx, 0x18, upper_32_bits(grch->mmio->linst)); + nv_wo32(grctx, 0x14, lower_32_bits(grch->mmio_vma.offset)); + nv_wo32(grctx, 0x18, upper_32_bits(grch->mmio_vma.offset)); nv_wo32(grctx, 0x1c, 1); nv_wo32(grctx, 0x20, 0); nv_wo32(grctx, 0x28, 0); @@ -260,6 +285,11 @@ nve0_graph_context_del(struct nouveau_channel *chan, int engine) { struct nve0_graph_chan *grch = chan->engctx[engine]; + nouveau_gpuobj_unmap(&grch->mmio_vma); + nouveau_gpuobj_unmap(&grch->unk418810_vma); + nouveau_gpuobj_unmap(&grch->unk40800c_vma); + nouveau_gpuobj_unmap(&grch->unk408004_vma); + nouveau_gpuobj_unmap(&grch->grctx_vma); nouveau_gpuobj_ref(NULL, &grch->mmio); nouveau_gpuobj_ref(NULL, &grch->unk418810); nouveau_gpuobj_ref(NULL, &grch->unk40800c); diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nve0.h b/drivers/gpu/drm/nouveau/core/engine/graph/nve0.h index 2ba70449ba01..b136cd5b8a26 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nve0.h +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nve0.h @@ -62,10 +62,15 @@ struct nve0_graph_priv { struct nve0_graph_chan { struct nouveau_gpuobj *grctx; + struct nouveau_vma grctx_vma; struct nouveau_gpuobj *unk408004; /* 0x418810 too */ + struct nouveau_vma unk408004_vma; struct nouveau_gpuobj *unk40800c; /* 0x419004 too */ + struct nouveau_vma unk40800c_vma; struct nouveau_gpuobj *unk418810; /* 0x419848 too */ + struct nouveau_vma unk418810_vma; struct nouveau_gpuobj *mmio; + struct nouveau_vma mmio_vma; int mmio_nr; }; diff --git a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv50.c index 24d077a1d842..be7344d1334d 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv50.c @@ -328,24 +328,6 @@ nv50_instmem_get(struct nouveau_gpuobj *gpuobj, struct nouveau_channel *chan, } gpuobj->vinst = node->vram->offset; - - 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(chan->vm, size, 12, flags, - &node->chan_vma); - if (ret) { - nvfb_vram_put(dev, &node->vram); - kfree(node); - return ret; - } - - nouveau_vm_map(&node->chan_vma, node->vram); - gpuobj->linst = node->chan_vma.offset; - } - gpuobj->size = size; gpuobj->node = node; return 0; diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 8ec8ca6ef16f..0c03b472a9a0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -175,8 +175,6 @@ enum nouveau_flags { #define NVOBJ_FLAG_DONT_MAP (1 << 0) #define NVOBJ_FLAG_ZERO_ALLOC (1 << 1) #define NVOBJ_FLAG_ZERO_FREE (1 << 2) -#define NVOBJ_FLAG_VM (1 << 3) -#define NVOBJ_FLAG_VM_USER (1 << 4) #define NVOBJ_CINST_GLOBAL 0xdeadbeef @@ -194,7 +192,6 @@ struct nouveau_gpuobj { u32 pinst; /* PRAMIN BAR offset */ u32 cinst; /* Channel offset */ u64 vinst; /* VRAM address */ - u64 linst; /* VM address */ uint32_t engine; uint32_t class; diff --git a/drivers/gpu/drm/nouveau/nouveau_gpuobj.c b/drivers/gpu/drm/nouveau/nouveau_gpuobj.c index 4f8020d565a5..79f1d1ef3798 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gpuobj.c +++ b/drivers/gpu/drm/nouveau/nouveau_gpuobj.c @@ -162,7 +162,7 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan, list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list); spin_unlock(&dev_priv->ramin_lock); - if (!(flags & NVOBJ_FLAG_VM) && chan) { + if (chan) { ramin = drm_mm_search_free(&chan->ramin_heap, size, align, 0); if (ramin) ramin = drm_mm_get_block(ramin, size, align);