From 6398325ba11da8a01c72f6203af0a2e4b43125c2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 16 Oct 2007 13:27:27 +1100 Subject: [PATCH] nouveau: Handle multiple PFIFO exceptions per irq, cleanup output. --- shared-core/nouveau_irq.c | 78 +++++++++++++++++++-------------------- shared-core/nouveau_mem.c | 3 +- 2 files changed, 39 insertions(+), 42 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); + while ((status = NV_READ(NV03_PFIFO_INTR_0))) { + uint32_t chid, get; - if (status & NV_PFIFO_INTR_CACHE_ERROR) { - uint32_t c1get, c1method, c1data; + NV_WRITE(NV03_PFIFO_CACHES, 0); - DRM_ERROR("PFIFO error interrupt\n"); + chid = NV_READ(NV03_PFIFO_CACHE1_PUSH1) & + (nouveau_fifo_number(dev) - 1); + get = NV_READ(NV03_PFIFO_CACHE1_GET); - 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)); + 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_INFO("PFIFO_CACHE_ERROR - " + "Ch %d/%d Mthd 0x%04x Data 0x%08x\n", + chid, (mthd >> 13) & 7, mthd & 0x1ffc, data); + + 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); + if (status & NV_PFIFO_INTR_DMA_PUSHER) { + DRM_INFO("PFIFO_DMA_PUSHER - Ch %d\n", chid); - status &= ~NV_PFIFO_INTR_CACHE_ERROR; - NV_WRITE(NV03_PFIFO_INTR_0, NV_PFIFO_INTR_CACHE_ERROR); - } + status &= ~NV_PFIFO_INTR_DMA_PUSHER; + NV_WRITE(NV03_PFIFO_INTR_0, NV_PFIFO_INTR_DMA_PUSHER); - 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)); - - 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); diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index e2f0b38d..97691780 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -399,8 +399,7 @@ int nouveau_mem_init(struct drm_device *dev) } /*Note: this is *not* just NV50 code, but only used on NV50 for now */ - if (dev_priv->gart_info.type == NOUVEAU_GART_NONE && - dev_priv->card_type >= NV_50) { + if (dev_priv->gart_info.type == NOUVEAU_GART_NONE) { ret = nouveau_sgdma_init(dev); if (!ret) { ret = nouveau_sgdma_nottm_hack_init(dev);