diff options
-rw-r--r-- | linux-core/radeon_drv.c | 10 | ||||
-rw-r--r-- | linux/Makefile.linux | 2 | ||||
-rw-r--r-- | linux/radeon_bufs.c | 188 | ||||
-rw-r--r-- | linux/radeon_cp.c | 271 | ||||
-rw-r--r-- | linux/radeon_drv.c | 10 | ||||
-rw-r--r-- | linux/radeon_drv.h | 4 | ||||
-rw-r--r-- | linux/radeon_state.c | 2 |
7 files changed, 440 insertions, 47 deletions
diff --git a/linux-core/radeon_drv.c b/linux-core/radeon_drv.c index 0113ed97..7441880a 100644 --- a/linux-core/radeon_drv.c +++ b/linux-core/radeon_drv.c @@ -104,7 +104,9 @@ static drm_ioctl_desc_t radeon_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 }, #endif - + [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = { drm_sg_alloc, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = { drm_sg_free, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_INIT)] = { radeon_cp_init, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_START)] = { radeon_cp_start, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_STOP)] = { radeon_cp_stop, 1, 1 }, @@ -305,6 +307,12 @@ static int radeon_takedown(drm_device_t *dev) /* Do nothing here, because this is all handled in the AGP/GART driver. */ break; + case _DRM_SCATTER_GATHER: + if (dev->sg) { + drm_sg_cleanup(dev->sg); + dev->sg = NULL; + } + break; } drm_free(map, sizeof(*map), DRM_MEM_MAPS); } diff --git a/linux/Makefile.linux b/linux/Makefile.linux index 677353c9..58b963e0 100644 --- a/linux/Makefile.linux +++ b/linux/Makefile.linux @@ -147,7 +147,7 @@ R128OBJS= r128_drv.o r128_cce.o r128_bufs.o r128_context.o r128_state.o \ R128HEADERS= r128_drv.h r128_drm.h $(DRMHEADERS) RADEONOBJS= radeon_drv.o radeon_cp.o radeon_bufs.o radeon_context.o \ - radeon_state.o + radeon_state.o ati_pcigart.o RADEONHEADERS= radeon_drv.h radeon_drm.h $(DRMHEADERS) ifeq ($(SIS),1) diff --git a/linux/radeon_bufs.c b/linux/radeon_bufs.c index 9a3093eb..abcbd8da 100644 --- a/linux/radeon_bufs.c +++ b/linux/radeon_bufs.c @@ -37,8 +37,8 @@ #if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) -int radeon_addbufs_agp(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +int radeon_addbufs_agp(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; @@ -57,9 +57,12 @@ int radeon_addbufs_agp(struct inode *inode, struct file *filp, int byte_count; int i; + printk("%s\n", __FUNCTION__); if (!dma) return -EINVAL; - if (copy_from_user(&request, (drm_buf_desc_t *)arg, sizeof(request))) + if (copy_from_user(&request, + (drm_buf_desc_t *)arg, + sizeof(request))) return -EFAULT; count = request.count; @@ -71,7 +74,7 @@ int radeon_addbufs_agp(struct inode *inode, struct file *filp, total = PAGE_SIZE << page_order; byte_count = 0; - agp_offset = dev->agp->base + request.agp_start; + agp_offset = request.agp_start; DRM_DEBUG("count: %d\n", count); DRM_DEBUG("order: %d\n", order); @@ -122,7 +125,8 @@ int radeon_addbufs_agp(struct inode *inode, struct file *filp, buf->order = order; buf->used = 0; buf->offset = (dma->byte_count + offset); - buf->address = (void *)(agp_offset + offset); + buf->bus_address = agp_offset + offset; + buf->address = (void *)(agp_offset + dev->agp->base + offset); buf->next = NULL; buf->waiting = 0; buf->pending = 0; @@ -170,7 +174,9 @@ int radeon_addbufs_agp(struct inode *inode, struct file *filp, request.count = entry->buf_count; request.size = size; - if (copy_to_user((drm_buf_desc_t *)arg, &request, sizeof(request))) + if (copy_to_user((drm_buf_desc_t *)arg, + &request, + sizeof(request))) return -EFAULT; dma->flags = _DRM_DMA_USE_AGP; @@ -180,6 +186,153 @@ int radeon_addbufs_agp(struct inode *inode, struct file *filp, } #endif +int radeon_addbufs_sg(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_device_dma_t *dma = dev->dma; + drm_buf_desc_t request; + drm_buf_entry_t *entry; + drm_buf_t *buf; + unsigned long offset; + unsigned long agp_offset; + int count; + int order; + int size; + int alignment; + int page_order; + int total; + int byte_count; + int i; + + printk("%s\n", __FUNCTION__); + if (!dma) return -EINVAL; + + if (copy_from_user(&request, + (drm_buf_desc_t *)arg, + sizeof(request))) + return -EFAULT; + + count = request.count; + order = drm_order(request.size); + size = 1 << order; + + alignment = (request.flags & _DRM_PAGE_ALIGN) ? PAGE_ALIGN(size):size; + page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; + total = PAGE_SIZE << page_order; + + byte_count = 0; + agp_offset = request.agp_start; + + DRM_DEBUG("count: %d\n", count); + DRM_DEBUG("order: %d\n", order); + DRM_DEBUG("size: %d\n", size); + DRM_DEBUG("agp_offset: %ld\n", agp_offset); + DRM_DEBUG("alignment: %d\n", alignment); + DRM_DEBUG("page_order: %d\n", page_order); + DRM_DEBUG("total: %d\n", total); + + if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL; + if (dev->queue_count) return -EBUSY; /* Not while in use */ + + spin_lock(&dev->count_lock); + if (dev->buf_use) { + spin_unlock(&dev->count_lock); + return -EBUSY; + } + atomic_inc(&dev->buf_alloc); + spin_unlock(&dev->count_lock); + + down(&dev->struct_sem); + entry = &dma->bufs[order]; + if (entry->buf_count) { + up(&dev->struct_sem); + atomic_dec(&dev->buf_alloc); + return -ENOMEM; /* May only call once for each order */ + } + + entry->buflist = drm_alloc(count * sizeof(*entry->buflist), + DRM_MEM_BUFS); + if (!entry->buflist) { + up(&dev->struct_sem); + atomic_dec(&dev->buf_alloc); + return -ENOMEM; + } + memset(entry->buflist, 0, count * sizeof(*entry->buflist)); + + entry->buf_size = size; + entry->page_order = page_order; + offset = 0; + + for (offset = 0; + entry->buf_count < count; + offset += alignment, ++entry->buf_count) { + buf = &entry->buflist[entry->buf_count]; + buf->idx = dma->buf_count + entry->buf_count; + buf->total = alignment; + buf->order = order; + buf->used = 0; + buf->offset = (dma->byte_count + offset); + buf->bus_address = agp_offset + offset; + buf->address = (void *)(agp_offset + dev->sg->handle + offset); + buf->next = NULL; + buf->waiting = 0; + buf->pending = 0; + init_waitqueue_head(&buf->dma_wait); + buf->pid = 0; + + buf->dev_priv_size = sizeof(drm_radeon_buf_priv_t); + buf->dev_private = drm_alloc(sizeof(drm_radeon_buf_priv_t), + DRM_MEM_BUFS); + memset(buf->dev_private, 0, buf->dev_priv_size); + +#if DRM_DMA_HISTOGRAM + buf->time_queued = 0; + buf->time_dispatched = 0; + buf->time_completed = 0; + buf->time_freed = 0; +#endif + + byte_count += PAGE_SIZE << page_order; + + DRM_DEBUG("buffer %d @ %p\n", + entry->buf_count, buf->address); + } + + DRM_DEBUG("byte_count: %d\n", byte_count); + + dma->buflist = drm_realloc(dma->buflist, + dma->buf_count * sizeof(*dma->buflist), + (dma->buf_count + entry->buf_count) + * sizeof(*dma->buflist), + DRM_MEM_BUFS); + for (i = dma->buf_count; i < dma->buf_count + entry->buf_count; i++) + dma->buflist[i] = &entry->buflist[i - dma->buf_count]; + + dma->buf_count += entry->buf_count; + dma->byte_count += byte_count; + + drm_freelist_create(&entry->freelist, entry->buf_count); + for (i = 0; i < entry->buf_count; i++) { + drm_freelist_put(dev, &entry->freelist, &entry->buflist[i]); + } + + up(&dev->struct_sem); + + request.count = entry->buf_count; + request.size = size; + + if (copy_to_user((drm_buf_desc_t *)arg, + &request, + sizeof(request))) + return -EFAULT; + dma->flags = _DRM_DMA_USE_SG; + + atomic_dec(&dev->buf_alloc); + return 0; +} + int radeon_addbufs(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -188,7 +341,8 @@ int radeon_addbufs(struct inode *inode, struct file *filp, unsigned int cmd, drm_radeon_private_t *dev_priv = dev->dev_private; drm_buf_desc_t request; - if (!dev_priv || dev_priv->is_pci) return -EINVAL; + printk("%s\n", __FUNCTION__); + if (!dev_priv) return -EINVAL; if (copy_from_user(&request, (drm_buf_desc_t *)arg, sizeof(request))) return -EFAULT; @@ -196,13 +350,16 @@ int radeon_addbufs(struct inode *inode, struct file *filp, unsigned int cmd, #if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) if (request.flags & _DRM_AGP_BUFFER) return radeon_addbufs_agp(inode, filp, cmd, arg); - else #endif + if (request.flags & _DRM_SG_BUFFER) { + return radeon_addbufs_sg(inode, filp, cmd, arg); + } else { return -EINVAL; + } } int radeon_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) + unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; @@ -215,7 +372,7 @@ int radeon_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd, drm_buf_map_t request; int i; - if (!dma || !dev_priv || dev_priv->is_pci) return -EINVAL; + if (!dma || !dev_priv) return -EINVAL; DRM_DEBUG("\n"); @@ -227,11 +384,14 @@ int radeon_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd, ++dev->buf_use; /* Can't allocate more after this call */ spin_unlock(&dev->count_lock); - if (copy_from_user(&request, (drm_buf_map_t *)arg, sizeof(request))) + if (copy_from_user(&request, + (drm_buf_map_t *)arg, + sizeof(request))) return -EFAULT; if (request.count >= dma->buf_count) { - if (dma->flags & _DRM_DMA_USE_AGP) { + if (dma->flags & _DRM_DMA_USE_AGP || + dma->flags & _DRM_DMA_USE_SG) { drm_map_t *map; map = dev_priv->buffers; @@ -291,7 +451,9 @@ int radeon_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd, request.count = dma->buf_count; DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode); - if (copy_to_user((drm_buf_map_t *)arg, &request, sizeof(request))) + if (copy_to_user((drm_buf_map_t *)arg, + &request, + sizeof(request))) return -EFAULT; return retcode; 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; diff --git a/linux/radeon_drv.c b/linux/radeon_drv.c index 0113ed97..7441880a 100644 --- a/linux/radeon_drv.c +++ b/linux/radeon_drv.c @@ -104,7 +104,9 @@ static drm_ioctl_desc_t radeon_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 }, #endif - + [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = { drm_sg_alloc, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = { drm_sg_free, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_INIT)] = { radeon_cp_init, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_START)] = { radeon_cp_start, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_STOP)] = { radeon_cp_stop, 1, 1 }, @@ -305,6 +307,12 @@ static int radeon_takedown(drm_device_t *dev) /* Do nothing here, because this is all handled in the AGP/GART driver. */ break; + case _DRM_SCATTER_GATHER: + if (dev->sg) { + drm_sg_cleanup(dev->sg); + dev->sg = NULL; + } + break; } drm_free(map, sizeof(*map), DRM_MEM_MAPS); } diff --git a/linux/radeon_drv.h b/linux/radeon_drv.h index 06b54199..61f86ae9 100644 --- a/linux/radeon_drv.h +++ b/linux/radeon_drv.h @@ -30,6 +30,8 @@ * */ +#include "ati_pcigart.h" + #ifndef __RADEON_DRV_H__ #define __RADEON_DRV_H__ @@ -107,6 +109,8 @@ typedef struct drm_radeon_private { drm_radeon_depth_clear_t depth_clear; + unsigned long phys_pci_gart; + drm_map_t *sarea; drm_map_t *fb; drm_map_t *mmio; diff --git a/linux/radeon_state.c b/linux/radeon_state.c index 7bfefb2c..73e6dcbd 100644 --- a/linux/radeon_state.c +++ b/linux/radeon_state.c @@ -1385,7 +1385,7 @@ int radeon_cp_indirect( struct inode *inode, struct file *filp, DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); return -EINVAL; } - if ( !dev_priv || dev_priv->is_pci ) { + if ( !dev_priv ) { DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ ); return -EINVAL; } |