]> Pileus Git - ~andy/linux/blobdiff - drivers/gpu/drm/nouveau/nvc0_fb.c
Merge branch 'staging-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
[~andy/linux] / drivers / gpu / drm / nouveau / nvc0_fb.c
index 08e6b118f021163b1959fdc0e8b5a4e68e9f5a38..5bf55038fd9238a4ec582f0d72b505dc3b804bd2 100644 (file)
@@ -32,6 +32,30 @@ struct nvc0_fb_priv {
        dma_addr_t r100c10;
 };
 
+static inline void
+nvc0_mfb_subp_isr(struct drm_device *dev, int unit, int subp)
+{
+       u32 subp_base = 0x141000 + (unit * 0x2000) + (subp * 0x400);
+       u32 stat = nv_rd32(dev, subp_base + 0x020);
+
+       if (stat) {
+               NV_INFO(dev, "PMFB%d_SUBP%d: 0x%08x\n", unit, subp, stat);
+               nv_wr32(dev, subp_base + 0x020, stat);
+       }
+}
+
+static void
+nvc0_mfb_isr(struct drm_device *dev)
+{
+       u32 units = nv_rd32(dev, 0x00017c);
+       while (units) {
+               u32 subp, unit = ffs(units) - 1;
+               for (subp = 0; subp < 2; subp++)
+                       nvc0_mfb_subp_isr(dev, unit, subp);
+               units &= ~(1 << unit);
+       }
+}
+
 static void
 nvc0_fb_destroy(struct drm_device *dev)
 {
@@ -39,6 +63,8 @@ nvc0_fb_destroy(struct drm_device *dev)
        struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
        struct nvc0_fb_priv *priv = pfb->priv;
 
+       nouveau_irq_unregister(dev, 25);
+
        if (priv->r100c10_page) {
                pci_unmap_page(dev->pdev, priv->r100c10, PAGE_SIZE,
                               PCI_DMA_BIDIRECTIONAL);
@@ -74,6 +100,7 @@ nvc0_fb_create(struct drm_device *dev)
                return -EFAULT;
        }
 
+       nouveau_irq_register(dev, 25, nvc0_mfb_isr);
        return 0;
 }