[Nouveau] [PATCH 5/6] drm/nv50: make the pgraph irq handler loop like the pre-nv50 version

Maarten Maathuis madman2003 at gmail.com
Tue Feb 2 13:36:04 PST 2010


- Unset the bit that indicates that a ctxprog can continue at the end.

Signed-off-by: Maarten Maathuis <madman2003 at gmail.com>
---
 drivers/gpu/drm/nouveau/nouveau_irq.c |  139 ++++++++++++++++++---------------
 1 files changed, 75 insertions(+), 64 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c
index 3e46b85..e21bec3 100644
--- a/drivers/gpu/drm/nouveau/nouveau_irq.c
+++ b/drivers/gpu/drm/nouveau/nouveau_irq.c
@@ -580,86 +580,97 @@ nouveau_pgraph_irq_handler(struct drm_device *dev)
 static void
 nv50_pgraph_irq_handler(struct drm_device *dev)
 {
-	uint32_t status, nsource;
+	uint32_t status;
 
-	status = nv_rd32(dev, NV03_PGRAPH_INTR);
-	nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE);
+	while ((status = nv_rd32(dev, NV03_PGRAPH_INTR))) {
+		uint32_t nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE);
 
-	if (status & 0x00000001) {
-		nouveau_pgraph_intr_notify(dev, nsource);
-		status &= ~0x00000001;
-		nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000001);
-	}
+		if (status & 0x00000001) {
+			nouveau_pgraph_intr_notify(dev, nsource);
+			status &= ~0x00000001;
+			nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000001);
+		}
 
-	if (status & 0x00000010) {
-		nouveau_pgraph_intr_error(dev, nsource |
-					  NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD);
+		if (status & 0x00000010) {
+			nouveau_pgraph_intr_error(dev, nsource |
+						  NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD);
 
-		status &= ~0x00000010;
-		nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000010);
-	}
+			status &= ~0x00000010;
+			nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000010);
+		}
 
-	if (status & 0x00001000) {
-		nv_wr32(dev, 0x400500, 0x00000000);
-		nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH);
-		nv_wr32(dev, NV40_PGRAPH_INTR_EN, nv_rd32(dev,
-			NV40_PGRAPH_INTR_EN) & ~NV_PGRAPH_INTR_CONTEXT_SWITCH);
-		nv_wr32(dev, 0x400500, 0x00010001);
+		if (status & 0x00001000) {
+			nv_wr32(dev, 0x400500, 0x00000000);
+			nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH);
+			nv_wr32(dev, NV40_PGRAPH_INTR_EN, nv_rd32(dev,
+				NV40_PGRAPH_INTR_EN) & ~NV_PGRAPH_INTR_CONTEXT_SWITCH);
+			nv_wr32(dev, 0x400500, 0x00010001);
 
-		nv50_graph_context_switch(dev);
+			nv50_graph_context_switch(dev);
 
-		status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
-	}
+			status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
+		}
 
-	if (status & 0x00100000) {
-		nouveau_pgraph_intr_error(dev, nsource |
-					  NV03_PGRAPH_NSOURCE_DATA_ERROR);
+		if (status & 0x00100000) {
+			nouveau_pgraph_intr_error(dev, nsource |
+						  NV03_PGRAPH_NSOURCE_DATA_ERROR);
 
-		status &= ~0x00100000;
-		nv_wr32(dev, NV03_PGRAPH_INTR, 0x00100000);
-	}
+			status &= ~0x00100000;
+			nv_wr32(dev, NV03_PGRAPH_INTR, 0x00100000);
+		}
 
-	if (status & 0x00200000) {
-		int r;
-
-		nouveau_pgraph_intr_error(dev, nsource |
-					  NV03_PGRAPH_NSOURCE_PROTECTION_ERROR);
-
-		NV_ERROR(dev, "magic set 1:\n");
-		for (r = 0x408900; r <= 0x408910; r += 4)
-			NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(dev, r));
-		nv_wr32(dev, 0x408900, nv_rd32(dev, 0x408904) | 0xc0000000);
-		for (r = 0x408e08; r <= 0x408e24; r += 4)
-			NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(dev, r));
-		nv_wr32(dev, 0x408e08, nv_rd32(dev, 0x408e08) | 0xc0000000);
-
-		NV_ERROR(dev, "magic set 2:\n");
-		for (r = 0x409900; r <= 0x409910; r += 4)
-			NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(dev, r));
-		nv_wr32(dev, 0x409900, nv_rd32(dev, 0x409904) | 0xc0000000);
-		for (r = 0x409e08; r <= 0x409e24; r += 4)
-			NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(dev, r));
-		nv_wr32(dev, 0x409e08, nv_rd32(dev, 0x409e08) | 0xc0000000);
-
-		status &= ~0x00200000;
-		nv_wr32(dev, NV03_PGRAPH_NSOURCE, nsource);
-		nv_wr32(dev, NV03_PGRAPH_INTR, 0x00200000);
-	}
+		if (status & 0x00200000) {
+			int r;
+
+			nouveau_pgraph_intr_error(dev, nsource |
+					NV03_PGRAPH_NSOURCE_PROTECTION_ERROR);
+
+			NV_ERROR(dev, "magic set 1:\n");
+			for (r = 0x408900; r <= 0x408910; r += 4)
+				NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
+					nv_rd32(dev, r));
+			nv_wr32(dev, 0x408900,
+				nv_rd32(dev, 0x408904) | 0xc0000000);
+			for (r = 0x408e08; r <= 0x408e24; r += 4)
+				NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
+							nv_rd32(dev, r));
+			nv_wr32(dev, 0x408e08,
+				nv_rd32(dev, 0x408e08) | 0xc0000000);
+
+			NV_ERROR(dev, "magic set 2:\n");
+			for (r = 0x409900; r <= 0x409910; r += 4)
+				NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
+					nv_rd32(dev, r));
+			nv_wr32(dev, 0x409900,
+				nv_rd32(dev, 0x409904) | 0xc0000000);
+			for (r = 0x409e08; r <= 0x409e24; r += 4)
+				NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
+					nv_rd32(dev, r));
+			nv_wr32(dev, 0x409e08,
+				nv_rd32(dev, 0x409e08) | 0xc0000000);
+
+			status &= ~0x00200000;
+			nv_wr32(dev, NV03_PGRAPH_NSOURCE, nsource);
+			nv_wr32(dev, NV03_PGRAPH_INTR, 0x00200000);
+		}
 
-	if (status) {
-		NV_INFO(dev, "Unhandled PGRAPH_INTR - 0x%08x\n", status);
-		nv_wr32(dev, NV03_PGRAPH_INTR, status);
-	}
+		if (status) {
+			NV_INFO(dev, "Unhandled PGRAPH_INTR - 0x%08x\n",
+				status);
+			nv_wr32(dev, NV03_PGRAPH_INTR, status);
+		}
 
-	{
-		const int isb = (1 << 16) | (1 << 0);
+		{
+			const int isb = (1 << 16) | (1 << 0);
 
-		if ((nv_rd32(dev, 0x400500) & isb) != isb)
-			nv_wr32(dev, 0x400500, nv_rd32(dev, 0x400500) | isb);
-		nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31));
+			if ((nv_rd32(dev, 0x400500) & isb) != isb)
+				nv_wr32(dev, 0x400500,
+					nv_rd32(dev, 0x400500) | isb);
+		}
 	}
 
 	nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING);
+	nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31));
 }
 
 static void
-- 
1.6.6.1



More information about the Nouveau mailing list