mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2025-12-24 20:40:12 +01:00
- Sync up with trunk code.
- Apply PPC updates, renders front-buffered apps fine. Seems to be a
problem with the last_frame counter in the SAREA getting smashed, so
double-buffered apps will spin forever waiting for a garbage value.
TODO: Texturing updates for PPC, fix last_frame counter.
This commit is contained in:
parent
d1b280b5d8
commit
d4f794a30e
7 changed files with 187 additions and 235 deletions
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
#define R128_NAME "r128"
|
||||
#define R128_DESC "ATI Rage 128"
|
||||
#define R128_DATE "20010123"
|
||||
#define R128_DATE "20010130"
|
||||
#define R128_MAJOR 2
|
||||
#define R128_MINOR 1
|
||||
#define R128_PATCHLEVEL 4
|
||||
|
|
@ -571,12 +571,6 @@ int r128_ioctl(struct inode *inode, struct file *filp,
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if ( retcode ) {
|
||||
DRM_INFO( "%s 0x%x ret = %d\n", __FUNCTION__, nr, retcode );
|
||||
}
|
||||
#endif
|
||||
|
||||
atomic_dec(&dev->ioctl_count);
|
||||
return retcode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,7 +99,8 @@ unsigned long ati_pcigart_init( drm_device_t *dev )
|
|||
memset( pci_gart, 0, ATI_MAX_PCIGART_PAGES * sizeof(u32) );
|
||||
|
||||
for ( i = 0 ; i < pages ; i++ ) {
|
||||
pci_gart[i] = (u32) virt_to_bus( entry->pagelist[i]->virtual );
|
||||
struct page *page = entry->pagelist[i];
|
||||
pci_gart[i] = cpu_to_le32( virt_to_bus( page->virtual ) );
|
||||
}
|
||||
|
||||
#if __i386__
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ int r128_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
buf->used = 0;
|
||||
buf->offset = (dma->byte_count + offset);
|
||||
buf->bus_address = agp_offset + offset;
|
||||
buf->address = (void *)(agp_offset + dev->agp->base + offset);
|
||||
buf->address = (void *)(agp_offset + offset + dev->agp->base);
|
||||
buf->next = NULL;
|
||||
buf->waiting = 0;
|
||||
buf->pending = 0;
|
||||
|
|
|
|||
126
linux/r128_cce.c
126
linux/r128_cce.c
|
|
@ -129,12 +129,8 @@ static void r128_status( drm_r128_private_t *dev_priv )
|
|||
(unsigned int)R128_READ( R128_PM4_MICRO_CNTL ) );
|
||||
printk( "PM4_BUFFER_CNTL = 0x%08x\n",
|
||||
(unsigned int)R128_READ( R128_PM4_BUFFER_CNTL ) );
|
||||
printk( "PM4_BUFFER_DL_WPTR = 0x%08x\n",
|
||||
(unsigned int)R128_READ( R128_PM4_BUFFER_DL_WPTR ) );
|
||||
printk( "PM4_BUFFER_DL_RPTR = 0x%08x\n",
|
||||
(unsigned int)R128_READ( R128_PM4_BUFFER_DL_RPTR ) );
|
||||
printk( "*ring.head = 0x%08x\n",
|
||||
(unsigned int)*dev_priv->ring.head );
|
||||
(unsigned int) GET_RING_HEAD( dev_priv ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -158,7 +154,7 @@ static int r128_do_pixcache_flush( drm_r128_private_t *dev_priv )
|
|||
udelay( 1 );
|
||||
}
|
||||
|
||||
DRM_ERROR( "%s failed!\n", __FUNCTION__ );
|
||||
DRM_ERROR( "failed!\n" );
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
|
|
@ -172,7 +168,7 @@ static int r128_do_wait_for_fifo( drm_r128_private_t *dev_priv, int entries )
|
|||
udelay( 1 );
|
||||
}
|
||||
|
||||
DRM_ERROR( "%s failed!\n", __FUNCTION__ );
|
||||
DRM_ERROR( "failed!\n" );
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
|
|
@ -191,7 +187,7 @@ static int r128_do_wait_for_idle( drm_r128_private_t *dev_priv )
|
|||
udelay( 1 );
|
||||
}
|
||||
|
||||
DRM_ERROR( "%s failed!\n", __FUNCTION__ );
|
||||
DRM_ERROR( "failed!\n" );
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
|
|
@ -235,7 +231,7 @@ int r128_do_cce_idle( drm_r128_private_t *dev_priv )
|
|||
int i;
|
||||
|
||||
for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
|
||||
if ( *dev_priv->ring.head == dev_priv->ring.tail ) {
|
||||
if ( GET_RING_HEAD( dev_priv ) == dev_priv->ring.tail ) {
|
||||
u32 pm4stat = R128_READ( R128_PM4_STAT );
|
||||
if ( ( (pm4stat & R128_PM4_FIFOCNT_MASK) >=
|
||||
dev_priv->cce_fifo_size ) &&
|
||||
|
|
@ -248,7 +244,7 @@ int r128_do_cce_idle( drm_r128_private_t *dev_priv )
|
|||
}
|
||||
|
||||
#if R128_FIFO_DEBUG
|
||||
DRM_ERROR( "cce idle failed!\n" );
|
||||
DRM_ERROR( "failed!\n" );
|
||||
r128_status( dev_priv );
|
||||
#endif
|
||||
return -EBUSY;
|
||||
|
|
@ -276,7 +272,8 @@ static void r128_do_cce_reset( drm_r128_private_t *dev_priv )
|
|||
{
|
||||
R128_WRITE( R128_PM4_BUFFER_DL_WPTR, 0 );
|
||||
R128_WRITE( R128_PM4_BUFFER_DL_RPTR, 0 );
|
||||
*dev_priv->ring.head = 0;
|
||||
|
||||
SET_RING_HEAD( dev_priv, 0 );
|
||||
dev_priv->ring.tail = 0;
|
||||
}
|
||||
|
||||
|
|
@ -355,7 +352,7 @@ static void r128_cce_init_ring_buffer( drm_device_t *dev )
|
|||
R128_WRITE( R128_PM4_BUFFER_DL_RPTR, 0 );
|
||||
|
||||
/* DL_RPTR_ADDR is a physical address in AGP space. */
|
||||
*dev_priv->ring.head = 0;
|
||||
SET_RING_HEAD( dev_priv, 0 );
|
||||
if ( !dev_priv->is_pci ) {
|
||||
R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR,
|
||||
dev_priv->ring_rptr->offset );
|
||||
|
|
@ -537,6 +534,8 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
|
|||
dev_priv->ring.tail_mask =
|
||||
(dev_priv->ring.size / sizeof(u32)) - 1;
|
||||
|
||||
dev_priv->ring.high_mark = 128;
|
||||
|
||||
dev_priv->sarea_priv->last_frame = 0;
|
||||
R128_WRITE( R128_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame );
|
||||
|
||||
|
|
@ -546,18 +545,15 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
|
|||
|
||||
if ( dev_priv->is_pci ) {
|
||||
dev_priv->phys_pci_gart = ati_pcigart_init( dev );
|
||||
if( dev_priv->phys_pci_gart == 0 ) {
|
||||
if ( !dev_priv->phys_pci_gart ) {
|
||||
DRM_ERROR( "failed to init PCI GART!\n" );
|
||||
drm_free( dev_priv, sizeof(*dev_priv),
|
||||
DRM_MEM_DRIVER );
|
||||
drm_free( dev_priv, sizeof(*dev_priv),
|
||||
DRM_MEM_DRIVER );
|
||||
dev->dev_private = NULL;
|
||||
return -EINVAL;
|
||||
}
|
||||
DRM_DEBUG( "%s: writing PCI_GART_PAGE...\n", __FUNCTION__ );
|
||||
R128_WRITE( R128_PCI_GART_PAGE,
|
||||
R128_WRITE( R128_PCI_GART_PAGE,
|
||||
virt_to_bus( (void *)dev_priv->phys_pci_gart ) );
|
||||
DRM_DEBUG( "%s: writing PCI_GART_PAGE... done.\n",
|
||||
__FUNCTION__ );
|
||||
}
|
||||
|
||||
r128_cce_init_ring_buffer( dev );
|
||||
|
|
@ -570,30 +566,28 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
|
|||
u32 last_dispatch;
|
||||
RING_LOCALS;
|
||||
|
||||
printk( "GUI_STAT = 0x%08x\n",
|
||||
(unsigned int)R128_READ( R128_GUI_STAT ) );
|
||||
printk( "PM4_STAT = 0x%08x\n",
|
||||
(unsigned int)R128_READ( R128_PM4_STAT ) );
|
||||
printk( "PM4_BUFFER_DL_WPTR = 0x%08x\n",
|
||||
(unsigned int)R128_READ( R128_PM4_BUFFER_DL_WPTR ) );
|
||||
printk( "PM4_BUFFER_DL_RPTR = 0x%08x\n",
|
||||
(unsigned int)R128_READ( R128_PM4_BUFFER_DL_RPTR ) );
|
||||
printk( "PM4_MICRO_CNTL = 0x%08x\n",
|
||||
(unsigned int)R128_READ( R128_PM4_MICRO_CNTL ) );
|
||||
printk( "PM4_BUFFER_CNTL = 0x%08x\n",
|
||||
(unsigned int)R128_READ( R128_PM4_BUFFER_CNTL ) );
|
||||
printk( "PM4_BUFFER_OFFSET = 0x%08x\n",
|
||||
(unsigned int)R128_READ( R128_PM4_BUFFER_OFFSET ) );
|
||||
printk( "PM4_BUFFER_DL_RPTR_ADDR = 0x%08x\n",
|
||||
(unsigned int)R128_READ( R128_PM4_BUFFER_DL_RPTR_ADDR ));
|
||||
printk( "PCI_GART_PAGE = 0x%08x\n",
|
||||
(unsigned int)R128_READ( R128_PCI_GART_PAGE ) );
|
||||
printk( "BM_CHUNK_0_VAL = 0x%08x\n",
|
||||
(unsigned int)R128_READ( R128_BM_CHUNK_0_VAL ) );
|
||||
DRM_INFO( "GUI_STAT = 0x%08x\n",
|
||||
(unsigned int)R128_READ( R128_GUI_STAT ) );
|
||||
DRM_INFO( "PM4_STAT = 0x%08x\n",
|
||||
(unsigned int)R128_READ( R128_PM4_STAT ) );
|
||||
DRM_INFO( "PM4_BUFFER_DL_WPTR = 0x%08x\n",
|
||||
(unsigned int)R128_READ( R128_PM4_BUFFER_DL_WPTR ) );
|
||||
DRM_INFO( "PM4_BUFFER_DL_RPTR = 0x%08x\n",
|
||||
(unsigned int)R128_READ( R128_PM4_BUFFER_DL_RPTR ) );
|
||||
DRM_INFO( "PM4_MICRO_CNTL = 0x%08x\n",
|
||||
(unsigned int)R128_READ( R128_PM4_MICRO_CNTL ) );
|
||||
DRM_INFO( "PM4_BUFFER_CNTL = 0x%08x\n",
|
||||
(unsigned int)R128_READ( R128_PM4_BUFFER_CNTL ) );
|
||||
DRM_INFO( "PM4_BUFFER_OFFSET = 0x%08x\n",
|
||||
(unsigned int)R128_READ( R128_PM4_BUFFER_OFFSET ) );
|
||||
DRM_INFO( "PCI_GART_PAGE = 0x%08x\n",
|
||||
(unsigned int)R128_READ( R128_PCI_GART_PAGE ) );
|
||||
DRM_INFO( "BM_CHUNK_0_VAL = 0x%08x\n",
|
||||
(unsigned int)R128_READ( R128_BM_CHUNK_0_VAL ) );
|
||||
|
||||
r128_do_cce_start( dev_priv );
|
||||
|
||||
printk("Doing a test write to dispatch register\n");
|
||||
DRM_INFO("Doing a test write to dispatch register\n");
|
||||
|
||||
BEGIN_RING( 2 );
|
||||
OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) );
|
||||
|
|
@ -603,7 +597,7 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
|
|||
r128_do_cce_flush( dev_priv );
|
||||
r128_do_cce_idle( dev_priv );
|
||||
last_dispatch = R128_READ( R128_LAST_DISPATCH_REG );
|
||||
printk("last_dispatch = 0x%x\n", last_dispatch);
|
||||
DRM_INFO("last_dispatch = 0x%x\n", last_dispatch);
|
||||
|
||||
BEGIN_RING( 2 );
|
||||
OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) );
|
||||
|
|
@ -613,11 +607,13 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
|
|||
r128_do_cce_flush( dev_priv );
|
||||
r128_do_cce_idle( dev_priv );
|
||||
last_dispatch = R128_READ( R128_LAST_DISPATCH_REG );
|
||||
printk("last_dispatch 2 = 0x%x\n", last_dispatch);
|
||||
DRM_INFO("last_dispatch 2 = 0x%x\n", last_dispatch);
|
||||
|
||||
r128_do_wait_for_idle( dev_priv );
|
||||
r128_do_engine_reset( dev );
|
||||
r128_do_wait_for_idle( dev_priv );
|
||||
|
||||
r128_status( dev_priv );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -673,11 +669,8 @@ int r128_cce_start( struct inode *inode, struct file *filp,
|
|||
drm_r128_private_t *dev_priv = dev->dev_private;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
|
||||
dev->lock.pid != current->pid ) {
|
||||
DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
|
||||
return -EINVAL;
|
||||
}
|
||||
LOCK_TEST_WITH_RETURN( dev );
|
||||
|
||||
if ( dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4 ) {
|
||||
DRM_DEBUG( "%s while CCE running\n", __FUNCTION__ );
|
||||
return 0;
|
||||
|
|
@ -701,11 +694,7 @@ int r128_cce_stop( struct inode *inode, struct file *filp,
|
|||
int ret;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
|
||||
dev->lock.pid != current->pid ) {
|
||||
DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
|
||||
return -EINVAL;
|
||||
}
|
||||
LOCK_TEST_WITH_RETURN( dev );
|
||||
|
||||
if ( copy_from_user( &stop, (drm_r128_init_t *)arg, sizeof(stop) ) )
|
||||
return -EFAULT;
|
||||
|
|
@ -747,11 +736,8 @@ int r128_cce_reset( struct inode *inode, struct file *filp,
|
|||
drm_r128_private_t *dev_priv = dev->dev_private;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
|
||||
dev->lock.pid != current->pid ) {
|
||||
DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
|
||||
return -EINVAL;
|
||||
}
|
||||
LOCK_TEST_WITH_RETURN( dev );
|
||||
|
||||
if ( !dev_priv ) {
|
||||
DRM_DEBUG( "%s called before init done\n", __FUNCTION__ );
|
||||
return -EINVAL;
|
||||
|
|
@ -773,11 +759,7 @@ int r128_cce_idle( struct inode *inode, struct file *filp,
|
|||
drm_r128_private_t *dev_priv = dev->dev_private;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
|
||||
dev->lock.pid != current->pid ) {
|
||||
DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
|
||||
return -EINVAL;
|
||||
}
|
||||
LOCK_TEST_WITH_RETURN( dev );
|
||||
|
||||
if ( dev_priv->cce_running ) {
|
||||
r128_do_cce_flush( dev_priv );
|
||||
|
|
@ -793,11 +775,7 @@ int r128_engine_reset( struct inode *inode, struct file *filp,
|
|||
drm_device_t *dev = priv->dev;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
|
||||
dev->lock.pid != current->pid ) {
|
||||
DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
|
||||
return -EINVAL;
|
||||
}
|
||||
LOCK_TEST_WITH_RETURN( dev );
|
||||
|
||||
return r128_do_engine_reset( dev );
|
||||
}
|
||||
|
|
@ -846,11 +824,7 @@ int r128_fullscreen( struct inode *inode, struct file *filp,
|
|||
drm_device_t *dev = priv->dev;
|
||||
drm_r128_fullscreen_t fs;
|
||||
|
||||
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
|
||||
dev->lock.pid != current->pid ) {
|
||||
DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
|
||||
return -EINVAL;
|
||||
}
|
||||
LOCK_TEST_WITH_RETURN( dev );
|
||||
|
||||
if ( copy_from_user( &fs, (drm_r128_fullscreen_t *)arg, sizeof(fs) ) )
|
||||
return -EFAULT;
|
||||
|
|
@ -1041,15 +1015,11 @@ int r128_cce_buffers( struct inode *inode, struct file *filp,
|
|||
int ret = 0;
|
||||
drm_dma_t d;
|
||||
|
||||
LOCK_TEST_WITH_RETURN( dev );
|
||||
|
||||
if ( copy_from_user( &d, (drm_dma_t *) arg, sizeof(d) ) )
|
||||
return -EFAULT;
|
||||
|
||||
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
|
||||
dev->lock.pid != current->pid ) {
|
||||
DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Please don't send us buffers.
|
||||
*/
|
||||
if ( d.send_count != 0 ) {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
#define R128_NAME "r128"
|
||||
#define R128_DESC "ATI Rage 128"
|
||||
#define R128_DATE "20010123"
|
||||
#define R128_DATE "20010130"
|
||||
#define R128_MAJOR 2
|
||||
#define R128_MINOR 1
|
||||
#define R128_PATCHLEVEL 4
|
||||
|
|
@ -571,12 +571,6 @@ int r128_ioctl(struct inode *inode, struct file *filp,
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if ( retcode ) {
|
||||
DRM_INFO( "%s 0x%x ret = %d\n", __FUNCTION__, nr, retcode );
|
||||
}
|
||||
#endif
|
||||
|
||||
atomic_dec(&dev->ioctl_count);
|
||||
return retcode;
|
||||
}
|
||||
|
|
|
|||
137
linux/r128_drv.h
137
linux/r128_drv.h
|
|
@ -32,11 +32,11 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "ati_pcigart.h"
|
||||
|
||||
#ifndef __R128_DRV_H__
|
||||
#define __R128_DRV_H__
|
||||
|
||||
#include "ati_pcigart.h"
|
||||
|
||||
typedef struct drm_r128_freelist {
|
||||
unsigned int age;
|
||||
drm_buf_t *buf;
|
||||
|
|
@ -54,6 +54,8 @@ typedef struct drm_r128_ring_buffer {
|
|||
u32 tail;
|
||||
u32 tail_mask;
|
||||
int space;
|
||||
|
||||
int high_mark;
|
||||
} drm_r128_ring_buffer_t;
|
||||
|
||||
typedef struct drm_r128_private {
|
||||
|
|
@ -196,6 +198,7 @@ extern int r128_rmctx(struct inode *inode, struct file *filp,
|
|||
extern int r128_context_switch(drm_device_t *dev, int old, int new);
|
||||
extern int r128_context_switch_complete(drm_device_t *dev, int new);
|
||||
|
||||
|
||||
/* Register definitions, register access macros and drmAddMap constants
|
||||
* for Rage 128 kernel driver.
|
||||
*/
|
||||
|
|
@ -271,9 +274,6 @@ extern int r128_context_switch_complete(drm_device_t *dev, int new);
|
|||
#define R128_GUI_SCRATCH_REG4 0x15f0
|
||||
#define R128_GUI_SCRATCH_REG5 0x15f4
|
||||
|
||||
#define R128_WAIT_UNTIL 0x1720
|
||||
#define R128_EVENT_CRTC_OFFSET (1 << 0)
|
||||
|
||||
#define R128_GUI_STAT 0x1740
|
||||
# define R128_GUI_FIFOCNT_MASK 0x0fff
|
||||
# define R128_GUI_ACTIVE (1 << 31)
|
||||
|
|
@ -302,6 +302,8 @@ extern int r128_context_switch_complete(drm_device_t *dev, int new);
|
|||
#define R128_TEX_CNTL_C 0x1c9c
|
||||
# define R128_TEX_CACHE_FLUSH (1 << 23)
|
||||
|
||||
#define R128_WAIT_UNTIL 0x1720
|
||||
# define R128_EVENT_CRTC_OFFSET (1 << 0)
|
||||
#define R128_WINDOW_XY_OFFSET 0x1bcc
|
||||
|
||||
|
||||
|
|
@ -409,59 +411,20 @@ extern int r128_context_switch_complete(drm_device_t *dev, int new);
|
|||
#define R128_MAX_VB_AGE 0x7fffffff
|
||||
#define R128_MAX_VB_VERTS (0xffff)
|
||||
|
||||
#define R128_PERFORMANCE_BOXES 0
|
||||
|
||||
|
||||
#define R128_BASE(reg) ((u32)(dev_priv->mmio->handle))
|
||||
#define R128_ADDR(reg) (R128_BASE(reg) + reg)
|
||||
|
||||
#ifdef __powerpc__
|
||||
|
||||
static __inline__ void
|
||||
WriteMmio32Le(int *base, const unsigned long offset,
|
||||
const unsigned long val)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"stwbrx %1,%2,%3\n\t"
|
||||
: "=m" (*(volatile int *)(base+offset))
|
||||
: "r" (val), "b" (base), "r" (offset));
|
||||
}
|
||||
|
||||
static __inline__ unsigned int
|
||||
ReadMmio32Le(int *base, const unsigned long offset)
|
||||
{
|
||||
register unsigned int val;
|
||||
__asm__ __volatile__(
|
||||
"lwbrx %0,%1,%2\n\t"
|
||||
"eieio"
|
||||
: "=r" (val)
|
||||
: "b" (base), "r" (offset),
|
||||
"m" (*(volatile int *)(base+offset)));
|
||||
return(val);
|
||||
}
|
||||
|
||||
#define R128_READ(reg) ReadMmio32Le((int *)R128_BASE(reg),reg)
|
||||
#define R128_WRITE(reg,val) WriteMmio32Le((int *)R128_BASE(reg),reg,val)
|
||||
|
||||
#else /* ! __powerpc__; FIXME: other big endian machines need their own code here */
|
||||
|
||||
#define R128_DEREF(reg) *(__volatile__ u32 *)R128_ADDR(reg)
|
||||
#define R128_READ(reg) R128_DEREF(reg)
|
||||
#define R128_WRITE(reg,val) do { R128_DEREF(reg) = val; } while (0)
|
||||
|
||||
#endif /* __powerpc__ */
|
||||
#define R128_DEREF(reg) *(volatile u32 *)R128_ADDR(reg)
|
||||
#define R128_READ(reg) le32_to_cpu( R128_DEREF(reg) )
|
||||
#define R128_WRITE(reg,val) do { R128_DEREF(reg) = cpu_to_le32(val); } while (0)
|
||||
|
||||
#define R128_DEREF8(reg) *(__volatile__ u8 *)R128_ADDR(reg)
|
||||
#define R128_READ8(reg) R128_DEREF8(reg)
|
||||
#define R128_WRITE8(reg,val) do { R128_DEREF8(reg) = val; } while (0)
|
||||
|
||||
#define VB_AGE_CHECK_WITH_RET( dev_priv ) \
|
||||
do { \
|
||||
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; \
|
||||
if ( sarea_priv->last_dispatch >= R128_MAX_VB_AGE ) { \
|
||||
int __ret = r128_do_cce_idle( dev_priv ); \
|
||||
if ( __ret < 0 ) return __ret; \
|
||||
sarea_priv->last_dispatch = 0; \
|
||||
r128_freelist_reset( dev ); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define R128_WRITE_PLL(addr,val) \
|
||||
do { \
|
||||
|
|
@ -471,13 +434,6 @@ do { \
|
|||
|
||||
extern u32 R128_READ_PLL(drm_device_t *dev, int addr);
|
||||
|
||||
#define R128CCE0(p,r,n) ((p) | ((n) << 16) | ((r) >> 2))
|
||||
#define R128CCE1(p,r1,r2) ((p) | (((r2) >> 2) << 11) | ((r1) >> 2))
|
||||
#define R128CCE2(p) ((p))
|
||||
#define R128CCE3(p,n) ((p) | ((n) << 16))
|
||||
|
||||
|
||||
|
||||
|
||||
#define CCE_PACKET0( reg, n ) (R128_CCE_PACKET0 | \
|
||||
((n) << 16) | ((reg) >> 2))
|
||||
|
|
@ -488,7 +444,61 @@ extern u32 R128_READ_PLL(drm_device_t *dev, int addr);
|
|||
(pkt) | ((n) << 16))
|
||||
|
||||
|
||||
#define r128_flush_write_combine() mb()
|
||||
/* ================================================================
|
||||
* Misc helper macros
|
||||
*/
|
||||
|
||||
#define LOCK_TEST_WITH_RETURN( dev ) \
|
||||
do { \
|
||||
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \
|
||||
dev->lock.pid != current->pid ) { \
|
||||
DRM_ERROR( "%s called without lock held\n", \
|
||||
__FUNCTION__ ); \
|
||||
return -EINVAL; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \
|
||||
do { \
|
||||
drm_r128_ring_buffer_t *ring = &dev_priv->ring; int i; \
|
||||
if ( ring->space < ring->high_mark ) { \
|
||||
for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { \
|
||||
ring->space = *ring->head - ring->tail; \
|
||||
if ( ring->space <= 0 ) \
|
||||
ring->space += ring->size; \
|
||||
if ( ring->space >= ring->high_mark ) \
|
||||
goto __ring_space_done; \
|
||||
udelay( 1 ); \
|
||||
} \
|
||||
DRM_ERROR( "ring space check failed!\n" ); \
|
||||
return -EBUSY; \
|
||||
} \
|
||||
__ring_space_done: \
|
||||
} while (0)
|
||||
|
||||
#define VB_AGE_TEST_WITH_RETURN( dev_priv ) \
|
||||
do { \
|
||||
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; \
|
||||
if ( sarea_priv->last_dispatch >= R128_MAX_VB_AGE ) { \
|
||||
int __ret = r128_do_cce_idle( dev_priv ); \
|
||||
if ( __ret < 0 ) return __ret; \
|
||||
sarea_priv->last_dispatch = 0; \
|
||||
r128_freelist_reset( dev ); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define R128_WAIT_UNTIL_PAGE_FLIPPED() \
|
||||
do { \
|
||||
OUT_RING( CCE_PACKET0( R128_WAIT_UNTIL, 0 ) ); \
|
||||
OUT_RING( R128_EVENT_CRTC_OFFSET ); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* ================================================================
|
||||
* Ring control
|
||||
*/
|
||||
|
||||
#define r128_flush_write_combine() mb()
|
||||
|
||||
|
||||
#define R128_VERBOSE 0
|
||||
|
|
@ -524,16 +534,11 @@ extern u32 R128_READ_PLL(drm_device_t *dev, int addr);
|
|||
DRM_INFO( " OUT_RING( 0x%08x ) at 0x%x\n", \
|
||||
(unsigned int)(x), write ); \
|
||||
} \
|
||||
ring[write++] = (x); \
|
||||
ring[write++] = cpu_to_le32( x ); \
|
||||
write &= tail_mask; \
|
||||
} while (0)
|
||||
|
||||
#define R128_WAIT_UNTIL_PAGE_FLIPPED() \
|
||||
do { \
|
||||
OUT_RING( CCE_PACKET0( R128_WAIT_UNTIL, 0 ) ); \
|
||||
OUT_RING( R128_EVENT_CRTC_OFFSET ); \
|
||||
} while (0)
|
||||
|
||||
#define R128_PERFORMANCE_BOXES 0
|
||||
#define GET_RING_HEAD( dev_priv ) le32_to_cpu( *dev_priv->ring.head )
|
||||
#define SET_RING_HEAD( dev_priv, val ) *dev_priv->ring.head = cpu_to_le32( val )
|
||||
|
||||
#endif /* __R128_DRV_H__ */
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include "drmP.h"
|
||||
#include "r128_drv.h"
|
||||
#include "drm.h"
|
||||
#include <linux/delay.h>
|
||||
|
||||
|
||||
/* ================================================================
|
||||
|
|
@ -372,7 +373,7 @@ static void r128_cce_dispatch_clear( drm_device_t *dev,
|
|||
u32 fb_bpp, depth_bpp;
|
||||
int i;
|
||||
RING_LOCALS;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
DRM_DEBUG( "%s:\n", __FUNCTION__ );
|
||||
|
||||
r128_update_ring_snapshot( dev_priv );
|
||||
|
||||
|
|
@ -398,7 +399,7 @@ static void r128_cce_dispatch_clear( drm_device_t *dev,
|
|||
return;
|
||||
}
|
||||
|
||||
if ( dev_priv->page_flipping && dev_priv->current_page == 1) {
|
||||
if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) {
|
||||
unsigned int tmp = flags;
|
||||
|
||||
flags &= ~(R128_FRONT | R128_BACK);
|
||||
|
|
@ -581,7 +582,6 @@ static void r128_cce_dispatch_flip( drm_device_t *dev )
|
|||
BEGIN_RING( 4 );
|
||||
|
||||
R128_WAIT_UNTIL_PAGE_FLIPPED();
|
||||
|
||||
OUT_RING( CCE_PACKET0( R128_CRTC_OFFSET, 0 ) );
|
||||
|
||||
if ( dev_priv->current_page == 0 ) {
|
||||
|
|
@ -620,8 +620,8 @@ static void r128_cce_dispatch_vertex( drm_device_t *dev,
|
|||
int prim = buf_priv->prim;
|
||||
int i = 0;
|
||||
RING_LOCALS;
|
||||
DRM_DEBUG( "%s: buf=%d nbox=%d\n",
|
||||
__FUNCTION__, buf->idx, sarea_priv->nbox );
|
||||
DRM_DEBUG( "%s: buf=%d nbox=%d used=%d\n",
|
||||
__FUNCTION__, buf->idx, sarea_priv->nbox, buf->used );
|
||||
|
||||
r128_update_ring_snapshot( dev_priv );
|
||||
|
||||
|
|
@ -660,7 +660,7 @@ static void r128_cce_dispatch_vertex( drm_device_t *dev,
|
|||
}
|
||||
|
||||
if ( buf_priv->discard ) {
|
||||
buf_priv->age = dev_priv->sarea_priv->last_dispatch;
|
||||
buf_priv->age = sarea_priv->last_dispatch;
|
||||
|
||||
/* Emit the vertex buffer age */
|
||||
BEGIN_RING( 2 );
|
||||
|
|
@ -676,7 +676,7 @@ static void r128_cce_dispatch_vertex( drm_device_t *dev,
|
|||
buf_priv->dispatched = 0;
|
||||
}
|
||||
|
||||
dev_priv->sarea_priv->last_dispatch++;
|
||||
sarea_priv->last_dispatch++;
|
||||
|
||||
sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS;
|
||||
sarea_priv->nbox = 0;
|
||||
|
|
@ -695,7 +695,7 @@ static void r128_cce_dispatch_indirect( drm_device_t *dev,
|
|||
r128_update_ring_snapshot( dev_priv );
|
||||
|
||||
if ( start != end ) {
|
||||
int offset = (buf->bus_address + start);
|
||||
int offset = buf->bus_address + start;
|
||||
int dwords = (end - start + 3) / sizeof(u32);
|
||||
|
||||
/* Indirect buffer data must be an even number of
|
||||
|
|
@ -706,7 +706,7 @@ static void r128_cce_dispatch_indirect( drm_device_t *dev,
|
|||
u32 *data = (u32 *)
|
||||
((char *)dev_priv->buffers->handle
|
||||
+ buf->offset + start);
|
||||
data[dwords++] = R128_CCE_PACKET2;
|
||||
data[dwords++] = cpu_to_le32( R128_CCE_PACKET2 );
|
||||
}
|
||||
|
||||
buf_priv->dispatched = 1;
|
||||
|
|
@ -775,16 +775,20 @@ static void r128_cce_dispatch_indices( drm_device_t *dev,
|
|||
data = (u32 *)((char *)dev_priv->buffers->handle
|
||||
+ buf->offset + start);
|
||||
|
||||
data[0] = CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM, dwords-2 );
|
||||
|
||||
data[1] = offset;
|
||||
data[2] = R128_MAX_VB_VERTS;
|
||||
data[3] = format;
|
||||
data[4] = (prim | R128_CCE_VC_CNTL_PRIM_WALK_IND |
|
||||
(count << 16));
|
||||
data[0] = cpu_to_le32( CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM,
|
||||
dwords-2 ) );
|
||||
data[1] = cpu_to_le32( offset );
|
||||
data[2] = cpu_to_le32( R128_MAX_VB_VERTS );
|
||||
data[3] = cpu_to_le32( format );
|
||||
data[4] = cpu_to_le32( (prim | R128_CCE_VC_CNTL_PRIM_WALK_IND |
|
||||
(count << 16)) );
|
||||
|
||||
if ( count & 0x1 ) {
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
data[dwords-1] &= 0x0000ffff;
|
||||
#else
|
||||
data[dwords-1] &= 0xffff0000;
|
||||
#endif
|
||||
}
|
||||
|
||||
do {
|
||||
|
|
@ -892,23 +896,24 @@ static int r128_cce_dispatch_blit( drm_device_t *dev,
|
|||
|
||||
data = (u32 *)((char *)dev_priv->buffers->handle + buf->offset);
|
||||
|
||||
data[0] = CCE_PACKET3( R128_CNTL_HOSTDATA_BLT, dwords + 6 );
|
||||
data[1] = (R128_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
R128_GMC_BRUSH_NONE |
|
||||
(blit->format << 8) |
|
||||
R128_GMC_SRC_DATATYPE_COLOR |
|
||||
R128_ROP3_S |
|
||||
R128_DP_SRC_SOURCE_HOST_DATA |
|
||||
R128_GMC_CLR_CMP_CNTL_DIS |
|
||||
R128_GMC_AUX_CLIP_DIS |
|
||||
R128_GMC_WR_MSK_DIS);
|
||||
data[0] = cpu_to_le32( CCE_PACKET3( R128_CNTL_HOSTDATA_BLT,
|
||||
dwords + 6 ) );
|
||||
data[1] = cpu_to_le32( R128_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
R128_GMC_BRUSH_NONE |
|
||||
(blit->format << 8) |
|
||||
R128_GMC_SRC_DATATYPE_COLOR |
|
||||
R128_ROP3_S |
|
||||
R128_DP_SRC_SOURCE_HOST_DATA |
|
||||
R128_GMC_CLR_CMP_CNTL_DIS |
|
||||
R128_GMC_AUX_CLIP_DIS |
|
||||
R128_GMC_WR_MSK_DIS );
|
||||
|
||||
data[2] = (blit->pitch << 21) | (blit->offset >> 5);
|
||||
data[3] = 0xffffffff;
|
||||
data[4] = 0xffffffff;
|
||||
data[5] = (blit->y << 16) | blit->x;
|
||||
data[6] = (blit->height << 16) | blit->width;
|
||||
data[7] = dwords;
|
||||
data[2] = cpu_to_le32( (blit->pitch << 21) | (blit->offset >> 5) );
|
||||
data[3] = cpu_to_le32( 0xffffffff );
|
||||
data[4] = cpu_to_le32( 0xffffffff );
|
||||
data[5] = cpu_to_le32( (blit->y << 16) | blit->x );
|
||||
data[6] = cpu_to_le32( (blit->height << 16) | blit->width );
|
||||
data[7] = cpu_to_le32( dwords );
|
||||
|
||||
buf->used = (dwords + 8) * sizeof(u32);
|
||||
|
||||
|
|
@ -1351,16 +1356,14 @@ int r128_cce_clear( struct inode *inode, struct file *filp,
|
|||
drm_r128_clear_t clear;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
|
||||
dev->lock.pid != current->pid ) {
|
||||
DRM_ERROR( "r128_cce_clear called without lock held\n" );
|
||||
return -EINVAL;
|
||||
}
|
||||
LOCK_TEST_WITH_RETURN( dev );
|
||||
|
||||
if ( copy_from_user( &clear, (drm_r128_clear_t *) arg,
|
||||
sizeof(clear) ) )
|
||||
return -EFAULT;
|
||||
|
||||
RING_SPACE_TEST_WITH_RETURN( dev_priv );
|
||||
|
||||
if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS )
|
||||
sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
|
||||
|
||||
|
|
@ -1384,11 +1387,9 @@ int r128_cce_swap( struct inode *inode, struct file *filp,
|
|||
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
|
||||
dev->lock.pid != current->pid ) {
|
||||
DRM_ERROR( "r128_cce_swap called without lock held\n" );
|
||||
return -EINVAL;
|
||||
}
|
||||
LOCK_TEST_WITH_RETURN( dev );
|
||||
|
||||
RING_SPACE_TEST_WITH_RETURN( dev_priv );
|
||||
|
||||
if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS )
|
||||
sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
|
||||
|
|
@ -1415,11 +1416,8 @@ int r128_cce_vertex( struct inode *inode, struct file *filp,
|
|||
drm_r128_buf_priv_t *buf_priv;
|
||||
drm_r128_vertex_t vertex;
|
||||
|
||||
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
|
||||
dev->lock.pid != current->pid ) {
|
||||
DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
|
||||
return -EINVAL;
|
||||
}
|
||||
LOCK_TEST_WITH_RETURN( dev );
|
||||
|
||||
if ( !dev_priv )
|
||||
return -EINVAL;
|
||||
|
||||
|
|
@ -1442,7 +1440,8 @@ int r128_cce_vertex( struct inode *inode, struct file *filp,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
VB_AGE_CHECK_WITH_RET( dev_priv );
|
||||
RING_SPACE_TEST_WITH_RETURN( dev_priv );
|
||||
VB_AGE_TEST_WITH_RETURN( dev_priv );
|
||||
|
||||
buf = dma->buflist[vertex.idx];
|
||||
buf_priv = buf->dev_private;
|
||||
|
|
@ -1478,11 +1477,8 @@ int r128_cce_indices( struct inode *inode, struct file *filp,
|
|||
drm_r128_indices_t elts;
|
||||
int count;
|
||||
|
||||
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
|
||||
dev->lock.pid != current->pid ) {
|
||||
DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
|
||||
return -EINVAL;
|
||||
}
|
||||
LOCK_TEST_WITH_RETURN( dev );
|
||||
|
||||
if ( !dev_priv )
|
||||
return -EINVAL;
|
||||
|
||||
|
|
@ -1505,7 +1501,8 @@ int r128_cce_indices( struct inode *inode, struct file *filp,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
VB_AGE_CHECK_WITH_RET( dev_priv );
|
||||
RING_SPACE_TEST_WITH_RETURN( dev_priv );
|
||||
VB_AGE_TEST_WITH_RETURN( dev_priv );
|
||||
|
||||
buf = dma->buflist[elts.idx];
|
||||
buf_priv = buf->dev_private;
|
||||
|
|
@ -1550,11 +1547,7 @@ int r128_cce_blit( struct inode *inode, struct file *filp,
|
|||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_r128_blit_t blit;
|
||||
|
||||
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
|
||||
dev->lock.pid != current->pid ) {
|
||||
DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
|
||||
return -EINVAL;
|
||||
}
|
||||
LOCK_TEST_WITH_RETURN( dev );
|
||||
|
||||
if ( copy_from_user( &blit, (drm_r128_blit_t *)arg,
|
||||
sizeof(blit) ) )
|
||||
|
|
@ -1569,7 +1562,8 @@ int r128_cce_blit( struct inode *inode, struct file *filp,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
VB_AGE_CHECK_WITH_RET( dev_priv );
|
||||
RING_SPACE_TEST_WITH_RETURN( dev_priv );
|
||||
VB_AGE_TEST_WITH_RETURN( dev_priv );
|
||||
|
||||
return r128_cce_dispatch_blit( dev, &blit );
|
||||
}
|
||||
|
|
@ -1579,18 +1573,17 @@ int r128_cce_depth( struct inode *inode, struct file *filp,
|
|||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_r128_private_t *dev_priv = dev->dev_private;
|
||||
drm_r128_depth_t depth;
|
||||
|
||||
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
|
||||
dev->lock.pid != current->pid ) {
|
||||
DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
|
||||
return -EINVAL;
|
||||
}
|
||||
LOCK_TEST_WITH_RETURN( dev );
|
||||
|
||||
if ( copy_from_user( &depth, (drm_r128_depth_t *)arg,
|
||||
sizeof(depth) ) )
|
||||
return -EFAULT;
|
||||
|
||||
RING_SPACE_TEST_WITH_RETURN( dev_priv );
|
||||
|
||||
switch ( depth.func ) {
|
||||
case R128_WRITE_SPAN:
|
||||
return r128_cce_dispatch_write_span( dev, &depth );
|
||||
|
|
@ -1610,14 +1603,11 @@ int r128_cce_stipple( struct inode *inode, struct file *filp,
|
|||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_r128_private_t *dev_priv = dev->dev_private;
|
||||
drm_r128_stipple_t stipple;
|
||||
u32 mask[32];
|
||||
|
||||
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
|
||||
dev->lock.pid != current->pid ) {
|
||||
DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
|
||||
return -EINVAL;
|
||||
}
|
||||
LOCK_TEST_WITH_RETURN( dev );
|
||||
|
||||
if ( copy_from_user( &stipple, (drm_r128_stipple_t *)arg,
|
||||
sizeof(stipple) ) )
|
||||
|
|
@ -1627,6 +1617,8 @@ int r128_cce_stipple( struct inode *inode, struct file *filp,
|
|||
32 * sizeof(u32) ) )
|
||||
return -EFAULT;
|
||||
|
||||
RING_SPACE_TEST_WITH_RETURN( dev_priv );
|
||||
|
||||
r128_cce_dispatch_stipple( dev, mask );
|
||||
|
||||
return 0;
|
||||
|
|
@ -1638,11 +1630,7 @@ int r128_cce_indirect( struct inode *inode, struct file *filp,
|
|||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
|
||||
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
|
||||
dev->lock.pid != current->pid ) {
|
||||
DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
|
||||
return -EINVAL;
|
||||
}
|
||||
LOCK_TEST_WITH_RETURN( dev );
|
||||
|
||||
/* Indirect buffer firing is not supported at this time.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue