From: <dar...@ke...> - 2006-10-16 20:30:13
|
shared-core/nouveau_fifo.c | 149 ++++++++++++++++++++++++++++--------------- shared-core/nouveau_irq.c | 6 - shared-core/nouveau_object.c | 2 shared-core/nouveau_reg.h | 2 4 files changed, 104 insertions(+), 55 deletions(-) New commits: diff-tree 98e718d48fcd166accf1af3c017c34e331ab09cb (from 1943f39d8ce27c799f928bab172e521f4d540166) Author: Ben Skeggs <dar...@ii...> Date: Tue Oct 17 07:29:31 2006 +1100 NV40: FIFO context switching now WorksForMe(tm) diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 96c3c5e..d015d42 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -92,9 +92,12 @@ static void nouveau_fifo_init(drm_device ((dev_priv->objs.ht_bits - 9) << 16) | (dev_priv->objs.ht_base >> 8) ); - dev_priv->ramfc_offset=0x11000; + dev_priv->ramfc_offset=0x12000; dev_priv->ramro_offset=0x11200; - NV_WRITE(NV_PFIFO_RAMFC, dev_priv->ramfc_offset>>8); /* RAMIN+0x11000 0.5k */ + if (dev_priv->card_type < NV_40) + NV_WRITE(NV_PFIFO_RAMFC, dev_priv->ramfc_offset>>8); /* RAMIN+0x11000 0.5k */ + else + NV_WRITE(0x2220, 0x30002); NV_WRITE(NV_PFIFO_RAMRO, dev_priv->ramro_offset>>8); /* RAMIN+0x11200 0.5k */ NV_WRITE(NV_PFIFO_CACH0_PUL1, 0x00000001); NV_WRITE(NV_PFIFO_CACH1_DMAC, 0x00000000); @@ -314,6 +317,10 @@ static int nouveau_fifo_alloc(drm_device /* enable the fifo dma operation */ NV_WRITE(NV_PFIFO_MODE,NV_READ(NV_PFIFO_MODE)|(1<<init->channel)); + NV_WRITE(NV03_FIFO_REGS_DMAPUT(init->channel), init->put_base); + NV_WRITE(NV03_FIFO_REGS_DMAGET(init->channel), init->put_base); + +if (init->channel == 0) { // FIXME check if we need to refill the time quota with something like NV_WRITE(0x204C, 0x0003FFFF); if (dev_priv->card_type >= NV_40) @@ -323,8 +330,6 @@ static int nouveau_fifo_alloc(drm_device NV_WRITE(NV_PFIFO_CACH1_DMAP, init->put_base); NV_WRITE(NV_PFIFO_CACH1_DMAG, init->put_base); - NV_WRITE(NV03_FIFO_REGS_DMAPUT(init->channel), init->put_base); - NV_WRITE(NV03_FIFO_REGS_DMAGET(init->channel), init->put_base); NV_WRITE(NV_PFIFO_CACH1_DMAI, dev_priv->cmdbuf_obj->instance >> 4); NV_WRITE(NV_PFIFO_SIZE , 0x0000FFFF); NV_WRITE(NV_PFIFO_CACH1_HASH, 0x0000FFFF); @@ -338,6 +343,7 @@ static int nouveau_fifo_alloc(drm_device #else NV_WRITE(NV_PFIFO_CACH1_DMAF, NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4); #endif +} NV_WRITE(NV_PFIFO_CACH1_DMAPSH, 0x00000001); NV_WRITE(NV_PFIFO_CACH1_PSH0, 0x00000001); NV_WRITE(NV_PFIFO_CACH1_PUL0, 0x00000001); @@ -375,6 +381,8 @@ static int nouveau_fifo_alloc(drm_device void nouveau_fifo_free(drm_device_t* dev,int n) { drm_nouveau_private_t *dev_priv = dev->dev_private; + int i; + dev_priv->fifos[n].used=0; DRM_INFO("%s: freeing fifo %d\n", __func__, n); @@ -382,7 +390,14 @@ void nouveau_fifo_free(drm_device_t* dev NV_WRITE(NV_PFIFO_CACHES, 0x00000000); NV_WRITE(NV_PFIFO_MODE,NV_READ(NV_PFIFO_MODE)&~(1<<n)); - // FIXME XXX needs more code + // FIXME XXX needs more code + + /* Clean RAMFC */ + for (i=0;i<128;i+=4) { + DRM_DEBUG("RAMFC +%02x: 0x%08x\n", i, NV_READ(NV_RAMIN + + dev_priv->ramfc_offset + n*128 + i)); + NV_WRITE(NV_RAMIN + dev_priv->ramfc_offset + n*128 + i, 0); + } /* reenable the fifo caches */ NV_WRITE(NV_PFIFO_CACHES, 0x00000001); diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c index da68868..cff6bbb 100644 --- a/shared-core/nouveau_irq.c +++ b/shared-core/nouveau_irq.c @@ -133,7 +133,7 @@ void nouveau_irq_uninstall(drm_device_t static void nouveau_fifo_irq_handler(drm_device_t *dev) { - uint32_t status, chmode, chstat; + uint32_t status, chmode, chstat, channel; drm_nouveau_private_t *dev_priv = dev->dev_private; status = NV_READ(NV_PFIFO_INTSTAT); @@ -141,9 +141,9 @@ static void nouveau_fifo_irq_handler(drm return; chmode = NV_READ(NV_PFIFO_MODE); chstat = NV_READ(NV_PFIFO_DMA); + channel=NV_READ(NV_PFIFO_CACH1_PSH1)&(nouveau_fifo_number(dev)-1); - DRM_DEBUG("NV: PFIFO interrupt! INTSTAT=0x%08x/MODE=0x%08x/PEND=0x%08x\n", - status, chmode, chstat); + DRM_DEBUG("NV: PFIFO interrupt! Channel=%d, INTSTAT=0x%08x/MODE=0x%08x/PEND=0x%08x\n", channel, status, chmode, chstat); if (status & NV_PFIFO_INTR_CACHE_ERROR) { DRM_ERROR("NV: PFIFO error interrupt\n"); diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index 4e0571b..5f11cfa 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -297,7 +297,7 @@ void nouveau_hash_table_init(drm_device_ dev_priv->objs.ht_base = 0x10000; dev_priv->objs.ht_size = (1 << dev_priv->objs.ht_bits); - dev_priv->objs.first_instance = 0x12000; + dev_priv->objs.first_instance = 0x13000; dev_priv->objs.free_instance = 1024; /*FIXME*/ dev_priv->objs.num_instance = 1024; /*FIXME*/ dev_priv->objs.inst_bmap = drm_calloc diff-tree 1943f39d8ce27c799f928bab172e521f4d540166 (from 95486bbde05ae51975c4d51fd194111788edee9a) Author: Ben Skeggs <dar...@ii...> Date: Tue Oct 17 06:37:40 2006 +1100 Setup NV40 RAMFC (in wrong location.. but anyway), rearrange the RAMFC setup code a bit. diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 5b8cabd..96c3c5e 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -181,13 +181,88 @@ static int nouveau_dma_init(struct drm_d return 0; } +static void nouveau_context_init(drm_device_t *dev, + drm_nouveau_fifo_alloc_t *init) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + uint32_t ctx_addr,ctx_size; + 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; + } + + ctx_addr=NV_RAMIN+dev_priv->ramfc_offset+init->channel*ctx_size; + // clear the fifo context + for(i=0;i<ctx_size/4;i++) + NV_WRITE(ctx_addr+4*i,0x0); + + 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,dev_priv->cmdbuf_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); +#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); +#endif + } + else + { + NV_WRITE(ctx_addr+12,dev_priv->cmdbuf_obj->instance >> 4/*DMA INST/DMA COUNT*/); +#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); +#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); +#endif + } + +} + +static void nouveau_nv40_context_init(drm_device_t *dev, + drm_nouveau_fifo_alloc_t *init) +{ +#define RAMFC_WR(offset, val) NV_WRITE(fifoctx + NV40_RAMFC_##offset, (val)) + drm_nouveau_private_t *dev_priv = dev->dev_private; + uint32_t fifoctx; + int i; + + fifoctx = NV_RAMIN + dev_priv->ramfc_offset + init->channel*128; + for (i=0;i<128;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 , dev_priv->cmdbuf_obj->instance >> 4); + RAMFC_WR(DMA_FETCH , 0x30086078); + RAMFC_WR(DMA_SUBROUTINE, init->put_base); + RAMFC_WR(GRCTX_INSTANCE, 0); /* XXX */ + RAMFC_WR(DMA_TIMESLICE , 0x0001FFFF); +#undef RAMFC_WR +} + /* allocates and initializes a fifo for user space consumption */ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, DRMFILE filp) { int i; int ret; drm_nouveau_private_t *dev_priv = dev->dev_private; - uint32_t ctx_addr,ctx_size; /* Init cmdbuf on first FIFO init, this is delayed until now to * give the ddx a chance to configure the cmdbuf with SETPARAM @@ -231,51 +306,10 @@ static int nouveau_fifo_alloc(drm_device NV_WRITE(NV_PFIFO_CACH1_PSH0, 0x00000000); NV_WRITE(NV_PFIFO_CACH1_PUL0, 0x00000000); - 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: - ctx_size=64; - break; - case NV_40: - case G_70: - default: - ctx_size=128; - break; - } - - ctx_addr=NV_RAMIN+dev_priv->ramfc_offset+init->channel*ctx_size; - // clear the fifo context - for(i=0;i<ctx_size/4;i++) - NV_WRITE(ctx_addr+4*i,0x0); - - 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,dev_priv->cmdbuf_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); -#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); -#endif - } + if (dev_priv->card_type < NV_40) + nouveau_context_init(dev, init); else - { - NV_WRITE(ctx_addr+12,dev_priv->cmdbuf_obj->instance >> 4/*DMA INST/DMA COUNT*/); -#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); -#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); -#endif - } + nouveau_nv40_context_init(dev, init); /* enable the fifo dma operation */ NV_WRITE(NV_PFIFO_MODE,NV_READ(NV_PFIFO_MODE)|(1<<init->channel)); diff --git a/shared-core/nouveau_reg.h b/shared-core/nouveau_reg.h index c74feeb..7a0f429 100644 --- a/shared-core/nouveau_reg.h +++ b/shared-core/nouveau_reg.h @@ -193,7 +193,7 @@ #define NV40_RAMFC_ACQUIRE_TIMEOUT 0x2C #define NV40_RAMFC_SEMAPHORE 0x30 #define NV40_RAMFC_DMA_SUBROUTINE 0x34 -#define NV40_RAMFC_GRCTX_INSTANCE_32E0 /* guess */ 0x38 +#define NV40_RAMFC_GRCTX_INSTANCE /* guess */ 0x38 #define NV40_RAMFC_DMA_TIMESLICE 0x3C #define NV40_RAMFC_UNK_40 0x40 #define NV40_RAMFC_UNK_44 0x44 |