static int nvd0_disp_ovly_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { struct nv50_display_ovly_class *args = data; struct nv50_disp_priv *priv = (void *)engine; struct nv50_disp_dmac *dmac; int ret; if (size < sizeof(*args) || args->head >= priv->head.nr) return -EINVAL; ret = nv50_disp_dmac_create_(parent, engine, oclass, args->pushbuf, 5 + args->head, sizeof(*dmac), (void **)&dmac); *pobject = nv_object(dmac); if (ret) return ret; nv_parent(dmac)->object_attach = nvd0_disp_dmac_object_attach; nv_parent(dmac)->object_detach = nvd0_disp_dmac_object_detach; return 0; }
int nouveau_parent_lclass(struct nouveau_object *parent, u32 *lclass, int size) { struct nouveau_sclass *sclass; struct nouveau_engine *engine; struct nouveau_oclass *oclass; int nr = -1, i; u64 mask; sclass = nv_parent(parent)->sclass; while (sclass) { if (++nr < size) lclass[nr] = sclass->oclass->handle; sclass = sclass->sclass; } mask = nv_parent(parent)->engine; while (i = __ffs64(mask), mask) { engine = nouveau_engine(parent, i); if (engine && (oclass = engine->sclass)) { while (oclass->ofuncs) { if (++nr < size) lclass[nr] = oclass->handle; oclass++; } } mask &= ~(1ULL << i); } return nr + 1; }
static int nv10_fifo_chan_ctor(struct nvkm_object *parent, struct nvkm_object *engine, struct nvkm_oclass *oclass, void *data, u32 size, struct nvkm_object **pobject) { union { struct nv03_channel_dma_v0 v0; } *args = data; struct nv04_fifo_priv *priv = (void *)engine; struct nv04_fifo_chan *chan; int ret; nv_ioctl(parent, "create channel dma size %d\n", size); if (nvif_unpack(args->v0, 0, 0, false)) { nv_ioctl(parent, "create channel dma vers %d pushbuf %08x " "offset %016llx\n", args->v0.version, args->v0.pushbuf, args->v0.offset); } else return ret; ret = nvkm_fifo_channel_create(parent, engine, oclass, 0, 0x800000, 0x10000, args->v0.pushbuf, (1ULL << NVDEV_ENGINE_DMAOBJ) | (1ULL << NVDEV_ENGINE_SW) | (1ULL << NVDEV_ENGINE_GR), &chan); *pobject = nv_object(chan); if (ret) return ret; args->v0.chid = chan->base.chid; nv_parent(chan)->object_attach = nv04_fifo_object_attach; nv_parent(chan)->object_detach = nv04_fifo_object_detach; nv_parent(chan)->context_attach = nv04_fifo_context_attach; chan->ramfc = chan->base.chid * 32; nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->v0.offset); nv_wo32(priv->ramfc, chan->ramfc + 0x04, args->v0.offset); nv_wo32(priv->ramfc, chan->ramfc + 0x0c, chan->base.pushgpu->addr >> 4); nv_wo32(priv->ramfc, chan->ramfc + 0x14, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | #ifdef __BIG_ENDIAN NV_PFIFO_CACHE1_BIG_ENDIAN | #endif NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8); return 0; }
int nouveau_parent_sclass(struct nouveau_object *parent, u16 handle, struct nouveau_object **pengine, struct nouveau_oclass **poclass) { struct nouveau_sclass *sclass; struct nouveau_engine *engine; struct nouveau_oclass *oclass; u64 mask; sclass = nv_parent(parent)->sclass; while (sclass) { if ((sclass->oclass->handle & 0xffff) == handle) { *pengine = parent->engine; *poclass = sclass->oclass; return 0; } sclass = sclass->sclass; } mask = nv_parent(parent)->engine; while (mask) { int i = __ffs64(mask); if (nv_iclass(parent, NV_CLIENT_CLASS)) engine = nv_engine(nv_client(parent)->device); else engine = nouveau_engine(parent, i); if (engine) { oclass = engine->sclass; while (oclass->ofuncs) { if ((oclass->handle & 0xffff) == handle) { *pengine = nv_object(engine); *poclass = oclass; return 0; } oclass++; } } mask &= ~(1ULL << i); } return -EINVAL; }
static int nv10_fifo_chan_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { struct nv04_fifo_priv *priv = (void *)engine; struct nv04_fifo_chan *chan; struct nv03_channel_dma_class *args = data; int ret; if (size < sizeof(*args)) return -EINVAL; ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0x800000, 0x10000, args->pushbuf, (1ULL << NVDEV_ENGINE_DMAOBJ) | (1ULL << NVDEV_ENGINE_SW) | (1ULL << NVDEV_ENGINE_GR), &chan); *pobject = nv_object(chan); if (ret) return ret; nv_parent(chan)->object_attach = nv04_fifo_object_attach; nv_parent(chan)->object_detach = nv04_fifo_object_detach; nv_parent(chan)->context_attach = nv04_fifo_context_attach; chan->ramfc = chan->base.chid * 32; nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->offset); nv_wo32(priv->ramfc, chan->ramfc + 0x04, args->offset); nv_wo32(priv->ramfc, chan->ramfc + 0x0c, chan->base.pushgpu->addr >> 4); nv_wo32(priv->ramfc, chan->ramfc + 0x14, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | #ifdef __BIG_ENDIAN NV_PFIFO_CACHE1_BIG_ENDIAN | #endif NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8); return 0; }
static int nv50_disp_mast_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { struct nv50_display_mast_class *args = data; struct nv50_disp_dmac *mast; int ret; if (size < sizeof(*args)) return -EINVAL; ret = nv50_disp_dmac_create_(parent, engine, oclass, args->pushbuf, 0, sizeof(*mast), (void **)&mast); *pobject = nv_object(mast); if (ret) return ret; nv_parent(mast)->object_attach = nv50_disp_dmac_object_attach; nv_parent(mast)->object_detach = nv50_disp_dmac_object_detach; return 0; }
void _nouveau_parent_dtor(struct nouveau_object *object) { nouveau_parent_destroy(nv_parent(object)); }
void _nvkm_parent_dtor(struct nvkm_object *object) { nvkm_parent_destroy(nv_parent(object)); }