浏览代码

drm/nv50: create graph and crypt contexts on demand

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>
Ben Skeggs 14 年之前
父节点
当前提交
f4512e6579
共有 2 个文件被更改,包括 25 次插入9 次删除
  1. 2 9
      drivers/gpu/drm/nouveau/nouveau_channel.c
  2. 23 0
      drivers/gpu/drm/nouveau/nouveau_object.c

+ 2 - 9
drivers/gpu/drm/nouveau/nouveau_channel.c

@@ -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;

+ 23 - 0
drivers/gpu/drm/nouveau/nouveau_object.c

@@ -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,