Index: shared-core/nouveau_drv.h =================================================================== --- shared-core.orig/nouveau_drv.h 2006-11-29 22:30:40.000000000 +0100 +++ shared-core/nouveau_drv.h 2006-12-04 19:12:35.000000000 +0100 @@ -75,6 +75,9 @@ struct nouveau_object *cmdbuf_obj; /* objects belonging to this fifo */ struct nouveau_object *objs; + + /* XXX move this in PGRAPH struct */ + uint32_t pgraph_ctx_user; }; struct nouveau_object_store Index: shared-core/nouveau_fifo.c =================================================================== --- shared-core.orig/nouveau_fifo.c 2006-11-29 22:32:20.000000000 +0100 +++ shared-core/nouveau_fifo.c 2006-12-04 19:12:33.000000000 +0100 @@ -165,6 +165,7 @@ NV_WRITE(NV_PFIFO_CACH1_PUL0, 0x00000001); NV_WRITE(NV_PFIFO_CACH1_PUL1, 0x00000001); + //XXX we assume that channel 0 is the first to use PGRAPH NV_WRITE(NV_PGRAPH_CTX_USER, 0x0); NV_WRITE(NV_PFIFO_DELAY_0, 0xff /* retrycount*/ ); if (dev_priv->card_type >= NV_40) @@ -418,6 +419,7 @@ init->channel = i; init->put_base = i*dev_priv->cmdbuf_ch_size * 0; dev_priv->cur_fifo = init->channel; + dev_priv->fifos[i].pgraph_ctx_user = i << 24; nouveau_wait_for_idle(dev); Index: shared-core/nouveau_irq.c =================================================================== --- shared-core.orig/nouveau_irq.c 2006-11-29 22:42:04.000000000 +0100 +++ shared-core/nouveau_irq.c 2006-12-04 19:16:11.000000000 +0100 @@ -240,21 +240,31 @@ 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 + + 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) @@ -339,7 +349,7 @@ if (status & NV_PGRAPH_INTR_CONTEXT_SWITCH) { uint32_t channel=NV_READ(NV_PFIFO_CACH1_PSH1)&(nouveau_fifo_number(dev)-1); - DRM_INFO("NV: PGRAPH context switch interrupt channel %x\n",channel); + DRM_INFO("NV: PGRAPH context switch interrupt channel %x\n", channel); switch(dev_priv->card_type) { case NV_04: