提交 a27e5699 编写于 作者: L Lucas Stach 提交者: Ben Skeggs

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: NLucas Stach <dev@lynxeye.de>
Signed-off-by: NBen Skeggs <bskeggs@redhat.com>
上级 4b31ebcf
...@@ -12,6 +12,7 @@ struct nouveau_mc_intr { ...@@ -12,6 +12,7 @@ struct nouveau_mc_intr {
struct nouveau_mc { struct nouveau_mc {
struct nouveau_subdev base; struct nouveau_subdev base;
const struct nouveau_mc_intr *intr_map; const struct nouveau_mc_intr *intr_map;
bool use_msi;
}; };
static inline struct nouveau_mc * static inline struct nouveau_mc *
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/log2.h> #include <linux/log2.h>
#include <linux/pm_runtime.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
*/ */
#include <subdev/mc.h> #include <subdev/mc.h>
#include <linux/pm_runtime.h> #include <core/option.h>
static irqreturn_t static irqreturn_t
nouveau_mc_intr(int irq, void *arg) nouveau_mc_intr(int irq, void *arg)
...@@ -47,6 +47,9 @@ nouveau_mc_intr(int irq, void *arg) ...@@ -47,6 +47,9 @@ nouveau_mc_intr(int irq, void *arg)
map++; map++;
} }
if (pmc->use_msi)
nv_wr08(pmc->base.base.parent, 0x00088068, 0xff);
if (intr) { if (intr) {
nv_error(pmc, "unknown intr 0x%08x\n", stat); nv_error(pmc, "unknown intr 0x%08x\n", stat);
} }
...@@ -81,6 +84,8 @@ _nouveau_mc_dtor(struct nouveau_object *object) ...@@ -81,6 +84,8 @@ _nouveau_mc_dtor(struct nouveau_object *object)
struct nouveau_device *device = nv_device(object); struct nouveau_device *device = nv_device(object);
struct nouveau_mc *pmc = (void *)object; struct nouveau_mc *pmc = (void *)object;
free_irq(device->pdev->irq, pmc); free_irq(device->pdev->irq, pmc);
if (pmc->use_msi)
pci_disable_msi(device->pdev);
nouveau_subdev_destroy(&pmc->base); nouveau_subdev_destroy(&pmc->base);
} }
...@@ -102,6 +107,23 @@ nouveau_mc_create_(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -102,6 +107,23 @@ nouveau_mc_create_(struct nouveau_object *parent, struct nouveau_object *engine,
pmc->intr_map = intr_map; 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, ret = request_irq(device->pdev->irq, nouveau_mc_intr,
IRQF_SHARED, "nouveau", pmc); IRQF_SHARED, "nouveau", pmc);
if (ret < 0) if (ret < 0)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册