aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nv20_graph.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv20_graph.c')
-rw-r--r--drivers/gpu/drm/nouveau/nv20_graph.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nv20_graph.c b/drivers/gpu/drm/nouveau/nv20_graph.c
index bd065c2fcba..8464b76798d 100644
--- a/drivers/gpu/drm/nouveau/nv20_graph.c
+++ b/drivers/gpu/drm/nouveau/nv20_graph.c
@@ -34,6 +34,7 @@
34 34
35static int nv20_graph_register(struct drm_device *); 35static int nv20_graph_register(struct drm_device *);
36static int nv30_graph_register(struct drm_device *); 36static int nv30_graph_register(struct drm_device *);
37static void nv20_graph_isr(struct drm_device *);
37 38
38static void 39static void
39nv20_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) 40nv20_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
@@ -584,6 +585,7 @@ nv20_graph_init(struct drm_device *dev)
584 return ret; 585 return ret;
585 } 586 }
586 587
588 nouveau_irq_register(dev, 12, nv20_graph_isr);
587 nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF); 589 nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF);
588 nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); 590 nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
589 591
@@ -661,6 +663,9 @@ nv20_graph_takedown(struct drm_device *dev)
661 struct drm_nouveau_private *dev_priv = dev->dev_private; 663 struct drm_nouveau_private *dev_priv = dev->dev_private;
662 struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; 664 struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
663 665
666 nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000);
667 nouveau_irq_unregister(dev, 12);
668
664 nouveau_gpuobj_ref(NULL, &pgraph->ctx_table); 669 nouveau_gpuobj_ref(NULL, &pgraph->ctx_table);
665} 670}
666 671
@@ -712,6 +717,7 @@ nv30_graph_init(struct drm_device *dev)
712 nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE, 717 nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE,
713 pgraph->ctx_table->pinst >> 4); 718 pgraph->ctx_table->pinst >> 4);
714 719
720 nouveau_irq_register(dev, 12, nv20_graph_isr);
715 nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF); 721 nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF);
716 nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); 722 nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
717 723
@@ -850,3 +856,44 @@ nv30_graph_register(struct drm_device *dev)
850 dev_priv->engine.graph.registered = true; 856 dev_priv->engine.graph.registered = true;
851 return 0; 857 return 0;
852} 858}
859
860static void
861nv20_graph_isr(struct drm_device *dev)
862{
863 u32 stat;
864
865 while ((stat = nv_rd32(dev, NV03_PGRAPH_INTR))) {
866 u32 nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE);
867 u32 nstatus = nv_rd32(dev, NV03_PGRAPH_NSTATUS);
868 u32 addr = nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR);
869 u32 chid = (addr & 0x01f00000) >> 20;
870 u32 subc = (addr & 0x00070000) >> 16;
871 u32 mthd = (addr & 0x00001ffc);
872 u32 data = nv_rd32(dev, NV04_PGRAPH_TRAPPED_DATA);
873 u32 class = nv_rd32(dev, 0x400160 + subc * 4) & 0xfff;
874 u32 show = stat;
875
876 if (stat & NV_PGRAPH_INTR_ERROR) {
877 if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) {
878 if (!nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data))
879 show &= ~NV_PGRAPH_INTR_ERROR;
880 }
881 }
882
883 nv_wr32(dev, NV03_PGRAPH_INTR, stat);
884 nv_wr32(dev, NV04_PGRAPH_FIFO, 0x00000001);
885
886 if (show && nouveau_ratelimit()) {
887 NV_INFO(dev, "PGRAPH -");
888 nouveau_bitfield_print(nv10_graph_intr, show);
889 printk(" nsource:");
890 nouveau_bitfield_print(nv04_graph_nsource, nsource);
891 printk(" nstatus:");
892 nouveau_bitfield_print(nv10_graph_nstatus, nstatus);
893 printk("\n");
894 NV_INFO(dev, "PGRAPH - ch %d/%d class 0x%04x "
895 "mthd 0x%04x data 0x%08x\n",
896 chid, subc, class, mthd, data);
897 }
898 }
899}