nouveau: store user control reg offsets in channel struct

This commit is contained in:
Ben Skeggs 2007-11-14 04:05:48 +11:00
parent d0904f0f2b
commit 7246a33dd1
6 changed files with 75 additions and 40 deletions

View file

@ -79,6 +79,7 @@ nouveau_fence_perform_flush(struct drm_device *dev, uint32_t class)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct drm_fence_class_manager *fc = &dev->fm.fence_class[class];
struct nouveau_channel *chan = dev_priv->fifos[class];
uint32_t pending_types = 0;
DRM_DEBUG("class=%d\n", class);
@ -89,7 +90,7 @@ nouveau_fence_perform_flush(struct drm_device *dev, uint32_t class)
fc->pending_flush);
if (pending_types) {
uint32_t sequence = NV_READ(NV03_FIFO_REGS(class) + 0x48);
uint32_t sequence = NV_READ(chan->ref_cnt);
DRM_DEBUG("got 0x%08x\n", sequence);
drm_fence_handler(dev, class, sequence, pending_types, 0);

View file

@ -133,10 +133,10 @@ nouveau_dma_channel_takedown(struct drm_device *dev)
#define RING_SKIPS 8
#define READ_GET() ((NV_READ(NV03_FIFO_REGS_DMAGET(dchan->chan->id)) - \
dchan->chan->pushbuf_base) >> 2)
#define READ_GET() ((NV_READ(dchan->chan->get) - \
dchan->chan->pushbuf_base) >> 2)
#define WRITE_PUT(val) do { \
NV_WRITE(NV03_FIFO_REGS_DMAPUT(dchan->chan->id), \
NV_WRITE(dchan->chan->put, \
((val) << 2) + dchan->chan->pushbuf_base); \
} while(0)

View file

@ -89,8 +89,7 @@ typedef enum {
if (dchan->cur != dchan->put) { \
DRM_MEMORYBARRIER(); \
dchan->put = dchan->cur; \
NV_WRITE(NV03_FIFO_REGS_DMAPUT(dchan->chan->id), \
(dchan->put<<2)); \
NV_WRITE(dchan->chan->put, dchan->put << 2); \
} \
} while(0)

View file

@ -114,6 +114,12 @@ struct nouveau_channel
struct mem_block *pushbuf_mem;
uint32_t pushbuf_base;
/* FIFO user control regs */
uint32_t user, user_size;
uint32_t put;
uint32_t get;
uint32_t ref_cnt;
/* Notifier memory */
struct mem_block *notifier_block;
struct mem_block *notifier_heap;
@ -225,6 +231,7 @@ struct nouveau_engine {
struct nouveau_fifo_engine fifo;
};
#define NOUVEAU_MAX_CHANNEL_NR 128
struct drm_nouveau_private {
enum {
NOUVEAU_CARD_INIT_DOWN,
@ -245,7 +252,7 @@ struct drm_nouveau_private {
drm_local_map_t *ramin; /* NV40 onwards */
int fifo_alloc_count;
struct nouveau_channel *fifos[NV_MAX_FIFO_NUMBER];
struct nouveau_channel *fifos[NOUVEAU_MAX_CHANNEL_NR];
struct nouveau_engine Engine;
struct nouveau_drm_channel channel;

View file

@ -294,6 +294,21 @@ nouveau_fifo_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
DRM_INFO("Allocating FIFO number %d\n", channel);
/* Locate channel's user control regs */
if (dev_priv->card_type < NV_50) {
chan->user = NV03_USER(channel);
chan->user_size = NV03_USER_SIZE;
chan->put = NV03_USER_DMA_PUT(channel);
chan->get = NV03_USER_DMA_GET(channel);
chan->ref_cnt = NV03_USER_REF_CNT(channel);
} else {
chan->user = NV50_USER(channel);
chan->user_size = NV50_USER_SIZE;
chan->put = NV50_USER_DMA_PUT(channel);
chan->get = NV50_USER_DMA_GET(channel);
chan->ref_cnt = NV50_USER_REF_CNT(channel);
}
/* Allocate space for per-channel fixed notifier memory */
ret = nouveau_notifier_init_channel(chan);
if (ret) {
@ -337,14 +352,11 @@ nouveau_fifo_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
return ret;
}
/* setup channel's default get/put values */
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);
}
/* setup channel's default get/put values
* XXX: quite possibly extremely pointless..
*/
NV_WRITE(chan->get, chan->pushbuf_base);
NV_WRITE(chan->put, 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.
@ -393,14 +405,12 @@ void nouveau_fifo_free(struct nouveau_channel *chan)
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);
}
* it will crash when removing gpu objects
*XXX: from real-world evidence, absolutely useless..
*/
NV_WRITE(chan->get, chan->pushbuf_base);
NV_WRITE(chan->put, chan->pushbuf_base);
// FIXME XXX needs more code
engine->fifo.destroy_context(chan);
@ -495,14 +505,8 @@ static int nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data,
/* make the fifo available to user space */
/* first, the fifo control regs */
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;
}
init->ctrl = dev_priv->mmio->offset + chan->user;
init->ctrl_size = chan->user_size;
res = drm_addmap(dev, init->ctrl, init->ctrl_size, _DRM_REGISTERS,
0, &chan->regs);
if (res != 0)

