mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2025-12-31 21:50:14 +01:00
Added option to enable 3dnow in the host.def file. Enabled by default in
our host.def file.
Turned on G200.
Major rewrite of how the kernel module deals with primary/secondary
buffers.
Added fastpath asm that was posted on the Utah-GLX devel list.
Audit of use of int's when they should be unsigned int's.
-Jeff
This commit is contained in:
parent
c6e6ec0ace
commit
fed8c1a177
4 changed files with 268 additions and 302 deletions
292
linux/mga_dma.c
292
linux/mga_dma.c
|
|
@ -53,6 +53,7 @@ static unsigned long mga_alloc_page(drm_device_t *dev)
|
|||
{
|
||||
unsigned long address;
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
address = __get_free_page(GFP_KERNEL);
|
||||
if(address == 0UL) {
|
||||
return 0;
|
||||
|
|
@ -65,6 +66,8 @@ static unsigned long mga_alloc_page(drm_device_t *dev)
|
|||
|
||||
static void mga_free_page(drm_device_t *dev, unsigned long page)
|
||||
{
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
if(page == 0UL) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -80,9 +83,11 @@ static void mga_delay(void)
|
|||
return;
|
||||
}
|
||||
|
||||
static void mga_flush_write_combine(void)
|
||||
void mga_flush_write_combine(void)
|
||||
{
|
||||
int xchangeDummy;
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
__asm__ volatile(" push %%eax ; xchg %%eax, %0 ; pop %%eax" : : "m" (xchangeDummy));
|
||||
__asm__ volatile(" push %%eax ; push %%ebx ; push %%ecx ; push %%edx ;"
|
||||
" movl $0,%%eax ; cpuid ; pop %%edx ; pop %%ecx ; pop %%ebx ;"
|
||||
|
|
@ -94,18 +99,6 @@ static void mga_flush_write_combine(void)
|
|||
#define MGA_BUF_USED 0xffffffff
|
||||
#define MGA_BUF_FREE 0
|
||||
|
||||
static void mga_freelist_debug(drm_mga_freelist_t *item)
|
||||
{
|
||||
if(item->buf != NULL) {
|
||||
DRM_DEBUG("buf index : %d\n", item->buf->idx);
|
||||
} else {
|
||||
DRM_DEBUG("Freelist head\n");
|
||||
}
|
||||
DRM_DEBUG("item->age : %x\n", item->age);
|
||||
DRM_DEBUG("item->next : %p\n", item->next);
|
||||
DRM_DEBUG("item->prev : %p\n", item->prev);
|
||||
}
|
||||
|
||||
static int mga_freelist_init(drm_device_t *dev)
|
||||
{
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
|
|
@ -114,7 +107,9 @@ static int mga_freelist_init(drm_device_t *dev)
|
|||
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
|
||||
drm_mga_freelist_t *item;
|
||||
int i;
|
||||
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
dev_priv->head = drm_alloc(sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER);
|
||||
if(dev_priv->head == NULL) return -ENOMEM;
|
||||
memset(dev_priv->head, 0, sizeof(drm_mga_freelist_t));
|
||||
|
|
@ -136,19 +131,10 @@ static int mga_freelist_init(drm_device_t *dev)
|
|||
item->buf = buf;
|
||||
buf_priv->my_freelist = item;
|
||||
buf_priv->discard = 0;
|
||||
buf_priv->dispatched = 0;
|
||||
dev_priv->head->next = item;
|
||||
}
|
||||
|
||||
item = dev_priv->head;
|
||||
while(item) {
|
||||
mga_freelist_debug(item);
|
||||
item = item->next;
|
||||
}
|
||||
DRM_DEBUG("Head\n");
|
||||
mga_freelist_debug(dev_priv->head);
|
||||
DRM_DEBUG("Tail\n");
|
||||
mga_freelist_debug(dev_priv->tail);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -158,6 +144,8 @@ static void mga_freelist_cleanup(drm_device_t *dev)
|
|||
drm_mga_freelist_t *item;
|
||||
drm_mga_freelist_t *prev;
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
item = dev_priv->head;
|
||||
while(item) {
|
||||
prev = item;
|
||||
|
|
@ -174,11 +162,10 @@ static inline void mga_dma_quiescent(drm_device_t *dev)
|
|||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
|
||||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
__volatile__ unsigned int *status =
|
||||
(__volatile__ unsigned int *)dev_priv->status_page;
|
||||
unsigned long end;
|
||||
int i;
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
end = jiffies + (HZ*3);
|
||||
while(1) {
|
||||
if(!test_and_set_bit(MGA_IN_DISPATCH,
|
||||
|
|
@ -206,8 +193,6 @@ static inline void mga_dma_quiescent(drm_device_t *dev)
|
|||
}
|
||||
for (i = 0 ; i < 2000 ; i++) mga_delay();
|
||||
}
|
||||
DRM_DEBUG("status[1] : %x last_sync_tag : %x\n", status[1],
|
||||
dev_priv->last_sync_tag);
|
||||
sarea_priv->dirty |= MGA_DMA_FLUSH;
|
||||
|
||||
out_status:
|
||||
|
|
@ -215,42 +200,18 @@ out_status:
|
|||
out_nolock:
|
||||
}
|
||||
|
||||
#define FREELIST_INITIAL (MGA_DMA_BUF_NR * 2)
|
||||
#define FREELIST_COMPARE(age) ((age >> 2))
|
||||
|
||||
unsigned int mga_create_sync_tag(drm_device_t *dev)
|
||||
static void mga_reset_freelist(drm_device_t *dev)
|
||||
{
|
||||
drm_mga_private_t *dev_priv =
|
||||
(drm_mga_private_t *) dev->dev_private;
|
||||
unsigned int temp;
|
||||
drm_buf_t *buf;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_buf_t *buf;
|
||||
drm_mga_buf_priv_t *buf_priv;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
int i;
|
||||
|
||||
dev_priv->sync_tag++;
|
||||
|
||||
if(dev_priv->sync_tag < FREELIST_INITIAL) {
|
||||
dev_priv->sync_tag = FREELIST_INITIAL;
|
||||
}
|
||||
if(dev_priv->sync_tag > 0x3fffffff) {
|
||||
mga_flush_queue(dev);
|
||||
mga_dma_quiescent(dev);
|
||||
|
||||
for (i = 0; i < dma->buf_count; i++) {
|
||||
buf = dma->buflist[ i ];
|
||||
buf_priv = buf->dev_private;
|
||||
buf_priv->my_freelist->age = MGA_BUF_FREE;
|
||||
}
|
||||
|
||||
dev_priv->sync_tag = FREELIST_INITIAL;
|
||||
}
|
||||
temp = dev_priv->sync_tag << 2;
|
||||
int i;
|
||||
|
||||
dev_priv->sarea_priv->last_enqueue = temp;
|
||||
|
||||
DRM_DEBUG("sync_tag : %x\n", temp);
|
||||
return temp;
|
||||
for (i = 0; i < dma->buf_count; i++) {
|
||||
buf = dma->buflist[ i ];
|
||||
buf_priv = buf->dev_private;
|
||||
buf_priv->my_freelist->age = MGA_BUF_FREE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Least recently used :
|
||||
|
|
@ -259,23 +220,52 @@ unsigned int mga_create_sync_tag(drm_device_t *dev)
|
|||
|
||||
drm_buf_t *mga_freelist_get(drm_device_t *dev)
|
||||
{
|
||||
DECLARE_WAITQUEUE(entry, current);
|
||||
drm_mga_private_t *dev_priv =
|
||||
(drm_mga_private_t *) dev->dev_private;
|
||||
__volatile__ unsigned int *status =
|
||||
(__volatile__ unsigned int *)dev_priv->status_page;
|
||||
drm_mga_freelist_t *prev;
|
||||
drm_mga_freelist_t *next;
|
||||
static int failed = 0;
|
||||
|
||||
DRM_DEBUG("%s : tail->age : %d last_prim_age : %d\n", __FUNCTION__,
|
||||
dev_priv->tail->age, dev_priv->last_prim_age);
|
||||
|
||||
if((dev_priv->tail->age >> 2) <= FREELIST_COMPARE(status[1])) {
|
||||
if(failed >= 1000 && dev_priv->tail->age >= dev_priv->last_prim_age) {
|
||||
DRM_DEBUG("I'm waiting on the freelist!!! %d\n",
|
||||
dev_priv->last_prim_age);
|
||||
set_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status);
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
add_wait_queue(&dev_priv->buf_queue, &entry);
|
||||
for (;;) {
|
||||
mga_dma_schedule(dev, 0);
|
||||
if(!test_bit(MGA_IN_GETBUF,
|
||||
&dev_priv->dispatch_status))
|
||||
break;
|
||||
atomic_inc(&dev->total_sleeps);
|
||||
schedule();
|
||||
if (signal_pending(current)) {
|
||||
clear_bit(MGA_IN_GETBUF,
|
||||
&dev_priv->dispatch_status);
|
||||
goto failed_getbuf;
|
||||
}
|
||||
}
|
||||
current->state = TASK_RUNNING;
|
||||
remove_wait_queue(&dev_priv->buf_queue, &entry);
|
||||
}
|
||||
|
||||
if(dev_priv->tail->age < dev_priv->last_prim_age) {
|
||||
prev = dev_priv->tail->prev;
|
||||
next = dev_priv->tail;
|
||||
prev->next = NULL;
|
||||
next->prev = next->next = NULL;
|
||||
dev_priv->tail = prev;
|
||||
next->age = MGA_BUF_USED;
|
||||
failed = 0;
|
||||
return next->buf;
|
||||
}
|
||||
}
|
||||
|
||||
failed_getbuf:
|
||||
failed++;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -288,6 +278,8 @@ int mga_freelist_put(drm_device_t *dev, drm_buf_t *buf)
|
|||
drm_mga_freelist_t *head;
|
||||
drm_mga_freelist_t *next;
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
if(buf_priv->my_freelist->age == MGA_BUF_USED) {
|
||||
/* Discarded buffer, put it on the tail */
|
||||
next = buf_priv->my_freelist;
|
||||
|
|
@ -314,34 +306,6 @@ int mga_freelist_put(drm_device_t *dev, drm_buf_t *buf)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void mga_print_all_primary(drm_device_t *dev)
|
||||
{
|
||||
#if 0
|
||||
drm_mga_private_t *dev_priv = dev->dev_private;
|
||||
drm_mga_prim_buf_t *prim;
|
||||
int i;
|
||||
|
||||
DRM_DEBUG("Full list of primarys\n");
|
||||
for(i = 0; i < MGA_NUM_PRIM_BUFS; i++) {
|
||||
prim = dev_priv->prim_bufs[i];
|
||||
DRM_DEBUG("index : %d num_dwords : %d "
|
||||
"max_dwords : %d phy_head : %x\n",
|
||||
prim->idx, prim->num_dwords,
|
||||
prim->max_dwords, prim->phys_head);
|
||||
DRM_DEBUG("sec_used : %d swap_pending : %x "
|
||||
"in_use : %x force_fire : %d\n",
|
||||
prim->sec_used, prim->swap_pending,
|
||||
prim->in_use, atomic_read(&prim->force_fire));
|
||||
DRM_DEBUG("needs_overflow : %d\n",
|
||||
atomic_read(&prim->needs_overflow));
|
||||
}
|
||||
|
||||
DRM_DEBUG("current_idx : %d, next_idx : %d, last_idx : %d\n",
|
||||
dev_priv->next_prim->idx, dev_priv->last_prim->idx,
|
||||
dev_priv->current_prim->idx);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int mga_init_primary_bufs(drm_device_t *dev, drm_mga_init_t *init)
|
||||
{
|
||||
drm_mga_private_t *dev_priv = dev->dev_private;
|
||||
|
|
@ -349,10 +313,9 @@ static int mga_init_primary_bufs(drm_device_t *dev, drm_mga_init_t *init)
|
|||
int i, temp, size_of_buf;
|
||||
int offset = init->reserved_map_agpstart;
|
||||
|
||||
DRM_DEBUG("mga_init_primary_bufs\n");
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
dev_priv->primary_size = ((init->primary_size + PAGE_SIZE - 1) /
|
||||
PAGE_SIZE) * PAGE_SIZE;
|
||||
DRM_DEBUG("primary_size\n");
|
||||
size_of_buf = dev_priv->primary_size / MGA_NUM_PRIM_BUFS;
|
||||
dev_priv->warp_ucode_size = init->warp_ucode_size;
|
||||
dev_priv->prim_bufs = drm_alloc(sizeof(drm_mga_prim_buf_t *) *
|
||||
|
|
@ -362,18 +325,12 @@ static int mga_init_primary_bufs(drm_device_t *dev, drm_mga_init_t *init)
|
|||
DRM_ERROR("Unable to allocate memory for prim_buf\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
DRM_DEBUG("memset\n");
|
||||
memset(dev_priv->prim_bufs,
|
||||
0, sizeof(drm_mga_prim_buf_t *) * (MGA_NUM_PRIM_BUFS + 1));
|
||||
|
||||
temp = init->warp_ucode_size + dev_priv->primary_size;
|
||||
temp = ((temp + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE;
|
||||
|
||||
DRM_DEBUG("temp : %x\n", temp);
|
||||
DRM_DEBUG("dev->agp->base: %lx\n", dev->agp->base);
|
||||
DRM_DEBUG("init->reserved_map_agpstart: %x\n",
|
||||
init->reserved_map_agpstart);
|
||||
DRM_DEBUG("ioremap\n");
|
||||
dev_priv->ioremap = drm_ioremap(dev->agp->base + offset,
|
||||
temp);
|
||||
if(dev_priv->ioremap == NULL) {
|
||||
|
|
@ -383,11 +340,9 @@ static int mga_init_primary_bufs(drm_device_t *dev, drm_mga_init_t *init)
|
|||
init_waitqueue_head(&dev_priv->wait_queue);
|
||||
|
||||
for(i = 0; i < MGA_NUM_PRIM_BUFS; i++) {
|
||||
DRM_DEBUG("For loop\n");
|
||||
prim_buffer = drm_alloc(sizeof(drm_mga_prim_buf_t),
|
||||
DRM_MEM_DRIVER);
|
||||
if(prim_buffer == NULL) return -ENOMEM;
|
||||
DRM_DEBUG("memset\n");
|
||||
memset(prim_buffer, 0, sizeof(drm_mga_prim_buf_t));
|
||||
prim_buffer->phys_head = offset + dev->agp->base;
|
||||
prim_buffer->current_dma_ptr =
|
||||
|
|
@ -400,17 +355,18 @@ static int mga_init_primary_bufs(drm_device_t *dev, drm_mga_init_t *init)
|
|||
prim_buffer->max_dwords -= 5; /* Leave room for the softrap */
|
||||
prim_buffer->sec_used = 0;
|
||||
prim_buffer->idx = i;
|
||||
prim_buffer->prim_age = i + 1;
|
||||
offset = offset + size_of_buf;
|
||||
dev_priv->prim_bufs[i] = prim_buffer;
|
||||
DRM_DEBUG("Looping\n");
|
||||
}
|
||||
dev_priv->current_prim_idx = 0;
|
||||
dev_priv->next_prim =
|
||||
dev_priv->last_prim =
|
||||
dev_priv->current_prim =
|
||||
dev_priv->prim_bufs[0];
|
||||
dev_priv->next_prim_age = 2;
|
||||
dev_priv->last_prim_age = 1;
|
||||
set_bit(MGA_BUF_IN_USE, &dev_priv->current_prim->buffer_status);
|
||||
DRM_DEBUG("init done\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -424,9 +380,8 @@ void mga_fire_primary(drm_device_t *dev, drm_mga_prim_buf_t *prim)
|
|||
int i;
|
||||
int next_idx;
|
||||
PRIMLOCALS;
|
||||
|
||||
DRM_DEBUG("mga_fire_primary\n");
|
||||
dev_priv->last_sync_tag = mga_create_sync_tag(dev);
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
dev_priv->last_prim = prim;
|
||||
|
||||
/* We never check for overflow, b/c there is always room */
|
||||
|
|
@ -437,7 +392,7 @@ void mga_fire_primary(drm_device_t *dev, drm_mga_prim_buf_t *prim)
|
|||
}
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag);
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_SOFTRAP, 0);
|
||||
PRIMFINISH(prim);
|
||||
|
||||
|
|
@ -472,13 +427,13 @@ void mga_fire_primary(drm_device_t *dev, drm_mga_prim_buf_t *prim)
|
|||
for (i = 0 ; i < 4096 ; i++) mga_delay();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mga_flush_write_combine();
|
||||
atomic_inc(&dev_priv->pending_bufs);
|
||||
atomic_inc(&dma->total_lost);
|
||||
MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL);
|
||||
MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp);
|
||||
prim->num_dwords = 0;
|
||||
sarea_priv->last_enqueue = prim->prim_age;
|
||||
|
||||
next_idx = prim->idx + 1;
|
||||
if(next_idx >= MGA_NUM_PRIM_BUFS)
|
||||
|
|
@ -494,7 +449,6 @@ void mga_fire_primary(drm_device_t *dev, drm_mga_prim_buf_t *prim)
|
|||
wake_up_interruptible(&dev_priv->wait_queue);
|
||||
clear_bit(MGA_BUF_SWAP_PENDING, &prim->buffer_status);
|
||||
clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
|
||||
atomic_dec(&dev_priv->pending_bufs);
|
||||
}
|
||||
|
||||
int mga_advance_primary(drm_device_t *dev)
|
||||
|
|
@ -509,6 +463,7 @@ int mga_advance_primary(drm_device_t *dev)
|
|||
/* This needs to reset the primary buffer if available,
|
||||
* we should collect stats on how many times it bites
|
||||
* it's tail */
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
next_prim_idx = dev_priv->current_prim_idx + 1;
|
||||
if(next_prim_idx >= MGA_NUM_PRIM_BUFS)
|
||||
|
|
@ -520,18 +475,16 @@ int mga_advance_primary(drm_device_t *dev)
|
|||
|
||||
if(test_and_set_bit(MGA_BUF_IN_USE, &prim_buffer->buffer_status)) {
|
||||
add_wait_queue(&dev_priv->wait_queue, &entry);
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
|
||||
for (;;) {
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
mga_dma_schedule(dev, 0);
|
||||
if(!test_and_set_bit(MGA_BUF_IN_USE,
|
||||
&prim_buffer->buffer_status))
|
||||
break;
|
||||
atomic_inc(&dev->total_sleeps);
|
||||
atomic_inc(&dma->total_missed_sched);
|
||||
mga_print_all_primary(dev);
|
||||
DRM_DEBUG("Schedule in advance\n");
|
||||
/* Three second delay */
|
||||
schedule_timeout(HZ*3);
|
||||
schedule();
|
||||
if (signal_pending(current)) {
|
||||
ret = -ERESTARTSYS;
|
||||
break;
|
||||
|
|
@ -547,6 +500,14 @@ int mga_advance_primary(drm_device_t *dev)
|
|||
prim_buffer->current_dma_ptr = prim_buffer->head;
|
||||
prim_buffer->num_dwords = 0;
|
||||
prim_buffer->sec_used = 0;
|
||||
prim_buffer->prim_age = dev_priv->next_prim_age++;
|
||||
if(prim_buffer->prim_age == 0 || prim_buffer->prim_age == 0xffffffff) {
|
||||
mga_flush_queue(dev);
|
||||
mga_dma_quiescent(dev);
|
||||
mga_reset_freelist(dev);
|
||||
prim_buffer->prim_age = (dev_priv->next_prim_age += 2);
|
||||
}
|
||||
|
||||
/* Reset all buffer status stuff */
|
||||
clear_bit(MGA_BUF_NEEDS_OVERFLOW, &prim_buffer->buffer_status);
|
||||
clear_bit(MGA_BUF_FORCE_FIRE, &prim_buffer->buffer_status);
|
||||
|
|
@ -554,8 +515,6 @@ int mga_advance_primary(drm_device_t *dev)
|
|||
|
||||
dev_priv->current_prim = prim_buffer;
|
||||
dev_priv->current_prim_idx = next_prim_idx;
|
||||
DRM_DEBUG("Primarys at advance\n");
|
||||
mga_print_all_primary(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -564,12 +523,20 @@ static inline int mga_decide_to_fire(drm_device_t *dev)
|
|||
{
|
||||
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
if(test_bit(MGA_BUF_FORCE_FIRE, &dev_priv->next_prim->buffer_status)) {
|
||||
atomic_inc(&dma->total_prio);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status) &&
|
||||
dev_priv->next_prim->num_dwords) {
|
||||
atomic_inc(&dma->total_prio);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) &&
|
||||
dev_priv->next_prim->num_dwords) {
|
||||
atomic_inc(&dma->total_prio);
|
||||
|
|
@ -612,10 +579,11 @@ int mga_dma_schedule(drm_device_t *dev, int locked)
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
DRM_DEBUG("mga_dma_schedule\n");
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
if(test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) ||
|
||||
test_bit(MGA_IN_WAIT, &dev_priv->dispatch_status)) {
|
||||
test_bit(MGA_IN_WAIT, &dev_priv->dispatch_status) ||
|
||||
test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status)) {
|
||||
locked = 1;
|
||||
}
|
||||
|
||||
|
|
@ -623,6 +591,7 @@ int mga_dma_schedule(drm_device_t *dev, int locked)
|
|||
!drm_lock_take(&dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT)) {
|
||||
atomic_inc(&dma->total_missed_lock);
|
||||
clear_bit(0, &dev->dma_flag);
|
||||
DRM_DEBUG("Not locked\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
DRM_DEBUG("I'm locked\n");
|
||||
|
|
@ -630,7 +599,6 @@ int mga_dma_schedule(drm_device_t *dev, int locked)
|
|||
if(!test_and_set_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status)) {
|
||||
/* Fire dma buffer */
|
||||
if(mga_decide_to_fire(dev)) {
|
||||
DRM_DEBUG("mga_fire_primary\n");
|
||||
DRM_DEBUG("idx :%d\n", dev_priv->next_prim->idx);
|
||||
clear_bit(MGA_BUF_FORCE_FIRE,
|
||||
&dev_priv->next_prim->buffer_status);
|
||||
|
|
@ -654,16 +622,26 @@ int mga_dma_schedule(drm_device_t *dev, int locked)
|
|||
}
|
||||
}
|
||||
|
||||
clear_bit(0, &dev->dma_flag);
|
||||
if(test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) &&
|
||||
dev_priv->next_prim->num_dwords == 0) {
|
||||
/* Everything is on the hardware */
|
||||
DRM_DEBUG("Primarys at Flush\n");
|
||||
mga_print_all_primary(dev);
|
||||
dev_priv->next_prim->num_dwords == 0 &&
|
||||
atomic_read(&dev_priv->pending_bufs) == 0) {
|
||||
/* Everything has been processed by the hardware */
|
||||
clear_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status);
|
||||
wake_up_interruptible(&dev_priv->flush_queue);
|
||||
}
|
||||
|
||||
if(test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status) &&
|
||||
dev_priv->tail->age < dev_priv->last_prim_age) {
|
||||
clear_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status);
|
||||
DRM_DEBUG("Waking up buf queue\n");
|
||||
wake_up_interruptible(&dev_priv->buf_queue);
|
||||
} else if (test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status)) {
|
||||
DRM_DEBUG("Not waking buf_queue on %d %d\n",
|
||||
atomic_read(&dev->total_irq),
|
||||
dev_priv->last_prim_age);
|
||||
}
|
||||
|
||||
clear_bit(0, &dev->dma_flag);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -672,32 +650,35 @@ static void mga_dma_service(int irq, void *device, struct pt_regs *regs)
|
|||
drm_device_t *dev = (drm_device_t *)device;
|
||||
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
|
||||
drm_mga_prim_buf_t *last_prim_buffer;
|
||||
__volatile__ unsigned int *status =
|
||||
(__volatile__ unsigned int *)dev_priv->status_page;
|
||||
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
atomic_inc(&dev->total_irq);
|
||||
if((MGA_READ(MGAREG_STATUS) & 0x00000001) != 0x00000001) return;
|
||||
MGA_WRITE(MGAREG_ICLEAR, 0x00000001);
|
||||
last_prim_buffer = dev_priv->last_prim;
|
||||
last_prim_buffer->num_dwords = 0;
|
||||
last_prim_buffer->sec_used = 0;
|
||||
dev_priv->sarea_priv->last_dispatch =
|
||||
dev_priv->last_prim_age = last_prim_buffer->prim_age;
|
||||
clear_bit(MGA_BUF_IN_USE, &last_prim_buffer->buffer_status);
|
||||
wake_up_interruptible(&dev_priv->wait_queue);
|
||||
clear_bit(MGA_BUF_SWAP_PENDING, &last_prim_buffer->buffer_status);
|
||||
clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
|
||||
atomic_dec(&dev_priv->pending_bufs);
|
||||
dev_priv->sarea_priv->last_dispatch = status[1];
|
||||
queue_task(&dev->tq, &tq_immediate);
|
||||
mark_bh(IMMEDIATE_BH);
|
||||
}
|
||||
|
||||
static void mga_dma_task_queue(void *device)
|
||||
{
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
mga_dma_schedule((drm_device_t *)device, 0);
|
||||
}
|
||||
|
||||
int mga_dma_cleanup(drm_device_t *dev)
|
||||
{
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
if(dev->dev_private) {
|
||||
drm_mga_private_t *dev_priv =
|
||||
(drm_mga_private_t *) dev->dev_private;
|
||||
|
|
@ -746,12 +727,12 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) {
|
|||
drm_map_t *sarea_map = NULL;
|
||||
int i;
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER);
|
||||
if(dev_priv == NULL) return -ENOMEM;
|
||||
dev->dev_private = (void *) dev_priv;
|
||||
|
||||
DRM_DEBUG("dev_private\n");
|
||||
|
||||
memset(dev_priv, 0, sizeof(drm_mga_private_t));
|
||||
|
||||
if((init->reserved_map_idx >= dev->map_count) ||
|
||||
|
|
@ -767,7 +748,6 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) {
|
|||
dev_priv->sarea_priv = (drm_mga_sarea_t *)
|
||||
((u8 *)sarea_map->handle +
|
||||
init->sarea_priv_offset);
|
||||
DRM_DEBUG("sarea_priv\n");
|
||||
|
||||
/* Scale primary size to the next page */
|
||||
dev_priv->chipset = init->chipset;
|
||||
|
|
@ -782,6 +762,7 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) {
|
|||
|
||||
dev_priv->mAccess = init->mAccess;
|
||||
init_waitqueue_head(&dev_priv->flush_queue);
|
||||
init_waitqueue_head(&dev_priv->buf_queue);
|
||||
dev_priv->WarpPipe = -1;
|
||||
|
||||
DRM_DEBUG("chipset: %d ucode_size: %d backOffset: %x depthOffset: %x\n",
|
||||
|
|
@ -801,20 +782,17 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) {
|
|||
dev_priv->WarpIndex[i].phys_addr,
|
||||
dev_priv->WarpIndex[i].size);
|
||||
|
||||
DRM_DEBUG("Doing init prim buffers\n");
|
||||
if(mga_init_primary_bufs(dev, init) != 0) {
|
||||
DRM_ERROR("Can not initialize primary buffers\n");
|
||||
mga_dma_cleanup(dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
DRM_DEBUG("Done with init prim buffers\n");
|
||||
dev_priv->real_status_page = mga_alloc_page(dev);
|
||||
if(dev_priv->real_status_page == 0UL) {
|
||||
mga_dma_cleanup(dev);
|
||||
DRM_ERROR("Can not allocate status page\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
DRM_DEBUG("Status page at %lx\n", dev_priv->real_status_page);
|
||||
|
||||
dev_priv->status_page =
|
||||
ioremap_nocache(virt_to_bus((void *)dev_priv->real_status_page),
|
||||
|
|
@ -826,31 +804,23 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) {
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
DRM_DEBUG("Status page remapped to %p\n", dev_priv->status_page);
|
||||
/* Write status page when secend or softrap occurs */
|
||||
MGA_WRITE(MGAREG_PRIMPTR,
|
||||
virt_to_bus((void *)dev_priv->real_status_page) | 0x00000003);
|
||||
|
||||
DRM_DEBUG("dma initialization\n");
|
||||
|
||||
/* Private is now filled in, initialize the hardware */
|
||||
{
|
||||
__volatile__ unsigned int *status =
|
||||
(unsigned int *)dev_priv->status_page;
|
||||
PRIMLOCALS;
|
||||
PRIMGETPTR( dev_priv );
|
||||
|
||||
dev_priv->last_sync_tag = mga_create_sync_tag(dev);
|
||||
|
||||
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_DWGSYNC, dev_priv->last_sync_tag);
|
||||
PRIMOUTREG(MGAREG_DWGSYNC, 0x0100);
|
||||
PRIMOUTREG(MGAREG_SOFTRAP, 0);
|
||||
/* Poll for the first buffer to insure that
|
||||
* the status register will be correct
|
||||
*/
|
||||
DRM_DEBUG("phys_head : %lx\n", (unsigned long)phys_head);
|
||||
status[1] = 0;
|
||||
|
||||
mga_flush_write_combine();
|
||||
MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL);
|
||||
|
|
@ -858,9 +828,7 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) {
|
|||
MGA_WRITE(MGAREG_PRIMEND, ((phys_head + num_dwords * 4) |
|
||||
PDEA_pagpxfer_enable));
|
||||
|
||||
while(MGA_READ(MGAREG_DWGSYNC) != dev_priv->last_sync_tag) ;
|
||||
DRM_DEBUG("status[0] after initialization : %x\n", status[0]);
|
||||
DRM_DEBUG("status[1] after initialization : %x\n", status[1]);
|
||||
while(MGA_READ(MGAREG_DWGSYNC) != 0x0100) ;
|
||||
}
|
||||
|
||||
if(mga_freelist_init(dev) != 0) {
|
||||
|
|
@ -868,7 +836,6 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) {
|
|||
mga_dma_cleanup(dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
DRM_DEBUG("dma init was successful\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -879,6 +846,8 @@ int mga_dma_init(struct inode *inode, struct file *filp,
|
|||
drm_device_t *dev = priv->dev;
|
||||
drm_mga_init_t init;
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
copy_from_user_ret(&init, (drm_mga_init_t *)arg, sizeof(init), -EFAULT);
|
||||
|
||||
switch(init.func) {
|
||||
|
|
@ -962,7 +931,9 @@ int mga_control(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
drm_control_t ctl;
|
||||
|
||||
copy_from_user_ret(&ctl, (drm_control_t *)arg, sizeof(ctl), -EFAULT);
|
||||
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
switch (ctl.func) {
|
||||
case DRM_INST_HANDLER:
|
||||
return mga_irq_install(dev, ctl.irq);
|
||||
|
|
@ -979,6 +950,8 @@ static int mga_flush_queue(drm_device_t *dev)
|
|||
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
|
||||
int ret = 0;
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
if(dev_priv == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -993,8 +966,7 @@ static int mga_flush_queue(drm_device_t *dev)
|
|||
&dev_priv->dispatch_status))
|
||||
break;
|
||||
atomic_inc(&dev->total_sleeps);
|
||||
DRM_DEBUG("Schedule in flush_queue\n");
|
||||
schedule_timeout(HZ*3);
|
||||
schedule();
|
||||
if (signal_pending(current)) {
|
||||
ret = -EINTR; /* Can't restart */
|
||||
clear_bit(MGA_IN_FLUSH,
|
||||
|
|
@ -1018,6 +990,7 @@ void mga_reclaim_buffers(drm_device_t *dev, pid_t pid)
|
|||
if(dev->dev_private == NULL) return;
|
||||
if(dma->buflist == NULL) return;
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
mga_flush_queue(dev);
|
||||
|
||||
for (i = 0; i < dma->buf_count; i++) {
|
||||
|
|
@ -1043,6 +1016,7 @@ int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
int ret = 0;
|
||||
drm_lock_t lock;
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT);
|
||||
|
||||
if (lock.context == DRM_KERNEL_CONTEXT) {
|
||||
|
|
@ -1081,7 +1055,6 @@ int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
/* Contention */
|
||||
atomic_inc(&dev->total_sleeps);
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
DRM_DEBUG("Calling lock schedule\n");
|
||||
schedule();
|
||||
if (signal_pending(current)) {
|
||||
ret = -ERESTARTSYS;
|
||||
|
|
@ -1111,11 +1084,8 @@ int mga_flush_ioctl(struct inode *inode, struct file *filp,
|
|||
drm_device_t *dev = priv->dev;
|
||||
drm_lock_t lock;
|
||||
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
|
||||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
__volatile__ unsigned int *status =
|
||||
(__volatile__ unsigned int *)dev_priv->status_page;
|
||||
int i;
|
||||
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT);
|
||||
|
||||
if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
|
||||
|
|
|
|||
|
|
@ -160,19 +160,19 @@ typedef struct drm_mga_init {
|
|||
int sarea_priv_offset;
|
||||
int primary_size;
|
||||
int warp_ucode_size;
|
||||
int frontOffset;
|
||||
int backOffset;
|
||||
int depthOffset;
|
||||
int textureOffset;
|
||||
int textureSize;
|
||||
int agpTextureOffset;
|
||||
int agpTextureSize;
|
||||
int cpp;
|
||||
int stride;
|
||||
unsigned int frontOffset;
|
||||
unsigned int backOffset;
|
||||
unsigned int depthOffset;
|
||||
unsigned int textureOffset;
|
||||
unsigned int textureSize;
|
||||
unsigned int agpTextureOffset;
|
||||
unsigned int agpTextureSize;
|
||||
unsigned int cpp;
|
||||
unsigned int stride;
|
||||
int sgram;
|
||||
int chipset;
|
||||
drm_mga_warp_index_t WarpIndex[MGA_MAX_WARP_PIPES];
|
||||
int mAccess;
|
||||
unsigned int mAccess;
|
||||
} drm_mga_init_t;
|
||||
|
||||
/* Warning: if you change the sarea structure, you must change the Xserver
|
||||
|
|
@ -181,7 +181,7 @@ typedef struct drm_mga_init {
|
|||
typedef struct _drm_mga_tex_region {
|
||||
unsigned char next, prev;
|
||||
unsigned char in_use;
|
||||
int age;
|
||||
unsigned int age;
|
||||
} drm_mga_tex_region_t;
|
||||
|
||||
typedef struct _drm_mga_sarea {
|
||||
|
|
@ -220,9 +220,9 @@ typedef struct _drm_mga_sarea {
|
|||
|
||||
/* Counters for aging textures and for client-side throttling.
|
||||
*/
|
||||
int last_enqueue; /* last time a buffer was enqueued */
|
||||
int last_dispatch; /* age of the most recently dispatched buffer */
|
||||
int last_quiescent; /* */
|
||||
unsigned int last_enqueue; /* last time a buffer was enqueued */
|
||||
unsigned int last_dispatch; /* age of the most recently dispatched buffer */
|
||||
unsigned int last_quiescent; /* */
|
||||
|
||||
|
||||
/* LRU lists for texture memory in agp space and on the card
|
||||
|
|
@ -238,9 +238,9 @@ typedef struct _drm_mga_sarea {
|
|||
/* Device specific ioctls:
|
||||
*/
|
||||
typedef struct _drm_mga_clear {
|
||||
int clear_color;
|
||||
int clear_depth;
|
||||
int flags;
|
||||
unsigned int clear_color;
|
||||
unsigned int clear_depth;
|
||||
unsigned int flags;
|
||||
} drm_mga_clear_t;
|
||||
|
||||
typedef struct _drm_mga_swap {
|
||||
|
|
@ -261,8 +261,8 @@ typedef struct _drm_mga_vertex {
|
|||
|
||||
typedef struct _drm_mga_indices {
|
||||
int idx; /* buffer to queue */
|
||||
int start;
|
||||
int end;
|
||||
unsigned int start;
|
||||
unsigned int end;
|
||||
int discard; /* client finished with buffer? */
|
||||
} drm_mga_indices_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ typedef struct {
|
|||
u32 *current_dma_ptr;
|
||||
u32 *head;
|
||||
u32 phys_head;
|
||||
unsigned int prim_age;
|
||||
int sec_used;
|
||||
int idx;
|
||||
} drm_mga_prim_buf_t;
|
||||
|
|
@ -58,29 +59,30 @@ typedef struct _drm_mga_freelist {
|
|||
#define MGA_IN_DISPATCH 0
|
||||
#define MGA_IN_FLUSH 1
|
||||
#define MGA_IN_WAIT 2
|
||||
#define MGA_IN_GETBUF 3
|
||||
|
||||
typedef struct _drm_mga_private {
|
||||
u32 dispatch_status;
|
||||
unsigned int next_prim_age;
|
||||
__volatile__ unsigned int last_prim_age;
|
||||
int reserved_map_idx;
|
||||
int buffer_map_idx;
|
||||
drm_mga_sarea_t *sarea_priv;
|
||||
int primary_size;
|
||||
int warp_ucode_size;
|
||||
int chipset;
|
||||
int frontOffset;
|
||||
int backOffset;
|
||||
int depthOffset;
|
||||
int textureOffset;
|
||||
int textureSize;
|
||||
unsigned int frontOffset;
|
||||
unsigned int backOffset;
|
||||
unsigned int depthOffset;
|
||||
unsigned int textureOffset;
|
||||
unsigned int textureSize;
|
||||
int cpp;
|
||||
int stride;
|
||||
unsigned int stride;
|
||||
int sgram;
|
||||
int use_agp;
|
||||
drm_mga_warp_index_t WarpIndex[MGA_MAX_G400_PIPES];
|
||||
unsigned int WarpPipe;
|
||||
atomic_t pending_bufs;
|
||||
unsigned int last_sync_tag;
|
||||
unsigned int sync_tag;
|
||||
void *status_page;
|
||||
unsigned long real_status_page;
|
||||
u8 *ioremap;
|
||||
|
|
@ -93,7 +95,7 @@ typedef struct _drm_mga_private {
|
|||
drm_mga_freelist_t *tail;
|
||||
wait_queue_head_t flush_queue; /* Processes waiting until flush */
|
||||
wait_queue_head_t wait_queue; /* Processes waiting until interrupt */
|
||||
|
||||
wait_queue_head_t buf_queue; /* Processes waiting for a free buf */
|
||||
/* Some validated register values:
|
||||
*/
|
||||
u32 mAccess;
|
||||
|
|
@ -128,7 +130,7 @@ extern int mga_dma_init(struct inode *inode, struct file *filp,
|
|||
extern int mga_dma_cleanup(drm_device_t *dev);
|
||||
extern int mga_flush_ioctl(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
|
||||
extern void mga_flush_write_combine(void);
|
||||
extern unsigned int mga_create_sync_tag(drm_device_t *dev);
|
||||
extern drm_buf_t *mga_freelist_get(drm_device_t *dev);
|
||||
extern int mga_freelist_put(drm_device_t *dev, drm_buf_t *buf);
|
||||
|
|
@ -190,6 +192,7 @@ typedef enum {
|
|||
typedef struct {
|
||||
drm_mga_freelist_t *my_freelist;
|
||||
int discard;
|
||||
int dispatched;
|
||||
} drm_mga_buf_priv_t;
|
||||
|
||||
#define DWGREG0 0x1c00
|
||||
|
|
@ -211,16 +214,16 @@ typedef struct {
|
|||
#define PRIM_OVERFLOW(dev, dev_priv, length) do { \
|
||||
drm_mga_prim_buf_t *tmp_buf = \
|
||||
dev_priv->prim_bufs[dev_priv->current_prim_idx]; \
|
||||
if( tmp_buf->max_dwords - tmp_buf->num_dwords < length || \
|
||||
if( test_bit(MGA_BUF_NEEDS_OVERFLOW, \
|
||||
&tmp_buf->buffer_status)) { \
|
||||
mga_advance_primary(dev); \
|
||||
mga_dma_schedule(dev, 1); \
|
||||
} else if( tmp_buf->max_dwords - tmp_buf->num_dwords < length ||\
|
||||
tmp_buf->sec_used > MGA_DMA_BUF_NR/2) { \
|
||||
set_bit(MGA_BUF_FORCE_FIRE, &tmp_buf->buffer_status); \
|
||||
mga_advance_primary(dev); \
|
||||
mga_dma_schedule(dev, 1); \
|
||||
} else if( test_bit(MGA_BUF_NEEDS_OVERFLOW, \
|
||||
&tmp_buf->buffer_status)) { \
|
||||
mga_advance_primary(dev); \
|
||||
mga_dma_schedule(dev, 1); \
|
||||
} \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define PRIMGETPTR(dev_priv) do { \
|
||||
|
|
@ -271,6 +274,13 @@ drm_mga_prim_buf_t *tmp_buf = \
|
|||
tmp_buf->sec_used++; \
|
||||
} while (0)
|
||||
|
||||
#define AGEBUF(dev_priv, buf_priv) do { \
|
||||
drm_mga_prim_buf_t *tmp_buf = \
|
||||
dev_priv->prim_bufs[dev_priv->current_prim_idx]; \
|
||||
buf_priv->my_freelist->age = tmp_buf->prim_age; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define PRIMOUTREG(reg, val) do { \
|
||||
tempIndex[outcount]=ADRINDEX(reg); \
|
||||
dma_ptr[1+outcount] = val; \
|
||||
|
|
|
|||
|
|
@ -41,14 +41,15 @@ static void mgaEmitClipRect( drm_mga_private_t *dev_priv,
|
|||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
unsigned int *regs = sarea_priv->ContextState;
|
||||
PRIMLOCALS;
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
/* This takes 10 dwords */
|
||||
PRIMGETPTR( dev_priv );
|
||||
|
||||
/* Force reset of dwgctl (eliminates clip disable) */
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0 );
|
||||
PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag - 1 );
|
||||
PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag - 1 );
|
||||
PRIMOUTREG( MGAREG_DWGSYNC, 0 );
|
||||
PRIMOUTREG( MGAREG_DWGSYNC, 0 );
|
||||
PRIMOUTREG( MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL] );
|
||||
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0 );
|
||||
|
|
@ -64,6 +65,7 @@ static void mgaEmitContext(drm_mga_private_t *dev_priv )
|
|||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
unsigned int *regs = sarea_priv->ContextState;
|
||||
PRIMLOCALS;
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
/* This takes a max of 15 dwords */
|
||||
PRIMGETPTR( dev_priv );
|
||||
|
|
@ -98,6 +100,7 @@ static void mgaG200EmitTex( drm_mga_private_t *dev_priv )
|
|||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
unsigned int *regs = sarea_priv->TexState[0];
|
||||
PRIMLOCALS;
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
PRIMGETPTR( dev_priv );
|
||||
|
||||
|
|
@ -132,6 +135,7 @@ static void mgaG400EmitTex0( drm_mga_private_t *dev_priv )
|
|||
unsigned int *regs = sarea_priv->TexState[0];
|
||||
int multitex = sarea_priv->WarpPipe & MGA_T2;
|
||||
PRIMLOCALS;
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
PRIMGETPTR( dev_priv );
|
||||
|
||||
|
|
@ -179,6 +183,7 @@ static void mgaG400EmitTex1( drm_mga_private_t *dev_priv )
|
|||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
unsigned int *regs = sarea_priv->TexState[1];
|
||||
PRIMLOCALS;
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
PRIMGETPTR(dev_priv);
|
||||
|
||||
|
|
@ -217,6 +222,7 @@ static void mgaG400EmitPipe(drm_mga_private_t *dev_priv )
|
|||
unsigned int pipe = sarea_priv->WarpPipe;
|
||||
float fParam = 12800.0f;
|
||||
PRIMLOCALS;
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
PRIMGETPTR(dev_priv);
|
||||
|
||||
|
|
@ -255,7 +261,7 @@ static void mgaG400EmitPipe(drm_mga_private_t *dev_priv )
|
|||
PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
|
||||
PRIMOUTREG(MGAREG_WIADDR2, (__u32)(dev_priv->WarpIndex[pipe].phys_addr |
|
||||
PRIMOUTREG(MGAREG_WIADDR2, (u32)(dev_priv->WarpIndex[pipe].phys_addr |
|
||||
WIA_wmode_start | WIA_wagp_agp));
|
||||
PRIMADVANCE(dev_priv);
|
||||
}
|
||||
|
|
@ -265,6 +271,7 @@ static void mgaG200EmitPipe( drm_mga_private_t *dev_priv )
|
|||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
unsigned int pipe = sarea_priv->WarpPipe;
|
||||
PRIMLOCALS;
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
PRIMGETPTR(dev_priv);
|
||||
|
||||
|
|
@ -284,7 +291,7 @@ static void mgaG200EmitPipe( drm_mga_private_t *dev_priv )
|
|||
PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
|
||||
PRIMOUTREG(MGAREG_WIADDR, (__u32)(dev_priv->WarpIndex[pipe].phys_addr |
|
||||
PRIMOUTREG(MGAREG_WIADDR, (u32)(dev_priv->WarpIndex[pipe].phys_addr |
|
||||
WIA_wmode_start | WIA_wagp_agp));
|
||||
|
||||
PRIMADVANCE(dev_priv);
|
||||
|
|
@ -294,6 +301,7 @@ static void mgaEmitState( drm_mga_private_t *dev_priv )
|
|||
{
|
||||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
unsigned int dirty = sarea_priv->dirty;
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
if (dev_priv->chipset == MGA_CARD_TYPE_G400) {
|
||||
int multitex = sarea_priv->WarpPipe & MGA_T2;
|
||||
|
|
@ -343,6 +351,8 @@ static int mgaVerifyContext(drm_mga_private_t *dev_priv )
|
|||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
unsigned int *regs = sarea_priv->ContextState;
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
if (regs[MGA_CTXREG_DSTORG] != dev_priv->frontOffset &&
|
||||
regs[MGA_CTXREG_DSTORG] != dev_priv->backOffset) {
|
||||
DRM_DEBUG("BAD DSTORG: %x (front %x, back %x)\n\n",
|
||||
|
|
@ -362,6 +372,8 @@ static int mgaVerifyTex(drm_mga_private_t *dev_priv,
|
|||
{
|
||||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
if ((sarea_priv->TexState[unit][MGA_TEXREG_ORG] & 0x3) == 0x1) {
|
||||
DRM_DEBUG("BAD TEXREG_ORG: %x, unit %d\n",
|
||||
sarea_priv->TexState[unit][MGA_TEXREG_ORG],
|
||||
|
|
@ -379,6 +391,8 @@ static int mgaVerifyState( drm_mga_private_t *dev_priv )
|
|||
unsigned int dirty = sarea_priv->dirty;
|
||||
int rv = 0;
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
|
||||
sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
|
||||
|
||||
|
|
@ -409,6 +423,8 @@ static int mgaVerifyIload( drm_mga_private_t *dev_priv,
|
|||
unsigned long bus_address,
|
||||
unsigned int dstOrg, int length )
|
||||
{
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
if(dstOrg < dev_priv->textureOffset ||
|
||||
dstOrg + length >
|
||||
(dev_priv->textureOffset + dev_priv->textureSize)) {
|
||||
|
|
@ -432,14 +448,13 @@ static void mga_dma_dispatch_tex_blit( drm_device_t *dev,
|
|||
int use_agp = PDEA_pagpxfer_enable | 0x00000001;
|
||||
u16 y2;
|
||||
PRIMLOCALS;
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
y2 = length / 64;
|
||||
|
||||
PRIM_OVERFLOW(dev, dev_priv, 30);
|
||||
PRIMGETPTR( dev_priv );
|
||||
|
||||
dev_priv->last_sync_tag = mga_create_sync_tag(dev);
|
||||
|
||||
PRIMOUTREG( MGAREG_DSTORG, destOrg);
|
||||
PRIMOUTREG( MGAREG_MACCESS, 0x00000000);
|
||||
DRM_DEBUG("srcorg : %lx\n", bus_address | use_agp);
|
||||
|
|
@ -459,7 +474,7 @@ static void mga_dma_dispatch_tex_blit( drm_device_t *dev,
|
|||
PRIMOUTREG( MGAREG_SRCORG, 0);
|
||||
PRIMOUTREG( MGAREG_PITCH, dev_priv->stride / dev_priv->cpp);
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag);
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMADVANCE(dev_priv);
|
||||
}
|
||||
|
||||
|
|
@ -475,33 +490,33 @@ static void mga_dma_dispatch_vertex(drm_device_t *dev,
|
|||
int i = 0;
|
||||
int primary_needed;
|
||||
PRIMLOCALS;
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
DRM_DEBUG("dispatch vertex %d addr 0x%lx, "
|
||||
"length 0x%x nbox %d dirty %x\n",
|
||||
buf->idx, address, length,
|
||||
sarea_priv->nbox, sarea_priv->dirty);
|
||||
|
||||
|
||||
dev_priv->last_sync_tag = mga_create_sync_tag(dev);
|
||||
|
||||
if (buf_priv->discard) {
|
||||
buf_priv->my_freelist->age = dev_priv->last_sync_tag;
|
||||
mga_freelist_put(dev, buf);
|
||||
DRM_DEBUG("used : %d, total : %d\n", buf->used, buf->total);
|
||||
if(sarea_priv->WarpPipe & MGA_T2) {
|
||||
if ((buf->used/4) % 10)
|
||||
DRM_DEBUG("Multitex Buf is not aligned properly!!!\n");
|
||||
} else {
|
||||
if ((buf->used/4) % 8)
|
||||
DRM_DEBUG("Buf is not aligned properly!!!\n");
|
||||
}
|
||||
|
||||
|
||||
/* WARNING: if you change any of the state functions verify
|
||||
* these numbers (Overestimating this doesn't hurt).
|
||||
*/
|
||||
primary_needed = (25+15+30+25+
|
||||
10 +
|
||||
15 * MGA_NR_SAREA_CLIPRECTS);
|
||||
|
||||
|
||||
PRIM_OVERFLOW(dev, dev_priv, primary_needed);
|
||||
mgaEmitState( dev_priv );
|
||||
|
||||
if (buf->used) {
|
||||
/* WARNING: if you change any of the state functions verify
|
||||
* these numbers (Overestimating this doesn't hurt).
|
||||
*/
|
||||
buf_priv->dispatched = 1;
|
||||
primary_needed = (25+15+30+25+
|
||||
10 +
|
||||
15 * MGA_NR_SAREA_CLIPRECTS);
|
||||
PRIM_OVERFLOW(dev, dev_priv, primary_needed);
|
||||
mgaEmitState( dev_priv );
|
||||
|
||||
do {
|
||||
if (i < sarea_priv->nbox) {
|
||||
DRM_DEBUG("idx %d Emit box %d/%d:"
|
||||
|
|
@ -521,28 +536,28 @@ static void mga_dma_dispatch_vertex(drm_device_t *dev,
|
|||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_SECADDRESS,
|
||||
((__u32)address) | TT_VERTEX);
|
||||
((u32)address) | TT_VERTEX);
|
||||
PRIMOUTREG( MGAREG_SECEND,
|
||||
(((__u32)(address + length)) |
|
||||
(((u32)(address + length)) |
|
||||
use_agp));
|
||||
PRIMADVANCE( dev_priv );
|
||||
} while (++i < sarea_priv->nbox);
|
||||
}
|
||||
|
||||
PRIMGETPTR( dev_priv );
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_DWGSYNC, 0);
|
||||
PRIMOUTREG(MGAREG_DWGSYNC, dev_priv->last_sync_tag);
|
||||
PRIMADVANCE( dev_priv );
|
||||
}
|
||||
if (buf_priv->discard) {
|
||||
if(buf_priv->dispatched == 1) AGEBUF(dev_priv, buf_priv);
|
||||
buf_priv->dispatched = 0;
|
||||
mga_freelist_put(dev, buf);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void mga_dma_dispatch_indices(drm_device_t *dev,
|
||||
drm_buf_t *buf,
|
||||
int start,
|
||||
int end)
|
||||
unsigned int start,
|
||||
unsigned int end)
|
||||
{
|
||||
drm_mga_private_t *dev_priv = dev->dev_private;
|
||||
drm_mga_buf_priv_t *buf_priv = buf->dev_private;
|
||||
|
|
@ -552,33 +567,24 @@ static void mga_dma_dispatch_indices(drm_device_t *dev,
|
|||
int i = 0;
|
||||
int primary_needed;
|
||||
PRIMLOCALS;
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
DRM_DEBUG("dispatch indices %d addr 0x%lx, "
|
||||
DRM_DEBUG("dispatch indices %d addr 0x%x, "
|
||||
"start 0x%x end 0x%x nbox %d dirty %x\n",
|
||||
buf->idx, address, start, end,
|
||||
sarea_priv->nbox, sarea_priv->dirty);
|
||||
|
||||
|
||||
dev_priv->last_sync_tag = mga_create_sync_tag(dev);
|
||||
|
||||
if (buf_priv->discard) {
|
||||
buf_priv->my_freelist->age = dev_priv->last_sync_tag;
|
||||
mga_freelist_put(dev, buf);
|
||||
}
|
||||
|
||||
|
||||
/* WARNING: if you change any of the state functions verify
|
||||
* these numbers (Overestimating this doesn't hurt).
|
||||
*/
|
||||
primary_needed = (25+15+30+25+
|
||||
10 +
|
||||
15 * MGA_NR_SAREA_CLIPRECTS);
|
||||
|
||||
|
||||
PRIM_OVERFLOW(dev, dev_priv, primary_needed);
|
||||
mgaEmitState( dev_priv );
|
||||
|
||||
if (start != end) {
|
||||
/* WARNING: if you change any of the state functions verify
|
||||
* these numbers (Overestimating this doesn't hurt).
|
||||
*/
|
||||
buf_priv->dispatched = 1;
|
||||
primary_needed = (25+15+30+25+
|
||||
10 +
|
||||
15 * MGA_NR_SAREA_CLIPRECTS);
|
||||
PRIM_OVERFLOW(dev, dev_priv, primary_needed);
|
||||
mgaEmitState( dev_priv );
|
||||
|
||||
do {
|
||||
if (i < sarea_priv->nbox) {
|
||||
DRM_DEBUG("idx %d Emit box %d/%d:"
|
||||
|
|
@ -604,13 +610,11 @@ static void mga_dma_dispatch_indices(drm_device_t *dev,
|
|||
PRIMADVANCE( dev_priv );
|
||||
} while (++i < sarea_priv->nbox);
|
||||
}
|
||||
|
||||
PRIMGETPTR( dev_priv );
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_DWGSYNC, dev_priv->last_sync_tag);
|
||||
PRIMADVANCE( dev_priv );
|
||||
if (buf_priv->discard) {
|
||||
if(buf_priv->dispatched == 1) AGEBUF(dev_priv, buf_priv);
|
||||
buf_priv->dispatched = 0;
|
||||
mga_freelist_put(dev, buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -627,6 +631,7 @@ static void mga_dma_dispatch_clear( drm_device_t *dev, int flags,
|
|||
int i;
|
||||
int primary_needed;
|
||||
PRIMLOCALS;
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
if ( dev_priv->sgram )
|
||||
cmd = MGA_CLEAR_CMD | DC_atype_blk;
|
||||
|
|
@ -637,7 +642,6 @@ static void mga_dma_dispatch_clear( drm_device_t *dev, int flags,
|
|||
if(primary_needed == 0) primary_needed = 70;
|
||||
PRIM_OVERFLOW(dev, dev_priv, primary_needed);
|
||||
PRIMGETPTR( dev_priv );
|
||||
dev_priv->last_sync_tag = mga_create_sync_tag(dev);
|
||||
|
||||
for (i = 0 ; i < nbox ; i++) {
|
||||
unsigned int height = pbox[i].y2 - pbox[i].y1;
|
||||
|
|
@ -691,11 +695,6 @@ static void mga_dma_dispatch_clear( drm_device_t *dev, int flags,
|
|||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL] );
|
||||
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag);
|
||||
PRIMADVANCE(dev_priv);
|
||||
}
|
||||
|
||||
|
|
@ -709,14 +708,13 @@ static void mga_dma_dispatch_swap( drm_device_t *dev )
|
|||
int i;
|
||||
int primary_needed;
|
||||
PRIMLOCALS;
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
primary_needed = nbox * 5;
|
||||
primary_needed += 60;
|
||||
PRIM_OVERFLOW(dev, dev_priv, primary_needed);
|
||||
PRIMGETPTR( dev_priv );
|
||||
|
||||
dev_priv->last_sync_tag = mga_create_sync_tag(dev);
|
||||
|
||||
PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontOffset);
|
||||
PRIMOUTREG(MGAREG_MACCESS, dev_priv->mAccess);
|
||||
PRIMOUTREG(MGAREG_SRCORG, dev_priv->backOffset);
|
||||
|
|
@ -744,13 +742,9 @@ static void mga_dma_dispatch_swap( drm_device_t *dev )
|
|||
/* Force reset of DWGCTL */
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_SRCORG, 0);
|
||||
PRIMOUTREG( MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL] );
|
||||
|
||||
PRIMOUTREG( MGAREG_SRCORG, 0);
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag);
|
||||
PRIMADVANCE(dev_priv);
|
||||
}
|
||||
|
||||
|
|
@ -761,12 +755,11 @@ int mga_clear_bufs(struct inode *inode, struct file *filp,
|
|||
drm_device_t *dev = priv->dev;
|
||||
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
|
||||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
__volatile__ unsigned int *status =
|
||||
(__volatile__ unsigned int *)dev_priv->status_page;
|
||||
drm_mga_clear_t clear;
|
||||
|
||||
copy_from_user_ret(&clear, (drm_mga_clear_t *)arg, sizeof(clear),
|
||||
-EFAULT);
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
|
||||
DRM_ERROR("mga_clear_bufs called without lock held\n");
|
||||
|
|
@ -783,8 +776,8 @@ int mga_clear_bufs(struct inode *inode, struct file *filp,
|
|||
clear.clear_color,
|
||||
clear.clear_depth );
|
||||
PRIMUPDATE(dev_priv);
|
||||
mga_flush_write_combine();
|
||||
mga_dma_schedule(dev, 1);
|
||||
sarea_priv->last_dispatch = status[1];
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -795,8 +788,7 @@ int mga_swap_bufs(struct inode *inode, struct file *filp,
|
|||
drm_device_t *dev = priv->dev;
|
||||
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
|
||||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
__volatile__ unsigned int *status =
|
||||
(__volatile__ unsigned int *)dev_priv->status_page;
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
|
||||
DRM_ERROR("mga_swap_bufs called without lock held\n");
|
||||
|
|
@ -812,8 +804,8 @@ int mga_swap_bufs(struct inode *inode, struct file *filp,
|
|||
mga_dma_dispatch_swap( dev );
|
||||
PRIMUPDATE(dev_priv);
|
||||
set_bit(MGA_BUF_SWAP_PENDING, &dev_priv->current_prim->buffer_status);
|
||||
mga_flush_write_combine();
|
||||
mga_dma_schedule(dev, 1);
|
||||
sarea_priv->last_dispatch = status[1];
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -825,12 +817,11 @@ int mga_iload(struct inode *inode, struct file *filp,
|
|||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
|
||||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
__volatile__ unsigned int *status =
|
||||
(__volatile__ unsigned int *)dev_priv->status_page;
|
||||
drm_buf_t *buf;
|
||||
drm_mga_buf_priv_t *buf_priv;
|
||||
drm_mga_iload_t iload;
|
||||
unsigned long bus_address;
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
DRM_DEBUG("Starting Iload\n");
|
||||
copy_from_user_ret(&iload, (drm_mga_iload_t *)arg, sizeof(iload),
|
||||
|
|
@ -859,11 +850,11 @@ int mga_iload(struct inode *inode, struct file *filp,
|
|||
|
||||
mga_dma_dispatch_tex_blit(dev, bus_address, iload.length,
|
||||
iload.destOrg);
|
||||
buf_priv->my_freelist->age = dev_priv->last_sync_tag;
|
||||
AGEBUF(dev_priv, buf_priv);
|
||||
buf_priv->discard = 1;
|
||||
mga_freelist_put(dev, buf);
|
||||
mga_flush_write_combine();
|
||||
mga_dma_schedule(dev, 1);
|
||||
sarea_priv->last_dispatch = status[1];
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -873,13 +864,11 @@ int mga_vertex(struct inode *inode, struct file *filp,
|
|||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
|
||||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
__volatile__ unsigned int *status =
|
||||
(__volatile__ unsigned int *)dev_priv->status_page;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_buf_t *buf;
|
||||
drm_mga_buf_priv_t *buf_priv;
|
||||
drm_mga_vertex_t vertex;
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
copy_from_user_ret(&vertex, (drm_mga_vertex_t *)arg, sizeof(vertex),
|
||||
-EFAULT);
|
||||
|
|
@ -898,9 +887,10 @@ int mga_vertex(struct inode *inode, struct file *filp,
|
|||
buf_priv->discard = vertex.discard;
|
||||
|
||||
if (!mgaVerifyState(dev_priv)) {
|
||||
if (vertex.discard) {
|
||||
buf_priv->my_freelist->age = dev_priv->last_sync_tag;
|
||||
mga_freelist_put(dev, buf);
|
||||
if (vertex.discard) {
|
||||
if(buf_priv->dispatched == 1) AGEBUF(dev_priv, buf_priv);
|
||||
buf_priv->dispatched = 0;
|
||||
mga_freelist_put(dev, buf);
|
||||
}
|
||||
DRM_DEBUG("bad state\n");
|
||||
return -EINVAL;
|
||||
|
|
@ -909,8 +899,8 @@ int mga_vertex(struct inode *inode, struct file *filp,
|
|||
mga_dma_dispatch_vertex(dev, buf);
|
||||
|
||||
PRIMUPDATE(dev_priv);
|
||||
mga_flush_write_combine();
|
||||
mga_dma_schedule(dev, 1);
|
||||
sarea_priv->last_dispatch = status[1];
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -921,13 +911,11 @@ int mga_indices(struct inode *inode, struct file *filp,
|
|||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
|
||||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
__volatile__ unsigned int *status =
|
||||
(__volatile__ unsigned int *)dev_priv->status_page;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_buf_t *buf;
|
||||
drm_mga_buf_priv_t *buf_priv;
|
||||
drm_mga_indices_t indices;
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
copy_from_user_ret(&indices, (drm_mga_indices_t *)arg, sizeof(indices),
|
||||
-EFAULT);
|
||||
|
|
@ -945,9 +933,10 @@ int mga_indices(struct inode *inode, struct file *filp,
|
|||
buf_priv->discard = indices.discard;
|
||||
|
||||
if (!mgaVerifyState(dev_priv)) {
|
||||
if (indices.discard) {
|
||||
buf_priv->my_freelist->age = dev_priv->last_sync_tag;
|
||||
mga_freelist_put(dev, buf);
|
||||
if (indices.discard) {
|
||||
if(buf_priv->dispatched == 1) AGEBUF(dev_priv, buf_priv);
|
||||
buf_priv->dispatched = 0;
|
||||
mga_freelist_put(dev, buf);
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -955,8 +944,8 @@ int mga_indices(struct inode *inode, struct file *filp,
|
|||
mga_dma_dispatch_indices(dev, buf, indices.start, indices.end);
|
||||
|
||||
PRIMUPDATE(dev_priv);
|
||||
mga_flush_write_combine();
|
||||
mga_dma_schedule(dev, 1);
|
||||
sarea_priv->last_dispatch = status[1];
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -966,6 +955,7 @@ static int mga_dma_get_buffers(drm_device_t *dev, drm_dma_t *d)
|
|||
{
|
||||
int i;
|
||||
drm_buf_t *buf;
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
for (i = d->granted_count; i < d->request_count; i++) {
|
||||
buf = mga_freelist_get(dev);
|
||||
|
|
@ -990,12 +980,9 @@ int mga_dma(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
|
||||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
__volatile__ unsigned int *status =
|
||||
(__volatile__ unsigned int *)dev_priv->status_page;
|
||||
int retcode = 0;
|
||||
drm_dma_t d;
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
copy_from_user_ret(&d, (drm_dma_t *)arg, sizeof(d), -EFAULT);
|
||||
DRM_DEBUG("%d %d: %d send, %d req\n",
|
||||
|
|
@ -1031,6 +1018,5 @@ int mga_dma(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
DRM_DEBUG("%d returning, granted = %d\n",
|
||||
current->pid, d.granted_count);
|
||||
copy_to_user_ret((drm_dma_t *)arg, &d, sizeof(d), -EFAULT);
|
||||
sarea_priv->last_dispatch = status[1];
|
||||
return retcode;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue