aboutsummaryrefslogtreecommitdiff
path: root/shared-core/nouveau_irq.c
diff options
context:
space:
mode:
authorBen Skeggs <skeggsb@gmail.com>2008-05-02 00:06:22 +1000
committerBen Skeggs <skeggsb@gmail.com>2008-05-02 00:06:22 +1000
commite317dfdabfb836165fbe3b006e53a88a1bc7c264 (patch)
tree9703ac1749b0280cad0a1dca2790c55e47ab0a53 /shared-core/nouveau_irq.c
parentb92efd59565b9c63734b762b9d2be46447309007 (diff)
nv50: PGRAPH exception handling completely different from earlier chips
Diffstat (limited to 'shared-core/nouveau_irq.c')
-rw-r--r--shared-core/nouveau_irq.c49
1 files changed, 48 insertions, 1 deletions
diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c
index ec158d82..3e1e6e30 100644
--- a/shared-core/nouveau_irq.c
+++ b/shared-core/nouveau_irq.c
@@ -433,6 +433,49 @@ nouveau_pgraph_irq_handler(struct drm_device *dev)
}
static void
+nv50_pgraph_irq_handler(struct drm_device *dev)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ uint32_t status;
+
+ status = NV_READ(NV03_PGRAPH_INTR);
+
+ if (status & 0x00000020) {
+ nouveau_pgraph_intr_error(dev,
+ NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD);
+
+ status &= ~0x00000020;
+ NV_WRITE(NV03_PGRAPH_INTR, 0x00000020);
+ }
+
+ if (status & 0x00100000) {
+ nouveau_pgraph_intr_error(dev,
+ NV03_PGRAPH_NSOURCE_DATA_ERROR);
+
+ status &= ~0x00100000;
+ NV_WRITE(NV03_PGRAPH_INTR, 0x00100000);
+ }
+
+ if (status & 0x00200000) {
+ nouveau_pgraph_intr_error(dev,
+ NV03_PGRAPH_NSOURCE_PROTECTION_ERROR);
+
+ status &= ~0x00200000;
+ NV_WRITE(NV03_PGRAPH_INTR, 0x00200000);
+ }
+
+ if (status) {
+ DRM_INFO("Unhandled PGRAPH_INTR - 0x%08x\n", status);
+ NV_WRITE(NV03_PGRAPH_INTR, status);
+ }
+
+ if ((NV_READ(0x400500) & (1 << 16)) == 0)
+ NV_WRITE(0x400500, NV_READ(0x400500) | (1 << 16));
+
+ NV_WRITE(NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING);
+}
+
+static void
nouveau_crtc_irq_handler(struct drm_device *dev, int crtc)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -485,7 +528,11 @@ nouveau_irq_handler(DRM_IRQ_ARGS)
}
if (status & NV_PMC_INTR_0_PGRAPH_PENDING) {
- nouveau_pgraph_irq_handler(dev);
+ if (dev_priv->card_type >= NV_50)
+ nv50_pgraph_irq_handler(dev);
+ else
+ nouveau_pgraph_irq_handler(dev);
+
status &= ~NV_PMC_INTR_0_PGRAPH_PENDING;
}