nouveau: NV3X PGRAPH engtab functions
authorBen Skeggs <skeggsb@gmail.com>
Sun, 24 Jun 2007 08:58:38 +0000 (18:58 +1000)
committerBen Skeggs <skeggsb@gmail.com>
Sun, 24 Jun 2007 08:58:38 +0000 (18:58 +1000)
shared-core/nouveau_drv.h
shared-core/nouveau_fifo.c
shared-core/nouveau_state.c
shared-core/nv30_graph.c

index c7872c3..a4a3764 100644 (file)
@@ -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 *);
index 0a88364..1ef5a42 100644 (file)
@@ -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);
index 55d10b8..a997b07 100644 (file)
@@ -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;
index f4faadd..9f064a0 100644 (file)
@@ -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 =