aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Skeggs <darktama@iinet.net.au>2007-01-02 15:08:04 +1100
committerBen Skeggs <darktama@iinet.net.au>2007-01-02 15:08:04 +1100
commit41da9fd2e59b2af295c8f345586030e5a70d7a83 (patch)
tree6eb478f72669456a3aca2081b39731da6218bf48
parent0e0d954584ba95656663efa3daf6e191e521040b (diff)
nouveau: Hook up grctx code for NV4x.
This is enough to get grctx switching going on my NV40 and C51 after the binary driver has initialised the card first. Bumping the drm patchlevel because the ddx needs some modifications to have NV4x work at all with these changes.
-rw-r--r--shared-core/nouveau_drv.h3
-rw-r--r--shared-core/nouveau_fifo.c30
2 files changed, 26 insertions, 7 deletions
diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h
index a8108a8c..6e998f3a 100644
--- a/shared-core/nouveau_drv.h
+++ b/shared-core/nouveau_drv.h
@@ -34,7 +34,7 @@
#define DRIVER_MAJOR 0
#define DRIVER_MINOR 0
-#define DRIVER_PATCHLEVEL 1
+#define DRIVER_PATCHLEVEL 2
#define NOUVEAU_FAMILY 0x0000FFFF
#define NOUVEAU_FLAGS 0xFFFF0000
@@ -168,6 +168,7 @@ extern int nouveau_fifo_init(drm_device_t *dev);
extern int nouveau_fifo_number(drm_device_t *dev);
extern void nouveau_fifo_cleanup(drm_device_t *dev, DRMFILE filp);
extern int nouveau_fifo_id_get(drm_device_t *dev, DRMFILE filp);
+extern void nouveau_fifo_free(drm_device_t *dev, int channel);
/* nouveau_object.c */
extern void nouveau_object_cleanup(drm_device_t *dev, DRMFILE filp);
diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c
index 9cc579f9..15d2d928 100644
--- a/shared-core/nouveau_fifo.c
+++ b/shared-core/nouveau_fifo.c
@@ -357,11 +357,12 @@ static void nouveau_nv40_context_init(drm_device_t *dev,
drm_nouveau_fifo_alloc_t *init)
{
drm_nouveau_private_t *dev_priv = dev->dev_private;
- struct nouveau_object *cb_obj;
- uint32_t fifoctx;
+ struct nouveau_fifo *chan = &dev_priv->fifos[init->channel];
+ uint32_t fifoctx, cb_inst, grctx_inst;
int i;
- cb_obj = dev_priv->fifos[init->channel].cmdbuf_obj;
+ cb_inst = nouveau_chip_instance_get(dev, chan->cmdbuf_obj->instance);
+ grctx_inst = nouveau_chip_instance_get(dev, chan->ramin_grctx);
fifoctx = NV_RAMIN + dev_priv->ramfc_offset + init->channel*128;
for (i=0;i<128;i+=4)
NV_WRITE(fifoctx + i, 0);
@@ -371,8 +372,7 @@ static void nouveau_nv40_context_init(drm_device_t *dev,
*/
RAMFC_WR(DMA_PUT , init->put_base);
RAMFC_WR(DMA_GET , init->put_base);
- RAMFC_WR(DMA_INSTANCE , nouveau_chip_instance_get(dev,
- cb_obj->instance));
+ RAMFC_WR(DMA_INSTANCE , cb_inst);
RAMFC_WR(DMA_FETCH , NV_PFIFO_CACH1_DMAF_TRIG_128_BYTES |
NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES |
NV_PFIFO_CACH1_DMAF_MAX_REQS_8 |
@@ -381,7 +381,7 @@ static void nouveau_nv40_context_init(drm_device_t *dev,
#endif
0x30000000 /* no idea.. */);
RAMFC_WR(DMA_SUBROUTINE, init->put_base);
- RAMFC_WR(GRCTX_INSTANCE, 0); /* XXX */
+ RAMFC_WR(GRCTX_INSTANCE, grctx_inst);
RAMFC_WR(DMA_TIMESLICE , 0x0001FFFF);
}
@@ -503,6 +503,11 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init,
} else if (dev_priv->card_type < NV_40) {
nouveau_nv10_context_init(dev, init);
} else {
+ ret = nv40_graph_context_create(dev, init->channel);
+ if (ret) {
+ nouveau_fifo_free(dev, init->channel);
+ return ret;
+ }
nouveau_nv40_context_init(dev, init);
}
@@ -518,6 +523,19 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init,
*/
if (dev_priv->fifo_alloc_count == 0) {
nouveau_fifo_context_restore(dev, init->channel);
+ if (dev_priv->card_type >= NV_40) {
+ struct nouveau_fifo *chan;
+ uint32_t inst;
+
+ chan = &dev_priv->fifos[init->channel];
+ inst = nouveau_chip_instance_get(dev,
+ chan->ramin_grctx);
+
+ /* see comments in nv40_graph_context_restore() */
+ NV_WRITE(0x400784, inst);
+ NV_WRITE(0x40032C, inst | 0x01000000);
+ NV_WRITE(NV40_PFIFO_GRCTX_INSTANCE, inst);
+ }
}
NV_WRITE(NV_PFIFO_CACH1_DMAPSH, 0x00000001);