コード例 #1
0
ファイル: gpuobj.c プロジェクト: 383530895/linux
void
_nouveau_gpuobj_wr32(struct nouveau_object *object, u64 addr, u32 data)
{
	struct nouveau_gpuobj *gpuobj = nv_gpuobj(object);
	struct nouveau_ofuncs *pfuncs = nv_ofuncs(gpuobj->parent);
	if (gpuobj->node)
		addr += gpuobj->node->offset;
	pfuncs->wr32(gpuobj->parent, addr, data);
}
コード例 #2
0
ファイル: gpuobj.c プロジェクト: 383530895/linux
u32
_nouveau_gpuobj_rd32(struct nouveau_object *object, u64 addr)
{
	struct nouveau_gpuobj *gpuobj = nv_gpuobj(object);
	struct nouveau_ofuncs *pfuncs = nv_ofuncs(gpuobj->parent);
	if (gpuobj->node)
		addr += gpuobj->node->offset;
	return pfuncs->rd32(gpuobj->parent, addr);
}
コード例 #3
0
ファイル: nvd0.c プロジェクト: thornbirdblue/linux
static int
nvd0_disp_dmac_object_attach(struct nouveau_object *parent,
                             struct nouveau_object *object, u32 name)
{
    struct nv50_disp_base *base = (void *)parent->parent;
    struct nv50_disp_chan *chan = (void *)parent;
    u32 addr = nv_gpuobj(object)->node->offset;
    u32 data = (chan->chid << 27) | (addr << 9) | 0x00000001;
    return nouveau_ramht_insert(base->ramht, chan->chid, name, data);
}
コード例 #4
0
ファイル: gpuobj.c プロジェクト: 383530895/linux
void
nouveau_gpuobj_destroy(struct nouveau_gpuobj *gpuobj)
{
	int i;

	if (gpuobj->flags & NVOBJ_FLAG_ZERO_FREE) {
		for (i = 0; i < gpuobj->size; i += 4)
			nv_wo32(gpuobj, i, 0x00000000);
	}

	if (gpuobj->node) {
		nouveau_mm_free(&nv_gpuobj(gpuobj->parent)->heap,
				&gpuobj->node);
	}

	if (gpuobj->heap.block_size)
		nouveau_mm_fini(&gpuobj->heap);

	nouveau_object_destroy(&gpuobj->base);
}
コード例 #5
0
ファイル: nv50.c プロジェクト: AdrianHuang/linux-3.8.13
static int
nv50_graph_context_ctor(struct nouveau_object *parent,
			struct nouveau_object *engine,
			struct nouveau_oclass *oclass, void *data, u32 size,
			struct nouveau_object **pobject)
{
	struct nv50_graph_priv *priv = (void *)engine;
	struct nv50_graph_chan *chan;
	int ret;

	ret = nouveau_graph_context_create(parent, engine, oclass, NULL,
					   priv->size, 0,
					   NVOBJ_FLAG_ZERO_ALLOC, &chan);
	*pobject = nv_object(chan);
	if (ret)
		return ret;

	nv50_grctx_fill(nv_device(priv), nv_gpuobj(chan));
	return 0;
}
コード例 #6
0
static int
nv50_software_mthd_dma_vblsem(struct nouveau_object *object, u32 mthd,
			      void *args, u32 size)
{
	struct nv50_software_chan *chan = (void *)nv_engctx(object->parent);
	struct nouveau_fifo_chan *fifo = (void *)nv_object(chan)->parent;
	struct nouveau_handle *handle;
	int ret = -EINVAL;

	handle = nouveau_namedb_get(nv_namedb(fifo), *(u32 *)args);
	if (!handle)
		return -ENOENT;

	if (nv_iclass(handle->object, NV_GPUOBJ_CLASS)) {
		struct nouveau_gpuobj *gpuobj = nv_gpuobj(handle->object);
		chan->vblank.ctxdma = gpuobj->node->offset >> 4;
		ret = 0;
	}
	nouveau_namedb_put(handle);
	return ret;
}
コード例 #7
0
ファイル: nouveau_core_ramht.c プロジェクト: ryo/netbsd-src
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;
}
コード例 #8
0
ファイル: gpuobj.c プロジェクト: 383530895/linux
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;
}
コード例 #9
0
ファイル: gpuobj.c プロジェクト: 383530895/linux
int
_nouveau_gpuobj_fini(struct nouveau_object *object, bool suspend)
{
	return nouveau_gpuobj_fini(nv_gpuobj(object), suspend);
}
コード例 #10
0
ファイル: gpuobj.c プロジェクト: 383530895/linux
int
_nouveau_gpuobj_init(struct nouveau_object *object)
{
	return nouveau_gpuobj_init(nv_gpuobj(object));
}
コード例 #11
0
ファイル: gpuobj.c プロジェクト: 383530895/linux
void
_nouveau_gpuobj_dtor(struct nouveau_object *object)
{
	nouveau_gpuobj_destroy(nv_gpuobj(object));
}
コード例 #12
0
int
nvc0_graph_context_ctor(struct nouveau_object *parent,
			struct nouveau_object *engine,
			struct nouveau_oclass *oclass, void *args, u32 size,
			struct nouveau_object **pobject)
{
	struct nouveau_vm *vm = nouveau_client(parent)->vm;
	struct nvc0_graph_priv *priv = (void *)engine;
	struct nvc0_graph_data *data = priv->mmio_data;
	struct nvc0_graph_mmio *mmio = priv->mmio_list;
	struct nvc0_graph_chan *chan;
	int ret, i;

	/* allocate memory for context, and fill with default values */
	ret = nouveau_graph_context_create(parent, engine, oclass, NULL,
					   priv->size, 0x100,
					   NVOBJ_FLAG_ZERO_ALLOC, &chan);
	*pobject = nv_object(chan);
	if (ret)
		return ret;

	/* allocate memory for a "mmio list" buffer that's used by the HUB
	 * fuc to modify some per-context register settings on first load
	 * of the context.
	 */
	ret = nouveau_gpuobj_new(nv_object(chan), NULL, 0x1000, 0x100, 0,
				&chan->mmio);
	if (ret)
		return ret;

	ret = nouveau_gpuobj_map_vm(nv_gpuobj(chan->mmio), vm,
				    NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS,
				    &chan->mmio_vma);
	if (ret)
		return ret;

	/* allocate buffers referenced by mmio list */
	for (i = 0; data->size && i < ARRAY_SIZE(priv->mmio_data); i++) {
		ret = nouveau_gpuobj_new(nv_object(chan), NULL, data->size,
					 data->align, 0, &chan->data[i].mem);
		if (ret)
			return ret;

		ret = nouveau_gpuobj_map_vm(chan->data[i].mem, vm, data->access,
					   &chan->data[i].vma);
		if (ret)
			return ret;

		data++;
	}

	/* finally, fill in the mmio list and point the context at it */
	for (i = 0; mmio->addr && i < ARRAY_SIZE(priv->mmio_list); i++) {
		u32 addr = mmio->addr;
		u32 data = mmio->data;

		if (mmio->shift) {
			u64 info = chan->data[mmio->buffer].vma.offset;
			data |= info >> mmio->shift;
		}

		nv_wo32(chan->mmio, chan->mmio_nr++ * 4, addr);
		nv_wo32(chan->mmio, chan->mmio_nr++ * 4, data);
		mmio++;
	}