From 07bbc1c5f49b64323d9e5c1e0d5d7d201e1f2627 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: 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 --- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c | 133 +++++++++++---------- 1 file changed, 69 insertions(+), 64 deletions(-) (limited to 'drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c') 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); -- cgit v1.2.3-59-g8ed1b