Chuck Ebbert c2055fa
From 030e105efc9a29c7d34fb59fb0e0a40e54178299 Mon Sep 17 00:00:00 2001
Chuck Ebbert c2055fa
From: Ben Skeggs <bskeggs@redhat.com>
Chuck Ebbert c2055fa
Date: Wed, 30 Jun 2010 13:34:05 +1000
Chuck Ebbert c2055fa
Subject: [PATCH] drm/nouveau: disable acceleration on NVA3/NVA5/NVA8 by default
Chuck Ebbert c2055fa
Chuck Ebbert c2055fa
There's an GPU lockup problem for which the cause is currently unknown
Chuck Ebbert c2055fa
on these chipsets.
Chuck Ebbert c2055fa
Chuck Ebbert c2055fa
Until it's resolved, it's better to leave the user with a working system
Chuck Ebbert c2055fa
without acceleration than to have random lockups.
Chuck Ebbert c2055fa
Chuck Ebbert c2055fa
With this patch, acceleration will be off by default if a known problem
Chuck Ebbert c2055fa
chipset is detected, but can be re-enabled with nouveau.noaccel=0 on
Chuck Ebbert c2055fa
the kernel commandline.
Chuck Ebbert c2055fa
Chuck Ebbert c2055fa
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Chuck Ebbert c2055fa
Chuck Ebbert c2055fa
[ cebbert@redhat.com : Backport to F12 and fix some module parameter descriptions. ]
Chuck Ebbert c2055fa
---
Chuck Ebbert c2055fa
Chuck Ebbert c2055fa
--- a/drivers/gpu/drm/nouveau/nouveau_drv.c
Chuck Ebbert c2055fa
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.c
Chuck Ebbert c2055fa
@@ -75,11 +75,11 @@ int nouveau_ignorelid = 0;
Chuck Ebbert c2055fa
 int nouveau_ignorelid = 0;
Chuck Ebbert c2055fa
 module_param_named(ignorelid, nouveau_ignorelid, int, 0400);
Chuck Ebbert c2055fa
 
Chuck Ebbert c2055fa
-MODULE_PARM_DESC(noagp, "Disable all acceleration");
Chuck Ebbert c2055fa
+MODULE_PARM_DESC(noaccel, "Disable all acceleration");
Chuck Ebbert c2055fa
-int nouveau_noaccel = 0;
Chuck Ebbert c2055fa
+int nouveau_noaccel = -1;
Chuck Ebbert c2055fa
 module_param_named(noaccel, nouveau_noaccel, int, 0400);
Chuck Ebbert c2055fa
 
Chuck Ebbert c2055fa
-MODULE_PARM_DESC(noagp, "Disable fbcon acceleration");
Chuck Ebbert c2055fa
+MODULE_PARM_DESC(nofbaccel, "Disable fbcon acceleration");
Chuck Ebbert c2055fa
 int nouveau_nofbaccel = 0;
Chuck Ebbert c2055fa
 module_param_named(nofbaccel, nouveau_nofbaccel, int, 0400);
Chuck Ebbert c2055fa
 
