From 173a5be28f4ed59e27d7a719f62bc275959b5b70 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 5 Nov 2007 02:20:35 +1100 Subject: nouveau: hook up an inital fence irq handler --- shared-core/nouveau_irq.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'shared-core/nouveau_irq.c') diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c index ac507299..ad9a6fcf 100644 --- a/shared-core/nouveau_irq.c +++ b/shared-core/nouveau_irq.c @@ -301,6 +301,13 @@ nouveau_pgraph_intr_notify(struct drm_device *dev, uint32_t nsource) int handled = 0; DRM_DEBUG("PGRAPH notify interrupt\n"); + + if (nsource & NV03_PGRAPH_NSOURCE_NOTIFICATION && dev_priv->ttm) { + int channel; + if (!nouveau_graph_trapped_channel(dev, &channel)) + nouveau_fence_handler(dev, channel); + } + if (dev_priv->card_type == NV_04 && (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD)) { uint32_t class, mthd; -- cgit v1.2.3 From c1008104adcd45faad2c6c1a2192c86447f3d9a3 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 5 Nov 2007 02:35:56 +1100 Subject: nouveau: only pass annoying messages if irq isn't handled fully. --- shared-core/nouveau_irq.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'shared-core/nouveau_irq.c') diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c index ad9a6fcf..e3fb62f4 100644 --- a/shared-core/nouveau_irq.c +++ b/shared-core/nouveau_irq.c @@ -298,16 +298,14 @@ static inline void nouveau_pgraph_intr_notify(struct drm_device *dev, uint32_t nsource) { struct drm_nouveau_private *dev_priv = dev->dev_private; - int handled = 0; - - DRM_DEBUG("PGRAPH notify interrupt\n"); + int unhandled = 0; if (nsource & NV03_PGRAPH_NSOURCE_NOTIFICATION && dev_priv->ttm) { int channel; - if (!nouveau_graph_trapped_channel(dev, &channel)) + if (!nouveau_graph_trapped_channel(dev, &channel)) { nouveau_fence_handler(dev, channel); - } - + } + } else if (dev_priv->card_type == NV_04 && (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD)) { uint32_t class, mthd; @@ -324,12 +322,13 @@ nouveau_pgraph_intr_notify(struct drm_device *dev, uint32_t nsource) DRM_ERROR("Unable to execute NV04 software method %x " "for object class %x. Please report.\n", mthd, class); - } else { - handled = 1; + unhandled = 1; } + } else { + unhandled = 1; } - if (!handled) + if (unhandled) nouveau_graph_dump_trap_info(dev, "PGRAPH_NOTIFY"); } -- cgit v1.2.3 From 0a2ab1a9003f132195fe70c145a78b4079a3fb7f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 5 Nov 2007 03:53:46 +1100 Subject: nouveau: cleanups --- shared-core/nouveau_irq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'shared-core/nouveau_irq.c') diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c index e3fb62f4..1a52a584 100644 --- a/shared-core/nouveau_irq.c +++ b/shared-core/nouveau_irq.c @@ -115,7 +115,7 @@ nouveau_fifo_irq_handler(struct drm_device *dev) } if (status) { - DRM_INFO("Unhandled PFIFO_INTR - 0x%8x\n", status); + DRM_INFO("Unhandled PFIFO_INTR - 0x%08x\n", status); NV_WRITE(NV03_PFIFO_INTR_0, status); } @@ -395,7 +395,7 @@ nouveau_pgraph_irq_handler(struct drm_device *dev) } if (status) { - DRM_INFO("Unhandled PGRAPH_INTR - 0x%8x\n", status); + DRM_INFO("Unhandled PGRAPH_INTR - 0x%08x\n", status); NV_WRITE(NV03_PGRAPH_INTR, status); } -- cgit v1.2.3 From 5092865601ccaae1409abfa083147276916d6c25 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 5 Nov 2007 05:42:08 +1100 Subject: nouveau: Use a sw method instead of notify interrupt to signal fence completion. --- shared-core/nouveau_irq.c | 97 +++++++++++++++++++++++++++++------------------ 1 file changed, 60 insertions(+), 37 deletions(-) (limited to 'shared-core/nouveau_irq.c') diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c index 1a52a584..08bd1da0 100644 --- a/shared-core/nouveau_irq.c +++ b/shared-core/nouveau_irq.c @@ -244,39 +244,53 @@ nouveau_graph_trapped_channel(struct drm_device *dev, int *channel_ret) return 0; } +struct nouveau_pgraph_trap { + int channel; + int class; + int subc, mthd, size; + uint32_t data, data2; +}; + static void -nouveau_graph_dump_trap_info(struct drm_device *dev, const char *id) +nouveau_graph_trap_info(struct drm_device *dev, + struct nouveau_pgraph_trap *trap) { struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t address; - uint32_t channel, class; - uint32_t method, subc, data, data2; - uint32_t nsource, nstatus; - if (nouveau_graph_trapped_channel(dev, &channel)) - channel = -1; - - data = NV_READ(NV04_PGRAPH_TRAPPED_DATA); + if (nouveau_graph_trapped_channel(dev, &trap->channel)) + trap->channel = -1; address = NV_READ(NV04_PGRAPH_TRAPPED_ADDR); - method = address & 0x1FFC; + + trap->mthd = address & 0x1FFC; + trap->data = NV_READ(NV04_PGRAPH_TRAPPED_DATA); if (dev_priv->card_type < NV_10) { - subc = (address >> 13) & 0x7; - data2= 0; + trap->subc = (address >> 13) & 0x7; } else { - subc = (address >> 16) & 0x7; - data2= NV_READ(NV10_PGRAPH_TRAPPED_DATA_HIGH); + trap->subc = (address >> 16) & 0x7; + trap->data2 = NV_READ(NV10_PGRAPH_TRAPPED_DATA_HIGH); } - nsource = NV_READ(NV03_PGRAPH_NSOURCE); - nstatus = NV_READ(NV03_PGRAPH_NSTATUS); + if (dev_priv->card_type < NV_10) { - class = NV_READ(0x400180 + subc*4) & 0xFF; + trap->class = NV_READ(0x400180 + trap->subc*4) & 0xFF; } else if (dev_priv->card_type < NV_40) { - class = NV_READ(0x400160 + subc*4) & 0xFFF; + trap->class = NV_READ(0x400160 + trap->subc*4) & 0xFFF; } else if (dev_priv->card_type < NV_50) { - class = NV_READ(0x400160 + subc*4) & 0xFFFF; + trap->class = NV_READ(0x400160 + trap->subc*4) & 0xFFFF; } else { - class = NV_READ(0x400814); + trap->class = NV_READ(0x400814); } +} + +static void +nouveau_graph_dump_trap_info(struct drm_device *dev, const char *id, + struct nouveau_pgraph_trap *trap) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t nsource, nstatus; + + nsource = NV_READ(NV03_PGRAPH_NSOURCE); + nstatus = NV_READ(NV03_PGRAPH_NSTATUS); DRM_INFO("%s - nSource:", id); nouveau_print_bitfield_names(nsource, nouveau_nsource_names, @@ -291,37 +305,29 @@ nouveau_graph_dump_trap_info(struct drm_device *dev, const char *id) printk("\n"); DRM_INFO("%s - Ch %d/%d Class 0x%04x Mthd 0x%04x Data 0x%08x:0x%08x\n", - id, channel, subc, class, method, data2, data); + id, trap->channel, trap->subc, trap->class, trap->mthd, + trap->data2, trap->data); } static inline void nouveau_pgraph_intr_notify(struct drm_device *dev, uint32_t nsource) { - struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_pgraph_trap trap; int unhandled = 0; - if (nsource & NV03_PGRAPH_NSOURCE_NOTIFICATION && dev_priv->ttm) { - int channel; - if (!nouveau_graph_trapped_channel(dev, &channel)) { - nouveau_fence_handler(dev, channel); - } - } else - if (dev_priv->card_type == NV_04 && - (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD)) { - uint32_t class, mthd; + nouveau_graph_trap_info(dev, &trap); + if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) { /* NV4 (nvidia TNT 1) reports software methods with * PGRAPH NOTIFY ILLEGAL_MTHD */ - mthd = NV_READ(NV04_PGRAPH_TRAPPED_ADDR) & 0x1FFC; - class = NV_READ(NV04_PGRAPH_CTX_SWITCH1) & 0xFFF; DRM_DEBUG("Got NV04 software method method %x for class %#x\n", - mthd, class); + trap.mthd, trap.class); - if (nouveau_sw_method_execute(dev, class, mthd)) { + if (nouveau_sw_method_execute(dev, trap.class, trap.mthd)) { DRM_ERROR("Unable to execute NV04 software method %x " "for object class %x. Please report.\n", - mthd, class); + trap.mthd, trap.class); unhandled = 1; } } else { @@ -329,13 +335,30 @@ nouveau_pgraph_intr_notify(struct drm_device *dev, uint32_t nsource) } if (unhandled) - nouveau_graph_dump_trap_info(dev, "PGRAPH_NOTIFY"); + nouveau_graph_dump_trap_info(dev, "PGRAPH_NOTIFY", &trap); } static inline void nouveau_pgraph_intr_error(struct drm_device *dev, uint32_t nsource) { - nouveau_graph_dump_trap_info(dev, "PGRAPH_ERROR"); + struct nouveau_pgraph_trap trap; + int unhandled = 0; + + nouveau_graph_trap_info(dev, &trap); + + if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) { + if (trap.channel >= 0 && trap.mthd == 0x0150) { + nouveau_fence_handler(dev, trap.channel); + } else + if (nouveau_sw_method_execute(dev, trap.class, trap.mthd)) { + unhandled = 1; + } + } else { + unhandled = 1; + } + + if (unhandled) + nouveau_graph_dump_trap_info(dev, "PGRAPH_ERROR", &trap); } static inline void -- cgit v1.2.3 From 7f6bf84c238a1859ffd409c0ef1f1ca7eb5e6e72 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 5 Nov 2007 12:42:22 +1000 Subject: drm: remove lots of spurious whitespace. Kernel "cleanfile" script run. --- shared-core/nouveau_irq.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'shared-core/nouveau_irq.c') diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c index 08bd1da0..43f37ca0 100644 --- a/shared-core/nouveau_irq.c +++ b/shared-core/nouveau_irq.c @@ -82,7 +82,7 @@ nouveau_fifo_irq_handler(struct drm_device *dev) 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)); @@ -366,7 +366,7 @@ nouveau_pgraph_intr_context_switch(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t chid; - + chid = NV_READ(NV03_PFIFO_CACHE1_PUSH1) & (nouveau_fifo_number(dev)-1); DRM_DEBUG("PGRAPH context switch interrupt channel %x\n", chid); @@ -474,4 +474,3 @@ nouveau_irq_handler(DRM_IRQ_ARGS) return IRQ_HANDLED; } - -- cgit v1.2.3 From d0904f0f2b87c725d3e67060419c445259bd4a5e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 14 Nov 2007 03:27:37 +1100 Subject: nouveau: funcs to determine active channel on PFIFO. --- shared-core/nouveau_irq.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'shared-core/nouveau_irq.c') diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c index 43f37ca0..500fda2f 100644 --- a/shared-core/nouveau_irq.c +++ b/shared-core/nouveau_irq.c @@ -68,6 +68,7 @@ static void nouveau_fifo_irq_handler(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_engine *engine = &dev_priv->Engine; uint32_t status; while ((status = NV_READ(NV03_PFIFO_INTR_0))) { @@ -75,8 +76,7 @@ nouveau_fifo_irq_handler(struct drm_device *dev) NV_WRITE(NV03_PFIFO_CACHES, 0); - chid = NV_READ(NV03_PFIFO_CACHE1_PUSH1) & - (nouveau_fifo_number(dev) - 1); + chid = engine->fifo.channel_id(dev); get = NV_READ(NV03_PFIFO_CACHE1_GET); if (status & NV_PFIFO_INTR_CACHE_ERROR) { @@ -190,6 +190,7 @@ static int nouveau_graph_trapped_channel(struct drm_device *dev, int *channel_ret) { struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_engine *engine = &dev_priv->Engine; int channel; if (dev_priv->card_type < NV_10) { @@ -234,8 +235,7 @@ nouveau_graph_trapped_channel(struct drm_device *dev, int *channel_ret) } } - if (channel > nouveau_fifo_number(dev) || - dev_priv->fifos[channel] == NULL) { + if (channel > engine->fifo.channels || !dev_priv->fifos[channel]) { DRM_ERROR("AIII, invalid/inactive channel id %d\n", channel); return -EINVAL; } @@ -365,9 +365,10 @@ static inline void nouveau_pgraph_intr_context_switch(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_engine *engine = &dev_priv->Engine; uint32_t chid; - chid = NV_READ(NV03_PFIFO_CACHE1_PUSH1) & (nouveau_fifo_number(dev)-1); + chid = engine->fifo.channel_id(dev); DRM_DEBUG("PGRAPH context switch interrupt channel %x\n", chid); switch(dev_priv->card_type) { -- cgit v1.2.3