From 5f05cd7086c54bccf1c2f0b003b78a08dc55472a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 24 Jun 2007 19:00:26 +1000 Subject: nouveau: NV04/NV10/NV20 PGRAPH engtab functions NV04/NV10 load_context()/save_context() are stubs. I don't know enough about how they work to implement them sanely. The "old" context_switch() code remains hooked up, so it shouldn't break anything. NV20 will probably break if load_context() works. No inital context values are filled in, so when the first channel is created PGRAPH will probably end up having its state zeroed. Some setup from nv20_graph_init() will probably need to be moved to the per-channel context setup. --- shared-core/nv20_graph.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) (limited to 'shared-core/nv20_graph.c') diff --git a/shared-core/nv20_graph.c b/shared-core/nv20_graph.c index 7190fc84..1b8a6727 100644 --- a/shared-core/nv20_graph.c +++ b/shared-core/nv20_graph.c @@ -29,7 +29,7 @@ #define NV20_GRCTX_SIZE (3529*4) -int nv20_graph_context_create(drm_device_t *dev, int channel) { +int nv20_graph_create_context(drm_device_t *dev, int channel) { drm_nouveau_private_t *dev_priv = (drm_nouveau_private_t *)dev->dev_private; struct nouveau_fifo *chan = &dev_priv->fifos[channel]; @@ -47,10 +47,21 @@ int nv20_graph_context_create(drm_device_t *dev, int channel) { INSTANCE_WR(chan->ramin_grctx, 10, channel << 24); /* CTX_USER */ INSTANCE_WR(dev_priv->ctx_table, channel, nouveau_chip_instance_get(dev, chan->ramin_grctx)); - return 0; } +void nv20_graph_destroy_context(drm_device_t *dev, int channel) { + drm_nouveau_private_t *dev_priv = dev->dev_private; + struct nouveau_fifo *chan = &dev_priv->fifos[channel]; + + if (chan->ramin_grctx) { + nouveau_instmem_free(dev, chan->ramin_grctx); + chan->ramin_grctx = NULL; + } + + INSTANCE_WR(dev_priv->ctx_table, channel, 0); +} + static void nv20_graph_rdi(drm_device_t *dev) { drm_nouveau_private_t *dev_priv = (drm_nouveau_private_t *)dev->dev_private; @@ -65,40 +76,42 @@ static void nv20_graph_rdi(drm_device_t *dev) { /* Save current context (from PGRAPH) into the channel's context */ -static void nv20_graph_context_save_current(drm_device_t *dev, int channel) { +int nv20_graph_save_context(drm_device_t *dev, int channel) { drm_nouveau_private_t *dev_priv = (drm_nouveau_private_t *)dev->dev_private; uint32_t instance; instance = INSTANCE_RD(dev_priv->ctx_table, channel); if (!instance) { - return; + return DRM_ERR(EINVAL); } if (instance != nouveau_chip_instance_get(dev, dev_priv->fifos[channel].ramin_grctx)) - DRM_ERROR("nv20_graph_context_save_current : bad instance\n"); + DRM_ERROR("nv20_graph_save_context : bad instance\n"); NV_WRITE(NV10_PGRAPH_CHANNEL_CTX_SIZE, instance); NV_WRITE(NV10_PGRAPH_CHANNEL_CTX_POINTER, 2 /* save ctx */); + return 0; } /* Restore the context for a specific channel into PGRAPH */ -static void nv20_graph_context_restore(drm_device_t *dev, int channel) { +int nv20_graph_load_context(drm_device_t *dev, int channel) { drm_nouveau_private_t *dev_priv = (drm_nouveau_private_t *)dev->dev_private; uint32_t instance; instance = INSTANCE_RD(dev_priv->ctx_table, channel); if (!instance) { - return; + return DRM_ERR(EINVAL); } if (instance != nouveau_chip_instance_get(dev, dev_priv->fifos[channel].ramin_grctx)) - DRM_ERROR("nv20_graph_context_restore_current : bad instance\n"); + DRM_ERROR("nv20_graph_load_context_current : bad instance\n"); NV_WRITE(NV10_PGRAPH_CTX_USER, channel << 24); NV_WRITE(NV10_PGRAPH_CHANNEL_CTX_SIZE, instance); NV_WRITE(NV10_PGRAPH_CHANNEL_CTX_POINTER, 1 /* restore ctx */); + return 0; } void nouveau_nv20_context_switch(drm_device_t *dev) @@ -113,13 +126,13 @@ void nouveau_nv20_context_switch(drm_device_t *dev) NV_WRITE(NV04_PGRAPH_FIFO,0x0); - nv20_graph_context_save_current(dev, channel_old); + nv20_graph_save_context(dev, channel_old); nouveau_wait_for_idle(dev); NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x10000000); - nv20_graph_context_restore(dev, channel); + nv20_graph_load_context(dev, channel); nouveau_wait_for_idle(dev); -- cgit v1.2.3