Blob Blame History Raw
From 030e105efc9a29c7d34fb59fb0e0a40e54178299 Mon Sep 17 00:00:00 2001
From: Ben Skeggs <bskeggs@redhat.com>
Date: Wed, 30 Jun 2010 13:34:05 +1000
Subject: [PATCH] drm/nouveau: disable acceleration on NVA3/NVA5/NVA8 by default

There's an GPU lockup problem for which the cause is currently unknown
on these chipsets.

Until it's resolved, it's better to leave the user with a working system
without acceleration than to have random lockups.

With this patch, acceleration will be off by default if a known problem
chipset is detected, but can be re-enabled with nouveau.noaccel=0 on
the kernel commandline.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
---
 drivers/gpu/drm/nouveau/nouveau_drv.c   |    2 +-
 drivers/gpu/drm/nouveau/nouveau_drv.h   |    1 +
 drivers/gpu/drm/nouveau/nouveau_state.c |   23 +++++++++++++++++++----
 3 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c
index b4d958c..02b564c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.c
@@ -72,7 +72,7 @@ int nouveau_ignorelid = 0;
 module_param_named(ignorelid, nouveau_ignorelid, int, 0400);
 
 MODULE_PARM_DESC(noaccel, "Disable all acceleration");
-int nouveau_noaccel = 0;
+int nouveau_noaccel = -1;
 module_param_named(noaccel, nouveau_noaccel, int, 0400);
 
 MODULE_PARM_DESC(nofbaccel, "Disable fbcon acceleration");
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 022648e..76ec783 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -493,6 +493,7 @@ enum nouveau_card_type {
 
 struct drm_nouveau_private {
 	struct drm_device *dev;
+	bool noaccel;
 
 	/* the card type, takes NV_* as values */
 	enum nouveau_card_type card_type;
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index 63c2d24..866f437 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -454,7 +454,7 @@ nouveau_card_init(struct drm_device *dev)
 	if (ret)
 		goto out_timer;
 
-	if (nouveau_noaccel)
+	if (dev_priv->noaccel)
 		engine->graph.accel_blocked = true;
 	else {
 		/* PGRAPH */
@@ -509,10 +509,10 @@ out_display:
 	else
 		nv04_display_destroy(dev);
 out_fifo:
-	if (!nouveau_noaccel)
+	if (!dev_priv->noaccel)
 		engine->fifo.takedown(dev);
 out_graph:
-	if (!nouveau_noaccel)
+	if (!dev_priv->noaccel)
 		engine->graph.takedown(dev);
 out_fb:
 	engine->fb.takedown(dev);
@@ -548,7 +548,7 @@ static void nouveau_card_takedown(struct drm_device *dev)
 		dev_priv->channel = NULL;
 	}
 
-	if (!nouveau_noaccel) {
+	if (!dev_priv->noaccel) {
 		engine->fifo.takedown(dev);
 		engine->graph.takedown(dev);
 	}
@@ -744,6 +744,21 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
 	if (ret)
 		return ret;
 
+	if (nouveau_noaccel == -1) {
+		switch (dev_priv->chipset) {
+		case 0xa3:
+		case 0xa5:
+		case 0xa8:
+			dev_priv->noaccel = true;
+			break;
+		default:
+			dev_priv->noaccel = false;
+			break;
+		}
+	} else {
+		dev_priv->noaccel = (nouveau_noaccel != 0);
+	}
+
 	/* Map PRAMIN BAR, or on older cards, the aperture withing BAR0 */
 	if (dev_priv->card_type >= NV_40) {
 		int ramin_bar = 2;
-- 
1.7.2