aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/core/subdev
diff options
context:
space:
mode:
authorLucas Stach <dev@lynxeye.de>2013-08-28 02:00:50 +0200
committerBen Skeggs <bskeggs@redhat.com>2013-09-04 13:48:23 +1000
commita27e56996687e79416d69a7e6dc26f9d8fe06059 (patch)
tree4bd0338da3740423ebe98f48ad2e77cbd5766baa /drivers/gpu/drm/nouveau/core/subdev
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>
Diffstat (limited to 'drivers/gpu/drm/nouveau/core/subdev')
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/base.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/base.c b/drivers/gpu/drm/nouveau/core/subdev/mc/base.c
index 20f9a538746..37712a6df92 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 @@
*/
#include <subdev/mc.h>
-#include <linux/pm_runtime.h>
+#include <core/option.h>
static irqreturn_t
nouveau_mc_intr(int irq, void *arg)
@@ -47,6 +47,9 @@ nouveau_mc_intr(int irq, void *arg)
map++;
}
+ if (pmc->use_msi)
+ nv_wr08(pmc->base.base.parent, 0x00088068, 0xff);
+
if (intr) {
nv_error(pmc, "unknown intr 0x%08x\n", stat);
}
@@ -81,6 +84,8 @@ _nouveau_mc_dtor(struct nouveau_object *object)
struct nouveau_device *device = nv_device(object);
struct nouveau_mc *pmc = (void *)object;
free_irq(device->pdev->irq, pmc);
+ if (pmc->use_msi)
+ pci_disable_msi(device->pdev);
nouveau_subdev_destroy(&pmc->base);
}
@@ -102,6 +107,23 @@ nouveau_mc_create_(struct nouveau_object *parent, struct nouveau_object *engine,
pmc->intr_map = intr_map;
+ switch (device->pdev->device & 0x0ff0) {
+ case 0x00f0: /* BR02? */
+ case 0x02e0: /* BR02? */
+ pmc->use_msi = false;
+ break;
+ default:
+ pmc->use_msi = nouveau_boolopt(device->cfgopt, "NvMSI", true);
+ if (pmc->use_msi) {
+ pmc->use_msi = pci_enable_msi(device->pdev) == 0;
+ if (pmc->use_msi) {
+ nv_info(pmc, "MSI interrupts enabled\n");
+ nv_wr08(device, 0x00088068, 0xff);
+ }
+ }
+ break;
+ }
+
ret = request_irq(device->pdev->irq, nouveau_mc_intr,
IRQF_SHARED, "nouveau", pmc);
if (ret < 0)