From 59784116bf7d18cfbbb7236fbdd601476207b9dc Mon Sep 17 00:00:00 2001 From: Matthieu Castet Date: Tue, 8 May 2007 21:18:02 +0200 Subject: nouveau : fix fifo context size for nv10 --- shared-core/nouveau_fifo.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 92166eeb..8e66ca2e 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -51,7 +51,7 @@ int nouveau_fifo_ctx_size(drm_device_t* dev) if (dev_priv->card_type >= NV_40) return 128; - else if (dev_priv->card_type >= NV_10) + else if (dev_priv->card_type >= NV_17) return 64; else return 32; @@ -90,10 +90,12 @@ static int nouveau_fifo_instmem_configure(drm_device_t *dev) break; case NV_30: case NV_20: - case NV_10: + case NV_17: NV_WRITE(NV03_PFIFO_RAMFC, (dev_priv->ramfc_offset>>8) | (1 << 16) /* 64 Bytes entry*/); + /* XXX nvidia blob set bit 18, 21,23 for nv20 & nv30 */ break; + case NV_10: case NV_04: case NV_03: NV_WRITE(NV03_PFIFO_RAMFC, dev_priv->ramfc_offset>>8); @@ -269,11 +271,12 @@ static void nouveau_nv10_context_init(drm_device_t *dev, int channel) drm_nouveau_private_t *dev_priv = dev->dev_private; struct nouveau_object *cb_obj; uint32_t fifoctx; + int ctx_size = nouveau_fifo_ctx_size(dev); int i; cb_obj = dev_priv->fifos[channel].cmdbuf_obj; - fifoctx = NV_RAMIN + dev_priv->ramfc_offset + channel*64; + fifoctx = NV_RAMIN + dev_priv->ramfc_offset + channel*ctx_size; - for (i=0;i<64;i+=4) + for (i=0;idev_private; @@ -350,6 +354,7 @@ static void nouveau_nv10_context_save(drm_device_t *dev) RAMFC_WR(SEMAPHORE , NV_READ(NV10_PFIFO_CACHE1_SEMAPHORE)); RAMFC_WR(DMA_SUBROUTINE , NV_READ(NV10_PFIFO_CACHE1_DMA_SUBROUTINE)); } +#endif #undef RAMFC_WR #define RAMFC_WR(offset, val) NV_WRITE(fifoctx + NV40_RAMFC_##offset, (val)) @@ -507,6 +512,7 @@ static int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp) nouveau_nv04_context_init(dev, channel); break; case NV_10: + case NV_17: nv10_graph_context_create(dev, channel); nouveau_nv10_context_init(dev, channel); break; -- cgit v1.2.3 From 9dbf322d26642f9e671f144b34e7cd7d295e9b8e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 24 Jun 2007 18:55:06 +1000 Subject: nouveau: (mostly) hook up put_base again --- shared-core/nouveau_fifo.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 8e66ca2e..cc4ff127 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -232,6 +232,7 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) return DRM_ERR(ENOMEM); } + dev_priv->fifos[channel].pushbuf_base = 0; dev_priv->fifos[channel].cmdbuf_mem = cb; dev_priv->fifos[channel].cmdbuf_obj = cb_dma; return 0; @@ -460,7 +461,7 @@ static int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp) { int ret; drm_nouveau_private_t *dev_priv = dev->dev_private; - struct nouveau_object *cb_obj; + struct nouveau_fifo *chan; int channel; /* @@ -478,14 +479,16 @@ static int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp) if (channel==nouveau_fifo_number(dev)) return DRM_ERR(EINVAL); (*chan_ret) = channel; + chan = &dev_priv->fifos[channel]; DRM_INFO("Allocating FIFO number %d\n", channel); /* that fifo is used */ - dev_priv->fifos[channel].used = 1; - dev_priv->fifos[channel].filp = filp; + chan->used = 1; + chan->filp = filp; + /* FIFO has no objects yet */ - dev_priv->fifos[channel].objs = NULL; + chan->objs = NULL; /* allocate a command buffer, and create a dma object for the gpu */ ret = nouveau_fifo_cmdbuf_alloc(dev, channel); @@ -493,7 +496,6 @@ static int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp) nouveau_fifo_free(dev, channel); return ret; } - cb_obj = dev_priv->fifos[channel].cmdbuf_obj; nouveau_wait_for_idle(dev); @@ -548,8 +550,8 @@ static int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp) NV_WRITE(NV04_PFIFO_MODE,NV_READ(NV04_PFIFO_MODE)|(1<pushbuf_base); + NV_WRITE(NV03_FIFO_REGS_DMAGET(channel), chan->pushbuf_base); /* If this is the first channel, setup PFIFO ourselves. For any * other case, the GPU will handle this when it switches contexts. @@ -557,10 +559,8 @@ static int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp) if (dev_priv->fifo_alloc_count == 0) { nouveau_fifo_context_restore(dev, channel); if (dev_priv->card_type >= NV_30) { - struct nouveau_fifo *chan; uint32_t inst; - chan = &dev_priv->fifos[channel]; inst = nouveau_chip_instance_get(dev, chan->ramin_grctx); @@ -679,8 +679,7 @@ static int nouveau_ioctl_fifo_alloc(DRM_IOCTL_ARGS) if (res) return res; - /* this should probably disappear in the next abi break? */ - init.put_base = 0; + init.put_base = dev_priv->fifos[init.channel].pushbuf_base; /* make the fifo available to user space */ /* first, the fifo control regs */ -- cgit v1.2.3 From 0afb3b518e1ece820b01f3eea64b25cff01c97bc Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 24 Jun 2007 18:55:23 +1000 Subject: nouveau: split PFIFO/PGRAPH context creation --- shared-core/nouveau_fifo.c | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index cc4ff127..5bbd1c02 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -505,18 +505,16 @@ static int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp) NV_WRITE(NV03_PFIFO_CACHE1_PUSH0, 0x00000000); NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000000); - /* Construct inital RAMFC for new channel */ + /* Create a graphics context for new channel */ switch(dev_priv->card_type) { case NV_04: case NV_05: nv04_graph_context_create(dev, channel); - nouveau_nv04_context_init(dev, channel); break; case NV_10: case NV_17: nv10_graph_context_create(dev, channel); - nouveau_nv10_context_init(dev, channel); break; case NV_20: ret = nv20_graph_context_create(dev, channel); @@ -524,7 +522,6 @@ static int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp) nouveau_fifo_free(dev, channel); return ret; } - nouveau_nv10_context_init(dev, channel); break; case NV_30: ret = nv30_graph_context_create(dev, channel); @@ -532,18 +529,45 @@ static int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp) nouveau_fifo_free(dev, channel); return ret; } - nouveau_nv30_context_init(dev, channel); break; case NV_40: case NV_44: - case NV_50: ret = nv40_graph_context_create(dev, channel); if (ret) { nouveau_fifo_free(dev, channel); return ret; } - nouveau_nv40_context_init(dev, channel); break; + default: + DRM_ERROR("grctx: unknown card type\n"); + nouveau_fifo_free(dev, channel); + return DRM_ERR(EINVAL); + } + + /* Construct inital RAMFC for new channel */ + switch (dev_priv->card_type) { + case NV_04: + case NV_05: + nouveau_nv04_context_init(dev, channel); + break; + case NV_10: + case NV_17: + nouveau_nv10_context_init(dev, channel); + break; + case NV_20: + nouveau_nv10_context_init(dev, channel); + break; + case NV_30: + nouveau_nv30_context_init(dev, channel); + break; + case NV_40: + case NV_44: + nouveau_nv40_context_init(dev, channel); + break; + default: + DRM_ERROR("fifoctx: unknown card type\n"); + nouveau_fifo_free(dev, channel); + return DRM_ERR(EINVAL); } /* enable the fifo dma operation */ -- cgit v1.2.3 From f2e64d527699751d6b64698495ae1d48eeee6cf7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 24 Jun 2007 18:56:01 +1000 Subject: nouveau: NV4X PFIFO engtab functions --- shared-core/nouveau_fifo.c | 100 +++++++++++++-------------------------------- 1 file changed, 28 insertions(+), 72 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 5bbd1c02..50f094b9 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -358,64 +358,6 @@ static void nouveau_nv10_context_save(drm_device_t *dev) #endif #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, int channel) -{ - drm_nouveau_private_t *dev_priv = dev->dev_private; - struct nouveau_fifo *chan = &dev_priv->fifos[channel]; - uint32_t fifoctx, cb_inst, grctx_inst; - int i; - - 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 + 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_INSTANCE , cb_inst); - RAMFC_WR(DMA_FETCH , NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | - NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | - NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 | -#ifdef __BIG_ENDIAN - NV_PFIFO_CACHE1_BIG_ENDIAN | -#endif - 0x30000000 /* no idea.. */); - RAMFC_WR(GRCTX_INSTANCE, grctx_inst); - RAMFC_WR(DMA_TIMESLICE , 0x0001FFFF); -} - -static void nouveau_nv40_context_save(drm_device_t *dev) -{ - drm_nouveau_private_t *dev_priv = dev->dev_private; - uint32_t fifoctx; - int channel; - - channel = NV_READ(NV03_PFIFO_CACHE1_PUSH1) & (nouveau_fifo_number(dev)-1); - fifoctx = NV_RAMIN + dev_priv->ramfc_offset + channel*128; - - RAMFC_WR(DMA_PUT , NV_READ(NV04_PFIFO_CACHE1_DMA_PUT)); - RAMFC_WR(DMA_GET , NV_READ(NV04_PFIFO_CACHE1_DMA_GET)); - RAMFC_WR(REF_CNT , NV_READ(NV10_PFIFO_CACHE1_REF_CNT)); - RAMFC_WR(DMA_INSTANCE , NV_READ(NV04_PFIFO_CACHE1_DMA_INSTANCE)); - RAMFC_WR(DMA_DCOUNT , NV_READ(NV10_PFIFO_CACHE1_DMA_DCOUNT)); - RAMFC_WR(DMA_STATE , NV_READ(NV04_PFIFO_CACHE1_DMA_STATE)); - RAMFC_WR(DMA_FETCH , NV_READ(NV04_PFIFO_CACHE1_DMA_FETCH)); - RAMFC_WR(ENGINE , NV_READ(NV04_PFIFO_CACHE1_ENGINE)); - RAMFC_WR(PULL1_ENGINE , NV_READ(NV04_PFIFO_CACHE1_PULL1)); - RAMFC_WR(ACQUIRE_VALUE , NV_READ(NV10_PFIFO_CACHE1_ACQUIRE_VALUE)); - RAMFC_WR(ACQUIRE_TIMESTAMP, NV_READ(NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP)); - RAMFC_WR(ACQUIRE_TIMEOUT , NV_READ(NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT)); - RAMFC_WR(SEMAPHORE , NV_READ(NV10_PFIFO_CACHE1_SEMAPHORE)); - RAMFC_WR(DMA_SUBROUTINE , NV_READ(NV04_PFIFO_CACHE1_DMA_GET)); - RAMFC_WR(GRCTX_INSTANCE , NV_READ(NV40_PFIFO_GRCTX_INSTANCE)); - RAMFC_WR(DMA_TIMESLICE , NV_READ(NV04_PFIFO_DMA_TIMESLICE) & 0x1FFFF); - RAMFC_WR(UNK_40 , NV_READ(NV40_PFIFO_UNK32E4)); -} -#undef RAMFC_WR - /* This function should load values from RAMFC into PFIFO, but for now * it just clobbers PFIFO with what nouveau_fifo_alloc used to setup * unconditionally. @@ -461,6 +403,7 @@ static int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp) { int ret; drm_nouveau_private_t *dev_priv = dev->dev_private; + nouveau_engine_func_t *engine = &dev_priv->Engine; struct nouveau_fifo *chan; int channel; @@ -560,14 +503,17 @@ static int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp) case NV_30: nouveau_nv30_context_init(dev, channel); break; - case NV_40: - case NV_44: - nouveau_nv40_context_init(dev, channel); - break; default: - DRM_ERROR("fifoctx: unknown card type\n"); - nouveau_fifo_free(dev, channel); - return DRM_ERR(EINVAL); + if (!engine->fifo.create_context) { + DRM_ERROR("fifo.create_context == NULL\n"); + return DRM_ERR(EINVAL); + } + + ret = engine->fifo.create_context(dev, channel); + if (ret) { + nouveau_fifo_free(dev, channel); + return ret; + } } /* enable the fifo dma operation */ @@ -581,7 +527,11 @@ static int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp) * other case, the GPU will handle this when it switches contexts. */ if (dev_priv->fifo_alloc_count == 0) { - nouveau_fifo_context_restore(dev, channel); + if (engine->fifo.load_context) + engine->fifo.load_context(dev, channel); + else + nouveau_fifo_context_restore(dev, channel); + if (dev_priv->card_type >= NV_30) { uint32_t inst; @@ -615,6 +565,7 @@ static int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp) void nouveau_fifo_free(drm_device_t* dev, int channel) { drm_nouveau_private_t *dev_priv = dev->dev_private; + nouveau_engine_func_t *engine = &dev_priv->Engine; struct nouveau_fifo *chan = &dev_priv->fifos[channel]; int i; int ctx_size = nouveau_fifo_ctx_size(dev); @@ -629,12 +580,17 @@ void nouveau_fifo_free(drm_device_t* dev, int channel) // FIXME XXX needs more code /* Clean RAMFC */ - for (i=0;iramfc_offset + - channel*ctx_size + i)); - NV_WRITE(NV_RAMIN + dev_priv->ramfc_offset + - channel*ctx_size + i, 0); + if (engine->fifo.destroy_context) + engine->fifo.destroy_context(dev, channel); + else { + for (i=0;iramfc_offset + + channel*ctx_size + i)); + NV_WRITE(NV_RAMIN + dev_priv->ramfc_offset + + channel*ctx_size + i, 0); + } } /* Cleanup PGRAPH state */ -- cgit v1.2.3 From acb710d1a59788a0205cd0daf0859864e683fbd2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 24 Jun 2007 18:56:40 +1000 Subject: nouveau: NV4X PGRAPH engtab functions --- shared-core/nouveau_fifo.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 50f094b9..527a71ae 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -473,18 +473,17 @@ static int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp) return ret; } break; - case NV_40: - case NV_44: - ret = nv40_graph_context_create(dev, channel); + default: + if (!engine->graph.create_context) { + DRM_ERROR("graph.create_context == NULL\n"); + return DRM_ERR(EINVAL); + } + ret = engine->graph.create_context(dev, channel); if (ret) { nouveau_fifo_free(dev, channel); return ret; } break; - default: - DRM_ERROR("grctx: unknown card type\n"); - nouveau_fifo_free(dev, channel); - return DRM_ERR(EINVAL); } /* Construct inital RAMFC for new channel */ @@ -532,6 +531,13 @@ static int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp) else nouveau_fifo_context_restore(dev, channel); + if (engine->graph.load_context) { + ret = engine->graph.load_context(dev, channel); + if (ret) { + nouveau_fifo_free(dev, channel); + return ret; + } + } else if (dev_priv->card_type >= NV_30) { uint32_t inst; @@ -594,8 +600,8 @@ void nouveau_fifo_free(drm_device_t* dev, int channel) } /* Cleanup PGRAPH state */ - if (dev_priv->card_type >= NV_40) - nouveau_instmem_free(dev, chan->ramin_grctx); + if (engine->graph.destroy_context) + engine->graph.destroy_context(dev, channel); else if (dev_priv->card_type >= NV_30) { } else if (dev_priv->card_type >= NV_20) { -- cgit v1.2.3 From 05d86d950a10b77ffaa708e9d89b2a87c11fed01 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 24 Jun 2007 18:57:09 +1000 Subject: nouveau: NV04 PFIFO engtab functions --- shared-core/nouveau_fifo.c | 32 -------------------------------- 1 file changed, 32 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 527a71ae..58408a1e 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -238,34 +238,6 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) return 0; } -#define RAMFC_WR(offset, val) NV_WRITE(fifoctx + NV04_RAMFC_##offset, (val)) -static void nouveau_nv04_context_init(drm_device_t *dev, int channel) -{ - drm_nouveau_private_t *dev_priv = dev->dev_private; - struct nouveau_object *cb_obj; - uint32_t fifoctx, ctx_size = 32; - int i; - - cb_obj = dev_priv->fifos[channel].cmdbuf_obj; - - fifoctx=NV_RAMIN+dev_priv->ramfc_offset+channel*ctx_size; - - // clear the fifo context - for(i=0;iinstance)); - - RAMFC_WR(DMA_FETCH, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_112_BYTES | - NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | - NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_4 | -#ifdef __BIG_ENDIAN - NV_PFIFO_CACHE1_BIG_ENDIAN | -#endif - 0x00000000); -} -#undef RAMFC_WR - #define RAMFC_WR(offset, val) NV_WRITE(fifoctx + NV10_RAMFC_##offset, (val)) static void nouveau_nv10_context_init(drm_device_t *dev, int channel) { @@ -488,10 +460,6 @@ static int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp) /* Construct inital RAMFC for new channel */ switch (dev_priv->card_type) { - case NV_04: - case NV_05: - nouveau_nv04_context_init(dev, channel); - break; case NV_10: case NV_17: nouveau_nv10_context_init(dev, channel); -- cgit v1.2.3 From 341bc7820749024e09275de6e689b10c2908689a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 24 Jun 2007 18:58:14 +1000 Subject: nouveau: NV1X/2X/3X PFIFO engtab functions Earlier NV1X chips use the NV04 code, see previous commits about NV10 RAMFC entry size. --- shared-core/nouveau_fifo.c | 177 ++------------------------------------------- 1 file changed, 6 insertions(+), 171 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 58408a1e..0a883647 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -238,138 +238,6 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) return 0; } -#define RAMFC_WR(offset, val) NV_WRITE(fifoctx + NV10_RAMFC_##offset, (val)) -static void nouveau_nv10_context_init(drm_device_t *dev, int channel) -{ - drm_nouveau_private_t *dev_priv = dev->dev_private; - struct nouveau_object *cb_obj; - uint32_t fifoctx; - int ctx_size = nouveau_fifo_ctx_size(dev); - int i; - cb_obj = dev_priv->fifos[channel].cmdbuf_obj; - fifoctx = NV_RAMIN + dev_priv->ramfc_offset + channel*ctx_size; - - for (i=0;iinstance)); - - RAMFC_WR(DMA_FETCH, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_112_BYTES | - NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | - NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_4 | -#ifdef __BIG_ENDIAN - NV_PFIFO_CACHE1_BIG_ENDIAN | -#endif - 0x00000000); -} - -static void nouveau_nv30_context_init(drm_device_t *dev, int channel) -{ - drm_nouveau_private_t *dev_priv = dev->dev_private; - struct nouveau_fifo *chan = &dev_priv->fifos[channel]; - struct nouveau_object *cb_obj; - uint32_t fifoctx, grctx_inst, cb_inst, ctx_size = 64; - int i; - - cb_obj = dev_priv->fifos[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 + channel * ctx_size; - - for (i = 0; i < ctx_size; i += 4) - NV_WRITE(fifoctx + i, 0); - - RAMFC_WR(REF_CNT, NV_READ(NV10_PFIFO_CACHE1_REF_CNT)); - RAMFC_WR(DMA_INSTANCE, cb_inst); - RAMFC_WR(DMA_STATE, NV_READ(NV04_PFIFO_CACHE1_DMA_STATE)); - RAMFC_WR(DMA_FETCH, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | - NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | - NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 | -#ifdef __BIG_ENDIAN - NV_PFIFO_CACHE1_BIG_ENDIAN | -#endif - 0x00000000); - - RAMFC_WR(ENGINE, NV_READ(NV04_PFIFO_CACHE1_ENGINE)); - RAMFC_WR(PULL1_ENGINE, NV_READ(NV04_PFIFO_CACHE1_PULL1)); - RAMFC_WR(ACQUIRE_VALUE, NV_READ(NV10_PFIFO_CACHE1_ACQUIRE_VALUE)); - RAMFC_WR(ACQUIRE_TIMESTAMP, NV_READ(NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP)); - RAMFC_WR(ACQUIRE_TIMEOUT, NV_READ(NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT)); - RAMFC_WR(SEMAPHORE, NV_READ(NV10_PFIFO_CACHE1_SEMAPHORE)); -} - -#if 0 -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(NV03_PFIFO_CACHE1_PUSH1) & (nouveau_fifo_number(dev)-1); - fifoctx = NV_RAMIN + dev_priv->ramfc_offset + channel*64; - - RAMFC_WR(DMA_PUT , NV_READ(NV04_PFIFO_CACHE1_DMA_PUT)); - RAMFC_WR(DMA_GET , NV_READ(NV04_PFIFO_CACHE1_DMA_GET)); - RAMFC_WR(REF_CNT , NV_READ(NV10_PFIFO_CACHE1_REF_CNT)); - RAMFC_WR(DMA_INSTANCE , NV_READ(NV04_PFIFO_CACHE1_DMA_INSTANCE)); - RAMFC_WR(DMA_STATE , NV_READ(NV04_PFIFO_CACHE1_DMA_STATE)); - RAMFC_WR(DMA_FETCH , NV_READ(NV04_PFIFO_CACHE1_DMA_FETCH)); - RAMFC_WR(ENGINE , NV_READ(NV04_PFIFO_CACHE1_ENGINE)); - RAMFC_WR(PULL1_ENGINE , NV_READ(NV04_PFIFO_CACHE1_PULL1)); - RAMFC_WR(ACQUIRE_VALUE , NV_READ(NV10_PFIFO_CACHE1_ACQUIRE_VALUE)); - RAMFC_WR(ACQUIRE_TIMESTAMP, NV_READ(NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP)); - RAMFC_WR(ACQUIRE_TIMEOUT , NV_READ(NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT)); - RAMFC_WR(SEMAPHORE , NV_READ(NV10_PFIFO_CACHE1_SEMAPHORE)); - RAMFC_WR(DMA_SUBROUTINE , NV_READ(NV10_PFIFO_CACHE1_DMA_SUBROUTINE)); -} -#endif -#undef RAMFC_WR - -/* This function should load values from RAMFC into PFIFO, but for now - * it just clobbers PFIFO with what nouveau_fifo_alloc used to setup - * unconditionally. - */ -static void -nouveau_fifo_context_restore(drm_device_t *dev, int channel) -{ - drm_nouveau_private_t *dev_priv = dev->dev_private; - struct nouveau_fifo *chan = &dev_priv->fifos[channel]; - uint32_t cb_inst; - - cb_inst = nouveau_chip_instance_get(dev, chan->cmdbuf_obj->instance); - - // FIXME check if we need to refill the time quota with something like NV_WRITE(0x204C, 0x0003FFFF); - - if (dev_priv->card_type >= NV_40) - NV_WRITE(NV03_PFIFO_CACHE1_PUSH1, 0x00010000|channel); - else - NV_WRITE(NV03_PFIFO_CACHE1_PUSH1, 0x00000100|channel); - - NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUT, 0 /*RAMFC_DMA_PUT*/); - NV_WRITE(NV04_PFIFO_CACHE1_DMA_GET, 0 /*RAMFC_DMA_GET*/); - NV_WRITE(NV04_PFIFO_CACHE1_DMA_INSTANCE, cb_inst); - NV_WRITE(NV04_PFIFO_SIZE , 0x0000FFFF); - NV_WRITE(NV04_PFIFO_CACHE1_HASH, 0x0000FFFF); - - NV_WRITE(NV04_PFIFO_CACHE0_PULL1, 0x00000001); - NV_WRITE(NV04_PFIFO_CACHE1_DMA_CTL, 0x00000000); - NV_WRITE(NV04_PFIFO_CACHE1_DMA_STATE, 0x00000000); - NV_WRITE(NV04_PFIFO_CACHE1_ENGINE, 0x00000000); - - NV_WRITE(NV04_PFIFO_CACHE1_DMA_FETCH, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_112_BYTES | - NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | - NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_4 | -#ifdef __BIG_ENDIAN - NV_PFIFO_CACHE1_BIG_ENDIAN | -#endif - 0x00000000); -} - /* allocates and initializes a fifo for user space consumption */ static int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp) { @@ -459,28 +327,10 @@ static int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp) } /* Construct inital RAMFC for new channel */ - switch (dev_priv->card_type) { - case NV_10: - case NV_17: - nouveau_nv10_context_init(dev, channel); - break; - case NV_20: - nouveau_nv10_context_init(dev, channel); - break; - case NV_30: - nouveau_nv30_context_init(dev, channel); - break; - default: - if (!engine->fifo.create_context) { - DRM_ERROR("fifo.create_context == NULL\n"); - return DRM_ERR(EINVAL); - } - - ret = engine->fifo.create_context(dev, channel); - if (ret) { - nouveau_fifo_free(dev, channel); - return ret; - } + ret = engine->fifo.create_context(dev, channel); + if (ret) { + nouveau_fifo_free(dev, channel); + return ret; } /* enable the fifo dma operation */ @@ -494,10 +344,7 @@ static int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp) * other case, the GPU will handle this when it switches contexts. */ if (dev_priv->fifo_alloc_count == 0) { - if (engine->fifo.load_context) - engine->fifo.load_context(dev, channel); - else - nouveau_fifo_context_restore(dev, channel); + engine->fifo.load_context(dev, channel); if (engine->graph.load_context) { ret = engine->graph.load_context(dev, channel); @@ -553,19 +400,7 @@ void nouveau_fifo_free(drm_device_t* dev, int channel) NV_WRITE(NV04_PFIFO_MODE, NV_READ(NV04_PFIFO_MODE)&~(1<fifo.destroy_context) - engine->fifo.destroy_context(dev, channel); - else { - for (i=0;iramfc_offset + - channel*ctx_size + i)); - NV_WRITE(NV_RAMIN + dev_priv->ramfc_offset + - channel*ctx_size + i, 0); - } - } + engine->fifo.destroy_context(dev, channel); /* Cleanup PGRAPH state */ if (engine->graph.destroy_context) -- cgit v1.2.3 From 5d55b0655cb480b7d6ab4cf2467dac6dc6d8df25 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 24 Jun 2007 18:58:38 +1000 Subject: nouveau: NV3X PGRAPH engtab functions --- shared-core/nouveau_fifo.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 0a883647..1ef5a425 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -306,13 +306,6 @@ static int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp) return ret; } break; - case NV_30: - ret = nv30_graph_context_create(dev, channel); - if (ret) { - nouveau_fifo_free(dev, channel); - return ret; - } - break; default: if (!engine->graph.create_context) { DRM_ERROR("graph.create_context == NULL\n"); @@ -388,8 +381,6 @@ void nouveau_fifo_free(drm_device_t* dev, int channel) drm_nouveau_private_t *dev_priv = dev->dev_private; nouveau_engine_func_t *engine = &dev_priv->Engine; struct nouveau_fifo *chan = &dev_priv->fifos[channel]; - int i; - int ctx_size = nouveau_fifo_ctx_size(dev); chan->used = 0; DRM_INFO("%s: freeing fifo %d\n", __func__, channel); -- cgit v1.2.3 From 5f05cd7086c54bccf1c2f0b003b78a08dc55472a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 24 Jun 2007 19:00:26 +1000 Subject: nouveau: NV04/NV10/NV20 PGRAPH engtab functions NV04/NV10 load_context()/save_context() are stubs. I don't know enough about how they work to implement them sanely. The "old" context_switch() code remains hooked up, so it shouldn't break anything. NV20 will probably break if load_context() works. No inital context values are filled in, so when the first channel is created PGRAPH will probably end up having its state zeroed. Some setup from nv20_graph_init() will probably need to be moved to the per-channel context setup. --- shared-core/nouveau_fifo.c | 32 ++++---------------------------- 1 file changed, 4 insertions(+), 28 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 1ef5a425..b47d4e0c 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -289,34 +289,10 @@ static int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp) NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000000); /* Create a graphics context for new channel */ - switch(dev_priv->card_type) - { - case NV_04: - case NV_05: - nv04_graph_context_create(dev, channel); - break; - case NV_10: - case NV_17: - nv10_graph_context_create(dev, channel); - break; - case NV_20: - ret = nv20_graph_context_create(dev, channel); - if (ret) { - nouveau_fifo_free(dev, channel); - return ret; - } - break; - default: - if (!engine->graph.create_context) { - DRM_ERROR("graph.create_context == NULL\n"); - return DRM_ERR(EINVAL); - } - ret = engine->graph.create_context(dev, channel); - if (ret) { - nouveau_fifo_free(dev, channel); - return ret; - } - break; + ret = engine->graph.create_context(dev, channel); + if (ret) { + nouveau_fifo_free(dev, channel); + return ret; } /* Construct inital RAMFC for new channel */ -- cgit v1.2.3 From 3dfc13e2da10e86051c7106feb5683542907acdc Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 24 Jun 2007 19:00:44 +1000 Subject: nouveau: kill some dead code --- shared-core/nouveau_fifo.c | 41 +++++++++++------------------------------ 1 file changed, 11 insertions(+), 30 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index b47d4e0c..3c07b0da 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -313,27 +313,16 @@ static int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp) * other case, the GPU will handle this when it switches contexts. */ if (dev_priv->fifo_alloc_count == 0) { - engine->fifo.load_context(dev, channel); - - if (engine->graph.load_context) { - ret = engine->graph.load_context(dev, channel); - if (ret) { - nouveau_fifo_free(dev, channel); - return ret; - } - } else - if (dev_priv->card_type >= NV_30) { - uint32_t inst; - - inst = nouveau_chip_instance_get(dev, - chan->ramin_grctx); - - /* see comments in nv40_graph_context_restore() */ - NV_WRITE(NV10_PGRAPH_CHANNEL_CTX_SIZE, inst); - if (dev_priv->card_type >= NV_40) { - NV_WRITE(0x40032C, inst | 0x01000000); - NV_WRITE(NV40_PFIFO_GRCTX_INSTANCE, inst); - } + ret = engine->fifo.load_context(dev, channel); + if (ret) { + nouveau_fifo_free(dev, channel); + return ret; + } + + ret = engine->graph.load_context(dev, channel); + if (ret) { + nouveau_fifo_free(dev, channel); + return ret; } } @@ -370,15 +359,7 @@ void nouveau_fifo_free(drm_device_t* dev, int channel) engine->fifo.destroy_context(dev, channel); /* Cleanup PGRAPH state */ - if (engine->graph.destroy_context) - engine->graph.destroy_context(dev, channel); - else if (dev_priv->card_type >= NV_30) { - } - else if (dev_priv->card_type >= NV_20) { - /* clear ctx table */ - INSTANCE_WR(dev_priv->ctx_table, channel, 0); - nouveau_instmem_free(dev, chan->ramin_grctx); - } + engine->graph.destroy_context(dev, channel); /* reenable the fifo caches */ NV_WRITE(NV03_PFIFO_CACHES, 0x00000001); -- cgit v1.2.3 From 9f617522d9cb8cd33e588d12a13f427dbe5171c2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 25 Jun 2007 01:57:57 +1000 Subject: nouveau: NV49/NV4B PGRAPH setup from jb17bsome and stephan_2303 --- shared-core/nouveau_fifo.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 3c07b0da..1a06f913 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -83,6 +83,8 @@ static int nouveau_fifo_instmem_configure(drm_device_t *dev) case NV_50: case NV_40: NV_WRITE(NV40_PFIFO_RAMFC, 0x30002); + if((dev_priv->chipset == 0x49) || (dev_priv->chipset == 0x4b)) + NV_WRITE(0x2230,0x00000001); break; case NV_44: NV_WRITE(NV40_PFIFO_RAMFC, ((nouveau_mem_fb_amount(dev)-512*1024+dev_priv->ramfc_offset)>>16) | -- cgit v1.2.3 From 695599f18d907bb277805581bbe208b0e083e7d9 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 24 Jun 2007 19:03:35 +1000 Subject: nouveau: Nuke DMA_OBJECT_INIT ioctl (bumps interface to 0.0.7) For various reasons, this ioctl was a bad idea. At channel creation we now automatically create DMA objects covering available VRAM and GART memory, where the client used to do this themselves. However, there is still a need to be able to create DMA objects pointing at specific areas of memory (ie. notifiers). Each channel is now allocated a small amount of memory from which a client can suballocate things (such as notifiers), and have a DMA object created which covers the suballocated area. The NOTIFIER_ALLOC ioctl exposes this functionality. --- shared-core/nouveau_fifo.c | 45 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 1a06f913..f179af63 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -241,7 +241,8 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) } /* allocates and initializes a fifo for user space consumption */ -static int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp) +int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp, + uint32_t vram_handle, uint32_t tt_handle) { int ret; drm_nouveau_private_t *dev_priv = dev->dev_private; @@ -282,6 +283,20 @@ static int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp) return ret; } + /* Setup channel's default objects */ + ret = nouveau_object_init_channel(dev, channel, vram_handle, tt_handle); + if (ret) { + nouveau_fifo_free(dev, channel); + return ret; + } + + /* Allocate space for per-channel fixed notifier memory */ + ret = nouveau_notifier_init_channel(dev, channel, filp); + if (ret) { + nouveau_fifo_free(dev, channel); + return ret; + } + nouveau_wait_for_idle(dev); /* disable the fifo caches */ @@ -370,6 +385,8 @@ void nouveau_fifo_free(drm_device_t* dev, int channel) if (chan->cmdbuf_mem) nouveau_mem_free(dev, chan->cmdbuf_mem); + nouveau_notifier_takedown_channel(dev, channel); + /* Destroy objects belonging to the channel */ nouveau_object_cleanup(dev, channel); @@ -408,30 +425,42 @@ static int nouveau_ioctl_fifo_alloc(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_nouveau_private_t *dev_priv = dev->dev_private; + struct nouveau_fifo *chan; drm_nouveau_fifo_alloc_t init; int res; DRM_COPY_FROM_USER_IOCTL(init, (drm_nouveau_fifo_alloc_t __user *) data, sizeof(init)); - res = nouveau_fifo_alloc(dev, &init.channel, filp); + res = nouveau_fifo_alloc(dev, &init.channel, filp, + init.fb_ctxdma_handle, + init.tt_ctxdma_handle); if (res) return res; + chan = &dev_priv->fifos[init.channel]; - init.put_base = dev_priv->fifos[init.channel].pushbuf_base; + init.put_base = chan->pushbuf_base; /* make the fifo available to user space */ /* first, the fifo control regs */ init.ctrl = dev_priv->mmio->offset + NV03_FIFO_REGS(init.channel); init.ctrl_size = NV03_FIFO_REGS_SIZE; res = drm_addmap(dev, init.ctrl, init.ctrl_size, _DRM_REGISTERS, - 0, &dev_priv->fifos[init.channel].regs); + 0, &chan->regs); if (res != 0) return res; /* pass back FIFO map info to the caller */ - init.cmdbuf = dev_priv->fifos[init.channel].cmdbuf_mem->start; - init.cmdbuf_size = dev_priv->fifos[init.channel].cmdbuf_mem->size; + init.cmdbuf = chan->cmdbuf_mem->start; + init.cmdbuf_size = chan->cmdbuf_mem->size; + + /* and the notifier block */ + init.notifier = chan->notifier_block->start; + init.notifier_size = chan->notifier_block->size; + res = drm_addmap(dev, init.notifier, init.notifier_size, _DRM_REGISTERS, + 0, &chan->notifier_map); + if (res != 0) + return res; DRM_COPY_TO_USER_IOCTL((drm_nouveau_fifo_alloc_t __user *)data, init, sizeof(init)); @@ -444,8 +473,8 @@ static int nouveau_ioctl_fifo_alloc(DRM_IOCTL_ARGS) drm_ioctl_desc_t nouveau_ioctls[] = { [DRM_IOCTL_NR(DRM_NOUVEAU_FIFO_ALLOC)] = {nouveau_ioctl_fifo_alloc, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_NOUVEAU_OBJECT_INIT)] = {nouveau_ioctl_object_init, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_NOUVEAU_DMA_OBJECT_INIT)] = {nouveau_ioctl_dma_object_init, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_NOUVEAU_GROBJ_ALLOC)] = {nouveau_ioctl_grobj_alloc, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_NOUVEAU_NOTIFIER_ALLOC)] = {nouveau_ioctl_notifier_alloc, DRM_AUTH}, [DRM_IOCTL_NR(DRM_NOUVEAU_MEM_ALLOC)] = {nouveau_ioctl_mem_alloc, DRM_AUTH}, [DRM_IOCTL_NR(DRM_NOUVEAU_MEM_FREE)] = {nouveau_ioctl_mem_free, DRM_AUTH}, [DRM_IOCTL_NR(DRM_NOUVEAU_GETPARAM)] = {nouveau_ioctl_getparam, DRM_AUTH}, -- cgit v1.2.3 From 1c32fecd6d2286af075976167c4887b9096e8312 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 28 Jun 2007 21:01:17 +1000 Subject: nouveau: Hack around possible Xv blit adaptor breakage --- shared-core/nouveau_fifo.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index f179af63..81dbfcda 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -341,6 +341,19 @@ int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp, nouveau_fifo_free(dev, channel); return ret; } + + /* Temporary hack, to avoid breaking Xv on cards where the + * initial context value for 0x400710 doesn't have these bits + * set. Proper fix would be to find which object+method is + * responsible for modifying this state. + */ + if (dev_priv->chipset >= 0x10) { + uint32_t tmp; + tmp = NV_READ(NV10_PGRAPH_SURFACE) & 0x0007ff00; + NV_WRITE(NV10_PGRAPH_SURFACE, tmp); + tmp = NV_READ(NV10_PGRAPH_SURFACE) | 0x00020100; + NV_WRITE(NV10_PGRAPH_SURFACE, tmp); + } } NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUSH, 0x00000001); -- cgit v1.2.3 From 163f8526123ffa38783fc911b5f7a19debce7f73 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 2 Jul 2007 19:31:18 +1000 Subject: nouveau: rewrite gpu object code Allows multiple references to a single object, needed to support PCI(E)GART scatter-gather DMA objects which would quickly fill PRAMIN if each channel had its own. Handle per-channel private instmem areas. This is needed to support NV50, but might be something we want to do on earlier chipsets at some point? Everything that touches PRAMIN is a GPU object. --- shared-core/nouveau_fifo.c | 66 ++++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 28 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 81dbfcda..9f916307 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -186,10 +186,12 @@ static int nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) { drm_nouveau_private_t *dev_priv = dev->dev_private; + struct nouveau_fifo *chan = &dev_priv->fifos[channel]; struct nouveau_config *config = &dev_priv->config; struct mem_block *cb; - struct nouveau_object *cb_dma = NULL; int cb_min_size = max(NV03_FIFO_SIZE,PAGE_SIZE); + nouveau_gpuobj_t *pushbuf = NULL; + int ret; /* Defaults for unconfigured values */ if (!config->cmdbuf.location) @@ -206,37 +208,42 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) } if (cb->flags & NOUVEAU_MEM_AGP) { - cb_dma = nouveau_object_dma_create(dev, channel, - NV_CLASS_DMA_IN_MEMORY, - cb->start - dev_priv->agp_phys, - cb->size, - NV_DMA_ACCESS_RO, NV_DMA_TARGET_AGP); + ret = nouveau_gpuobj_dma_new + (dev, channel, NV_CLASS_DMA_IN_MEMORY, + cb->start - dev_priv->agp_phys, + cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_AGP, + &pushbuf); } else if (dev_priv->card_type != NV_04) { - cb_dma = nouveau_object_dma_create(dev, channel, - NV_CLASS_DMA_IN_MEMORY, - cb->start - drm_get_resource_start(dev, 1), - cb->size, - NV_DMA_ACCESS_RO, NV_DMA_TARGET_VIDMEM); + ret = nouveau_gpuobj_dma_new + (dev, channel, NV_CLASS_DMA_IN_MEMORY, + cb->start - drm_get_resource_start(dev, 1), + cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_VIDMEM, + &pushbuf); } else { /* NV04 cmdbuf hack, from original ddx.. not sure of it's * exact reason for existing :) PCI access to cmdbuf in * VRAM. */ - cb_dma = nouveau_object_dma_create(dev, channel, - NV_CLASS_DMA_IN_MEMORY, - cb->start, cb->size, - NV_DMA_ACCESS_RO, NV_DMA_TARGET_PCI); + ret = nouveau_gpuobj_dma_new + (dev, channel, NV_CLASS_DMA_IN_MEMORY, + cb->start, cb->size, NV_DMA_ACCESS_RO, + NV_DMA_TARGET_PCI, &pushbuf); } - if (!cb_dma) { + if (ret) { nouveau_mem_free(dev, cb); - DRM_ERROR("Failed to alloc DMA object for command buffer\n"); - return DRM_ERR(ENOMEM); + DRM_ERROR("Error creating push buffer ctxdma: %d\n", ret); + return ret; + } + + if ((ret = nouveau_gpuobj_ref_add(dev, channel, 0, pushbuf, + &chan->pushbuf))) { + DRM_ERROR("Error referencing push buffer ctxdma: %d\n", ret); + return ret; } dev_priv->fifos[channel].pushbuf_base = 0; dev_priv->fifos[channel].cmdbuf_mem = cb; - dev_priv->fifos[channel].cmdbuf_obj = cb_dma; return 0; } @@ -266,6 +273,7 @@ int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp, return DRM_ERR(EINVAL); (*chan_ret) = channel; chan = &dev_priv->fifos[channel]; + memset(chan, sizeof(*chan), 0); DRM_INFO("Allocating FIFO number %d\n", channel); @@ -273,18 +281,15 @@ int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp, chan->used = 1; chan->filp = filp; - /* FIFO has no objects yet */ - chan->objs = NULL; - - /* allocate a command buffer, and create a dma object for the gpu */ - ret = nouveau_fifo_cmdbuf_alloc(dev, channel); + /* Setup channel's default objects */ + ret = nouveau_gpuobj_channel_init(dev, channel, vram_handle, tt_handle); if (ret) { nouveau_fifo_free(dev, channel); return ret; } - /* Setup channel's default objects */ - ret = nouveau_object_init_channel(dev, channel, vram_handle, tt_handle); + /* allocate a command buffer, and create a dma object for the gpu */ + ret = nouveau_fifo_cmdbuf_alloc(dev, channel); if (ret) { nouveau_fifo_free(dev, channel); return ret; @@ -395,13 +400,18 @@ void nouveau_fifo_free(drm_device_t* dev, int channel) NV_WRITE(NV03_PFIFO_CACHES, 0x00000001); /* Deallocate command buffer */ - if (chan->cmdbuf_mem) + if (chan->pushbuf) + nouveau_gpuobj_ref_del(dev, &chan->pushbuf); + + if (chan->cmdbuf_mem) { nouveau_mem_free(dev, chan->cmdbuf_mem); + chan->cmdbuf_mem = NULL; + } nouveau_notifier_takedown_channel(dev, channel); /* Destroy objects belonging to the channel */ - nouveau_object_cleanup(dev, channel); + nouveau_gpuobj_channel_takedown(dev, channel); dev_priv->fifo_alloc_count--; } -- cgit v1.2.3 From c806bba4665bb369168ee0b453fa28e2e0bf2a5d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 5 Jul 2007 00:12:33 +1000 Subject: nouveau/nv50: Initial channel/object support Should be OK on G84 for a single channel, multiple channels *almost* work. Untested on G80. --- shared-core/nouveau_fifo.c | 99 +++++++++++++++++++++++++++------------------- 1 file changed, 58 insertions(+), 41 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 9f916307..c140a634 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -39,6 +39,8 @@ int nouveau_fifo_number(drm_device_t* dev) case NV_04: case NV_05: return 16; + case NV_50: + return 128; default: return 32; } @@ -186,7 +188,7 @@ static int nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) { drm_nouveau_private_t *dev_priv = dev->dev_private; - struct nouveau_fifo *chan = &dev_priv->fifos[channel]; + struct nouveau_fifo *chan = dev_priv->fifos[channel]; struct nouveau_config *config = &dev_priv->config; struct mem_block *cb; int cb_min_size = max(NV03_FIFO_SIZE,PAGE_SIZE); @@ -242,8 +244,8 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) return ret; } - dev_priv->fifos[channel].pushbuf_base = 0; - dev_priv->fifos[channel].cmdbuf_mem = cb; + dev_priv->fifos[channel]->pushbuf_base = 0; + dev_priv->fifos[channel]->pushbuf_mem = cb; return 0; } @@ -265,22 +267,27 @@ int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp, * (woo, full userspace command submission !) * When there are no more contexts, you lost */ - for(channel=0; channelfifos[channel].used==0) + for(channel=0; channelcard_type == NV_50) && (channel == 0)) + continue; + if (dev_priv->fifos[channel] == NULL) break; + } /* no more fifos. you lost. */ if (channel==nouveau_fifo_number(dev)) return DRM_ERR(EINVAL); (*chan_ret) = channel; - chan = &dev_priv->fifos[channel]; - memset(chan, sizeof(*chan), 0); - - DRM_INFO("Allocating FIFO number %d\n", channel); - /* that fifo is used */ - chan->used = 1; + dev_priv->fifos[channel] = drm_calloc(1, sizeof(struct nouveau_fifo), + DRM_MEM_DRIVER); + if (!dev_priv->fifos[channel]) + return DRM_ERR(ENOMEM); + dev_priv->fifo_alloc_count++; + chan = dev_priv->fifos[channel]; chan->filp = filp; + DRM_INFO("Allocating FIFO number %d\n", channel); + /* Setup channel's default objects */ ret = nouveau_gpuobj_channel_init(dev, channel, vram_handle, tt_handle); if (ret) { @@ -324,17 +331,19 @@ int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp, return ret; } - /* enable the fifo dma operation */ - NV_WRITE(NV04_PFIFO_MODE,NV_READ(NV04_PFIFO_MODE)|(1<pushbuf_base); - NV_WRITE(NV03_FIFO_REGS_DMAGET(channel), chan->pushbuf_base); + if (dev_priv->card_type < NV_50) { + NV_WRITE(NV03_FIFO_REGS_DMAPUT(channel), chan->pushbuf_base); + NV_WRITE(NV03_FIFO_REGS_DMAGET(channel), chan->pushbuf_base); + } else { + NV_WRITE(NV50_FIFO_REGS_DMAPUT(channel), chan->pushbuf_base); + NV_WRITE(NV50_FIFO_REGS_DMAGET(channel), chan->pushbuf_base); + } /* If this is the first channel, setup PFIFO ourselves. For any * other case, the GPU will handle this when it switches contexts. */ - if (dev_priv->fifo_alloc_count == 0) { + if (dev_priv->fifo_alloc_count == 1) { ret = engine->fifo.load_context(dev, channel); if (ret) { nouveau_fifo_free(dev, channel); @@ -352,7 +361,7 @@ int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp, * set. Proper fix would be to find which object+method is * responsible for modifying this state. */ - if (dev_priv->chipset >= 0x10) { + if (dev_priv->chipset >= 0x10 && dev_priv->chipset < 0x50) { uint32_t tmp; tmp = NV_READ(NV10_PGRAPH_SURFACE) & 0x0007ff00; NV_WRITE(NV10_PGRAPH_SURFACE, tmp); @@ -361,15 +370,14 @@ int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp, } } - NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUSH, 0x00000001); + NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUSH, + NV_READ(NV04_PFIFO_CACHE1_DMA_PUSH) | 1); NV_WRITE(NV03_PFIFO_CACHE1_PUSH0, 0x00000001); NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000001); NV_WRITE(NV04_PFIFO_CACHE1_PULL1, 0x00000001); /* reenable the fifo caches */ - NV_WRITE(NV03_PFIFO_CACHES, 0x00000001); - - dev_priv->fifo_alloc_count++; + NV_WRITE(NV03_PFIFO_CACHES, 1); DRM_INFO("%s: initialised FIFO %d\n", __func__, channel); return 0; @@ -380,17 +388,20 @@ void nouveau_fifo_free(drm_device_t* dev, int channel) { drm_nouveau_private_t *dev_priv = dev->dev_private; nouveau_engine_func_t *engine = &dev_priv->Engine; - struct nouveau_fifo *chan = &dev_priv->fifos[channel]; + struct nouveau_fifo *chan = dev_priv->fifos[channel]; + + if (!chan) { + DRM_ERROR("Freeing non-existant channel %d\n", channel); + return; + } - chan->used = 0; DRM_INFO("%s: freeing fifo %d\n", __func__, channel); /* disable the fifo caches */ NV_WRITE(NV03_PFIFO_CACHES, 0x00000000); - NV_WRITE(NV04_PFIFO_MODE, NV_READ(NV04_PFIFO_MODE)&~(1<fifo.destroy_context(dev, channel); /* Cleanup PGRAPH state */ @@ -399,13 +410,11 @@ void nouveau_fifo_free(drm_device_t* dev, int channel) /* reenable the fifo caches */ NV_WRITE(NV03_PFIFO_CACHES, 0x00000001); - /* Deallocate command buffer */ - if (chan->pushbuf) - nouveau_gpuobj_ref_del(dev, &chan->pushbuf); - - if (chan->cmdbuf_mem) { - nouveau_mem_free(dev, chan->cmdbuf_mem); - chan->cmdbuf_mem = NULL; + /* Deallocate push buffer */ + nouveau_gpuobj_ref_del(dev, &chan->pushbuf); + if (chan->pushbuf_mem) { + nouveau_mem_free(dev, chan->pushbuf_mem); + chan->pushbuf_mem = NULL; } nouveau_notifier_takedown_channel(dev, channel); @@ -413,7 +422,9 @@ void nouveau_fifo_free(drm_device_t* dev, int channel) /* Destroy objects belonging to the channel */ nouveau_gpuobj_channel_takedown(dev, channel); + dev_priv->fifos[channel] = NULL; dev_priv->fifo_alloc_count--; + drm_free(chan, sizeof(*chan), DRM_MEM_DRIVER); } /* cleanups all the fifos from filp */ @@ -424,7 +435,7 @@ void nouveau_fifo_cleanup(drm_device_t* dev, DRMFILE filp) DRM_DEBUG("clearing FIFO enables from filp\n"); for(i=0;ififos[i].used && dev_priv->fifos[i].filp==filp) + if (dev_priv->fifos[i] && dev_priv->fifos[i]->filp==filp) nouveau_fifo_free(dev,i); } @@ -435,9 +446,9 @@ nouveau_fifo_owner(drm_device_t *dev, DRMFILE filp, int channel) if (channel >= nouveau_fifo_number(dev)) return 0; - if (dev_priv->fifos[channel].used == 0) + if (dev_priv->fifos[channel] == NULL) return 0; - return (dev_priv->fifos[channel].filp == filp); + return (dev_priv->fifos[channel]->filp == filp); } /*********************************** @@ -460,22 +471,28 @@ static int nouveau_ioctl_fifo_alloc(DRM_IOCTL_ARGS) init.tt_ctxdma_handle); if (res) return res; - chan = &dev_priv->fifos[init.channel]; + chan = dev_priv->fifos[init.channel]; init.put_base = chan->pushbuf_base; /* make the fifo available to user space */ /* first, the fifo control regs */ - init.ctrl = dev_priv->mmio->offset + NV03_FIFO_REGS(init.channel); - init.ctrl_size = NV03_FIFO_REGS_SIZE; + init.ctrl = dev_priv->mmio->offset; + if (dev_priv->card_type < NV_50) { + init.ctrl += NV03_FIFO_REGS(init.channel); + init.ctrl_size = NV03_FIFO_REGS_SIZE; + } else { + init.ctrl += NV50_FIFO_REGS(init.channel); + init.ctrl_size = NV50_FIFO_REGS_SIZE; + } res = drm_addmap(dev, init.ctrl, init.ctrl_size, _DRM_REGISTERS, 0, &chan->regs); if (res != 0) return res; /* pass back FIFO map info to the caller */ - init.cmdbuf = chan->cmdbuf_mem->start; - init.cmdbuf_size = chan->cmdbuf_mem->size; + init.cmdbuf = chan->pushbuf_mem->start; + init.cmdbuf_size = chan->pushbuf_mem->size; /* and the notifier block */ init.notifier = chan->notifier_block->start; -- cgit v1.2.3 From 023f7d9c0064f912415c92a85c3a9d722191909f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 9 Jul 2007 23:58:00 +1000 Subject: nouveau: Allocate mappable VRAM for notifiers.. --- shared-core/nouveau_fifo.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index c140a634..4095a57f 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -497,10 +497,6 @@ static int nouveau_ioctl_fifo_alloc(DRM_IOCTL_ARGS) /* and the notifier block */ init.notifier = chan->notifier_block->start; init.notifier_size = chan->notifier_block->size; - res = drm_addmap(dev, init.notifier, init.notifier_size, _DRM_REGISTERS, - 0, &chan->notifier_map); - if (res != 0) - return res; DRM_COPY_TO_USER_IOCTL((drm_nouveau_fifo_alloc_t __user *)data, init, sizeof(init)); -- cgit v1.2.3 From 694e1c5c3f768436651ddf95e11ab5a89ccc8ffa Mon Sep 17 00:00:00 2001 From: Arthur Huillet Date: Wed, 11 Jul 2007 02:35:10 +0200 Subject: Added support for PCIGART for PCI(E) cards. Bumped DRM interface patchlevel. --- shared-core/nouveau_fifo.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 4095a57f..bc3a9948 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -210,11 +210,19 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) } if (cb->flags & NOUVEAU_MEM_AGP) { - ret = nouveau_gpuobj_dma_new - (dev, channel, NV_CLASS_DMA_IN_MEMORY, - cb->start - dev_priv->agp_phys, - cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_AGP, - &pushbuf); + DRM_DEBUG("Creating CB in AGP memory\n"); + ret = nouveau_gpuobj_dma_new(dev, channel, + NV_CLASS_DMA_IN_MEMORY, + cb->start - dev_priv->agp_phys, + cb->size, + NV_DMA_ACCESS_RO, NV_DMA_TARGET_AGP, &pushbuf); + } else if ( cb->flags & NOUVEAU_MEM_PCI) { + DRM_DEBUG("Creating CB in PCI memory starting at virt 0x%08llx size %d\n", cb->start, cb->size); + ret = nouveau_gpuobj_dma_new(dev, channel, + NV_CLASS_DMA_IN_MEMORY, + cb->start, + cb->size, + NV_DMA_ACCESS_RO, NV_DMA_TARGET_PCI_NONLINEAR, &pushbuf); } else if (dev_priv->card_type != NV_04) { ret = nouveau_gpuobj_dma_new (dev, channel, NV_CLASS_DMA_IN_MEMORY, -- cgit v1.2.3