diff options
author | Ben Skeggs <darktama@iinet.net.au> | 2007-01-02 15:08:04 +1100 |
---|---|---|
committer | Ben Skeggs <darktama@iinet.net.au> | 2007-01-02 15:08:04 +1100 |
commit | 41da9fd2e59b2af295c8f345586030e5a70d7a83 (patch) | |
tree | 6eb478f72669456a3aca2081b39731da6218bf48 | |
parent | 0e0d954584ba95656663efa3daf6e191e521040b (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.h | 3 | ||||
-rw-r--r-- | shared-core/nouveau_fifo.c | 30 |
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); |