From 9d167f1f4bc89b784248d22bc95dfc15a72d0244 Mon Sep 17 00:00:00 2001
From: Matthieu Castet <mat@mat-pc.(none)>
Date: Fri, 5 Jan 2007 19:40:11 +0100
Subject: Add basic pgraph context for nv10. It only fake a context switch :
 pgraph state are not save/restored.

---
 shared-core/nouveau_drv.h  |  3 +++
 shared-core/nouveau_fifo.c |  1 +
 shared-core/nouveau_irq.c  | 37 ++++++++++++++++++++++++-------------
 3 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h
index 6e998f3a..44479d70 100644
--- a/shared-core/nouveau_drv.h
+++ b/shared-core/nouveau_drv.h
@@ -89,6 +89,9 @@ struct nouveau_fifo
 	struct mem_block *ramin_grctx;
 	/* objects belonging to this fifo */
 	struct nouveau_object *objs;
+
+	/* XXX move this in PGRAPH struct */
+	uint32_t pgraph_ctx_user;
 };
 
 struct nouveau_config {
diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c
index 9f8c740e..e97e4a68 100644
--- a/shared-core/nouveau_fifo.c
+++ b/shared-core/nouveau_fifo.c
@@ -488,6 +488,7 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init,
 	init->channel  = i;
 	init->put_base = 0;
 	dev_priv->cur_fifo = init->channel;
+	dev_priv->fifos[i].pgraph_ctx_user = i << 24;
 
 	nouveau_wait_for_idle(dev);
 
diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c
index 160016ea..7a31fb0b 100644
--- a/shared-core/nouveau_irq.c
+++ b/shared-core/nouveau_irq.c
@@ -240,21 +240,32 @@ static void nouveau_nv04_context_switch(drm_device_t *dev)
 static void nouveau_nv10_context_switch(drm_device_t *dev)
 {
 	drm_nouveau_private_t *dev_priv = dev->dev_private;
-	int channel;
+	int channel, channel_old;
 
 	channel=NV_READ(NV_PFIFO_CACH1_PSH1)&(nouveau_fifo_number(dev)-1);
-	/* 2-channel commute */
-//	if (channel==0)
-//		channel=1;
-//	else
-//		channel=0;
-//	dev_priv->cur_fifo=channel;
-
-//	NV_WRITE(NV_PGRAPH_CTX_CONTROL, 0x10000100);
-	NV_WRITE(NV_PGRAPH_CTX_USER, NV_READ(NV_PGRAPH_CTX_USER)|0x1F000000);
-//	NV_WRITE(NV_PGRAPH_FFINTFC_ST2, NV_READ(NV_PGRAPH_FFINTFC_ST2)&0xCFFFFFFF);
-	/* touch PGRAPH_CTX_SWITCH* here ? */
-	NV_WRITE(NV_PGRAPH_CTX_CONTROL, 0x10000100);
+	channel_old = (NV_READ(NV_PGRAPH_CTX_USER) >> 24) & (nouveau_fifo_number(dev)-1);
+
+	DRM_INFO("NV: PGRAPH context switch interrupt channel %x -> %x\n",channel_old, channel);
+
+	NV_WRITE(NV_PGRAPH_FIFO,0x0);
+	NV_WRITE(NV_PFIFO_CACH1_PUL0, 0x00000000);
+	NV_WRITE(NV_PFIFO_CACH1_PUL1, 0x00000000);
+	NV_WRITE(NV_PFIFO_CACHES, 0x00000000);
+
+	dev_priv->fifos[channel_old].pgraph_ctx_user = NV_READ(NV_PGRAPH_CTX_USER);
+	//XXX save PGRAPH context
+	NV_WRITE(NV_PGRAPH_CTX_CONTROL, 0x10000000);
+	NV_WRITE(NV_PGRAPH_CTX_USER, dev_priv->fifos[channel].pgraph_ctx_user);
+	//XXX restore PGRAPH context
+	printk("ctx_user %x %x\n", dev_priv->fifos[channel_old].pgraph_ctx_user, dev_priv->fifos[channel].pgraph_ctx_user);
+
+	NV_WRITE(NV_PGRAPH_FFINTFC_ST2, NV_READ(NV_PGRAPH_FFINTFC_ST2)&0xCFFFFFFF);
+	NV_WRITE(NV_PGRAPH_CTX_CONTROL, 0x10010100);
+
+	NV_WRITE(NV_PFIFO_CACH1_PUL0, 0x00000001);
+	NV_WRITE(NV_PFIFO_CACH1_PUL1, 0x00000001);
+	NV_WRITE(NV_PFIFO_CACHES, 0x00000001);
+	NV_WRITE(NV_PGRAPH_FIFO,0x1);
 }
 
 static void nouveau_pgraph_irq_handler(drm_device_t *dev)
-- 
cgit v1.2.3