Context switching work.
Added preliminary support for context switches (triggers the interrupts, but hangs after the switch ; something's not quite right yet). Removed the PFIFO_REINIT ioctl. I hope it's that a good idea... Requires the upcoming commit to the DDX.main
parent
22382bd8c5
commit
dd473411f8
|
@ -25,7 +25,7 @@
|
|||
#ifndef __NOUVEAU_DRM_H__
|
||||
#define __NOUVEAU_DRM_H__
|
||||
|
||||
typedef struct drm_nouveau_fifo_init {
|
||||
typedef struct drm_nouveau_fifo_alloc {
|
||||
int channel;
|
||||
uint32_t put_base;
|
||||
/* FIFO control regs */
|
||||
|
@ -35,7 +35,7 @@ typedef struct drm_nouveau_fifo_init {
|
|||
drm_handle_t cmdbuf;
|
||||
int cmdbuf_size;
|
||||
}
|
||||
drm_nouveau_fifo_init_t;
|
||||
drm_nouveau_fifo_alloc_t;
|
||||
|
||||
typedef struct drm_nouveau_object_init {
|
||||
uint32_t handle;
|
||||
|
@ -122,14 +122,13 @@ typedef struct drm_nouveau_sarea {
|
|||
}
|
||||
drm_nouveau_sarea_t;
|
||||
|
||||
#define DRM_NOUVEAU_FIFO_INIT 0x00
|
||||
#define DRM_NOUVEAU_PFIFO_REINIT 0x01
|
||||
#define DRM_NOUVEAU_OBJECT_INIT 0x02
|
||||
#define DRM_NOUVEAU_DMA_OBJECT_INIT 0x03 // We don't want this eventually..
|
||||
#define DRM_NOUVEAU_MEM_ALLOC 0x04
|
||||
#define DRM_NOUVEAU_MEM_FREE 0x05
|
||||
#define DRM_NOUVEAU_GETPARAM 0x06
|
||||
#define DRM_NOUVEAU_SETPARAM 0x07
|
||||
#define DRM_NOUVEAU_FIFO_ALLOC 0x00
|
||||
#define DRM_NOUVEAU_OBJECT_INIT 0x01
|
||||
#define DRM_NOUVEAU_DMA_OBJECT_INIT 0x02 // We don't want this eventually..
|
||||
#define DRM_NOUVEAU_MEM_ALLOC 0x03
|
||||
#define DRM_NOUVEAU_MEM_FREE 0x04
|
||||
#define DRM_NOUVEAU_GETPARAM 0x05
|
||||
#define DRM_NOUVEAU_SETPARAM 0x06
|
||||
|
||||
#endif /* __NOUVEAU_DRM_H__ */
|
||||
|
||||
|
|
|
@ -123,6 +123,9 @@ typedef struct drm_nouveau_private {
|
|||
|
||||
struct nouveau_fifo fifos[NV_MAX_FIFO_NUMBER];
|
||||
struct nouveau_object_store objs;
|
||||
/* RAMFC and RAMRO offsets */
|
||||
uint32_t ramfc_offset;
|
||||
uint32_t ramro_offset;
|
||||
|
||||
struct mem_block *agp_heap;
|
||||
struct mem_block *fb_heap;
|
||||
|
@ -139,7 +142,7 @@ extern int nouveau_firstopen(struct drm_device *dev);
|
|||
extern int nouveau_unload(struct drm_device *dev);
|
||||
extern int nouveau_ioctl_getparam(DRM_IOCTL_ARGS);
|
||||
extern int nouveau_ioctl_setparam(DRM_IOCTL_ARGS);
|
||||
extern int nouveau_dma_init(struct drm_device *dev);
|
||||
extern void nouveau_wait_for_idle(struct drm_device *dev);
|
||||
|
||||
/* nouveau_mem.c */
|
||||
extern uint64_t nouveau_mem_fb_amount(struct drm_device *dev);
|
||||
|
|
|
@ -44,23 +44,6 @@ int nouveau_fifo_number(drm_device_t* dev)
|
|||
}
|
||||
}
|
||||
|
||||
/* setup the fifo enable register */
|
||||
static void nouveau_fifo_enable(drm_device_t* dev)
|
||||
{
|
||||
int i;
|
||||
unsigned enable_val=0;
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
for(i=31;i>=0;i--)
|
||||
{
|
||||
enable_val<<=1;
|
||||
if (dev_priv->fifos[i].used)
|
||||
enable_val|=1;
|
||||
}
|
||||
DRM_DEBUG("enable_val=0x%08x\n", enable_val);
|
||||
NV_WRITE(NV03_FIFO_ENABLE,enable_val);
|
||||
}
|
||||
|
||||
/***********************************
|
||||
* functions doing the actual work
|
||||
***********************************/
|
||||
|
@ -70,12 +53,141 @@ static void nouveau_fifo_enable(drm_device_t* dev)
|
|||
* voir nv_driver.c : NVPreInit
|
||||
*/
|
||||
|
||||
/* initializes a fifo */
|
||||
static int nouveau_fifo_init(drm_device_t* dev,drm_nouveau_fifo_init_t* init, DRMFILE filp)
|
||||
static void nouveau_fifo_init(drm_device_t* dev)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
/* Init PFIFO - This is an exact copy of what's done in the Xorg ddx so far.
|
||||
* We should be able to figure out what's happening from the
|
||||
* resources available..
|
||||
*/
|
||||
|
||||
if (dev->irq_enabled)
|
||||
nouveau_irq_postinstall(dev);
|
||||
|
||||
if (dev_priv->card_type >= NV_40)
|
||||
NV_WRITE(NV_PGRAPH_NV40_UNK220, dev_priv->fb_obj->instance >> 4);
|
||||
|
||||
DRM_DEBUG("%s: setting FIFO %d active\n", __func__, dev_priv->cur_fifo);
|
||||
|
||||
NV_WRITE(NV_PFIFO_CACHES, 0x00000000);
|
||||
NV_WRITE(NV_PFIFO_MODE, 0x00000000);
|
||||
|
||||
NV_WRITE(NV_PFIFO_CACH1_PSH0, 0x00000000);
|
||||
NV_WRITE(NV_PFIFO_CACH1_PUL0, 0x00000000);
|
||||
if (dev_priv->card_type >= NV_40)
|
||||
NV_WRITE(NV_PFIFO_CACH1_PSH1, 0x00010000|dev_priv->cur_fifo);
|
||||
else
|
||||
NV_WRITE(NV_PFIFO_CACH1_PSH1, 0x00000100|dev_priv->cur_fifo);
|
||||
NV_WRITE(NV_PFIFO_CACH1_DMAP, dev_priv->cur_fifo * dev_priv->cmdbuf_ch_size);
|
||||
NV_WRITE(NV_PFIFO_CACH1_DMAG, dev_priv->cur_fifo * dev_priv->cmdbuf_ch_size);
|
||||
NV_WRITE(NV_PFIFO_CACH1_DMAI, dev_priv->cmdbuf_obj->instance >> 4);
|
||||
NV_WRITE(NV_PFIFO_CACH0_PSH0, 0x00000000);
|
||||
NV_WRITE(NV_PFIFO_CACH0_PUL0, 0x00000000);
|
||||
NV_WRITE(NV_PFIFO_SIZE , 0x0000FFFF);
|
||||
NV_WRITE(NV_PFIFO_CACH1_HASH, 0x0000FFFF);
|
||||
NV_WRITE(NV_PFIFO_RAMHT,
|
||||
(0x03 << 24) /* search 128 */ |
|
||||
((dev_priv->objs.ht_bits - 9) << 16) |
|
||||
(dev_priv->objs.ht_base >> 8)
|
||||
);
|
||||
dev_priv->ramfc_offset=0x11000;
|
||||
dev_priv->ramro_offset=0x11200;
|
||||
NV_WRITE(NV_PFIFO_RAMFC, dev_priv->ramfc_offset>>8); /* RAMIN+0x11000 0.5k */
|
||||
NV_WRITE(NV_PFIFO_RAMRO, dev_priv->ramro_offset>>8); /* RAMIN+0x11200 0.5k */
|
||||
NV_WRITE(NV_PFIFO_CACH0_PUL1, 0x00000001);
|
||||
NV_WRITE(NV_PFIFO_CACH1_DMAC, 0x00000000);
|
||||
NV_WRITE(NV_PFIFO_CACH1_DMAS, 0x00000000);
|
||||
NV_WRITE(NV_PFIFO_CACH1_ENG, 0x00000000);
|
||||
#ifdef __BIG_ENDIAN
|
||||
NV_WRITE(NV_PFIFO_CACH1_DMAF, NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4|NV_PFIFO_CACH1_BIG_ENDIAN);
|
||||
#else
|
||||
NV_WRITE(NV_PFIFO_CACH1_DMAF, NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4);
|
||||
#endif
|
||||
NV_WRITE(NV_PFIFO_CACH1_DMAPSH, 0x00000001);
|
||||
NV_WRITE(NV_PFIFO_CACH1_PSH0, 0x00000001);
|
||||
NV_WRITE(NV_PFIFO_CACH1_PUL0, 0x00000001);
|
||||
NV_WRITE(NV_PFIFO_CACH1_PUL1, 0x00000001);
|
||||
|
||||
NV_WRITE(NV_PGRAPH_CTX_USER, 0x0);
|
||||
NV_WRITE(NV_PGRAPH_CTX_SWITCH1, 0x19);
|
||||
NV_WRITE(NV_PFIFO_DELAY_0, 0xff /* retrycount*/ );
|
||||
if (dev_priv->card_type >= NV_40)
|
||||
NV_WRITE(NV_PGRAPH_CTX_CONTROL, 0x00002001);
|
||||
else
|
||||
NV_WRITE(NV_PGRAPH_CTX_CONTROL, 0x10110000);
|
||||
|
||||
NV_WRITE(NV_PFIFO_DMA_TIMESLICE, 0x001fffff);
|
||||
NV_WRITE(NV_PFIFO_CACHES, 0x00000001);
|
||||
|
||||
DRM_DEBUG("%s: CACHE1 GET/PUT readback %d/%d\n", __func__,
|
||||
NV_READ(NV_PFIFO_CACH1_DMAG),
|
||||
NV_READ(NV_PFIFO_CACH1_DMAP));
|
||||
|
||||
DRM_INFO("%s: OK\n", __func__);
|
||||
}
|
||||
|
||||
static int nouveau_dma_init(struct drm_device *dev)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
struct nouveau_config *config = &dev_priv->config;
|
||||
struct mem_block *cb;
|
||||
int cb_min_size = nouveau_fifo_number(dev) * NV03_FIFO_SIZE;
|
||||
|
||||
/* XXX this should be done earlier on init */
|
||||
nouveau_hash_table_init(dev);
|
||||
|
||||
if (dev_priv->card_type >= NV_40)
|
||||
dev_priv->fb_obj = nouveau_dma_object_create(dev,
|
||||
0, nouveau_mem_fb_amount(dev),
|
||||
NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM);
|
||||
|
||||
/* 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, (DRMFILE)-2);
|
||||
/* Try defaults if that didn't succeed */
|
||||
if (!cb) {
|
||||
config->cmdbuf.location = NOUVEAU_MEM_FB;
|
||||
config->cmdbuf.size = cb_min_size;
|
||||
cb = nouveau_mem_alloc(dev, 0, config->cmdbuf.size,
|
||||
config->cmdbuf.location, (DRMFILE)-2);
|
||||
}
|
||||
if (!cb) {
|
||||
DRM_ERROR("Couldn't allocate DMA command buffer.\n");
|
||||
return DRM_ERR(ENOMEM);
|
||||
}
|
||||
|
||||
if (config->cmdbuf.location == NOUVEAU_MEM_AGP)
|
||||
dev_priv->cmdbuf_obj = nouveau_dma_object_create(dev,
|
||||
cb->start, cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_AGP);
|
||||
else
|
||||
dev_priv->cmdbuf_obj = nouveau_dma_object_create(dev,
|
||||
cb->start - drm_get_resource_start(dev, 1),
|
||||
cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_VIDMEM);
|
||||
dev_priv->cmdbuf_ch_size = (uint32_t)cb->size / nouveau_fifo_number(dev);
|
||||
dev_priv->cmdbuf_alloc = cb;
|
||||
|
||||
nouveau_fifo_init(dev);
|
||||
DRM_INFO("DMA command buffer is %dKiB at 0x%08x(%s)\n",
|
||||
(uint32_t)cb->size>>10, (uint32_t)cb->start,
|
||||
config->cmdbuf.location == NOUVEAU_MEM_FB ? "VRAM" : "AGP");
|
||||
DRM_INFO("FIFO size is %dKiB\n", dev_priv->cmdbuf_ch_size>>10);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* allocates and initializes a fifo for user space consumption */
|
||||
static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init, DRMFILE filp)
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
uint32_t ctx_addr;
|
||||
|
||||
/* Init cmdbuf on first FIFO init, this is delayed until now to
|
||||
* give the ddx a chance to configure the cmdbuf with SETPARAM
|
||||
|
@ -90,18 +202,15 @@ static int nouveau_fifo_init(drm_device_t* dev,drm_nouveau_fifo_init_t* init, DR
|
|||
* Alright, here is the full story
|
||||
* Nvidia cards have multiple hw fifo contexts (praise them for that,
|
||||
* no complicated crash-prone context switches)
|
||||
* X always uses context 0 (0x00800000)
|
||||
* We allocate a new context for each app and let it write to it directly
|
||||
* (woo, full userspace command submission !)
|
||||
* When there are no more contexts, you lost
|
||||
*/
|
||||
for(i=0;i<nouveau_fifo_number(dev);i++)
|
||||
if (dev_priv->fifos[i].used==0)
|
||||
{
|
||||
dev_priv->fifos[i].used=1;
|
||||
break;
|
||||
}
|
||||
|
||||
DRM_INFO("Allocating FIFO number %d\n", i);
|
||||
/* no more fifos. you lost. */
|
||||
if (i==nouveau_fifo_number(dev))
|
||||
return DRM_ERR(EINVAL);
|
||||
|
@ -110,16 +219,49 @@ static int nouveau_fifo_init(drm_device_t* dev,drm_nouveau_fifo_init_t* init, DR
|
|||
dev_priv->fifos[i].used=1;
|
||||
dev_priv->fifos[i].filp=filp;
|
||||
|
||||
/* enable the fifo */
|
||||
nouveau_fifo_enable(dev);
|
||||
nouveau_wait_for_idle(dev);
|
||||
|
||||
/* disable the fifo caches */
|
||||
NV_WRITE(NV_PFIFO_CACHES, 0x00000000);
|
||||
|
||||
// FIXME i*32 is true on nv04, what is it on >=nv10 ?
|
||||
ctx_addr=NV_RAMIN+dev_priv->ramfc_offset+i*32;
|
||||
|
||||
// clear the first 2 RAMFC entries
|
||||
// FIXME try to fill GET/PUT and see what that changes
|
||||
NV_WRITE(ctx_addr,0x0);
|
||||
NV_WRITE(ctx_addr+4,0x0);
|
||||
|
||||
// FIXME that's what is done in nvosdk, but that part of the code is buggy so...
|
||||
// RAMFC + 8 = instoffset
|
||||
NV_WRITE(ctx_addr+8,dev_priv->cmdbuf_obj->instance >> 4);
|
||||
|
||||
// RAMFC + 16 = defaultFetch
|
||||
NV_WRITE(ctx_addr+16,NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES|NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES|NV_PFIFO_CACH1_DMAF_MAX_REQS_4);
|
||||
|
||||
/* enable the fifo dma operation */
|
||||
NV_WRITE(NV_PFIFO_MODE,NV_READ(NV_PFIFO_MODE)|(1<<i));
|
||||
|
||||
// FIXME check if we need to refill the time quota with something like NV_WRITE(0x204C, 0x0003FFFF);
|
||||
|
||||
dev_priv->cur_fifo=i;
|
||||
if (dev_priv->card_type >= NV_40)
|
||||
NV_WRITE(NV_PFIFO_CACH1_PSH1, 0x00010000|dev_priv->cur_fifo);
|
||||
else
|
||||
NV_WRITE(NV_PFIFO_CACH1_PSH1, 0x00000100|dev_priv->cur_fifo);
|
||||
|
||||
/* make the fifo available to user space */
|
||||
init->channel = i;
|
||||
init->put_base = i*dev_priv->cmdbuf_ch_size;
|
||||
|
||||
NV_WRITE(NV03_FIFO_REGS_DMAPUT(i), init->put_base);
|
||||
NV_WRITE(NV03_FIFO_REGS_DMAGET(i), init->put_base);
|
||||
NV_WRITE(NV_PFIFO_CACH1_DMAP, init->put_base);
|
||||
NV_WRITE(NV_PFIFO_CACH1_DMAG, init->put_base);
|
||||
|
||||
/* reenable the fifo caches */
|
||||
NV_WRITE(NV_PFIFO_CACHES, 0x00000001);
|
||||
|
||||
/* make the fifo available to user space */
|
||||
/* first, the fifo control regs */
|
||||
init->ctrl = dev_priv->mmio->offset + NV03_FIFO_REGS(i);
|
||||
init->ctrl_size = NV03_FIFO_REGS_SIZE;
|
||||
|
@ -140,14 +282,29 @@ static int nouveau_fifo_init(drm_device_t* dev,drm_nouveau_fifo_init_t* init, DR
|
|||
/* FIFO has no objects yet */
|
||||
dev_priv->fifos[i].objs = NULL;
|
||||
|
||||
DRM_DEBUG("%s: initialised FIFO %d\n", __func__, i);
|
||||
dev_priv->cur_fifo = i;
|
||||
DRM_INFO("%s: initialised FIFO %d\n", __func__, i);
|
||||
return 0;
|
||||
}
|
||||
static void nouveau_pfifo_init(drm_device_t* dev);
|
||||
|
||||
/* stops a fifo */
|
||||
void nouveau_fifo_free(drm_device_t* dev,int n)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
dev_priv->fifos[n].used=0;
|
||||
DRM_DEBUG("%s: freeing fifo %d\n", __func__, n);
|
||||
|
||||
/* disable the fifo caches */
|
||||
NV_WRITE(NV_PFIFO_CACHES, 0x00000000);
|
||||
|
||||
NV_WRITE(NV_PFIFO_MODE,NV_READ(NV_PFIFO_MODE)&~(1<<n));
|
||||
// FIXME XXX needs more code
|
||||
|
||||
/* reenable the fifo caches */
|
||||
NV_WRITE(NV_PFIFO_CACHES, 0x00000001);
|
||||
}
|
||||
|
||||
/* cleanups all the fifos from filp */
|
||||
void nouveau_fifo_cleanup(drm_device_t * dev, DRMFILE filp)
|
||||
void nouveau_fifo_cleanup(drm_device_t* dev, DRMFILE filp)
|
||||
{
|
||||
int i;
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
|
@ -155,9 +312,10 @@ void nouveau_fifo_cleanup(drm_device_t * dev, DRMFILE filp)
|
|||
DRM_DEBUG("clearing FIFO enables from filp\n");
|
||||
for(i=0;i<nouveau_fifo_number(dev);i++)
|
||||
if (dev_priv->fifos[i].filp==filp)
|
||||
dev_priv->fifos[i].used=0;
|
||||
nouveau_fifo_free(dev,i);
|
||||
|
||||
if (dev_priv->cur_fifo == i) {
|
||||
/* check we still point at an active channel */
|
||||
if (dev_priv->fifos[dev_priv->cur_fifo].used == 0) {
|
||||
DRM_DEBUG("%s: cur_fifo is no longer owned.\n", __func__);
|
||||
for (i=0;i<nouveau_fifo_number(dev);i++)
|
||||
if (dev_priv->fifos[i].used) break;
|
||||
|
@ -167,9 +325,8 @@ void nouveau_fifo_cleanup(drm_device_t * dev, DRMFILE filp)
|
|||
dev_priv->cur_fifo = i;
|
||||
}
|
||||
|
||||
if (dev_priv->cmdbuf_alloc)
|
||||
nouveau_pfifo_init(dev);
|
||||
// nouveau_fifo_enable(dev);
|
||||
/* if (dev_priv->cmdbuf_alloc)
|
||||
nouveau_fifo_init(dev);*/
|
||||
}
|
||||
|
||||
int nouveau_fifo_id_get(drm_device_t* dev, DRMFILE filp)
|
||||
|
@ -183,99 +340,30 @@ int nouveau_fifo_id_get(drm_device_t* dev, DRMFILE filp)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void nouveau_pfifo_init(drm_device_t* dev)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
/* Init PFIFO - This is an exact copy of what's done in the Xorg ddx so far.
|
||||
* We should be able to figure out what's happening from the
|
||||
* resources available..
|
||||
*/
|
||||
|
||||
if (dev->irq_enabled)
|
||||
nouveau_irq_postinstall(dev);
|
||||
|
||||
if (dev_priv->card_type >= NV_40)
|
||||
NV_WRITE(NV_PGRAPH_NV40_UNK220, dev_priv->fb_obj->instance >> 4);
|
||||
|
||||
DRM_DEBUG("%s: setting FIFO %d active\n", __func__, dev_priv->cur_fifo);
|
||||
|
||||
NV_WRITE(NV_PFIFO_CACHES, 0x00000000);
|
||||
nouveau_fifo_enable(dev);
|
||||
|
||||
NV_WRITE(NV_PFIFO_CACH1_PSH0, 0x00000000);
|
||||
NV_WRITE(NV_PFIFO_CACH1_PUL0, 0x00000000);
|
||||
if (dev_priv->card_type >= NV_40)
|
||||
NV_WRITE(NV_PFIFO_CACH1_PSH1, 0x00010000|dev_priv->cur_fifo);
|
||||
else
|
||||
NV_WRITE(NV_PFIFO_CACH1_PSH1, 0x00000100|dev_priv->cur_fifo);
|
||||
NV_WRITE(NV_PFIFO_CACH1_DMAP, dev_priv->cur_fifo * dev_priv->cmdbuf_ch_size);
|
||||
NV_WRITE(NV_PFIFO_CACH1_DMAG, dev_priv->cur_fifo * dev_priv->cmdbuf_ch_size);
|
||||
NV_WRITE(NV_PFIFO_CACH1_DMAI, dev_priv->cmdbuf_obj->instance >> 4);
|
||||
NV_WRITE(NV_PFIFO_CACH0_PSH0, 0x00000000);
|
||||
NV_WRITE(NV_PFIFO_CACH0_PUL0, 0x00000000);
|
||||
NV_WRITE(NV_PFIFO_SIZE , 0x0000FFFF);
|
||||
NV_WRITE(NV_PFIFO_CACH1_HASH, 0x0000FFFF);
|
||||
NV_WRITE(NV_PFIFO_RAMHT,
|
||||
(0x03 << 24) /* search 128 */ |
|
||||
((dev_priv->objs.ht_bits - 9) << 16) |
|
||||
(dev_priv->objs.ht_base >> 8)
|
||||
);
|
||||
NV_WRITE(NV_PFIFO_RAMFC, 0x00000110); /* RAMIN+0x11000 0.5k */
|
||||
NV_WRITE(NV_PFIFO_RAMRO, 0x00000112); /* RAMIN+0x11200 0.5k */
|
||||
NV_WRITE(NV_PFIFO_CACH0_PUL1, 0x00000001);
|
||||
NV_WRITE(NV_PFIFO_CACH1_DMAC, 0x00000000);
|
||||
NV_WRITE(NV_PFIFO_CACH1_ENG, 0x00000000);
|
||||
#ifdef __BIG_ENDIAN
|
||||
NV_WRITE(NV_PFIFO_CACH1_DMAF, 0x800F0078);
|
||||
#else
|
||||
NV_WRITE(NV_PFIFO_CACH1_DMAF, 0x000F0078);
|
||||
#endif
|
||||
NV_WRITE(NV_PFIFO_CACH1_DMAS, 0x00000001);
|
||||
NV_WRITE(NV_PFIFO_CACH1_PSH0, 0x00000001);
|
||||
NV_WRITE(NV_PFIFO_CACH1_PUL0, 0x00000001);
|
||||
NV_WRITE(NV_PFIFO_CACH1_PUL1, 0x00000001);
|
||||
|
||||
NV_WRITE(NV_PFIFO_CACHES, 0x00000001);
|
||||
|
||||
DRM_DEBUG("%s: CACHE1 GET/PUT readback %d/%d\n", __func__,
|
||||
NV_READ(NV_PFIFO_CACH1_DMAG),
|
||||
NV_READ(NV_PFIFO_CACH1_DMAP));
|
||||
}
|
||||
|
||||
/***********************************
|
||||
* ioctls wrapping the functions
|
||||
***********************************/
|
||||
|
||||
static int nouveau_ioctl_fifo_init(DRM_IOCTL_ARGS)
|
||||
static int nouveau_ioctl_fifo_alloc(DRM_IOCTL_ARGS)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_nouveau_fifo_init_t init;
|
||||
drm_nouveau_fifo_alloc_t init;
|
||||
int res;
|
||||
DRM_COPY_FROM_USER_IOCTL(init, (drm_nouveau_fifo_init_t __user *) data, sizeof(init));
|
||||
DRM_COPY_FROM_USER_IOCTL(init, (drm_nouveau_fifo_alloc_t __user *) data, sizeof(init));
|
||||
|
||||
res=nouveau_fifo_init(dev,&init,filp);
|
||||
res=nouveau_fifo_alloc(dev,&init,filp);
|
||||
if (!res)
|
||||
DRM_COPY_TO_USER_IOCTL((drm_nouveau_fifo_init_t __user *)data, init, sizeof(init));
|
||||
DRM_COPY_TO_USER_IOCTL((drm_nouveau_fifo_alloc_t __user *)data, init, sizeof(init));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int nouveau_ioctl_fifo_reinit(DRM_IOCTL_ARGS)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
|
||||
nouveau_pfifo_init(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************
|
||||
* finally, the ioctl table
|
||||
***********************************/
|
||||
|
||||
drm_ioctl_desc_t nouveau_ioctls[] = {
|
||||
[DRM_IOCTL_NR(DRM_NOUVEAU_FIFO_INIT)] = {nouveau_ioctl_fifo_init, DRM_AUTH},
|
||||
[DRM_IOCTL_NR(DRM_NOUVEAU_PFIFO_REINIT)] = {nouveau_ioctl_fifo_reinit, DRM_AUTH},
|
||||
[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_MEM_ALLOC)] = {nouveau_ioctl_mem_alloc, DRM_AUTH},
|
||||
|
|
|
@ -46,7 +46,10 @@ void nouveau_irq_preinstall(drm_device_t *dev)
|
|||
NV_WRITE(NV_PFIFO_INTEN, 0);
|
||||
NV_WRITE(NV_PFIFO_INTSTAT, 0xFFFFFFFF);
|
||||
/* Disable/Clear PGRAPH interrupts */
|
||||
NV_WRITE(NV_PGRAPH_INTEN, 0);
|
||||
if (dev_priv->card_type<NV_40)
|
||||
NV_WRITE(NV04_PGRAPH_INTEN, 0);
|
||||
else
|
||||
NV_WRITE(NV40_PGRAPH_INTEN, 0);
|
||||
NV_WRITE(NV_PGRAPH_INTSTAT, 0xFFFFFFFF);
|
||||
#if 0
|
||||
/* Disable/Clear CRTC0/1 interrupts */
|
||||
|
@ -70,9 +73,19 @@ void nouveau_irq_postinstall(drm_device_t *dev)
|
|||
NV_WRITE(NV_PFIFO_INTSTAT, 0xFFFFFFFF);
|
||||
|
||||
/* Enable PGRAPH interrupts */
|
||||
NV_WRITE(NV_PGRAPH_INTEN,
|
||||
if (dev_priv->card_type<NV_40)
|
||||
NV_WRITE(NV04_PGRAPH_INTEN,
|
||||
NV_PGRAPH_INTR_NOTIFY |
|
||||
NV_PGRAPH_INTR_MISSING_HW |
|
||||
NV_PGRAPH_INTR_CONTEXT_SWITCH |
|
||||
NV_PGRAPH_INTR_BUFFER_NOTIFY |
|
||||
NV_PGRAPH_INTR_ERROR
|
||||
);
|
||||
else
|
||||
NV_WRITE(NV40_PGRAPH_INTEN,
|
||||
NV_PGRAPH_INTR_NOTIFY |
|
||||
NV_PGRAPH_INTR_MISSING_HW |
|
||||
NV_PGRAPH_INTR_CONTEXT_SWITCH |
|
||||
NV_PGRAPH_INTR_BUFFER_NOTIFY |
|
||||
NV_PGRAPH_INTR_ERROR
|
||||
);
|
||||
|
@ -97,7 +110,10 @@ void nouveau_irq_uninstall(drm_device_t *dev)
|
|||
/* Disable PFIFO interrupts */
|
||||
NV_WRITE(NV_PFIFO_INTEN, 0);
|
||||
/* Disable PGRAPH interrupts */
|
||||
NV_WRITE(NV_PGRAPH_INTEN, 0);
|
||||
if (dev_priv->card_type<NV_40)
|
||||
NV_WRITE(NV04_PGRAPH_INTEN, 0);
|
||||
else
|
||||
NV_WRITE(NV40_PGRAPH_INTEN, 0);
|
||||
#if 0
|
||||
/* Disable CRTC0/1 interrupts */
|
||||
NV_WRITE(NV_CRTC0_INTEN, 0);
|
||||
|
@ -107,15 +123,16 @@ void nouveau_irq_uninstall(drm_device_t *dev)
|
|||
NV_WRITE(NV_PMC_INTEN, 0);
|
||||
}
|
||||
|
||||
void nouveau_fifo_irq_handler(drm_nouveau_private_t *dev_priv)
|
||||
static void nouveau_fifo_irq_handler(drm_device_t *dev)
|
||||
{
|
||||
uint32_t status, chmode, chstat;
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
status = NV_READ(NV_PFIFO_INTSTAT);
|
||||
if (!status)
|
||||
return;
|
||||
chmode = NV_READ(NV_PFIFO_MODE);
|
||||
chstat = NV_READ(0x2508);
|
||||
chstat = NV_READ(NV_PFIFO_DMA);
|
||||
|
||||
DRM_DEBUG("NV: PFIFO interrupt! INTSTAT=0x%08x/MODE=0x%08x/PEND=0x%08x\n",
|
||||
status, chmode, chstat);
|
||||
|
@ -136,9 +153,73 @@ void nouveau_fifo_irq_handler(drm_nouveau_private_t *dev_priv)
|
|||
NV_WRITE(NV_PMC_INTSTAT, NV_PMC_INTSTAT_PFIFO_PENDING);
|
||||
}
|
||||
|
||||
void nouveau_pgraph_irq_handler(drm_nouveau_private_t *dev_priv)
|
||||
static void nouveau_nv04_context_switch(drm_device_t *dev)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
uint32_t channel,i;
|
||||
uint32_t max=0;
|
||||
NV_WRITE(NV_PGRAPH_FIFO,0x0);
|
||||
channel=NV_READ(NV_PFIFO_CACH1_PSH1)&(nouveau_fifo_number(dev)-1);
|
||||
//DRM_INFO("raw PFIFO_CACH1_PHS1 reg is %x\n",NV_READ(NV_PFIFO_CACH1_PSH1));
|
||||
//DRM_INFO("currently on channel %d\n",channel);
|
||||
for (i=0;i<nouveau_fifo_number(dev);i++)
|
||||
if ((dev_priv->fifos[i].used)&&(i!=channel)) {
|
||||
uint32_t put,get,pending;
|
||||
//put=NV_READ(dev_priv->ramfc_offset+i*32);
|
||||
//get=NV_READ(dev_priv->ramfc_offset+4+i*32);
|
||||
put=NV_READ(NV03_FIFO_REGS_DMAPUT(i));
|
||||
get=NV_READ(NV03_FIFO_REGS_DMAGET(i));
|
||||
pending=NV_READ(NV_PFIFO_DMA);
|
||||
//DRM_INFO("Channel %d (put/get %x/%x)\n",i,put,get);
|
||||
/* mark all pending channels as such */
|
||||
if ((put!=get)&!(pending&(1<<i)))
|
||||
{
|
||||
pending|=(1<<i);
|
||||
NV_WRITE(NV_PFIFO_DMA,pending);
|
||||
}
|
||||
max++;
|
||||
}
|
||||
nouveau_wait_for_idle(dev);
|
||||
|
||||
#if 1
|
||||
/* 2-channel commute */
|
||||
// NV_WRITE(NV_PFIFO_CACH1_PSH1,channel|0x100);
|
||||
if (channel==0)
|
||||
channel=1;
|
||||
else
|
||||
channel=0;
|
||||
// dev_priv->cur_fifo=channel;
|
||||
NV_WRITE(0x2050,channel|0x100);
|
||||
#endif
|
||||
//NV_WRITE(NV_PFIFO_CACH1_PSH1,max|0x100);
|
||||
//NV_WRITE(0x2050,max|0x100);
|
||||
|
||||
NV_WRITE(NV_PGRAPH_FIFO,0x1);
|
||||
|
||||
}
|
||||
|
||||
static void nouveau_nv10_context_switch(drm_device_t *dev)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
int channel;
|
||||
|
||||
channel=NV_READ(NV_PFIFO_CACH1_PSH1)&(nouveau_fifo_number(dev)-1);
|
||||
/* 2-channel commute */
|
||||
if (channel==0)
|
||||
channel=1;
|
||||
else
|
||||
channel=0;
|
||||
dev_priv->cur_fifo=channel;
|
||||
|
||||
NV_WRITE(NV_PGRAPH_CTX_USER, (NV_READ(NV_PGRAPH_CTX_USER)&0xE0FFFFFF)|(dev_priv->cur_fifo<<24));
|
||||
NV_WRITE(NV_PGRAPH_CTX_CONTROL, 0x10010100);
|
||||
NV_WRITE(NV_PGRAPH_FFINTFC_ST2, NV_READ(NV_PGRAPH_FFINTFC_ST2)&0xCFFFFFFF);
|
||||
}
|
||||
|
||||
static void nouveau_pgraph_irq_handler(drm_device_t *dev)
|
||||
{
|
||||
uint32_t status;
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
status = NV_READ(NV_PGRAPH_INTSTAT);
|
||||
if (!status)
|
||||
|
@ -190,6 +271,26 @@ void nouveau_pgraph_irq_handler(drm_nouveau_private_t *dev_priv)
|
|||
NV_WRITE(NV_PGRAPH_INTSTAT, NV_PGRAPH_INTR_ERROR);
|
||||
}
|
||||
|
||||
if (status & NV_PGRAPH_INTR_CONTEXT_SWITCH) {
|
||||
uint32_t channel=NV_READ(NV_PFIFO_CACH1_PSH1)&(nouveau_fifo_number(dev)-1);
|
||||
DRM_INFO("NV: PGRAPH context switch interrupt channel %x\n",channel);
|
||||
switch(dev_priv->card_type)
|
||||
{
|
||||
case NV_04:
|
||||
nouveau_nv04_context_switch(dev);
|
||||
break;
|
||||
case NV_10:
|
||||
nouveau_nv10_context_switch(dev);
|
||||
break;
|
||||
default:
|
||||
DRM_INFO("NV: Context switch not implemented\n");
|
||||
break;
|
||||
}
|
||||
|
||||
status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
|
||||
NV_WRITE(NV_PGRAPH_INTSTAT, NV_PGRAPH_INTR_CONTEXT_SWITCH);
|
||||
}
|
||||
|
||||
if (status) {
|
||||
DRM_INFO("NV: Unknown PGRAPH interrupt! STAT=0x%08x\n", status);
|
||||
NV_WRITE(NV_PGRAPH_INTSTAT, status);
|
||||
|
@ -198,8 +299,9 @@ void nouveau_pgraph_irq_handler(drm_nouveau_private_t *dev_priv)
|
|||
NV_WRITE(NV_PMC_INTSTAT, NV_PMC_INTSTAT_PGRAPH_PENDING);
|
||||
}
|
||||
|
||||
void nouveau_crtc_irq_handler(drm_nouveau_private_t *dev_priv, int crtc)
|
||||
static void nouveau_crtc_irq_handler(drm_device_t *dev, int crtc)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
if (crtc&1) {
|
||||
NV_WRITE(NV_CRTC0_INTSTAT, NV_CRTC_INTR_VBLANK);
|
||||
}
|
||||
|
@ -220,15 +322,15 @@ irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS)
|
|||
DRM_DEBUG("PMC INTSTAT: 0x%08x\n", status);
|
||||
|
||||
if (status & NV_PMC_INTSTAT_PFIFO_PENDING) {
|
||||
nouveau_fifo_irq_handler(dev_priv);
|
||||
nouveau_fifo_irq_handler(dev);
|
||||
status &= ~NV_PMC_INTSTAT_PFIFO_PENDING;
|
||||
}
|
||||
if (status & NV_PMC_INTSTAT_PGRAPH_PENDING) {
|
||||
nouveau_pgraph_irq_handler(dev_priv);
|
||||
nouveau_pgraph_irq_handler(dev);
|
||||
status &= ~NV_PMC_INTSTAT_PGRAPH_PENDING;
|
||||
}
|
||||
if (status & NV_PMC_INTSTAT_CRTCn_PENDING) {
|
||||
nouveau_crtc_irq_handler(dev_priv, (status>>24)&3);
|
||||
nouveau_crtc_irq_handler(dev, (status>>24)&3);
|
||||
status &= ~NV_PMC_INTSTAT_CRTCn_PENDING;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
# define NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK 0xfff00000
|
||||
# define NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT 20
|
||||
|
||||
#define NV03_STATUS 0x004006b0
|
||||
#define NV04_STATUS 0x00400700
|
||||
#define NV03_PGRAPH_STATUS 0x004006b0
|
||||
#define NV04_PGRAPH_STATUS 0x00400700
|
||||
|
||||
#define NV_RAMIN 0x00700000
|
||||
|
||||
|
@ -55,16 +55,24 @@
|
|||
# define NV_PMC_INTEN_MASTER_ENABLE (1<< 0)
|
||||
|
||||
#define NV_PGRAPH_INTSTAT 0x00400100
|
||||
#define NV_PGRAPH_INTEN 0x00400140
|
||||
#define NV04_PGRAPH_INTEN 0x00400140
|
||||
#define NV40_PGRAPH_INTEN 0x0040013C
|
||||
# define NV_PGRAPH_INTR_NOTIFY (1<< 0)
|
||||
# define NV_PGRAPH_INTR_MISSING_HW (1<< 4)
|
||||
# define NV_PGRAPH_INTR_CONTEXT_SWITCH (1<<12)
|
||||
# define NV_PGRAPH_INTR_BUFFER_NOTIFY (1<<16)
|
||||
# define NV_PGRAPH_INTR_ERROR (1<<20)
|
||||
#define NV_PGRAPH_CTX_CONTROL 0x00400144
|
||||
#define NV_PGRAPH_NV40_UNK220 0x00400220
|
||||
# define NV_PGRAPH_NV40_UNK220_FB_INSTANCE
|
||||
#define NV_PGRAPH_CTX_USER 0x00400148
|
||||
#define NV_PGRAPH_CTX_SWITCH1 0x0040014C
|
||||
#define NV_PGRAPH_FIFO 0x00400720
|
||||
#define NV_PGRAPH_FFINTFC_ST2 0x00400764
|
||||
|
||||
/* It's a guess that this works on NV03. Confirmed on NV04, though */
|
||||
#define NV03_FIFO_ENABLE 0x00002504
|
||||
#define NV_PFIFO_DELAY_0 0x00002040
|
||||
#define NV_PFIFO_DMA_TIMESLICE 0x00002044
|
||||
#define NV_PFIFO_INTSTAT 0x00002100
|
||||
#define NV_PFIFO_INTEN 0x00002140
|
||||
# define NV_PFIFO_INTR_ERROR (1<<0)
|
||||
|
@ -73,14 +81,78 @@
|
|||
#define NV_PFIFO_RAMRO 0x00002218
|
||||
#define NV_PFIFO_CACHES 0x00002500
|
||||
#define NV_PFIFO_MODE 0x00002504
|
||||
#define NV_PFIFO_DMA 0x00002508
|
||||
#define NV_PFIFO_SIZE 0x0000250c
|
||||
#define NV_PFIFO_CACH0_PSH0 0x00003000
|
||||
#define NV_PFIFO_CACH0_PUL0 0x00003050
|
||||
#define NV_PFIFO_CACH0_PUL1 0x00003054
|
||||
#define NV_PFIFO_CACH1_PSH0 0x00003200
|
||||
#define NV_PFIFO_CACH1_PSH1 0x00003204
|
||||
#define NV_PFIFO_CACH1_DMAS 0x00003220
|
||||
#define NV_PFIFO_CACH1_DMAPSH 0x00003220
|
||||
#define NV_PFIFO_CACH1_DMAF 0x00003224
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_8_BYTES 0x00000000
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_8_BYTES 0x00000000
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_16_BYTES 0x00000008
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_24_BYTES 0x00000010
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_32_BYTES 0x00000018
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_40_BYTES 0x00000020
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_48_BYTES 0x00000028
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_56_BYTES 0x00000030
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_64_BYTES 0x00000038
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_72_BYTES 0x00000040
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_80_BYTES 0x00000048
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_88_BYTES 0x00000050
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_96_BYTES 0x00000058
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_104_BYTES 0x00000060
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_112_BYTES 0x00000068
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_120_BYTES 0x00000070
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_128_BYTES 0x00000078
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_136_BYTES 0x00000080
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_144_BYTES 0x00000088
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_152_BYTES 0x00000090
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_160_BYTES 0x00000098
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_168_BYTES 0x000000A0
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_176_BYTES 0x000000A8
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_184_BYTES 0x000000B0
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_192_BYTES 0x000000B8
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_200_BYTES 0x000000C0
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_208_BYTES 0x000000C8
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_216_BYTES 0x000000D0
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_224_BYTES 0x000000D8
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_232_BYTES 0x000000E0
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_240_BYTES 0x000000E8
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_248_BYTES 0x000000F0
|
||||
# define NV_PFIFO_CACH1_DMAF_TRIG_256_BYTES 0x000000F8
|
||||
# define NV_PFIFO_CACH1_DMAF_SIZE 0x0000E000
|
||||
# define NV_PFIFO_CACH1_DMAF_SIZE_32_BYTES 0x00000000
|
||||
# define NV_PFIFO_CACH1_DMAF_SIZE_64_BYTES 0x00002000
|
||||
# define NV_PFIFO_CACH1_DMAF_SIZE_96_BYTES 0x00004000
|
||||
# define NV_PFIFO_CACH1_DMAF_SIZE_128_BYTES 0x00006000
|
||||
# define NV_PFIFO_CACH1_DMAF_SIZE_160_BYTES 0x00008000
|
||||
# define NV_PFIFO_CACH1_DMAF_SIZE_192_BYTES 0x0000A000
|
||||
# define NV_PFIFO_CACH1_DMAF_SIZE_224_BYTES 0x0000C000
|
||||
# define NV_PFIFO_CACH1_DMAF_SIZE_256_BYTES 0x0000E000
|
||||
# define NV_PFIFO_CACH1_DMAF_MAX_REQS 0x001F0000
|
||||
# define NV_PFIFO_CACH1_DMAF_MAX_REQS_0 0x00000000
|
||||
# define NV_PFIFO_CACH1_DMAF_MAX_REQS_1 0x00010000
|
||||
# define NV_PFIFO_CACH1_DMAF_MAX_REQS_2 0x00020000
|
||||
# define NV_PFIFO_CACH1_DMAF_MAX_REQS_3 0x00030000
|
||||
# define NV_PFIFO_CACH1_DMAF_MAX_REQS_4 0x00040000
|
||||
# define NV_PFIFO_CACH1_DMAF_MAX_REQS_5 0x00050000
|
||||
# define NV_PFIFO_CACH1_DMAF_MAX_REQS_6 0x00060000
|
||||
# define NV_PFIFO_CACH1_DMAF_MAX_REQS_7 0x00070000
|
||||
# define NV_PFIFO_CACH1_DMAF_MAX_REQS_8 0x00080000
|
||||
# define NV_PFIFO_CACH1_DMAF_MAX_REQS_9 0x00090000
|
||||
# define NV_PFIFO_CACH1_DMAF_MAX_REQS_10 0x000A0000
|
||||
# define NV_PFIFO_CACH1_DMAF_MAX_REQS_11 0x000B0000
|
||||
# define NV_PFIFO_CACH1_DMAF_MAX_REQS_12 0x000C0000
|
||||
# define NV_PFIFO_CACH1_DMAF_MAX_REQS_13 0x000D0000
|
||||
# define NV_PFIFO_CACH1_DMAF_MAX_REQS_14 0x000E0000
|
||||
# define NV_PFIFO_CACH1_DMAF_MAX_REQS_15 0x000F0000
|
||||
# define NV_PFIFO_CACH1_ENDIAN 0x80000000
|
||||
# define NV_PFIFO_CACH1_LITTLE_ENDIAN 0x7FFFFFFF
|
||||
# define NV_PFIFO_CACH1_BIG_ENDIAN 0x80000000
|
||||
#define NV_PFIFO_CACH1_DMAS 0x00003228
|
||||
#define NV_PFIFO_CACH1_DMAI 0x0000322c
|
||||
#define NV_PFIFO_CACH1_DMAC 0x00003230
|
||||
#define NV_PFIFO_CACH1_DMAP 0x00003240
|
||||
|
@ -101,3 +173,4 @@
|
|||
#define NV03_FIFO_CMD_JUMP_OFFSET_MASK 0x1ffffffc
|
||||
#define NV03_FIFO_CMD_REWIND (NV03_FIFO_CMD_JUMP | (0 & NV03_FIFO_CMD_JUMP_OFFSET_MASK))
|
||||
|
||||
|
||||
|
|
|
@ -150,55 +150,18 @@ int nouveau_ioctl_setparam(DRM_IOCTL_ARGS)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int nouveau_dma_init(struct drm_device *dev)
|
||||
/* waits for idle */
|
||||
void nouveau_wait_for_idle(struct drm_device *dev)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
struct nouveau_config *config = &dev_priv->config;
|
||||
struct mem_block *cb;
|
||||
int cb_min_size = nouveau_fifo_number(dev) * NV03_FIFO_SIZE;
|
||||
|
||||
nouveau_hash_table_init(dev);
|
||||
|
||||
if (dev_priv->card_type >= NV_40)
|
||||
dev_priv->fb_obj = nouveau_dma_object_create(dev,
|
||||
0, nouveau_mem_fb_amount(dev),
|
||||
NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM);
|
||||
|
||||
/* 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, (DRMFILE)-2);
|
||||
/* Try defaults if that didn't succeed */
|
||||
if (!cb) {
|
||||
config->cmdbuf.location = NOUVEAU_MEM_FB;
|
||||
config->cmdbuf.size = cb_min_size;
|
||||
cb = nouveau_mem_alloc(dev, 0, config->cmdbuf.size,
|
||||
config->cmdbuf.location, (DRMFILE)-2);
|
||||
drm_nouveau_private_t *dev_priv=dev->dev_private;
|
||||
switch(dev_priv->card_type)
|
||||
{
|
||||
case NV_03:
|
||||
while(NV_READ(NV03_PGRAPH_STATUS));
|
||||
break;
|
||||
default:
|
||||
while(NV_READ(NV04_PGRAPH_STATUS));
|
||||
break;
|
||||
}
|
||||
if (!cb) {
|
||||
DRM_ERROR("Couldn't allocate DMA command buffer.\n");
|
||||
return DRM_ERR(ENOMEM);
|
||||
}
|
||||
|
||||
if (config->cmdbuf.location == NOUVEAU_MEM_AGP)
|
||||
dev_priv->cmdbuf_obj = nouveau_dma_object_create(dev,
|
||||
cb->start, cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_AGP);
|
||||
else
|
||||
dev_priv->cmdbuf_obj = nouveau_dma_object_create(dev,
|
||||
cb->start - drm_get_resource_start(dev, 1),
|
||||
cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_VIDMEM);
|
||||
dev_priv->cmdbuf_ch_size = (uint32_t)cb->size / nouveau_fifo_number(dev);
|
||||
dev_priv->cmdbuf_alloc = cb;
|
||||
|
||||
DRM_INFO("DMA command buffer is %dKiB at 0x%08x(%s)\n",
|
||||
(uint32_t)cb->size>>10, (uint32_t)cb->start,
|
||||
config->cmdbuf.location == NOUVEAU_MEM_FB ? "VRAM" : "AGP");
|
||||
DRM_INFO("FIFO size is %dKiB\n", dev_priv->cmdbuf_ch_size>>10);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue