aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2017-11-01 03:56:19 +1000
committerBen Skeggs <bskeggs@redhat.com>2017-11-02 13:32:18 +1000
commit07bbc1c5f49b64323d9e5c1e0d5d7d201e1f2627 (patch)
tree8ef86f7972db2f92d01824787bc9a3c729346354 /drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
parentdrm/nouveau/imem: add some useful debug output (diff)
downloadlinux-dev-07bbc1c5f49b64323d9e5c1e0d5d7d201e1f2627.tar.xz
linux-dev-07bbc1c5f49b64323d9e5c1e0d5d7d201e1f2627.zip
drm/nouveau/core/memory: split info pointers from accessor pointers
The accessor functions can change as a result of acquire()/release() calls, and are protected by any refcounting done there. Other functions must remain constant, as they can be called any time. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c')
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c133
1 files changed, 69 insertions, 64 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
index a3cd3e193d03..e3273aed3381 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
@@ -49,50 +49,51 @@ struct nv50_instobj {
void *map;
};
-static enum nvkm_memory_target
-nv50_instobj_target(struct nvkm_memory *memory)
+static void
+nv50_instobj_wr32_slow(struct nvkm_memory *memory, u64 offset, u32 data)
{
- return NVKM_MEM_TARGET_VRAM;
-}
+ struct nv50_instobj *iobj = nv50_instobj(memory);
+ struct nv50_instmem *imem = iobj->imem;
+ struct nvkm_device *device = imem->base.subdev.device;
+ u64 base = (iobj->mem->offset + offset) & 0xffffff00000ULL;
+ u64 addr = (iobj->mem->offset + offset) & 0x000000fffffULL;
-static u64
-nv50_instobj_addr(struct nvkm_memory *memory)
-{
- return nv50_instobj(memory)->mem->offset;
+ if (unlikely(imem->addr != base)) {
+ nvkm_wr32(device, 0x001700, base >> 16);
+ imem->addr = base;
+ }
+ nvkm_wr32(device, 0x700000 + addr, data);
}
-static u64
-nv50_instobj_size(struct nvkm_memory *memory)
+static u32
+nv50_instobj_rd32_slow(struct nvkm_memory *memory, u64 offset)
{
- return (u64)nv50_instobj(memory)->mem->size << NVKM_RAM_MM_SHIFT;
+ struct nv50_instobj *iobj = nv50_instobj(memory);
+ struct nv50_instmem *imem = iobj->imem;
+ struct nvkm_device *device = imem->base.subdev.device;
+ u64 base = (iobj->mem->offset + offset) & 0xffffff00000ULL;
+ u64 addr = (iobj->mem->offset + offset) & 0x000000fffffULL;
+ u32 data;
+
+ if (unlikely(imem->addr != base)) {
+ nvkm_wr32(device, 0x001700, base >> 16);
+ imem->addr = base;
+ }
+ data = nvkm_rd32(device, 0x700000 + addr);
+ return data;
}
+static const struct nvkm_memory_ptrs
+nv50_instobj_slow = {
+ .rd32 = nv50_instobj_rd32_slow,
+ .wr32 = nv50_instobj_wr32_slow,
+};
+
static void
-nv50_instobj_boot(struct nvkm_memory *memory, struct nvkm_vm *vm)
+nv50_instobj_map(struct nvkm_memory *memory, struct nvkm_vma *vma, u64 offset)
{
struct nv50_instobj *iobj = nv50_instobj(memory);
- struct nvkm_subdev *subdev = &iobj->imem->base.subdev;
- struct nvkm_device *device = subdev->device;
- u64 size = nvkm_memory_size(memory);
- void __iomem *map;
- int ret;
-
- iobj->map = ERR_PTR(-ENOMEM);
-
- ret = nvkm_vm_get(vm, size, 12, NV_MEM_ACCESS_RW, &iobj->bar);
- if (ret == 0) {
- map = ioremap(device->func->resource_addr(device, 3) +
- (u32)iobj->bar.offset, size);
- if (map) {
- nvkm_memory_map(memory, &iobj->bar, 0);
- iobj->map = map;
- } else {
- nvkm_warn(subdev, "PRAMIN ioremap failed\n");
- nvkm_vm_put(&iobj->bar);
- }
- } else {
- nvkm_warn(subdev, "PRAMIN exhausted\n");
- }
+ nvkm_vm_map_at(vma, offset, iobj->mem);
}
static void
@@ -120,45 +121,50 @@ nv50_instobj_acquire(struct nvkm_memory *memory)
return NULL;
}
-static u32
-nv50_instobj_rd32(struct nvkm_memory *memory, u64 offset)
+static void
+nv50_instobj_boot(struct nvkm_memory *memory, struct nvkm_vm *vm)
{
struct nv50_instobj *iobj = nv50_instobj(memory);
- struct nv50_instmem *imem = iobj->imem;
- struct nvkm_device *device = imem->base.subdev.device;
- u64 base = (iobj->mem->offset + offset) & 0xffffff00000ULL;
- u64 addr = (iobj->mem->offset + offset) & 0x000000fffffULL;
- u32 data;
+ struct nvkm_subdev *subdev = &iobj->imem->base.subdev;
+ struct nvkm_device *device = subdev->device;
+ u64 size = nvkm_memory_size(memory);
+ void __iomem *map;
+ int ret;
- if (unlikely(imem->addr != base)) {
- nvkm_wr32(device, 0x001700, base >> 16);
- imem->addr = base;
+ iobj->map = ERR_PTR(-ENOMEM);
+
+ ret = nvkm_vm_get(vm, size, 12, NV_MEM_ACCESS_RW, &iobj->bar);
+ if (ret == 0) {
+ map = ioremap(device->func->resource_addr(device, 3) +
+ (u32)iobj->bar.offset, size);
+ if (map) {
+ nvkm_memory_map(memory, &iobj->bar, 0);
+ iobj->map = map;
+ } else {
+ nvkm_warn(subdev, "PRAMIN ioremap failed\n");
+ nvkm_vm_put(&iobj->bar);
+ }
+ } else {
+ nvkm_warn(subdev, "PRAMIN exhausted\n");
}
- data = nvkm_rd32(device, 0x700000 + addr);
- return data;
}
-static void
-nv50_instobj_wr32(struct nvkm_memory *memory, u64 offset, u32 data)
+static u64
+nv50_instobj_size(struct nvkm_memory *memory)
{
- struct nv50_instobj *iobj = nv50_instobj(memory);
- struct nv50_instmem *imem = iobj->imem;
- struct nvkm_device *device = imem->base.subdev.device;
- u64 base = (iobj->mem->offset + offset) & 0xffffff00000ULL;
- u64 addr = (iobj->mem->offset + offset) & 0x000000fffffULL;
+ return (u64)nv50_instobj(memory)->mem->size << NVKM_RAM_MM_SHIFT;
+}
- if (unlikely(imem->addr != base)) {
- nvkm_wr32(device, 0x001700, base >> 16);
- imem->addr = base;
- }
- nvkm_wr32(device, 0x700000 + addr, data);
+static u64
+nv50_instobj_addr(struct nvkm_memory *memory)
+{
+ return nv50_instobj(memory)->mem->offset;
}
-static void
-nv50_instobj_map(struct nvkm_memory *memory, struct nvkm_vma *vma, u64 offset)
+static enum nvkm_memory_target
+nv50_instobj_target(struct nvkm_memory *memory)
{
- struct nv50_instobj *iobj = nv50_instobj(memory);
- nvkm_vm_map_at(vma, offset, iobj->mem);
+ return NVKM_MEM_TARGET_VRAM;
}
static void *
@@ -183,8 +189,6 @@ nv50_instobj_func = {
.boot = nv50_instobj_boot,
.acquire = nv50_instobj_acquire,
.release = nv50_instobj_release,
- .rd32 = nv50_instobj_rd32,
- .wr32 = nv50_instobj_wr32,
.map = nv50_instobj_map,
};
@@ -202,6 +206,7 @@ nv50_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero,
*pmemory = &iobj->memory;
nvkm_memory_ctor(&nv50_instobj_func, &iobj->memory);
+ iobj->memory.ptrs = &nv50_instobj_slow;
iobj->imem = imem;
size = max((size + 4095) & ~4095, (u32)4096);