aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLucas Stach <dev@lynxeye.de>2013-08-27 20:00:50 -0400
committerBen Skeggs <bskeggs@redhat.com>2013-09-03 23:48:23 -0400
commita27e56996687e79416d69a7e6dc26f9d8fe06059 (patch)
tree4bd0338da3740423ebe98f48ad2e77cbd5766baa
parent4b31ebcf69a48d5d70cf26cea080bd0818fdd9af (diff)
drm/nouveau: use MSI interrupts
MSIs were only problematic on some old, broken chipsets. But now that we already see systems where PCI legacy interrupts are somewhat flaky, it's really time to move to MSIs. v2 (Ben Skeggs): blacklist BR02 boards Signed-off-by: Lucas Stach <dev@lynxeye.de> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/mc.h1
-rw-r--r--drivers/gpu/drm/nouveau/core/os.h1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/base.c24
3 files changed, 25 insertions, 1 deletions
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/mc.h b/drivers/gpu/drm/nouveau/core/include/subdev/mc.h
index 9d2cd2006250..ce6569f365a7 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/mc.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/mc.h
@@ -12,6 +12,7 @@ struct nouveau_mc_intr {
12struct nouveau_mc { 12struct nouveau_mc {
13 struct nouveau_subdev base; 13 struct nouveau_subdev base;
14 const struct nouveau_mc_intr *intr_map; 14 const struct nouveau_mc_intr *intr_map;
15 bool use_msi;
15}; 16};
16 17
17static inline struct nouveau_mc * 18static inline struct nouveau_mc *
diff --git a/drivers/gpu/drm/nouveau/core/os.h b/drivers/gpu/drm/nouveau/core/os.h
index d48683a82585..191e739f30d1 100644
--- a/drivers/gpu/drm/nouveau/core/os.h
+++ b/drivers/gpu/drm/nouveau/core/os.h
@@ -19,6 +19,7 @@
19#include <linux/reboot.h> 19#include <linux/reboot.h>
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/log2.h> 21#include <linux/log2.h>
22#include <linux/pm_runtime.h>
22 23
23#include <asm/unaligned.h> 24#include <asm/unaligned.h>
24 25
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/base.c b/drivers/gpu/drm/nouveau/core/subdev/mc/base.c
index 20f9a538746e..37712a6df923 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/mc/base.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include <subdev/mc.h> 25#include <subdev/mc.h>
26#include <linux/pm_runtime.h> 26#include <core/option.h>
27 27
28static irqreturn_t 28static irqreturn_t
29nouveau_mc_intr(int irq, void *arg) 29nouveau_mc_intr(int irq, void *arg)
@@ -47,6 +47,9 @@ nouveau_mc_intr(int irq, void *arg)
47 map++; 47 map++;
48 } 48 }
49 49
50 if (pmc->use_msi)
51 nv_wr08(pmc->base.base.parent, 0x00088068, 0xff);
52
50 if (intr) { 53 if (intr) {
51 nv_error(pmc, "unknown intr 0x%08x\n", stat); 54 nv_error(pmc, "unknown intr 0x%08x\n", stat);
52 } 55 }
@@ -81,6 +84,8 @@ _nouveau_mc_dtor(struct nouveau_object *object)
81 struct nouveau_device *device = nv_device(object); 84 struct nouveau_device *device = nv_device(object);
82 struct nouveau_mc *pmc = (void *)object; 85 struct nouveau_mc *pmc = (void *)object;
83 free_irq(device->pdev->irq, pmc); 86 free_irq(device->pdev->irq, pmc);
87 if (pmc->use_msi)
88 pci_disable_msi(device->pdev);
84 nouveau_subdev_destroy(&pmc->base); 89 nouveau_subdev_destroy(&pmc->base);
85} 90}
86 91
@@ -102,6 +107,23 @@ nouveau_mc_create_(struct nouveau_object *parent, struct nouveau_object *engine,
102 107
103 pmc->intr_map = intr_map; 108 pmc->intr_map = intr_map;
104 109
110 switch (device->pdev->device & 0x0ff0) {
111 case 0x00f0: /* BR02? */
112 case 0x02e0: /* BR02? */
113 pmc->use_msi = false;
114 break;
115 default:
116 pmc->use_msi = nouveau_boolopt(device->cfgopt, "NvMSI", true);
117 if (pmc->use_msi) {
118 pmc->use_msi = pci_enable_msi(device->pdev) == 0;
119 if (pmc->use_msi) {
120 nv_info(pmc, "MSI interrupts enabled\n");
121 nv_wr08(device, 0x00088068, 0xff);
122 }
123 }
124 break;
125 }
126
105 ret = request_irq(device->pdev->irq, nouveau_mc_intr, 127 ret = request_irq(device->pdev->irq, nouveau_mc_intr,
106 IRQF_SHARED, "nouveau", pmc); 128 IRQF_SHARED, "nouveau", pmc);
107 if (ret < 0) 129 if (ret < 0)