Beispiel #1
0
int
nv50_graph_create_context(struct nouveau_channel *chan)
{
	struct drm_device *dev = chan->dev;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_gpuobj *ramin = chan->ramin->gpuobj;
	struct nouveau_gpuobj *ctx;
	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
	int hdr, ret;

	NV_DEBUG(dev, "ch%d\n", chan->id);

	ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pgraph->grctx_size,
				     0x1000, NVOBJ_FLAG_ZERO_ALLOC |
				     NVOBJ_FLAG_ZERO_FREE, &chan->ramin_grctx);
	if (ret)
		return ret;
	ctx = chan->ramin_grctx->gpuobj;

	hdr = IS_G80 ? 0x200 : 0x20;
	dev_priv->engine.instmem.prepare_access(dev, true);
	nv_wo32(dev, ramin, (hdr + 0x00)/4, 0x00190002);
	nv_wo32(dev, ramin, (hdr + 0x04)/4, chan->ramin_grctx->instance +
					   pgraph->grctx_size - 1);
	nv_wo32(dev, ramin, (hdr + 0x08)/4, chan->ramin_grctx->instance);
	nv_wo32(dev, ramin, (hdr + 0x0c)/4, 0);
	nv_wo32(dev, ramin, (hdr + 0x10)/4, 0);
	nv_wo32(dev, ramin, (hdr + 0x14)/4, 0x00010000);
	dev_priv->engine.instmem.finish_access(dev);

	dev_priv->engine.instmem.prepare_access(dev, true);
	if (!pgraph->ctxprog) {
		struct nouveau_grctx ctx = {};
		ctx.dev = chan->dev;
		ctx.mode = NOUVEAU_GRCTX_VALS;
		ctx.data = chan->ramin_grctx->gpuobj;
		nv50_grctx_init(&ctx);
	} else {
		nouveau_grctx_vals_load(dev, ctx);
	}
	nv_wo32(dev, ctx, 0x00000/4, chan->ramin->instance >> 12);
	if ((dev_priv->chipset & 0xf0) == 0xa0)
		nv_wo32(dev, ctx, 0x00004/4, 0x00000000);
	else
		nv_wo32(dev, ctx, 0x0011c/4, 0x00000000);
	dev_priv->engine.instmem.finish_access(dev);

	return 0;
}
Beispiel #2
0
static int
nv50_graph_init_ctxctl(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;

	NV_DEBUG(dev, "\n");

	if (nouveau_ctxfw) {
		nouveau_grctx_prog_load(dev);
		dev_priv->engine.graph.grctx_size = 0x70000;
	}
	if (!dev_priv->engine.graph.ctxprog) {
		struct nouveau_grctx ctx = {};
		uint32_t *cp = kmalloc(512 * 4, GFP_KERNEL);
		int i;
		if (!cp) {
			NV_ERROR(dev, "Couldn't alloc ctxprog! Disabling acceleration.\n");
			dev_priv->engine.graph.accel_blocked = true;
			return 0;
		}
		ctx.dev = dev;
		ctx.mode = NOUVEAU_GRCTX_PROG;
		ctx.data = cp;
		ctx.ctxprog_max = 512;
		if (!nv50_grctx_init(&ctx)) {
			dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4;

			nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
			for (i = 0; i < ctx.ctxprog_len; i++)
				nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]);
		} else {
			dev_priv->engine.graph.accel_blocked = true;
		}
		kfree(cp);
	}

	nv_wr32(dev, 0x400320, 4);
	nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0);
	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, 0);
	return 0;
}
Beispiel #3
0
static int
nv50_graph_context_new(struct nouveau_channel *chan, int engine)
{
	struct drm_device *dev = chan->dev;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_gpuobj *ramin = chan->ramin;
	struct nouveau_gpuobj *grctx = NULL;
	struct nv50_graph_engine *pgraph = nv_engine(dev, engine);
	struct nouveau_grctx ctx = {};
	int hdr, ret;

	NV_DEBUG(dev, "ch%d\n", chan->id);

	ret = nouveau_gpuobj_new(dev, NULL, pgraph->grctx_size, 0,
				 NVOBJ_FLAG_ZERO_ALLOC |
				 NVOBJ_FLAG_ZERO_FREE, &grctx);
	if (ret)
		return ret;

	hdr = (dev_priv->chipset == 0x50) ? 0x200 : 0x20;
	nv_wo32(ramin, hdr + 0x00, 0x00190002);
	nv_wo32(ramin, hdr + 0x04, grctx->vinst + grctx->size - 1);
	nv_wo32(ramin, hdr + 0x08, grctx->vinst);
	nv_wo32(ramin, hdr + 0x0c, 0);
	nv_wo32(ramin, hdr + 0x10, 0);
	nv_wo32(ramin, hdr + 0x14, 0x00010000);

	ctx.dev = chan->dev;
	ctx.mode = NOUVEAU_GRCTX_VALS;
	ctx.data = grctx;
	nv50_grctx_init(&ctx);

	nv_wo32(grctx, 0x00000, chan->ramin->vinst >> 12);

	dev_priv->engine.instmem.flush(dev);

	atomic_inc(&chan->vm->engref[NVOBJ_ENGINE_GR]);
	chan->engctx[NVOBJ_ENGINE_GR] = grctx;
	return 0;
}
Beispiel #4
0
int
nv50_graph_create_context(struct nouveau_channel *chan)
{
	struct drm_device *dev = chan->dev;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_gpuobj *ramin = chan->ramin;
	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
	struct nouveau_grctx ctx = {};
	int hdr, ret;

	NV_DEBUG(dev, "ch%d\n", chan->id);

	ret = nouveau_gpuobj_new(dev, chan, pgraph->grctx_size, 0,
				 NVOBJ_FLAG_ZERO_ALLOC |
				 NVOBJ_FLAG_ZERO_FREE, &chan->ramin_grctx);
	if (ret)
		return ret;

	hdr = (dev_priv->chipset == 0x50) ? 0x200 : 0x20;
	nv_wo32(ramin, hdr + 0x00, 0x00190002);
	nv_wo32(ramin, hdr + 0x04, chan->ramin_grctx->vinst +
				   pgraph->grctx_size - 1);
	nv_wo32(ramin, hdr + 0x08, chan->ramin_grctx->vinst);
	nv_wo32(ramin, hdr + 0x0c, 0);
	nv_wo32(ramin, hdr + 0x10, 0);
	nv_wo32(ramin, hdr + 0x14, 0x00010000);

	ctx.dev = chan->dev;
	ctx.mode = NOUVEAU_GRCTX_VALS;
	ctx.data = chan->ramin_grctx;
	nv50_grctx_init(&ctx);

	nv_wo32(chan->ramin_grctx, 0x00000, chan->ramin->vinst >> 12);

	dev_priv->engine.instmem.flush(dev);
	atomic_inc(&chan->vm->pgraph_refs);
	return 0;
}