View file

@ -45,16 +45,40 @@
#define NV_CLASS_NULL 0x00000030
#define NV_CLASS_DMA_IN_MEMORY 0x0000003D
#define NV03_USER(i) (0x00800000+(i*NV03_USER_SIZE))
#define NV03_USER__SIZE 16
#define NV10_USER__SIZE 32
#define NV03_USER_SIZE 0x00010000
#define NV03_USER_DMA_PUT(i) (0x00800040+(i*NV03_USER_SIZE))
#define NV03_USER_DMA_PUT__SIZE 16
#define NV10_USER_DMA_PUT__SIZE 32
#define NV03_USER_DMA_GET(i) (0x00800044+(i*NV03_USER_SIZE))
#define NV03_USER_DMA_GET__SIZE 16
#define NV10_USER_DMA_GET__SIZE 32
#define NV03_USER_REF_CNT(i) (0x00800048+(i*NV03_USER_SIZE))
#define NV03_USER_REF_CNT__SIZE 16
#define NV10_USER_REF_CNT__SIZE 32
#define NV40_USER(i) (0x00c00000+(i*NV40_USER_SIZE))
#define NV40_USER_SIZE 0x00001000
#define NV40_USER_DMA_PUT(i) (0x00c00040+(i*NV40_USER_SIZE))
#define NV40_USER_DMA_PUT__SIZE 32
#define NV40_USER_DMA_GET(i) (0x00c00044+(i*NV40_USER_SIZE))
#define NV40_USER_DMA_GET__SIZE 32
#define NV40_USER_REF_CNT(i) (0x00c00048+(i*NV40_USER_SIZE))
#define NV40_USER_REF_CNT__SIZE 32
#define NV50_USER(i) (0x00c00000+(i*NV50_USER_SIZE))
#define NV50_USER_SIZE 0x00002000
#define NV50_USER_DMA_PUT(i) (0x00c00040+(i*NV50_USER_SIZE))
#define NV50_USER_DMA_PUT__SIZE 128
#define NV50_USER_DMA_GET(i) (0x00c00044+(i*NV50_USER_SIZE))
#define NV50_USER_DMA_GET__SIZE 128
/*XXX: I don't think this actually exists.. */
#define NV50_USER_REF_CNT(i) (0x00c00048+(i*NV50_USER_SIZE))
#define NV50_USER_REF_CNT__SIZE 128
#define NV03_FIFO_SIZE 0x8000UL
#define NV_MAX_FIFO_NUMBER 128
#define NV03_FIFO_REGS_SIZE 0x10000
#define NV03_FIFO_REGS(i) (0x00800000+i*NV03_FIFO_REGS_SIZE)
# define NV03_FIFO_REGS_DMAPUT(i) (NV03_FIFO_REGS(i)+0x40)
# define NV03_FIFO_REGS_DMAGET(i) (NV03_FIFO_REGS(i)+0x44)
#define NV50_FIFO_REGS_SIZE 0x2000
#define NV50_FIFO_REGS(i) (0x00c00000+i*NV50_FIFO_REGS_SIZE)
# define NV50_FIFO_REGS_DMAPUT(i) (NV50_FIFO_REGS(i)+0x40)
# define NV50_FIFO_REGS_DMAGET(i) (NV50_FIFO_REGS(i)+0x44)
#define NV03_PMC_BOOT_0 0x00000000
#define NV03_PMC_BOOT_1 0x00000004