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>
This commit is contained in:
Родитель
4b31ebcf69
Коммит
a27e569966
|
@ -12,6 +12,7 @@ struct nouveau_mc_intr {
|
|||
struct nouveau_mc {
|
||||
struct nouveau_subdev base;
|
||||
const struct nouveau_mc_intr *intr_map;
|
||||
bool use_msi;
|
||||
};
|
||||
|
||||
static inline struct nouveau_mc *
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <linux/reboot.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/log2.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Загрузка…
Ссылка в новой задаче