diff options
-rw-r--r-- | linux-core/drmP.h | 51 | ||||
-rw-r--r-- | linux-core/r128_drv.c | 2 | ||||
-rw-r--r-- | linux/drmP.h | 51 | ||||
-rw-r--r-- | linux/r128_cce.c | 127 | ||||
-rw-r--r-- | linux/r128_drm.h | 3 | ||||
-rw-r--r-- | linux/r128_drv.c | 2 | ||||
-rw-r--r-- | linux/r128_drv.h | 75 | ||||
-rw-r--r-- | linux/r128_state.c | 224 | ||||
-rw-r--r-- | linux/radeon_cp.c | 54 | ||||
-rw-r--r-- | linux/radeon_drm.h | 2 | ||||
-rw-r--r-- | linux/radeon_drv.h | 32 | ||||
-rw-r--r-- | linux/radeon_state.c | 24 |
12 files changed, 294 insertions, 353 deletions
diff --git a/linux-core/drmP.h b/linux-core/drmP.h index affeae70..9a8fe61f 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -11,11 +11,11 @@ * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -23,10 +23,10 @@ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. - * + * * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> - * + * */ #ifndef _DRM_P_H_ @@ -284,6 +284,27 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, len += sprintf(&buf[len], fmt , ##arg); \ if (len > DRM_PROC_LIMIT) { ret; return len; } + /* Mapping helper macros */ +#define DRM_IOREMAP(map) \ + (map)->handle = drm_ioremap( (map)->offset, (map)->size ) + +#define DRM_IOREMAPFREE(map) \ + do { \ + if ( (map)->handle && (map)->size ) \ + drm_ioremapfree( (map)->handle, (map)->size ); \ + } while (0) + +#define DRM_FIND_MAP(map, o) \ + do { \ + int i; \ + for ( i = 0 ; i < dev->map_count ; i++ ) { \ + if ( dev->maplist[i]->offset == o ) { \ + map = dev->maplist[i]; \ + break; \ + } \ + } \ + } while (0) + /* Internal types and structures */ #define DRM_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) #define DRM_MIN(a,b) ((a)<(b)?(a):(b)) @@ -304,7 +325,7 @@ typedef struct drm_ioctl_desc { typedef struct drm_devstate { pid_t owner; /* X server pid holding x_lock */ - + } drm_devstate_t; typedef struct drm_magic_entry { @@ -365,14 +386,14 @@ typedef struct drm_buf { #define DRM_DMA_HISTOGRAM_NEXT(current) ((current)*10) typedef struct drm_histogram { atomic_t total; - + atomic_t queued_to_dispatched[DRM_DMA_HISTOGRAM_SLOTS]; atomic_t dispatched_to_completed[DRM_DMA_HISTOGRAM_SLOTS]; atomic_t completed_to_freed[DRM_DMA_HISTOGRAM_SLOTS]; - + atomic_t queued_to_completed[DRM_DMA_HISTOGRAM_SLOTS]; atomic_t queued_to_freed[DRM_DMA_HISTOGRAM_SLOTS]; - + atomic_t dma[DRM_DMA_HISTOGRAM_SLOTS]; atomic_t schedule[DRM_DMA_HISTOGRAM_SLOTS]; atomic_t ctx[DRM_DMA_HISTOGRAM_SLOTS]; @@ -396,7 +417,7 @@ typedef struct drm_freelist { int initialized; /* Freelist in use */ atomic_t count; /* Number of free buffers */ drm_buf_t *next; /* End pointer */ - + wait_queue_head_t waiting; /* Processes waiting on free bufs */ int low_mark; /* Low water mark */ int high_mark; /* High water mark */ @@ -462,7 +483,7 @@ typedef struct drm_device_dma { atomic_t total_prio; /* Total DRM_DMA_PRIORITY */ atomic_t total_bytes; /* Total bytes DMA'd */ atomic_t total_dmas; /* Total DMA buffers dispatched */ - + atomic_t total_missed_dma; /* Missed drm_do_dma */ atomic_t total_missed_lock; /* Missed lock in drm_do_dma */ atomic_t total_missed_free; /* Missed drm_free_this_buffer */ @@ -475,7 +496,7 @@ typedef struct drm_device_dma { drm_buf_entry_t bufs[DRM_MAX_ORDER+1]; int buf_count; drm_buf_t **buflist; /* Vector of pointers info bufs */ - int seg_count; + int seg_count; int page_count; unsigned long *pagelist; unsigned long byte_count; @@ -523,7 +544,7 @@ typedef struct drm_device { int unique_len; /* Length of unique field */ dev_t device; /* Device number for mknod */ char *devname; /* For /proc/interrupts */ - + int blocked; /* Blocked due to VC switch? */ struct proc_dir_entry *root; /* Root for this device's entries */ @@ -544,7 +565,7 @@ typedef struct drm_device { atomic_t total_ioctl; atomic_t total_irq; /* Total interruptions */ atomic_t total_ctx; /* Total context switches */ - + atomic_t total_locks; atomic_t total_unlocks; atomic_t total_contends; @@ -585,7 +606,7 @@ typedef struct drm_device { #if DRM_DMA_HISTOGRAM drm_histogram_t histo; #endif - + /* Callback to X server for context switch and for heavy-handed reset. */ char buf[DRM_BSZ]; /* Output buffer */ @@ -595,7 +616,7 @@ typedef struct drm_device { struct fasync_struct *buf_async;/* Processes waiting for SIGIO */ wait_queue_head_t buf_readers; /* Processes waiting to read */ wait_queue_head_t buf_writers; /* Processes waiting to ctx switch */ - + #if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) drm_agp_head_t *agp; #endif diff --git a/linux-core/r128_drv.c b/linux-core/r128_drv.c index cf258925..62185b58 100644 --- a/linux-core/r128_drv.c +++ b/linux-core/r128_drv.c @@ -37,7 +37,7 @@ #define R128_NAME "r128" #define R128_DESC "ATI Rage 128" -#define R128_DATE "20010101" +#define R128_DATE "20010125" #define R128_MAJOR 2 #define R128_MINOR 1 #define R128_PATCHLEVEL 4 diff --git a/linux/drmP.h b/linux/drmP.h index affeae70..9a8fe61f 100644 --- a/linux/drmP.h +++ b/linux/drmP.h @@ -11,11 +11,11 @@ * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -23,10 +23,10 @@ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. - * + * * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> - * + * */ #ifndef _DRM_P_H_ @@ -284,6 +284,27 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, len += sprintf(&buf[len], fmt , ##arg); \ if (len > DRM_PROC_LIMIT) { ret; return len; } + /* Mapping helper macros */ +#define DRM_IOREMAP(map) \ + (map)->handle = drm_ioremap( (map)->offset, (map)->size ) + +#define DRM_IOREMAPFREE(map) \ + do { \ + if ( (map)->handle && (map)->size ) \ + drm_ioremapfree( (map)->handle, (map)->size ); \ + } while (0) + +#define DRM_FIND_MAP(map, o) \ + do { \ + int i; \ + for ( i = 0 ; i < dev->map_count ; i++ ) { \ + if ( dev->maplist[i]->offset == o ) { \ + map = dev->maplist[i]; \ + break; \ + } \ + } \ + } while (0) + /* Internal types and structures */ #define DRM_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) #define DRM_MIN(a,b) ((a)<(b)?(a):(b)) @@ -304,7 +325,7 @@ typedef struct drm_ioctl_desc { typedef struct drm_devstate { pid_t owner; /* X server pid holding x_lock */ - + } drm_devstate_t; typedef struct drm_magic_entry { @@ -365,14 +386,14 @@ typedef struct drm_buf { #define DRM_DMA_HISTOGRAM_NEXT(current) ((current)*10) typedef struct drm_histogram { atomic_t total; - + atomic_t queued_to_dispatched[DRM_DMA_HISTOGRAM_SLOTS]; atomic_t dispatched_to_completed[DRM_DMA_HISTOGRAM_SLOTS]; atomic_t completed_to_freed[DRM_DMA_HISTOGRAM_SLOTS]; - + atomic_t queued_to_completed[DRM_DMA_HISTOGRAM_SLOTS]; atomic_t queued_to_freed[DRM_DMA_HISTOGRAM_SLOTS]; - + atomic_t dma[DRM_DMA_HISTOGRAM_SLOTS]; atomic_t schedule[DRM_DMA_HISTOGRAM_SLOTS]; atomic_t ctx[DRM_DMA_HISTOGRAM_SLOTS]; @@ -396,7 +417,7 @@ typedef struct drm_freelist { int initialized; /* Freelist in use */ atomic_t count; /* Number of free buffers */ drm_buf_t *next; /* End pointer */ - + wait_queue_head_t waiting; /* Processes waiting on free bufs */ int low_mark; /* Low water mark */ int high_mark; /* High water mark */ @@ -462,7 +483,7 @@ typedef struct drm_device_dma { atomic_t total_prio; /* Total DRM_DMA_PRIORITY */ atomic_t total_bytes; /* Total bytes DMA'd */ atomic_t total_dmas; /* Total DMA buffers dispatched */ - + atomic_t total_missed_dma; /* Missed drm_do_dma */ atomic_t total_missed_lock; /* Missed lock in drm_do_dma */ atomic_t total_missed_free; /* Missed drm_free_this_buffer */ @@ -475,7 +496,7 @@ typedef struct drm_device_dma { drm_buf_entry_t bufs[DRM_MAX_ORDER+1]; int buf_count; drm_buf_t **buflist; /* Vector of pointers info bufs */ - int seg_count; + int seg_count; int page_count; unsigned long *pagelist; unsigned long byte_count; @@ -523,7 +544,7 @@ typedef struct drm_device { int unique_len; /* Length of unique field */ dev_t device; /* Device number for mknod */ char *devname; /* For /proc/interrupts */ - + int blocked; /* Blocked due to VC switch? */ struct proc_dir_entry *root; /* Root for this device's entries */ @@ -544,7 +565,7 @@ typedef struct drm_device { atomic_t total_ioctl; atomic_t total_irq; /* Total interruptions */ atomic_t total_ctx; /* Total context switches */ - + atomic_t total_locks; atomic_t total_unlocks; atomic_t total_contends; @@ -585,7 +606,7 @@ typedef struct drm_device { #if DRM_DMA_HISTOGRAM drm_histogram_t histo; #endif - + /* Callback to X server for context switch and for heavy-handed reset. */ char buf[DRM_BSZ]; /* Output buffer */ @@ -595,7 +616,7 @@ typedef struct drm_device { struct fasync_struct *buf_async;/* Processes waiting for SIGIO */ wait_queue_head_t buf_readers; /* Processes waiting to read */ wait_queue_head_t buf_writers; /* Processes waiting to ctx switch */ - + #if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) drm_agp_head_t *agp; #endif diff --git a/linux/r128_cce.c b/linux/r128_cce.c index 6df2b45a..279d6404 100644 --- a/linux/r128_cce.c +++ b/linux/r128_cce.c @@ -85,26 +85,6 @@ static u32 r128_cce_microcode[] = { }; -#define DO_IOREMAP(_m) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size) - -#define DO_IOREMAPFREE(_m) \ - do { \ - if ((_m)->handle && (_m)->size) \ - drm_ioremapfree((_m)->handle, (_m)->size); \ - } while (0) - -#define DO_FIND_MAP(_m, _o) \ - do { \ - int _i; \ - for (_i = 0; _i < dev->map_count; _i++) { \ - if (dev->maplist[_i]->offset == _o) { \ - _m = dev->maplist[_i]; \ - break; \ - } \ - } \ - } while (0) - - int R128_READ_PLL(drm_device_t *dev, int addr) { drm_r128_private_t *dev_priv = dev->dev_private; @@ -223,7 +203,7 @@ static void r128_do_cce_flush( drm_r128_private_t *dev_priv ) /* Wait for the CCE to go idle. */ -static int r128_do_cce_idle( drm_r128_private_t *dev_priv ) +int r128_do_cce_idle( drm_r128_private_t *dev_priv ) { int i; @@ -433,13 +413,30 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) break; } - dev_priv->fb_bpp = init->fb_bpp; + switch ( init->fb_bpp ) { + case 16: + dev_priv->color_fmt = R128_DATATYPE_RGB565; + break; + case 32: + default: + dev_priv->color_fmt = R128_DATATYPE_ARGB8888; + break; + } dev_priv->front_offset = init->front_offset; dev_priv->front_pitch = init->front_pitch; dev_priv->back_offset = init->back_offset; dev_priv->back_pitch = init->back_pitch; - dev_priv->depth_bpp = init->depth_bpp; + switch ( init->depth_bpp ) { + case 16: + dev_priv->depth_fmt = R128_DATATYPE_RGB565; + break; + case 24: + case 32: + default: + dev_priv->depth_fmt = R128_DATATYPE_ARGB8888; + break; + } dev_priv->depth_offset = init->depth_offset; dev_priv->depth_pitch = init->depth_pitch; dev_priv->span_offset = init->span_offset; @@ -464,29 +461,24 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) } } - DO_FIND_MAP( dev_priv->fb, init->fb_offset ); - DO_FIND_MAP( dev_priv->mmio, init->mmio_offset ); - DO_FIND_MAP( dev_priv->cce_ring, init->ring_offset ); - DO_FIND_MAP( dev_priv->ring_rptr, init->ring_rptr_offset ); - DO_FIND_MAP( dev_priv->buffers, init->buffers_offset ); + DRM_FIND_MAP( dev_priv->fb, init->fb_offset ); + DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset ); + DRM_FIND_MAP( dev_priv->cce_ring, init->ring_offset ); + DRM_FIND_MAP( dev_priv->ring_rptr, init->ring_rptr_offset ); + DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset ); if ( !dev_priv->is_pci ) { - DO_FIND_MAP( dev_priv->agp_textures, - init->agp_textures_offset ); + DRM_FIND_MAP( dev_priv->agp_textures, + init->agp_textures_offset ); } dev_priv->sarea_priv = (drm_r128_sarea_t *)((u8 *)dev_priv->sarea->handle + init->sarea_priv_offset); - DO_IOREMAP( dev_priv->cce_ring ); - DO_IOREMAP( dev_priv->ring_rptr ); - DO_IOREMAP( dev_priv->buffers ); -#if 0 - if ( !dev_priv->is_pci ) { - DO_IOREMAP( dev_priv->agp_textures ); - } -#endif + DRM_IOREMAP( dev_priv->cce_ring ); + DRM_IOREMAP( dev_priv->ring_rptr ); + DRM_IOREMAP( dev_priv->buffers ); dev_priv->ring.head = ((__volatile__ u32 *) dev_priv->ring_rptr->handle); @@ -500,6 +492,8 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1; + dev_priv->ring.high_mark = 128; + dev_priv->sarea_priv->last_frame = 0; R128_WRITE( R128_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame ); @@ -519,14 +513,9 @@ static int r128_do_cleanup_cce( drm_device_t *dev ) if ( dev->dev_private ) { drm_r128_private_t *dev_priv = dev->dev_private; - DO_IOREMAPFREE( dev_priv->cce_ring ); - DO_IOREMAPFREE( dev_priv->ring_rptr ); - DO_IOREMAPFREE( dev_priv->buffers ); -#if 0 - if ( !dev_priv->is_pci ) { - DO_IOREMAPFREE( dev_priv->agp_textures ); - } -#endif + DRM_IOREMAPFREE( dev_priv->cce_ring ); + DRM_IOREMAPFREE( dev_priv->ring_rptr ); + DRM_IOREMAPFREE( dev_priv->buffers ); drm_free( dev->dev_private, sizeof(drm_r128_private_t), DRM_MEM_DRIVER ); @@ -564,11 +553,8 @@ int r128_cce_start( struct inode *inode, struct file *filp, drm_r128_private_t *dev_priv = dev->dev_private; DRM_DEBUG( "%s\n", __FUNCTION__ ); - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); - return -EINVAL; - } + LOCK_TEST_WITH_RETURN( dev ); + if ( dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4 ) { DRM_DEBUG( "%s while CCE running\n", __FUNCTION__ ); return 0; @@ -592,11 +578,7 @@ int r128_cce_stop( struct inode *inode, struct file *filp, int ret; DRM_DEBUG( "%s\n", __FUNCTION__ ); - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); - return -EINVAL; - } + LOCK_TEST_WITH_RETURN( dev ); if ( copy_from_user( &stop, (drm_r128_init_t *)arg, sizeof(stop) ) ) return -EFAULT; @@ -638,11 +620,8 @@ int r128_cce_reset( struct inode *inode, struct file *filp, drm_r128_private_t *dev_priv = dev->dev_private; DRM_DEBUG( "%s\n", __FUNCTION__ ); - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); - return -EINVAL; - } + LOCK_TEST_WITH_RETURN( dev ); + if ( !dev_priv ) { DRM_DEBUG( "%s called before init done\n", __FUNCTION__ ); return -EINVAL; @@ -664,11 +643,7 @@ int r128_cce_idle( struct inode *inode, struct file *filp, drm_r128_private_t *dev_priv = dev->dev_private; DRM_DEBUG( "%s\n", __FUNCTION__ ); - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); - return -EINVAL; - } + LOCK_TEST_WITH_RETURN( dev ); if ( dev_priv->cce_running ) { r128_do_cce_flush( dev_priv ); @@ -684,11 +659,7 @@ int r128_engine_reset( struct inode *inode, struct file *filp, drm_device_t *dev = priv->dev; DRM_DEBUG( "%s\n", __FUNCTION__ ); - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); - return -EINVAL; - } + LOCK_TEST_WITH_RETURN( dev ); return r128_do_engine_reset( dev ); } @@ -737,11 +708,7 @@ int r128_fullscreen( struct inode *inode, struct file *filp, drm_device_t *dev = priv->dev; drm_r128_fullscreen_t fs; - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); - return -EINVAL; - } + LOCK_TEST_WITH_RETURN( dev ); if ( copy_from_user( &fs, (drm_r128_fullscreen_t *)arg, sizeof(fs) ) ) return -EFAULT; @@ -932,15 +899,11 @@ int r128_cce_buffers( struct inode *inode, struct file *filp, int ret = 0; drm_dma_t d; + LOCK_TEST_WITH_RETURN( dev ); + if ( copy_from_user( &d, (drm_dma_t *) arg, sizeof(d) ) ) return -EFAULT; - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); - return -EINVAL; - } - /* Please don't send us buffers. */ if ( d.send_count != 0 ) { diff --git a/linux/r128_drm.h b/linux/r128_drm.h index 94dba1ed..3454de7b 100644 --- a/linux/r128_drm.h +++ b/linux/r128_drm.h @@ -218,9 +218,10 @@ typedef struct drm_r128_fullscreen { typedef struct drm_r128_clear { unsigned int flags; - int x, y, w, h; unsigned int clear_color; unsigned int clear_depth; + unsigned int color_mask; + unsigned int depth_mask; } drm_r128_clear_t; typedef struct drm_r128_vertex { diff --git a/linux/r128_drv.c b/linux/r128_drv.c index cf258925..62185b58 100644 --- a/linux/r128_drv.c +++ b/linux/r128_drv.c @@ -37,7 +37,7 @@ #define R128_NAME "r128" #define R128_DESC "ATI Rage 128" -#define R128_DATE "20010101" +#define R128_DATE "20010125" #define R128_MAJOR 2 #define R128_MINOR 1 #define R128_PATCHLEVEL 4 diff --git a/linux/r128_drv.h b/linux/r128_drv.h index 08ef5dc9..c5cd2181 100644 --- a/linux/r128_drv.h +++ b/linux/r128_drv.h @@ -51,6 +51,8 @@ typedef struct drm_r128_ring_buffer { u32 tail; u32 tail_mask; int space; + + int high_mark; } drm_r128_ring_buffer_t; typedef struct drm_r128_private { @@ -74,13 +76,13 @@ typedef struct drm_r128_private { u32 crtc_offset; u32 crtc_offset_cntl; - unsigned int fb_bpp; + u32 color_fmt; unsigned int front_offset; unsigned int front_pitch; unsigned int back_offset; unsigned int back_pitch; - unsigned int depth_bpp; + u32 depth_fmt; unsigned int depth_offset; unsigned int depth_pitch; unsigned int span_offset; @@ -143,6 +145,7 @@ 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_cce_idle( drm_r128_private_t *dev_priv ); extern int r128_do_cleanup_pageflip( drm_device_t *dev ); /* r128_state.c */ @@ -386,23 +389,24 @@ extern int r128_context_switch_complete(drm_device_t *dev, int new); #define R128_WATERMARK_N 8 #define R128_WATERMARK_K 128 -#define R128_MAX_USEC_TIMEOUT 100000 /* 100 ms */ +#define R128_MAX_USEC_TIMEOUT 100000 /* 100 ms */ #define R128_LAST_FRAME_REG R128_GUI_SCRATCH_REG0 #define R128_LAST_DISPATCH_REG R128_GUI_SCRATCH_REG1 #define R128_MAX_VB_AGE 0xffffffff - #define R128_MAX_VB_VERTS (0xffff) +#define R128_RING_HIGH_MARK 128 + #define R128_BASE(reg) ((u32)(dev_priv->mmio->handle)) #define R128_ADDR(reg) (R128_BASE(reg) + reg) -#define R128_DEREF(reg) *(__volatile__ int *)R128_ADDR(reg) +#define R128_DEREF(reg) *(volatile u32 *)R128_ADDR(reg) #define R128_READ(reg) R128_DEREF(reg) #define R128_WRITE(reg,val) do { R128_DEREF(reg) = val; } while (0) -#define R128_DEREF8(reg) *(__volatile__ char *)R128_ADDR(reg) +#define R128_DEREF8(reg) *(volatile u8 *)R128_ADDR(reg) #define R128_READ8(reg) R128_DEREF8(reg) #define R128_WRITE8(reg,val) do { R128_DEREF8(reg) = val; } while (0) @@ -414,13 +418,6 @@ do { \ extern int R128_READ_PLL(drm_device_t *dev, int addr); -#define R128CCE0(p,r,n) ((p) | ((n) << 16) | ((r) >> 2)) -#define R128CCE1(p,r1,r2) ((p) | (((r2) >> 2) << 11) | ((r1) >> 2)) -#define R128CCE2(p) ((p)) -#define R128CCE3(p,n) ((p) | ((n) << 16)) - - - #define CCE_PACKET0( reg, n ) (R128_CCE_PACKET0 | \ ((n) << 16) | ((reg) >> 2)) @@ -431,7 +428,57 @@ extern int R128_READ_PLL(drm_device_t *dev, int addr); (pkt) | ((n) << 16)) -#define r128_flush_write_combine() mb() + + +/* ================================================================ + * Misc helper macros + */ + +#define LOCK_TEST_WITH_RETURN( dev ) \ +do { \ + if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \ + dev->lock.pid != current->pid ) { \ + DRM_ERROR( "%s called without lock held\n", \ + __FUNCTION__ ); \ + return -EINVAL; \ + } \ +} while (0) + +#define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \ +do { \ + drm_r128_ring_buffer_t *ring = &dev_priv->ring; int i; \ + if ( ring->space < ring->high_mark ) { \ + for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { \ + ring->space = *ring->head - ring->tail; \ + if ( ring->space <= 0 ) \ + ring->space += ring->size; \ + if ( ring->space >= ring->high_mark ) \ + goto __ring_space_done; \ + udelay( 1 ); \ + } \ + DRM_ERROR( "ring space check failed!\n" ); \ + return -EBUSY; \ + } \ + __ring_space_done: \ +} while (0) + +#define VB_AGE_TEST_WITH_RETURN( dev_priv ) \ +do { \ + drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; \ + if ( sarea_priv->last_dispatch >= R128_MAX_VB_AGE ) { \ + int __ret = r128_do_cce_idle( dev_priv ); \ + if ( __ret < 0 ) return __ret; \ + sarea_priv->last_dispatch = 0; \ + r128_freelist_reset( dev ); \ + } \ +} while (0) + + +/* ================================================================ + * Ring control + */ + +#define r128_flush_write_combine() mb() #define R128_VERBOSE 0 diff --git a/linux/r128_state.c b/linux/r128_state.c index ba003929..60bddd8a 100644 --- a/linux/r128_state.c +++ b/linux/r128_state.c @@ -32,6 +32,7 @@ #include "drmP.h" #include "r128_drv.h" #include "drm.h" +#include <linux/delay.h> /* ================================================================ @@ -360,45 +361,20 @@ static void r128_print_dirty( const char *msg, unsigned int flags ) } static void r128_cce_dispatch_clear( drm_device_t *dev, - unsigned int flags, - int cx, int cy, int cw, int ch, - unsigned int clear_color, - unsigned int clear_depth ) + drm_r128_clear_t *clear ) { drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; int nbox = sarea_priv->nbox; drm_clip_rect_t *pbox = sarea_priv->boxes; - u32 fb_bpp, depth_bpp; + unsigned int flags = clear->flags; int i; RING_LOCALS; DRM_DEBUG( "%s\n", __FUNCTION__ ); r128_update_ring_snapshot( dev_priv ); - switch ( dev_priv->fb_bpp ) { - case 16: - fb_bpp = R128_GMC_DST_16BPP; - break; - case 32: - fb_bpp = R128_GMC_DST_32BPP; - break; - default: - return; - } - switch ( dev_priv->depth_bpp ) { - case 16: - depth_bpp = R128_GMC_DST_16BPP; - break; - case 24: - case 32: - depth_bpp = R128_GMC_DST_32BPP; - break; - default: - return; - } - - if ( dev_priv->page_flipping && dev_priv->current_page == 1) { + if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) { unsigned int tmp = flags; flags &= ~(R128_FRONT | R128_BACK); @@ -420,7 +396,7 @@ static void r128_cce_dispatch_clear( drm_device_t *dev, BEGIN_RING( 2 ); OUT_RING( CCE_PACKET0( R128_DP_WRITE_MASK, 0 ) ); - OUT_RING( sarea_priv->context_state.plane_3d_mask_c ); + OUT_RING( clear->color_mask ); ADVANCE_RING(); } @@ -431,14 +407,14 @@ static void r128_cce_dispatch_clear( drm_device_t *dev, OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | R128_GMC_BRUSH_SOLID_COLOR | - fb_bpp | + (dev_priv->color_fmt << 8) | 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 ); + OUT_RING( clear->clear_color ); OUT_RING( (x << 16) | y ); OUT_RING( (w << 16) | h ); @@ -452,14 +428,14 @@ static void r128_cce_dispatch_clear( drm_device_t *dev, OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | R128_GMC_BRUSH_SOLID_COLOR | - fb_bpp | + (dev_priv->color_fmt << 8) | 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 ); + OUT_RING( clear->clear_color ); OUT_RING( (x << 16) | y ); OUT_RING( (w << 16) | h ); @@ -473,7 +449,7 @@ static void r128_cce_dispatch_clear( drm_device_t *dev, OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | R128_GMC_BRUSH_SOLID_COLOR | - depth_bpp | + (dev_priv->depth_fmt << 8) | R128_GMC_SRC_DATATYPE_COLOR | R128_ROP3_P | R128_GMC_CLR_CMP_CNTL_DIS | @@ -481,7 +457,7 @@ static void r128_cce_dispatch_clear( drm_device_t *dev, R128_GMC_WR_MSK_DIS ); OUT_RING( dev_priv->depth_pitch_offset_c ); - OUT_RING( clear_depth ); + OUT_RING( clear->clear_depth ); OUT_RING( (x << 16) | y ); OUT_RING( (w << 16) | h ); @@ -497,7 +473,6 @@ static void r128_cce_dispatch_swap( drm_device_t *dev ) drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; int nbox = sarea_priv->nbox; drm_clip_rect_t *pbox = sarea_priv->boxes; - u32 fb_bpp; int i; RING_LOCALS; DRM_DEBUG( "%s\n", __FUNCTION__ ); @@ -510,16 +485,6 @@ static void r128_cce_dispatch_swap( drm_device_t *dev ) r128_cce_performance_boxes( dev_priv ); #endif - switch ( dev_priv->fb_bpp ) { - case 16: - fb_bpp = R128_GMC_DST_16BPP; - break; - case 32: - default: - fb_bpp = R128_GMC_DST_32BPP; - break; - } - for ( i = 0 ; i < nbox ; i++ ) { int x = pbox[i].x1; int y = pbox[i].y1; @@ -532,7 +497,7 @@ static void r128_cce_dispatch_swap( drm_device_t *dev ) OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL | R128_GMC_DST_PITCH_OFFSET_CNTL | R128_GMC_BRUSH_NONE | - fb_bpp | + (dev_priv->color_fmt << 8) | R128_GMC_SRC_DATATYPE_COLOR | R128_ROP3_S | R128_DP_SRC_SOURCE_MEMORY | @@ -676,15 +641,6 @@ static void r128_cce_dispatch_vertex( drm_device_t *dev, dev_priv->sarea_priv->last_dispatch++; -#if 0 - if ( dev_priv->submit_age == R128_MAX_VB_AGE ) { - ret = r128_do_cce_idle( dev_priv ); - if ( ret < 0 ) return ret; - dev_priv->submit_age = 0; - r128_freelist_reset( dev ); - } -#endif - sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS; sarea_priv->nbox = 0; } @@ -750,15 +706,6 @@ static void r128_cce_dispatch_indirect( drm_device_t *dev, } dev_priv->sarea_priv->last_dispatch++; - -#if 0 - if ( dev_priv->submit_age == R128_MAX_VB_AGE ) { - ret = r128_do_cce_idle( dev_priv ); - if ( ret < 0 ) return ret; - dev_priv->submit_age = 0; - r128_freelist_reset( dev ); - } -#endif } static void r128_cce_dispatch_indices( drm_device_t *dev, @@ -839,15 +786,6 @@ static void r128_cce_dispatch_indices( drm_device_t *dev, dev_priv->sarea_priv->last_dispatch++; -#if 0 - if ( dev_priv->submit_age == R128_MAX_VB_AGE ) { - ret = r128_do_cce_idle( dev_priv ); - if ( ret < 0 ) return ret; - dev_priv->submit_age = 0; - r128_freelist_reset( dev ); - } -#endif - sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS; sarea_priv->nbox = 0; } @@ -972,25 +910,12 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev, int count, x, y; u32 *buffer; u8 *mask; - u32 depth_bpp; int i; RING_LOCALS; DRM_DEBUG( "%s\n", __FUNCTION__ ); r128_update_ring_snapshot( dev_priv ); - switch ( dev_priv->depth_bpp ) { - case 16: - depth_bpp = R128_GMC_DST_16BPP; - break; - case 24: - case 32: - depth_bpp = R128_GMC_DST_32BPP; - break; - default: - return -EINVAL; - } - count = depth->n; if ( copy_from_user( &x, depth->x, sizeof(x) ) ) { return -EFAULT; @@ -1028,7 +953,7 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev, OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | R128_GMC_BRUSH_SOLID_COLOR | - depth_bpp | + (dev_priv->depth_fmt << 8) | R128_GMC_SRC_DATATYPE_COLOR | R128_ROP3_P | R128_GMC_CLR_CMP_CNTL_DIS | @@ -1052,7 +977,7 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev, OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | R128_GMC_BRUSH_SOLID_COLOR | - depth_bpp | + (dev_priv->depth_fmt << 8) | R128_GMC_SRC_DATATYPE_COLOR | R128_ROP3_P | R128_GMC_CLR_CMP_CNTL_DIS | @@ -1080,25 +1005,12 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev, int count, *x, *y; u32 *buffer; u8 *mask; - u32 depth_bpp; int i; RING_LOCALS; DRM_DEBUG( "%s\n", __FUNCTION__ ); r128_update_ring_snapshot( dev_priv ); - switch ( dev_priv->depth_bpp ) { - case 16: - depth_bpp = R128_GMC_DST_16BPP; - break; - case 24: - case 32: - depth_bpp = R128_GMC_DST_32BPP; - break; - default: - return -EINVAL; - } - count = depth->n; x = kmalloc( count * sizeof(*x), 0 ); @@ -1159,7 +1071,7 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev, OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | R128_GMC_BRUSH_SOLID_COLOR | - depth_bpp | + (dev_priv->depth_fmt << 8) | R128_GMC_SRC_DATATYPE_COLOR | R128_ROP3_P | R128_GMC_CLR_CMP_CNTL_DIS | @@ -1183,7 +1095,7 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev, OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | R128_GMC_BRUSH_SOLID_COLOR | - depth_bpp | + (dev_priv->depth_fmt << 8) | R128_GMC_SRC_DATATYPE_COLOR | R128_ROP3_P | R128_GMC_CLR_CMP_CNTL_DIS | @@ -1211,24 +1123,11 @@ static int r128_cce_dispatch_read_span( drm_device_t *dev, { drm_r128_private_t *dev_priv = dev->dev_private; int count, x, y; - u32 depth_bpp; RING_LOCALS; DRM_DEBUG( "%s\n", __FUNCTION__ ); r128_update_ring_snapshot( dev_priv ); - switch ( dev_priv->depth_bpp ) { - case 16: - depth_bpp = R128_GMC_DST_16BPP; - break; - case 24: - case 32: - depth_bpp = R128_GMC_DST_32BPP; - break; - default: - return -EINVAL; - } - count = depth->n; if ( copy_from_user( &x, depth->x, sizeof(x) ) ) { return -EFAULT; @@ -1243,7 +1142,7 @@ static int r128_cce_dispatch_read_span( drm_device_t *dev, OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL | R128_GMC_DST_PITCH_OFFSET_CNTL | R128_GMC_BRUSH_NONE | - depth_bpp | + (dev_priv->depth_fmt << 8) | R128_GMC_SRC_DATATYPE_COLOR | R128_ROP3_S | R128_DP_SRC_SOURCE_MEMORY | @@ -1267,25 +1166,12 @@ static int r128_cce_dispatch_read_pixels( drm_device_t *dev, { drm_r128_private_t *dev_priv = dev->dev_private; int count, *x, *y; - u32 depth_bpp; int i; RING_LOCALS; DRM_DEBUG( "%s\n", __FUNCTION__ ); r128_update_ring_snapshot( dev_priv ); - switch ( dev_priv->depth_bpp ) { - case 16: - depth_bpp = R128_GMC_DST_16BPP; - break; - case 24: - case 32: - depth_bpp = R128_GMC_DST_32BPP; - break; - default: - return -EINVAL; - } - count = depth->n; if ( count > dev_priv->depth_pitch ) { count = dev_priv->depth_pitch; @@ -1318,7 +1204,7 @@ static int r128_cce_dispatch_read_pixels( drm_device_t *dev, OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL | R128_GMC_DST_PITCH_OFFSET_CNTL | R128_GMC_BRUSH_NONE | - depth_bpp | + (dev_priv->depth_fmt << 8) | R128_GMC_SRC_DATATYPE_COLOR | R128_ROP3_S | R128_DP_SRC_SOURCE_MEMORY | @@ -1380,22 +1266,18 @@ int r128_cce_clear( struct inode *inode, struct file *filp, drm_r128_clear_t clear; DRM_DEBUG( "%s\n", __FUNCTION__ ); - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "r128_cce_clear called without lock held\n" ); - return -EINVAL; - } + LOCK_TEST_WITH_RETURN( dev ); if ( copy_from_user( &clear, (drm_r128_clear_t *) arg, sizeof(clear) ) ) return -EFAULT; + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS ) sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS; - r128_cce_dispatch_clear( dev, clear.flags, - clear.x, clear.y, clear.w, clear.h, - clear.clear_color, clear.clear_depth ); + r128_cce_dispatch_clear( dev, &clear ); /* Make sure we restore the 3D state next time. */ @@ -1413,11 +1295,9 @@ int r128_cce_swap( struct inode *inode, struct file *filp, drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; DRM_DEBUG( "%s\n", __FUNCTION__ ); - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "r128_cce_swap called without lock held\n" ); - return -EINVAL; - } + LOCK_TEST_WITH_RETURN( dev ); + + RING_SPACE_TEST_WITH_RETURN( dev_priv ); if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS ) sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS; @@ -1444,11 +1324,8 @@ int r128_cce_vertex( struct inode *inode, struct file *filp, drm_r128_buf_priv_t *buf_priv; drm_r128_vertex_t vertex; - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); - return -EINVAL; - } + LOCK_TEST_WITH_RETURN( dev ); + if ( !dev_priv || dev_priv->is_pci ) { DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ ); return -EINVAL; @@ -1473,6 +1350,9 @@ int r128_cce_vertex( struct inode *inode, struct file *filp, return -EINVAL; } + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + VB_AGE_TEST_WITH_RETURN( dev_priv ); + buf = dma->buflist[vertex.idx]; buf_priv = buf->dev_private; @@ -1507,11 +1387,8 @@ int r128_cce_indices( struct inode *inode, struct file *filp, drm_r128_indices_t elts; int count; - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); - return -EINVAL; - } + LOCK_TEST_WITH_RETURN( dev ); + if ( !dev_priv || dev_priv->is_pci ) { DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ ); return -EINVAL; @@ -1536,6 +1413,9 @@ int r128_cce_indices( struct inode *inode, struct file *filp, return -EINVAL; } + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + VB_AGE_TEST_WITH_RETURN( dev_priv ); + buf = dma->buflist[elts.idx]; buf_priv = buf->dev_private; @@ -1576,13 +1456,10 @@ int r128_cce_blit( struct inode *inode, struct file *filp, drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; drm_device_dma_t *dma = dev->dma; + drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_blit_t blit; - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); - return -EINVAL; - } + LOCK_TEST_WITH_RETURN( dev ); if ( copy_from_user( &blit, (drm_r128_blit_t *)arg, sizeof(blit) ) ) @@ -1597,6 +1474,9 @@ int r128_cce_blit( struct inode *inode, struct file *filp, return -EINVAL; } + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + VB_AGE_TEST_WITH_RETURN( dev_priv ); + return r128_cce_dispatch_blit( dev, &blit ); } @@ -1605,18 +1485,17 @@ int r128_cce_depth( struct inode *inode, struct file *filp, { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; + drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_depth_t depth; - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); - return -EINVAL; - } + LOCK_TEST_WITH_RETURN( dev ); if ( copy_from_user( &depth, (drm_r128_depth_t *)arg, sizeof(depth) ) ) return -EFAULT; + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + switch ( depth.func ) { case R128_WRITE_SPAN: return r128_cce_dispatch_write_span( dev, &depth ); @@ -1636,14 +1515,11 @@ int r128_cce_stipple( struct inode *inode, struct file *filp, { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; + drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_stipple_t stipple; u32 mask[32]; - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); - return -EINVAL; - } + LOCK_TEST_WITH_RETURN( dev ); if ( copy_from_user( &stipple, (drm_r128_stipple_t *)arg, sizeof(stipple) ) ) @@ -1653,6 +1529,8 @@ int r128_cce_stipple( struct inode *inode, struct file *filp, 32 * sizeof(u32) ) ) return -EFAULT; + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + r128_cce_dispatch_stipple( dev, mask ); return 0; @@ -1664,11 +1542,7 @@ int r128_cce_indirect( struct inode *inode, struct file *filp, drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); - return -EINVAL; - } + LOCK_TEST_WITH_RETURN( dev ); /* Indirect buffer firing is not supported at this time. */ diff --git a/linux/radeon_cp.c b/linux/radeon_cp.c index 5d662bc0..d0fb7a0b 100644 --- a/linux/radeon_cp.c +++ b/linux/radeon_cp.c @@ -300,26 +300,6 @@ static u32 radeon_cp_microcode[][2] = { }; -#define DO_IOREMAP(_m) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size) - -#define DO_IOREMAPFREE(_m) \ - do { \ - if ((_m)->handle && (_m)->size) \ - drm_ioremapfree((_m)->handle, (_m)->size); \ - } while (0) - -#define DO_FIND_MAP(_m, _o) \ - do { \ - int _i; \ - for (_i = 0; _i < dev->map_count; _i++) { \ - if (dev->maplist[_i]->offset == _o) { \ - _m = dev->maplist[_i]; \ - break; \ - } \ - } \ - } while (0) - - int RADEON_READ_PLL(drm_device_t *dev, int addr) { drm_radeon_private_t *dev_priv = dev->dev_private; @@ -722,12 +702,10 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) RADEON_BFACE_SOLID | RADEON_FFACE_SOLID | RADEON_FLAT_SHADE_VTX_LAST | - RADEON_DIFFUSE_SHADE_FLAT | RADEON_ALPHA_SHADE_FLAT | RADEON_SPECULAR_SHADE_FLAT | RADEON_FOG_SHADE_FLAT | - RADEON_VTX_PIX_CENTER_OGL | RADEON_ROUND_MODE_TRUNC | RADEON_ROUND_PREC_8TH_PIX); @@ -742,27 +720,27 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) } } - DO_FIND_MAP( dev_priv->fb, init->fb_offset ); - DO_FIND_MAP( dev_priv->mmio, init->mmio_offset ); - DO_FIND_MAP( dev_priv->cp_ring, init->ring_offset ); - DO_FIND_MAP( dev_priv->ring_rptr, init->ring_rptr_offset ); - DO_FIND_MAP( dev_priv->buffers, init->buffers_offset ); + DRM_FIND_MAP( dev_priv->fb, init->fb_offset ); + DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset ); + DRM_FIND_MAP( dev_priv->cp_ring, init->ring_offset ); + DRM_FIND_MAP( dev_priv->ring_rptr, init->ring_rptr_offset ); + DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset ); if ( !dev_priv->is_pci ) { - DO_FIND_MAP( dev_priv->agp_textures, - init->agp_textures_offset ); + DRM_FIND_MAP( dev_priv->agp_textures, + init->agp_textures_offset ); } dev_priv->sarea_priv = (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 ); + DRM_IOREMAP( dev_priv->cp_ring ); + DRM_IOREMAP( dev_priv->ring_rptr ); + DRM_IOREMAP( dev_priv->buffers ); #if 0 if ( !dev_priv->is_pci ) { - DO_IOREMAP( dev_priv->agp_textures ); + DRM_IOREMAP( dev_priv->agp_textures ); } #endif @@ -784,6 +762,8 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1; + dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; + #if 0 /* Initialize the scratch register pointer. This will cause * the scratch register values to be written out to memory @@ -828,12 +808,12 @@ static int radeon_do_cleanup_cp( drm_device_t *dev ) 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 ); + DRM_IOREMAPFREE( dev_priv->cp_ring ); + DRM_IOREMAPFREE( dev_priv->ring_rptr ); + DRM_IOREMAPFREE( dev_priv->buffers ); #if 0 if ( !dev_priv->is_pci ) { - DO_IOREMAPFREE( dev_priv->agp_textures ); + DRM_IOREMAPFREE( dev_priv->agp_textures ); } #endif diff --git a/linux/radeon_drm.h b/linux/radeon_drm.h index c5f9f66d..15d91693 100644 --- a/linux/radeon_drm.h +++ b/linux/radeon_drm.h @@ -281,6 +281,8 @@ typedef struct drm_radeon_clear { int x, y, w, h; unsigned int clear_color; unsigned int clear_depth; + unsigned int color_mask; + unsigned int depth_mask; union { float f[5]; unsigned int ui[5]; diff --git a/linux/radeon_drv.h b/linux/radeon_drv.h index 06b54199..e2c3ebd4 100644 --- a/linux/radeon_drv.h +++ b/linux/radeon_drv.h @@ -50,6 +50,8 @@ typedef struct drm_radeon_ring_buffer { u32 tail; u32 tail_mask; int space; + + int high_mark; } drm_radeon_ring_buffer_t; typedef struct drm_radeon_depth_clear_t { @@ -91,13 +93,13 @@ typedef struct drm_radeon_private { u32 crtc_offset; u32 crtc_offset_cntl; - unsigned int color_fmt; + u32 color_fmt; unsigned int front_offset; unsigned int front_pitch; unsigned int back_offset; unsigned int back_pitch; - unsigned int depth_fmt; + u32 depth_fmt; unsigned int depth_offset; unsigned int depth_pitch; @@ -534,15 +536,17 @@ extern int radeon_context_switch_complete(drm_device_t *dev, int new); #define RADEON_MAX_VB_AGE 0x7fffffff #define RADEON_MAX_VB_VERTS (0xffff) +#define RADEON_RING_HIGH_MARK 128 + #define RADEON_BASE(reg) ((u32)(dev_priv->mmio->handle)) #define RADEON_ADDR(reg) (RADEON_BASE(reg) + reg) -#define RADEON_DEREF(reg) *(__volatile__ u32 *)RADEON_ADDR(reg) +#define RADEON_DEREF(reg) *(volatile u32 *)RADEON_ADDR(reg) #define RADEON_READ(reg) RADEON_DEREF(reg) #define RADEON_WRITE(reg,val) do { RADEON_DEREF(reg) = val; } while (0) -#define RADEON_DEREF8(reg) *(__volatile__ u8 *)RADEON_ADDR(reg) +#define RADEON_DEREF8(reg) *(volatile u8 *)RADEON_ADDR(reg) #define RADEON_READ8(reg) RADEON_DEREF8(reg) #define RADEON_WRITE8(reg,val) do { RADEON_DEREF8(reg) = val; } while (0) @@ -630,7 +634,25 @@ do { \ * Misc helper macros */ -#define VB_AGE_CHECK_WITH_RET( dev_priv ) \ +#define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \ +do { \ + drm_radeon_ring_buffer_t *ring = &dev_priv->ring; int i; \ + if ( ring->space < ring->high_mark ) { \ + for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { \ + ring->space = *ring->head - ring->tail; \ + if ( ring->space <= 0 ) \ + ring->space += ring->size; \ + if ( ring->space >= ring->high_mark ) \ + goto __ring_space_done; \ + udelay( 1 ); \ + } \ + DRM_ERROR( "ring space check failed!\n" ); \ + return -EBUSY; \ + } \ + __ring_space_done: \ +} while (0) + +#define VB_AGE_TEST_WITH_RETURN( dev_priv ) \ do { \ drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; \ if ( sarea_priv->last_dispatch >= RADEON_MAX_VB_AGE ) { \ diff --git a/linux/radeon_state.c b/linux/radeon_state.c index 1a4da800..75aed88d 100644 --- a/linux/radeon_state.c +++ b/linux/radeon_state.c @@ -23,9 +23,8 @@ * DEALINGS IN THE SOFTWARE. * * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> - * + * Kevin E. Martin <martin@valinux.com> */ #define __NO_VERSION__ @@ -525,7 +524,7 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, RADEON_WAIT_UNTIL_3D_IDLE(); OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) ); - OUT_RING( sarea_priv->context_state.rb3d_planemask ); + OUT_RING( clear->color_mask ); ADVANCE_RING(); @@ -1130,6 +1129,8 @@ int radeon_cp_clear( struct inode *inode, struct file *filp, sizeof(clear) ) ) return -EFAULT; + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS ) sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; @@ -1153,6 +1154,8 @@ int radeon_cp_swap( struct inode *inode, struct file *filp, return -EINVAL; } + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS ) sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; @@ -1207,7 +1210,8 @@ int radeon_cp_vertex( struct inode *inode, struct file *filp, return -EINVAL; } - VB_AGE_CHECK_WITH_RET( dev_priv ); + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + VB_AGE_TEST_WITH_RETURN( dev_priv ); buf = dma->buflist[vertex.idx]; buf_priv = buf->dev_private; @@ -1272,7 +1276,8 @@ int radeon_cp_indices( struct inode *inode, struct file *filp, return -EINVAL; } - VB_AGE_CHECK_WITH_RET( dev_priv ); + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + VB_AGE_TEST_WITH_RETURN( dev_priv ); buf = dma->buflist[elts.idx]; buf_priv = buf->dev_private; @@ -1336,7 +1341,8 @@ int radeon_cp_blit( struct inode *inode, struct file *filp, return -EINVAL; } - VB_AGE_CHECK_WITH_RET( dev_priv ); + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + VB_AGE_TEST_WITH_RETURN( dev_priv ); return radeon_cp_dispatch_blit( dev, &blit ); } @@ -1346,6 +1352,7 @@ int radeon_cp_stipple( 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_radeon_stipple_t stipple; u32 mask[32]; @@ -1363,6 +1370,8 @@ int radeon_cp_stipple( struct inode *inode, struct file *filp, 32 * sizeof(u32) ) ) return -EFAULT; + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + radeon_cp_dispatch_stipple( dev, mask ); return 0; @@ -1423,7 +1432,8 @@ int radeon_cp_indirect( struct inode *inode, struct file *filp, return -EINVAL; } - VB_AGE_CHECK_WITH_RET( dev_priv ); + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + VB_AGE_TEST_WITH_RETURN( dev_priv ); buf->used = indirect.end; buf_priv->discard = indirect.discard; |