summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nv04_graph.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2010-11-03 13:16:18 +1000
committerBen Skeggs <bskeggs@redhat.com>2010-12-03 15:11:41 +1000
commit274fec93cdd627408a799519fa602f2eecb14d2f (patch)
tree1ffc788a096237583608dfa3f09caccfc500ec82 /drivers/gpu/drm/nouveau/nv04_graph.c
parent5178d40dff23b5eef7f0a3be2411fa6a347e750d (diff)
downloadtalos-obmc-linux-274fec93cdd627408a799519fa602f2eecb14d2f.tar.gz
talos-obmc-linux-274fec93cdd627408a799519fa602f2eecb14d2f.zip
drm/nouveau: tidy+move PGRAPH ISRs to their respective *_graph.c files
Reviewed-by: Francisco Jerez <currojerez@riseup.net> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv04_graph.c')
-rw-r--r--drivers/gpu/drm/nouveau/nv04_graph.c95
1 files changed, 93 insertions, 2 deletions
diff --git a/drivers/gpu/drm/nouveau/nv04_graph.c b/drivers/gpu/drm/nouveau/nv04_graph.c
index 239519aefce6..0bc616d35eb6 100644
--- a/drivers/gpu/drm/nouveau/nv04_graph.c
+++ b/drivers/gpu/drm/nouveau/nv04_graph.c
@@ -27,8 +27,10 @@
#include "nouveau_drm.h"
#include "nouveau_drv.h"
#include "nouveau_hw.h"
+#include "nouveau_util.h"
-static int nv04_graph_register(struct drm_device *dev);
+static int nv04_graph_register(struct drm_device *dev);
+static void nv04_graph_isr(struct drm_device *dev);
static uint32_t nv04_graph_ctx_regs[] = {
0x0040053c,
@@ -363,7 +365,7 @@ nv04_graph_channel(struct drm_device *dev)
return dev_priv->channels.ptr[chid];
}
-void
+static void
nv04_graph_context_switch(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -498,6 +500,7 @@ int nv04_graph_init(struct drm_device *dev)
return ret;
/* Enable PGRAPH interrupts */
+ nouveau_irq_register(dev, 12, nv04_graph_isr);
nv_wr32(dev, NV03_PGRAPH_INTR, 0xFFFFFFFF);
nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
@@ -533,6 +536,8 @@ int nv04_graph_init(struct drm_device *dev)
void nv04_graph_takedown(struct drm_device *dev)
{
+ nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000);
+ nouveau_irq_unregister(dev, 12);
}
void
@@ -1224,3 +1229,89 @@ nv04_graph_register(struct drm_device *dev)
dev_priv->engine.graph.registered = true;
return 0;
};
+
+static struct nouveau_bitfield nv04_graph_intr[] = {
+ { NV_PGRAPH_INTR_NOTIFY, "NOTIFY" },
+ {}
+};
+
+static struct nouveau_bitfield nv04_graph_nstatus[] =
+{
+ { NV04_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" },
+ { NV04_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" },
+ { NV04_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" },
+ { NV04_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" },
+ {}
+};
+
+struct nouveau_bitfield nv04_graph_nsource[] =
+{
+ { NV03_PGRAPH_NSOURCE_NOTIFICATION, "NOTIFICATION" },
+ { NV03_PGRAPH_NSOURCE_DATA_ERROR, "DATA_ERROR" },
+ { NV03_PGRAPH_NSOURCE_PROTECTION_ERROR, "PROTECTION_ERROR" },
+ { NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION, "RANGE_EXCEPTION" },
+ { NV03_PGRAPH_NSOURCE_LIMIT_COLOR, "LIMIT_COLOR" },
+ { NV03_PGRAPH_NSOURCE_LIMIT_ZETA, "LIMIT_ZETA" },
+ { NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD, "ILLEGAL_MTHD" },
+ { NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION, "DMA_R_PROTECTION" },
+ { NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION, "DMA_W_PROTECTION" },
+ { NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION, "FORMAT_EXCEPTION" },
+ { NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION, "PATCH_EXCEPTION" },
+ { NV03_PGRAPH_NSOURCE_STATE_INVALID, "STATE_INVALID" },
+ { NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY, "DOUBLE_NOTIFY" },
+ { NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE, "NOTIFY_IN_USE" },
+ { NV03_PGRAPH_NSOURCE_METHOD_CNT, "METHOD_CNT" },
+ { NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION, "BFR_NOTIFICATION" },
+ { NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION, "DMA_VTX_PROTECTION" },
+ { NV03_PGRAPH_NSOURCE_DMA_WIDTH_A, "DMA_WIDTH_A" },
+ { NV03_PGRAPH_NSOURCE_DMA_WIDTH_B, "DMA_WIDTH_B" },
+ {}
+};
+
+static void
+nv04_graph_isr(struct drm_device *dev)
+{
+ u32 stat;
+
+ while ((stat = nv_rd32(dev, NV03_PGRAPH_INTR))) {
+ u32 nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE);
+ u32 nstatus = nv_rd32(dev, NV03_PGRAPH_NSTATUS);
+ u32 addr = nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR);
+ u32 chid = (addr & 0x0f000000) >> 24;
+ u32 subc = (addr & 0x0000e000) >> 13;
+ u32 mthd = (addr & 0x00001ffc);
+ u32 data = nv_rd32(dev, NV04_PGRAPH_TRAPPED_DATA);
+ u32 class = nv_rd32(dev, 0x400180 + subc * 4) & 0xff;
+ u32 show = stat;
+
+ if (stat & NV_PGRAPH_INTR_NOTIFY) {
+ if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) {
+ if (!nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data))
+ show &= ~NV_PGRAPH_INTR_NOTIFY;
+ }
+ }
+
+ if (stat & NV_PGRAPH_INTR_CONTEXT_SWITCH) {
+ nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH);
+ stat &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
+ show &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
+ nv04_graph_context_switch(dev);
+ }
+
+ nv_wr32(dev, NV03_PGRAPH_INTR, stat);
+ nv_wr32(dev, NV04_PGRAPH_FIFO, 0x00000001);
+
+ if (show && nouveau_ratelimit()) {
+ NV_INFO(dev, "PGRAPH -");
+ nouveau_bitfield_print(nv04_graph_intr, show);
+ printk(" nsource:");
+ nouveau_bitfield_print(nv04_graph_nsource, nsource);
+ printk(" nstatus:");
+ nouveau_bitfield_print(nv04_graph_nstatus, nstatus);
+ printk("\n");
+ NV_INFO(dev, "PGRAPH - ch %d/%d class 0x%04x "
+ "mthd 0x%04x data 0x%08x\n",
+ chid, subc, class, mthd, data);
+ }
+ }
+}
OpenPOWER on IntegriCloud