aboutsummaryrefslogtreecommitdiff
path: root/shared-core/nouveau_irq.c
diff options
context:
space:
mode:
authorBen Skeggs <skeggsb@gmail.com>2007-10-16 13:27:27 +1100
committerBen Skeggs <skeggsb@gmail.com>2007-10-16 13:27:27 +1100
commit6398325ba11da8a01c72f6203af0a2e4b43125c2 (patch)
treed56731b305475fde2278429a4337e2d3d52c6d3f /shared-core/nouveau_irq.c
parent30353c8efcc026ee8940f3eadab084c42a3acd4e (diff)
nouveau: Handle multiple PFIFO exceptions per irq, cleanup output.
Diffstat (limited to 'shared-core/nouveau_irq.c')
-rw-r--r--shared-core/nouveau_irq.c80
1 files changed, 39 insertions, 41 deletions
diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c
index 7ba45700..5a696d5e 100644
--- a/shared-core/nouveau_irq.c
+++ b/shared-core/nouveau_irq.c
@@ -63,58 +63,56 @@ void nouveau_irq_uninstall(struct drm_device *dev)
static void nouveau_fifo_irq_handler(struct drm_device *dev)
{
- uint32_t status, chmode, chstat, channel;
struct drm_nouveau_private *dev_priv = dev->dev_private;
+ uint32_t status;
- status = NV_READ(NV03_PFIFO_INTR_0);
- if (!status)
- return;
- chmode = NV_READ(NV04_PFIFO_MODE);
- chstat = NV_READ(NV04_PFIFO_DMA);
- channel=NV_READ(NV03_PFIFO_CACHE1_PUSH1)&(nouveau_fifo_number(dev)-1);
-
- if (status & NV_PFIFO_INTR_CACHE_ERROR) {
- uint32_t c1get, c1method, c1data;
+ while ((status = NV_READ(NV03_PFIFO_INTR_0))) {
+ uint32_t chid, get;
+
+ NV_WRITE(NV03_PFIFO_CACHES, 0);
+
+ chid = NV_READ(NV03_PFIFO_CACHE1_PUSH1) &
+ (nouveau_fifo_number(dev) - 1);
+ get = NV_READ(NV03_PFIFO_CACHE1_GET);
+
+ if (status & NV_PFIFO_INTR_CACHE_ERROR) {
+ uint32_t mthd, data;
+ int ptr;
+
+ ptr = get >> 2;
+ if (dev_priv->card_type < NV_40) {
+ mthd = NV_READ(NV04_PFIFO_CACHE1_METHOD(ptr));
+ data = NV_READ(NV04_PFIFO_CACHE1_DATA(ptr));
+ } else {
+ mthd = NV_READ(NV40_PFIFO_CACHE1_METHOD(ptr));
+ data = NV_READ(NV40_PFIFO_CACHE1_DATA(ptr));
+ }
- DRM_ERROR("PFIFO error interrupt\n");
+ DRM_INFO("PFIFO_CACHE_ERROR - "
+ "Ch %d/%d Mthd 0x%04x Data 0x%08x\n",
+ chid, (mthd >> 13) & 7, mthd & 0x1ffc, data);
- c1get = NV_READ(NV03_PFIFO_CACHE1_GET) >> 2;
- if (dev_priv->card_type < NV_40) {
- /* Untested, so it may not work.. */
- c1method = NV_READ(NV04_PFIFO_CACHE1_METHOD(c1get));
- c1data = NV_READ(NV04_PFIFO_CACHE1_DATA(c1get));
- } else {
- c1method = NV_READ(NV40_PFIFO_CACHE1_METHOD(c1get));
- c1data = NV_READ(NV40_PFIFO_CACHE1_DATA(c1get));
+ status &= ~NV_PFIFO_INTR_CACHE_ERROR;
+ NV_WRITE(NV03_PFIFO_INTR_0, NV_PFIFO_INTR_CACHE_ERROR);
}
- DRM_ERROR("Channel %d/%d - Method 0x%04x, Data 0x%08x\n",
- channel, (c1method >> 13) & 7, c1method & 0x1ffc,
- c1data);
-
- status &= ~NV_PFIFO_INTR_CACHE_ERROR;
- NV_WRITE(NV03_PFIFO_INTR_0, NV_PFIFO_INTR_CACHE_ERROR);
- }
-
- if (status & NV_PFIFO_INTR_DMA_PUSHER) {
- DRM_ERROR("PFIFO DMA pusher interrupt: ch%d, 0x%08x\n",
- channel, NV_READ(NV04_PFIFO_CACHE1_DMA_GET));
+ if (status & NV_PFIFO_INTR_DMA_PUSHER) {
+ DRM_INFO("PFIFO_DMA_PUSHER - Ch %d\n", chid);
- status &= ~NV_PFIFO_INTR_DMA_PUSHER;
- NV_WRITE(NV03_PFIFO_INTR_0, NV_PFIFO_INTR_DMA_PUSHER);
+ status &= ~NV_PFIFO_INTR_DMA_PUSHER;
+ NV_WRITE(NV03_PFIFO_INTR_0, NV_PFIFO_INTR_DMA_PUSHER);
- NV_WRITE(NV04_PFIFO_CACHE1_DMA_STATE, 0x00000000);
- if (NV_READ(NV04_PFIFO_CACHE1_DMA_PUT)!=NV_READ(NV04_PFIFO_CACHE1_DMA_GET))
- {
- uint32_t getval=NV_READ(NV04_PFIFO_CACHE1_DMA_GET)+4;
- NV_WRITE(NV04_PFIFO_CACHE1_DMA_GET,getval);
+ NV_WRITE(NV04_PFIFO_CACHE1_DMA_STATE, 0x00000000);
+ if (NV_READ(NV04_PFIFO_CACHE1_DMA_PUT) != get)
+ NV_WRITE(NV04_PFIFO_CACHE1_DMA_GET, get + 4);
}
- }
- if (status) {
- DRM_ERROR("Unhandled PFIFO interrupt: status=0x%08x\n", status);
+ if (status) {
+ DRM_INFO("Unhandled PFIFO_INTR - 0x%8x\n", status);
+ NV_WRITE(NV03_PFIFO_INTR_0, status);
+ }
- NV_WRITE(NV03_PFIFO_INTR_0, status);
+ NV_WRITE(NV03_PFIFO_CACHES, 1);
}
NV_WRITE(NV03_PMC_INTR_0, NV_PMC_INTR_0_PFIFO_PENDING);