Skip to content

Commit

Permalink
drm/nouveau: use MSI interrupts
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Lucas Stach authored and Ben Skeggs committed Sep 4, 2013
1 parent 4b31ebc commit a27e569
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 1 deletion.
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/core/include/subdev/mc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/core/os.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand Down
24 changes: 23 additions & 1 deletion drivers/gpu/drm/nouveau/core/subdev/mc/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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);
}
Expand Down Expand Up @@ -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);
}

Expand All @@ -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)
Expand Down

0 comments on commit a27e569

Please sign in to comment.