drm/nv50: create graph and crypt contexts on demand
authorBen Skeggs <bskeggs@redhat.com>
Wed, 20 Oct 2010 01:47:09 +0000 (11:47 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 3 Dec 2010 05:10:44 +0000 (15:10 +1000)
This really needs cleaning up somehow, and probably investigate what's
needed to do this on earlier generations.  NVIDIA do something similar
there too.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nouveau_channel.c
drivers/gpu/drm/nouveau/nouveau_object.c

index 8f2df6b..f2d6742 100644 (file)
@@ -112,7 +112,6 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
        struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
-       struct nouveau_crypt_engine *pcrypt = &dev_priv->engine.crypt;
        struct nouveau_channel *chan;
        unsigned long flags;
        int user, ret;
@@ -209,14 +208,8 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
        pfifo->reassign(dev, false);
 
        /* Create a graphics context for new channel */
-       ret = pgraph->create_context(chan);
-       if (ret) {
-               nouveau_channel_put(&chan);
-               return ret;
-       }
-
-       if (pcrypt->create_context) {
-               ret = pcrypt->create_context(chan);
+       if (dev_priv->card_type < NV_50) {
+               ret = pgraph->create_context(chan);
                if (ret) {
                        nouveau_channel_put(&chan);
                        return ret;
index ee52653..5407818 100644 (file)
@@ -634,6 +634,29 @@ found:
        if (oc->engine == NVOBJ_ENGINE_SW)
                return nouveau_gpuobj_sw_new(chan, class, gpuobj);
 
+       switch (oc->engine) {
+       case NVOBJ_ENGINE_GR:
+               if (dev_priv->card_type >= NV_50 && !chan->ramin_grctx) {
+                       struct nouveau_pgraph_engine *pgraph =
+                               &dev_priv->engine.graph;
+
+                       ret = pgraph->create_context(chan);
+                       if (ret)
+                               return ret;
+               }
+               break;
+       case NVOBJ_ENGINE_CRYPT:
+               if (!chan->crypt_ctx) {
+                       struct nouveau_crypt_engine *pcrypt =
+                               &dev_priv->engine.crypt;
+
+                       ret = pcrypt->create_context(chan);
+                       if (ret)
+                               return ret;
+               }
+               break;
+       }
+
        ret = nouveau_gpuobj_new(dev, chan,
                                 nouveau_gpuobj_class_instmem_size(dev, class),
                                 16,