From 07a51882863d9e45b0715dcffbb66491adf2fb4e Mon Sep 17 00:00:00 2001 From: Ben Skeggs 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 --- 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 946748a..9b69328 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 24b3d03..0cf1bee 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -504,6 +504,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 be85960..896f6ae 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -563,7 +563,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 */ @@ -613,10 +613,10 @@ out_irq: out_display: engine->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); @@ -655,7 +655,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); } @@ -861,6 +861,21 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) if (ret) goto err_mmio; + 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.2