linux merge for drm
parent
c14006ba9f
commit
b3eb34e0ea
|
@ -27,7 +27,7 @@
|
|||
* Authors: Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
* Kevin E. Martin <martin@valinux.com>
|
||||
*
|
||||
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c,v 1.28 2002/10/16 01:26:49 dawes Exp $
|
||||
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c,v 1.31 2003/02/04 03:01:59 dawes Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ tdfx-objs := tdfx_drv.o
|
|||
r128-objs := r128_drv.o r128_cce.o r128_irq.o r128_state.o
|
||||
mga-objs := mga_drv.o mga_dma.o mga_irq.o mga_state.o mga_warp.o
|
||||
i810-objs := i810_drv.o i810_dma.o
|
||||
i830-objs := i830_drv.o i830_dma.o
|
||||
i830-objs := i830_drv.o i830_dma.o i830_irq.o
|
||||
radeon-objs := radeon_drv.o radeon_cp.o radeon_irq.o radeon_mem.o radeon_state.o
|
||||
ffb-objs := ffb_drv.o ffb_context.o
|
||||
|
||||
|
|
|
@ -166,6 +166,12 @@
|
|||
#define pte_unmap(pte)
|
||||
#endif
|
||||
|
||||
#ifndef list_for_each_safe
|
||||
#define list_for_each_safe(pos, n, head) \
|
||||
for (pos = (head)->next, n = pos->next; pos != (head); \
|
||||
pos = n, n = pos->next)
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19)
|
||||
static inline struct page * vmalloc_to_page(void * vmalloc_addr)
|
||||
{
|
||||
|
|
|
@ -267,12 +267,12 @@ drm_agp_head_t *DRM(agp_init)(void)
|
|||
head->cant_use_aperture = head->agp_info.cant_use_aperture;
|
||||
head->page_mask = head->agp_info.page_mask;
|
||||
#endif
|
||||
|
||||
DRM_DEBUG("AGP %d.%d, aperture @ 0x%08lx %ZuMB\n",
|
||||
head->agp_info.version.major,
|
||||
head->agp_info.version.minor,
|
||||
head->agp_info.aper_base,
|
||||
head->agp_info.aper_size);
|
||||
|
||||
DRM_INFO("AGP %d.%d aperture @ 0x%08lx %ZuMB\n",
|
||||
head->agp_info.version.major,
|
||||
head->agp_info.version.minor,
|
||||
head->agp_info.aper_base,
|
||||
head->agp_info.aper_size);
|
||||
}
|
||||
return head;
|
||||
}
|
||||
|
|
|
@ -714,7 +714,7 @@ void DRM(vbl_send_signals)( drm_device_t *dev )
|
|||
|
||||
list_del( (struct list_head *) vbl_sig );
|
||||
|
||||
DRM_FREE(vbl_sig,sizeof(*vbl_sig));
|
||||
DRM_FREE( vbl_sig );
|
||||
|
||||
dev->vbl_pending--;
|
||||
}
|
||||
|
|
|
@ -765,8 +765,8 @@ int DRM(release)( struct inode *inode, struct file *filp )
|
|||
* Begin inline drm_release
|
||||
*/
|
||||
|
||||
DRM_DEBUG( "pid = %d, device = 0x%x, open_count = %d\n",
|
||||
current->pid, dev->device, dev->open_count );
|
||||
DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n",
|
||||
current->pid, (long)dev->device, dev->open_count );
|
||||
|
||||
if ( dev->lock.hw_lock &&
|
||||
_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
|
||||
|
@ -891,8 +891,9 @@ int DRM(ioctl)( struct inode *inode, struct file *filp,
|
|||
atomic_inc( &dev->counts[_DRM_STAT_IOCTLS] );
|
||||
++priv->ioctl_count;
|
||||
|
||||
DRM_DEBUG( "pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%x, auth=%d\n",
|
||||
current->pid, cmd, nr, dev->device, priv->authenticated );
|
||||
DRM_DEBUG( "pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
|
||||
current->pid, cmd, nr, (long)dev->device,
|
||||
priv->authenticated );
|
||||
|
||||
if ( nr >= DRIVER_IOCTL_COUNT ) {
|
||||
retcode = -EINVAL;
|
||||
|
|
|
@ -95,8 +95,8 @@ int DRM(flush)(struct file *filp)
|
|||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
|
||||
DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d\n",
|
||||
current->pid, dev->device, dev->open_count);
|
||||
DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
|
||||
current->pid, (long)dev->device, dev->open_count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ int DRM(fasync)(int fd, struct file *filp, int on)
|
|||
drm_device_t *dev = priv->dev;
|
||||
int retcode;
|
||||
|
||||
DRM_DEBUG("fd = %d, device = 0x%x\n", fd, dev->device);
|
||||
DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, (long)dev->device);
|
||||
retcode = fasync_helper(fd, filp, on, &dev->buf_async);
|
||||
if (retcode < 0) return retcode;
|
||||
return 0;
|
||||
|
|
|
@ -41,6 +41,28 @@ int DRM(irq_busid)(struct inode *inode, struct file *filp,
|
|||
|
||||
if (copy_from_user(&p, (drm_irq_busid_t *)arg, sizeof(p)))
|
||||
return -EFAULT;
|
||||
#ifdef __alpha__
|
||||
{
|
||||
int domain = p.busnum >> 8;
|
||||
p.busnum &= 0xff;
|
||||
|
||||
/*
|
||||
* Find the hose the device is on (the domain number is the
|
||||
* hose index) and offset the bus by the root bus of that
|
||||
* hose.
|
||||
*/
|
||||
for(dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,NULL);
|
||||
dev;
|
||||
dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,dev)) {
|
||||
struct pci_controller *hose = dev->sysdata;
|
||||
|
||||
if (hose->index == domain) {
|
||||
p.busnum += hose->bus->number;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
dev = pci_find_slot(p.busnum, PCI_DEVFN(p.devnum, p.funcnum));
|
||||
if (!dev) {
|
||||
DRM_ERROR("pci_find_slot failed for %d:%d:%d\n",
|
||||
|
@ -113,7 +135,7 @@ int DRM(setunique)(struct inode *inode, struct file *filp,
|
|||
|
||||
do {
|
||||
struct pci_dev *pci_dev;
|
||||
int b, d, f;
|
||||
int domain, b, d, f;
|
||||
char *p;
|
||||
|
||||
for(p = dev->unique; p && *p && *p != ':'; p++);
|
||||
|
@ -125,6 +147,27 @@ int DRM(setunique)(struct inode *inode, struct file *filp,
|
|||
f = (int)simple_strtoul(p+1, &p, 10);
|
||||
if (*p) break;
|
||||
|
||||
domain = b >> 8;
|
||||
b &= 0xff;
|
||||
|
||||
#ifdef __alpha__
|
||||
/*
|
||||
* Find the hose the device is on (the domain number is the
|
||||
* hose index) and offset the bus by the root bus of that
|
||||
* hose.
|
||||
*/
|
||||
for(pci_dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,NULL);
|
||||
pci_dev;
|
||||
pci_dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,pci_dev)) {
|
||||
struct pci_controller *hose = pci_dev->sysdata;
|
||||
|
||||
if (hose->index == domain) {
|
||||
b += hose->bus->number;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
pci_dev = pci_find_slot(b, PCI_DEVFN(d,f));
|
||||
if (pci_dev) {
|
||||
dev->pdev = pci_dev;
|
||||
|
|
|
@ -148,10 +148,10 @@ static int DRM(name_info)(char *buf, char **start, off_t offset, int request,
|
|||
*eof = 0;
|
||||
|
||||
if (dev->unique) {
|
||||
DRM_PROC_PRINT("%s 0x%x %s\n",
|
||||
dev->name, dev->device, dev->unique);
|
||||
DRM_PROC_PRINT("%s 0x%lx %s\n",
|
||||
dev->name, (long)dev->device, dev->unique);
|
||||
} else {
|
||||
DRM_PROC_PRINT("%s 0x%x\n", dev->name, dev->device);
|
||||
DRM_PROC_PRINT("%s 0x%lx\n", dev->name, (long)dev->device);
|
||||
}
|
||||
|
||||
if (len > request + offset) return request;
|
||||
|
|
|
@ -53,30 +53,10 @@
|
|||
#define I810_BUF_UNMAPPED 0
|
||||
#define I810_BUF_MAPPED 1
|
||||
|
||||
#define RING_LOCALS unsigned int outring, ringmask; volatile char *virt;
|
||||
|
||||
#define BEGIN_LP_RING(n) do { \
|
||||
if (0) DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", n, __FUNCTION__); \
|
||||
if (dev_priv->ring.space < n*4) \
|
||||
i810_wait_ring(dev, n*4); \
|
||||
dev_priv->ring.space -= n*4; \
|
||||
outring = dev_priv->ring.tail; \
|
||||
ringmask = dev_priv->ring.tail_mask; \
|
||||
virt = dev_priv->ring.virtual_start; \
|
||||
} while (0)
|
||||
|
||||
#define ADVANCE_LP_RING() do { \
|
||||
if (0) DRM_DEBUG("ADVANCE_LP_RING\n"); \
|
||||
dev_priv->ring.tail = outring; \
|
||||
I810_WRITE(LP_RING + RING_TAIL, outring); \
|
||||
} while(0)
|
||||
|
||||
#define OUT_RING(n) do { \
|
||||
if (0) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \
|
||||
*(volatile unsigned int *)(virt + outring) = n; \
|
||||
outring += 4; \
|
||||
outring &= ringmask; \
|
||||
} while (0)
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,2)
|
||||
#define down_write down
|
||||
#define up_write up
|
||||
#endif
|
||||
|
||||
static inline void i810_print_status_page(drm_device_t *dev)
|
||||
{
|
||||
|
@ -185,11 +165,7 @@ static int i810_map_buffer(drm_buf_t *buf, struct file *filp)
|
|||
|
||||
if(buf_priv->currently_mapped == I810_BUF_MAPPED) return -EINVAL;
|
||||
|
||||
#if LINUX_VERSION_CODE <= 0x020402
|
||||
down( ¤t->mm->mmap_sem );
|
||||
#else
|
||||
down_write( ¤t->mm->mmap_sem );
|
||||
#endif
|
||||
old_fops = filp->f_op;
|
||||
filp->f_op = &i810_buffer_fops;
|
||||
dev_priv->mmap_buffer = buf;
|
||||
|
@ -201,15 +177,12 @@ static int i810_map_buffer(drm_buf_t *buf, struct file *filp)
|
|||
filp->f_op = old_fops;
|
||||
if ((unsigned long)buf_priv->virtual > -1024UL) {
|
||||
/* Real error */
|
||||
DRM_DEBUG("mmap error\n");
|
||||
DRM_ERROR("mmap error\n");
|
||||
retcode = (signed int)buf_priv->virtual;
|
||||
buf_priv->virtual = 0;
|
||||
}
|
||||
#if LINUX_VERSION_CODE <= 0x020402
|
||||
up( ¤t->mm->mmap_sem );
|
||||
#else
|
||||
up_write( ¤t->mm->mmap_sem );
|
||||
#endif
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
|
@ -220,19 +193,13 @@ static int i810_unmap_buffer(drm_buf_t *buf)
|
|||
|
||||
if(buf_priv->currently_mapped != I810_BUF_MAPPED)
|
||||
return -EINVAL;
|
||||
#if LINUX_VERSION_CODE <= 0x020402
|
||||
down( ¤t->mm->mmap_sem );
|
||||
#else
|
||||
down_write( ¤t->mm->mmap_sem );
|
||||
#endif
|
||||
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
retcode = DO_MUNMAP(current->mm,
|
||||
(unsigned long)buf_priv->virtual,
|
||||
(size_t) buf->total);
|
||||
#if LINUX_VERSION_CODE <= 0x020402
|
||||
up( ¤t->mm->mmap_sem );
|
||||
#else
|
||||
up_write( ¤t->mm->mmap_sem );
|
||||
#endif
|
||||
up_write(¤t->mm->mmap_sem);
|
||||
|
||||
buf_priv->currently_mapped = I810_BUF_UNMAPPED;
|
||||
buf_priv->virtual = 0;
|
||||
|
||||
|
@ -257,7 +224,7 @@ static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d,
|
|||
retcode = i810_map_buffer(buf, filp);
|
||||
if(retcode) {
|
||||
i810_freelist_put(dev, buf);
|
||||
DRM_DEBUG("mapbuf failed, retcode %d\n", retcode);
|
||||
DRM_ERROR("mapbuf failed, retcode %d\n", retcode);
|
||||
return retcode;
|
||||
}
|
||||
buf->pid = priv->pid;
|
||||
|
@ -321,7 +288,7 @@ static int i810_wait_ring(drm_device_t *dev, int n)
|
|||
end = jiffies + (HZ*3);
|
||||
|
||||
iters++;
|
||||
if((signed)(end - jiffies) <= 0) {
|
||||
if(time_before(end, jiffies)) {
|
||||
DRM_ERROR("space: %d wanted %d\n", ring->space, n);
|
||||
DRM_ERROR("lockup\n");
|
||||
goto out_wait_ring;
|
||||
|
|
|
@ -136,6 +136,33 @@ int i810_clear_bufs(struct inode *inode, struct file *filp,
|
|||
#define I810_READ16(reg) I810_DEREF16(reg)
|
||||
#define I810_WRITE16(reg,val) do { I810_DEREF16(reg) = val; } while (0)
|
||||
|
||||
#define I810_VERBOSE 0
|
||||
#define RING_LOCALS unsigned int outring, ringmask; \
|
||||
volatile char *virt;
|
||||
|
||||
#define BEGIN_LP_RING(n) do { \
|
||||
if (I810_VERBOSE) \
|
||||
DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", n, __FUNCTION__); \
|
||||
if (dev_priv->ring.space < n*4) \
|
||||
i810_wait_ring(dev, n*4); \
|
||||
dev_priv->ring.space -= n*4; \
|
||||
outring = dev_priv->ring.tail; \
|
||||
ringmask = dev_priv->ring.tail_mask; \
|
||||
virt = dev_priv->ring.virtual_start; \
|
||||
} while (0)
|
||||
|
||||
#define ADVANCE_LP_RING() do { \
|
||||
if (I810_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING\n"); \
|
||||
dev_priv->ring.tail = outring; \
|
||||
I810_WRITE(LP_RING + RING_TAIL, outring); \
|
||||
} while(0)
|
||||
|
||||
#define OUT_RING(n) do { \
|
||||
if (I810_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \
|
||||
*(volatile unsigned int *)(virt + outring) = n; \
|
||||
outring += 4; \
|
||||
outring &= ringmask; \
|
||||
} while (0)
|
||||
|
||||
#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23))
|
||||
#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23))
|
||||
|
@ -198,6 +225,7 @@ int i810_clear_bufs(struct inode *inode, struct file *filp,
|
|||
|
||||
#define CMD_OP_Z_BUFFER_INFO ((0x0<<29)|(0x16<<23))
|
||||
#define CMD_OP_DESTBUFFER_INFO ((0x0<<29)|(0x15<<23))
|
||||
#define CMD_OP_FRONTBUFFER_INFO ((0x0<<29)|(0x14<<23))
|
||||
|
||||
#define BR00_BITBLT_CLIENT 0x40000000
|
||||
#define BR00_OP_COLOR_BLT 0x10000000
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "i830_drm.h"
|
||||
#include "i830_drv.h"
|
||||
#include <linux/interrupt.h> /* For task queue support */
|
||||
#include <linux/pagemap.h> /* For FASTCALL on unlock_page() */
|
||||
#include <linux/delay.h>
|
||||
|
||||
#ifdef DO_MUNMAP_4_ARGS
|
||||
|
@ -53,8 +54,6 @@
|
|||
#define I830_BUF_UNMAPPED 0
|
||||
#define I830_BUF_MAPPED 1
|
||||
|
||||
#define RING_LOCALS unsigned int outring, ringmask; volatile char *virt;
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,2)
|
||||
#define down_write down
|
||||
#define up_write up
|
||||
|
@ -67,32 +66,6 @@
|
|||
#define UnlockPage(page) unlock_page(page)
|
||||
#endif
|
||||
|
||||
#define I830_VERBOSE 0
|
||||
|
||||
#define BEGIN_LP_RING(n) do { \
|
||||
if (I830_VERBOSE) \
|
||||
printk("BEGIN_LP_RING(%d) in %s\n", \
|
||||
n, __FUNCTION__); \
|
||||
if (dev_priv->ring.space < n*4) \
|
||||
i830_wait_ring(dev, n*4); \
|
||||
dev_priv->ring.space -= n*4; \
|
||||
outring = dev_priv->ring.tail; \
|
||||
ringmask = dev_priv->ring.tail_mask; \
|
||||
virt = dev_priv->ring.virtual_start; \
|
||||
} while (0)
|
||||
|
||||
#define ADVANCE_LP_RING() do { \
|
||||
if (I830_VERBOSE) printk("ADVANCE_LP_RING %x\n", outring); \
|
||||
dev_priv->ring.tail = outring; \
|
||||
I830_WRITE(LP_RING + RING_TAIL, outring); \
|
||||
} while(0)
|
||||
|
||||
#define OUT_RING(n) do { \
|
||||
if (I830_VERBOSE) printk(" OUT_RING %x\n", (int)(n)); \
|
||||
*(volatile unsigned int *)(virt + outring) = n; \
|
||||
outring += 4; \
|
||||
outring &= ringmask; \
|
||||
} while (0)
|
||||
|
||||
static inline void i830_print_status_page(drm_device_t *dev)
|
||||
{
|
||||
|
@ -252,7 +225,7 @@ static int i830_dma_get_buffer(drm_device_t *dev, drm_i830_dma_t *d,
|
|||
buf = i830_freelist_get(dev);
|
||||
if (!buf) {
|
||||
retcode = -ENOMEM;
|
||||
DRM_ERROR("retcode=%d\n", retcode);
|
||||
DRM_DEBUG("retcode=%d\n", retcode);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
|
@ -286,12 +259,21 @@ static int i830_dma_cleanup(drm_device_t *dev)
|
|||
dev_priv->ring.Size);
|
||||
}
|
||||
if(dev_priv->hw_status_page != 0UL) {
|
||||
pci_free_consistent(dev->pdev, PAGE_SIZE,
|
||||
pci_free_consistent(dev->pdev, PAGE_SIZE,
|
||||
(void *)dev_priv->hw_status_page,
|
||||
dev_priv->dma_status_page);
|
||||
/* Need to rewrite hardware status page */
|
||||
I830_WRITE(0x02080, 0x1ffff000);
|
||||
}
|
||||
|
||||
/* Disable interrupts here because after dev_private
|
||||
* is freed, it's too late.
|
||||
*/
|
||||
if (dev->irq) {
|
||||
I830_WRITE16( I830REG_INT_MASK_R, 0xffff );
|
||||
I830_WRITE16( I830REG_INT_ENABLE_R, 0x0 );
|
||||
}
|
||||
|
||||
DRM(free)(dev->dev_private, sizeof(drm_i830_private_t),
|
||||
DRM_MEM_DRIVER);
|
||||
dev->dev_private = NULL;
|
||||
|
@ -305,7 +287,7 @@ static int i830_dma_cleanup(drm_device_t *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int i830_wait_ring(drm_device_t *dev, int n)
|
||||
int i830_wait_ring(drm_device_t *dev, int n, const char *caller)
|
||||
{
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
drm_i830_ring_buffer_t *ring = &(dev_priv->ring);
|
||||
|
@ -331,6 +313,7 @@ static int i830_wait_ring(drm_device_t *dev, int n)
|
|||
goto out_wait_ring;
|
||||
}
|
||||
udelay(1);
|
||||
dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT;
|
||||
}
|
||||
|
||||
out_wait_ring:
|
||||
|
@ -346,6 +329,9 @@ static void i830_kernel_lost_context(drm_device_t *dev)
|
|||
ring->tail = I830_READ(LP_RING + RING_TAIL) & TAIL_ADDR;
|
||||
ring->space = ring->head - (ring->tail+8);
|
||||
if (ring->space < 0) ring->space += ring->Size;
|
||||
|
||||
if (ring->head == ring->tail)
|
||||
dev_priv->sarea_priv->perf_boxes |= I830_BOX_RING_EMPTY;
|
||||
}
|
||||
|
||||
static int i830_freelist_init(drm_device_t *dev, drm_i830_private_t *dev_priv)
|
||||
|
@ -460,6 +446,8 @@ static int i830_dma_initialize(drm_device_t *dev,
|
|||
|
||||
dev_priv->back_pitch = init->back_pitch;
|
||||
dev_priv->depth_pitch = init->depth_pitch;
|
||||
dev_priv->do_boxes = 0;
|
||||
dev_priv->use_mi_batchbuffer_start = 0;
|
||||
|
||||
/* Program Hardware Status Page */
|
||||
dev_priv->hw_status_page =
|
||||
|
@ -474,7 +462,7 @@ static int i830_dma_initialize(drm_device_t *dev,
|
|||
memset((void *) dev_priv->hw_status_page, 0, PAGE_SIZE);
|
||||
DRM_DEBUG("hw status page @ %lx\n", dev_priv->hw_status_page);
|
||||
|
||||
I830_WRITE(0x02080, dev_priv->dma_status_page);
|
||||
I830_WRITE(0x02080, virt_to_bus((void *)dev_priv->hw_status_page));
|
||||
DRM_DEBUG("Enabled hardware status page\n");
|
||||
|
||||
/* Now we need to init our freelist */
|
||||
|
@ -535,11 +523,7 @@ static void i830EmitContextVerified( drm_device_t *dev,
|
|||
unsigned int tmp;
|
||||
RING_LOCALS;
|
||||
|
||||
BEGIN_LP_RING( I830_CTX_SETUP_SIZE + 2 );
|
||||
|
||||
OUT_RING( GFX_OP_STIPPLE );
|
||||
OUT_RING( 0 );
|
||||
|
||||
BEGIN_LP_RING( I830_CTX_SETUP_SIZE + 4 );
|
||||
|
||||
for ( i = 0 ; i < I830_CTXREG_BLENDCOLR0 ; i++ ) {
|
||||
tmp = code[i];
|
||||
|
@ -577,38 +561,44 @@ static void i830EmitContextVerified( drm_device_t *dev,
|
|||
ADVANCE_LP_RING();
|
||||
}
|
||||
|
||||
static void i830EmitTexVerified( drm_device_t *dev,
|
||||
volatile unsigned int *code )
|
||||
static void i830EmitTexVerified( drm_device_t *dev, unsigned int *code )
|
||||
{
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
int i, j = 0;
|
||||
unsigned int tmp;
|
||||
RING_LOCALS;
|
||||
|
||||
BEGIN_LP_RING( I830_TEX_SETUP_SIZE );
|
||||
if (code[I830_TEXREG_MI0] == GFX_OP_MAP_INFO ||
|
||||
(code[I830_TEXREG_MI0] & ~(0xf*LOAD_TEXTURE_MAP0)) ==
|
||||
(STATE3D_LOAD_STATE_IMMEDIATE_2|4)) {
|
||||
|
||||
OUT_RING( GFX_OP_MAP_INFO );
|
||||
OUT_RING( code[I830_TEXREG_MI1] );
|
||||
OUT_RING( code[I830_TEXREG_MI2] );
|
||||
OUT_RING( code[I830_TEXREG_MI3] );
|
||||
OUT_RING( code[I830_TEXREG_MI4] );
|
||||
OUT_RING( code[I830_TEXREG_MI5] );
|
||||
BEGIN_LP_RING( I830_TEX_SETUP_SIZE );
|
||||
|
||||
for ( i = 6 ; i < I830_TEX_SETUP_SIZE ; i++ ) {
|
||||
tmp = code[i];
|
||||
OUT_RING( tmp );
|
||||
j++;
|
||||
}
|
||||
OUT_RING( code[I830_TEXREG_MI0] ); /* TM0LI */
|
||||
OUT_RING( code[I830_TEXREG_MI1] ); /* TM0S0 */
|
||||
OUT_RING( code[I830_TEXREG_MI2] ); /* TM0S1 */
|
||||
OUT_RING( code[I830_TEXREG_MI3] ); /* TM0S2 */
|
||||
OUT_RING( code[I830_TEXREG_MI4] ); /* TM0S3 */
|
||||
OUT_RING( code[I830_TEXREG_MI5] ); /* TM0S4 */
|
||||
|
||||
for ( i = 6 ; i < I830_TEX_SETUP_SIZE ; i++ ) {
|
||||
tmp = code[i];
|
||||
OUT_RING( tmp );
|
||||
j++;
|
||||
}
|
||||
|
||||
if (j & 1)
|
||||
OUT_RING( 0 );
|
||||
if (j & 1)
|
||||
OUT_RING( 0 );
|
||||
|
||||
ADVANCE_LP_RING();
|
||||
ADVANCE_LP_RING();
|
||||
}
|
||||
else
|
||||
printk("rejected packet %x\n", code[0]);
|
||||
}
|
||||
|
||||
static void i830EmitTexBlendVerified( drm_device_t *dev,
|
||||
volatile unsigned int *code,
|
||||
volatile unsigned int num)
|
||||
unsigned int *code,
|
||||
unsigned int num)
|
||||
{
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
int i, j = 0;
|
||||
|
@ -618,7 +608,7 @@ static void i830EmitTexBlendVerified( drm_device_t *dev,
|
|||
if (!num)
|
||||
return;
|
||||
|
||||
BEGIN_LP_RING( num );
|
||||
BEGIN_LP_RING( num + 1 );
|
||||
|
||||
for ( i = 0 ; i < num ; i++ ) {
|
||||
tmp = code[i];
|
||||
|
@ -641,6 +631,8 @@ static void i830EmitTexPalette( drm_device_t *dev,
|
|||
int i;
|
||||
RING_LOCALS;
|
||||
|
||||
return;
|
||||
|
||||
BEGIN_LP_RING( 258 );
|
||||
|
||||
if(is_shared == 1) {
|
||||
|
@ -654,42 +646,41 @@ static void i830EmitTexPalette( drm_device_t *dev,
|
|||
OUT_RING(palette[i]);
|
||||
}
|
||||
OUT_RING(0);
|
||||
/* KW: WHERE IS THE ADVANCE_LP_RING? This is effectively a noop!
|
||||
*/
|
||||
}
|
||||
|
||||
/* Need to do some additional checking when setting the dest buffer.
|
||||
*/
|
||||
static void i830EmitDestVerified( drm_device_t *dev,
|
||||
volatile unsigned int *code )
|
||||
unsigned int *code )
|
||||
{
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
unsigned int tmp;
|
||||
RING_LOCALS;
|
||||
|
||||
BEGIN_LP_RING( I830_DEST_SETUP_SIZE + 6 );
|
||||
BEGIN_LP_RING( I830_DEST_SETUP_SIZE + 10 );
|
||||
|
||||
|
||||
tmp = code[I830_DESTREG_CBUFADDR];
|
||||
if (tmp == dev_priv->front_di1) {
|
||||
/* Don't use fence when front buffer rendering */
|
||||
OUT_RING( CMD_OP_DESTBUFFER_INFO );
|
||||
OUT_RING( BUF_3D_ID_COLOR_BACK |
|
||||
BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) );
|
||||
OUT_RING( tmp );
|
||||
if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) {
|
||||
if (((int)outring) & 8) {
|
||||
OUT_RING(0);
|
||||
OUT_RING(0);
|
||||
}
|
||||
|
||||
OUT_RING( CMD_OP_DESTBUFFER_INFO );
|
||||
OUT_RING( BUF_3D_ID_DEPTH |
|
||||
BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp));
|
||||
OUT_RING( dev_priv->zi1 );
|
||||
} else if(tmp == dev_priv->back_di1) {
|
||||
OUT_RING( CMD_OP_DESTBUFFER_INFO );
|
||||
OUT_RING( BUF_3D_ID_COLOR_BACK |
|
||||
BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) |
|
||||
BUF_3D_USE_FENCE);
|
||||
OUT_RING( tmp );
|
||||
OUT_RING( 0 );
|
||||
|
||||
OUT_RING( CMD_OP_DESTBUFFER_INFO );
|
||||
OUT_RING( BUF_3D_ID_DEPTH | BUF_3D_USE_FENCE |
|
||||
BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp));
|
||||
OUT_RING( dev_priv->zi1 );
|
||||
OUT_RING( 0 );
|
||||
} else {
|
||||
DRM_ERROR("bad di1 %x (allow %x or %x)\n",
|
||||
tmp, dev_priv->front_di1, dev_priv->back_di1);
|
||||
|
@ -717,21 +708,35 @@ static void i830EmitDestVerified( drm_device_t *dev,
|
|||
OUT_RING( 0 );
|
||||
}
|
||||
|
||||
OUT_RING( code[I830_DESTREG_SENABLE] );
|
||||
|
||||
OUT_RING( GFX_OP_SCISSOR_RECT );
|
||||
OUT_RING( code[I830_DESTREG_SR1] );
|
||||
OUT_RING( code[I830_DESTREG_SR2] );
|
||||
OUT_RING( 0 );
|
||||
|
||||
ADVANCE_LP_RING();
|
||||
}
|
||||
|
||||
static void i830EmitStippleVerified( drm_device_t *dev,
|
||||
unsigned int *code )
|
||||
{
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
RING_LOCALS;
|
||||
|
||||
BEGIN_LP_RING( 2 );
|
||||
OUT_RING( GFX_OP_STIPPLE );
|
||||
OUT_RING( code[1] );
|
||||
ADVANCE_LP_RING();
|
||||
}
|
||||
|
||||
|
||||
static void i830EmitState( drm_device_t *dev )
|
||||
{
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
unsigned int dirty = sarea_priv->dirty;
|
||||
|
||||
DRM_DEBUG("%s %x\n", __FUNCTION__, dirty);
|
||||
|
||||
if (dirty & I830_UPLOAD_BUFFERS) {
|
||||
i830EmitDestVerified( dev, sarea_priv->BufferState );
|
||||
sarea_priv->dirty &= ~I830_UPLOAD_BUFFERS;
|
||||
|
@ -765,17 +770,154 @@ static void i830EmitState( drm_device_t *dev )
|
|||
}
|
||||
|
||||
if (dirty & I830_UPLOAD_TEX_PALETTE_SHARED) {
|
||||
i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 1);
|
||||
i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 1);
|
||||
} else {
|
||||
if (dirty & I830_UPLOAD_TEX_PALETTE_N(0)) {
|
||||
i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 0);
|
||||
sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(0);
|
||||
}
|
||||
if (dirty & I830_UPLOAD_TEX_PALETTE_N(1)) {
|
||||
i830EmitTexPalette(dev, sarea_priv->Palette[1], 1, 0);
|
||||
sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(1);
|
||||
}
|
||||
if (dirty & I830_UPLOAD_TEX_PALETTE_N(0)) {
|
||||
i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 0);
|
||||
sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(0);
|
||||
}
|
||||
if (dirty & I830_UPLOAD_TEX_PALETTE_N(1)) {
|
||||
i830EmitTexPalette(dev, sarea_priv->Palette[1], 1, 0);
|
||||
sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(1);
|
||||
}
|
||||
|
||||
/* 1.3:
|
||||
*/
|
||||
#if 0
|
||||
if (dirty & I830_UPLOAD_TEX_PALETTE_N(2)) {
|
||||
i830EmitTexPalette(dev, sarea_priv->Palette2[0], 0, 0);
|
||||
sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(2);
|
||||
}
|
||||
if (dirty & I830_UPLOAD_TEX_PALETTE_N(3)) {
|
||||
i830EmitTexPalette(dev, sarea_priv->Palette2[1], 1, 0);
|
||||
sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(2);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* 1.3:
|
||||
*/
|
||||
if (dirty & I830_UPLOAD_STIPPLE) {
|
||||
i830EmitStippleVerified( dev,
|
||||
sarea_priv->StippleState);
|
||||
sarea_priv->dirty &= ~I830_UPLOAD_STIPPLE;
|
||||
}
|
||||
|
||||
if (dirty & I830_UPLOAD_TEX2) {
|
||||
i830EmitTexVerified( dev, sarea_priv->TexState2 );
|
||||
sarea_priv->dirty &= ~I830_UPLOAD_TEX2;
|
||||
}
|
||||
|
||||
if (dirty & I830_UPLOAD_TEX3) {
|
||||
i830EmitTexVerified( dev, sarea_priv->TexState3 );
|
||||
sarea_priv->dirty &= ~I830_UPLOAD_TEX3;
|
||||
}
|
||||
|
||||
|
||||
if (dirty & I830_UPLOAD_TEXBLEND2) {
|
||||
i830EmitTexBlendVerified(
|
||||
dev,
|
||||
sarea_priv->TexBlendState2,
|
||||
sarea_priv->TexBlendStateWordsUsed2);
|
||||
|
||||
sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND2;
|
||||
}
|
||||
|
||||
if (dirty & I830_UPLOAD_TEXBLEND3) {
|
||||
i830EmitTexBlendVerified(
|
||||
dev,
|
||||
sarea_priv->TexBlendState3,
|
||||
sarea_priv->TexBlendStateWordsUsed3);
|
||||
sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND3;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
* Performance monitoring functions
|
||||
*/
|
||||
|
||||
static void i830_fill_box( drm_device_t *dev,
|
||||
int x, int y, int w, int h,
|
||||
int r, int g, int b )
|
||||
{
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
u32 color;
|
||||
unsigned int BR13, CMD;
|
||||
RING_LOCALS;
|
||||
|
||||
BR13 = (0xF0 << 16) | (dev_priv->pitch * dev_priv->cpp) | (1<<24);
|
||||
CMD = XY_COLOR_BLT_CMD;
|
||||
x += dev_priv->sarea_priv->boxes[0].x1;
|
||||
y += dev_priv->sarea_priv->boxes[0].y1;
|
||||
|
||||
if (dev_priv->cpp == 4) {
|
||||
BR13 |= (1<<25);
|
||||
CMD |= (XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB);
|
||||
color = (((0xff) << 24) | (r << 16) | (g << 8) | b);
|
||||
} else {
|
||||
color = (((r & 0xf8) << 8) |
|
||||
((g & 0xfc) << 3) |
|
||||
((b & 0xf8) >> 3));
|
||||
}
|
||||
|
||||
BEGIN_LP_RING( 6 );
|
||||
OUT_RING( CMD );
|
||||
OUT_RING( BR13 );
|
||||
OUT_RING( (y << 16) | x );
|
||||
OUT_RING( ((y+h) << 16) | (x+w) );
|
||||
|
||||
if ( dev_priv->current_page == 1 ) {
|
||||
OUT_RING( dev_priv->front_offset );
|
||||
} else {
|
||||
OUT_RING( dev_priv->back_offset );
|
||||
}
|
||||
|
||||
OUT_RING( color );
|
||||
ADVANCE_LP_RING();
|
||||
}
|
||||
|
||||
static void i830_cp_performance_boxes( drm_device_t *dev )
|
||||
{
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
/* Purple box for page flipping
|
||||
*/
|
||||
if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_FLIP )
|
||||
i830_fill_box( dev, 4, 4, 8, 8, 255, 0, 255 );
|
||||
|
||||
/* Red box if we have to wait for idle at any point
|
||||
*/
|
||||
if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_WAIT )
|
||||
i830_fill_box( dev, 16, 4, 8, 8, 255, 0, 0 );
|
||||
|
||||
/* Blue box: lost context?
|
||||
*/
|
||||
if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_LOST_CONTEXT )
|
||||
i830_fill_box( dev, 28, 4, 8, 8, 0, 0, 255 );
|
||||
|
||||
/* Yellow box for texture swaps
|
||||
*/
|
||||
if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_TEXTURE_LOAD )
|
||||
i830_fill_box( dev, 40, 4, 8, 8, 255, 255, 0 );
|
||||
|
||||
/* Green box if hardware never idles (as far as we can tell)
|
||||
*/
|
||||
if ( !(dev_priv->sarea_priv->perf_boxes & I830_BOX_RING_EMPTY) )
|
||||
i830_fill_box( dev, 64, 4, 8, 8, 0, 255, 0 );
|
||||
|
||||
|
||||
/* Draw bars indicating number of buffers allocated
|
||||
* (not a great measure, easily confused)
|
||||
*/
|
||||
if (dev_priv->dma_used) {
|
||||
int bar = dev_priv->dma_used / 10240;
|
||||
if (bar > 100) bar = 100;
|
||||
if (bar < 1) bar = 1;
|
||||
i830_fill_box( dev, 4, 16, bar, 4, 196, 128, 128 );
|
||||
dev_priv->dma_used = 0;
|
||||
}
|
||||
|
||||
dev_priv->sarea_priv->perf_boxes = 0;
|
||||
}
|
||||
|
||||
static void i830_dma_dispatch_clear( drm_device_t *dev, int flags,
|
||||
|
@ -793,6 +935,15 @@ static void i830_dma_dispatch_clear( drm_device_t *dev, int flags,
|
|||
unsigned int BR13, CMD, D_CMD;
|
||||
RING_LOCALS;
|
||||
|
||||
|
||||
if ( dev_priv->current_page == 1 ) {
|
||||
unsigned int tmp = flags;
|
||||
|
||||
flags &= ~(I830_FRONT | I830_BACK);
|
||||
if ( tmp & I830_FRONT ) flags |= I830_BACK;
|
||||
if ( tmp & I830_BACK ) flags |= I830_FRONT;
|
||||
}
|
||||
|
||||
i830_kernel_lost_context(dev);
|
||||
|
||||
switch(cpp) {
|
||||
|
@ -872,13 +1023,17 @@ static void i830_dma_dispatch_swap( drm_device_t *dev )
|
|||
drm_clip_rect_t *pbox = sarea_priv->boxes;
|
||||
int pitch = dev_priv->pitch;
|
||||
int cpp = dev_priv->cpp;
|
||||
int ofs = dev_priv->back_offset;
|
||||
int i;
|
||||
unsigned int CMD, BR13;
|
||||
RING_LOCALS;
|
||||
|
||||
DRM_DEBUG("swapbuffers\n");
|
||||
|
||||
i830_kernel_lost_context(dev);
|
||||
|
||||
if (dev_priv->do_boxes)
|
||||
i830_cp_performance_boxes( dev );
|
||||
|
||||
switch(cpp) {
|
||||
case 2:
|
||||
BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24);
|
||||
|
@ -895,7 +1050,6 @@ static void i830_dma_dispatch_swap( drm_device_t *dev )
|
|||
break;
|
||||
}
|
||||
|
||||
i830_kernel_lost_context(dev);
|
||||
|
||||
if (nbox > I830_NR_SAREA_CLIPRECTS)
|
||||
nbox = I830_NR_SAREA_CLIPRECTS;
|
||||
|
@ -915,23 +1069,72 @@ static void i830_dma_dispatch_swap( drm_device_t *dev )
|
|||
BEGIN_LP_RING( 8 );
|
||||
OUT_RING( CMD );
|
||||
OUT_RING( BR13 );
|
||||
OUT_RING( (pbox->y1 << 16) | pbox->x1 );
|
||||
OUT_RING( (pbox->y2 << 16) | pbox->x2 );
|
||||
|
||||
OUT_RING( (pbox->y1 << 16) |
|
||||
pbox->x1 );
|
||||
OUT_RING( (pbox->y2 << 16) |
|
||||
pbox->x2 );
|
||||
|
||||
OUT_RING( dev_priv->front_offset );
|
||||
OUT_RING( (pbox->y1 << 16) |
|
||||
pbox->x1 );
|
||||
if (dev_priv->current_page == 0)
|
||||
OUT_RING( dev_priv->front_offset );
|
||||
else
|
||||
OUT_RING( dev_priv->back_offset );
|
||||
|
||||
OUT_RING( (pbox->y1 << 16) | pbox->x1 );
|
||||
OUT_RING( BR13 & 0xffff );
|
||||
OUT_RING( ofs );
|
||||
|
||||
if (dev_priv->current_page == 0)
|
||||
OUT_RING( dev_priv->back_offset );
|
||||
else
|
||||
OUT_RING( dev_priv->front_offset );
|
||||
|
||||
ADVANCE_LP_RING();
|
||||
}
|
||||
}
|
||||
|
||||
static void i830_dma_dispatch_flip( drm_device_t *dev )
|
||||
{
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
RING_LOCALS;
|
||||
|
||||
DRM_DEBUG( "%s: page=%d pfCurrentPage=%d\n",
|
||||
__FUNCTION__,
|
||||
dev_priv->current_page,
|
||||
dev_priv->sarea_priv->pf_current_page);
|
||||
|
||||
i830_kernel_lost_context(dev);
|
||||
|
||||
if (dev_priv->do_boxes) {
|
||||
dev_priv->sarea_priv->perf_boxes |= I830_BOX_FLIP;
|
||||
i830_cp_performance_boxes( dev );
|
||||
}
|
||||
|
||||
|
||||
BEGIN_LP_RING( 2 );
|
||||
OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE );
|
||||
OUT_RING( 0 );
|
||||
ADVANCE_LP_RING();
|
||||
|
||||
BEGIN_LP_RING( 6 );
|
||||
OUT_RING( CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP );
|
||||
OUT_RING( 0 );
|
||||
if ( dev_priv->current_page == 0 ) {
|
||||
OUT_RING( dev_priv->back_offset );
|
||||
dev_priv->current_page = 1;
|
||||
} else {
|
||||
OUT_RING( dev_priv->front_offset );
|
||||
dev_priv->current_page = 0;
|
||||
}
|
||||
OUT_RING(0);
|
||||
ADVANCE_LP_RING();
|
||||
|
||||
|
||||
BEGIN_LP_RING( 2 );
|
||||
OUT_RING( MI_WAIT_FOR_EVENT |
|
||||
MI_WAIT_FOR_PLANE_A_FLIP );
|
||||
OUT_RING( 0 );
|
||||
ADVANCE_LP_RING();
|
||||
|
||||
|
||||
dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
|
||||
}
|
||||
|
||||
static void i830_dma_dispatch_vertex(drm_device_t *dev,
|
||||
drm_buf_t *buf,
|
||||
|
@ -984,8 +1187,10 @@ static void i830_dma_dispatch_vertex(drm_device_t *dev,
|
|||
sarea_priv->vertex_prim |
|
||||
((used/4)-2));
|
||||
|
||||
vp[used/4] = MI_BATCH_BUFFER_END;
|
||||
used += 4;
|
||||
if (dev_priv->use_mi_batchbuffer_start) {
|
||||
vp[used/4] = MI_BATCH_BUFFER_END;
|
||||
used += 4;
|
||||
}
|
||||
|
||||
if (used & 4) {
|
||||
vp[used/4] = 0;
|
||||
|
@ -1008,11 +1213,21 @@ static void i830_dma_dispatch_vertex(drm_device_t *dev,
|
|||
ADVANCE_LP_RING();
|
||||
}
|
||||
|
||||
BEGIN_LP_RING(2);
|
||||
OUT_RING( MI_BATCH_BUFFER_START | (2<<6) );
|
||||
OUT_RING( start | MI_BATCH_NON_SECURE );
|
||||
ADVANCE_LP_RING();
|
||||
|
||||
if (dev_priv->use_mi_batchbuffer_start) {
|
||||
BEGIN_LP_RING(2);
|
||||
OUT_RING( MI_BATCH_BUFFER_START | (2<<6) );
|
||||
OUT_RING( start | MI_BATCH_NON_SECURE );
|
||||
ADVANCE_LP_RING();
|
||||
}
|
||||
else {
|
||||
BEGIN_LP_RING(4);
|
||||
OUT_RING( MI_BATCH_BUFFER );
|
||||
OUT_RING( start | MI_BATCH_NON_SECURE );
|
||||
OUT_RING( start + used - 4 );
|
||||
OUT_RING( 0 );
|
||||
ADVANCE_LP_RING();
|
||||
}
|
||||
|
||||
} while (++i < nbox);
|
||||
}
|
||||
|
||||
|
@ -1050,7 +1265,7 @@ void i830_dma_quiescent(drm_device_t *dev)
|
|||
OUT_RING( 0 );
|
||||
ADVANCE_LP_RING();
|
||||
|
||||
i830_wait_ring( dev, dev_priv->ring.Size - 8 );
|
||||
i830_wait_ring( dev, dev_priv->ring.Size - 8, __FUNCTION__ );
|
||||
}
|
||||
|
||||
static int i830_flush_queue(drm_device_t *dev)
|
||||
|
@ -1067,7 +1282,7 @@ static int i830_flush_queue(drm_device_t *dev)
|
|||
OUT_RING( 0 );
|
||||
ADVANCE_LP_RING();
|
||||
|
||||
i830_wait_ring( dev, dev_priv->ring.Size - 8 );
|
||||
i830_wait_ring( dev, dev_priv->ring.Size - 8, __FUNCTION__ );
|
||||
|
||||
for (i = 0; i < dma->buf_count; i++) {
|
||||
drm_buf_t *buf = dma->buflist[ i ];
|
||||
|
@ -1207,6 +1422,53 @@ int i830_swap_bufs(struct inode *inode, struct file *filp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Not sure why this isn't set all the time:
|
||||
*/
|
||||
static void i830_do_init_pageflip( drm_device_t *dev )
|
||||
{
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
dev_priv->page_flipping = 1;
|
||||
dev_priv->current_page = 0;
|
||||
dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
|
||||
}
|
||||
|
||||
int i830_do_cleanup_pageflip( drm_device_t *dev )
|
||||
{
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
if (dev_priv->current_page != 0)
|
||||
i830_dma_dispatch_flip( dev );
|
||||
|
||||
dev_priv->page_flipping = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i830_flip_bufs(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
|
||||
DRM_ERROR("i830_flip_buf called without lock held\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!dev_priv->page_flipping)
|
||||
i830_do_init_pageflip( dev );
|
||||
|
||||
i830_dma_dispatch_flip( dev );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i830_getage(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
|
@ -1270,3 +1532,66 @@ int i830_docopy(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int i830_getparam( struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg )
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
drm_i830_getparam_t param;
|
||||
int value;
|
||||
|
||||
if ( !dev_priv ) {
|
||||
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (copy_from_user(¶m, (drm_i830_getparam_t *)arg, sizeof(param) ))
|
||||
return -EFAULT;
|
||||
|
||||
switch( param.param ) {
|
||||
case I830_PARAM_IRQ_ACTIVE:
|
||||
value = dev->irq ? 1 : 0;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ( copy_to_user( param.value, &value, sizeof(int) ) ) {
|
||||
DRM_ERROR( "copy_to_user\n" );
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int i830_setparam( struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg )
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
drm_i830_setparam_t param;
|
||||
|
||||
if ( !dev_priv ) {
|
||||
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (copy_from_user(¶m, (drm_i830_setparam_t *)arg, sizeof(param) ))
|
||||
return -EFAULT;
|
||||
|
||||
switch( param.param ) {
|
||||
case I830_SETPARAM_USE_MI_BATCHBUFFER_START:
|
||||
dev_priv->use_mi_batchbuffer_start = param.value;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
/* WARNING: These defines must be the same as what the Xserver uses.
|
||||
* if you change them, you must change the defines in the Xserver.
|
||||
*
|
||||
* KW: Actually, you can't ever change them because doing so would
|
||||
* break backwards compatibility.
|
||||
*/
|
||||
|
||||
#ifndef _I830_DEFINES_
|
||||
|
@ -18,14 +21,12 @@
|
|||
#define I830_NR_TEX_REGIONS 64
|
||||
#define I830_LOG_MIN_TEX_REGION_SIZE 16
|
||||
|
||||
/* if defining I830_ENABLE_4_TEXTURES, do it in i830_3d_reg.h, too */
|
||||
#if !defined(I830_ENABLE_4_TEXTURES)
|
||||
/* KW: These aren't correct but someone set them to two and then
|
||||
* released the module. Now we can't change them as doing so would
|
||||
* break backwards compatibility.
|
||||
*/
|
||||
#define I830_TEXTURE_COUNT 2
|
||||
#define I830_TEXBLEND_COUNT 2 /* always same as TEXTURE_COUNT? */
|
||||
#else /* defined(I830_ENABLE_4_TEXTURES) */
|
||||
#define I830_TEXTURE_COUNT 4
|
||||
#define I830_TEXBLEND_COUNT 4 /* always same as TEXTURE_COUNT? */
|
||||
#endif /* I830_ENABLE_4_TEXTURES */
|
||||
#define I830_TEXBLEND_COUNT I830_TEXTURE_COUNT
|
||||
|
||||
#define I830_TEXBLEND_SIZE 12 /* (4 args + op) * 2 + COLOR_FACTOR */
|
||||
|
||||
|
@ -57,6 +58,7 @@
|
|||
#define I830_UPLOAD_TEXBLEND_MASK 0xf00000
|
||||
#define I830_UPLOAD_TEX_PALETTE_N(n) (0x1000000 << (n))
|
||||
#define I830_UPLOAD_TEX_PALETTE_SHARED 0x4000000
|
||||
#define I830_UPLOAD_STIPPLE 0x8000000
|
||||
|
||||
/* Indices into buf.Setup where various bits of state are mirrored per
|
||||
* context and per buffer. These can be fired at the card as a unit,
|
||||
|
@ -73,7 +75,6 @@
|
|||
*/
|
||||
|
||||
#define I830_DESTREG_CBUFADDR 0
|
||||
/* Invarient */
|
||||
#define I830_DESTREG_DBUFADDR 1
|
||||
#define I830_DESTREG_DV0 2
|
||||
#define I830_DESTREG_DV1 3
|
||||
|
@ -109,6 +110,13 @@
|
|||
#define I830_CTXREG_MCSB1 16
|
||||
#define I830_CTX_SETUP_SIZE 17
|
||||
|
||||
/* 1.3: Stipple state
|
||||
*/
|
||||
#define I830_STPREG_ST0 0
|
||||
#define I830_STPREG_ST1 1
|
||||
#define I830_STP_SETUP_SIZE 2
|
||||
|
||||
|
||||
/* Texture state (per tex unit)
|
||||
*/
|
||||
|
||||
|
@ -124,6 +132,18 @@
|
|||
#define I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS */
|
||||
#define I830_TEX_SETUP_SIZE 10
|
||||
|
||||
#define I830_TEXREG_TM0LI 0 /* load immediate 2 texture map n */
|
||||
#define I830_TEXREG_TM0S0 1
|
||||
#define I830_TEXREG_TM0S1 2
|
||||
#define I830_TEXREG_TM0S2 3
|
||||
#define I830_TEXREG_TM0S3 4
|
||||
#define I830_TEXREG_TM0S4 5
|
||||
#define I830_TEXREG_NOP0 6 /* noop */
|
||||
#define I830_TEXREG_NOP1 7 /* noop */
|
||||
#define I830_TEXREG_NOP2 8 /* noop */
|
||||
#define __I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS -- shared */
|
||||
#define __I830_TEX_SETUP_SIZE 10
|
||||
|
||||
#define I830_FRONT 0x1
|
||||
#define I830_BACK 0x2
|
||||
#define I830_DEPTH 0x4
|
||||
|
@ -199,8 +219,35 @@ typedef struct _drm_i830_sarea {
|
|||
int ctxOwner; /* last context to upload state */
|
||||
|
||||
int vertex_prim;
|
||||
|
||||
int pf_enabled; /* is pageflipping allowed? */
|
||||
int pf_active;
|
||||
int pf_current_page; /* which buffer is being displayed? */
|
||||
|
||||
int perf_boxes; /* performance boxes to be displayed */
|
||||
|
||||
/* Here's the state for texunits 2,3:
|
||||
*/
|
||||
unsigned int TexState2[I830_TEX_SETUP_SIZE];
|
||||
unsigned int TexBlendState2[I830_TEXBLEND_SIZE];
|
||||
unsigned int TexBlendStateWordsUsed2;
|
||||
|
||||
unsigned int TexState3[I830_TEX_SETUP_SIZE];
|
||||
unsigned int TexBlendState3[I830_TEXBLEND_SIZE];
|
||||
unsigned int TexBlendStateWordsUsed3;
|
||||
|
||||
unsigned int StippleState[I830_STP_SETUP_SIZE];
|
||||
} drm_i830_sarea_t;
|
||||
|
||||
/* Flags for perf_boxes
|
||||
*/
|
||||
#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */
|
||||
#define I830_BOX_FLIP 0x2 /* populated by kernel */
|
||||
#define I830_BOX_WAIT 0x4 /* populated by kernel & client */
|
||||
#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */
|
||||
#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */
|
||||
|
||||
|
||||
/* I830 specific ioctls
|
||||
* The device specific ioctl range is 0x40 to 0x79.
|
||||
*/
|
||||
|
@ -213,6 +260,11 @@ typedef struct _drm_i830_sarea {
|
|||
#define DRM_IOCTL_I830_SWAP DRM_IO ( 0x46)
|
||||
#define DRM_IOCTL_I830_COPY DRM_IOW( 0x47, drm_i830_copy_t)
|
||||
#define DRM_IOCTL_I830_DOCOPY DRM_IO ( 0x48)
|
||||
#define DRM_IOCTL_I830_FLIP DRM_IO ( 0x49)
|
||||
#define DRM_IOCTL_I830_IRQ_EMIT DRM_IOWR(0x4a, drm_i830_irq_emit_t)
|
||||
#define DRM_IOCTL_I830_IRQ_WAIT DRM_IOW( 0x4b, drm_i830_irq_wait_t)
|
||||
#define DRM_IOCTL_I830_GETPARAM DRM_IOWR(0x4c, drm_i830_getparam_t)
|
||||
#define DRM_IOCTL_I830_SETPARAM DRM_IOWR(0x4d, drm_i830_setparam_t)
|
||||
|
||||
typedef struct _drm_i830_clear {
|
||||
int clear_color;
|
||||
|
@ -248,4 +300,36 @@ typedef struct drm_i830_dma {
|
|||
int granted;
|
||||
} drm_i830_dma_t;
|
||||
|
||||
|
||||
/* 1.3: Userspace can request & wait on irq's:
|
||||
*/
|
||||
typedef struct drm_i830_irq_emit {
|
||||
int *irq_seq;
|
||||
} drm_i830_irq_emit_t;
|
||||
|
||||
typedef struct drm_i830_irq_wait {
|
||||
int irq_seq;
|
||||
} drm_i830_irq_wait_t;
|
||||
|
||||
|
||||
/* 1.3: New ioctl to query kernel params:
|
||||
*/
|
||||
#define I830_PARAM_IRQ_ACTIVE 1
|
||||
|
||||
typedef struct drm_i830_getparam {
|
||||
int param;
|
||||
int *value;
|
||||
} drm_i830_getparam_t;
|
||||
|
||||
|
||||
/* 1.3: New ioctl to set kernel params:
|
||||
*/
|
||||
#define I830_SETPARAM_USE_MI_BATCHBUFFER_START 1
|
||||
|
||||
typedef struct drm_i830_setparam {
|
||||
int param;
|
||||
int value;
|
||||
} drm_i830_setparam_t;
|
||||
|
||||
|
||||
#endif /* _I830_DRM_H_ */
|
||||
|
|
|
@ -78,6 +78,19 @@ typedef struct drm_i830_private {
|
|||
int back_pitch;
|
||||
int depth_pitch;
|
||||
unsigned int cpp;
|
||||
|
||||
int do_boxes;
|
||||
int dma_used;
|
||||
|
||||
int current_page;
|
||||
int page_flipping;
|
||||
|
||||
wait_queue_head_t irq_queue;
|
||||
atomic_t irq_received;
|
||||
atomic_t irq_emitted;
|
||||
|
||||
int use_mi_batchbuffer_start;
|
||||
|
||||
} drm_i830_private_t;
|
||||
|
||||
/* i830_dma.c */
|
||||
|
@ -108,6 +121,23 @@ extern int i830_swap_bufs(struct inode *inode, struct file *filp,
|
|||
extern int i830_clear_bufs(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
|
||||
extern int i830_flip_bufs(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
|
||||
extern int i830_getparam( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
|
||||
extern int i830_setparam( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
|
||||
/* i830_irq.c */
|
||||
extern int i830_irq_emit( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
extern int i830_irq_wait( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
extern int i830_wait_irq(drm_device_t *dev, int irq_nr);
|
||||
extern int i830_emit_irq(drm_device_t *dev);
|
||||
|
||||
|
||||
#define I830_BASE(reg) ((unsigned long) \
|
||||
dev_priv->mmio_map->handle)
|
||||
|
@ -119,12 +149,53 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp,
|
|||
#define I830_READ16(reg) I830_DEREF16(reg)
|
||||
#define I830_WRITE16(reg,val) do { I830_DEREF16(reg) = val; } while (0)
|
||||
|
||||
|
||||
|
||||
#define I830_VERBOSE 0
|
||||
|
||||
#define RING_LOCALS unsigned int outring, ringmask, outcount; \
|
||||
volatile char *virt;
|
||||
|
||||
#define BEGIN_LP_RING(n) do { \
|
||||
if (I830_VERBOSE) \
|
||||
printk("BEGIN_LP_RING(%d) in %s\n", \
|
||||
n, __FUNCTION__); \
|
||||
if (dev_priv->ring.space < n*4) \
|
||||
i830_wait_ring(dev, n*4, __FUNCTION__); \
|
||||
outcount = 0; \
|
||||
outring = dev_priv->ring.tail; \
|
||||
ringmask = dev_priv->ring.tail_mask; \
|
||||
virt = dev_priv->ring.virtual_start; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define OUT_RING(n) do { \
|
||||
if (I830_VERBOSE) printk(" OUT_RING %x\n", (int)(n)); \
|
||||
*(volatile unsigned int *)(virt + outring) = n; \
|
||||
outcount++; \
|
||||
outring += 4; \
|
||||
outring &= ringmask; \
|
||||
} while (0)
|
||||
|
||||
#define ADVANCE_LP_RING() do { \
|
||||
if (I830_VERBOSE) printk("ADVANCE_LP_RING %x\n", outring); \
|
||||
dev_priv->ring.tail = outring; \
|
||||
dev_priv->ring.space -= outcount * 4; \
|
||||
I830_WRITE(LP_RING + RING_TAIL, outring); \
|
||||
} while(0)
|
||||
|
||||
extern int i830_wait_ring(drm_device_t *dev, int n, const char *caller);
|
||||
|
||||
|
||||
#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23))
|
||||
#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23))
|
||||
#define CMD_REPORT_HEAD (7<<23)
|
||||
#define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1)
|
||||
#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1)
|
||||
|
||||
#define STATE3D_LOAD_STATE_IMMEDIATE_2 ((0x3<<29)|(0x1d<<24)|(0x03<<16))
|
||||
#define LOAD_TEXTURE_MAP0 (1<<11)
|
||||
|
||||
#define INST_PARSER_CLIENT 0x00000000
|
||||
#define INST_OP_FLUSH 0x02000000
|
||||
#define INST_FLUSH_MAP_CACHE 0x00000001
|
||||
|
@ -140,6 +211,9 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp,
|
|||
#define I830REG_INT_MASK_R 0x020a8
|
||||
#define I830REG_INT_ENABLE_R 0x020a0
|
||||
|
||||
#define I830_IRQ_RESERVED ((1<<13)|(3<<2))
|
||||
|
||||
|
||||
#define LP_RING 0x2030
|
||||
#define HP_RING 0x2040
|
||||
#define RING_TAIL 0x00
|
||||
|
@ -182,6 +256,9 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp,
|
|||
|
||||
#define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
|
||||
|
||||
#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2)
|
||||
#define ASYNC_FLIP (1<<22)
|
||||
|
||||
#define CMD_3D (0x3<<29)
|
||||
#define STATE3D_CONST_BLEND_COLOR_CMD (CMD_3D|(0x1d<<24)|(0x88<<16))
|
||||
#define STATE3D_MAP_COORD_SETBIND_CMD (CMD_3D|(0x1d<<24)|(0x02<<16))
|
||||
|
@ -213,6 +290,11 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp,
|
|||
#define MI_BATCH_BUFFER_END (0xA<<23)
|
||||
#define MI_BATCH_NON_SECURE (1)
|
||||
|
||||
#define MI_WAIT_FOR_EVENT ((0x3<<23))
|
||||
#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
|
||||
#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
|
||||
|
||||
#define MI_LOAD_SCAN_LINES_INCL ((0x12<<23))
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ tdfx-objs := tdfx_drv.o
|
|||
r128-objs := r128_drv.o r128_cce.o r128_irq.o r128_state.o
|
||||
mga-objs := mga_drv.o mga_dma.o mga_irq.o mga_state.o mga_warp.o
|
||||
i810-objs := i810_drv.o i810_dma.o
|
||||
i830-objs := i830_drv.o i830_dma.o
|
||||
i830-objs := i830_drv.o i830_dma.o i830_irq.o
|
||||
radeon-objs := radeon_drv.o radeon_cp.o radeon_irq.o radeon_mem.o radeon_state.o
|
||||
ffb-objs := ffb_drv.o ffb_context.o
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
# make TREE=/usr/my-kernel-tree/include
|
||||
#
|
||||
|
||||
SHELL=/bin/sh
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
# *** Setup
|
||||
|
@ -44,7 +46,8 @@ LIBS =
|
|||
DRMTEMPLATES = drm_auth.h drm_bufs.h drm_context.h drm_dma.h drm_drawable.h \
|
||||
drm_drv.h drm_fops.h drm_init.h drm_ioctl.h drm_lists.h \
|
||||
drm_lock.h drm_memory.h drm_proc.h drm_stub.h drm_vm.h
|
||||
DRMHEADERS = drm.h drmP.h drm_sarea.h
|
||||
DRMSHARED = drm_sarea.h
|
||||
DRMHEADERS = drm.h drmP.h $(DRMSHARED)
|
||||
|
||||
GAMMAOBJS = gamma_drv.o gamma_dma.o
|
||||
GAMMAHEADERS = gamma_drv.h $(DRMHEADERS) $(DRMTEMPLATES)
|
||||
|
@ -54,10 +57,14 @@ TDFXHEADERS = tdfx.h $(DRMHEADERS) $(DRMTEMPLATES)
|
|||
|
||||
R128OBJS = r128_drv.o r128_cce.o r128_state.o r128_irq.o
|
||||
R128HEADERS = r128.h r128_drv.h r128_drm.h $(DRMHEADERS) $(DRMTEMPLATES)
|
||||
R128SHARED = r128.h r128_drv.h r128_drm.h r128_cce.c r128_state.c r128_irq.c
|
||||
|
||||
RADEONOBJS = radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o
|
||||
RADEONOBJS = radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o \
|
||||
radeon_irq.o
|
||||
RADEONHEADERS = radeon.h radeon_drv.h radeon_drm.h $(DRMHEADERS) \
|
||||
$(DRMTEMPLATES)
|
||||
RADEONSHARED = radeon.h radeon_drv.h radeon_drm.h radeon_cp.c radeon_irq.c \
|
||||
radeon_mem.c radeon_state.c
|
||||
|
||||
INC = /usr/include
|
||||
|
||||
|
@ -160,11 +167,13 @@ endif
|
|||
|
||||
MGAOBJS = mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o
|
||||
MGAHEADERS = mga.h mga_drv.h mga_drm.h $(DRMHEADERS) $(DRMTEMPLATES)
|
||||
MGASHARED = mga.h mga_dma.c mga_drm.h mga_drv.h mga_state.c \
|
||||
mga_ucode.h mga_warp.c
|
||||
|
||||
I810OBJS = i810_drv.o i810_dma.o
|
||||
I810HEADERS = i810.h i810_drv.h i810_drm.h $(DRMHEADERS) $(DRMTEMPLATES)
|
||||
|
||||
I830OBJS = i830_drv.o i830_dma.o
|
||||
I830OBJS = i830_drv.o i830_dma.o i830_irq.o
|
||||
I830HEADERS = i830.h i830_drv.h i830_drm.h $(DRMHEADERS) $(DRMTEMPLATES)
|
||||
|
||||
endif
|
||||
|
@ -172,6 +181,10 @@ endif
|
|||
ifeq ($(MACHINE),alpha)
|
||||
MODCFLAGS+= -ffixed-8 -mno-fp-regs -mcpu=ev56 -Wa,-mev6
|
||||
endif
|
||||
ifeq ($(MACHINE),x86_64)
|
||||
MODCFLAGS+= -mcmodel=kernel
|
||||
endif
|
||||
|
||||
|
||||
MODS += sis.o
|
||||
|
||||
|
@ -208,6 +221,15 @@ endif
|
|||
|
||||
# **** End of configuration
|
||||
|
||||
# Link in shared headers if needed
|
||||
|
||||
SHAREDSRC = $(DRMSHARED) $(MGASHARED) $(R128SHARED) $(RADEONSHARED)
|
||||
SHAREDDIR = ../../../shared/drm/kernel
|
||||
|
||||
$(SHAREDSRC):
|
||||
@if [ ! -r $@ ]; then (rm -f $@; set -x; ln -s $(SHAREDDIR)/$@ .); fi
|
||||
|
||||
|
||||
dristat: dristat.c
|
||||
$(CC) $(PRGCFLAGS) $< -o $@
|
||||
|
||||
|
@ -280,3 +302,7 @@ endif
|
|||
|
||||
clean cleandir::
|
||||
rm -f *.o *.a *~ core
|
||||
@for i in $(SHAREDSRC); do \
|
||||
if [ -L $$i ]; then (set -x; rm -f $$i); fi; \
|
||||
done
|
||||
|
||||
|
|
|
@ -166,6 +166,12 @@
|
|||
#define pte_unmap(pte)
|
||||
#endif
|
||||
|
||||
#ifndef list_for_each_safe
|
||||
#define list_for_each_safe(pos, n, head) \
|
||||
for (pos = (head)->next, n = pos->next; pos != (head); \
|
||||
pos = n, n = pos->next)
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19)
|
||||
static inline struct page * vmalloc_to_page(void * vmalloc_addr)
|
||||
{
|
||||
|
|
|
@ -267,12 +267,12 @@ drm_agp_head_t *DRM(agp_init)(void)
|
|||
head->cant_use_aperture = head->agp_info.cant_use_aperture;
|
||||
head->page_mask = head->agp_info.page_mask;
|
||||
#endif
|
||||
|
||||
DRM_DEBUG("AGP %d.%d, aperture @ 0x%08lx %ZuMB\n",
|
||||
head->agp_info.version.major,
|
||||
head->agp_info.version.minor,
|
||||
head->agp_info.aper_base,
|
||||
head->agp_info.aper_size);
|
||||
|
||||
DRM_INFO("AGP %d.%d aperture @ 0x%08lx %ZuMB\n",
|
||||
head->agp_info.version.major,
|
||||
head->agp_info.version.minor,
|
||||
head->agp_info.aper_base,
|
||||
head->agp_info.aper_size);
|
||||
}
|
||||
return head;
|
||||
}
|
||||
|
|
|
@ -714,7 +714,7 @@ void DRM(vbl_send_signals)( drm_device_t *dev )
|
|||
|
||||
list_del( (struct list_head *) vbl_sig );
|
||||
|
||||
DRM_FREE(vbl_sig,sizeof(*vbl_sig));
|
||||
DRM_FREE( vbl_sig );
|
||||
|
||||
dev->vbl_pending--;
|
||||
}
|
||||
|
|
|
@ -765,8 +765,8 @@ int DRM(release)( struct inode *inode, struct file *filp )
|
|||
* Begin inline drm_release
|
||||
*/
|
||||
|
||||
DRM_DEBUG( "pid = %d, device = 0x%x, open_count = %d\n",
|
||||
current->pid, dev->device, dev->open_count );
|
||||
DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n",
|
||||
current->pid, (long)dev->device, dev->open_count );
|
||||
|
||||
if ( dev->lock.hw_lock &&
|
||||
_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
|
||||
|
@ -891,8 +891,9 @@ int DRM(ioctl)( struct inode *inode, struct file *filp,
|
|||
atomic_inc( &dev->counts[_DRM_STAT_IOCTLS] );
|
||||
++priv->ioctl_count;
|
||||
|
||||
DRM_DEBUG( "pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%x, auth=%d\n",
|
||||
current->pid, cmd, nr, dev->device, priv->authenticated );
|
||||
DRM_DEBUG( "pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
|
||||
current->pid, cmd, nr, (long)dev->device,
|
||||
priv->authenticated );
|
||||
|
||||
if ( nr >= DRIVER_IOCTL_COUNT ) {
|
||||
retcode = -EINVAL;
|
||||
|
|
|
@ -95,8 +95,8 @@ int DRM(flush)(struct file *filp)
|
|||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
|
||||
DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d\n",
|
||||
current->pid, dev->device, dev->open_count);
|
||||
DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
|
||||
current->pid, (long)dev->device, dev->open_count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ int DRM(fasync)(int fd, struct file *filp, int on)
|
|||
drm_device_t *dev = priv->dev;
|
||||
int retcode;
|
||||
|
||||
DRM_DEBUG("fd = %d, device = 0x%x\n", fd, dev->device);
|
||||
DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, (long)dev->device);
|
||||
retcode = fasync_helper(fd, filp, on, &dev->buf_async);
|
||||
if (retcode < 0) return retcode;
|
||||
return 0;
|
||||
|
|
|
@ -41,6 +41,28 @@ int DRM(irq_busid)(struct inode *inode, struct file *filp,
|
|||
|
||||
if (copy_from_user(&p, (drm_irq_busid_t *)arg, sizeof(p)))
|
||||
return -EFAULT;
|
||||
#ifdef __alpha__
|
||||
{
|
||||
int domain = p.busnum >> 8;
|
||||
p.busnum &= 0xff;
|
||||
|
||||
/*
|
||||
* Find the hose the device is on (the domain number is the
|
||||
* hose index) and offset the bus by the root bus of that
|
||||
* hose.
|
||||
*/
|
||||
for(dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,NULL);
|
||||
dev;
|
||||
dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,dev)) {
|
||||
struct pci_controller *hose = dev->sysdata;
|
||||
|
||||
if (hose->index == domain) {
|
||||
p.busnum += hose->bus->number;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
dev = pci_find_slot(p.busnum, PCI_DEVFN(p.devnum, p.funcnum));
|
||||
if (!dev) {
|
||||
DRM_ERROR("pci_find_slot failed for %d:%d:%d\n",
|
||||
|
@ -113,7 +135,7 @@ int DRM(setunique)(struct inode *inode, struct file *filp,
|
|||
|
||||
do {
|
||||
struct pci_dev *pci_dev;
|
||||
int b, d, f;
|
||||
int domain, b, d, f;
|
||||
char *p;
|
||||
|
||||
for(p = dev->unique; p && *p && *p != ':'; p++);
|
||||
|
@ -125,6 +147,27 @@ int DRM(setunique)(struct inode *inode, struct file *filp,
|
|||
f = (int)simple_strtoul(p+1, &p, 10);
|
||||
if (*p) break;
|
||||
|
||||
domain = b >> 8;
|
||||
b &= 0xff;
|
||||
|
||||
#ifdef __alpha__
|
||||
/*
|
||||
* Find the hose the device is on (the domain number is the
|
||||
* hose index) and offset the bus by the root bus of that
|
||||
* hose.
|
||||
*/
|
||||
for(pci_dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,NULL);
|
||||
pci_dev;
|
||||
pci_dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,pci_dev)) {
|
||||
struct pci_controller *hose = pci_dev->sysdata;
|
||||
|
||||
if (hose->index == domain) {
|
||||
b += hose->bus->number;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
pci_dev = pci_find_slot(b, PCI_DEVFN(d,f));
|
||||
if (pci_dev) {
|
||||
dev->pdev = pci_dev;
|
||||
|
|
|
@ -148,10 +148,10 @@ static int DRM(name_info)(char *buf, char **start, off_t offset, int request,
|
|||
*eof = 0;
|
||||
|
||||
if (dev->unique) {
|
||||
DRM_PROC_PRINT("%s 0x%x %s\n",
|
||||
dev->name, dev->device, dev->unique);
|
||||
DRM_PROC_PRINT("%s 0x%lx %s\n",
|
||||
dev->name, (long)dev->device, dev->unique);
|
||||
} else {
|
||||
DRM_PROC_PRINT("%s 0x%x\n", dev->name, dev->device);
|
||||
DRM_PROC_PRINT("%s 0x%lx\n", dev->name, (long)dev->device);
|
||||
}
|
||||
|
||||
if (len > request + offset) return request;
|
||||
|
|
|
@ -522,11 +522,11 @@ static int gamma_dma_send_buffers(drm_device_t *dev, drm_dma_t *d)
|
|||
}
|
||||
}
|
||||
if (retcode) {
|
||||
DRM_ERROR("ctx%d w%d p%d c%d i%d l%d %d/%d\n",
|
||||
DRM_ERROR("ctx%d w%d p%d c%ld i%d l%d %d/%d\n",
|
||||
d->context,
|
||||
last_buf->waiting,
|
||||
last_buf->pending,
|
||||
DRM_WAITCOUNT(dev, d->context),
|
||||
(long)DRM_WAITCOUNT(dev, d->context),
|
||||
last_buf->idx,
|
||||
last_buf->list,
|
||||
last_buf->pid,
|
||||
|
@ -592,7 +592,7 @@ static int gamma_do_init_dma( drm_device_t *dev, drm_gamma_init_t *init )
|
|||
drm_buf_t *buf;
|
||||
int i;
|
||||
struct list_head *list;
|
||||
unsigned int *pgt;
|
||||
unsigned long *pgt;
|
||||
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
|
@ -645,7 +645,7 @@ static int gamma_do_init_dma( drm_device_t *dev, drm_gamma_init_t *init )
|
|||
|
||||
for (i = 0; i < GLINT_DRI_BUF_COUNT; i++) {
|
||||
buf = dma->buflist[i];
|
||||
*pgt = (unsigned int)buf->address + 0x07;
|
||||
*pgt = (unsigned long)buf->address + 0x07;
|
||||
pgt++;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,30 +53,10 @@
|
|||
#define I810_BUF_UNMAPPED 0
|
||||
#define I810_BUF_MAPPED 1
|
||||
|
||||
#define RING_LOCALS unsigned int outring, ringmask; volatile char *virt;
|
||||
|
||||
#define BEGIN_LP_RING(n) do { \
|
||||
if (0) DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", n, __FUNCTION__); \
|
||||
if (dev_priv->ring.space < n*4) \
|
||||
i810_wait_ring(dev, n*4); \
|
||||
dev_priv->ring.space -= n*4; \
|
||||
outring = dev_priv->ring.tail; \
|
||||
ringmask = dev_priv->ring.tail_mask; \
|
||||
virt = dev_priv->ring.virtual_start; \
|
||||
} while (0)
|
||||
|
||||
#define ADVANCE_LP_RING() do { \
|
||||
if (0) DRM_DEBUG("ADVANCE_LP_RING\n"); \
|
||||
dev_priv->ring.tail = outring; \
|
||||
I810_WRITE(LP_RING + RING_TAIL, outring); \
|
||||
} while(0)
|
||||
|
||||
#define OUT_RING(n) do { \
|
||||
if (0) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \
|
||||
*(volatile unsigned int *)(virt + outring) = n; \
|
||||
outring += 4; \
|
||||
outring &= ringmask; \
|
||||
} while (0)
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,2)
|
||||
#define down_write down
|
||||
#define up_write up
|
||||
#endif
|
||||
|
||||
static inline void i810_print_status_page(drm_device_t *dev)
|
||||
{
|
||||
|
@ -185,11 +165,7 @@ static int i810_map_buffer(drm_buf_t *buf, struct file *filp)
|
|||
|
||||
if(buf_priv->currently_mapped == I810_BUF_MAPPED) return -EINVAL;
|
||||
|
||||
#if LINUX_VERSION_CODE <= 0x020402
|
||||
down( ¤t->mm->mmap_sem );
|
||||
#else
|
||||
down_write( ¤t->mm->mmap_sem );
|
||||
#endif
|
||||
old_fops = filp->f_op;
|
||||
filp->f_op = &i810_buffer_fops;
|
||||
dev_priv->mmap_buffer = buf;
|
||||
|
@ -201,15 +177,12 @@ static int i810_map_buffer(drm_buf_t *buf, struct file *filp)
|
|||
filp->f_op = old_fops;
|
||||
if ((unsigned long)buf_priv->virtual > -1024UL) {
|
||||
/* Real error */
|
||||
DRM_DEBUG("mmap error\n");
|
||||
DRM_ERROR("mmap error\n");
|
||||
retcode = (signed int)buf_priv->virtual;
|
||||
buf_priv->virtual = 0;
|
||||
}
|
||||
#if LINUX_VERSION_CODE <= 0x020402
|
||||
up( ¤t->mm->mmap_sem );
|
||||
#else
|
||||
up_write( ¤t->mm->mmap_sem );
|
||||
#endif
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
|
@ -220,19 +193,13 @@ static int i810_unmap_buffer(drm_buf_t *buf)
|
|||
|
||||
if(buf_priv->currently_mapped != I810_BUF_MAPPED)
|
||||
return -EINVAL;
|
||||
#if LINUX_VERSION_CODE <= 0x020402
|
||||
down( ¤t->mm->mmap_sem );
|
||||
#else
|
||||
down_write( ¤t->mm->mmap_sem );
|
||||
#endif
|
||||
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
retcode = DO_MUNMAP(current->mm,
|
||||
(unsigned long)buf_priv->virtual,
|
||||
(size_t) buf->total);
|
||||
#if LINUX_VERSION_CODE <= 0x020402
|
||||
up( ¤t->mm->mmap_sem );
|
||||
#else
|
||||
up_write( ¤t->mm->mmap_sem );
|
||||
#endif
|
||||
up_write(¤t->mm->mmap_sem);
|
||||
|
||||
buf_priv->currently_mapped = I810_BUF_UNMAPPED;
|
||||
buf_priv->virtual = 0;
|
||||
|
||||
|
@ -257,7 +224,7 @@ static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d,
|
|||
retcode = i810_map_buffer(buf, filp);
|
||||
if(retcode) {
|
||||
i810_freelist_put(dev, buf);
|
||||
DRM_DEBUG("mapbuf failed, retcode %d\n", retcode);
|
||||
DRM_ERROR("mapbuf failed, retcode %d\n", retcode);
|
||||
return retcode;
|
||||
}
|
||||
buf->pid = priv->pid;
|
||||
|
@ -321,7 +288,7 @@ static int i810_wait_ring(drm_device_t *dev, int n)
|
|||
end = jiffies + (HZ*3);
|
||||
|
||||
iters++;
|
||||
if((signed)(end - jiffies) <= 0) {
|
||||
if(time_before(end, jiffies)) {
|
||||
DRM_ERROR("space: %d wanted %d\n", ring->space, n);
|
||||
DRM_ERROR("lockup\n");
|
||||
goto out_wait_ring;
|
||||
|
|
|
@ -136,6 +136,33 @@ int i810_clear_bufs(struct inode *inode, struct file *filp,
|
|||
#define I810_READ16(reg) I810_DEREF16(reg)
|
||||
#define I810_WRITE16(reg,val) do { I810_DEREF16(reg) = val; } while (0)
|
||||
|
||||
#define I810_VERBOSE 0
|
||||
#define RING_LOCALS unsigned int outring, ringmask; \
|
||||
volatile char *virt;
|
||||
|
||||
#define BEGIN_LP_RING(n) do { \
|
||||
if (I810_VERBOSE) \
|
||||
DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", n, __FUNCTION__); \
|
||||
if (dev_priv->ring.space < n*4) \
|
||||
i810_wait_ring(dev, n*4); \
|
||||
dev_priv->ring.space -= n*4; \
|
||||
outring = dev_priv->ring.tail; \
|
||||
ringmask = dev_priv->ring.tail_mask; \
|
||||
virt = dev_priv->ring.virtual_start; \
|
||||
} while (0)
|
||||
|
||||
#define ADVANCE_LP_RING() do { \
|
||||
if (I810_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING\n"); \
|
||||
dev_priv->ring.tail = outring; \
|
||||
I810_WRITE(LP_RING + RING_TAIL, outring); \
|
||||
} while(0)
|
||||
|
||||
#define OUT_RING(n) do { \
|
||||
if (I810_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \
|
||||
*(volatile unsigned int *)(virt + outring) = n; \
|
||||
outring += 4; \
|
||||
outring &= ringmask; \
|
||||
} while (0)
|
||||
|
||||
#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23))
|
||||
#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23))
|
||||
|
@ -198,6 +225,7 @@ int i810_clear_bufs(struct inode *inode, struct file *filp,
|
|||
|
||||
#define CMD_OP_Z_BUFFER_INFO ((0x0<<29)|(0x16<<23))
|
||||
#define CMD_OP_DESTBUFFER_INFO ((0x0<<29)|(0x15<<23))
|
||||
#define CMD_OP_FRONTBUFFER_INFO ((0x0<<29)|(0x14<<23))
|
||||
|
||||
#define BR00_BITBLT_CLIENT 0x40000000
|
||||
#define BR00_OP_COLOR_BLT 0x10000000
|
||||
|
|
80
linux/i830.h
80
linux/i830.h
|
@ -45,22 +45,37 @@
|
|||
|
||||
#define DRIVER_NAME "i830"
|
||||
#define DRIVER_DESC "Intel 830M"
|
||||
#define DRIVER_DATE "20020828"
|
||||
#define DRIVER_DATE "20021108"
|
||||
|
||||
/* Interface history:
|
||||
*
|
||||
* 1.1: Original.
|
||||
* 1.2: ?
|
||||
* 1.3: New irq emit/wait ioctls.
|
||||
* New pageflip ioctl.
|
||||
* New getparam ioctl.
|
||||
* State for texunits 3&4 in sarea.
|
||||
* New (alternative) layout for texture state.
|
||||
*/
|
||||
#define DRIVER_MAJOR 1
|
||||
#define DRIVER_MINOR 2
|
||||
#define DRIVER_PATCHLEVEL 1
|
||||
#define DRIVER_MINOR 3
|
||||
#define DRIVER_PATCHLEVEL 2
|
||||
|
||||
#define DRIVER_IOCTLS \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I830_INIT)] = { i830_dma_init, 1, 1 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I830_VERTEX)] = { i830_dma_vertex, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I830_CLEAR)] = { i830_clear_bufs, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I830_FLUSH)] = { i830_flush_ioctl, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I830_GETAGE)] = { i830_getage, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I830_VERTEX)] = { i830_dma_vertex, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I830_CLEAR)] = { i830_clear_bufs, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I830_FLUSH)] = { i830_flush_ioctl, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I830_GETAGE)] = { i830_getage, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I830_GETBUF)] = { i830_getbuf, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I830_SWAP)] = { i830_swap_bufs, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I830_COPY)] = { i830_copybuf, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I830_DOCOPY)] = { i830_docopy, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I830_SWAP)] = { i830_swap_bufs, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I830_COPY)] = { i830_copybuf, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I830_DOCOPY)] = { i830_docopy, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I830_FLIP)] = { i830_flip_bufs, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I830_IRQ_EMIT)] = { i830_irq_emit, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I830_IRQ_WAIT)] = { i830_irq_wait, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I830_GETPARAM)] = { i830_getparam, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I830_SETPARAM)] = { i830_setparam, 1, 0 }
|
||||
|
||||
#define __HAVE_COUNTERS 4
|
||||
#define __HAVE_COUNTER6 _DRM_STAT_IRQ
|
||||
|
@ -87,10 +102,49 @@
|
|||
i830_dma_quiescent( dev ); \
|
||||
} while (0)
|
||||
|
||||
/* Don't need an irq any more. The template code will make sure that
|
||||
* a noop stub is generated for compatibility.
|
||||
|
||||
/* Driver will work either way: IRQ's save cpu time when waiting for
|
||||
* the card, but are subject to subtle interactions between bios,
|
||||
* hardware and the driver.
|
||||
*/
|
||||
#define __HAVE_DMA_IRQ 0
|
||||
#define USE_IRQS 0
|
||||
|
||||
|
||||
#if USE_IRQS
|
||||
#define __HAVE_DMA_IRQ 1
|
||||
#define __HAVE_SHARED_IRQ 1
|
||||
|
||||
#define DRIVER_PREINSTALL() do { \
|
||||
drm_i830_private_t *dev_priv = \
|
||||
(drm_i830_private_t *)dev->dev_private; \
|
||||
\
|
||||
I830_WRITE16( I830REG_HWSTAM, 0xffff ); \
|
||||
I830_WRITE16( I830REG_INT_MASK_R, 0x0 ); \
|
||||
I830_WRITE16( I830REG_INT_ENABLE_R, 0x0 ); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define DRIVER_POSTINSTALL() do { \
|
||||
drm_i830_private_t *dev_priv = \
|
||||
(drm_i830_private_t *)dev->dev_private; \
|
||||
I830_WRITE16( I830REG_INT_ENABLE_R, 0x2 ); \
|
||||
atomic_set(&dev_priv->irq_received, 0); \
|
||||
atomic_set(&dev_priv->irq_emitted, 0); \
|
||||
init_waitqueue_head(&dev_priv->irq_queue); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* This gets called too late to be useful: dev_priv has already been
|
||||
* freed.
|
||||
*/
|
||||
#define DRIVER_UNINSTALL() do { \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
#define __HAVE_DMA_IRQ 0
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Buffer customization:
|
||||
*/
|
||||
|
|
527
linux/i830_dma.c
527
linux/i830_dma.c
|
@ -38,6 +38,7 @@
|
|||
#include "i830_drm.h"
|
||||
#include "i830_drv.h"
|
||||
#include <linux/interrupt.h> /* For task queue support */
|
||||
#include <linux/pagemap.h> /* For FASTCALL on unlock_page() */
|
||||
#include <linux/delay.h>
|
||||
|
||||
#ifdef DO_MUNMAP_4_ARGS
|
||||
|
@ -53,8 +54,6 @@
|
|||
#define I830_BUF_UNMAPPED 0
|
||||
#define I830_BUF_MAPPED 1
|
||||
|
||||
#define RING_LOCALS unsigned int outring, ringmask; volatile char *virt;
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,2)
|
||||
#define down_write down
|
||||
#define up_write up
|
||||
|
@ -67,32 +66,6 @@
|
|||
#define UnlockPage(page) unlock_page(page)
|
||||
#endif
|
||||
|
||||
#define I830_VERBOSE 0
|
||||
|
||||
#define BEGIN_LP_RING(n) do { \
|
||||
if (I830_VERBOSE) \
|
||||
printk("BEGIN_LP_RING(%d) in %s\n", \
|
||||
n, __FUNCTION__); \
|
||||
if (dev_priv->ring.space < n*4) \
|
||||
i830_wait_ring(dev, n*4); \
|
||||
dev_priv->ring.space -= n*4; \
|
||||
outring = dev_priv->ring.tail; \
|
||||
ringmask = dev_priv->ring.tail_mask; \
|
||||
virt = dev_priv->ring.virtual_start; \
|
||||
} while (0)
|
||||
|
||||
#define ADVANCE_LP_RING() do { \
|
||||
if (I830_VERBOSE) printk("ADVANCE_LP_RING %x\n", outring); \
|
||||
dev_priv->ring.tail = outring; \
|
||||
I830_WRITE(LP_RING + RING_TAIL, outring); \
|
||||
} while(0)
|
||||
|
||||
#define OUT_RING(n) do { \
|
||||
if (I830_VERBOSE) printk(" OUT_RING %x\n", (int)(n)); \
|
||||
*(volatile unsigned int *)(virt + outring) = n; \
|
||||
outring += 4; \
|
||||
outring &= ringmask; \
|
||||
} while (0)
|
||||
|
||||
static inline void i830_print_status_page(drm_device_t *dev)
|
||||
{
|
||||
|
@ -252,7 +225,7 @@ static int i830_dma_get_buffer(drm_device_t *dev, drm_i830_dma_t *d,
|
|||
buf = i830_freelist_get(dev);
|
||||
if (!buf) {
|
||||
retcode = -ENOMEM;
|
||||
DRM_ERROR("retcode=%d\n", retcode);
|
||||
DRM_DEBUG("retcode=%d\n", retcode);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
|
@ -286,12 +259,21 @@ static int i830_dma_cleanup(drm_device_t *dev)
|
|||
dev_priv->ring.Size);
|
||||
}
|
||||
if(dev_priv->hw_status_page != 0UL) {
|
||||
pci_free_consistent(dev->pdev, PAGE_SIZE,
|
||||
pci_free_consistent(dev->pdev, PAGE_SIZE,
|
||||
(void *)dev_priv->hw_status_page,
|
||||
dev_priv->dma_status_page);
|
||||
/* Need to rewrite hardware status page */
|
||||
I830_WRITE(0x02080, 0x1ffff000);
|
||||
}
|
||||
|
||||
/* Disable interrupts here because after dev_private
|
||||
* is freed, it's too late.
|
||||
*/
|
||||
if (dev->irq) {
|
||||
I830_WRITE16( I830REG_INT_MASK_R, 0xffff );
|
||||
I830_WRITE16( I830REG_INT_ENABLE_R, 0x0 );
|
||||
}
|
||||
|
||||
DRM(free)(dev->dev_private, sizeof(drm_i830_private_t),
|
||||
DRM_MEM_DRIVER);
|
||||
dev->dev_private = NULL;
|
||||
|
@ -305,7 +287,7 @@ static int i830_dma_cleanup(drm_device_t *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int i830_wait_ring(drm_device_t *dev, int n)
|
||||
int i830_wait_ring(drm_device_t *dev, int n, const char *caller)
|
||||
{
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
drm_i830_ring_buffer_t *ring = &(dev_priv->ring);
|
||||
|
@ -331,6 +313,7 @@ static int i830_wait_ring(drm_device_t *dev, int n)
|
|||
goto out_wait_ring;
|
||||
}
|
||||
udelay(1);
|
||||
dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT;
|
||||
}
|
||||
|
||||
out_wait_ring:
|
||||
|
@ -346,6 +329,9 @@ static void i830_kernel_lost_context(drm_device_t *dev)
|
|||
ring->tail = I830_READ(LP_RING + RING_TAIL) & TAIL_ADDR;
|
||||
ring->space = ring->head - (ring->tail+8);
|
||||
if (ring->space < 0) ring->space += ring->Size;
|
||||
|
||||
if (ring->head == ring->tail)
|
||||
dev_priv->sarea_priv->perf_boxes |= I830_BOX_RING_EMPTY;
|
||||
}
|
||||
|
||||
static int i830_freelist_init(drm_device_t *dev, drm_i830_private_t *dev_priv)
|
||||
|
@ -460,6 +446,8 @@ static int i830_dma_initialize(drm_device_t *dev,
|
|||
|
||||
dev_priv->back_pitch = init->back_pitch;
|
||||
dev_priv->depth_pitch = init->depth_pitch;
|
||||
dev_priv->do_boxes = 0;
|
||||
dev_priv->use_mi_batchbuffer_start = 0;
|
||||
|
||||
/* Program Hardware Status Page */
|
||||
dev_priv->hw_status_page =
|
||||
|
@ -474,7 +462,7 @@ static int i830_dma_initialize(drm_device_t *dev,
|
|||
memset((void *) dev_priv->hw_status_page, 0, PAGE_SIZE);
|
||||
DRM_DEBUG("hw status page @ %lx\n", dev_priv->hw_status_page);
|
||||
|
||||
I830_WRITE(0x02080, dev_priv->dma_status_page);
|
||||
I830_WRITE(0x02080, virt_to_bus((void *)dev_priv->hw_status_page));
|
||||
DRM_DEBUG("Enabled hardware status page\n");
|
||||
|
||||
/* Now we need to init our freelist */
|
||||
|
@ -535,11 +523,7 @@ static void i830EmitContextVerified( drm_device_t *dev,
|
|||
unsigned int tmp;
|
||||
RING_LOCALS;
|
||||
|
||||
BEGIN_LP_RING( I830_CTX_SETUP_SIZE + 2 );
|
||||
|
||||
OUT_RING( GFX_OP_STIPPLE );
|
||||
OUT_RING( 0 );
|
||||
|
||||
BEGIN_LP_RING( I830_CTX_SETUP_SIZE + 4 );
|
||||
|
||||
for ( i = 0 ; i < I830_CTXREG_BLENDCOLR0 ; i++ ) {
|
||||
tmp = code[i];
|
||||
|
@ -577,38 +561,44 @@ static void i830EmitContextVerified( drm_device_t *dev,
|
|||
ADVANCE_LP_RING();
|
||||
}
|
||||
|
||||
static void i830EmitTexVerified( drm_device_t *dev,
|
||||
volatile unsigned int *code )
|
||||
static void i830EmitTexVerified( drm_device_t *dev, unsigned int *code )
|
||||
{
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
int i, j = 0;
|
||||
unsigned int tmp;
|
||||
RING_LOCALS;
|
||||
|
||||
BEGIN_LP_RING( I830_TEX_SETUP_SIZE );
|
||||
if (code[I830_TEXREG_MI0] == GFX_OP_MAP_INFO ||
|
||||
(code[I830_TEXREG_MI0] & ~(0xf*LOAD_TEXTURE_MAP0)) ==
|
||||
(STATE3D_LOAD_STATE_IMMEDIATE_2|4)) {
|
||||
|
||||
OUT_RING( GFX_OP_MAP_INFO );
|
||||
OUT_RING( code[I830_TEXREG_MI1] );
|
||||
OUT_RING( code[I830_TEXREG_MI2] );
|
||||
OUT_RING( code[I830_TEXREG_MI3] );
|
||||
OUT_RING( code[I830_TEXREG_MI4] );
|
||||
OUT_RING( code[I830_TEXREG_MI5] );
|
||||
BEGIN_LP_RING( I830_TEX_SETUP_SIZE );
|
||||
|
||||
for ( i = 6 ; i < I830_TEX_SETUP_SIZE ; i++ ) {
|
||||
tmp = code[i];
|
||||
OUT_RING( tmp );
|
||||
j++;
|
||||
}
|
||||
OUT_RING( code[I830_TEXREG_MI0] ); /* TM0LI */
|
||||
OUT_RING( code[I830_TEXREG_MI1] ); /* TM0S0 */
|
||||
OUT_RING( code[I830_TEXREG_MI2] ); /* TM0S1 */
|
||||
OUT_RING( code[I830_TEXREG_MI3] ); /* TM0S2 */
|
||||
OUT_RING( code[I830_TEXREG_MI4] ); /* TM0S3 */
|
||||
OUT_RING( code[I830_TEXREG_MI5] ); /* TM0S4 */
|
||||
|
||||
for ( i = 6 ; i < I830_TEX_SETUP_SIZE ; i++ ) {
|
||||
tmp = code[i];
|
||||
OUT_RING( tmp );
|
||||
j++;
|
||||
}
|
||||
|
||||
if (j & 1)
|
||||
OUT_RING( 0 );
|
||||
if (j & 1)
|
||||
OUT_RING( 0 );
|
||||
|
||||
ADVANCE_LP_RING();
|
||||
ADVANCE_LP_RING();
|
||||
}
|
||||
else
|
||||
printk("rejected packet %x\n", code[0]);
|
||||
}
|
||||
|
||||
static void i830EmitTexBlendVerified( drm_device_t *dev,
|
||||
volatile unsigned int *code,
|
||||
volatile unsigned int num)
|
||||
unsigned int *code,
|
||||
unsigned int num)
|
||||
{
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
int i, j = 0;
|
||||
|
@ -618,7 +608,7 @@ static void i830EmitTexBlendVerified( drm_device_t *dev,
|
|||
if (!num)
|
||||
return;
|
||||
|
||||
BEGIN_LP_RING( num );
|
||||
BEGIN_LP_RING( num + 1 );
|
||||
|
||||
for ( i = 0 ; i < num ; i++ ) {
|
||||
tmp = code[i];
|
||||
|
@ -641,6 +631,8 @@ static void i830EmitTexPalette( drm_device_t *dev,
|
|||
int i;
|
||||
RING_LOCALS;
|
||||
|
||||
return;
|
||||
|
||||
BEGIN_LP_RING( 258 );
|
||||
|
||||
if(is_shared == 1) {
|
||||
|
@ -654,42 +646,41 @@ static void i830EmitTexPalette( drm_device_t *dev,
|
|||
OUT_RING(palette[i]);
|
||||
}
|
||||
OUT_RING(0);
|
||||
/* KW: WHERE IS THE ADVANCE_LP_RING? This is effectively a noop!
|
||||
*/
|
||||
}
|
||||
|
||||
/* Need to do some additional checking when setting the dest buffer.
|
||||
*/
|
||||
static void i830EmitDestVerified( drm_device_t *dev,
|
||||
volatile unsigned int *code )
|
||||
unsigned int *code )
|
||||
{
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
unsigned int tmp;
|
||||
RING_LOCALS;
|
||||
|
||||
BEGIN_LP_RING( I830_DEST_SETUP_SIZE + 6 );
|
||||
BEGIN_LP_RING( I830_DEST_SETUP_SIZE + 10 );
|
||||
|
||||
|
||||
tmp = code[I830_DESTREG_CBUFADDR];
|
||||
if (tmp == dev_priv->front_di1) {
|
||||
/* Don't use fence when front buffer rendering */
|
||||
OUT_RING( CMD_OP_DESTBUFFER_INFO );
|
||||
OUT_RING( BUF_3D_ID_COLOR_BACK |
|
||||
BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) );
|
||||
OUT_RING( tmp );
|
||||
if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) {
|
||||
if (((int)outring) & 8) {
|
||||
OUT_RING(0);
|
||||
OUT_RING(0);
|
||||
}
|
||||
|
||||
OUT_RING( CMD_OP_DESTBUFFER_INFO );
|
||||
OUT_RING( BUF_3D_ID_DEPTH |
|
||||
BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp));
|
||||
OUT_RING( dev_priv->zi1 );
|
||||
} else if(tmp == dev_priv->back_di1) {
|
||||
OUT_RING( CMD_OP_DESTBUFFER_INFO );
|
||||
OUT_RING( BUF_3D_ID_COLOR_BACK |
|
||||
BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) |
|
||||
BUF_3D_USE_FENCE);
|
||||
OUT_RING( tmp );
|
||||
OUT_RING( 0 );
|
||||
|
||||
OUT_RING( CMD_OP_DESTBUFFER_INFO );
|
||||
OUT_RING( BUF_3D_ID_DEPTH | BUF_3D_USE_FENCE |
|
||||
BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp));
|
||||
OUT_RING( dev_priv->zi1 );
|
||||
OUT_RING( 0 );
|
||||
} else {
|
||||
DRM_ERROR("bad di1 %x (allow %x or %x)\n",
|
||||
tmp, dev_priv->front_di1, dev_priv->back_di1);
|
||||
|
@ -717,21 +708,35 @@ static void i830EmitDestVerified( drm_device_t *dev,
|
|||
OUT_RING( 0 );
|
||||
}
|
||||
|
||||
OUT_RING( code[I830_DESTREG_SENABLE] );
|
||||
|
||||
OUT_RING( GFX_OP_SCISSOR_RECT );
|
||||
OUT_RING( code[I830_DESTREG_SR1] );
|
||||
OUT_RING( code[I830_DESTREG_SR2] );
|
||||
OUT_RING( 0 );
|
||||
|
||||
ADVANCE_LP_RING();
|
||||
}
|
||||
|
||||
static void i830EmitStippleVerified( drm_device_t *dev,
|
||||
unsigned int *code )
|
||||
{
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
RING_LOCALS;
|
||||
|
||||
BEGIN_LP_RING( 2 );
|
||||
OUT_RING( GFX_OP_STIPPLE );
|
||||
OUT_RING( code[1] );
|
||||
ADVANCE_LP_RING();
|
||||
}
|
||||
|
||||
|
||||
static void i830EmitState( drm_device_t *dev )
|
||||
{
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
unsigned int dirty = sarea_priv->dirty;
|
||||
|
||||
DRM_DEBUG("%s %x\n", __FUNCTION__, dirty);
|
||||
|
||||
if (dirty & I830_UPLOAD_BUFFERS) {
|
||||
i830EmitDestVerified( dev, sarea_priv->BufferState );
|
||||
sarea_priv->dirty &= ~I830_UPLOAD_BUFFERS;
|
||||
|
@ -765,17 +770,154 @@ static void i830EmitState( drm_device_t *dev )
|
|||
}
|
||||
|
||||
if (dirty & I830_UPLOAD_TEX_PALETTE_SHARED) {
|
||||
i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 1);
|
||||
i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 1);
|
||||
} else {
|
||||
if (dirty & I830_UPLOAD_TEX_PALETTE_N(0)) {
|
||||
i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 0);
|
||||
sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(0);
|
||||
}
|
||||
if (dirty & I830_UPLOAD_TEX_PALETTE_N(1)) {
|
||||
i830EmitTexPalette(dev, sarea_priv->Palette[1], 1, 0);
|
||||
sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(1);
|
||||
}
|
||||
if (dirty & I830_UPLOAD_TEX_PALETTE_N(0)) {
|
||||
i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 0);
|
||||
sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(0);
|
||||
}
|
||||
if (dirty & I830_UPLOAD_TEX_PALETTE_N(1)) {
|
||||
i830EmitTexPalette(dev, sarea_priv->Palette[1], 1, 0);
|
||||
sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(1);
|
||||
}
|
||||
|
||||
/* 1.3:
|
||||
*/
|
||||
#if 0
|
||||
if (dirty & I830_UPLOAD_TEX_PALETTE_N(2)) {
|
||||
i830EmitTexPalette(dev, sarea_priv->Palette2[0], 0, 0);
|
||||
sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(2);
|
||||
}
|
||||
if (dirty & I830_UPLOAD_TEX_PALETTE_N(3)) {
|
||||
i830EmitTexPalette(dev, sarea_priv->Palette2[1], 1, 0);
|
||||
sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(2);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* 1.3:
|
||||
*/
|
||||
if (dirty & I830_UPLOAD_STIPPLE) {
|
||||
i830EmitStippleVerified( dev,
|
||||
sarea_priv->StippleState);
|
||||
sarea_priv->dirty &= ~I830_UPLOAD_STIPPLE;
|
||||
}
|
||||
|
||||
if (dirty & I830_UPLOAD_TEX2) {
|
||||
i830EmitTexVerified( dev, sarea_priv->TexState2 );
|
||||
sarea_priv->dirty &= ~I830_UPLOAD_TEX2;
|
||||
}
|
||||
|
||||
if (dirty & I830_UPLOAD_TEX3) {
|
||||
i830EmitTexVerified( dev, sarea_priv->TexState3 );
|
||||
sarea_priv->dirty &= ~I830_UPLOAD_TEX3;
|
||||
}
|
||||
|
||||
|
||||
if (dirty & I830_UPLOAD_TEXBLEND2) {
|
||||
i830EmitTexBlendVerified(
|
||||
dev,
|
||||
sarea_priv->TexBlendState2,
|
||||
sarea_priv->TexBlendStateWordsUsed2);
|
||||
|
||||
sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND2;
|
||||
}
|
||||
|
||||
if (dirty & I830_UPLOAD_TEXBLEND3) {
|
||||
i830EmitTexBlendVerified(
|
||||
dev,
|
||||
sarea_priv->TexBlendState3,
|
||||
sarea_priv->TexBlendStateWordsUsed3);
|
||||
sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND3;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
* Performance monitoring functions
|
||||
*/
|
||||
|
||||
static void i830_fill_box( drm_device_t *dev,
|
||||
int x, int y, int w, int h,
|
||||
int r, int g, int b )
|
||||
{
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
u32 color;
|
||||
unsigned int BR13, CMD;
|
||||
RING_LOCALS;
|
||||
|
||||
BR13 = (0xF0 << 16) | (dev_priv->pitch * dev_priv->cpp) | (1<<24);
|
||||
CMD = XY_COLOR_BLT_CMD;
|
||||
x += dev_priv->sarea_priv->boxes[0].x1;
|
||||
y += dev_priv->sarea_priv->boxes[0].y1;
|
||||
|
||||
if (dev_priv->cpp == 4) {
|
||||
BR13 |= (1<<25);
|
||||
CMD |= (XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB);
|
||||
color = (((0xff) << 24) | (r << 16) | (g << 8) | b);
|
||||
} else {
|
||||
color = (((r & 0xf8) << 8) |
|
||||
((g & 0xfc) << 3) |
|
||||
((b & 0xf8) >> 3));
|
||||
}
|
||||
|
||||
BEGIN_LP_RING( 6 );
|
||||
OUT_RING( CMD );
|
||||
OUT_RING( BR13 );
|
||||
OUT_RING( (y << 16) | x );
|
||||
OUT_RING( ((y+h) << 16) | (x+w) );
|
||||
|
||||
if ( dev_priv->current_page == 1 ) {
|
||||
OUT_RING( dev_priv->front_offset );
|
||||
} else {
|
||||
OUT_RING( dev_priv->back_offset );
|
||||
}
|
||||
|
||||
OUT_RING( color );
|
||||
ADVANCE_LP_RING();
|
||||
}
|
||||
|
||||
static void i830_cp_performance_boxes( drm_device_t *dev )
|
||||
{
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
/* Purple box for page flipping
|
||||
*/
|
||||
if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_FLIP )
|
||||
i830_fill_box( dev, 4, 4, 8, 8, 255, 0, 255 );
|
||||
|
||||
/* Red box if we have to wait for idle at any point
|
||||
*/
|
||||
if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_WAIT )
|
||||
i830_fill_box( dev, 16, 4, 8, 8, 255, 0, 0 );
|
||||
|
||||
/* Blue box: lost context?
|
||||
*/
|
||||
if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_LOST_CONTEXT )
|
||||
i830_fill_box( dev, 28, 4, 8, 8, 0, 0, 255 );
|
||||
|
||||
/* Yellow box for texture swaps
|
||||
*/
|
||||
if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_TEXTURE_LOAD )
|
||||
i830_fill_box( dev, 40, 4, 8, 8, 255, 255, 0 );
|
||||
|
||||
/* Green box if hardware never idles (as far as we can tell)
|
||||
*/
|
||||
if ( !(dev_priv->sarea_priv->perf_boxes & I830_BOX_RING_EMPTY) )
|
||||
i830_fill_box( dev, 64, 4, 8, 8, 0, 255, 0 );
|
||||
|
||||
|
||||
/* Draw bars indicating number of buffers allocated
|
||||
* (not a great measure, easily confused)
|
||||
*/
|
||||
if (dev_priv->dma_used) {
|
||||
int bar = dev_priv->dma_used / 10240;
|
||||
if (bar > 100) bar = 100;
|
||||
if (bar < 1) bar = 1;
|
||||
i830_fill_box( dev, 4, 16, bar, 4, 196, 128, 128 );
|
||||
dev_priv->dma_used = 0;
|
||||
}
|
||||
|
||||
dev_priv->sarea_priv->perf_boxes = 0;
|
||||
}
|
||||
|
||||
static void i830_dma_dispatch_clear( drm_device_t *dev, int flags,
|
||||
|
@ -793,6 +935,15 @@ static void i830_dma_dispatch_clear( drm_device_t *dev, int flags,
|
|||
unsigned int BR13, CMD, D_CMD;
|
||||
RING_LOCALS;
|
||||
|
||||
|
||||
if ( dev_priv->current_page == 1 ) {
|
||||
unsigned int tmp = flags;
|
||||
|
||||
flags &= ~(I830_FRONT | I830_BACK);
|
||||
if ( tmp & I830_FRONT ) flags |= I830_BACK;
|
||||
if ( tmp & I830_BACK ) flags |= I830_FRONT;
|
||||
}
|
||||
|
||||
i830_kernel_lost_context(dev);
|
||||
|
||||
switch(cpp) {
|
||||
|
@ -872,13 +1023,17 @@ static void i830_dma_dispatch_swap( drm_device_t *dev )
|
|||
drm_clip_rect_t *pbox = sarea_priv->boxes;
|
||||
int pitch = dev_priv->pitch;
|
||||
int cpp = dev_priv->cpp;
|
||||
int ofs = dev_priv->back_offset;
|
||||
int i;
|
||||
unsigned int CMD, BR13;
|
||||
RING_LOCALS;
|
||||
|
||||
DRM_DEBUG("swapbuffers\n");
|
||||
|
||||
i830_kernel_lost_context(dev);
|
||||
|
||||
if (dev_priv->do_boxes)
|
||||
i830_cp_performance_boxes( dev );
|
||||
|
||||
switch(cpp) {
|
||||
case 2:
|
||||
BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24);
|
||||
|
@ -895,7 +1050,6 @@ static void i830_dma_dispatch_swap( drm_device_t *dev )
|
|||
break;
|
||||
}
|
||||
|
||||
i830_kernel_lost_context(dev);
|
||||
|
||||
if (nbox > I830_NR_SAREA_CLIPRECTS)
|
||||
nbox = I830_NR_SAREA_CLIPRECTS;
|
||||
|
@ -915,23 +1069,72 @@ static void i830_dma_dispatch_swap( drm_device_t *dev )
|
|||
BEGIN_LP_RING( 8 );
|
||||
OUT_RING( CMD );
|
||||
OUT_RING( BR13 );
|
||||
OUT_RING( (pbox->y1 << 16) | pbox->x1 );
|
||||
OUT_RING( (pbox->y2 << 16) | pbox->x2 );
|
||||
|
||||
OUT_RING( (pbox->y1 << 16) |
|
||||
pbox->x1 );
|
||||
OUT_RING( (pbox->y2 << 16) |
|
||||
pbox->x2 );
|
||||
|
||||
OUT_RING( dev_priv->front_offset );
|
||||
OUT_RING( (pbox->y1 << 16) |
|
||||
pbox->x1 );
|
||||
if (dev_priv->current_page == 0)
|
||||
OUT_RING( dev_priv->front_offset );
|
||||
else
|
||||
OUT_RING( dev_priv->back_offset );
|
||||
|
||||
OUT_RING( (pbox->y1 << 16) | pbox->x1 );
|
||||
OUT_RING( BR13 & 0xffff );
|
||||
OUT_RING( ofs );
|
||||
|
||||
if (dev_priv->current_page == 0)
|
||||
OUT_RING( dev_priv->back_offset );
|
||||
else
|
||||
OUT_RING( dev_priv->front_offset );
|
||||
|
||||
ADVANCE_LP_RING();
|
||||
}
|
||||
}
|
||||
|
||||
static void i830_dma_dispatch_flip( drm_device_t *dev )
|
||||
{
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
RING_LOCALS;
|
||||
|
||||
DRM_DEBUG( "%s: page=%d pfCurrentPage=%d\n",
|
||||
__FUNCTION__,
|
||||
dev_priv->current_page,
|
||||
dev_priv->sarea_priv->pf_current_page);
|
||||
|
||||
i830_kernel_lost_context(dev);
|
||||
|
||||
if (dev_priv->do_boxes) {
|
||||
dev_priv->sarea_priv->perf_boxes |= I830_BOX_FLIP;
|
||||
i830_cp_performance_boxes( dev );
|
||||
}
|
||||
|
||||
|
||||
BEGIN_LP_RING( 2 );
|
||||
OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE );
|
||||
OUT_RING( 0 );
|
||||
ADVANCE_LP_RING();
|
||||
|
||||
BEGIN_LP_RING( 6 );
|
||||
OUT_RING( CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP );
|
||||
OUT_RING( 0 );
|
||||
if ( dev_priv->current_page == 0 ) {
|
||||
OUT_RING( dev_priv->back_offset );
|
||||
dev_priv->current_page = 1;
|
||||
} else {
|
||||
OUT_RING( dev_priv->front_offset );
|
||||
dev_priv->current_page = 0;
|
||||
}
|
||||
OUT_RING(0);
|
||||
ADVANCE_LP_RING();
|
||||
|
||||
|
||||
BEGIN_LP_RING( 2 );
|
||||
OUT_RING( MI_WAIT_FOR_EVENT |
|
||||
MI_WAIT_FOR_PLANE_A_FLIP );
|
||||
OUT_RING( 0 );
|
||||
ADVANCE_LP_RING();
|
||||
|
||||
|
||||
dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
|
||||
}
|
||||
|
||||
static void i830_dma_dispatch_vertex(drm_device_t *dev,
|
||||
drm_buf_t *buf,
|
||||
|
@ -984,8 +1187,10 @@ static void i830_dma_dispatch_vertex(drm_device_t *dev,
|
|||
sarea_priv->vertex_prim |
|
||||
((used/4)-2));
|
||||
|
||||
vp[used/4] = MI_BATCH_BUFFER_END;
|
||||
used += 4;
|
||||
if (dev_priv->use_mi_batchbuffer_start) {
|
||||
vp[used/4] = MI_BATCH_BUFFER_END;
|
||||
used += 4;
|
||||
}
|
||||
|
||||
if (used & 4) {
|
||||
vp[used/4] = 0;
|
||||
|
@ -1008,11 +1213,21 @@ static void i830_dma_dispatch_vertex(drm_device_t *dev,
|
|||
ADVANCE_LP_RING();
|
||||
}
|
||||
|
||||
BEGIN_LP_RING(2);
|
||||
OUT_RING( MI_BATCH_BUFFER_START | (2<<6) );
|
||||
OUT_RING( start | MI_BATCH_NON_SECURE );
|
||||
ADVANCE_LP_RING();
|
||||
|
||||
if (dev_priv->use_mi_batchbuffer_start) {
|
||||
BEGIN_LP_RING(2);
|
||||
OUT_RING( MI_BATCH_BUFFER_START | (2<<6) );
|
||||
OUT_RING( start | MI_BATCH_NON_SECURE );
|
||||
ADVANCE_LP_RING();
|
||||
}
|
||||
else {
|
||||
BEGIN_LP_RING(4);
|
||||
OUT_RING( MI_BATCH_BUFFER );
|
||||
OUT_RING( start | MI_BATCH_NON_SECURE );
|
||||
OUT_RING( start + used - 4 );
|
||||
OUT_RING( 0 );
|
||||
ADVANCE_LP_RING();
|
||||
}
|
||||
|
||||
} while (++i < nbox);
|
||||
}
|
||||
|
||||
|
@ -1050,7 +1265,7 @@ void i830_dma_quiescent(drm_device_t *dev)
|
|||
OUT_RING( 0 );
|
||||
ADVANCE_LP_RING();
|
||||
|
||||
i830_wait_ring( dev, dev_priv->ring.Size - 8 );
|
||||
i830_wait_ring( dev, dev_priv->ring.Size - 8, __FUNCTION__ );
|
||||
}
|
||||
|
||||
static int i830_flush_queue(drm_device_t *dev)
|
||||
|
@ -1067,7 +1282,7 @@ static int i830_flush_queue(drm_device_t *dev)
|
|||
OUT_RING( 0 );
|
||||
ADVANCE_LP_RING();
|
||||
|
||||
i830_wait_ring( dev, dev_priv->ring.Size - 8 );
|
||||
i830_wait_ring( dev, dev_priv->ring.Size - 8, __FUNCTION__ );
|
||||
|
||||
for (i = 0; i < dma->buf_count; i++) {
|
||||
drm_buf_t *buf = dma->buflist[ i ];
|
||||
|
@ -1207,6 +1422,53 @@ int i830_swap_bufs(struct inode *inode, struct file *filp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Not sure why this isn't set all the time:
|
||||
*/
|
||||
static void i830_do_init_pageflip( drm_device_t *dev )
|
||||
{
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
dev_priv->page_flipping = 1;
|
||||
dev_priv->current_page = 0;
|
||||
dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
|
||||
}
|
||||
|
||||
int i830_do_cleanup_pageflip( drm_device_t *dev )
|
||||
{
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
if (dev_priv->current_page != 0)
|
||||
i830_dma_dispatch_flip( dev );
|
||||
|
||||
dev_priv->page_flipping = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i830_flip_bufs(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
|
||||
DRM_ERROR("i830_flip_buf called without lock held\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!dev_priv->page_flipping)
|
||||
i830_do_init_pageflip( dev );
|
||||
|
||||
i830_dma_dispatch_flip( dev );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i830_getage(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
|
@ -1270,3 +1532,66 @@ int i830_docopy(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int i830_getparam( struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg )
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
drm_i830_getparam_t param;
|
||||
int value;
|
||||
|
||||
if ( !dev_priv ) {
|
||||
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (copy_from_user(¶m, (drm_i830_getparam_t *)arg, sizeof(param) ))
|
||||
return -EFAULT;
|
||||
|
||||
switch( param.param ) {
|
||||
case I830_PARAM_IRQ_ACTIVE:
|
||||
value = dev->irq ? 1 : 0;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ( copy_to_user( param.value, &value, sizeof(int) ) ) {
|
||||
DRM_ERROR( "copy_to_user\n" );
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int i830_setparam( struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg )
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
drm_i830_setparam_t param;
|
||||
|
||||
if ( !dev_priv ) {
|
||||
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (copy_from_user(¶m, (drm_i830_setparam_t *)arg, sizeof(param) ))
|
||||
return -EFAULT;
|
||||
|
||||
switch( param.param ) {
|
||||
case I830_SETPARAM_USE_MI_BATCHBUFFER_START:
|
||||
dev_priv->use_mi_batchbuffer_start = param.value;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
100
linux/i830_drm.h
100
linux/i830_drm.h
|
@ -3,6 +3,9 @@
|
|||
|
||||
/* WARNING: These defines must be the same as what the Xserver uses.
|
||||
* if you change them, you must change the defines in the Xserver.
|
||||
*
|
||||
* KW: Actually, you can't ever change them because doing so would
|
||||
* break backwards compatibility.
|
||||
*/
|
||||
|
||||
#ifndef _I830_DEFINES_
|
||||
|
@ -18,14 +21,12 @@
|
|||
#define I830_NR_TEX_REGIONS 64
|
||||
#define I830_LOG_MIN_TEX_REGION_SIZE 16
|
||||
|
||||
/* if defining I830_ENABLE_4_TEXTURES, do it in i830_3d_reg.h, too */
|
||||
#if !defined(I830_ENABLE_4_TEXTURES)
|
||||
/* KW: These aren't correct but someone set them to two and then
|
||||
* released the module. Now we can't change them as doing so would
|
||||
* break backwards compatibility.
|
||||
*/
|
||||
#define I830_TEXTURE_COUNT 2
|
||||
#define I830_TEXBLEND_COUNT 2 /* always same as TEXTURE_COUNT? */
|
||||
#else /* defined(I830_ENABLE_4_TEXTURES) */
|
||||
#define I830_TEXTURE_COUNT 4
|
||||
#define I830_TEXBLEND_COUNT 4 /* always same as TEXTURE_COUNT? */
|
||||
#endif /* I830_ENABLE_4_TEXTURES */
|
||||
#define I830_TEXBLEND_COUNT I830_TEXTURE_COUNT
|
||||
|
||||
#define I830_TEXBLEND_SIZE 12 /* (4 args + op) * 2 + COLOR_FACTOR */
|
||||
|
||||
|
@ -57,6 +58,7 @@
|
|||
#define I830_UPLOAD_TEXBLEND_MASK 0xf00000
|
||||
#define I830_UPLOAD_TEX_PALETTE_N(n) (0x1000000 << (n))
|
||||
#define I830_UPLOAD_TEX_PALETTE_SHARED 0x4000000
|
||||
#define I830_UPLOAD_STIPPLE 0x8000000
|
||||
|
||||
/* Indices into buf.Setup where various bits of state are mirrored per
|
||||
* context and per buffer. These can be fired at the card as a unit,
|
||||
|
@ -73,7 +75,6 @@
|
|||
*/
|
||||
|
||||
#define I830_DESTREG_CBUFADDR 0
|
||||
/* Invarient */
|
||||
#define I830_DESTREG_DBUFADDR 1
|
||||
#define I830_DESTREG_DV0 2
|
||||
#define I830_DESTREG_DV1 3
|
||||
|
@ -109,6 +110,13 @@
|
|||
#define I830_CTXREG_MCSB1 16
|
||||
#define I830_CTX_SETUP_SIZE 17
|
||||
|
||||
/* 1.3: Stipple state
|
||||
*/
|
||||
#define I830_STPREG_ST0 0
|
||||
#define I830_STPREG_ST1 1
|
||||
#define I830_STP_SETUP_SIZE 2
|
||||
|
||||
|
||||
/* Texture state (per tex unit)
|
||||
*/
|
||||
|
||||
|
@ -124,6 +132,18 @@
|
|||
#define I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS */
|
||||
#define I830_TEX_SETUP_SIZE 10
|
||||
|
||||
#define I830_TEXREG_TM0LI 0 /* load immediate 2 texture map n */
|
||||
#define I830_TEXREG_TM0S0 1
|
||||
#define I830_TEXREG_TM0S1 2
|
||||
#define I830_TEXREG_TM0S2 3
|
||||
#define I830_TEXREG_TM0S3 4
|
||||
#define I830_TEXREG_TM0S4 5
|
||||
#define I830_TEXREG_NOP0 6 /* noop */
|
||||
#define I830_TEXREG_NOP1 7 /* noop */
|
||||
#define I830_TEXREG_NOP2 8 /* noop */
|
||||
#define __I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS -- shared */
|
||||
#define __I830_TEX_SETUP_SIZE 10
|
||||
|
||||
#define I830_FRONT 0x1
|
||||
#define I830_BACK 0x2
|
||||
#define I830_DEPTH 0x4
|
||||
|
@ -199,8 +219,35 @@ typedef struct _drm_i830_sarea {
|
|||
int ctxOwner; /* last context to upload state */
|
||||
|
||||
int vertex_prim;
|
||||
|
||||
int pf_enabled; /* is pageflipping allowed? */
|
||||
int pf_active;
|
||||
int pf_current_page; /* which buffer is being displayed? */
|
||||
|
||||
int perf_boxes; /* performance boxes to be displayed */
|
||||
|
||||
/* Here's the state for texunits 2,3:
|
||||
*/
|
||||
unsigned int TexState2[I830_TEX_SETUP_SIZE];
|
||||
unsigned int TexBlendState2[I830_TEXBLEND_SIZE];
|
||||
unsigned int TexBlendStateWordsUsed2;
|
||||
|
||||
unsigned int TexState3[I830_TEX_SETUP_SIZE];
|
||||
unsigned int TexBlendState3[I830_TEXBLEND_SIZE];
|
||||
unsigned int TexBlendStateWordsUsed3;
|
||||
|
||||
unsigned int StippleState[I830_STP_SETUP_SIZE];
|
||||
} drm_i830_sarea_t;
|
||||
|
||||
/* Flags for perf_boxes
|
||||
*/
|
||||
#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */
|
||||
#define I830_BOX_FLIP 0x2 /* populated by kernel */
|
||||
#define I830_BOX_WAIT 0x4 /* populated by kernel & client */
|
||||
#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */
|
||||
#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */
|
||||
|
||||
|
||||
/* I830 specific ioctls
|
||||
* The device specific ioctl range is 0x40 to 0x79.
|
||||
*/
|
||||
|
@ -213,6 +260,11 @@ typedef struct _drm_i830_sarea {
|
|||
#define DRM_IOCTL_I830_SWAP DRM_IO ( 0x46)
|
||||
#define DRM_IOCTL_I830_COPY DRM_IOW( 0x47, drm_i830_copy_t)
|
||||
#define DRM_IOCTL_I830_DOCOPY DRM_IO ( 0x48)
|
||||
#define DRM_IOCTL_I830_FLIP DRM_IO ( 0x49)
|
||||
#define DRM_IOCTL_I830_IRQ_EMIT DRM_IOWR(0x4a, drm_i830_irq_emit_t)
|
||||
#define DRM_IOCTL_I830_IRQ_WAIT DRM_IOW( 0x4b, drm_i830_irq_wait_t)
|
||||
#define DRM_IOCTL_I830_GETPARAM DRM_IOWR(0x4c, drm_i830_getparam_t)
|
||||
#define DRM_IOCTL_I830_SETPARAM DRM_IOWR(0x4d, drm_i830_setparam_t)
|
||||
|
||||
typedef struct _drm_i830_clear {
|
||||
int clear_color;
|
||||
|
@ -248,4 +300,36 @@ typedef struct drm_i830_dma {
|
|||
int granted;
|
||||
} drm_i830_dma_t;
|
||||
|
||||
|
||||
/* 1.3: Userspace can request & wait on irq's:
|
||||
*/
|
||||
typedef struct drm_i830_irq_emit {
|
||||
int *irq_seq;
|
||||
} drm_i830_irq_emit_t;
|
||||
|
||||
typedef struct drm_i830_irq_wait {
|
||||
int irq_seq;
|
||||
} drm_i830_irq_wait_t;
|
||||
|
||||
|
||||
/* 1.3: New ioctl to query kernel params:
|
||||
*/
|
||||
#define I830_PARAM_IRQ_ACTIVE 1
|
||||
|
||||
typedef struct drm_i830_getparam {
|
||||
int param;
|
||||
int *value;
|
||||
} drm_i830_getparam_t;
|
||||
|
||||
|
||||
/* 1.3: New ioctl to set kernel params:
|
||||
*/
|
||||
#define I830_SETPARAM_USE_MI_BATCHBUFFER_START 1
|
||||
|
||||
typedef struct drm_i830_setparam {
|
||||
int param;
|
||||
int value;
|
||||
} drm_i830_setparam_t;
|
||||
|
||||
|
||||
#endif /* _I830_DRM_H_ */
|
||||
|
|
|
@ -78,6 +78,19 @@ typedef struct drm_i830_private {
|
|||
int back_pitch;
|
||||
int depth_pitch;
|
||||
unsigned int cpp;
|
||||
|
||||
int do_boxes;
|
||||
int dma_used;
|
||||
|
||||
int current_page;
|
||||
int page_flipping;
|
||||
|
||||
wait_queue_head_t irq_queue;
|
||||
atomic_t irq_received;
|
||||
atomic_t irq_emitted;
|
||||
|
||||
int use_mi_batchbuffer_start;
|
||||
|
||||
} drm_i830_private_t;
|
||||
|
||||
/* i830_dma.c */
|
||||
|
@ -108,6 +121,23 @@ extern int i830_swap_bufs(struct inode *inode, struct file *filp,
|
|||
extern int i830_clear_bufs(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
|
||||
extern int i830_flip_bufs(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
|
||||
extern int i830_getparam( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
|
||||
extern int i830_setparam( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
|
||||
/* i830_irq.c */
|
||||
extern int i830_irq_emit( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
extern int i830_irq_wait( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
extern int i830_wait_irq(drm_device_t *dev, int irq_nr);
|
||||
extern int i830_emit_irq(drm_device_t *dev);
|
||||
|
||||
|
||||
#define I830_BASE(reg) ((unsigned long) \
|
||||
dev_priv->mmio_map->handle)
|
||||
|
@ -119,12 +149,53 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp,
|
|||
#define I830_READ16(reg) I830_DEREF16(reg)
|
||||
#define I830_WRITE16(reg,val) do { I830_DEREF16(reg) = val; } while (0)
|
||||
|
||||
|
||||
|
||||
#define I830_VERBOSE 0
|
||||
|
||||
#define RING_LOCALS unsigned int outring, ringmask, outcount; \
|
||||
volatile char *virt;
|
||||
|
||||
#define BEGIN_LP_RING(n) do { \
|
||||
if (I830_VERBOSE) \
|
||||
printk("BEGIN_LP_RING(%d) in %s\n", \
|
||||
n, __FUNCTION__); \
|
||||
if (dev_priv->ring.space < n*4) \
|
||||
i830_wait_ring(dev, n*4, __FUNCTION__); \
|
||||
outcount = 0; \
|
||||
outring = dev_priv->ring.tail; \
|
||||
ringmask = dev_priv->ring.tail_mask; \
|
||||
virt = dev_priv->ring.virtual_start; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define OUT_RING(n) do { \
|
||||
if (I830_VERBOSE) printk(" OUT_RING %x\n", (int)(n)); \
|
||||
*(volatile unsigned int *)(virt + outring) = n; \
|
||||
outcount++; \
|
||||
outring += 4; \
|
||||
outring &= ringmask; \
|
||||
} while (0)
|
||||
|
||||
#define ADVANCE_LP_RING() do { \
|
||||
if (I830_VERBOSE) printk("ADVANCE_LP_RING %x\n", outring); \
|
||||
dev_priv->ring.tail = outring; \
|
||||
dev_priv->ring.space -= outcount * 4; \
|
||||
I830_WRITE(LP_RING + RING_TAIL, outring); \
|
||||
} while(0)
|
||||
|
||||
extern int i830_wait_ring(drm_device_t *dev, int n, const char *caller);
|
||||
|
||||
|
||||
#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23))
|
||||
#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23))
|
||||
#define CMD_REPORT_HEAD (7<<23)
|
||||
#define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1)
|
||||
#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1)
|
||||
|
||||
#define STATE3D_LOAD_STATE_IMMEDIATE_2 ((0x3<<29)|(0x1d<<24)|(0x03<<16))
|
||||
#define LOAD_TEXTURE_MAP0 (1<<11)
|
||||
|
||||
#define INST_PARSER_CLIENT 0x00000000
|
||||
#define INST_OP_FLUSH 0x02000000
|
||||
#define INST_FLUSH_MAP_CACHE 0x00000001
|
||||
|
@ -140,6 +211,9 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp,
|
|||
#define I830REG_INT_MASK_R 0x020a8
|
||||
#define I830REG_INT_ENABLE_R 0x020a0
|
||||
|
||||
#define I830_IRQ_RESERVED ((1<<13)|(3<<2))
|
||||
|
||||
|
||||
#define LP_RING 0x2030
|
||||
#define HP_RING 0x2040
|
||||
#define RING_TAIL 0x00
|
||||
|
@ -182,6 +256,9 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp,
|
|||
|
||||
#define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
|
||||
|
||||
#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2)
|
||||
#define ASYNC_FLIP (1<<22)
|
||||
|
||||
#define CMD_3D (0x3<<29)
|
||||
#define STATE3D_CONST_BLEND_COLOR_CMD (CMD_3D|(0x1d<<24)|(0x88<<16))
|
||||
#define STATE3D_MAP_COORD_SETBIND_CMD (CMD_3D|(0x1d<<24)|(0x02<<16))
|
||||
|
@ -213,6 +290,11 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp,
|
|||
#define MI_BATCH_BUFFER_END (0xA<<23)
|
||||
#define MI_BATCH_NON_SECURE (1)
|
||||
|
||||
#define MI_WAIT_FOR_EVENT ((0x3<<23))
|
||||
#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
|
||||
#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
|
||||
|
||||
#define MI_LOAD_SCAN_LINES_INCL ((0x12<<23))
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis.h,v 1.2 2001/12/19 21:25:59 dawes Exp $ */
|
||||
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis.h,v 1.3 2002/10/30 12:52:38 alanh Exp $ */
|
||||
|
||||
#ifndef __SIS_H__
|
||||
#define __SIS_H__
|
||||
|
|
|
@ -183,10 +183,10 @@ int sisp_agp_alloc(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
if(block){
|
||||
/* TODO */
|
||||
agp.offset = block->ofs;
|
||||
agp.free = (unsigned int)block;
|
||||
agp.free = (unsigned long)block;
|
||||
if(!add_alloc_set(agp.context, AGP_TYPE, agp.free)){
|
||||
DRM_DEBUG("adding to allocation set fails\n");
|
||||
mmFreeMem((PMemBlock)agp.free);
|
||||
mmFreeMem((PMemBlock)(unsigned long)agp.free);
|
||||
retval = -1;
|
||||
}
|
||||
}
|
||||
|
@ -219,7 +219,7 @@ int sisp_agp_free(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
return -1;
|
||||
}
|
||||
|
||||
mmFreeMem((PMemBlock)agp.free);
|
||||
mmFreeMem((PMemBlock)(unsigned long)agp.free);
|
||||
if(!del_alloc_set(agp.context, AGP_TYPE, agp.free))
|
||||
retval = -1;
|
||||
|
||||
|
@ -289,7 +289,7 @@ int sis_final_context(int context)
|
|||
retval = setFirst(set, &item);
|
||||
while(retval){
|
||||
DRM_DEBUG("free agp memory 0x%x\n", item);
|
||||
mmFreeMem((PMemBlock)item);
|
||||
mmFreeMem((PMemBlock)(unsigned long)item);
|
||||
retval = setNext(set, &item);
|
||||
}
|
||||
setDestroy(set);
|
||||
|
|
Loading…
Reference in New Issue