summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGareth Hughes <gareth@users.sourceforge.net>2001-01-01 12:51:30 +0000
committerGareth Hughes <gareth@users.sourceforge.net>2001-01-01 12:51:30 +0000
commit5f32ef20720647e117845295fbe706ce39b28685 (patch)
tree64e9a545682028c272bad9c02c93dc258a08efb7
parent7c213c834b226e952faf2e1174e40b39350643d6 (diff)
- Removal of SubmitPackets routines, replaced with root-only indirect
buffer firing. Currently only implemented in Radeon driver. - Force old "UseCPFor2D" option to be on in Radeon driver and remove it. CP must be running (and stay running) for direct rendering support. - Cleanup of basic CP acceleration in Radeon driver for better interaction with direct rendering clients (hardware state cleanup for 2D and so on). - Better fullscreen mode support.
-rw-r--r--linux-core/r128_drv.c44
-rw-r--r--linux-core/radeon_drv.c48
-rw-r--r--linux/drm.h23
-rw-r--r--linux/r128_cce.c421
-rw-r--r--linux/r128_drm.h33
-rw-r--r--linux/r128_drv.c44
-rw-r--r--linux/r128_drv.h26
-rw-r--r--linux/r128_state.c281
-rw-r--r--linux/radeon_cp.c416
-rw-r--r--linux/radeon_drm.h23
-rw-r--r--linux/radeon_drv.c48
-rw-r--r--linux/radeon_drv.h65
-rw-r--r--linux/radeon_state.c110
-rw-r--r--shared-core/drm.h23
-rw-r--r--shared/drm.h23
15 files changed, 557 insertions, 1071 deletions
diff --git a/linux-core/r128_drv.c b/linux-core/r128_drv.c
index dbfc9b74..cf258925 100644
--- a/linux-core/r128_drv.c
+++ b/linux-core/r128_drv.c
@@ -37,10 +37,10 @@
#define R128_NAME "r128"
#define R128_DESC "ATI Rage 128"
-#define R128_DATE "20001215"
+#define R128_DATE "20010101"
#define R128_MAJOR 2
#define R128_MINOR 1
-#define R128_PATCHLEVEL 2
+#define R128_PATCHLEVEL 4
static drm_device_t r128_device;
drm_ctx_t r128_res_ctx;
@@ -108,20 +108,22 @@ static drm_ioctl_desc_t r128_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 },
#endif
- [DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)] = { r128_cce_init, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_START)] = { r128_cce_start, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_STOP)] = { r128_cce_stop, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_RESET)] = { r128_cce_reset, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_IDLE)] = { r128_cce_idle, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)] = { r128_engine_reset, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_SWAP)] = { r128_cce_swap, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_CLEAR)] = { r128_cce_clear, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_cce_vertex, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)] = { r128_cce_indices, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)] = { r128_cce_blit, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_DEPTH)] = { r128_cce_depth, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)] = { r128_cce_stipple, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_PACKET)] = { r128_cce_packet, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)] = { r128_cce_init, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_START)] = { r128_cce_start, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_STOP)] = { r128_cce_stop, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_RESET)] = { r128_cce_reset, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_IDLE)] = { r128_cce_idle, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)] = { r128_engine_reset, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_FULLSCREEN)]= { r128_fullscreen, 1, 0 },
+
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_SWAP)] = { r128_cce_swap, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_CLEAR)] = { r128_cce_clear, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_cce_vertex, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)] = { r128_cce_indices, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)] = { r128_cce_blit, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_DEPTH)] = { r128_cce_depth, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)] = { r128_cce_stipple, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_INDIRECT)] = { r128_cce_indirect, 1, 1 },
};
#define R128_IOCTL_COUNT DRM_ARRAY_SIZE(r128_ioctls)
@@ -489,7 +491,17 @@ int r128_release(struct inode *inode, struct file *filp)
lock_kernel();
dev = priv->dev;
+
DRM_DEBUG("open_count = %d\n", dev->open_count);
+
+ /* Force the cleanup of page flipping when required */
+ if ( dev->dev_private ) {
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ if ( dev_priv->page_flipping ) {
+ r128_do_cleanup_pageflip( dev );
+ }
+ }
+
if (!(retcode = drm_release(inode, filp))) {
#if LINUX_VERSION_CODE < 0x020333
MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */
diff --git a/linux-core/radeon_drv.c b/linux-core/radeon_drv.c
index 93ad2f0d..07f85981 100644
--- a/linux-core/radeon_drv.c
+++ b/linux-core/radeon_drv.c
@@ -34,7 +34,7 @@
#define RADEON_NAME "radeon"
#define RADEON_DESC "ATI Radeon"
-#define RADEON_DATE "20001228"
+#define RADEON_DATE "20001230"
#define RADEON_MAJOR 1
#define RADEON_MINOR 0
#define RADEON_PATCHLEVEL 0
@@ -105,20 +105,21 @@ static drm_ioctl_desc_t radeon_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 },
#endif
- [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 },
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_RESET)]= { radeon_cp_reset, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_IDLE)] = { radeon_cp_idle, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_RESET)] = { radeon_engine_reset,1,0 },
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_PAGEFLIP)]= { radeon_cp_pageflip,1, 0 },
+ [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 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_RESET)] = { radeon_cp_reset, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_IDLE)] = { radeon_cp_idle, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_RESET)] = { radeon_engine_reset, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FULLSCREEN)] = { radeon_fullscreen, 1, 0 },
+
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_SWAP)] = { radeon_cp_swap, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CLEAR)] = { radeon_cp_clear, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX)] = { radeon_cp_vertex, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDICES)] = { radeon_cp_indices, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_BLIT)] = { radeon_cp_blit, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_STIPPLE)] = { radeon_cp_stipple, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_PACKET)] = { radeon_cp_packet, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)]= { radeon_cp_indirect,1, 1 },
};
#define RADEON_IOCTL_COUNT DRM_ARRAY_SIZE(radeon_ioctls)
@@ -612,9 +613,6 @@ int radeon_lock(struct inode *inode, struct file *filp, unsigned int cmd,
/* Contention */
atomic_inc(&dev->total_sleeps);
-#if 1
- current->policy |= SCHED_YIELD;
-#endif
schedule();
if (signal_pending(current)) {
ret = -ERESTARTSYS;
@@ -625,32 +623,6 @@ int radeon_lock(struct inode *inode, struct file *filp, unsigned int cmd,
remove_wait_queue(&dev->lock.lock_queue, &entry);
}
-#if 0
- if (!ret && dev->last_context != lock.context &&
- lock.context != radeon_res_ctx.handle &&
- dev->last_context != radeon_res_ctx.handle) {
- add_wait_queue(&dev->context_wait, &entry);
- current->state = TASK_INTERRUPTIBLE;
- /* PRE: dev->last_context != lock.context */
- radeon_context_switch(dev, dev->last_context, lock.context);
- /* POST: we will wait for the context
- switch and will dispatch on a later call
- when dev->last_context == lock.context
- NOTE WE HOLD THE LOCK THROUGHOUT THIS
- TIME! */
- current->policy |= SCHED_YIELD;
- schedule();
- current->state = TASK_RUNNING;
- remove_wait_queue(&dev->context_wait, &entry);
- if (signal_pending(current)) {
- ret = -EINTR;
- } else if (dev->last_context != lock.context) {
- DRM_ERROR("Context mismatch: %d %d\n",
- dev->last_context, lock.context);
- }
- }
-#endif
-
if (!ret) {
sigemptyset(&dev->sigmask);
sigaddset(&dev->sigmask, SIGSTOP);
diff --git a/linux/drm.h b/linux/drm.h
index b892682a..e8bccd86 100644
--- a/linux/drm.h
+++ b/linux/drm.h
@@ -370,14 +370,15 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43)
#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44)
#define DRM_IOCTL_R128_RESET DRM_IO( 0x46)
-#define DRM_IOCTL_R128_SWAP DRM_IO( 0x47)
-#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x48, drm_r128_clear_t)
-#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t)
-#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t)
-#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t)
-#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4c, drm_r128_depth_t)
-#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t)
-#define DRM_IOCTL_R128_PACKET DRM_IOWR(0x4e, drm_r128_packet_t)
+#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x47, drm_r128_fullscreen_t)
+#define DRM_IOCTL_R128_SWAP DRM_IO( 0x48)
+#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x49, drm_r128_clear_t)
+#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x4a, drm_r128_vertex_t)
+#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4b, drm_r128_indices_t)
+#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4c, drm_r128_blit_t)
+#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4d, drm_r128_depth_t)
+#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4e, drm_r128_stipple_t)
+#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(0x4f, drm_r128_indirect_t)
/* Radeon specific ioctls */
#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( 0x40, drm_radeon_init_t)
@@ -386,14 +387,14 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_RADEON_CP_RESET DRM_IO( 0x43)
#define DRM_IOCTL_RADEON_CP_IDLE DRM_IO( 0x44)
#define DRM_IOCTL_RADEON_RESET DRM_IO( 0x45)
-#define DRM_IOCTL_RADEON_PAGEFLIP DRM_IOW( 0x46, drm_radeon_pageflip_t)
+#define DRM_IOCTL_RADEON_FULLSCREEN DRM_IOW( 0x46, drm_radeon_fullscreen_t)
#define DRM_IOCTL_RADEON_SWAP DRM_IO( 0x47)
#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( 0x48, drm_radeon_clear_t)
#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( 0x49, drm_radeon_vertex_t)
#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_t)
#define DRM_IOCTL_RADEON_BLIT DRM_IOW( 0x4b, drm_radeon_blit_t)
-#define DRM_IOCTL_RADEON_STIPPLE DRM_IOWR(0x4c, drm_radeon_stipple_t)
-#define DRM_IOCTL_RADEON_PACKET DRM_IOWR(0x4d, drm_radeon_packet_t)
+#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t)
+#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t)
/* SiS specific ioctls */
#define SIS_IOCTL_FB_ALLOC DRM_IOWR(0x44, drm_sis_mem_t)
diff --git a/linux/r128_cce.c b/linux/r128_cce.c
index c2281fc5..d4035045 100644
--- a/linux/r128_cce.c
+++ b/linux/r128_cce.c
@@ -36,9 +36,8 @@
#include <linux/interrupt.h> /* For task queue support */
#include <linux/delay.h>
+#define R128_FIFO_DEBUG 0
-/* FIXME: Temporary CCE packet buffer */
-u32 r128_cce_buffer[(1 << 14)] __attribute__ ((aligned (32)));
/* CCE microcode (from ATI) */
static u32 r128_cce_microcode[] = {
@@ -114,7 +113,7 @@ int R128_READ_PLL(drm_device_t *dev, int addr)
return R128_READ(R128_CLOCK_CNTL_DATA);
}
-#if 0
+#if R128_FIFO_DEBUG
static void r128_status( drm_r128_private_t *dev_priv )
{
printk( "GUI_STAT = 0x%08x\n",
@@ -241,7 +240,7 @@ static int r128_do_cce_idle( drm_r128_private_t *dev_priv )
udelay( 1 );
}
-#if 0
+#if R128_FIFO_DEBUG
DRM_ERROR( "failed!\n" );
r128_status( dev_priv );
#endif
@@ -395,7 +394,6 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
}
dev_priv->cce_mode = init->cce_mode;
- dev_priv->cce_secure = init->cce_secure;
/* GH: Simple idle check.
*/
@@ -697,6 +695,69 @@ int r128_engine_reset( struct inode *inode, struct file *filp,
/* ================================================================
+ * Fullscreen mode
+ */
+
+static int r128_do_init_pageflip( drm_device_t *dev )
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+ dev_priv->crtc_offset = R128_READ( R128_CRTC_OFFSET );
+ dev_priv->crtc_offset_cntl = R128_READ( R128_CRTC_OFFSET_CNTL );
+
+ R128_WRITE( R128_CRTC_OFFSET, dev_priv->front_offset );
+ R128_WRITE( R128_CRTC_OFFSET_CNTL,
+ dev_priv->crtc_offset_cntl | R128_CRTC_OFFSET_FLIP_CNTL );
+
+ dev_priv->page_flipping = 1;
+ dev_priv->current_page = 0;
+
+ return 0;
+}
+
+int r128_do_cleanup_pageflip( drm_device_t *dev )
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+ R128_WRITE( R128_CRTC_OFFSET, dev_priv->crtc_offset );
+ R128_WRITE( R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl );
+
+ dev_priv->page_flipping = 0;
+ dev_priv->current_page = 0;
+
+ return 0;
+}
+
+int r128_fullscreen( 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_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;
+ }
+
+ if ( copy_from_user( &fs, (drm_r128_fullscreen_t *)arg, sizeof(fs) ) )
+ return -EFAULT;
+
+ switch ( fs.func ) {
+ case R128_INIT_FULLSCREEN:
+ return r128_do_init_pageflip( dev );
+ case R128_CLEANUP_FULLSCREEN:
+ return r128_do_cleanup_pageflip( dev );
+ }
+
+ return -EINVAL;
+}
+
+
+/* ================================================================
* Freelist management
*/
#define R128_BUFFER_USED 0xffffffff
@@ -802,7 +863,7 @@ void r128_freelist_reset( drm_device_t *dev )
/* ================================================================
- * CCE packet submission
+ * CCE command submission
*/
int r128_wait_ring( drm_r128_private_t *dev_priv, int n )
@@ -821,6 +882,8 @@ int r128_wait_ring( drm_r128_private_t *dev_priv, int n )
udelay( 1 );
}
+ /* FIXME: This is being ignored... */
+ DRM_ERROR( "failed!\n" );
return -EBUSY;
}
@@ -837,352 +900,6 @@ void r128_update_ring_snapshot( drm_r128_private_t *dev_priv )
ring->space += ring->size;
}
-#if 0
-static int r128_verify_command( drm_r128_private_t *dev_priv,
- u32 cmd, int *size )
-{
- int writing = 1;
-
- *size = 0;
-
- switch ( cmd & R128_CCE_PACKET_MASK ) {
- case R128_CCE_PACKET0:
- if ( (cmd & R128_CCE_PACKET0_REG_MASK) <= (0x1004 >> 2) &&
- (cmd & R128_CCE_PACKET0_REG_MASK) !=
- (R128_PM4_VC_FPU_SETUP >> 2) ) {
- writing = 0;
- }
- *size = ((cmd & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2;
- break;
-
- case R128_CCE_PACKET1:
- if ( (cmd & R128_CCE_PACKET1_REG0_MASK) <= (0x1004 >> 2) &&
- (cmd & R128_CCE_PACKET1_REG0_MASK) !=
- (R128_PM4_VC_FPU_SETUP >> 2) ) {
- writing = 0;
- }
- if ( (cmd & R128_CCE_PACKET1_REG1_MASK) <= (0x1004 << 9) &&
- (cmd & R128_CCE_PACKET1_REG1_MASK) !=
- (R128_PM4_VC_FPU_SETUP << 9) ) {
- writing = 0;
- }
- *size = 3;
- break;
-
- case R128_CCE_PACKET2:
- break;
-
- case R128_CCE_PACKET3:
- *size = ((cmd & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2;
- break;
-
- }
-
- return writing;
-}
-
-static int r128_submit_packet_ring_secure( drm_r128_private_t *dev_priv,
- u32 *commands, int *count )
-{
-#if 0
- int write = dev_priv->sarea_priv->ring_write;
- int *write_ptr = dev_priv->ring_start + write;
- int c = *count;
- u32 tmp = 0;
- int psize = 0;
- int writing = 1;
- int timeout;
-
- while ( c > 0 ) {
- tmp = *commands++;
- if ( !psize ) {
- writing = r128_verify_command( dev_priv, tmp, &psize );
- }
- psize--;
-
- if ( writing ) {
- write++;
- *write_ptr++ = tmp;
- }
- if ( write >= dev_priv->ring_entries ) {
- write = 0;
- write_ptr = dev_priv->ring_start;
- }
- timeout = 0;
- while ( write == *dev_priv->ring_read_ptr ) {
- R128_READ( R128_PM4_BUFFER_DL_RPTR );
- if ( timeout++ >= dev_priv->usec_timeout )
- return -EBUSY;
- udelay( 1 );
- }
- c--;
- }
-
- if ( write < 32 ) {
- memcpy( dev_priv->ring_end,
- dev_priv->ring_start,
- write * sizeof(u32) );
- }
-
- /* Make sure WC cache has been flushed */
- r128_flush_write_combine();
-
- dev_priv->sarea_priv->ring_write = write;
- R128_WRITE( R128_PM4_BUFFER_DL_WPTR, write );
-
- *count = 0;
-#endif
- return 0;
-}
-
-static int r128_submit_packet_ring_insecure( drm_r128_private_t *dev_priv,
- u32 *commands, int *count )
-{
-#if 0
- int write = dev_priv->sarea_priv->ring_write;
- int *write_ptr = dev_priv->ring_start + write;
- int c = *count;
- int timeout;
-
- while ( c > 0 ) {
- write++;
- *write_ptr++ = *commands++;
- if ( write >= dev_priv->ring_entries ) {
- write = 0;
- write_ptr = dev_priv->ring_start;
- }
-
- timeout = 0;
- while ( write == *dev_priv->ring_read_ptr ) {
- R128_READ( R128_PM4_BUFFER_DL_RPTR );
- if ( timeout++ >= dev_priv->usec_timeout )
- return -EBUSY;
- udelay( 1 );
- }
- c--;
- }
-
- if ( write < 32 ) {
- memcpy( dev_priv->ring_end,
- dev_priv->ring_start,
- write * sizeof(u32) );
- }
-
- /* Make sure WC cache has been flushed */
- r128_flush_write_combine();
-
- dev_priv->sarea_priv->ring_write = write;
- R128_WRITE( R128_PM4_BUFFER_DL_WPTR, write );
-
- *count = 0;
-#endif
- return 0;
-}
-#endif
-
-/* Internal packet submission routine. This uses the insecure versions
- * of the packet submission functions, and thus should only be used for
- * packets generated inside the kernel module.
- */
-int r128_do_submit_packet( drm_r128_private_t *dev_priv,
- u32 *buffer, int count )
-{
- int c = count;
- int ret = 0;
-
-#if 0
- int left = 0;
-
- if ( c >= dev_priv->ring_entries ) {
- c = dev_priv->ring_entries - 1;
- left = count - c;
- }
-
- /* Since this is only used by the kernel we can use the
- * insecure ring buffer submit packet routine.
- */
- ret = r128_submit_packet_ring_insecure( dev_priv, buffer, &c );
- c += left;
-#endif
-
- return ( ret < 0 ) ? ret : c;
-}
-
-/* External packet submission routine. This uses the secure versions
- * by default, and can thus submit packets received from user space.
- */
-int r128_cce_packet( 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_r128_private_t *dev_priv = dev->dev_private;
- drm_r128_packet_t packet;
- u32 *buffer;
- int c;
- int size;
- int ret = 0;
-
-#if 0
- /* GH: Disable packet submission for now.
- */
- return -EINVAL;
-#endif
-
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "r128_submit_packet called without lock held\n" );
- return -EINVAL;
- }
-
- if ( copy_from_user( &packet, (drm_r128_packet_t *)arg,
- sizeof(packet) ) )
- return -EFAULT;
-
-#if 0
- c = packet.count;
- size = c * sizeof(*buffer);
-
- {
- int left = 0;
-
- if ( c >= dev_priv->ring_entries ) {
- c = dev_priv->ring_entries - 1;
- size = c * sizeof(*buffer);
- left = packet.count - c;
- }
-
- buffer = kmalloc( size, 0 );
- if ( buffer == NULL)
- return -ENOMEM;
- if ( copy_from_user( buffer, packet.buffer, size ) )
- return -EFAULT;
-
- if ( dev_priv->cce_secure ) {
- ret = r128_submit_packet_ring_secure( dev_priv,
- buffer, &c );
- } else {
- ret = r128_submit_packet_ring_insecure( dev_priv,
- buffer, &c );
- }
- c += left;
- }
-
- kfree( buffer );
-#else
- c = 0;
-#endif
-
- packet.count = c;
- if ( copy_to_user( (drm_r128_packet_t *)arg, &packet,
- sizeof(packet) ) )
- return -EFAULT;
-
- if ( ret ) {
- return ret;
- } else if ( c > 0 ) {
- return -EAGAIN;
- }
- return 0;
-}
-
-#if 0
-static int r128_send_vertbufs( drm_device_t *dev, drm_r128_vertex_t *v )
-{
- drm_device_dma_t *dma = dev->dma;
- drm_r128_private_t *dev_priv = dev->dev_private;
- drm_r128_buf_priv_t *buf_priv;
- drm_buf_t *buf;
- int i, ret;
- RING_LOCALS;
-
- /* Make sure we have valid data */
- for (i = 0; i < v->send_count; i++) {
- int idx = v->send_indices[i];
-
- if (idx < 0 || idx >= dma->buf_count) {
- DRM_ERROR("Index %d (of %d max)\n",
- idx, dma->buf_count - 1);
- return -EINVAL;
- }
- buf = dma->buflist[idx];
- if (buf->pid != current->pid) {
- DRM_ERROR("Process %d using buffer owned by %d\n",
- current->pid, buf->pid);
- return -EINVAL;
- }
- if (buf->pending) {
- DRM_ERROR("Sending pending buffer:"
- " buffer %d, offset %d\n",
- v->send_indices[i], i);
- return -EINVAL;
- }
- }
-
- /* Wait for idle, if we've wrapped to make sure that all pending
- buffers have been processed */
- if (dev_priv->submit_age == R128_MAX_VBUF_AGE) {
- if ((ret = r128_do_cce_idle(dev)) < 0) return ret;
- dev_priv->submit_age = 0;
- r128_freelist_reset(dev);
- }
-
- /* Make sure WC cache has been flushed (if in PIO mode) */
- if (!dev_priv->cce_is_bm_mode) r128_flush_write_combine();
-
- /* FIXME: Add support for sending vertex buffer to the CCE here
- instead of in client code. The v->prim holds the primitive
- type that should be drawn. Loop over the list buffers in
- send_indices[] and submit a packet for each VB.
-
- This will require us to loop over the clip rects here as
- well, which implies that we extend the kernel driver to allow
- cliprects to be stored here. Note that the cliprects could
- possibly come from the X server instead of the client, but
- this will require additional changes to the DRI to allow for
- this optimization. */
-
- /* Submit a CCE packet that writes submit_age to R128_VB_AGE_REG */
-#if 0
- cce_buffer[0] = R128CCE0(R128_CCE_PACKET0, R128_VB_AGE_REG, 0);
- cce_buffer[1] = dev_priv->submit_age;
-
- if ((ret = r128_do_submit_packet(dev, cce_buffer, 2)) < 0) {
- /* Until we add support for sending VBs to the CCE in
- this routine, we can recover from this error. After
- we add that support, we won't be able to easily
- recover, so we will probably have to implement
- another mechanism for handling timeouts from packets
- submitted directly by the kernel. */
- return ret;
- }
-#else
- BEGIN_RING( 2 );
-
- OUT_RING( CCE_PACKET0( R128_VB_AGE_REG, 0 ) );
- OUT_RING( dev_priv->submit_age );
-
- ADVANCE_RING();
-#endif
- /* Now that the submit packet request has succeeded, we can mark
- the buffers as pending */
- for (i = 0; i < v->send_count; i++) {
- buf = dma->buflist[v->send_indices[i]];
- buf->pending = 1;
-
- buf_priv = buf->dev_private;
- buf_priv->age = dev_priv->submit_age;
- }
-
- dev_priv->submit_age++;
-
- return 0;
-}
-#endif
-
-
-
-
static int r128_cce_get_buffers( drm_device_t *dev, drm_dma_t *d )
{
int i;
diff --git a/linux/r128_drm.h b/linux/r128_drm.h
index 57cb5c3d..94dba1ed 100644
--- a/linux/r128_drm.h
+++ b/linux/r128_drm.h
@@ -30,8 +30,8 @@
*
*/
-#ifndef _R128_DRM_H_
-#define _R128_DRM_H_
+#ifndef __R128_DRM_H__
+#define __R128_DRM_H__
/* WARNING: If you change any of these defines, make sure to change the
* defines in the X server file (r128_sarea.h)
@@ -69,21 +69,13 @@
/* Vertex/indirect buffer size
*/
-#if 1
#define R128_BUFFER_SIZE 16384
-#else
-#define R128_BUFFER_SIZE (128 * 1024)
-#endif
/* Byte offsets for indirect buffer data
*/
#define R128_INDEX_PRIM_OFFSET 20
#define R128_HOSTDATA_BLIT_OFFSET 32
-/* 2048x2048 @ 32bpp texture requires this many indirect buffers
- */
-#define R128_MAX_BLIT_BUFFERS ((2048 * 2048 * 4) / R128_BUFFER_SIZE)
-
/* Keep these small for testing.
*/
#define R128_NR_SAREA_CLIPRECTS 12
@@ -139,7 +131,8 @@ typedef struct {
unsigned int scale_3d_cntl;
} drm_r128_context_regs_t;
-/* Setup registers for each texture unit */
+/* Setup registers for each texture unit
+ */
typedef struct {
unsigned int tex_cntl;
unsigned int tex_combine_cntl;
@@ -216,6 +209,13 @@ typedef struct drm_r128_cce_stop {
int idle;
} drm_r128_cce_stop_t;
+typedef struct drm_r128_fullscreen {
+ enum {
+ R128_INIT_FULLSCREEN = 0x01,
+ R128_CLEANUP_FULLSCREEN = 0x02
+ } func;
+} drm_r128_fullscreen_t;
+
typedef struct drm_r128_clear {
unsigned int flags;
int x, y, w, h;
@@ -265,10 +265,11 @@ typedef struct drm_r128_stipple {
unsigned int *mask;
} drm_r128_stipple_t;
-typedef struct drm_r128_packet {
- unsigned int *buffer;
- int count;
- int flags;
-} drm_r128_packet_t;
+typedef struct drm_r128_indirect {
+ int idx;
+ int start;
+ int end;
+ int discard;
+} drm_r128_indirect_t;
#endif
diff --git a/linux/r128_drv.c b/linux/r128_drv.c
index dbfc9b74..cf258925 100644
--- a/linux/r128_drv.c
+++ b/linux/r128_drv.c
@@ -37,10 +37,10 @@
#define R128_NAME "r128"
#define R128_DESC "ATI Rage 128"
-#define R128_DATE "20001215"
+#define R128_DATE "20010101"
#define R128_MAJOR 2
#define R128_MINOR 1
-#define R128_PATCHLEVEL 2
+#define R128_PATCHLEVEL 4
static drm_device_t r128_device;
drm_ctx_t r128_res_ctx;
@@ -108,20 +108,22 @@ static drm_ioctl_desc_t r128_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 },
#endif
- [DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)] = { r128_cce_init, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_START)] = { r128_cce_start, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_STOP)] = { r128_cce_stop, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_RESET)] = { r128_cce_reset, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_IDLE)] = { r128_cce_idle, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)] = { r128_engine_reset, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_SWAP)] = { r128_cce_swap, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_CLEAR)] = { r128_cce_clear, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_cce_vertex, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)] = { r128_cce_indices, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)] = { r128_cce_blit, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_DEPTH)] = { r128_cce_depth, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)] = { r128_cce_stipple, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_PACKET)] = { r128_cce_packet, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)] = { r128_cce_init, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_START)] = { r128_cce_start, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_STOP)] = { r128_cce_stop, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_RESET)] = { r128_cce_reset, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_IDLE)] = { r128_cce_idle, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)] = { r128_engine_reset, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_FULLSCREEN)]= { r128_fullscreen, 1, 0 },
+
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_SWAP)] = { r128_cce_swap, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_CLEAR)] = { r128_cce_clear, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_cce_vertex, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)] = { r128_cce_indices, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)] = { r128_cce_blit, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_DEPTH)] = { r128_cce_depth, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)] = { r128_cce_stipple, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_INDIRECT)] = { r128_cce_indirect, 1, 1 },
};
#define R128_IOCTL_COUNT DRM_ARRAY_SIZE(r128_ioctls)
@@ -489,7 +491,17 @@ int r128_release(struct inode *inode, struct file *filp)
lock_kernel();
dev = priv->dev;
+
DRM_DEBUG("open_count = %d\n", dev->open_count);
+
+ /* Force the cleanup of page flipping when required */
+ if ( dev->dev_private ) {
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ if ( dev_priv->page_flipping ) {
+ r128_do_cleanup_pageflip( dev );
+ }
+ }
+
if (!(retcode = drm_release(inode, filp))) {
#if LINUX_VERSION_CODE < 0x020333
MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */
diff --git a/linux/r128_drv.h b/linux/r128_drv.h
index cffd0800..08ef5dc9 100644
--- a/linux/r128_drv.h
+++ b/linux/r128_drv.h
@@ -59,7 +59,6 @@ typedef struct drm_r128_private {
int cce_mode;
int cce_fifo_size;
- int cce_secure;
int cce_running;
drm_r128_freelist_t *head;
@@ -70,6 +69,11 @@ typedef struct drm_r128_private {
atomic_t idle_count;
+ int page_flipping;
+ int current_page;
+ u32 crtc_offset;
+ u32 crtc_offset_cntl;
+
unsigned int fb_bpp;
unsigned int front_offset;
unsigned int front_pitch;
@@ -128,7 +132,7 @@ extern int r128_cce_idle( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int r128_engine_reset( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
-extern int r128_cce_packet( struct inode *inode, struct file *filp,
+extern int r128_fullscreen( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int r128_cce_buffers( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
@@ -139,6 +143,8 @@ extern drm_buf_t *r128_freelist_get( drm_device_t *dev );
extern int r128_wait_ring( drm_r128_private_t *dev_priv, int n );
extern void r128_update_ring_snapshot( drm_r128_private_t *dev_priv );
+extern int r128_do_cleanup_pageflip( drm_device_t *dev );
+
/* r128_state.c */
extern int r128_cce_clear( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
@@ -154,6 +160,8 @@ extern int r128_cce_depth( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int r128_cce_stipple( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
+extern int r128_cce_indirect( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
/* r128_bufs.c */
extern int r128_addbufs(struct inode *inode, struct file *filp,
@@ -215,8 +223,10 @@ extern int r128_context_switch_complete(drm_device_t *dev, int new);
#define R128_CLOCK_CNTL_INDEX 0x0008
#define R128_CLOCK_CNTL_DATA 0x000c
# define R128_PLL_WR_EN (1 << 7)
-
#define R128_CONSTANT_COLOR_C 0x1d34
+#define R128_CRTC_OFFSET 0x0224
+#define R128_CRTC_OFFSET_CNTL 0x0228
+# define R128_CRTC_OFFSET_FLIP_CNTL (1 << 16)
#define R128_DP_GUI_MASTER_CNTL 0x146c
# define R128_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0)
@@ -431,12 +441,12 @@ extern int R128_READ_PLL(drm_device_t *dev, int addr);
#define BEGIN_RING( n ) do { \
if ( R128_VERBOSE ) { \
DRM_INFO( "BEGIN_RING( %d ) in %s\n", \
- n, __FUNCTION__ ); \
+ (n), __FUNCTION__ ); \
} \
- if ( dev_priv->ring.space < n * sizeof(u32) ) { \
- r128_wait_ring( dev_priv, n * sizeof(u32) ); \
+ if ( dev_priv->ring.space < (n) * sizeof(u32) ) { \
+ r128_wait_ring( dev_priv, (n) * sizeof(u32) ); \
} \
- dev_priv->ring.space -= n * sizeof(u32); \
+ dev_priv->ring.space -= (n) * sizeof(u32); \
ring = dev_priv->ring.start; \
write = dev_priv->ring.tail; \
tail_mask = dev_priv->ring.tail_mask; \
@@ -457,7 +467,7 @@ extern int 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++] = (x); \
write &= tail_mask; \
} while (0)
diff --git a/linux/r128_state.c b/linux/r128_state.c
index cdeb1bb5..cf54ed59 100644
--- a/linux/r128_state.c
+++ b/linux/r128_state.c
@@ -310,13 +310,13 @@ static void r128_clear_box( drm_r128_private_t *dev_priv,
BEGIN_RING( 6 );
OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
- OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
- | R128_GMC_BRUSH_SOLID_COLOR
- | fb_bpp
- | R128_GMC_SRC_DATATYPE_COLOR
- | R128_ROP3_P
- | R128_GMC_CLR_CMP_CNTL_DIS
- | R128_GMC_AUX_CLIP_DIS );
+ OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+ R128_GMC_BRUSH_SOLID_COLOR |
+ fb_bpp |
+ R128_GMC_SRC_DATATYPE_COLOR |
+ R128_ROP3_P |
+ R128_GMC_CLR_CMP_CNTL_DIS |
+ R128_GMC_AUX_CLIP_DIS );
OUT_RING( (pitch << 21) | (offset >> 5) );
OUT_RING( color );
@@ -398,6 +398,14 @@ static void r128_cce_dispatch_clear( drm_device_t *dev,
return;
}
+ if ( dev_priv->page_flipping && dev_priv->current_page == 1) {
+ unsigned int tmp = flags;
+
+ flags &= ~(R128_FRONT | R128_BACK);
+ if ( tmp & R128_FRONT ) flags |= R128_BACK;
+ if ( tmp & R128_BACK ) flags |= R128_FRONT;
+ }
+
for ( i = 0 ; i < nbox ; i++ ) {
int x = pbox[i].x1;
int y = pbox[i].y1;
@@ -421,13 +429,13 @@ static void r128_cce_dispatch_clear( drm_device_t *dev,
BEGIN_RING( 6 );
OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
- OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
- | R128_GMC_BRUSH_SOLID_COLOR
- | fb_bpp
- | R128_GMC_SRC_DATATYPE_COLOR
- | R128_ROP3_P
- | R128_GMC_CLR_CMP_CNTL_DIS
- | R128_GMC_AUX_CLIP_DIS );
+ OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+ R128_GMC_BRUSH_SOLID_COLOR |
+ fb_bpp |
+ R128_GMC_SRC_DATATYPE_COLOR |
+ R128_ROP3_P |
+ R128_GMC_CLR_CMP_CNTL_DIS |
+ R128_GMC_AUX_CLIP_DIS );
OUT_RING( dev_priv->front_pitch_offset_c );
OUT_RING( clear_color );
@@ -442,13 +450,13 @@ static void r128_cce_dispatch_clear( drm_device_t *dev,
BEGIN_RING( 6 );
OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
- OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
- | R128_GMC_BRUSH_SOLID_COLOR
- | fb_bpp
- | R128_GMC_SRC_DATATYPE_COLOR
- | R128_ROP3_P
- | R128_GMC_CLR_CMP_CNTL_DIS
- | R128_GMC_AUX_CLIP_DIS );
+ OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+ R128_GMC_BRUSH_SOLID_COLOR |
+ fb_bpp |
+ R128_GMC_SRC_DATATYPE_COLOR |
+ R128_ROP3_P |
+ R128_GMC_CLR_CMP_CNTL_DIS |
+ R128_GMC_AUX_CLIP_DIS );
OUT_RING( dev_priv->back_pitch_offset_c );
OUT_RING( clear_color );
@@ -463,14 +471,14 @@ static void r128_cce_dispatch_clear( drm_device_t *dev,
BEGIN_RING( 6 );
OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
- OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
- | R128_GMC_BRUSH_SOLID_COLOR
- | depth_bpp
- | R128_GMC_SRC_DATATYPE_COLOR
- | R128_ROP3_P
- | R128_GMC_CLR_CMP_CNTL_DIS
- | R128_GMC_AUX_CLIP_DIS
- | R128_GMC_WR_MSK_DIS );
+ OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+ R128_GMC_BRUSH_SOLID_COLOR |
+ depth_bpp |
+ R128_GMC_SRC_DATATYPE_COLOR |
+ R128_ROP3_P |
+ R128_GMC_CLR_CMP_CNTL_DIS |
+ R128_GMC_AUX_CLIP_DIS |
+ R128_GMC_WR_MSK_DIS );
OUT_RING( dev_priv->depth_pitch_offset_c );
OUT_RING( clear_depth );
@@ -521,16 +529,16 @@ static void r128_cce_dispatch_swap( drm_device_t *dev )
BEGIN_RING( 7 );
OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) );
- OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL
- | R128_GMC_DST_PITCH_OFFSET_CNTL
- | R128_GMC_BRUSH_NONE
- | fb_bpp
- | R128_GMC_SRC_DATATYPE_COLOR
- | R128_ROP3_S
- | R128_DP_SRC_SOURCE_MEMORY
- | R128_GMC_CLR_CMP_CNTL_DIS
- | R128_GMC_AUX_CLIP_DIS
- | R128_GMC_WR_MSK_DIS );
+ OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL |
+ R128_GMC_DST_PITCH_OFFSET_CNTL |
+ R128_GMC_BRUSH_NONE |
+ fb_bpp |
+ R128_GMC_SRC_DATATYPE_COLOR |
+ R128_ROP3_S |
+ R128_DP_SRC_SOURCE_MEMORY |
+ R128_GMC_CLR_CMP_CNTL_DIS |
+ R128_GMC_AUX_CLIP_DIS |
+ R128_GMC_WR_MSK_DIS );
OUT_RING( dev_priv->back_pitch_offset_c );
OUT_RING( dev_priv->front_pitch_offset_c );
@@ -556,6 +564,48 @@ static void r128_cce_dispatch_swap( drm_device_t *dev )
ADVANCE_RING();
}
+static void r128_cce_dispatch_flip( drm_device_t *dev )
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ RING_LOCALS;
+ DRM_DEBUG( "%s: page=%d\n", __FUNCTION__, dev_priv->current_page );
+
+ r128_update_ring_snapshot( dev_priv );
+
+#if R128_PERFORMANCE_BOXES
+ /* Do some trivial performance monitoring...
+ */
+ r128_cce_performance_boxes( dev_priv );
+#endif
+
+ BEGIN_RING( 2 );
+
+ OUT_RING( CCE_PACKET0( R128_CRTC_OFFSET, 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;
+ }
+
+ ADVANCE_RING();
+
+ /* Increment the frame counter. The client-side 3D driver must
+ * throttle the framerate by waiting for this value before
+ * performing the swapbuffer ioctl.
+ */
+ dev_priv->sarea_priv->last_frame++;
+
+ BEGIN_RING( 2 );
+
+ OUT_RING( CCE_PACKET0( R128_LAST_FRAME_REG, 0 ) );
+ OUT_RING( dev_priv->sarea_priv->last_frame );
+
+ ADVANCE_RING();
+}
+
static void r128_cce_dispatch_vertex( drm_device_t *dev,
drm_buf_t *buf )
{
@@ -821,13 +871,17 @@ static int r128_cce_dispatch_blit( drm_device_t *dev,
* use a shift instead.
*/
switch ( blit->format ) {
+ case R128_DATATYPE_ARGB8888:
+ dword_shift = 0;
+ break;
case R128_DATATYPE_ARGB1555:
case R128_DATATYPE_RGB565:
case R128_DATATYPE_ARGB4444:
dword_shift = 1;
break;
- case R128_DATATYPE_ARGB8888:
- dword_shift = 0;
+ case R128_DATATYPE_CI8:
+ case R128_DATATYPE_RGB8:
+ dword_shift = 2;
break;
default:
DRM_ERROR( "invalid blit format %d\n", blit->format );
@@ -868,15 +922,15 @@ 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[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[2] = (blit->pitch << 21) | (blit->offset >> 5);
data[3] = 0xffffffff;
@@ -971,15 +1025,14 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev,
if ( mask[i] ) {
BEGIN_RING( 6 );
- OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI,
- 4 ) );
- OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
- | R128_GMC_BRUSH_SOLID_COLOR
- | depth_bpp
- | R128_GMC_SRC_DATATYPE_COLOR
- | R128_ROP3_P
- | R128_GMC_CLR_CMP_CNTL_DIS
- | R128_GMC_WR_MSK_DIS );
+ OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
+ OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+ R128_GMC_BRUSH_SOLID_COLOR |
+ depth_bpp |
+ R128_GMC_SRC_DATATYPE_COLOR |
+ R128_ROP3_P |
+ R128_GMC_CLR_CMP_CNTL_DIS |
+ R128_GMC_WR_MSK_DIS );
OUT_RING( dev_priv->depth_pitch_offset_c );
OUT_RING( buffer[i] );
@@ -997,13 +1050,13 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev,
BEGIN_RING( 6 );
OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
- OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
- | R128_GMC_BRUSH_SOLID_COLOR
- | depth_bpp
- | R128_GMC_SRC_DATATYPE_COLOR
- | R128_ROP3_P
- | R128_GMC_CLR_CMP_CNTL_DIS
- | R128_GMC_WR_MSK_DIS );
+ OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+ R128_GMC_BRUSH_SOLID_COLOR |
+ depth_bpp |
+ R128_GMC_SRC_DATATYPE_COLOR |
+ R128_ROP3_P |
+ R128_GMC_CLR_CMP_CNTL_DIS |
+ R128_GMC_WR_MSK_DIS );
OUT_RING( dev_priv->depth_pitch_offset_c );
OUT_RING( buffer[i] );
@@ -1103,15 +1156,14 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
if ( mask[i] ) {
BEGIN_RING( 6 );
- OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI,
- 4 ) );
- OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
- | R128_GMC_BRUSH_SOLID_COLOR
- | depth_bpp
- | R128_GMC_SRC_DATATYPE_COLOR
- | R128_ROP3_P
- | R128_GMC_CLR_CMP_CNTL_DIS
- | R128_GMC_WR_MSK_DIS );
+ OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
+ OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+ R128_GMC_BRUSH_SOLID_COLOR |
+ depth_bpp |
+ R128_GMC_SRC_DATATYPE_COLOR |
+ R128_ROP3_P |
+ R128_GMC_CLR_CMP_CNTL_DIS |
+ R128_GMC_WR_MSK_DIS );
OUT_RING( dev_priv->depth_pitch_offset_c );
OUT_RING( buffer[i] );
@@ -1129,13 +1181,13 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
BEGIN_RING( 6 );
OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
- OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
- | R128_GMC_BRUSH_SOLID_COLOR
- | depth_bpp
- | R128_GMC_SRC_DATATYPE_COLOR
- | R128_ROP3_P
- | R128_GMC_CLR_CMP_CNTL_DIS
- | R128_GMC_WR_MSK_DIS );
+ OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+ R128_GMC_BRUSH_SOLID_COLOR |
+ depth_bpp |
+ R128_GMC_SRC_DATATYPE_COLOR |
+ R128_ROP3_P |
+ R128_GMC_CLR_CMP_CNTL_DIS |
+ R128_GMC_WR_MSK_DIS );
OUT_RING( dev_priv->depth_pitch_offset_c );
OUT_RING( buffer[i] );
@@ -1188,15 +1240,15 @@ static int r128_cce_dispatch_read_span( drm_device_t *dev,
BEGIN_RING( 7 );
OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) );
- OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL
- | R128_GMC_DST_PITCH_OFFSET_CNTL
- | R128_GMC_BRUSH_NONE
- | depth_bpp
- | R128_GMC_SRC_DATATYPE_COLOR
- | R128_ROP3_S
- | R128_DP_SRC_SOURCE_MEMORY
- | R128_GMC_CLR_CMP_CNTL_DIS
- | R128_GMC_WR_MSK_DIS );
+ OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL |
+ R128_GMC_DST_PITCH_OFFSET_CNTL |
+ R128_GMC_BRUSH_NONE |
+ depth_bpp |
+ R128_GMC_SRC_DATATYPE_COLOR |
+ R128_ROP3_S |
+ R128_DP_SRC_SOURCE_MEMORY |
+ R128_GMC_CLR_CMP_CNTL_DIS |
+ R128_GMC_WR_MSK_DIS );
OUT_RING( dev_priv->depth_pitch_offset_c );
OUT_RING( dev_priv->span_pitch_offset_c );
@@ -1263,15 +1315,15 @@ static int r128_cce_dispatch_read_pixels( drm_device_t *dev,
BEGIN_RING( 7 );
OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) );
- OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL
- | R128_GMC_DST_PITCH_OFFSET_CNTL
- | R128_GMC_BRUSH_NONE
- | depth_bpp
- | R128_GMC_SRC_DATATYPE_COLOR
- | R128_ROP3_S
- | R128_DP_SRC_SOURCE_MEMORY
- | R128_GMC_CLR_CMP_CNTL_DIS
- | R128_GMC_WR_MSK_DIS );
+ OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL |
+ R128_GMC_DST_PITCH_OFFSET_CNTL |
+ R128_GMC_BRUSH_NONE |
+ depth_bpp |
+ R128_GMC_SRC_DATATYPE_COLOR |
+ R128_ROP3_S |
+ R128_DP_SRC_SOURCE_MEMORY |
+ R128_GMC_CLR_CMP_CNTL_DIS |
+ R128_GMC_WR_MSK_DIS );
OUT_RING( dev_priv->depth_pitch_offset_c );
OUT_RING( dev_priv->span_pitch_offset_c );
@@ -1370,11 +1422,13 @@ int r128_cce_swap( struct inode *inode, struct file *filp,
if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS )
sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
- r128_cce_dispatch_swap( dev );
-
- /* Make sure we restore the 3D state next time.
- */
- dev_priv->sarea_priv->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS;
+ if ( !dev_priv->page_flipping ) {
+ r128_cce_dispatch_swap( dev );
+ dev_priv->sarea_priv->dirty |= (R128_UPLOAD_CONTEXT |
+ R128_UPLOAD_MASKS);
+ } else {
+ r128_cce_dispatch_flip( dev );
+ }
return 0;
}
@@ -1603,3 +1657,20 @@ int r128_cce_stipple( struct inode *inode, struct file *filp,
return 0;
}
+
+int r128_cce_indirect( 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;
+
+ 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;
+ }
+
+ /* Indirect buffer firing is not supported at this time.
+ */
+ return -EINVAL;
+}
diff --git a/linux/radeon_cp.c b/linux/radeon_cp.c
index 68a014cf..ac4d7823 100644
--- a/linux/radeon_cp.c
+++ b/linux/radeon_cp.c
@@ -36,6 +36,8 @@
#include <linux/interrupt.h> /* For task queue support */
#include <linux/delay.h>
+#define RADEON_FIFO_DEBUG 0
+
/* CP microcode (from ATI) */
static u32 radeon_cp_microcode[][2] = {
@@ -326,24 +328,9 @@ int RADEON_READ_PLL(drm_device_t *dev, int addr)
return RADEON_READ(RADEON_CLOCK_CNTL_DATA);
}
-
+#if RADEON_FIFO_DEBUG
static void radeon_status( drm_radeon_private_t *dev_priv )
{
-#if 0
- printk( "GUI_STAT = 0x%08x\n",
- (unsigned int)RADEON_READ( RADEON_GUI_STAT ) );
- printk( "PM4_STAT = 0x%08x\n",
- (unsigned int)RADEON_READ( RADEON_PM4_STAT ) );
- printk( "PM4_BUFFER_DL_WPTR = 0x%08x\n",
- (unsigned int)RADEON_READ( RADEON_PM4_BUFFER_DL_WPTR ) );
- printk( "PM4_BUFFER_DL_RPTR = 0x%08x\n",
- (unsigned int)RADEON_READ( RADEON_PM4_BUFFER_DL_RPTR ) );
- printk( "PM4_MICRO_CNTL = 0x%08x\n",
- (unsigned int)RADEON_READ( RADEON_PM4_MICRO_CNTL ) );
- printk( "PM4_BUFFER_CNTL = 0x%08x\n",
- (unsigned int)RADEON_READ( RADEON_PM4_BUFFER_CNTL ) );
-#endif
-
printk( "%s:\n", __FUNCTION__ );
printk( "RBBM_STATUS = 0x%08x\n",
(unsigned int)RADEON_READ( RADEON_RBBM_STATUS ) );
@@ -352,6 +339,7 @@ static void radeon_status( drm_radeon_private_t *dev_priv )
printk( "CP_RB_WTPR = 0x%08x\n",
(unsigned int)RADEON_READ( RADEON_CP_RB_WPTR ) );
}
+#endif
/* ================================================================
@@ -375,7 +363,10 @@ static int radeon_do_pixcache_flush( drm_radeon_private_t *dev_priv )
udelay( 1 );
}
+#if RADEON_FIFO_DEBUG
DRM_ERROR( "failed!\n" );
+ radeon_status( dev_priv );
+#endif
return -EBUSY;
}
@@ -391,7 +382,7 @@ static int radeon_do_wait_for_fifo( drm_radeon_private_t *dev_priv,
udelay( 1 );
}
-#if 1
+#if RADEON_FIFO_DEBUG
DRM_ERROR( "failed!\n" );
radeon_status( dev_priv );
#endif
@@ -414,8 +405,9 @@ static int radeon_do_wait_for_idle( drm_radeon_private_t *dev_priv )
udelay( 1 );
}
-#if 0
+#if RADEON_FIFO_DEBUG
DRM_ERROR( "failed!\n" );
+ radeon_status( dev_priv );
#endif
return -EBUSY;
}
@@ -459,12 +451,6 @@ static void radeon_do_cp_flush( drm_radeon_private_t *dev_priv )
*/
static int radeon_do_cp_idle( drm_radeon_private_t *dev_priv )
{
- RING_LOCALS;
-
- RADEON_WAIT_UNTIL_IDLE();
- RADEON_FLUSH_CACHE();
- RADEON_FLUSH_ZCACHE();
-
return radeon_do_wait_for_idle( dev_priv );
}
@@ -505,14 +491,6 @@ static void radeon_do_cp_reset( drm_radeon_private_t *dev_priv )
*/
static void radeon_do_cp_stop( drm_radeon_private_t *dev_priv )
{
- if ( dev_priv->cp_running ) {
- RING_LOCALS;
-
- RADEON_WAIT_UNTIL_IDLE();
- RADEON_FLUSH_CACHE();
- RADEON_FLUSH_ZCACHE();
- }
-
RADEON_WRITE( RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS );
dev_priv->cp_running = 0;
@@ -524,6 +502,7 @@ 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__ );
radeon_do_pixcache_flush( dev_priv );
@@ -618,10 +597,11 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev )
RADEON_WRITE( RADEON_BUS_CNTL, tmp );
/* Sync everything up */
- RADEON_WRITE( RADEON_ISYNC_CNTL, (RADEON_ISYNC_ANY2D_IDLE3D |
- RADEON_ISYNC_ANY3D_IDLE2D |
- RADEON_ISYNC_WAIT_IDLEGUI |
- RADEON_ISYNC_CPSCRATCH_IDLEGUI) );
+ RADEON_WRITE( RADEON_ISYNC_CNTL,
+ (RADEON_ISYNC_ANY2D_IDLE3D |
+ RADEON_ISYNC_ANY3D_IDLE2D |
+ RADEON_ISYNC_WAIT_IDLEGUI |
+ RADEON_ISYNC_CPSCRATCH_IDLEGUI) );
}
static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
@@ -943,20 +923,21 @@ int radeon_engine_reset( struct inode *inode, struct file *filp,
/* ================================================================
- * Page flipping
+ * Fullscreen mode
*/
static int radeon_do_init_pageflip( drm_device_t *dev )
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- u32 crtc_offset_cntl;
DRM_DEBUG( "%s\n", __FUNCTION__ );
- RADEON_WRITE( RADEON_CRTC_OFFSET, dev_priv->front_offset );
+ dev_priv->crtc_offset = RADEON_READ( RADEON_CRTC_OFFSET );
+ dev_priv->crtc_offset_cntl = RADEON_READ( RADEON_CRTC_OFFSET_CNTL );
- crtc_offset_cntl = RADEON_READ( RADEON_CRTC_OFFSET_CNTL );
+ RADEON_WRITE( RADEON_CRTC_OFFSET, dev_priv->front_offset );
RADEON_WRITE( RADEON_CRTC_OFFSET_CNTL,
- crtc_offset_cntl | RADEON_CRTC_OFFSET_FLIP_CNTL );
+ dev_priv->crtc_offset_cntl |
+ RADEON_CRTC_OFFSET_FLIP_CNTL );
dev_priv->page_flipping = 1;
dev_priv->current_page = 0;
@@ -967,14 +948,10 @@ static int radeon_do_init_pageflip( drm_device_t *dev )
int radeon_do_cleanup_pageflip( drm_device_t *dev )
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- u32 crtc_offset_cntl;
DRM_DEBUG( "%s\n", __FUNCTION__ );
- RADEON_WRITE( RADEON_CRTC_OFFSET, dev_priv->front_offset );
-
- crtc_offset_cntl = RADEON_READ( RADEON_CRTC_OFFSET_CNTL );
- RADEON_WRITE( RADEON_CRTC_OFFSET_CNTL,
- crtc_offset_cntl & ~RADEON_CRTC_OFFSET_FLIP_CNTL );
+ RADEON_WRITE( RADEON_CRTC_OFFSET, dev_priv->crtc_offset );
+ RADEON_WRITE( RADEON_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl );
dev_priv->page_flipping = 0;
dev_priv->current_page = 0;
@@ -982,12 +959,12 @@ int radeon_do_cleanup_pageflip( drm_device_t *dev )
return 0;
}
-int radeon_cp_pageflip( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+int radeon_fullscreen( 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_radeon_pageflip_t p;
+ drm_radeon_fullscreen_t fs;
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
dev->lock.pid != current->pid ) {
@@ -995,13 +972,14 @@ int radeon_cp_pageflip( struct inode *inode, struct file *filp,
return -EINVAL;
}
- if ( copy_from_user( &p, (drm_radeon_pageflip_t *)arg, sizeof(p) ) )
+ if ( copy_from_user( &fs, (drm_radeon_fullscreen_t *)arg,
+ sizeof(fs) ) )
return -EFAULT;
- switch ( p.func ) {
- case RADEON_INIT_PAGEFLIP:
+ switch ( fs.func ) {
+ case RADEON_INIT_FULLSCREEN:
return radeon_do_init_pageflip( dev );
- case RADEON_CLEANUP_PAGEFLIP:
+ case RADEON_CLEANUP_FULLSCREEN:
return radeon_do_cleanup_pageflip( dev );
}
@@ -1015,6 +993,7 @@ int radeon_cp_pageflip( struct inode *inode, struct file *filp,
#define RADEON_BUFFER_USED 0xffffffff
#define RADEON_BUFFER_FREE 0
+#if 0
static int radeon_freelist_init( drm_device_t *dev )
{
drm_device_dma_t *dma = dev->dma;
@@ -1060,6 +1039,7 @@ static int radeon_freelist_init( drm_device_t *dev )
return 0;
}
+#endif
drm_buf_t *radeon_freelist_get( drm_device_t *dev )
{
@@ -1142,7 +1122,7 @@ void radeon_freelist_reset( drm_device_t *dev )
/* ================================================================
- * CP packet submission
+ * CP command submission
*/
int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n )
@@ -1175,334 +1155,8 @@ void radeon_update_ring_snapshot( drm_radeon_private_t *dev_priv )
atomic_inc( &dev_priv->idle_count );
if ( ring->space <= 0 )
ring->space += ring->size;
-
- if ( 0 ) {
- DRM_INFO( "update_ring: size=0x%x space=%d\n",
- ring->size, ring->space );
- DRM_INFO( "tail=0x%04x\n", ring->tail );
- DRM_INFO( "head=0x%04x\n", *ring->head );
- }
-}
-
-#if 0
-static int radeon_verify_command( drm_radeon_private_t *dev_priv,
- u32 cmd, int *size )
-{
- int writing = 1;
-
- *size = 0;
-
- switch ( cmd & RADEON_CP_PACKET_MASK ) {
- case RADEON_CP_PACKET0:
- if ( (cmd & RADEON_CP_PACKET0_REG_MASK) <= (0x1004 >> 2) &&
- (cmd & RADEON_CP_PACKET0_REG_MASK) !=
- (RADEON_PM4_VC_FPU_SETUP >> 2) ) {
- writing = 0;
- }
- *size = ((cmd & RADEON_CP_PACKET_COUNT_MASK) >> 16) + 2;
- break;
-
- case RADEON_CP_PACKET1:
- if ( (cmd & RADEON_CP_PACKET1_REG0_MASK) <= (0x1004 >> 2) &&
- (cmd & RADEON_CP_PACKET1_REG0_MASK) !=
- (RADEON_PM4_VC_FPU_SETUP >> 2) ) {
- writing = 0;
- }
- if ( (cmd & RADEON_CP_PACKET1_REG1_MASK) <= (0x1004 << 9) &&
- (cmd & RADEON_CP_PACKET1_REG1_MASK) !=
- (RADEON_PM4_VC_FPU_SETUP << 9) ) {
- writing = 0;
- }
- *size = 3;
- break;
-
- case RADEON_CP_PACKET2:
- break;
-
- case RADEON_CP_PACKET3:
- *size = ((cmd & RADEON_CP_PACKET_COUNT_MASK) >> 16) + 2;
- break;
-
- }
-
- return writing;
-}
-
-static int radeon_submit_packet_ring_secure( drm_radeon_private_t *dev_priv,
- u32 *commands, int *count )
-{
-#if 0
- int write = dev_priv->sarea_priv->ring_write;
- int *write_ptr = dev_priv->ring_start + write;
- int c = *count;
- u32 tmp = 0;
- int psize = 0;
- int writing = 1;
- int timeout;
-
- while ( c > 0 ) {
- tmp = *commands++;
- if ( !psize ) {
- writing = radeon_verify_command( dev_priv, tmp, &psize );
- }
- psize--;
-
- if ( writing ) {
- write++;
- *write_ptr++ = tmp;
- }
- if ( write >= dev_priv->ring_entries ) {
- write = 0;
- write_ptr = dev_priv->ring_start;
- }
- timeout = 0;
- while ( write == *dev_priv->ring_read_ptr ) {
- RADEON_READ( RADEON_PM4_BUFFER_DL_RPTR );
- if ( timeout++ >= dev_priv->usec_timeout )
- return -EBUSY;
- udelay( 1 );
- }
- c--;
- }
-
- /* Make sure WC cache has been flushed */
- radeon_flush_write_combine();
-
- dev_priv->sarea_priv->ring_write = write;
- RADEON_WRITE( RADEON_PM4_BUFFER_DL_WPTR, write );
-
- *count = 0;
-#endif
- return 0;
-}
-
-static int radeon_submit_packet_ring_insecure( drm_radeon_private_t *dev_priv,
- u32 *commands, int *count )
-{
-#if 0
- int write = dev_priv->sarea_priv->ring_write;
- int *write_ptr = dev_priv->ring_start + write;
- int c = *count;
- int timeout;
-
- while ( c > 0 ) {
- write++;
- *write_ptr++ = *commands++;
- if ( write >= dev_priv->ring_entries ) {
- write = 0;
- write_ptr = dev_priv->ring_start;
- }
-
- timeout = 0;
- while ( write == *dev_priv->ring_read_ptr ) {
- RADEON_READ( RADEON_PM4_BUFFER_DL_RPTR );
- if ( timeout++ >= dev_priv->usec_timeout )
- return -EBUSY;
- udelay( 1 );
- }
- c--;
- }
-
- /* Make sure WC cache has been flushed */
- radeon_flush_write_combine();
-
- dev_priv->sarea_priv->ring_write = write;
- RADEON_WRITE( RADEON_PM4_BUFFER_DL_WPTR, write );
-
- *count = 0;
-#endif
- return 0;
-}
-#endif
-
-/* Internal packet submission routine. This uses the insecure versions
- * of the packet submission functions, and thus should only be used for
- * packets generated inside the kernel module.
- */
-int radeon_do_submit_packet( drm_radeon_private_t *dev_priv,
- u32 *buffer, int count )
-{
- int c = count;
- int ret = 0;
-
-#if 0
- int left = 0;
-
- if ( c >= dev_priv->ring_entries ) {
- c = dev_priv->ring_entries - 1;
- left = count - c;
- }
-
- /* Since this is only used by the kernel we can use the
- * insecure ring buffer submit packet routine.
- */
- ret = radeon_submit_packet_ring_insecure( dev_priv, buffer, &c );
- c += left;
-#endif
-
- return ( ret < 0 ) ? ret : c;
}
-static int radeon_do_cp_packet( drm_radeon_private_t *dev_priv,
- u32 *commands, int count )
-{
- int c;
- RING_LOCALS;
-
- /* FIXME: Optimize!!! GH: Why bother? */
- for ( c = 0 ; c < count ; c++ ) {
- BEGIN_RING( 1 );
- OUT_RING( commands[c] );
- ADVANCE_RING();
- }
-
- return 0;
-}
-
-/* External packet submission routine. This uses the secure versions
- * by default, and can thus submit packets received from user space.
- */
-int radeon_cp_packet( 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_radeon_private_t *dev_priv = dev->dev_private;
- drm_radeon_packet_t packet;
- u32 *buffer;
- int ret;
-
- if ( !capable( CAP_SYS_ADMIN ) ) {
- DRM_ERROR( "radeon_cp_packet called without permission\n" );
- return -EACCES;
- }
-
- 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;
- }
-
- if ( copy_from_user( &packet, (drm_radeon_packet_t *)arg,
- sizeof(packet) ) )
- return -EFAULT;
-
- buffer = kmalloc( packet.count * sizeof(*buffer), 0 );
- if ( buffer == NULL)
- return -ENOMEM;
- if ( copy_from_user( buffer, packet.buffer,
- packet.count * sizeof(*buffer) ) )
- return -EFAULT;
-
- ret = radeon_do_cp_packet( dev_priv, buffer, packet.count );
-
- kfree( buffer );
-
- packet.count = 0;
- if ( copy_to_user( (drm_radeon_packet_t *)arg, &packet,
- sizeof(packet) ) )
- return -EFAULT;
-
- return ret;
-}
-
-#if 0
-static int radeon_send_vertbufs( drm_device_t *dev, drm_radeon_vertex_t *v )
-{
- drm_device_dma_t *dma = dev->dma;
- drm_radeon_private_t *dev_priv = dev->dev_private;
- drm_radeon_buf_priv_t *buf_priv;
- drm_buf_t *buf;
- int i, ret;
- RING_LOCALS;
-
- /* Make sure we have valid data */
- for (i = 0; i < v->send_count; i++) {
- int idx = v->send_indices[i];
-
- if (idx < 0 || idx >= dma->buf_count) {
- DRM_ERROR("Index %d (of %d max)\n",
- idx, dma->buf_count - 1);
- return -EINVAL;
- }
- buf = dma->buflist[idx];
- if (buf->pid != current->pid) {
- DRM_ERROR("Process %d using buffer owned by %d\n",
- current->pid, buf->pid);
- return -EINVAL;
- }
- if (buf->pending) {
- DRM_ERROR("Sending pending buffer:"
- " buffer %d, offset %d\n",
- v->send_indices[i], i);
- return -EINVAL;
- }
- }
-
- /* Wait for idle, if we've wrapped to make sure that all pending
- buffers have been processed */
- if (dev_priv->submit_age == RADEON_MAX_VBUF_AGE) {
- if ((ret = radeon_do_cp_idle(dev)) < 0) return ret;
- dev_priv->submit_age = 0;
- radeon_freelist_reset(dev);
- }
-
- /* Make sure WC cache has been flushed (if in PIO mode) */
- if (!dev_priv->cp_is_bm_mode) radeon_flush_write_combine();
-
- /* FIXME: Add support for sending vertex buffer to the CP here
- instead of in client code. The v->prim holds the primitive
- type that should be drawn. Loop over the list buffers in
- send_indices[] and submit a packet for each VB.
-
- This will require us to loop over the clip rects here as
- well, which implies that we extend the kernel driver to allow
- cliprects to be stored here. Note that the cliprects could
- possibly come from the X server instead of the client, but
- this will require additional changes to the DRI to allow for
- this optimization. */
-
- /* Submit a CP packet that writes submit_age to RADEON_VB_AGE_REG */
-#if 0
- cp_buffer[0] = RADEONCP0(RADEON_CP_PACKET0, RADEON_VB_AGE_REG, 0);
- cp_buffer[1] = dev_priv->submit_age;
-
- if ((ret = radeon_do_submit_packet(dev, cp_buffer, 2)) < 0) {
- /* Until we add support for sending VBs to the CP in
- this routine, we can recover from this error. After
- we add that support, we won't be able to easily
- recover, so we will probably have to implement
- another mechanism for handling timeouts from packets
- submitted directly by the kernel. */
- return ret;
- }
-#else
- BEGIN_RING( 2 );
-
- OUT_RING( CP_PACKET0( RADEON_VB_AGE_REG, 0 ) );
- OUT_RING( dev_priv->submit_age );
-
- ADVANCE_RING();
-#endif
- /* Now that the submit packet request has succeeded, we can mark
- the buffers as pending */
- for (i = 0; i < v->send_count; i++) {
- buf = dma->buflist[v->send_indices[i]];
- buf->pending = 1;
-
- buf_priv = buf->dev_private;
- buf_priv->age = dev_priv->submit_age;
- }
-
- dev_priv->submit_age++;
-
- return 0;
-}
-#endif
-
-
-
-
static int radeon_cp_get_buffers( drm_device_t *dev, drm_dma_t *d )
{
int i;
diff --git a/linux/radeon_drm.h b/linux/radeon_drm.h
index 73eabd9c..03f29737 100644
--- a/linux/radeon_drm.h
+++ b/linux/radeon_drm.h
@@ -132,9 +132,6 @@ typedef struct {
unsigned int se_line_width; /* 0x1db8 */
- /* Texture state */
- unsigned int pp_tfactor;
-
/* Bumpmap state */
unsigned int pp_lum_matrix; /* 0x1d00 */
@@ -187,6 +184,7 @@ typedef struct {
unsigned int pp_txoffset;
unsigned int pp_txcblend;
unsigned int pp_txablend;
+ unsigned int pp_tfactor;
unsigned int pp_border_color;
@@ -262,12 +260,12 @@ typedef struct drm_radeon_cp_stop {
int idle;
} drm_radeon_cp_stop_t;
-typedef struct drm_radeon_pageflip {
+typedef struct drm_radeon_fullscreen {
enum {
- RADEON_INIT_PAGEFLIP = 0x01,
- RADEON_CLEANUP_PAGEFLIP = 0x02
+ RADEON_INIT_FULLSCREEN = 0x01,
+ RADEON_CLEANUP_FULLSCREEN = 0x02
} func;
-} drm_radeon_pageflip_t;
+} drm_radeon_fullscreen_t;
typedef struct drm_radeon_clear {
unsigned int flags;
@@ -304,10 +302,11 @@ typedef struct drm_radeon_stipple {
unsigned int *mask;
} drm_radeon_stipple_t;
-typedef struct drm_radeon_packet {
- unsigned int *buffer;
- int count;
- int flags;
-} drm_radeon_packet_t;
+typedef struct drm_radeon_indirect {
+ int idx;
+ int start;
+ int end;
+ int discard;
+} drm_radeon_indirect_t;
#endif
diff --git a/linux/radeon_drv.c b/linux/radeon_drv.c
index 93ad2f0d..07f85981 100644
--- a/linux/radeon_drv.c
+++ b/linux/radeon_drv.c
@@ -34,7 +34,7 @@
#define RADEON_NAME "radeon"
#define RADEON_DESC "ATI Radeon"
-#define RADEON_DATE "20001228"
+#define RADEON_DATE "20001230"
#define RADEON_MAJOR 1
#define RADEON_MINOR 0
#define RADEON_PATCHLEVEL 0
@@ -105,20 +105,21 @@ static drm_ioctl_desc_t radeon_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 },
#endif
- [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 },
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_RESET)]= { radeon_cp_reset, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_IDLE)] = { radeon_cp_idle, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_RESET)] = { radeon_engine_reset,1,0 },
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_PAGEFLIP)]= { radeon_cp_pageflip,1, 0 },
+ [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 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_RESET)] = { radeon_cp_reset, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_IDLE)] = { radeon_cp_idle, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_RESET)] = { radeon_engine_reset, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FULLSCREEN)] = { radeon_fullscreen, 1, 0 },
+
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_SWAP)] = { radeon_cp_swap, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CLEAR)] = { radeon_cp_clear, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX)] = { radeon_cp_vertex, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDICES)] = { radeon_cp_indices, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_BLIT)] = { radeon_cp_blit, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_STIPPLE)] = { radeon_cp_stipple, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_PACKET)] = { radeon_cp_packet, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)]= { radeon_cp_indirect,1, 1 },
};
#define RADEON_IOCTL_COUNT DRM_ARRAY_SIZE(radeon_ioctls)
@@ -612,9 +613,6 @@ int radeon_lock(struct inode *inode, struct file *filp, unsigned int cmd,
/* Contention */
atomic_inc(&dev->total_sleeps);
-#if 1
- current->policy |= SCHED_YIELD;
-#endif
schedule();
if (signal_pending(current)) {
ret = -ERESTARTSYS;
@@ -625,32 +623,6 @@ int radeon_lock(struct inode *inode, struct file *filp, unsigned int cmd,
remove_wait_queue(&dev->lock.lock_queue, &entry);
}
-#if 0
- if (!ret && dev->last_context != lock.context &&
- lock.context != radeon_res_ctx.handle &&
- dev->last_context != radeon_res_ctx.handle) {
- add_wait_queue(&dev->context_wait, &entry);
- current->state = TASK_INTERRUPTIBLE;
- /* PRE: dev->last_context != lock.context */
- radeon_context_switch(dev, dev->last_context, lock.context);
- /* POST: we will wait for the context
- switch and will dispatch on a later call
- when dev->last_context == lock.context
- NOTE WE HOLD THE LOCK THROUGHOUT THIS
- TIME! */
- current->policy |= SCHED_YIELD;
- schedule();
- current->state = TASK_RUNNING;
- remove_wait_queue(&dev->context_wait, &entry);
- if (signal_pending(current)) {
- ret = -EINTR;
- } else if (dev->last_context != lock.context) {
- DRM_ERROR("Context mismatch: %d %d\n",
- dev->last_context, lock.context);
- }
- }
-#endif
-
if (!ret) {
sigemptyset(&dev->sigmask);
sigaddset(&dev->sigmask, SIGSTOP);
diff --git a/linux/radeon_drv.h b/linux/radeon_drv.h
index 93c83e9e..8456a8a9 100644
--- a/linux/radeon_drv.h
+++ b/linux/radeon_drv.h
@@ -81,6 +81,8 @@ typedef struct drm_radeon_private {
int page_flipping;
int current_page;
+ u32 crtc_offset;
+ u32 crtc_offset_cntl;
unsigned int fb_bpp;
unsigned int front_offset;
@@ -138,10 +140,8 @@ extern int radeon_cp_idle( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_engine_reset( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
-extern int radeon_cp_pageflip( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
-extern int radeon_cp_packet( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
+extern int radeon_fullscreen( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
extern int radeon_cp_buffers( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
@@ -166,6 +166,8 @@ extern int radeon_cp_blit( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_stipple( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
+extern int radeon_cp_indirect( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
/* radeon_bufs.c */
extern int radeon_addbufs(struct inode *inode, struct file *filp,
@@ -214,6 +216,7 @@ extern int radeon_context_switch_complete(drm_device_t *dev, int new);
#define RADEON_CONFIG_APER_SIZE 0x0108
#define RADEON_CRTC_OFFSET 0x0224
#define RADEON_CRTC_OFFSET_CNTL 0x0228
+# define RADEON_CRTC_TILE_EN (1 << 15)
# define RADEON_CRTC_OFFSET_FLIP_CNTL (1 << 16)
#define RADEON_DP_GUI_MASTER_CNTL 0x146c
@@ -233,6 +236,12 @@ extern int radeon_context_switch_complete(drm_device_t *dev, int new);
# define RADEON_ROP3_S 0x00cc0000
# define RADEON_ROP3_P 0x00f00000
#define RADEON_DP_WRITE_MASK 0x16cc
+#define RADEON_DST_PITCH_OFFSET 0x142c
+#define RADEON_DST_PITCH_OFFSET_C 0x1c80
+# define RADEON_DST_TILE_LINEAR (0 << 30)
+# define RADEON_DST_TILE_MACRO (1 << 30)
+# define RADEON_DST_TILE_MICRO (2 << 30)
+# define RADEON_DST_TILE_BOTH (3 << 30)
#define RADEON_GUI_SCRATCH_REG0 0x15e0
#define RADEON_GUI_SCRATCH_REG1 0x15e4
@@ -367,8 +376,6 @@ extern int radeon_context_switch_complete(drm_device_t *dev, int new);
#define RADEON_WAIT_UNTIL 0x1720
# define RADEON_WAIT_CRTC_PFLIP (1 << 0)
-# define RADEON_WAIT_2D_IDLE (1 << 14)
-# define RADEON_WAIT_3D_IDLE (1 << 15)
# define RADEON_WAIT_2D_IDLECLEAN (1 << 16)
# define RADEON_WAIT_3D_IDLECLEAN (1 << 17)
# define RADEON_WAIT_HOST_IDLECLEAN (1 << 18)
@@ -451,11 +458,7 @@ extern int radeon_context_switch_complete(drm_device_t *dev, int new);
#define RADEON_COLOR_FORMAT_RGB565 4
#define RADEON_COLOR_FORMAT_ARGB8888 6
#define RADEON_COLOR_FORMAT_RGB332 7
-#define RADEON_COLOR_FORMAT_Y8 8
#define RADEON_COLOR_FORMAT_RGB8 9
-#define RADEON_COLOR_FORMAT_YUV422_VYUY 11
-#define RADEON_COLOR_FORMAT_YUV422_YVYU 12
-#define RADEON_COLOR_FORMAT_aYUV444 14
#define RADEON_COLOR_FORMAT_ARGB4444 15
#define RADEON_TXF_8BPP_I 0
@@ -512,45 +515,63 @@ extern int RADEON_READ_PLL(drm_device_t *dev, int addr);
/*
*/
+#define RADEON_WAIT_UNTIL_2D_IDLE() \
+do { \
+ BEGIN_RING( 2 ); \
+ OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \
+ OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \
+ RADEON_WAIT_HOST_IDLECLEAN) ); \
+ ADVANCE_RING(); \
+} while (0)
+
+#define RADEON_WAIT_UNTIL_3D_IDLE() \
+do { \
+ BEGIN_RING( 2 ); \
+ OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \
+ OUT_RING( (RADEON_WAIT_3D_IDLECLEAN | \
+ RADEON_WAIT_HOST_IDLECLEAN) ); \
+ ADVANCE_RING(); \
+} while (0)
+
#define RADEON_WAIT_UNTIL_IDLE() \
do { \
BEGIN_RING( 2 ); \
- \
OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \
OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \
RADEON_WAIT_3D_IDLECLEAN | \
RADEON_WAIT_HOST_IDLECLEAN) ); \
- \
ADVANCE_RING(); \
} while (0)
#define RADEON_WAIT_UNTIL_PAGE_FLIPPED() \
do { \
BEGIN_RING( 2 ); \
- \
OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \
OUT_RING( RADEON_WAIT_CRTC_PFLIP ); \
- \
ADVANCE_RING(); \
} while (0)
#define RADEON_FLUSH_CACHE() \
do { \
BEGIN_RING( 2 ); \
- \
OUT_RING( CP_PACKET0( RADEON_RB2D_DSTCACHE_CTLSTAT, 0 ) ); \
OUT_RING( RADEON_RB2D_DC_FLUSH ); \
- \
+ ADVANCE_RING(); \
+} while (0)
+
+#define RADEON_PURGE_CACHE() \
+do { \
+ BEGIN_RING( 2 ); \
+ OUT_RING( CP_PACKET0( RADEON_RB2D_DSTCACHE_CTLSTAT, 0 ) ); \
+ OUT_RING( RADEON_RB2D_DC_FLUSH_ALL ); \
ADVANCE_RING(); \
} while (0)
#define RADEON_FLUSH_ZCACHE() \
do { \
BEGIN_RING( 2 ); \
- \
OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 0 ) ); \
OUT_RING( RADEON_RB3D_ZC_FLUSH ); \
- \
ADVANCE_RING(); \
} while (0)
@@ -567,10 +588,10 @@ do { \
DRM_INFO( "BEGIN_RING( %d ) in %s\n", \
n, __FUNCTION__ ); \
} \
- if ( dev_priv->ring.space < n * sizeof(u32) ) { \
- radeon_wait_ring( dev_priv, n * sizeof(u32) ); \
+ if ( dev_priv->ring.space < (n) * sizeof(u32) ) { \
+ radeon_wait_ring( dev_priv, (n) * sizeof(u32) ); \
} \
- dev_priv->ring.space -= n * sizeof(u32); \
+ dev_priv->ring.space -= (n) * sizeof(u32); \
ring = dev_priv->ring.start; \
write = dev_priv->ring.tail; \
mask = dev_priv->ring.tail_mask; \
@@ -591,7 +612,7 @@ do { \
DRM_INFO( " OUT_RING( 0x%08x ) at 0x%x\n", \
(unsigned int)(x), write ); \
} \
- ring[write++] = x; \
+ ring[write++] = (x); \
write &= mask; \
} while (0)
diff --git a/linux/radeon_state.c b/linux/radeon_state.c
index c99e1ad7..f94f965f 100644
--- a/linux/radeon_state.c
+++ b/linux/radeon_state.c
@@ -34,9 +34,6 @@
#include "drm.h"
#include <linux/delay.h>
-/* This must be defined to 1 for now */
-#define USE_OLD_BLITS 0
-
/* ================================================================
* CP hardware state programming functions
@@ -235,9 +232,9 @@ static inline void radeon_emit_setup( drm_radeon_private_t *dev_priv )
ADVANCE_RING();
}
-#ifdef TCL_ENABLE
static inline void radeon_emit_tcl( drm_radeon_private_t *dev_priv )
{
+#ifdef TCL_ENABLE
drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
RING_LOCALS;
@@ -275,8 +272,10 @@ static inline void radeon_emit_tcl( drm_radeon_private_t *dev_priv )
}
ADVANCE_RING();
-}
+#else
+ DRM_ERROR( "TCL not enabled!\n" );
#endif
+}
static inline void radeon_emit_misc( drm_radeon_private_t *dev_priv )
{
@@ -297,7 +296,6 @@ static inline void radeon_emit_misc( drm_radeon_private_t *dev_priv )
static inline void radeon_emit_tex0( drm_radeon_private_t *dev_priv )
{
drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
- drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
drm_radeon_texture_regs_t *tex = &sarea_priv->tex_state[0];
RING_LOCALS;
DRM_DEBUG( " %s: offset=0x%x\n", __FUNCTION__, tex->pp_txoffset );
@@ -310,7 +308,7 @@ static inline void radeon_emit_tex0( drm_radeon_private_t *dev_priv )
OUT_RING( tex->pp_txoffset );
OUT_RING( tex->pp_txcblend );
OUT_RING( tex->pp_txablend );
- OUT_RING( ctx->pp_tfactor );
+ OUT_RING( tex->pp_tfactor );
OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_0, 0 ) );
OUT_RING( tex->pp_border_color );
@@ -321,7 +319,6 @@ static inline void radeon_emit_tex0( drm_radeon_private_t *dev_priv )
static inline void radeon_emit_tex1( drm_radeon_private_t *dev_priv )
{
drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
- drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
drm_radeon_texture_regs_t *tex = &sarea_priv->tex_state[1];
RING_LOCALS;
DRM_DEBUG( " %s: offset=0x%x\n", __FUNCTION__, tex->pp_txoffset );
@@ -334,7 +331,7 @@ static inline void radeon_emit_tex1( drm_radeon_private_t *dev_priv )
OUT_RING( tex->pp_txoffset );
OUT_RING( tex->pp_txcblend );
OUT_RING( tex->pp_txablend );
- OUT_RING( ctx->pp_tfactor );
+ OUT_RING( tex->pp_tfactor );
OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_1, 0 ) );
OUT_RING( tex->pp_border_color );
@@ -345,7 +342,6 @@ static inline void radeon_emit_tex1( drm_radeon_private_t *dev_priv )
static inline void radeon_emit_tex2( drm_radeon_private_t *dev_priv )
{
drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
- drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
drm_radeon_texture_regs_t *tex = &sarea_priv->tex_state[2];
RING_LOCALS;
DRM_DEBUG( " %s\n", __FUNCTION__ );
@@ -358,7 +354,7 @@ static inline void radeon_emit_tex2( drm_radeon_private_t *dev_priv )
OUT_RING( tex->pp_txoffset );
OUT_RING( tex->pp_txcblend );
OUT_RING( tex->pp_txablend );
- OUT_RING( ctx->pp_tfactor );
+ OUT_RING( tex->pp_tfactor );
OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_2, 0 ) );
OUT_RING( tex->pp_border_color );
@@ -408,12 +404,12 @@ static inline void radeon_emit_state( drm_radeon_private_t *dev_priv )
sarea_priv->dirty &= ~RADEON_UPLOAD_SETUP;
}
-#ifdef TCL_ENABLE
if ( dirty & RADEON_UPLOAD_TCL ) {
+#ifdef TCL_ENABLE
radeon_emit_tcl( dev_priv );
+#endif
sarea_priv->dirty &= ~RADEON_UPLOAD_TCL;
}
-#endif
if ( dirty & RADEON_UPLOAD_MISC ) {
radeon_emit_misc( dev_priv );
@@ -437,11 +433,6 @@ static inline void radeon_emit_state( drm_radeon_private_t *dev_priv )
sarea_priv->dirty &= ~RADEON_UPLOAD_TEX2;
}
-#if 0
- /* Turn off the texture cache flushing */
- sarea_priv->context_state.tex_cntl_c &= ~RADEON_TEX_CACHE_FLUSH;
-#endif
-
sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES |
RADEON_UPLOAD_TEX1IMAGES |
RADEON_UPLOAD_TEX2IMAGES |
@@ -576,16 +567,11 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev,
unsigned int tmp = flags;
flags &= ~(RADEON_FRONT | RADEON_BACK);
- if ( tmp & RADEON_FRONT )
- flags |= RADEON_BACK;
- if ( tmp & RADEON_BACK )
- flags |= RADEON_FRONT;
+ if ( tmp & RADEON_FRONT ) flags |= RADEON_BACK;
+ if ( tmp & RADEON_BACK ) flags |= RADEON_FRONT;
}
RADEON_WAIT_UNTIL_IDLE();
-#if 0
- RADEON_FLUSH_CACHE();
-#endif
for ( i = 0 ; i < nbox ; i++ ) {
int x = pbox[i].x1;
@@ -817,21 +803,12 @@ static void radeon_cp_dispatch_swap( drm_device_t *dev )
RADEON_GMC_CLR_CMP_CNTL_DIS |
RADEON_GMC_WR_MSK_DIS );
-#if 0
OUT_RING( dev_priv->back_pitch_offset );
OUT_RING( dev_priv->front_pitch_offset );
OUT_RING( (x << 16) | y );
OUT_RING( (x << 16) | y );
OUT_RING( (w << 16) | h );
-#else
- OUT_RING( dev_priv->depth_pitch_offset );
- OUT_RING( dev_priv->front_pitch_offset );
-
- OUT_RING( (0 << 16) | 0 );
- OUT_RING( (0 << 16) | 0 );
- OUT_RING( (832 << 16) | 600 );
-#endif
ADVANCE_RING();
}
@@ -1499,3 +1476,68 @@ int radeon_cp_stipple( struct inode *inode, struct file *filp,
return -EINVAL;
}
+
+int radeon_cp_indirect( 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_radeon_private_t *dev_priv = dev->dev_private;
+ drm_device_dma_t *dma = dev->dma;
+ drm_buf_t *buf;
+ drm_radeon_buf_priv_t *buf_priv;
+ drm_radeon_indirect_t indirect;
+ RING_LOCALS;
+
+ 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;
+ }
+ if ( !dev_priv || dev_priv->is_pci ) {
+ DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ );
+ return -EINVAL;
+ }
+
+ if ( copy_from_user( &indirect, (drm_radeon_indirect_t *)arg,
+ sizeof(indirect) ) )
+ return -EFAULT;
+
+ DRM_DEBUG( "indirect: idx=%d s=%d e=%d d=%d\n",
+ indirect.idx, indirect.start,
+ indirect.end, indirect.discard );
+
+ if ( indirect.idx < 0 || indirect.idx >= dma->buf_count ) {
+ DRM_ERROR( "buffer index %d (of %d max)\n",
+ indirect.idx, dma->buf_count - 1 );
+ return -EINVAL;
+ }
+
+ buf = dma->buflist[indirect.idx];
+ buf_priv = buf->dev_private;
+
+ if ( buf->pid != current->pid ) {
+ DRM_ERROR( "process %d using buffer owned by %d\n",
+ current->pid, buf->pid );
+ return -EINVAL;
+ }
+ if ( buf->pending ) {
+ DRM_ERROR( "sending pending buffer %d\n", indirect.idx );
+ return -EINVAL;
+ }
+
+ if ( indirect.start < buf->used ) {
+ DRM_ERROR( "reusing indirect: start=0x%x actual=0x%x\n",
+ indirect.start, buf->used );
+ return -EINVAL;
+ }
+
+ buf->used = indirect.end;
+ buf_priv->discard = indirect.discard;
+
+ RADEON_WAIT_UNTIL_3D_IDLE();
+
+ radeon_cp_dispatch_indirect( dev, buf, indirect.start, indirect.end );
+
+ return 0;
+}
diff --git a/shared-core/drm.h b/shared-core/drm.h
index b892682a..e8bccd86 100644
--- a/shared-core/drm.h
+++ b/shared-core/drm.h
@@ -370,14 +370,15 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43)
#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44)
#define DRM_IOCTL_R128_RESET DRM_IO( 0x46)
-#define DRM_IOCTL_R128_SWAP DRM_IO( 0x47)
-#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x48, drm_r128_clear_t)
-#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t)
-#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t)
-#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t)
-#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4c, drm_r128_depth_t)
-#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t)
-#define DRM_IOCTL_R128_PACKET DRM_IOWR(0x4e, drm_r128_packet_t)
+#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x47, drm_r128_fullscreen_t)
+#define DRM_IOCTL_R128_SWAP DRM_IO( 0x48)
+#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x49, drm_r128_clear_t)
+#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x4a, drm_r128_vertex_t)
+#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4b, drm_r128_indices_t)
+#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4c, drm_r128_blit_t)
+#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4d, drm_r128_depth_t)
+#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4e, drm_r128_stipple_t)
+#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(0x4f, drm_r128_indirect_t)
/* Radeon specific ioctls */
#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( 0x40, drm_radeon_init_t)
@@ -386,14 +387,14 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_RADEON_CP_RESET DRM_IO( 0x43)
#define DRM_IOCTL_RADEON_CP_IDLE DRM_IO( 0x44)
#define DRM_IOCTL_RADEON_RESET DRM_IO( 0x45)
-#define DRM_IOCTL_RADEON_PAGEFLIP DRM_IOW( 0x46, drm_radeon_pageflip_t)
+#define DRM_IOCTL_RADEON_FULLSCREEN DRM_IOW( 0x46, drm_radeon_fullscreen_t)
#define DRM_IOCTL_RADEON_SWAP DRM_IO( 0x47)
#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( 0x48, drm_radeon_clear_t)
#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( 0x49, drm_radeon_vertex_t)
#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_t)
#define DRM_IOCTL_RADEON_BLIT DRM_IOW( 0x4b, drm_radeon_blit_t)
-#define DRM_IOCTL_RADEON_STIPPLE DRM_IOWR(0x4c, drm_radeon_stipple_t)
-#define DRM_IOCTL_RADEON_PACKET DRM_IOWR(0x4d, drm_radeon_packet_t)
+#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t)
+#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t)
/* SiS specific ioctls */
#define SIS_IOCTL_FB_ALLOC DRM_IOWR(0x44, drm_sis_mem_t)
diff --git a/shared/drm.h b/shared/drm.h
index b892682a..e8bccd86 100644
--- a/shared/drm.h
+++ b/shared/drm.h
@@ -370,14 +370,15 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43)
#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44)
#define DRM_IOCTL_R128_RESET DRM_IO( 0x46)
-#define DRM_IOCTL_R128_SWAP DRM_IO( 0x47)
-#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x48, drm_r128_clear_t)
-#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t)
-#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t)
-#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t)
-#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4c, drm_r128_depth_t)
-#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t)
-#define DRM_IOCTL_R128_PACKET DRM_IOWR(0x4e, drm_r128_packet_t)
+#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x47, drm_r128_fullscreen_t)
+#define DRM_IOCTL_R128_SWAP DRM_IO( 0x48)
+#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x49, drm_r128_clear_t)
+#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x4a, drm_r128_vertex_t)
+#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4b, drm_r128_indices_t)
+#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4c, drm_r128_blit_t)
+#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4d, drm_r128_depth_t)
+#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4e, drm_r128_stipple_t)
+#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(0x4f, drm_r128_indirect_t)
/* Radeon specific ioctls */
#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( 0x40, drm_radeon_init_t)
@@ -386,14 +387,14 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_RADEON_CP_RESET DRM_IO( 0x43)
#define DRM_IOCTL_RADEON_CP_IDLE DRM_IO( 0x44)
#define DRM_IOCTL_RADEON_RESET DRM_IO( 0x45)
-#define DRM_IOCTL_RADEON_PAGEFLIP DRM_IOW( 0x46, drm_radeon_pageflip_t)
+#define DRM_IOCTL_RADEON_FULLSCREEN DRM_IOW( 0x46, drm_radeon_fullscreen_t)
#define DRM_IOCTL_RADEON_SWAP DRM_IO( 0x47)
#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( 0x48, drm_radeon_clear_t)
#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( 0x49, drm_radeon_vertex_t)
#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_t)
#define DRM_IOCTL_RADEON_BLIT DRM_IOW( 0x4b, drm_radeon_blit_t)
-#define DRM_IOCTL_RADEON_STIPPLE DRM_IOWR(0x4c, drm_radeon_stipple_t)
-#define DRM_IOCTL_RADEON_PACKET DRM_IOWR(0x4d, drm_radeon_packet_t)
+#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t)
+#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t)
/* SiS specific ioctls */
#define SIS_IOCTL_FB_ALLOC DRM_IOWR(0x44, drm_sis_mem_t)