Skip to contentSkip to conversation

nouveau: add software methods to c0

PATCH New Maarten Lankhorst 1 participant 1 message Jul 27, 2012

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/3 nouveau: add software methods to c0

Handle the INVALID_CLASS error that happens when you try to execute software commands.

---

 drivers/gpu/drm/nouveau/nouveau_software.h |    1 +
 drivers/gpu/drm/nouveau/nvc0_graph.c       |    9 ++++++---
 drivers/gpu/drm/nouveau/nvc0_software.c    |   21 +++++++++++++++++++++
 3 files changed, 28 insertions(+), 3 deletions(-)
drivers/gpu/drm/nouveau/nouveau_software.h +1 -0
index 709e5ac..2fb8c27 100644
@@ -52,5 +52,6 @@ int nv04_software_create(struct drm_device *);
 int nv50_software_create(struct drm_device *);
 int nvc0_software_create(struct drm_device *);
 u64 nvc0_software_crtc(struct nouveau_channel *, int crtc);
+bool nvc0_software_method(struct drm_device *, u32, u32, u32, u32);
 
 #endif
drivers/gpu/drm/nouveau/nvc0_graph.c +6 -3
index 2a01e6e..a929888 100644
@@ -30,6 +30,7 @@
 #include "nouveau_drv.h"
 #include "nouveau_mm.h"
 #include "nouveau_fifo.h"
+#include "nouveau_software.h"
 
 #include "nvc0_graph.h"
 #include "nvc0_grhub.fuc.h"
@@ -681,9 +682,11 @@ nvc0_graph_isr(struct drm_device *dev)
 	}
 
 	if (stat & 0x00000020) {
-		NV_INFO(dev, "PGRAPH: ILLEGAL_CLASS ch %d [0x%010llx] subc %d "
-			     "class 0x%04x mthd 0x%04x data 0x%08x\n",
-			chid, inst, subc, class, mthd, data);
+		if (class != 0x906e ||
+		    !nvc0_software_method(dev, chid, class, mthd, data))
+			NV_INFO(dev, "PGRAPH: ILLEGAL_CLASS ch %d [0x%010llx]"
+				"subc %d class 0x%04x mthd 0x%04x data 0x%08x"
+				"\n", chid, inst, subc, class, mthd, data);
 		nv_wr32(dev, 0x400100, 0x00000020);
 		stat &= ~0x00000020;
 	}
drivers/gpu/drm/nouveau/nvc0_software.c +21 -0
index 93e8c16..a029de5 100644
@@ -27,6 +27,7 @@
 #include "nouveau_drv.h"
 #include "nouveau_ramht.h"
 #include "nouveau_software.h"
+#include "nouveau_fifo.h"
 
 #include "nv50_display.h"
 
@@ -46,6 +47,26 @@ nvc0_software_crtc(struct nouveau_channel *chan, int crtc)
 	return pch->dispc_vma[crtc].offset;
 }
 
+bool
+nvc0_software_method(struct drm_device *dev, u32 chid, u32 class, u32 mthd, u32 data)
+{
+	struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO);
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan = NULL;
+	unsigned long flags;
+	bool handled = false;
+
+	spin_lock_irqsave(&dev_priv->channels.lock, flags);
+	if (chid < pfifo->channels)
+		chan = dev_priv->channels.ptr[chid];
+
+	if (chan)
+		handled = !nouveau_gpuobj_mthd_call(chan, class, mthd, data);
+
+	spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
+	return handled;
+}
+
 static int
 nvc0_software_context_new(struct nouveau_channel *chan, int engine)
 {