int nvkm_gpuobj_wrap(struct nvkm_memory *memory, struct nvkm_gpuobj **pgpuobj) { if (!(*pgpuobj = kzalloc(sizeof(**pgpuobj), GFP_KERNEL))) return -ENOMEM; (*pgpuobj)->addr = nvkm_memory_addr(memory); (*pgpuobj)->size = nvkm_memory_size(memory); return 0; }
int nv20_gr_chan_init(struct nvkm_object *object) { struct nv20_gr_chan *chan = nv20_gr_chan(object); struct nv20_gr *gr = chan->gr; u32 inst = nvkm_memory_addr(chan->inst); nvkm_kmap(gr->ctxtab); nvkm_wo32(gr->ctxtab, chan->chid * 4, inst >> 4); nvkm_done(gr->ctxtab); return 0; }
void gv100_fifo_runlist_chan(struct gk104_fifo_chan *chan, struct nvkm_memory *memory, u32 offset) { struct nvkm_memory *usermem = chan->fifo->user.mem; const u64 user = nvkm_memory_addr(usermem) + (chan->base.chid * 0x200); const u64 inst = chan->base.inst->addr; nvkm_wo32(memory, offset + 0x0, lower_32_bits(user)); nvkm_wo32(memory, offset + 0x4, upper_32_bits(user)); nvkm_wo32(memory, offset + 0x8, lower_32_bits(inst) | chan->base.chid); nvkm_wo32(memory, offset + 0xc, upper_32_bits(inst)); }
int nv20_gr_chan_fini(struct nvkm_object *object, bool suspend) { struct nv20_gr_chan *chan = nv20_gr_chan(object); struct nv20_gr *gr = chan->gr; struct nvkm_device *device = gr->base.engine.subdev.device; u32 inst = nvkm_memory_addr(chan->inst); int chid = -1; nvkm_mask(device, 0x400720, 0x00000001, 0x00000000); if (nvkm_rd32(device, 0x400144) & 0x00010000) chid = (nvkm_rd32(device, 0x400148) & 0x1f000000) >> 24; if (chan->chid == chid) { nvkm_wr32(device, 0x400784, inst >> 4); nvkm_wr32(device, 0x400788, 0x00000002); nvkm_msec(device, 2000, if (!nvkm_rd32(device, 0x400700)) break; );
static int nvkm_gpuobj_ctor(struct nvkm_device *device, u32 size, int align, bool zero, struct nvkm_gpuobj *parent, struct nvkm_gpuobj *gpuobj) { u32 offset; int ret; if (parent) { if (align >= 0) { ret = nvkm_mm_head(&parent->heap, 0, 1, size, size, max(align, 1), &gpuobj->node); } else { ret = nvkm_mm_tail(&parent->heap, 0, 1, size, size, -align, &gpuobj->node); } if (ret) return ret; gpuobj->parent = parent; gpuobj->func = &nvkm_gpuobj_func; gpuobj->addr = parent->addr + gpuobj->node->offset; gpuobj->size = gpuobj->node->length; if (zero) { nvkm_kmap(gpuobj); for (offset = 0; offset < gpuobj->size; offset += 4) nvkm_wo32(gpuobj, offset, 0x00000000); nvkm_done(gpuobj); } } else { ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, size, abs(align), zero, &gpuobj->memory); if (ret) return ret; gpuobj->func = &nvkm_gpuobj_heap; gpuobj->addr = nvkm_memory_addr(gpuobj->memory); gpuobj->size = nvkm_memory_size(gpuobj->memory); } return nvkm_mm_init(&gpuobj->heap, 0, 0, gpuobj->size, 1); }