diff options
-rw-r--r-- | shared-core/nouveau_drv.h | 7 | ||||
-rw-r--r-- | shared-core/nouveau_fifo.c | 9 | ||||
-rw-r--r-- | shared-core/nouveau_state.c | 4 | ||||
-rw-r--r-- | shared-core/nv30_graph.c | 66 |
4 files changed, 74 insertions, 12 deletions
diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index c7872c33..a4a37648 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -292,9 +292,12 @@ extern void nv20_graph_takedown(drm_device_t *dev); extern int nv20_graph_context_create(drm_device_t *dev, int channel); /* nv30_graph.c */ -extern int nv30_graph_init(drm_device_t *dev); +extern int nv30_graph_init(drm_device_t *dev); extern void nv30_graph_takedown(drm_device_t *dev); -extern int nv30_graph_context_create(drm_device_t *dev, int channel); +extern int nv30_graph_create_context(drm_device_t *, int channel); +extern void nv30_graph_destroy_context(drm_device_t *, int channel); +extern int nv30_graph_load_context(drm_device_t *, int channel); +extern int nv30_graph_save_context(drm_device_t *, int channel); /* nv40_graph.c */ extern int nv40_graph_init(drm_device_t *); diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 0a883647..1ef5a425 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -306,13 +306,6 @@ static int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp) return ret; } break; - case NV_30: - ret = nv30_graph_context_create(dev, channel); - if (ret) { - nouveau_fifo_free(dev, channel); - return ret; - } - break; default: if (!engine->graph.create_context) { DRM_ERROR("graph.create_context == NULL\n"); @@ -388,8 +381,6 @@ void nouveau_fifo_free(drm_device_t* dev, int channel) drm_nouveau_private_t *dev_priv = dev->dev_private; nouveau_engine_func_t *engine = &dev_priv->Engine; struct nouveau_fifo *chan = &dev_priv->fifos[channel]; - int i; - int ctx_size = nouveau_fifo_ctx_size(dev); chan->used = 0; DRM_INFO("%s: freeing fifo %d\n", __func__, channel); diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c index 55d10b8c..a997b075 100644 --- a/shared-core/nouveau_state.c +++ b/shared-core/nouveau_state.c @@ -143,6 +143,10 @@ static int nouveau_init_engine_ptrs(drm_device_t *dev) engine->fb.takedown = nv10_fb_takedown; engine->graph.init = nv30_graph_init; engine->graph.takedown = nv30_graph_takedown; + engine->graph.create_context = nv30_graph_create_context; + engine->graph.destroy_context = nv30_graph_destroy_context; + engine->graph.load_context = nv30_graph_load_context; + engine->graph.save_context = nv30_graph_save_context; engine->fifo.init = nouveau_fifo_init; engine->fifo.takedown = nouveau_stub_takedown; engine->fifo.create_context = nv10_fifo_create_context; diff --git a/shared-core/nv30_graph.c b/shared-core/nv30_graph.c index f4faadd8..9f064a0a 100644 --- a/shared-core/nv30_graph.c +++ b/shared-core/nv30_graph.c @@ -100,7 +100,7 @@ static void nv30_graph_context_init(drm_device_t *dev, struct mem_block *ctx) } -int nv30_graph_context_create(drm_device_t *dev, int channel) +int nv30_graph_create_context(drm_device_t *dev, int channel) { drm_nouveau_private_t *dev_priv = (drm_nouveau_private_t *)dev->dev_private; @@ -132,6 +132,70 @@ int nv30_graph_context_create(drm_device_t *dev, int channel) return 0; } +void nv30_graph_destroy_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]; + + if (chan->ramin_grctx) { + nouveau_instmem_free(dev, chan->ramin_grctx); + chan->ramin_grctx = NULL; + } + + INSTANCE_WR(dev_priv->ctx_table, channel, 0); +} + +static int +nouveau_graph_wait_idle(drm_device_t *dev) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + int tv = 1000; + + while (tv--) { + if (NV_READ(0x400700) == 0) + break; + } + + if (NV_READ(0x400700)) { + DRM_ERROR("timeout!\n"); + return DRM_ERR(EBUSY); + } + return 0; +} + +int nv30_graph_load_context(drm_device_t *dev, int channel) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + struct nouveau_fifo *chan = &dev_priv->fifos[channel]; + uint32_t inst; + + if (!chan->ramin_grctx) + return DRM_ERR(EINVAL); + inst = nouveau_chip_instance_get(dev, chan->ramin_grctx); + + NV_WRITE(0x400784, inst); + NV_WRITE(0x400788, 1); + + return nouveau_graph_wait_idle(dev); +} + +int nv30_graph_save_context(drm_device_t *dev, int channel) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + struct nouveau_fifo *chan = &dev_priv->fifos[channel]; + uint32_t inst; + + if (!chan->ramin_grctx) + return DRM_ERR(EINVAL); + inst = nouveau_chip_instance_get(dev, chan->ramin_grctx); + + NV_WRITE(0x400784, inst); + NV_WRITE(0x400788, 2); + + return nouveau_graph_wait_idle(dev); +} + int nv30_graph_init(drm_device_t *dev) { drm_nouveau_private_t *dev_priv = |