Chuck Ebbert c2055fa
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
Chuck Ebbert c2055fa
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
Chuck Ebbert c2055fa
@@ -493,6 +493,7 @@ enum nouveau_card_type {
Chuck Ebbert c2055fa
 
Chuck Ebbert c2055fa
 struct drm_nouveau_private {
Chuck Ebbert c2055fa
 	struct drm_device *dev;
Chuck Ebbert c2055fa
+	bool noaccel;
Chuck Ebbert c2055fa
 	enum {
Chuck Ebbert c2055fa
 		NOUVEAU_CARD_INIT_DOWN,
Chuck Ebbert c2055fa
 		NOUVEAU_CARD_INIT_DONE,
Chuck Ebbert c2055fa
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
Chuck Ebbert c2055fa
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
Chuck Ebbert c2055fa
@@ -435,7 +435,7 @@ nouveau_card_init(struct drm_device *dev)
Chuck Ebbert c2055fa
 	if (ret)
Chuck Ebbert c2055fa
 		goto out_timer;
Chuck Ebbert c2055fa
 
Chuck Ebbert c2055fa
-	if (nouveau_noaccel)
Chuck Ebbert c2055fa
+	if (dev_priv->noaccel)
Chuck Ebbert c2055fa
 		engine->graph.accel_blocked = true;
Chuck Ebbert c2055fa
 	else {
Chuck Ebbert c2055fa
 		/* PGRAPH */
Chuck Ebbert c2055fa
@@ -491,10 +491,10 @@ out_display:
Chuck Ebbert c2055fa
 out_irq:
Chuck Ebbert c2055fa
 	drm_irq_uninstall(dev);
Chuck Ebbert c2055fa
 out_fifo:
Chuck Ebbert c2055fa
-	if (!nouveau_noaccel)
Chuck Ebbert c2055fa
+	if (!dev_priv->noaccel)
Chuck Ebbert c2055fa
 		engine->fifo.takedown(dev);
Chuck Ebbert c2055fa
 out_graph:
Chuck Ebbert c2055fa
-	if (!nouveau_noaccel)
Chuck Ebbert c2055fa
+	if (!dev_priv->noaccel)
Chuck Ebbert c2055fa
 		engine->graph.takedown(dev);
Chuck Ebbert c2055fa
 out_fb:
Chuck Ebbert c2055fa
 	engine->fb.takedown(dev);
Chuck Ebbert c2055fa
@@ -532,7 +532,7 @@ static void nouveau_card_takedown(struct drm_device *dev)
Chuck Ebbert c2055fa
 			dev_priv->channel = NULL;
Chuck Ebbert c2055fa
 		}
Chuck Ebbert c2055fa
 
Chuck Ebbert c2055fa
-		if (!nouveau_noaccel) {
Chuck Ebbert c2055fa
+		if (!dev_priv->noaccel) {
Chuck Ebbert c2055fa
 			engine->fifo.takedown(dev);
Chuck Ebbert c2055fa
 			engine->graph.takedown(dev);
Chuck Ebbert c2055fa
 		}
Chuck Ebbert c2055fa
@@ -691,6 +691,21 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
Chuck Ebbert c2055fa
 	NV_INFO(dev, "Detected an NV%2x generation card (0x%08x)\n",
Chuck Ebbert c2055fa
 		dev_priv->card_type, reg0);
Chuck Ebbert c2055fa
 
Chuck Ebbert c2055fa
+	if (nouveau_noaccel == -1) {
Chuck Ebbert c2055fa
+		switch (dev_priv->chipset) {
Chuck Ebbert c2055fa
+		case 0xa3:
Chuck Ebbert c2055fa
+		case 0xa5:
Chuck Ebbert c2055fa
+		case 0xa8:
Chuck Ebbert c2055fa
+			dev_priv->noaccel = true;
Chuck Ebbert c2055fa
+			break;
Chuck Ebbert c2055fa
+		default:
Chuck Ebbert c2055fa
+			dev_priv->noaccel = false;
Chuck Ebbert c2055fa
+			break;
Chuck Ebbert c2055fa
+		}
Chuck Ebbert c2055fa
+	} else {
Chuck Ebbert c2055fa
+		dev_priv->noaccel = (nouveau_noaccel != 0);
Chuck Ebbert c2055fa
+	}
Chuck Ebbert c2055fa
+
Chuck Ebbert c2055fa
 	/* map larger RAMIN aperture on NV40 cards */
Chuck Ebbert c2055fa
 	dev_priv->ramin  = NULL;
Chuck Ebbert c2055fa
 	if (dev_priv->card_type >= NV_40) {
Chuck Ebbert c2055fa
-- 
Chuck Ebbert c2055fa
1.7.2
Chuck Ebbert c2055fa