From 2fd812f8ef8adb09fd8d17cab869f9fc8b047d75 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 14 Nov 2006 09:00:31 +1100 Subject: Completely untested NV10/20/30 FIFO context switching changes. --- shared-core/nouveau_fifo.c | 108 +++++++++++++++++++++++++++++---------------- shared-core/nouveau_reg.h | 14 ++++++ 2 files changed, 85 insertions(+), 37 deletions(-) diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index d4e5b1dd..c662165b 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -220,24 +220,9 @@ static void nouveau_context_init(drm_device_t *dev, { drm_nouveau_private_t *dev_priv = dev->dev_private; struct nouveau_object *cb_obj; - uint32_t ctx_addr,ctx_size; + uint32_t ctx_addr, ctx_size = 32; int i; - switch(dev_priv->card_type) - { - case NV_03: - case NV_04: - case NV_05: - ctx_size=32; - break; - case NV_10: - case NV_20: - case NV_30: - default: - ctx_size=64; - break; - } - cb_obj = dev_priv->fifos[init->channel].cmdbuf_obj; ctx_addr=NV_RAMIN+dev_priv->ramfc_offset+init->channel*ctx_size; @@ -247,27 +232,72 @@ static void nouveau_context_init(drm_device_t *dev, NV_WRITE(ctx_addr,init->put_base); NV_WRITE(ctx_addr+4,init->put_base); - if (dev_priv->card_type <= NV_05) - { - // that's what is done in nvosdk, but that part of the code is buggy so... - NV_WRITE(ctx_addr+8, cb_obj->instance >> 4); + // that's what is done in nvosdk, but that part of the code is buggy so... + NV_WRITE(ctx_addr+8, cb_obj->instance >> 4); #ifdef __BIG_ENDIAN - NV_WRITE(ctx_addr+16,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4|NV_PFIFO_CACH1_BIG_ENDIAN); + NV_WRITE(ctx_addr+16,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4|NV_PFIFO_CACH1_BIG_ENDIAN); #else - NV_WRITE(ctx_addr+16,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4); + NV_WRITE(ctx_addr+16,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4); #endif - } - else - { - NV_WRITE(ctx_addr+12,cb_obj->instance >> 4/*DMA INST/DMA COUNT*/); +} + +#define RAMFC_WR(offset, val) NV_WRITE(fifoctx + NV10_RAMFC_##offset, (val)) +static void nouveau_nv10_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; + int i; + + cb_obj = dev_priv->fifos[init->channel].cmdbuf_obj; + fifoctx = NV_RAMIN + dev_priv->ramfc_offset + init->channel*64; + for (i=0;i<64;i+=4) + NV_WRITE(fifoctx + i, 0); + + /* Fill entries that are seen filled in dumps of nvidia driver just + * after channel's is put into DMA mode + */ + RAMFC_WR(DMA_PUT , init->put_base); + RAMFC_WR(DMA_GET , init->put_base); + RAMFC_WR(DMA_INSTANCE , cb_obj->instance >> 4); #ifdef __BIG_ENDIAN - NV_WRITE(ctx_addr+20,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4|NV_PFIFO_CACH1_BIG_ENDIAN); + RAMFC_WR(DMA_FETCH, NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES | + NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES | + NV_PFIFO_CACH1_DMAF_MAX_REQS_4 | + NV_PFIFO_CACH1_BIG_ENDIAN); #else - NV_WRITE(ctx_addr+20,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4); + RAMFC_WR(DMA_FETCH, NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES | + NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES | + NV_PFIFO_CACH1_DMAF_MAX_REQS_4); #endif - } + RAMFC_WR(DMA_SUBROUTINE, init->put_base); +} + +static void nouveau_nv10_context_save(drm_device_t *dev) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + uint32_t fifoctx; + int channel; + channel = NV_READ(NV_PFIFO_CACH1_PSH1) & (nouveau_fifo_number(dev)-1); + fifoctx = NV_RAMIN + dev_priv->ramfc_offset + channel*64; + + RAMFC_WR(DMA_PUT , NV_READ(NV_PFIFO_CACH1_DMAP)); + RAMFC_WR(DMA_GET , NV_READ(NV_PFIFO_CACH1_DMAG)); + RAMFC_WR(REF_CNT , NV_READ(NV_PFIFO_CACH1_REF_CNT)); + RAMFC_WR(DMA_INSTANCE , NV_READ(NV_PFIFO_CACH1_DMAI)); + RAMFC_WR(DMA_STATE , NV_READ(NV_PFIFO_CACH1_DMAS)); + RAMFC_WR(DMA_FETCH , NV_READ(NV_PFIFO_CACH1_DMAF)); + RAMFC_WR(ENGINE , NV_READ(NV_PFIFO_CACH1_ENG)); + RAMFC_WR(PULL1_ENGINE , NV_READ(NV_PFIFO_CACH1_PUL1)); + RAMFC_WR(ACQUIRE_VALUE , NV_READ(NV_PFIFO_CACH1_ACQUIRE_VALUE)); + RAMFC_WR(ACQUIRE_TIMESTAMP, NV_READ(NV_PFIFO_CACH1_ACQUIRE_TIMESTAMP)); + RAMFC_WR(ACQUIRE_TIMEOUT , NV_READ(NV_PFIFO_CACH1_ACQUIRE_TIMEOUT)); + RAMFC_WR(SEMAPHORE , NV_READ(NV_PFIFO_CACH1_SEMAPHORE)); + RAMFC_WR(DMA_SUBROUTINE , NV_READ(NV_PFIFO_CACH1_DMAG)); } +#undef RAMFC_WR #define RAMFC_WR(offset, val) NV_WRITE(fifoctx + NV40_RAMFC_##offset, (val)) static void nouveau_nv40_context_init(drm_device_t *dev, @@ -391,16 +421,20 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, NV_WRITE(NV_PFIFO_CACH1_PSH0, 0x00000000); NV_WRITE(NV_PFIFO_CACH1_PUL0, 0x00000000); - if (dev_priv->card_type < NV_40) + /* Save current channel's state to it's RAMFC entry. + * + * Then, construct inital RAMFC for new channel, I'm not entirely + * sure this is needed if we activate the channel immediately. + * My understanding is that the GPU will fill RAMFC itself when + * it switches away from the channel + */ + if (dev_priv->card_type < NV_10) { nouveau_context_init(dev, init); - else { - /* Save current channel's state to it's RAMFC entry */ + } else if (dev_priv->card_type < NV_40) { + nouveau_nv10_context_save(dev); + nouveau_nv10_context_init(dev, init); + } else { nouveau_nv40_context_save(dev); - /* Construct inital RAMFC for new channel, I'm not entirely - * sure this is needed if we activate the channel immediately. - * My understanding is that the GPU will fill RAMFC itself - * when it switches away from the channel - */ nouveau_nv40_context_init(dev, init); } diff --git a/shared-core/nouveau_reg.h b/shared-core/nouveau_reg.h index 844ee865..fe42f986 100644 --- a/shared-core/nouveau_reg.h +++ b/shared-core/nouveau_reg.h @@ -193,6 +193,20 @@ #define NV03_FIFO_CMD_REWIND (NV03_FIFO_CMD_JUMP | (0 & NV03_FIFO_CMD_JUMP_OFFSET_MASK)) /* RAMFC offsets */ +#define NV10_RAMFC_DMA_PUT 0x00 +#define NV10_RAMFC_DMA_GET 0x04 +#define NV10_RAMFC_REF_CNT 0x08 +#define NV10_RAMFC_DMA_INSTANCE 0x0C +#define NV10_RAMFC_DMA_STATE 0x10 +#define NV10_RAMFC_DMA_FETCH 0x14 +#define NV10_RAMFC_ENGINE 0x18 +#define NV10_RAMFC_PULL1_ENGINE 0x1C +#define NV10_RAMFC_ACQUIRE_VALUE 0x20 +#define NV10_RAMFC_ACQUIRE_TIMESTAMP 0x24 +#define NV10_RAMFC_ACQUIRE_TIMEOUT 0x28 +#define NV10_RAMFC_SEMAPHORE 0x2C +#define NV10_RAMFC_DMA_SUBROUTINE 0x30 + #define NV40_RAMFC_DMA_PUT 0x00 #define NV40_RAMFC_DMA_GET 0x04 #define NV40_RAMFC_REF_CNT 0x08 -- cgit v1.2.3