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 From 13e1377044d581d692af77656e3bc32c9eb183f7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 11 Jul 2007 12:38:48 +1000 Subject: nouveau: Some checks on userspace object handles. --- shared-core/nouveau_fifo.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index bc3a9948..fcdc14c8 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -474,6 +474,9 @@ static int nouveau_ioctl_fifo_alloc(DRM_IOCTL_ARGS) DRM_COPY_FROM_USER_IOCTL(init, (drm_nouveau_fifo_alloc_t __user *) data, sizeof(init)); + if (init.fb_ctxdma_handle == ~0 || init.tt_ctxdma_handle == ~0) + return DRM_ERR(EINVAL); + res = nouveau_fifo_alloc(dev, &init.channel, filp, init.fb_ctxdma_handle, init.tt_ctxdma_handle); -- cgit v1.2.3 From d26ae22c2b17e0f193334cefec7d141befcfa1ee Mon Sep 17 00:00:00 2001 From: Arthur Huillet Date: Wed, 11 Jul 2007 14:56:27 +0200 Subject: fixed bug that prevented PCIE cards from actually using PCIGART - NV50 will probably still have a problem --- shared-core/nouveau_fifo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index fcdc14c8..88f66d70 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -217,7 +217,7 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) 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); + DRM_DEBUG("Creating CB in PCI memory\n", cb->start, cb->size); ret = nouveau_gpuobj_dma_new(dev, channel, NV_CLASS_DMA_IN_MEMORY, cb->start, -- cgit v1.2.3 From 5fbdf9da8bda996c0a474d13fe69d260f12ffce7 Mon Sep 17 00:00:00 2001 From: Arthur Huillet Date: Thu, 12 Jul 2007 02:35:39 +0200 Subject: fixed object creation code to not Oops on 64bits, worked around memalloc not working on 64bit for PCIGART --- shared-core/nouveau_fifo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 88f66d70..7bcb1c8f 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -217,7 +217,7 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) 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\n", cb->start, cb->size); + DRM_DEBUG("Creating CB in PCI memory\n"); ret = nouveau_gpuobj_dma_new(dev, channel, NV_CLASS_DMA_IN_MEMORY, cb->start, -- cgit v1.2.3 From 750371cb6ea9a64c9d4d4d3b9716c3c68d810d48 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 12 Jul 2007 10:15:16 +1000 Subject: nouveau: separate region_offset into map_handle and offset. --- shared-core/nouveau_fifo.c | 20 +++++++++++++------- 1 file changed, 13 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 7bcb1c8f..7114a931 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -213,8 +213,7 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) 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, + cb->start, 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\n"); @@ -226,7 +225,7 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) } else if (dev_priv->card_type != NV_04) { ret = nouveau_gpuobj_dma_new (dev, channel, NV_CLASS_DMA_IN_MEMORY, - cb->start - drm_get_resource_start(dev, 1), + cb->start, cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_VIDMEM, &pushbuf); } else { @@ -236,7 +235,8 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) */ ret = nouveau_gpuobj_dma_new (dev, channel, NV_CLASS_DMA_IN_MEMORY, - cb->start, cb->size, NV_DMA_ACCESS_RO, + cb->start + drm_get_resource_start(dev, 1), + cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_PCI, &pushbuf); } @@ -467,8 +467,9 @@ 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; + drm_map_list_t *entry; + struct nouveau_fifo *chan; int res; DRM_COPY_FROM_USER_IOCTL(init, (drm_nouveau_fifo_alloc_t __user *) data, @@ -501,12 +502,17 @@ static int nouveau_ioctl_fifo_alloc(DRM_IOCTL_ARGS) if (res != 0) return res; + entry = drm_find_matching_map(dev, chan->regs); + if (!entry) + return DRM_ERR(EINVAL); + init.ctrl = entry->user_token; + /* pass back FIFO map info to the caller */ - init.cmdbuf = chan->pushbuf_mem->start; + init.cmdbuf = chan->pushbuf_mem->map_handle; init.cmdbuf_size = chan->pushbuf_mem->size; /* and the notifier block */ - init.notifier = chan->notifier_block->start; + init.notifier = chan->notifier_block->map_handle; init.notifier_size = chan->notifier_block->size; DRM_COPY_TO_USER_IOCTL((drm_nouveau_fifo_alloc_t __user *)data, -- cgit v1.2.3 From 0029713451af6f5f216079775ff77cae9b423c0e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 13 Jul 2007 15:09:31 +1000 Subject: nouveau: nuke internal typedefs, and drm_device_t use. --- shared-core/nouveau_fifo.c | 49 +++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 24 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 7114a931..c769f58f 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -29,9 +29,9 @@ /* returns the number of hw fifos */ -int nouveau_fifo_number(drm_device_t* dev) +int nouveau_fifo_number(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv=dev->dev_private; + struct drm_nouveau_private *dev_priv=dev->dev_private; switch(dev_priv->card_type) { case NV_03: @@ -47,9 +47,9 @@ int nouveau_fifo_number(drm_device_t* dev) } /* returns the size of fifo context */ -int nouveau_fifo_ctx_size(drm_device_t* dev) +int nouveau_fifo_ctx_size(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv=dev->dev_private; + struct drm_nouveau_private *dev_priv=dev->dev_private; if (dev_priv->card_type >= NV_40) return 128; @@ -68,9 +68,9 @@ int nouveau_fifo_ctx_size(drm_device_t* dev) * voir nv_driver.c : NVPreInit */ -static int nouveau_fifo_instmem_configure(drm_device_t *dev) +static int nouveau_fifo_instmem_configure(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; NV_WRITE(NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ | @@ -109,9 +109,9 @@ static int nouveau_fifo_instmem_configure(drm_device_t *dev) return 0; } -int nouveau_fifo_init(drm_device_t *dev) +int nouveau_fifo_init(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; int ret; NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) & @@ -187,12 +187,12 @@ int nouveau_fifo_init(drm_device_t *dev) static int nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; 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); - nouveau_gpuobj_t *pushbuf = NULL; + struct nouveau_gpuobj *pushbuf = NULL; int ret; /* Defaults for unconfigured values */ @@ -258,12 +258,12 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) } /* allocates and initializes a fifo for user space consumption */ -int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp, +int nouveau_fifo_alloc(struct drm_device *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; - nouveau_engine_func_t *engine = &dev_priv->Engine; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_engine_func *engine = &dev_priv->Engine; struct nouveau_fifo *chan; int channel; @@ -392,10 +392,10 @@ int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp, } /* stops a fifo */ -void nouveau_fifo_free(drm_device_t* dev, int channel) +void nouveau_fifo_free(struct drm_device *dev, int channel) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - nouveau_engine_func_t *engine = &dev_priv->Engine; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_engine_func *engine = &dev_priv->Engine; struct nouveau_fifo *chan = dev_priv->fifos[channel]; if (!chan) { @@ -436,10 +436,10 @@ void nouveau_fifo_free(drm_device_t* dev, int channel) } /* cleanups all the fifos from filp */ -void nouveau_fifo_cleanup(drm_device_t* dev, DRMFILE filp) +void nouveau_fifo_cleanup(struct drm_device *dev, DRMFILE filp) { int i; - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; DRM_DEBUG("clearing FIFO enables from filp\n"); for(i=0;idev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; if (channel >= nouveau_fifo_number(dev)) return 0; @@ -466,13 +466,14 @@ nouveau_fifo_owner(drm_device_t *dev, DRMFILE filp, int channel) static int nouveau_ioctl_fifo_alloc(DRM_IOCTL_ARGS) { DRM_DEVICE; - drm_nouveau_private_t *dev_priv = dev->dev_private; - drm_nouveau_fifo_alloc_t init; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct drm_nouveau_fifo_alloc init; drm_map_list_t *entry; struct nouveau_fifo *chan; int res; - DRM_COPY_FROM_USER_IOCTL(init, (drm_nouveau_fifo_alloc_t __user *) data, + DRM_COPY_FROM_USER_IOCTL(init, + (struct drm_nouveau_fifo_alloc __user *) data, sizeof(init)); if (init.fb_ctxdma_handle == ~0 || init.tt_ctxdma_handle == ~0) @@ -515,7 +516,7 @@ static int nouveau_ioctl_fifo_alloc(DRM_IOCTL_ARGS) init.notifier = chan->notifier_block->map_handle; init.notifier_size = chan->notifier_block->size; - DRM_COPY_TO_USER_IOCTL((drm_nouveau_fifo_alloc_t __user *)data, + DRM_COPY_TO_USER_IOCTL((struct drm_nouveau_fifo_alloc __user *)data, init, sizeof(init)); return 0; } -- cgit v1.2.3 From bc7d6c76fab2ff4d2f11b6bd84ca8b8f124729fd Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 14 Jul 2007 18:32:11 +0200 Subject: nouveau: nv10 and nv11/15 are different --- shared-core/nouveau_fifo.c | 1 + 1 file changed, 1 insertion(+) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index c769f58f..236dd4a1 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -99,6 +99,7 @@ static int nouveau_fifo_instmem_configure(struct drm_device *dev) (1 << 16) /* 64 Bytes entry*/); /* XXX nvidia blob set bit 18, 21,23 for nv20 & nv30 */ break; + case NV_11: case NV_10: case NV_04: case NV_03: -- cgit v1.2.3 From 21ee6fbfb8f2219a454458204afc9c5fcd89f9a8 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 16 Jul 2007 12:32:51 +1000 Subject: drm: remove drmP.h internal typedefs --- shared-core/nouveau_fifo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 236dd4a1..56c25a6e 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -469,7 +469,7 @@ static int nouveau_ioctl_fifo_alloc(DRM_IOCTL_ARGS) DRM_DEVICE; struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_fifo_alloc init; - drm_map_list_t *entry; + struct drm_map_list *entry; struct nouveau_fifo *chan; int res; @@ -526,7 +526,7 @@ static int nouveau_ioctl_fifo_alloc(DRM_IOCTL_ARGS) * finally, the ioctl table ***********************************/ -drm_ioctl_desc_t nouveau_ioctls[] = { +struct drm_ioctl_desc nouveau_ioctls[] = { [DRM_IOCTL_NR(DRM_NOUVEAU_FIFO_ALLOC)] = {nouveau_ioctl_fifo_alloc, 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}, -- cgit v1.2.3 From ec67c2def9af16bf9252d6742aec815b817f135a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 15 Jul 2007 17:18:15 +1000 Subject: nouveau: G8x PCIEGART Actually a NV04-NV50 ttm backend for both PCI and PCIEGART, but PCIGART support for G8X using the current mm has been hacked on top of it. --- shared-core/nouveau_fifo.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 56c25a6e..230c8298 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -211,24 +211,27 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) } if (cb->flags & NOUVEAU_MEM_AGP) { - DRM_DEBUG("Creating CB in AGP memory\n"); + ret = nouveau_gpuobj_gart_dma_new(dev, channel, + cb->start, cb->size, + NV_DMA_ACCESS_RO, + &pushbuf, + &chan->pushbuf_base); + } else + if (cb->flags & NOUVEAU_MEM_PCI) { ret = nouveau_gpuobj_dma_new(dev, channel, - NV_CLASS_DMA_IN_MEMORY, - cb->start, 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\n"); - 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); + NV_CLASS_DMA_IN_MEMORY, + cb->start, cb->size, + NV_DMA_ACCESS_RO, + NV_DMA_TARGET_PCI_NONLINEAR, + &pushbuf); + chan->pushbuf_base = 0; } else if (dev_priv->card_type != NV_04) { ret = nouveau_gpuobj_dma_new (dev, channel, NV_CLASS_DMA_IN_MEMORY, cb->start, cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_VIDMEM, &pushbuf); + chan->pushbuf_base = 0; } else { /* NV04 cmdbuf hack, from original ddx.. not sure of it's * exact reason for existing :) PCI access to cmdbuf in @@ -239,6 +242,7 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) cb->start + drm_get_resource_start(dev, 1), cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_PCI, &pushbuf); + chan->pushbuf_base = 0; } if (ret) { @@ -250,11 +254,12 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) if ((ret = nouveau_gpuobj_ref_add(dev, channel, 0, pushbuf, &chan->pushbuf))) { DRM_ERROR("Error referencing push buffer ctxdma: %d\n", ret); + if (pushbuf != dev_priv->gart_info.sg_ctxdma) + nouveau_gpuobj_del(dev, &pushbuf); return ret; } - dev_priv->fifos[channel]->pushbuf_base = 0; - dev_priv->fifos[channel]->pushbuf_mem = cb; + chan->pushbuf_mem = cb; return 0; } -- cgit v1.2.3 From e39286eb5eab8846a228863abf8f1b8b07a9e29d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 19 Jul 2007 17:00:17 -0700 Subject: Remove DRM_ERR OS macro. This was used to make all ioctl handlers return -errno on linux and errno on *BSD. Instead, just return -errno in shared code, and flip sign on return from shared code to *BSD code. --- shared-core/nouveau_fifo.c | 10 +++++----- 1 file changed, 5 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 230c8298..e3a6674d 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -207,7 +207,7 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) (DRMFILE)-2); if (!cb) { DRM_ERROR("Couldn't allocate DMA command buffer.\n"); - return DRM_ERR(ENOMEM); + return -ENOMEM; } if (cb->flags & NOUVEAU_MEM_AGP) { @@ -289,13 +289,13 @@ int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret, DRMFILE filp, } /* no more fifos. you lost. */ if (channel==nouveau_fifo_number(dev)) - return DRM_ERR(EINVAL); + return -EINVAL; (*chan_ret) = channel; dev_priv->fifos[channel] = drm_calloc(1, sizeof(struct nouveau_fifo), DRM_MEM_DRIVER); if (!dev_priv->fifos[channel]) - return DRM_ERR(ENOMEM); + return -ENOMEM; dev_priv->fifo_alloc_count++; chan = dev_priv->fifos[channel]; chan->filp = filp; @@ -483,7 +483,7 @@ static int nouveau_ioctl_fifo_alloc(DRM_IOCTL_ARGS) sizeof(init)); if (init.fb_ctxdma_handle == ~0 || init.tt_ctxdma_handle == ~0) - return DRM_ERR(EINVAL); + return -EINVAL; res = nouveau_fifo_alloc(dev, &init.channel, filp, init.fb_ctxdma_handle, @@ -511,7 +511,7 @@ static int nouveau_ioctl_fifo_alloc(DRM_IOCTL_ARGS) entry = drm_find_matching_map(dev, chan->regs); if (!entry) - return DRM_ERR(EINVAL); + return -EINVAL; init.ctrl = entry->user_token; /* pass back FIFO map info to the caller */ -- cgit v1.2.3 From c1119b1b092527fbb6950d0b5e51e076ddb00f29 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 20 Jul 2007 06:39:25 -0700 Subject: Replace filp in ioctl arguments with drm_file *file_priv. As a fallout, replace filp storage with file_priv storage for "unique identifier of a client" all over the DRM. There is a 1:1 mapping, so this should be a noop. This could be a minor performance improvement, as everything on Linux dereferenced filp to get file_priv anyway, while only the mmap ioctls went the other direction. --- shared-core/nouveau_fifo.c | 25 ++++++++++++++----------- 1 file changed, 14 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 e3a6674d..8731c6a1 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -204,7 +204,7 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) cb = nouveau_mem_alloc(dev, 0, config->cmdbuf.size, config->cmdbuf.location | NOUVEAU_MEM_MAPPED, - (DRMFILE)-2); + (struct drm_file *)-2); if (!cb) { DRM_ERROR("Couldn't allocate DMA command buffer.\n"); return -ENOMEM; @@ -264,7 +264,8 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) } /* allocates and initializes a fifo for user space consumption */ -int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret, DRMFILE filp, +int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret, + struct drm_file *file_priv, uint32_t vram_handle, uint32_t tt_handle) { int ret; @@ -298,7 +299,7 @@ int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret, DRMFILE filp, return -ENOMEM; dev_priv->fifo_alloc_count++; chan = dev_priv->fifos[channel]; - chan->filp = filp; + chan->file_priv = file_priv; DRM_INFO("Allocating FIFO number %d\n", channel); @@ -317,7 +318,7 @@ int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret, DRMFILE filp, } /* Allocate space for per-channel fixed notifier memory */ - ret = nouveau_notifier_init_channel(dev, channel, filp); + ret = nouveau_notifier_init_channel(dev, channel, file_priv); if (ret) { nouveau_fifo_free(dev, channel); return ret; @@ -441,20 +442,22 @@ void nouveau_fifo_free(struct drm_device *dev, int channel) drm_free(chan, sizeof(*chan), DRM_MEM_DRIVER); } -/* cleanups all the fifos from filp */ -void nouveau_fifo_cleanup(struct drm_device *dev, DRMFILE filp) +/* cleanups all the fifos from file_priv */ +void nouveau_fifo_cleanup(struct drm_device *dev, struct drm_file *file_priv) { int i; struct drm_nouveau_private *dev_priv = dev->dev_private; - DRM_DEBUG("clearing FIFO enables from filp\n"); + DRM_DEBUG("clearing FIFO enables from file_priv\n"); for(i=0;ififos[i] && dev_priv->fifos[i]->filp==filp) + if (dev_priv->fifos[i] && + dev_priv->fifos[i]->file_priv==file_priv) nouveau_fifo_free(dev,i); } int -nouveau_fifo_owner(struct drm_device *dev, DRMFILE filp, int channel) +nouveau_fifo_owner(struct drm_device *dev, struct drm_file *file_priv, + int channel) { struct drm_nouveau_private *dev_priv = dev->dev_private; @@ -462,7 +465,7 @@ nouveau_fifo_owner(struct drm_device *dev, DRMFILE filp, int channel) return 0; if (dev_priv->fifos[channel] == NULL) return 0; - return (dev_priv->fifos[channel]->filp == filp); + return (dev_priv->fifos[channel]->file_priv == file_priv); } /*********************************** @@ -485,7 +488,7 @@ static int nouveau_ioctl_fifo_alloc(DRM_IOCTL_ARGS) if (init.fb_ctxdma_handle == ~0 || init.tt_ctxdma_handle == ~0) return -EINVAL; - res = nouveau_fifo_alloc(dev, &init.channel, filp, + res = nouveau_fifo_alloc(dev, &init.channel, file_priv, init.fb_ctxdma_handle, init.tt_ctxdma_handle); if (res) -- cgit v1.2.3 From 5b38e134163cc375e91424c4688cc9328c6e9082 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 19 Jul 2007 17:11:11 -0700 Subject: Replace DRM_IOCTL_ARGS with (dev, data, file_priv) and remove DRM_DEVICE. The data is now in kernel space, copied in/out as appropriate according to the This results in DRM_COPY_{TO,FROM}_USER going away, and error paths to deal with those failures. This also means that XFree86 4.2.0 support for i810 DRM is lost. --- shared-core/nouveau_fifo.c | 59 ++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 33 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 8731c6a1..e5d3ab3c 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -472,42 +472,37 @@ nouveau_fifo_owner(struct drm_device *dev, struct drm_file *file_priv, * ioctls wrapping the functions ***********************************/ -static int nouveau_ioctl_fifo_alloc(DRM_IOCTL_ARGS) +static int nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; struct drm_nouveau_private *dev_priv = dev->dev_private; - struct drm_nouveau_fifo_alloc init; + struct drm_nouveau_fifo_alloc *init = data; struct drm_map_list *entry; struct nouveau_fifo *chan; int res; - DRM_COPY_FROM_USER_IOCTL(init, - (struct drm_nouveau_fifo_alloc __user *) data, - sizeof(init)); - - if (init.fb_ctxdma_handle == ~0 || init.tt_ctxdma_handle == ~0) + if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0) return -EINVAL; - res = nouveau_fifo_alloc(dev, &init.channel, file_priv, - init.fb_ctxdma_handle, - init.tt_ctxdma_handle); + res = nouveau_fifo_alloc(dev, &init->channel, file_priv, + init->fb_ctxdma_handle, + 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; + init->put_base = chan->pushbuf_base; /* make the fifo available to user space */ /* first, the fifo control regs */ - init.ctrl = dev_priv->mmio->offset; + 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; + 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; + 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, + res = drm_addmap(dev, init->ctrl, init->ctrl_size, _DRM_REGISTERS, 0, &chan->regs); if (res != 0) return res; @@ -515,18 +510,16 @@ static int nouveau_ioctl_fifo_alloc(DRM_IOCTL_ARGS) entry = drm_find_matching_map(dev, chan->regs); if (!entry) return -EINVAL; - init.ctrl = entry->user_token; + init->ctrl = entry->user_token; /* pass back FIFO map info to the caller */ - init.cmdbuf = chan->pushbuf_mem->map_handle; - init.cmdbuf_size = chan->pushbuf_mem->size; + init->cmdbuf = chan->pushbuf_mem->map_handle; + init->cmdbuf_size = chan->pushbuf_mem->size; /* and the notifier block */ - init.notifier = chan->notifier_block->map_handle; - init.notifier_size = chan->notifier_block->size; + init->notifier = chan->notifier_block->map_handle; + init->notifier_size = chan->notifier_block->size; - DRM_COPY_TO_USER_IOCTL((struct drm_nouveau_fifo_alloc __user *)data, - init, sizeof(init)); return 0; } @@ -535,13 +528,13 @@ static int nouveau_ioctl_fifo_alloc(DRM_IOCTL_ARGS) ***********************************/ struct drm_ioctl_desc nouveau_ioctls[] = { - [DRM_IOCTL_NR(DRM_NOUVEAU_FIFO_ALLOC)] = {nouveau_ioctl_fifo_alloc, 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}, - [DRM_IOCTL_NR(DRM_NOUVEAU_SETPARAM)] = {nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, + DRM_IOCTL_DEF(DRM_NOUVEAU_FIFO_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH), + DRM_IOCTL_DEF(DRM_NOUVEAU_GROBJ_ALLOC, nouveau_ioctl_grobj_alloc, DRM_AUTH), + DRM_IOCTL_DEF(DRM_NOUVEAU_NOTIFIER_ALLOC, nouveau_ioctl_notifier_alloc, DRM_AUTH), + DRM_IOCTL_DEF(DRM_NOUVEAU_MEM_ALLOC, nouveau_ioctl_mem_alloc, DRM_AUTH), + DRM_IOCTL_DEF(DRM_NOUVEAU_MEM_FREE, nouveau_ioctl_mem_free, DRM_AUTH), + DRM_IOCTL_DEF(DRM_NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH), + DRM_IOCTL_DEF(DRM_NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), }; int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls); -- cgit v1.2.3 From beaa0c9a28b30a6ba3292184d04875b6a597e433 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 6 Aug 2007 03:40:43 +1000 Subject: nouveau: Pass channel struct around instead of channel id. --- shared-core/nouveau_fifo.c | 104 ++++++++++++++++++++++----------------------- 1 file changed, 50 insertions(+), 54 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index e5d3ab3c..c7ce1d8d 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -186,10 +186,10 @@ int nouveau_fifo_init(struct drm_device *dev) } static int -nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) +nouveau_fifo_cmdbuf_alloc(struct nouveau_channel *chan) { + struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; - 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); @@ -211,37 +211,34 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) } if (cb->flags & NOUVEAU_MEM_AGP) { - ret = nouveau_gpuobj_gart_dma_new(dev, channel, - cb->start, cb->size, + ret = nouveau_gpuobj_gart_dma_new(chan, cb->start, cb->size, NV_DMA_ACCESS_RO, &pushbuf, &chan->pushbuf_base); } else if (cb->flags & NOUVEAU_MEM_PCI) { - ret = nouveau_gpuobj_dma_new(dev, channel, - NV_CLASS_DMA_IN_MEMORY, + ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, cb->start, cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_PCI_NONLINEAR, &pushbuf); chan->pushbuf_base = 0; } else if (dev_priv->card_type != NV_04) { - ret = nouveau_gpuobj_dma_new - (dev, channel, NV_CLASS_DMA_IN_MEMORY, - cb->start, - cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_VIDMEM, - &pushbuf); + ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, + cb->start, cb->size, + NV_DMA_ACCESS_RO, + NV_DMA_TARGET_VIDMEM, &pushbuf); chan->pushbuf_base = 0; } else { /* NV04 cmdbuf hack, from original ddx.. not sure of it's * exact reason for existing :) PCI access to cmdbuf in * VRAM. */ - 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_PCI, &pushbuf); + ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, + cb->start + + drm_get_resource_start(dev, 1), + cb->size, NV_DMA_ACCESS_RO, + NV_DMA_TARGET_PCI, &pushbuf); chan->pushbuf_base = 0; } @@ -251,7 +248,7 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) return ret; } - if ((ret = nouveau_gpuobj_ref_add(dev, channel, 0, pushbuf, + if ((ret = nouveau_gpuobj_ref_add(dev, chan, 0, pushbuf, &chan->pushbuf))) { DRM_ERROR("Error referencing push buffer ctxdma: %d\n", ret); if (pushbuf != dev_priv->gart_info.sg_ctxdma) @@ -270,8 +267,8 @@ int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret, { int ret; struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_engine_func *engine = &dev_priv->Engine; - struct nouveau_fifo *chan; + struct nouveau_engine *engine = &dev_priv->Engine; + struct nouveau_channel *chan; int channel; /* @@ -293,34 +290,36 @@ int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret, return -EINVAL; (*chan_ret) = channel; - dev_priv->fifos[channel] = drm_calloc(1, sizeof(struct nouveau_fifo), + dev_priv->fifos[channel] = drm_calloc(1, sizeof(struct nouveau_channel), DRM_MEM_DRIVER); if (!dev_priv->fifos[channel]) return -ENOMEM; dev_priv->fifo_alloc_count++; chan = dev_priv->fifos[channel]; + chan->dev = dev; + chan->id = channel; chan->file_priv = file_priv; DRM_INFO("Allocating FIFO number %d\n", channel); /* Setup channel's default objects */ - ret = nouveau_gpuobj_channel_init(dev, channel, vram_handle, tt_handle); + ret = nouveau_gpuobj_channel_init(chan, vram_handle, tt_handle); if (ret) { - nouveau_fifo_free(dev, channel); + nouveau_fifo_free(chan); return ret; } /* allocate a command buffer, and create a dma object for the gpu */ - ret = nouveau_fifo_cmdbuf_alloc(dev, channel); + ret = nouveau_fifo_cmdbuf_alloc(chan); if (ret) { - nouveau_fifo_free(dev, channel); + nouveau_fifo_free(chan); return ret; } /* Allocate space for per-channel fixed notifier memory */ - ret = nouveau_notifier_init_channel(dev, channel, file_priv); + ret = nouveau_notifier_init_channel(chan); if (ret) { - nouveau_fifo_free(dev, channel); + nouveau_fifo_free(chan); return ret; } @@ -333,16 +332,16 @@ int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret, NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000000); /* Create a graphics context for new channel */ - ret = engine->graph.create_context(dev, channel); + ret = engine->graph.create_context(chan); if (ret) { - nouveau_fifo_free(dev, channel); + nouveau_fifo_free(chan); return ret; } /* Construct inital RAMFC for new channel */ - ret = engine->fifo.create_context(dev, channel); + ret = engine->fifo.create_context(chan); if (ret) { - nouveau_fifo_free(dev, channel); + nouveau_fifo_free(chan); return ret; } @@ -359,15 +358,15 @@ int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret, * other case, the GPU will handle this when it switches contexts. */ if (dev_priv->fifo_alloc_count == 1) { - ret = engine->fifo.load_context(dev, channel); + ret = engine->fifo.load_context(chan); if (ret) { - nouveau_fifo_free(dev, channel); + nouveau_fifo_free(chan); return ret; } - ret = engine->graph.load_context(dev, channel); + ret = engine->graph.load_context(chan); if (ret) { - nouveau_fifo_free(dev, channel); + nouveau_fifo_free(chan); return ret; } @@ -399,28 +398,23 @@ int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret, } /* stops a fifo */ -void nouveau_fifo_free(struct drm_device *dev, int channel) +void nouveau_fifo_free(struct nouveau_channel *chan) { + struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_engine_func *engine = &dev_priv->Engine; - struct nouveau_fifo *chan = dev_priv->fifos[channel]; - - if (!chan) { - DRM_ERROR("Freeing non-existant channel %d\n", channel); - return; - } + struct nouveau_engine *engine = &dev_priv->Engine; - DRM_INFO("%s: freeing fifo %d\n", __func__, channel); + DRM_INFO("%s: freeing fifo %d\n", __func__, chan->id); /* disable the fifo caches */ NV_WRITE(NV03_PFIFO_CACHES, 0x00000000); // FIXME XXX needs more code - engine->fifo.destroy_context(dev, channel); + engine->fifo.destroy_context(chan); /* Cleanup PGRAPH state */ - engine->graph.destroy_context(dev, channel); + engine->graph.destroy_context(chan); /* reenable the fifo caches */ NV_WRITE(NV03_PFIFO_CACHES, 0x00000001); @@ -432,12 +426,12 @@ void nouveau_fifo_free(struct drm_device *dev, int channel) chan->pushbuf_mem = NULL; } - nouveau_notifier_takedown_channel(dev, channel); + nouveau_notifier_takedown_channel(chan); /* Destroy objects belonging to the channel */ - nouveau_gpuobj_channel_takedown(dev, channel); + nouveau_gpuobj_channel_takedown(chan); - dev_priv->fifos[channel] = NULL; + dev_priv->fifos[chan->id] = NULL; dev_priv->fifo_alloc_count--; drm_free(chan, sizeof(*chan), DRM_MEM_DRIVER); } @@ -445,14 +439,16 @@ void nouveau_fifo_free(struct drm_device *dev, int channel) /* cleanups all the fifos from file_priv */ void nouveau_fifo_cleanup(struct drm_device *dev, struct drm_file *file_priv) { - int i; struct drm_nouveau_private *dev_priv = dev->dev_private; + int i; DRM_DEBUG("clearing FIFO enables from file_priv\n"); - for(i=0;ififos[i] && - dev_priv->fifos[i]->file_priv==file_priv) - nouveau_fifo_free(dev,i); + for(i = 0; i < nouveau_fifo_number(dev); i++) { + struct nouveau_channel *chan = dev_priv->fifos[i]; + + if (chan && chan->file_priv == file_priv) + nouveau_fifo_free(chan); + } } int @@ -477,7 +473,7 @@ static int nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, struct d struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_fifo_alloc *init = data; struct drm_map_list *entry; - struct nouveau_fifo *chan; + struct nouveau_channel *chan; int res; if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0) -- cgit v1.2.3 From 97770db72040dc032130413e0cdabc1777560a75 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 6 Aug 2007 21:45:18 +1000 Subject: nouveau: Various internal and external API changes 1. DRM_NOUVEAU_GPUOBJ_FREE Used to free GPU objects. The obvious usage case is for Gr objects, but notifiers can also be destroyed in the same way. GPU objects gain a destructor method and private data fields with this change, so other specialised cases (like notifiers) can be implemented on top of gpuobjs. 2. DRM_NOUVEAU_CHANNEL_FREE 3. DRM_NOUVEAU_CARD_INIT Ideally we'd do init during module load, but this isn't currently possible. Doing init during firstopen() is bad as X has a love of opening/closing the DRM many times during startup. Once the modesetting-101 branch is merged this can go away. IRQs are enabled in nouveau_card_init() now, rather than having the X server call drmCtlInstHandler(). We'll need this for when we give the kernel module its own channel. 4. DRM_NOUVEAU_GETPARAM Add CHIPSET_ID value, which will return the chipset id derived from NV_PMC_BOOT_0. 4. Use list_* in a few places, rather than home-brewed stuff. --- shared-core/nouveau_fifo.c | 47 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 14 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index c7ce1d8d..152b669a 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -302,22 +302,22 @@ int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret, DRM_INFO("Allocating FIFO number %d\n", channel); - /* Setup channel's default objects */ - ret = nouveau_gpuobj_channel_init(chan, vram_handle, tt_handle); + /* Allocate space for per-channel fixed notifier memory */ + ret = nouveau_notifier_init_channel(chan); if (ret) { nouveau_fifo_free(chan); return ret; } - /* allocate a command buffer, and create a dma object for the gpu */ - ret = nouveau_fifo_cmdbuf_alloc(chan); + /* Setup channel's default objects */ + ret = nouveau_gpuobj_channel_init(chan, vram_handle, tt_handle); if (ret) { nouveau_fifo_free(chan); return ret; } - /* Allocate space for per-channel fixed notifier memory */ - ret = nouveau_notifier_init_channel(chan); + /* allocate a command buffer, and create a dma object for the gpu */ + ret = nouveau_fifo_cmdbuf_alloc(chan); if (ret) { nouveau_fifo_free(chan); return ret; @@ -426,11 +426,11 @@ void nouveau_fifo_free(struct nouveau_channel *chan) chan->pushbuf_mem = NULL; } - nouveau_notifier_takedown_channel(chan); - /* Destroy objects belonging to the channel */ nouveau_gpuobj_channel_takedown(chan); + nouveau_notifier_takedown_channel(chan); + dev_priv->fifos[chan->id] = NULL; dev_priv->fifo_alloc_count--; drm_free(chan, sizeof(*chan), DRM_MEM_DRIVER); @@ -468,14 +468,17 @@ nouveau_fifo_owner(struct drm_device *dev, struct drm_file *file_priv, * ioctls wrapping the functions ***********************************/ -static int nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv) +static int nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, + struct drm_file *file_priv) { struct drm_nouveau_private *dev_priv = dev->dev_private; - struct drm_nouveau_fifo_alloc *init = data; + struct drm_nouveau_channel_alloc *init = data; struct drm_map_list *entry; struct nouveau_channel *chan; int res; + NOUVEAU_CHECK_INITIALISED_WITH_RETURN; + if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0) return -EINVAL; @@ -519,18 +522,34 @@ static int nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, struct d return 0; } +static int nouveau_ioctl_fifo_free(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_nouveau_channel_free *cfree = data; + struct nouveau_channel *chan; + + NOUVEAU_CHECK_INITIALISED_WITH_RETURN; + NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(cfree->channel, file_priv, chan); + + nouveau_fifo_free(chan); + return 0; +} + /*********************************** * finally, the ioctl table ***********************************/ struct drm_ioctl_desc nouveau_ioctls[] = { - DRM_IOCTL_DEF(DRM_NOUVEAU_FIFO_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH), + DRM_IOCTL_DEF(DRM_NOUVEAU_CARD_INIT, nouveau_ioctl_card_init, DRM_AUTH), + DRM_IOCTL_DEF(DRM_NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH), + DRM_IOCTL_DEF(DRM_NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH), + DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_FREE, nouveau_ioctl_fifo_free, DRM_AUTH), DRM_IOCTL_DEF(DRM_NOUVEAU_GROBJ_ALLOC, nouveau_ioctl_grobj_alloc, DRM_AUTH), - DRM_IOCTL_DEF(DRM_NOUVEAU_NOTIFIER_ALLOC, nouveau_ioctl_notifier_alloc, DRM_AUTH), + DRM_IOCTL_DEF(DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_ioctl_notifier_alloc, DRM_AUTH), + DRM_IOCTL_DEF(DRM_NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_AUTH), DRM_IOCTL_DEF(DRM_NOUVEAU_MEM_ALLOC, nouveau_ioctl_mem_alloc, DRM_AUTH), DRM_IOCTL_DEF(DRM_NOUVEAU_MEM_FREE, nouveau_ioctl_mem_free, DRM_AUTH), - DRM_IOCTL_DEF(DRM_NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH), - DRM_IOCTL_DEF(DRM_NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), }; int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls); -- cgit v1.2.3 From cf04641bc61c8bc18101713a8d95ef98e6afae7f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 6 Aug 2007 22:05:31 +1000 Subject: nouveau: Give DRM its own gpu channel If your card doesn't have working context switching, it is now broken. --- shared-core/nouveau_fifo.c | 14 +++++++------- 1 file changed, 7 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 152b669a..823801f9 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -261,9 +261,10 @@ nouveau_fifo_cmdbuf_alloc(struct nouveau_channel *chan) } /* allocates and initializes a fifo for user space consumption */ -int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret, - struct drm_file *file_priv, - uint32_t vram_handle, uint32_t tt_handle) +int +nouveau_fifo_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, + struct drm_file *file_priv, + uint32_t vram_handle, uint32_t tt_handle) { int ret; struct drm_nouveau_private *dev_priv = dev->dev_private; @@ -288,7 +289,6 @@ int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret, /* no more fifos. you lost. */ if (channel==nouveau_fifo_number(dev)) return -EINVAL; - (*chan_ret) = channel; dev_priv->fifos[channel] = drm_calloc(1, sizeof(struct nouveau_channel), DRM_MEM_DRIVER); @@ -394,6 +394,7 @@ int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret, NV_WRITE(NV03_PFIFO_CACHES, 1); DRM_INFO("%s: initialised FIFO %d\n", __func__, channel); + *chan_ret = chan; return 0; } @@ -482,13 +483,12 @@ static int nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0) return -EINVAL; - res = nouveau_fifo_alloc(dev, &init->channel, file_priv, + res = nouveau_fifo_alloc(dev, &chan, file_priv, init->fb_ctxdma_handle, init->tt_ctxdma_handle); if (res) return res; - chan = dev_priv->fifos[init->channel]; - + init->channel = chan->id; init->put_base = chan->pushbuf_base; /* make the fifo available to user space */ -- cgit v1.2.3 From 7a0a812ea42d80eed89b7b9993eae42c7c1b1613 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 6 Aug 2007 22:06:52 +1000 Subject: nouveau: Remove PGRAPH_SURFACE hack, it wont work now anyway. Need to find another way of doing this, ideally someone'd hunt down which object/method controls it! The Xv blit adaptor is likely now broken on cards that have pNv->WaitVSyncPossible enabled. --- shared-core/nouveau_fifo.c | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 823801f9..fd21d2f3 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -369,19 +369,6 @@ nouveau_fifo_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, nouveau_fifo_free(chan); 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 && dev_priv->chipset < 0x50) { - 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, -- cgit v1.2.3 From 4ad487190d5b79947c65e238330506db6b77e523 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 8 Aug 2007 10:42:12 +1000 Subject: nouveau: enable/disable engine-specific interrupts in _init()/_takedown() All interrupts are still masked by PMC until init is finished. --- shared-core/nouveau_fifo.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index fd21d2f3..f9677514 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -120,6 +120,10 @@ int nouveau_fifo_init(struct drm_device *dev) NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) | NV_PMC_ENABLE_PFIFO); + /* Enable PFIFO error reporting */ + NV_WRITE(NV03_PFIFO_INTR_0, 0xFFFFFFFF); + NV_WRITE(NV03_PFIFO_INTR_EN_0, 0xFFFFFFFF); + NV_WRITE(NV03_PFIFO_CACHES, 0x00000000); ret = nouveau_fifo_instmem_configure(dev); -- cgit v1.2.3 From 05633ca3708f48cfbbb77518da4e791d7e1613c2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 8 Aug 2007 16:37:55 +1000 Subject: nouveau: Always allocate drm's push buffer in VRAM Fixes #11868 --- shared-core/nouveau_fifo.c | 78 +++++++++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 36 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index f9677514..22bced14 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -190,46 +190,30 @@ int nouveau_fifo_init(struct drm_device *dev) } static int -nouveau_fifo_cmdbuf_alloc(struct nouveau_channel *chan) +nouveau_fifo_pushbuf_ctxdma_init(struct nouveau_channel *chan) { struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_config *config = &dev_priv->config; - struct mem_block *cb; - int cb_min_size = max(NV03_FIFO_SIZE,PAGE_SIZE); + struct mem_block *pb = chan->pushbuf_mem; struct nouveau_gpuobj *pushbuf = NULL; int ret; - /* Defaults for unconfigured values */ - if (!config->cmdbuf.location) - config->cmdbuf.location = NOUVEAU_MEM_FB; - if (!config->cmdbuf.size || config->cmdbuf.size < cb_min_size) - config->cmdbuf.size = cb_min_size; - - cb = nouveau_mem_alloc(dev, 0, config->cmdbuf.size, - config->cmdbuf.location | NOUVEAU_MEM_MAPPED, - (struct drm_file *)-2); - if (!cb) { - DRM_ERROR("Couldn't allocate DMA command buffer.\n"); - return -ENOMEM; - } - - if (cb->flags & NOUVEAU_MEM_AGP) { - ret = nouveau_gpuobj_gart_dma_new(chan, cb->start, cb->size, + if (pb->flags & NOUVEAU_MEM_AGP) { + ret = nouveau_gpuobj_gart_dma_new(chan, pb->start, pb->size, NV_DMA_ACCESS_RO, &pushbuf, &chan->pushbuf_base); } else - if (cb->flags & NOUVEAU_MEM_PCI) { + if (pb->flags & NOUVEAU_MEM_PCI) { ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, - cb->start, cb->size, + pb->start, pb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_PCI_NONLINEAR, &pushbuf); chan->pushbuf_base = 0; } else if (dev_priv->card_type != NV_04) { ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, - cb->start, cb->size, + pb->start, pb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_VIDMEM, &pushbuf); chan->pushbuf_base = 0; @@ -239,19 +223,13 @@ nouveau_fifo_cmdbuf_alloc(struct nouveau_channel *chan) * VRAM. */ ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, - cb->start + + pb->start + drm_get_resource_start(dev, 1), - cb->size, NV_DMA_ACCESS_RO, + pb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_PCI, &pushbuf); chan->pushbuf_base = 0; } - if (ret) { - nouveau_mem_free(dev, cb); - DRM_ERROR("Error creating push buffer ctxdma: %d\n", ret); - return ret; - } - if ((ret = nouveau_gpuobj_ref_add(dev, chan, 0, pushbuf, &chan->pushbuf))) { DRM_ERROR("Error referencing push buffer ctxdma: %d\n", ret); @@ -260,14 +238,36 @@ nouveau_fifo_cmdbuf_alloc(struct nouveau_channel *chan) return ret; } - chan->pushbuf_mem = cb; return 0; } +static struct mem_block * +nouveau_fifo_user_pushbuf_alloc(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_config *config = &dev_priv->config; + struct mem_block *pb; + int pb_min_size = max(NV03_FIFO_SIZE,PAGE_SIZE); + + /* Defaults for unconfigured values */ + if (!config->cmdbuf.location) + config->cmdbuf.location = NOUVEAU_MEM_FB; + if (!config->cmdbuf.size || config->cmdbuf.size < pb_min_size) + config->cmdbuf.size = pb_min_size; + + pb = nouveau_mem_alloc(dev, 0, config->cmdbuf.size, + config->cmdbuf.location | NOUVEAU_MEM_MAPPED, + (struct drm_file *)-2); + if (!pb) + DRM_ERROR("Couldn't allocate DMA push buffer.\n"); + + return pb; +} + /* allocates and initializes a fifo for user space consumption */ int nouveau_fifo_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, - struct drm_file *file_priv, + struct drm_file *file_priv, struct mem_block *pushbuf, uint32_t vram_handle, uint32_t tt_handle) { int ret; @@ -303,6 +303,7 @@ nouveau_fifo_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, chan->dev = dev; chan->id = channel; chan->file_priv = file_priv; + chan->pushbuf_mem = pushbuf; DRM_INFO("Allocating FIFO number %d\n", channel); @@ -320,8 +321,8 @@ nouveau_fifo_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, return ret; } - /* allocate a command buffer, and create a dma object for the gpu */ - ret = nouveau_fifo_cmdbuf_alloc(chan); + /* Create a dma object for the push buffer */ + ret = nouveau_fifo_pushbuf_ctxdma_init(chan); if (ret) { nouveau_fifo_free(chan); return ret; @@ -467,6 +468,7 @@ static int nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, struct drm_nouveau_channel_alloc *init = data; struct drm_map_list *entry; struct nouveau_channel *chan; + struct mem_block *pushbuf; int res; NOUVEAU_CHECK_INITIALISED_WITH_RETURN; @@ -474,7 +476,11 @@ static int nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0) return -EINVAL; - res = nouveau_fifo_alloc(dev, &chan, file_priv, + pushbuf = nouveau_fifo_user_pushbuf_alloc(dev); + if (!pushbuf) + return -ENOMEM; + + res = nouveau_fifo_alloc(dev, &chan, file_priv, pushbuf, init->fb_ctxdma_handle, init->tt_ctxdma_handle); if (res) -- cgit v1.2.3 From a46104674f129e873b8dfa29cf8aac9c67bd77be Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 10 Aug 2007 13:54:26 +1000 Subject: nouveau/nv50: demagic instmem setup. --- shared-core/nouveau_fifo.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 22bced14..f0c2a556 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -285,8 +285,6 @@ nouveau_fifo_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, * When there are no more contexts, you lost */ for(channel=0; channelcard_type == NV_50) && (channel == 0)) - continue; if (dev_priv->fifos[channel] == NULL) break; } -- cgit v1.2.3 From 216f1b0573b2c0e39ac82c7f56235c1003e9bd4d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 21 Aug 2007 02:18:27 +1000 Subject: nouveau: Poke 0x2230 on NV47 also. Makes 0x2220 work the same way as on NV40. --- shared-core/nouveau_fifo.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index f0c2a556..1aa724f1 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -84,9 +84,16 @@ static int nouveau_fifo_instmem_configure(struct drm_device *dev) { case NV_50: case NV_40: + switch (dev_priv->chipset) { + case 0x47: + case 0x49: + case 0x4b: + NV_WRITE(0x2230, 1); + break; + default: + break; + } 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 69b11f44f0a0cfe0806e18dae2f360bc1ed8e005 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Thu, 30 Aug 2007 21:51:53 +0200 Subject: nouveau: give nv03 the last cut. --- shared-core/nouveau_fifo.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 1aa724f1..437c84f2 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -34,8 +34,6 @@ int nouveau_fifo_number(struct drm_device *dev) struct drm_nouveau_private *dev_priv=dev->dev_private; switch(dev_priv->card_type) { - case NV_03: - return 8; case NV_04: case NV_05: return 16; @@ -109,7 +107,6 @@ static int nouveau_fifo_instmem_configure(struct drm_device *dev) case NV_11: case NV_10: case NV_04: - case NV_03: NV_WRITE(NV03_PFIFO_RAMFC, dev_priv->ramfc_offset>>8); break; } -- cgit v1.2.3 From f8f31f04574cd6986d7d9ef2215bbb23e0f44b73 Mon Sep 17 00:00:00 2001 From: Matthieu Castet Date: Sat, 29 Sep 2007 23:06:29 +0200 Subject: nouveau : stop the fifo of the channel we are deleting --- shared-core/nouveau_fifo.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'shared-core/nouveau_fifo.c') diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 437c84f2..f82d130b 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -403,7 +403,19 @@ void nouveau_fifo_free(struct nouveau_channel *chan) /* disable the fifo caches */ NV_WRITE(NV03_PFIFO_CACHES, 0x00000000); + NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUSH, NV_READ(NV04_PFIFO_CACHE1_DMA_PUSH)&(~0x1)); + NV_WRITE(NV03_PFIFO_CACHE1_PUSH0, 0x00000000); + NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000000); + /* stop the fifo, otherwise it could be running and + * it will crash when removing gpu objects */ + if (dev_priv->card_type < NV_50) { + NV_WRITE(NV03_FIFO_REGS_DMAPUT(chan->id), chan->pushbuf_base); + NV_WRITE(NV03_FIFO_REGS_DMAGET(chan->id), chan->pushbuf_base); + } else { + NV_WRITE(NV50_FIFO_REGS_DMAPUT(chan->id), chan->pushbuf_base); + NV_WRITE(NV50_FIFO_REGS_DMAGET(chan->id), chan->pushbuf_base); + } // FIXME XXX needs more code engine->fifo.destroy_context(chan); @@ -412,6 +424,10 @@ void nouveau_fifo_free(struct nouveau_channel *chan) engine->graph.destroy_context(chan); /* reenable the fifo caches */ + 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(NV03_PFIFO_CACHES, 0x00000001); /* Deallocate push buffer */ -- cgit v1.2.3