void nouveau_ramht_remove(struct nouveau_ramht *ramht, int cookie) { struct nouveau_bar *bar = nouveau_bar(ramht); nv_wo32(ramht, cookie + 0, 0x00000000); nv_wo32(ramht, cookie + 4, 0x00000000); if (bar) bar->flush(bar); }
int nouveau_gpuobj_map(struct nouveau_gpuobj *gpuobj, u32 access, struct nouveau_vma *vma) { struct nouveau_bar *bar = nouveau_bar(gpuobj); int ret = -EINVAL; if (bar && bar->umap) { struct nouveau_instobj *iobj = (void *) nv_pclass(nv_object(gpuobj), NV_MEMOBJ_CLASS); struct nouveau_mem **mem = (void *)(iobj + 1); ret = bar->umap(bar, *mem, access, vma); } return ret; }
static int nvc0_software_vblsem_release(struct nouveau_eventh *event, int head) { struct nouveau_software_chan *chan = container_of(event, struct nouveau_software_chan, vblank.event); struct nvc0_software_priv *priv = (void *)nv_object(chan)->engine; struct nouveau_bar *bar = nouveau_bar(priv); nv_wr32(priv, 0x001718, 0x80000000 | chan->vblank.channel); bar->flush(bar); nv_wr32(priv, 0x06000c, upper_32_bits(chan->vblank.offset)); nv_wr32(priv, 0x060010, lower_32_bits(chan->vblank.offset)); nv_wr32(priv, 0x060014, chan->vblank.value); return NVKM_EVENT_DROP; }
static int nvc0_software_vblsem_release(struct nvkm_notify *notify) { struct nv50_software_chan *chan = container_of(notify, typeof(*chan), vblank.notify[notify->index]); struct nv50_software_priv *priv = (void *)nv_object(chan)->engine; struct nouveau_bar *bar = nouveau_bar(priv); nv_wr32(priv, 0x001718, 0x80000000 | chan->vblank.channel); bar->flush(bar); nv_wr32(priv, 0x06000c, upper_32_bits(chan->vblank.offset)); nv_wr32(priv, 0x060010, lower_32_bits(chan->vblank.offset)); nv_wr32(priv, 0x060014, chan->vblank.value); return NVKM_NOTIFY_DROP; }
static int nv50_software_vblsem_release(void *data, int head) { struct nv50_software_chan *chan = data; struct nv50_software_priv *priv = (void *)nv_object(chan)->engine; struct nouveau_bar *bar = nouveau_bar(priv); nv_wr32(priv, 0x001704, chan->vblank.channel); nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma); bar->flush(bar); if (nv_device(priv)->chipset == 0x50) { nv_wr32(priv, 0x001570, chan->vblank.offset); nv_wr32(priv, 0x001574, chan->vblank.value); } else { nv_wr32(priv, 0x060010, chan->vblank.offset); nv_wr32(priv, 0x060014, chan->vblank.value); } return NVKM_EVENT_DROP; }
int nouveau_ramht_insert(struct nouveau_ramht *ramht, int chid, u32 handle, u32 context) { struct nouveau_bar *bar = nouveau_bar(ramht); u32 co, ho; co = ho = nouveau_ramht_hash(ramht, chid, handle); do { if (!nv_ro32(ramht, co + 4)) { nv_wo32(ramht, co + 0, handle); nv_wo32(ramht, co + 4, context); if (bar) bar->flush(bar); return co; } co += 8; if (co >= nv_gpuobj(ramht)->size) co = 0; } while (co != ho); return -ENOMEM; }
int nouveau_gpuobj_create_(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, u32 pclass, struct nouveau_object *pargpu, u32 size, u32 align, u32 flags, int length, void **pobject) { struct nouveau_instmem *imem = nouveau_instmem(parent); struct nouveau_bar *bar = nouveau_bar(parent); struct nouveau_gpuobj *gpuobj; struct nouveau_mm *heap = NULL; int ret, i; u64 addr; *pobject = NULL; if (pargpu) { while ((pargpu = nv_pclass(pargpu, NV_GPUOBJ_CLASS))) { if (nv_gpuobj(pargpu)->heap.block_size) break; pargpu = pargpu->parent; } if (unlikely(pargpu == NULL)) { nv_error(parent, "no gpuobj heap\n"); return -EINVAL; } addr = nv_gpuobj(pargpu)->addr; heap = &nv_gpuobj(pargpu)->heap; atomic_inc(&parent->refcount); } else { ret = imem->alloc(imem, parent, size, align, &parent); pargpu = parent; if (ret) return ret; addr = nv_memobj(pargpu)->addr; size = nv_memobj(pargpu)->size; if (bar && bar->alloc) { struct nouveau_instobj *iobj = (void *)parent; struct nouveau_mem **mem = (void *)(iobj + 1); struct nouveau_mem *node = *mem; if (!bar->alloc(bar, parent, node, &pargpu)) { nouveau_object_ref(NULL, &parent); parent = pargpu; } } } ret = nouveau_object_create_(parent, engine, oclass, pclass | NV_GPUOBJ_CLASS, length, pobject); nouveau_object_ref(NULL, &parent); gpuobj = *pobject; if (ret) return ret; gpuobj->parent = pargpu; gpuobj->flags = flags; gpuobj->addr = addr; gpuobj->size = size; if (heap) { ret = nouveau_mm_head(heap, 0, 1, size, size, max(align, (u32)1), &gpuobj->node); if (ret) return ret; gpuobj->addr += gpuobj->node->offset; } if (gpuobj->flags & NVOBJ_FLAG_HEAP) { ret = nouveau_mm_init(&gpuobj->heap, 0, gpuobj->size, 1); if (ret) return ret; } if (flags & NVOBJ_FLAG_ZERO_ALLOC) { for (i = 0; i < gpuobj->size; i += 4) nv_wo32(gpuobj, i, 0x00000000); } return ret; }