summaryrefslogtreecommitdiff
path: root/linux/radeon_cp.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux/radeon_cp.c')
-rw-r--r--linux/radeon_cp.c271
1 files changed, 241 insertions, 30 deletions
diff --git a/linux/radeon_cp.c b/linux/radeon_cp.c
index 5d662bc0..a9817e1d 100644
--- a/linux/radeon_cp.c
+++ b/linux/radeon_cp.c
@@ -331,12 +331,12 @@ int RADEON_READ_PLL(drm_device_t *dev, int addr)
#if RADEON_FIFO_DEBUG
static void radeon_status( drm_radeon_private_t *dev_priv )
{
- printk( "%s:\n", __FUNCTION__ );
- printk( "RBBM_STATUS = 0x%08x\n",
+ DRM_DEBUG( "%s:\n", __FUNCTION__ );
+ DRM_DEBUG( "RBBM_STATUS = 0x%08x\n",
(unsigned int)RADEON_READ( RADEON_RBBM_STATUS ) );
- printk( "CP_RB_RTPR = 0x%08x\n",
+ DRM_DEBUG( "CP_RB_RTPR = 0x%08x\n",
(unsigned int)RADEON_READ( RADEON_CP_RB_RPTR ) );
- printk( "CP_RB_WTPR = 0x%08x\n",
+ DRM_DEBUG( "CP_RB_WTPR = 0x%08x\n",
(unsigned int)RADEON_READ( RADEON_CP_RB_WPTR ) );
}
#endif
@@ -351,6 +351,7 @@ static int radeon_do_pixcache_flush( drm_radeon_private_t *dev_priv )
u32 tmp;
int i;
+ DRM_DEBUG("%s\n", __FUNCTION__);
tmp = RADEON_READ( RADEON_RB2D_DSTCACHE_CTLSTAT );
tmp |= RADEON_RB2D_DC_FLUSH_ALL;
RADEON_WRITE( RADEON_RB2D_DSTCACHE_CTLSTAT, tmp );
@@ -375,6 +376,7 @@ static int radeon_do_wait_for_fifo( drm_radeon_private_t *dev_priv,
{
int i;
+ DRM_DEBUG("%s\n", __FUNCTION__);
for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
int slots = ( RADEON_READ( RADEON_RBBM_STATUS )
& RADEON_RBBM_FIFOCNT_MASK );
@@ -393,6 +395,8 @@ static int radeon_do_wait_for_idle( drm_radeon_private_t *dev_priv )
{
int i, ret;
+ DRM_DEBUG("%s\n", __FUNCTION__);
+
ret = radeon_do_wait_for_fifo( dev_priv, 64 );
if ( ret < 0 ) return ret;
@@ -422,6 +426,7 @@ static void radeon_cp_load_microcode( drm_radeon_private_t *dev_priv )
{
int i;
+ DRM_DEBUG("%s\n", __FUNCTION__);
radeon_do_wait_for_idle( dev_priv );
RADEON_WRITE( RADEON_CP_ME_RAM_ADDR, 0 );
@@ -453,6 +458,7 @@ int radeon_do_cp_idle( drm_radeon_private_t *dev_priv )
{
RING_LOCALS;
+ DRM_DEBUG("%s\n", __FUNCTION__);
BEGIN_RING( 6 );
RADEON_PURGE_CACHE();
@@ -472,6 +478,7 @@ static void radeon_do_cp_start( drm_radeon_private_t *dev_priv )
radeon_do_wait_for_idle( dev_priv );
+ DRM_DEBUG("%s\n", __FUNCTION__);
RADEON_WRITE( RADEON_CP_CSQ_CNTL, dev_priv->cp_mode );
dev_priv->cp_running = 1;
@@ -493,6 +500,7 @@ static void radeon_do_cp_reset( drm_radeon_private_t *dev_priv )
{
u32 cur_read_ptr;
+ DRM_DEBUG("%s\n", __FUNCTION__);
cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR );
RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr );
*dev_priv->ring.head = cur_read_ptr;
@@ -505,6 +513,7 @@ static void radeon_do_cp_reset( drm_radeon_private_t *dev_priv )
*/
static void radeon_do_cp_stop( drm_radeon_private_t *dev_priv )
{
+ DRM_DEBUG("%s\n", __FUNCTION__);
RADEON_WRITE( RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS );
dev_priv->cp_running = 0;
@@ -516,7 +525,8 @@ static int radeon_do_engine_reset( drm_device_t *dev )
{
drm_radeon_private_t *dev_priv = dev->dev_private;
u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset;
- DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+ DRM_DEBUG("%s\n", __FUNCTION__);
radeon_do_pixcache_flush( dev_priv );
@@ -566,12 +576,120 @@ static int radeon_do_engine_reset( drm_device_t *dev )
return 0;
}
-static void radeon_cp_init_ring_buffer( drm_device_t *dev )
+#define RADEON_AGP_BASE 0x0170
+#define RADEON_AIC_LO_ADDR 0x01dc
+#define RADEON_AIC_HI_ADDR 0x01e0
+#define RADEON_AIC_TLB_ADDR 0x01e4
+#define RADEON_AIC_TLB_DATA 0x01e8
+#define RADEON_AIC_PT_BASE 0x01d8
+
+
+static int radeon_cp_init_pciring( drm_device_t *dev )
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ u32 ring_start, cur_read_ptr;
+ unsigned int temp, temp2, rdata;
+
+ DRM_DEBUG("%s\n", __FUNCTION__);
+ dev_priv->phys_pci_gart = ati_pcigart_init( dev );
+ if (!dev_priv->phys_pci_gart ) return -ENOMEM;
+
+ /* Initialize the memory controller */
+ RADEON_WRITE( RADEON_MC_FB_LOCATION,
+ (dev_priv->agp_vm_start - 1) & 0xffff0000 );
+ RADEON_WRITE( RADEON_MC_AGP_LOCATION,
+ (((dev_priv->agp_vm_start - 1 +
+ dev_priv->agp_size) & 0xffff0000) |
+ (dev_priv->agp_vm_start >> 16)) );
+
+ RADEON_WRITE( RADEON_AGP_BASE,
+ 0 );
+
+ temp = RADEON_READ( RADEON_MC_FB_LOCATION ) | 0x0000ffff;
+ temp2 = RADEON_READ( RADEON_MC_AGP_LOCATION ) | 0x0000ffff;
+
+ if (temp > temp2) {
+ DRM_DEBUG("rdata is MC_FB_LOCATION\n");
+ rdata = temp + 1;
+ } else {
+ DRM_DEBUG("rdata is MC_AGP_LOCATION\n");
+ rdata = temp2 + 1;
+ }
+ RADEON_WRITE( RADEON_AIC_LO_ADDR,
+ rdata & 0xfffff000 );
+ rdata += (dev_priv->agp_size);
+ DRM_DEBUG("dev_priv->agp_size : %d\n", dev_priv->agp_size);
+ RADEON_WRITE( RADEON_AIC_HI_ADDR,
+ rdata & 0xfffff000 );
+ DRM_DEBUG("virtual phys_pci_gart (%08x), bus phys_pci_gart (%08x)\n",
+ dev_priv->phys_pci_gart,
+ virt_to_bus((void *)dev_priv->phys_pci_gart) );
+ RADEON_WRITE( RADEON_AIC_PT_BASE,
+ virt_to_bus((void *)dev_priv->phys_pci_gart) );
+
+ temp = RADEON_READ( RADEON_AIC_CNTL ) | RADEON_PCIGART_TRANSLATE_EN;
+ RADEON_WRITE( RADEON_AIC_CNTL, temp );
+
+ temp = RADEON_READ( RADEON_AIC_TLB_ADDR );
+ DRM_DEBUG("AIC_TLB_ADDR = %08x\n", temp);
+ temp = RADEON_READ( RADEON_AIC_TLB_DATA );
+ DRM_DEBUG("AIC_TLB_DATA = %08x\n", temp);
+
+ ring_start = (dev_priv->cp_ring->offset
+ - dev->sg->handle
+ + dev_priv->agp_vm_start);
+
+ RADEON_WRITE( RADEON_CP_RB_BASE, ring_start );
+
+ /* Set the write pointer delay */
+ RADEON_WRITE( RADEON_CP_RB_WPTR_DELAY, 0 );
+
+ /* Initialize the ring buffer's read and write pointers */
+ cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR );
+ RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr );
+ *dev_priv->ring.head = cur_read_ptr;
+ dev_priv->ring.tail = cur_read_ptr;
+
+ {
+ drm_sg_mem_t *entry = dev->sg;
+ unsigned long tmp_ofs, page_ofs;
+
+ tmp_ofs = dev_priv->ring_rptr->offset - entry->handle;
+ page_ofs = tmp_ofs >> PAGE_SHIFT;
+
+ DRM_DEBUG("tmp_ofs (%08x), page_ofs (%d), bus_addr (%08x)\n",
+ tmp_ofs, page_ofs,
+ virt_to_bus(entry->pagelist[page_ofs]->virtual));
+
+ RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR,
+ virt_to_bus(entry->pagelist[page_ofs]->virtual) );
+ }
+
+ /* Set ring buffer size */
+ RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw );
+
+ radeon_do_wait_for_idle( dev_priv );
+
+ /* Turn on bus mastering */
+ temp = RADEON_READ( RADEON_BUS_CNTL ) & ~RADEON_BUS_MASTER_DIS;
+ RADEON_WRITE( RADEON_BUS_CNTL, temp );
+
+ /* Sync everything up */
+ RADEON_WRITE( RADEON_ISYNC_CNTL,
+ (RADEON_ISYNC_ANY2D_IDLE3D |
+ RADEON_ISYNC_ANY3D_IDLE2D |
+ RADEON_ISYNC_WAIT_IDLEGUI |
+ RADEON_ISYNC_CPSCRATCH_IDLEGUI) );
+ return 0;
+}
+
+static void radeon_cp_init_agpring( drm_device_t *dev )
{
drm_radeon_private_t *dev_priv = dev->dev_private;
u32 ring_start, cur_read_ptr;
u32 tmp;
+ DRM_DEBUG("%s\n", __FUNCTION__);
/* Initialize the memory controller */
RADEON_WRITE( RADEON_MC_FB_LOCATION,
(dev_priv->agp_vm_start - 1) & 0xffff0000 );
@@ -621,8 +739,9 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev )
static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
{
drm_radeon_private_t *dev_priv;
- int i;
+ int i, j = 0;
+ DRM_DEBUG("%s : %d\n", __FUNCTION__, j++);
dev_priv = drm_alloc( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER );
if ( dev_priv == NULL )
return -ENOMEM;
@@ -632,16 +751,6 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
dev_priv->is_pci = init->is_pci;
- /* We don't support PCI cards until PCI GART is implemented.
- * Fail here so we can remove all checks for PCI cards around
- * the CP ring code.
- */
- if ( dev_priv->is_pci ) {
- drm_free( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
- dev->dev_private = NULL;
- return -EINVAL;
- }
-
dev_priv->usec_timeout = init->usec_timeout;
if ( dev_priv->usec_timeout < 1 ||
dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT ) {
@@ -666,6 +775,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
dev->dev_private = NULL;
return -EINVAL;
}
+ DRM_DEBUG("%s : %d\n", __FUNCTION__, j++);
switch ( init->fb_bpp ) {
case 16:
@@ -757,9 +867,18 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
(drm_radeon_sarea_t *)((u8 *)dev_priv->sarea->handle +
init->sarea_priv_offset);
- DO_IOREMAP( dev_priv->cp_ring );
- DO_IOREMAP( dev_priv->ring_rptr );
- DO_IOREMAP( dev_priv->buffers );
+ if ( !dev_priv->is_pci ) {
+ DO_IOREMAP( dev_priv->cp_ring );
+ DO_IOREMAP( dev_priv->ring_rptr );
+ DO_IOREMAP( dev_priv->buffers );
+ } else {
+ dev_priv->cp_ring->handle = (void *)dev_priv->cp_ring->offset;
+ dev_priv->ring_rptr->handle =
+ (void *)dev_priv->ring_rptr->offset;
+ dev_priv->buffers->handle =
+ (void *)dev_priv->buffers->offset;
+ }
+
#if 0
if ( !dev_priv->is_pci ) {
DO_IOREMAP( dev_priv->agp_textures );
@@ -768,9 +887,15 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
dev_priv->agp_size = init->agp_size;
dev_priv->agp_vm_start = RADEON_READ( RADEON_CONFIG_APER_SIZE );
- dev_priv->agp_buffers_offset = (dev_priv->buffers->offset
- - dev->agp->base
- + dev_priv->agp_vm_start);
+
+ if ( !dev_priv->is_pci )
+ dev_priv->agp_buffers_offset = (dev_priv->buffers->offset
+ - dev->agp->base
+ + dev_priv->agp_vm_start);
+ else
+ dev_priv->agp_buffers_offset = (dev_priv->buffers->offset
+ - dev->sg->handle
+ + dev_priv->agp_vm_start);
dev_priv->ring.head = ((__volatile__ u32 *)
dev_priv->ring_rptr->handle);
@@ -813,24 +938,105 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
dev_priv->sarea_priv->last_clear );
radeon_cp_load_microcode( dev_priv );
- radeon_cp_init_ring_buffer( dev );
+
+ DRM_DEBUG("%s : %d\n", __FUNCTION__, j++);
+
+ if ( !dev_priv->is_pci ) radeon_cp_init_agpring( dev );
+ else if ( radeon_cp_init_pciring( dev ) ) {
+ drm_free( dev->dev_private, sizeof(drm_radeon_private_t),
+ DRM_MEM_DRIVER );
+ dev->dev_private = NULL;
+ return -ENOMEM;
+ }
+
radeon_do_engine_reset( dev );
#if ROTATE_BUFS
dev_priv->last_buf = 0;
#endif
+#define DEBUG_RING_AFTER_INIT 1
+#if DEBUG_RING_AFTER_INIT
+ {
+ u32 last_dispatch;
+ RING_LOCALS;
+
+ DRM_DEBUG( "RBBM_STATUS = 0x%08x\n",
+ (unsigned int)RADEON_READ( RADEON_RBBM_STATUS ) );
+ DRM_DEBUG( "MC_FB_LOCATION = 0x%08x\n",
+ (unsigned int)RADEON_READ(RADEON_MC_FB_LOCATION) );
+ DRM_DEBUG( "MC_AGP_LOCATION = 0x%08x\n",
+ (unsigned int)RADEON_READ(RADEON_MC_AGP_LOCATION));
+ DRM_DEBUG( "AIC_LO_ADDR = 0x%08x\n",
+ (unsigned int)RADEON_READ(RADEON_AIC_LO_ADDR));
+ DRM_DEBUG( "AIC_HI_ADDR = 0x%08x\n",
+ (unsigned int)RADEON_READ(RADEON_AIC_HI_ADDR));
+ DRM_DEBUG( "AIC_PT_BASE = 0x%08x\n",
+ (unsigned int)RADEON_READ(RADEON_AIC_PT_BASE));
+ DRM_DEBUG( "AIC_CNTL = 0x%08x\n",
+ (unsigned int)RADEON_READ(RADEON_AIC_CNTL));
+ DRM_DEBUG( "CP_RB_BASE = 0x%08x\n",
+ (unsigned int)RADEON_READ(RADEON_CP_RB_BASE));
+ DRM_DEBUG( "CP_RB_WPTR_DELAY = 0x%08x\n",
+ (unsigned int)RADEON_READ(RADEON_CP_RB_WPTR_DELAY));
+ DRM_DEBUG( "CP_RB_RPTR = 0x%08x\n",
+ (unsigned int)RADEON_READ(RADEON_CP_RB_RPTR));
+ DRM_DEBUG( "CP_RB_WPTR = 0x%08x\n",
+ (unsigned int)RADEON_READ(RADEON_CP_RB_WPTR));
+ DRM_DEBUG( "CP_RB_RPTR_ADDR = 0x%08x\n",
+ (unsigned int)RADEON_READ(RADEON_CP_RB_RPTR_ADDR));
+ DRM_DEBUG( "CP_RB_CNTL = 0x%08x\n",
+ (unsigned int)RADEON_READ(RADEON_CP_RB_CNTL));
+ DRM_DEBUG( "BUS_CNTL = 0x%08x\n",
+ (unsigned int)RADEON_READ(RADEON_BUS_CNTL));
+
+ radeon_do_cp_start( dev_priv );
+
+ DRM_DEBUG("Doing a test write to dispatch register\n");
+
+ BEGIN_RING( 2 );
+ OUT_RING( CP_PACKET0( RADEON_LAST_DISPATCH_REG, 0 ) );
+ OUT_RING( 0xcafebabe );
+ ADVANCE_RING();
+
+ radeon_do_cp_flush( dev_priv );
+ radeon_do_cp_idle( dev_priv );
+ last_dispatch = RADEON_READ( RADEON_LAST_DISPATCH_REG );
+ DRM_DEBUG("last_dispatch = 0x%x\n", last_dispatch);
+
+ BEGIN_RING( 2 );
+ OUT_RING( CP_PACKET0( RADEON_LAST_DISPATCH_REG, 0 ) );
+ OUT_RING( 0 );
+ ADVANCE_RING();
+
+ radeon_do_cp_flush( dev_priv );
+ radeon_do_cp_idle( dev_priv );
+ last_dispatch = RADEON_READ( RADEON_LAST_DISPATCH_REG );
+ DRM_DEBUG("last_dispatch 2 = 0x%x\n", last_dispatch);
+
+ radeon_do_wait_for_idle( dev_priv );
+ radeon_do_engine_reset( dev );
+ radeon_do_wait_for_idle( dev_priv );
+ }
+#endif
+
+ DRM_DEBUG("Returning zero\n");
+
return 0;
}
static int radeon_do_cleanup_cp( drm_device_t *dev )
{
+ DRM_DEBUG("%s\n", __FUNCTION__);
if ( dev->dev_private ) {
drm_radeon_private_t *dev_priv = dev->dev_private;
-
- DO_IOREMAPFREE( dev_priv->cp_ring );
- DO_IOREMAPFREE( dev_priv->ring_rptr );
- DO_IOREMAPFREE( dev_priv->buffers );
+ if ( !dev_priv->is_pci) {
+ DO_IOREMAPFREE( dev_priv->cp_ring );
+ DO_IOREMAPFREE( dev_priv->ring_rptr );
+ DO_IOREMAPFREE( dev_priv->buffers );
+ } else {
+ ati_pcigart_cleanup( dev_priv->phys_pci_gart );
+ }
#if 0
if ( !dev_priv->is_pci ) {
DO_IOREMAPFREE( dev_priv->agp_textures );
@@ -852,6 +1058,7 @@ int radeon_cp_init( struct inode *inode, struct file *filp,
drm_device_t *dev = priv->dev;
drm_radeon_init_t init;
+ DRM_DEBUG("%s\n", __FUNCTION__);
if ( copy_from_user( &init, (drm_radeon_init_t *)arg, sizeof(init) ) )
return -EFAULT;
@@ -871,7 +1078,7 @@ int radeon_cp_start( struct inode *inode, struct file *filp,
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_radeon_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG( "%s\n", __FUNCTION__ );
+ DRM_DEBUG("%s\n", __FUNCTION__);
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
dev->lock.pid != current->pid ) {
@@ -904,7 +1111,7 @@ int radeon_cp_stop( struct inode *inode, struct file *filp,
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_radeon_cp_stop_t stop;
int ret;
- DRM_DEBUG( "%s\n", __FUNCTION__ );
+ DRM_DEBUG("%s\n", __FUNCTION__);
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
dev->lock.pid != current->pid ) {
@@ -1217,6 +1424,7 @@ int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n )
drm_radeon_ring_buffer_t *ring = &dev_priv->ring;
int i;
+ DRM_DEBUG( "%s\n", __FUNCTION__ );
for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
ring->space = *ring->head - ring->tail;
if ( ring->space <= 0 )
@@ -1237,6 +1445,7 @@ void radeon_update_ring_snapshot( drm_radeon_private_t *dev_priv )
{
drm_radeon_ring_buffer_t *ring = &dev_priv->ring;
+ DRM_DEBUG( "%s\n", __FUNCTION__ );
ring->space = *ring->head - ring->tail;
if ( ring->space == 0 )
atomic_inc( &dev_priv->idle_count );
@@ -1249,6 +1458,7 @@ static int radeon_cp_get_buffers( drm_device_t *dev, drm_dma_t *d )
int i;
drm_buf_t *buf;
+ DRM_DEBUG( "%s\n", __FUNCTION__ );
for ( i = d->granted_count ; i < d->request_count ; i++ ) {
buf = radeon_freelist_get( dev );
if ( !buf ) return -EAGAIN;
@@ -1276,6 +1486,7 @@ int radeon_cp_buffers( struct inode *inode, struct file *filp,
int ret = 0;
drm_dma_t d;
+ DRM_DEBUG( "%s\n", __FUNCTION__ );
if ( copy_from_user( &d, (drm_dma_t *) arg, sizeof(d) ) )
return -EFAULT;