diff options
Diffstat (limited to 'linux')
-rw-r--r-- | linux/Makefile.kernel | 18 | ||||
-rw-r--r-- | linux/Makefile.linux | 6 | ||||
-rw-r--r-- | linux/agpsupport.c | 120 | ||||
-rw-r--r-- | linux/compat-pre24.h | 4 | ||||
-rw-r--r-- | linux/dma.c | 1 | ||||
-rw-r--r-- | linux/drm.h | 28 | ||||
-rw-r--r-- | linux/drmP.h | 27 | ||||
-rw-r--r-- | linux/gamma_drv.c | 4 | ||||
-rw-r--r-- | linux/i810_drv.c | 7 | ||||
-rw-r--r-- | linux/memory.c | 64 | ||||
-rw-r--r-- | linux/mga_bufs.c | 1 | ||||
-rw-r--r-- | linux/mga_drv.c | 7 | ||||
-rw-r--r-- | linux/r128_bufs.c | 20 | ||||
-rw-r--r-- | linux/r128_cce.c | 30 | ||||
-rw-r--r-- | linux/r128_context.c | 4 | ||||
-rw-r--r-- | linux/r128_drm.h | 44 | ||||
-rw-r--r-- | linux/r128_drv.c | 45 | ||||
-rw-r--r-- | linux/r128_drv.h | 26 | ||||
-rw-r--r-- | linux/r128_state.c | 830 | ||||
-rw-r--r-- | linux/radeon_drv.c | 5 | ||||
-rw-r--r-- | linux/sis_context.c | 36 | ||||
-rw-r--r-- | linux/sis_drv.c | 23 | ||||
-rw-r--r-- | linux/sis_mm.c | 19 | ||||
-rw-r--r-- | linux/tdfx_drv.c | 6 |
24 files changed, 847 insertions, 528 deletions
diff --git a/linux/Makefile.kernel b/linux/Makefile.kernel index 261eb0d89..1e61ae972 100644 --- a/linux/Makefile.kernel +++ b/linux/Makefile.kernel @@ -36,16 +36,16 @@ else endif endif -gamma-objs := $(lib-objs) gamma_drv.o gamma_dma.o -tdfx-objs := $(lib-objs) tdfx_drv.o tdfx_context.o -r128-objs := $(lib-objs) r128_drv.o r128_cce.o r128_context.o \ - r128_bufs.o r128_state.o -radeon-objs := $(lib-objs) radeon_drv.o radeon_cp.o radeon_context.o \ +gamma-objs := $(lib-objs) gamma_drv.o gamma_dma.o +tdfx-objs := $(lib-objs) tdfx_drv.o tdfx_context.o +r128-objs := $(lib-objs) r128_drv.o r128_cce.o r128_context.o \ + r128_bufs.o r128_state.o +radeon-objs := $(lib-objs) radeon_drv.o radeon_cp.o radeon_context.o \ radeon_bufs.o radeon_state.o -ffb-objs := $(lib-objs) ffb_drv.o ffb_context.o -mga-objs := $(lib-objs) mga_drv.o mga_dma.o mga_context.o \ - mga_bufs.o mga_state.o -i810-objs := $(lib-objs) i810_drv.o i810_dma.o i810_context.o \ +ffb-objs := $(lib-objs) ffb_drv.o ffb_context.o +mga-objs := $(lib-objs) mga_drv.o mga_dma.o mga_context.o \ + mga_bufs.o mga_state.o +i810-objs := $(lib-objs) i810_drv.o i810_dma.o i810_context.o \ i810_bufs.o obj-$(CONFIG_DRM_GAMMA) += gamma.o $(gamma-objs) diff --git a/linux/Makefile.linux b/linux/Makefile.linux index 283a66da7..2860f4c4b 100644 --- a/linux/Makefile.linux +++ b/linux/Makefile.linux @@ -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 @@ -142,7 +142,7 @@ MODS += i810.o endif -MGAOBJS= mga_drv.o mga_dma.o mga_bufs.o mga_state.o mga_context.o +MGAOBJS= mga_drv.o mga_dma.o mga_bufs.o mga_context.o mga_state.o MGAHEADERS= mga_drv.h $(DRMHEADERS) I810OBJS= i810_drv.o i810_dma.o i810_bufs.o i810_context.o diff --git a/linux/agpsupport.c b/linux/agpsupport.c index 24fd59cdf..c996df8f4 100644 --- a/linux/agpsupport.c +++ b/linux/agpsupport.c @@ -31,48 +31,14 @@ #define __NO_VERSION__ #include "drmP.h" #include <linux/module.h> +#if LINUX_VERSION_CODE < 0x020400 +#include "agpsupport-pre24.h" +#else +#define DRM_AGP_GET (drm_agp_t *)inter_module_get("drm_agp") +#define DRM_AGP_PUT inter_module_put("drm_agp") +#endif -drm_agp_func_t drm_agp = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; - -/* The C standard says that 'void *' is not guaranteed to hold a function - pointer, so we use this union to define a generic pointer that is - guaranteed to hold any of the function pointers we care about. */ -typedef union { - void (*free_memory)(agp_memory *); - agp_memory *(*allocate_memory)(size_t, u32); - int (*bind_memory)(agp_memory *, off_t); - int (*unbind_memory)(agp_memory *); - void (*enable)(u32); - int (*acquire)(void); - void (*release)(void); - void (*copy_info)(agp_kern_info *); - unsigned long address; -} drm_agp_func_u; - -typedef struct drm_agp_fill { - const char *name; - drm_agp_func_u *f; -} drm_agp_fill_t; - -static drm_agp_fill_t drm_agp_fill[] = { - { __MODULE_STRING(agp_free_memory), - (drm_agp_func_u *)&drm_agp.free_memory }, - { __MODULE_STRING(agp_allocate_memory), - (drm_agp_func_u *)&drm_agp.allocate_memory }, - { __MODULE_STRING(agp_bind_memory), - (drm_agp_func_u *)&drm_agp.bind_memory }, - { __MODULE_STRING(agp_unbind_memory), - (drm_agp_func_u *)&drm_agp.unbind_memory }, - { __MODULE_STRING(agp_enable), - (drm_agp_func_u *)&drm_agp.enable }, - { __MODULE_STRING(agp_backend_acquire), - (drm_agp_func_u *)&drm_agp.acquire }, - { __MODULE_STRING(agp_backend_release), - (drm_agp_func_u *)&drm_agp.release }, - { __MODULE_STRING(agp_copy_info), - (drm_agp_func_u *)&drm_agp.copy_info }, - { NULL, NULL } -}; +static const drm_agp_t *drm_agp = NULL; int drm_agp_info(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) @@ -82,7 +48,7 @@ int drm_agp_info(struct inode *inode, struct file *filp, unsigned int cmd, agp_kern_info *kern; drm_agp_info_t info; - if (!dev->agp->acquired || !drm_agp.copy_info) return -EINVAL; + if (!dev->agp->acquired || !drm_agp->copy_info) return -EINVAL; kern = &dev->agp->agp_info; info.agp_version_major = kern->version.major; @@ -107,8 +73,8 @@ int drm_agp_acquire(struct inode *inode, struct file *filp, unsigned int cmd, drm_device_t *dev = priv->dev; int retcode; - if (dev->agp->acquired || !drm_agp.acquire) return -EINVAL; - if ((retcode = (*drm_agp.acquire)())) return retcode; + if (dev->agp->acquired || !drm_agp->acquire) return -EINVAL; + if ((retcode = drm_agp->acquire())) return retcode; dev->agp->acquired = 1; return 0; } @@ -119,13 +85,18 @@ int drm_agp_release(struct inode *inode, struct file *filp, unsigned int cmd, drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; - if (!dev->agp->acquired || !drm_agp.release) return -EINVAL; - (*drm_agp.release)(); + if (!dev->agp->acquired || !drm_agp->release) return -EINVAL; + drm_agp->release(); dev->agp->acquired = 0; return 0; } +void _drm_agp_release(void) +{ + if (drm_agp->release) drm_agp->release(); +} + int drm_agp_enable(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -133,13 +104,13 @@ int drm_agp_enable(struct inode *inode, struct file *filp, unsigned int cmd, drm_device_t *dev = priv->dev; drm_agp_mode_t mode; - if (!dev->agp->acquired || !drm_agp.enable) return -EINVAL; + if (!dev->agp->acquired || !drm_agp->enable) return -EINVAL; if (copy_from_user(&mode, (drm_agp_mode_t *)arg, sizeof(mode))) return -EFAULT; dev->agp->mode = mode.mode; - (*drm_agp.enable)(mode.mode); + drm_agp->enable(mode.mode); dev->agp->base = dev->agp->agp_info.aper_base; dev->agp->enabled = 1; return 0; @@ -231,7 +202,7 @@ int drm_agp_bind(struct inode *inode, struct file *filp, unsigned int cmd, int retcode; int page; - if (!dev->agp->acquired || !drm_agp.bind_memory) return -EINVAL; + if (!dev->agp->acquired || !drm_agp->bind_memory) return -EINVAL; if (copy_from_user(&request, (drm_agp_binding_t *)arg, sizeof(request))) return -EFAULT; if (!(entry = drm_agp_lookup_entry(dev, request.handle))) @@ -270,24 +241,14 @@ int drm_agp_free(struct inode *inode, struct file *filp, unsigned int cmd, drm_agp_head_t *drm_agp_init(void) { - drm_agp_fill_t *fill; drm_agp_head_t *head = NULL; - int agp_available = 1; - - for (fill = &drm_agp_fill[0]; fill->name; fill++) { - char *n = (char *)fill->name; - *fill->f = (drm_agp_func_u)get_module_symbol(NULL, n); - DRM_DEBUG("%s resolves to 0x%08lx\n", n, (*fill->f).address); - if (!(*fill->f).address) agp_available = 0; - } - - DRM_DEBUG("agp_available = %d\n", agp_available); - if (agp_available) { + drm_agp = DRM_AGP_GET; + if (drm_agp) { if (!(head = drm_alloc(sizeof(*head), DRM_MEM_AGPLISTS))) return NULL; memset((void *)head, 0, sizeof(*head)); - (*drm_agp.copy_info)(&head->agp_info); + drm_agp->copy_info(&head->agp_info); if (head->agp_info.chipset == NOT_SUPPORTED) { drm_free(head, sizeof(*head), DRM_MEM_AGPLISTS); return NULL; @@ -337,12 +298,31 @@ drm_agp_head_t *drm_agp_init(void) void drm_agp_uninit(void) { - drm_agp_fill_t *fill; - - for (fill = &drm_agp_fill[0]; fill->name; fill++) { -#if LINUX_VERSION_CODE >= 0x020400 - if ((*fill->f).address) put_module_symbol((*fill->f).address); -#endif - (*fill->f).address = 0; - } + DRM_AGP_PUT; + drm_agp = NULL; +} + +agp_memory *drm_agp_allocate_memory(size_t pages, u32 type) +{ + if (!drm_agp->allocate_memory) return NULL; + return drm_agp->allocate_memory(pages, type); +} + +int drm_agp_free_memory(agp_memory *handle) +{ + if (!handle || !drm_agp->free_memory) return 0; + drm_agp->free_memory(handle); + return 1; +} + +int drm_agp_bind_memory(agp_memory *handle, off_t start) +{ + if (!handle || !drm_agp->bind_memory) return -EINVAL; + return drm_agp->bind_memory(handle, start); +} + +int drm_agp_unbind_memory(agp_memory *handle) +{ + if (!handle || !drm_agp->unbind_memory) return -EINVAL; + return drm_agp->unbind_memory(handle); } diff --git a/linux/compat-pre24.h b/linux/compat-pre24.h index 257baca15..77a2bee1c 100644 --- a/linux/compat-pre24.h +++ b/linux/compat-pre24.h @@ -38,4 +38,8 @@ #define block_all_signals(a,b,c) #define unblock_all_signals() +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) +#define __exit +#endif + #endif diff --git a/linux/dma.c b/linux/dma.c index 5cc3ec369..56dd2441e 100644 --- a/linux/dma.c +++ b/linux/dma.c @@ -405,6 +405,7 @@ int drm_dma_enqueue(drm_device_t *dev, drm_dma_t *d) schedule(); if (signal_pending(current)) { atomic_dec(&q->use_count); + remove_wait_queue(&q->write_queue, &entry); return -EINTR; } } diff --git a/linux/drm.h b/linux/drm.h index 77d23a9eb..e0496bc75 100644 --- a/linux/drm.h +++ b/linux/drm.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,7 +23,7 @@ * 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> * @@ -364,18 +364,20 @@ typedef struct drm_agp_info { #define DRM_IOCTL_I810_DOCOPY DRM_IO ( 0x48) /* Rage 128 specific ioctls */ -#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t) +#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t) #define DRM_IOCTL_R128_CCE_START DRM_IO( 0x41) -#define DRM_IOCTL_R128_CCE_STOP DRM_IOW( 0x42, drm_r128_cce_stop_t) +#define DRM_IOCTL_R128_CCE_STOP DRM_IOW( 0x42, drm_r128_cce_stop_t) #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_PACKET DRM_IOWR(0x4c, drm_r128_packet_t) +#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) /* Radeon specific ioctls */ #define DRM_IOCTL_RADEON_RESET DRM_IO( 0x40) diff --git a/linux/drmP.h b/linux/drmP.h index 46e08e057..affeae705 100644 --- a/linux/drmP.h +++ b/linux/drmP.h @@ -59,15 +59,6 @@ #include <asm/io.h> #include <asm/mman.h> #include <asm/uaccess.h> - -#ifndef copy_to_user_ret -#define copy_to_user_ret(to,from,n,retval) ({ if (copy_to_user(to,from,n)) return retval; }) -#endif - -#ifndef copy_from_user_ret -#define copy_from_user_ret(to,from,n,retval) ({ if (copy_from_user(to,from,n)) return retval; }) -#endif - #ifdef CONFIG_MTRR #include <asm/mtrr.h> #endif @@ -519,19 +510,6 @@ typedef struct drm_agp_head { unsigned long base; int agp_mtrr; } drm_agp_head_t; - -typedef struct { - void (*free_memory)(agp_memory *); - agp_memory *(*allocate_memory)(size_t, u32); - int (*bind_memory)(agp_memory *, off_t); - int (*unbind_memory)(agp_memory *); - void (*enable)(u32); - int (*acquire)(void); - void (*release)(void); - void (*copy_info)(agp_kern_info *); -} drm_agp_func_t; - -extern drm_agp_func_t drm_agp; #endif typedef struct drm_sigdata { @@ -833,6 +811,7 @@ extern drm_agp_head_t *drm_agp_init(void); extern void drm_agp_uninit(void); extern int drm_agp_acquire(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); +extern void _drm_agp_release(void); extern int drm_agp_release(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int drm_agp_enable(struct inode *inode, struct file *filp, @@ -847,6 +826,10 @@ extern int drm_agp_unbind(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int drm_agp_bind(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); +extern agp_memory *drm_agp_allocate_memory(size_t pages, u32 type); +extern int drm_agp_free_memory(agp_memory *handle); +extern int drm_agp_bind_memory(agp_memory *handle, off_t start); +extern int drm_agp_unbind_memory(agp_memory *handle); #endif #endif #endif diff --git a/linux/gamma_drv.c b/linux/gamma_drv.c index dba974c2b..a17bc1a9f 100644 --- a/linux/gamma_drv.c +++ b/linux/gamma_drv.c @@ -339,7 +339,7 @@ int gamma_find_devices(void) /* gamma_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ -static int gamma_init(void) +static int __init gamma_init(void) { int retcode; drm_device_t *dev = &gamma_device; @@ -380,7 +380,7 @@ static int gamma_init(void) /* gamma_cleanup is called via cleanup_module at module unload time. */ -static void gamma_cleanup(void) +static void __exit gamma_cleanup(void) { drm_device_t *dev = &gamma_device; diff --git a/linux/i810_drv.c b/linux/i810_drv.c index ed880c41a..7152eac3a 100644 --- a/linux/i810_drv.c +++ b/linux/i810_drv.c @@ -255,8 +255,7 @@ static int i810_takedown(drm_device_t *dev) } dev->agp->memory = NULL; - if (dev->agp->acquired && drm_agp.release) - (*drm_agp.release)(); + if (dev->agp->acquired) _drm_agp_release(); dev->agp->acquired = 0; dev->agp->enabled = 0; @@ -338,7 +337,7 @@ static int i810_takedown(drm_device_t *dev) /* i810_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ -static int i810_init(void) +static int __init i810_init(void) { int retcode; drm_device_t *dev = &i810_device; @@ -397,7 +396,7 @@ static int i810_init(void) /* i810_cleanup is called via cleanup_module at module unload time. */ -static void i810_cleanup(void) +static void __exit i810_cleanup(void) { drm_device_t *dev = &i810_device; diff --git a/linux/memory.c b/linux/memory.c index 34d19b203..261fb34a3 100644 --- a/linux/memory.c +++ b/linux/memory.c @@ -352,16 +352,13 @@ agp_memory *drm_alloc_agp(int pages, u32 type) return NULL; } - if (drm_agp.allocate_memory) { - if ((handle = (*drm_agp.allocate_memory)(pages, - type))) { - spin_lock(&drm_mem_lock); - ++drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count; - drm_mem_stats[DRM_MEM_TOTALAGP].bytes_allocated - += pages << PAGE_SHIFT; - spin_unlock(&drm_mem_lock); - return handle; - } + if ((handle = drm_agp_allocate_memory(pages, type))) { + spin_lock(&drm_mem_lock); + ++drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count; + drm_mem_stats[DRM_MEM_TOTALAGP].bytes_allocated + += pages << PAGE_SHIFT; + spin_unlock(&drm_mem_lock); + return handle; } spin_lock(&drm_mem_lock); ++drm_mem_stats[DRM_MEM_TOTALAGP].fail_count; @@ -381,8 +378,7 @@ int drm_free_agp(agp_memory *handle, int pages) return retval;; } - if (drm_agp.free_memory) { - (*drm_agp.free_memory)(handle); + if (drm_agp_free_memory(handle)) { spin_lock(&drm_mem_lock); free_count = ++drm_mem_stats[DRM_MEM_TOTALAGP].free_count; alloc_count = drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count; @@ -403,24 +399,19 @@ int drm_bind_agp(agp_memory *handle, unsigned int start) { int retcode = -EINVAL; - DRM_DEBUG("drm_bind_agp called\n"); if (!handle) { DRM_MEM_ERROR(DRM_MEM_BOUNDAGP, "Attempt to bind NULL AGP handle\n"); return retcode; } - DRM_DEBUG("drm_agp.bind_memory : %p\n", drm_agp.bind_memory); - if (drm_agp.bind_memory) { - if (!(retcode = (*drm_agp.bind_memory)(handle, start))) { - spin_lock(&drm_mem_lock); - ++drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count; - drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_allocated - += handle->page_count << PAGE_SHIFT; - spin_unlock(&drm_mem_lock); - DRM_DEBUG("drm_agp.bind_memory: retcode %d\n", retcode); - return retcode; - } + if (!(retcode = drm_agp_bind_memory(handle, start))) { + spin_lock(&drm_mem_lock); + ++drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count; + drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_allocated + += handle->page_count << PAGE_SHIFT; + spin_unlock(&drm_mem_lock); + return retcode; } spin_lock(&drm_mem_lock); ++drm_mem_stats[DRM_MEM_BOUNDAGP].fail_count; @@ -440,20 +431,17 @@ int drm_unbind_agp(agp_memory *handle) return retcode; } - if (drm_agp.unbind_memory) { - int c = handle->page_count; - if ((retcode = (*drm_agp.unbind_memory)(handle))) - return retcode; - spin_lock(&drm_mem_lock); - free_count = ++drm_mem_stats[DRM_MEM_BOUNDAGP].free_count; - alloc_count = drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count; - drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_freed += c << PAGE_SHIFT; - spin_unlock(&drm_mem_lock); - if (free_count > alloc_count) { - DRM_MEM_ERROR(DRM_MEM_BOUNDAGP, - "Excess frees: %d frees, %d allocs\n", - free_count, alloc_count); - } + if ((retcode = drm_agp_unbind_memory(handle))) return retcode; + spin_lock(&drm_mem_lock); + free_count = ++drm_mem_stats[DRM_MEM_BOUNDAGP].free_count; + alloc_count = drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count; + drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_freed + += handle->page_count << PAGE_SHIFT; + spin_unlock(&drm_mem_lock); + if (free_count > alloc_count) { + DRM_MEM_ERROR(DRM_MEM_BOUNDAGP, + "Excess frees: %d frees, %d allocs\n", + free_count, alloc_count); } return retcode; } diff --git a/linux/mga_bufs.c b/linux/mga_bufs.c index 00c0ea7f9..05d941b4c 100644 --- a/linux/mga_bufs.c +++ b/linux/mga_bufs.c @@ -420,7 +420,6 @@ int mga_infobufs(struct inode *inode, struct file *filp, unsigned int cmd, sizeof(dma->bufs[0] .freelist.high_mark))) return -EFAULT; - ++count; } } diff --git a/linux/mga_drv.c b/linux/mga_drv.c index 4aaac6254..883eb75ca 100644 --- a/linux/mga_drv.c +++ b/linux/mga_drv.c @@ -255,8 +255,7 @@ static int mga_takedown(drm_device_t *dev) } dev->agp->memory = NULL; - if (dev->agp->acquired && drm_agp.release) - (*drm_agp.release)(); + if (dev->agp->acquired) _drm_agp_release(); dev->agp->acquired = 0; dev->agp->enabled = 0; @@ -338,7 +337,7 @@ static int mga_takedown(drm_device_t *dev) /* mga_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ -static int mga_init(void) +static int __init mga_init(void) { int retcode; drm_device_t *dev = &mga_device; @@ -398,7 +397,7 @@ static int mga_init(void) /* mga_cleanup is called via cleanup_module at module unload time. */ -static void mga_cleanup(void) +static void __exit mga_cleanup(void) { drm_device_t *dev = &mga_device; diff --git a/linux/r128_bufs.c b/linux/r128_bufs.c index 86a63a427..a060749e3 100644 --- a/linux/r128_bufs.c +++ b/linux/r128_bufs.c @@ -60,7 +60,9 @@ int r128_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd, if (!dma) return -EINVAL; - if (copy_from_user(&request, (drm_buf_desc_t *)arg, sizeof(request))) + if (copy_from_user(&request, + (drm_buf_desc_t *)arg, + sizeof(request))) return -EFAULT; count = request.count; @@ -171,7 +173,9 @@ int r128_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd, request.count = entry->buf_count; request.size = size; - if (copy_to_user((drm_buf_desc_t *)arg, &request, sizeof(request))) + if (copy_to_user((drm_buf_desc_t *)arg, + &request, + sizeof(request))) return -EFAULT; dma->flags = _DRM_DMA_USE_AGP; @@ -191,7 +195,9 @@ int r128_addbufs(struct inode *inode, struct file *filp, unsigned int cmd, if (!dev_priv || dev_priv->is_pci) return -EINVAL; - if (copy_from_user(&request, (drm_buf_desc_t *)arg, sizeof(request))) + if (copy_from_user(&request, + (drm_buf_desc_t *)arg, + sizeof(request))) return -EFAULT; #if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) @@ -228,7 +234,9 @@ int r128_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd, ++dev->buf_use; /* Can't allocate more after this call */ spin_unlock(&dev->count_lock); - if (copy_from_user(&request, (drm_buf_map_t *)arg, sizeof(request))) + if (copy_from_user(&request, + (drm_buf_map_t *)arg, + sizeof(request))) return -EFAULT; if (request.count >= dma->buf_count) { @@ -292,7 +300,9 @@ int r128_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd, request.count = dma->buf_count; DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode); - if (copy_to_user((drm_buf_map_t *)arg, &request, sizeof(request))) + if (copy_to_user((drm_buf_map_t *)arg, + &request, + sizeof(request))) return -EFAULT; return retcode; diff --git a/linux/r128_cce.c b/linux/r128_cce.c index 0fed514bd..d978d53e1 100644 --- a/linux/r128_cce.c +++ b/linux/r128_cce.c @@ -114,7 +114,7 @@ int R128_READ_PLL(drm_device_t *dev, int addr) return R128_READ(R128_CLOCK_CNTL_DATA); } - +#if 0 static void r128_status( drm_r128_private_t *dev_priv ) { printk( "GUI_STAT = 0x%08x\n", @@ -130,6 +130,7 @@ static void r128_status( drm_r128_private_t *dev_priv ) printk( "PM4_BUFFER_CNTL = 0x%08x\n", (unsigned int)R128_READ( R128_PM4_BUFFER_CNTL ) ); } +#endif /* ================================================================ @@ -437,18 +438,23 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) dev_priv->fb_bpp = init->fb_bpp; dev_priv->front_offset = init->front_offset; dev_priv->front_pitch = init->front_pitch; - dev_priv->front_x = init->front_x; - dev_priv->front_y = init->front_y; dev_priv->back_offset = init->back_offset; dev_priv->back_pitch = init->back_pitch; - dev_priv->back_x = init->back_x; - dev_priv->back_y = init->back_y; dev_priv->depth_bpp = init->depth_bpp; dev_priv->depth_offset = init->depth_offset; dev_priv->depth_pitch = init->depth_pitch; - dev_priv->depth_x = init->depth_x; - dev_priv->depth_y = init->depth_y; + dev_priv->span_offset = init->span_offset; + + dev_priv->front_pitch_offset_c = (((dev_priv->front_pitch/8) << 21) | + (dev_priv->front_offset >> 5)); + dev_priv->back_pitch_offset_c = (((dev_priv->back_pitch/8) << 21) | + (dev_priv->back_offset >> 5)); + dev_priv->depth_pitch_offset_c = (((dev_priv->depth_pitch/8) << 21) | + (dev_priv->depth_offset >> 5) | + R128_DST_TILE); + dev_priv->span_pitch_offset_c = (((dev_priv->depth_pitch/8) << 21) | + (dev_priv->span_offset >> 5)); /* FIXME: We want multiple shared areas, including one shared * only by the X Server and kernel module. @@ -666,6 +672,10 @@ int r128_cce_idle( struct inode *inode, struct file *filp, return -EINVAL; } + if ( dev_priv->cce_running ) { + r128_do_cce_flush( dev_priv ); + } + return r128_do_cce_idle( dev_priv ); } @@ -692,6 +702,7 @@ int r128_engine_reset( struct inode *inode, struct file *filp, #define R128_BUFFER_USED 0xffffffff #define R128_BUFFER_FREE 0 +#if 0 static int r128_freelist_init( drm_device_t *dev ) { drm_device_dma_t *dma = dev->dma; @@ -737,6 +748,7 @@ static int r128_freelist_init( drm_device_t *dev ) return 0; } +#endif drm_buf_t *r128_freelist_get( drm_device_t *dev ) { @@ -817,12 +829,15 @@ void r128_update_ring_snapshot( drm_r128_private_t *dev_priv ) drm_r128_ring_buffer_t *ring = &dev_priv->ring; ring->space = *ring->head - ring->tail; +#if R128_PERFORMANCE_BOXES if ( ring->space == 0 ) atomic_inc( &dev_priv->idle_count ); +#endif if ( ring->space <= 0 ) ring->space += ring->size; } +#if 0 static int r128_verify_command( drm_r128_private_t *dev_priv, u32 cmd, int *size ) { @@ -963,6 +978,7 @@ static int r128_submit_packet_ring_insecure( drm_r128_private_t *dev_priv, #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 diff --git a/linux/r128_context.c b/linux/r128_context.c index 0d8b2f5c2..0741e7745 100644 --- a/linux/r128_context.c +++ b/linux/r128_context.c @@ -109,7 +109,9 @@ int r128_resctx(struct inode *inode, struct file *filp, unsigned int cmd, memset(&ctx, 0, sizeof(ctx)); for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { ctx.handle = i; - if (copy_to_user(&res.contexts[i], &i, sizeof(i))) + if (copy_to_user(&res.contexts[i], + &i, + sizeof(i))) return -EFAULT; } } diff --git a/linux/r128_drm.h b/linux/r128_drm.h index 756e33c3c..68a55d5dc 100644 --- a/linux/r128_drm.h +++ b/linux/r128_drm.h @@ -94,7 +94,7 @@ #define R128_LOCAL_TEX_HEAP 0 #define R128_AGP_TEX_HEAP 1 #define R128_NR_TEX_HEAPS 2 -#define R128_NR_TEX_REGIONS 16 +#define R128_NR_TEX_REGIONS 64 #define R128_LOG_TEX_GRANULARITY 16 #define R128_NR_CONTEXT_REGS 12 @@ -147,11 +147,11 @@ typedef struct { } drm_r128_texture_regs_t; -typedef struct drm_r128_tex_region { +typedef struct drm_tex_region { unsigned char next, prev; unsigned char in_use; int age; -} drm_r128_tex_region_t; +} drm_tex_region_t; typedef struct drm_r128_sarea { /* The channel for communication of state information to the kernel @@ -173,7 +173,7 @@ typedef struct drm_r128_sarea { unsigned int last_frame; unsigned int last_dispatch; - drm_r128_tex_region_t tex_list[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS+1]; + drm_tex_region_t tex_list[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS+1]; int tex_age[R128_NR_TEX_HEAPS]; int ctx_owner; } drm_r128_sarea_t; @@ -196,12 +196,10 @@ typedef struct drm_r128_init { unsigned int fb_bpp; unsigned int front_offset, front_pitch; - unsigned int front_x, front_y; unsigned int back_offset, back_pitch; - unsigned int back_x, back_y; unsigned int depth_bpp; unsigned int depth_offset, depth_pitch; - unsigned int depth_x, depth_y; + unsigned int span_offset; unsigned int fb_offset; unsigned int mmio_offset; @@ -221,8 +219,6 @@ typedef struct drm_r128_clear { 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 { @@ -240,21 +236,33 @@ typedef struct drm_r128_indices { int discard; /* Client finished with buffer? */ } drm_r128_indices_t; -typedef struct drm_r128_blit_rect { - int index; - unsigned short x, y; - unsigned short width, height; - int padding; -} drm_r128_blit_rect_t; - typedef struct drm_r128_blit { + int idx; int pitch; int offset; int format; - drm_r128_blit_rect_t *rects; - int count; + unsigned short x, y; + unsigned short width, height; } drm_r128_blit_t; +typedef struct drm_r128_depth { + enum { + R128_WRITE_SPAN = 0x01, + R128_WRITE_PIXELS = 0x02, + R128_READ_SPAN = 0x03, + R128_READ_PIXELS = 0x04 + } func; + int n; + int *x; + int *y; + unsigned int *buffer; + unsigned char *mask; +} drm_r128_depth_t; + +typedef struct drm_r128_stipple { + unsigned int *mask; +} drm_r128_stipple_t; + typedef struct drm_r128_packet { unsigned int *buffer; int count; diff --git a/linux/r128_drv.c b/linux/r128_drv.c index 66bdf36e1..dbfc9b740 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 "20001106" +#define R128_DATE "20001215" #define R128_MAJOR 2 -#define R128_MINOR 0 -#define R128_PATCHLEVEL 0 +#define R128_MINOR 1 +#define R128_PATCHLEVEL 2 static drm_device_t r128_device; drm_ctx_t r128_res_ctx; @@ -119,6 +119,8 @@ static drm_ioctl_desc_t r128_ioctls[] = { [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 }, }; #define R128_IOCTL_COUNT DRM_ARRAY_SIZE(r128_ioctls) @@ -261,8 +263,7 @@ static int r128_takedown(drm_device_t *dev) } dev->agp->memory = NULL; - if (dev->agp->acquired && drm_agp.release) - (*drm_agp.release)(); + if (dev->agp->acquired) _drm_agp_release(); dev->agp->acquired = 0; dev->agp->enabled = 0; @@ -332,7 +333,7 @@ static int r128_takedown(drm_device_t *dev) /* r128_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ -static int r128_init(void) +static int __init r128_init(void) { int retcode; drm_device_t *dev = &r128_device; @@ -359,12 +360,12 @@ static int r128_init(void) #if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) dev->agp = drm_agp_init(); - if (dev->agp == NULL) { - DRM_ERROR("Cannot initialize agpgart module.\n"); - drm_proc_cleanup(); - misc_deregister(&r128_misc); - r128_takedown(dev); - return -ENOMEM; + if (dev->agp == NULL) { + DRM_ERROR("Cannot initialize agpgart module.\n"); + drm_proc_cleanup(); + misc_deregister(&r128_misc); + r128_takedown(dev); + return -ENOMEM; } #ifdef CONFIG_MTRR @@ -396,7 +397,7 @@ static int r128_init(void) /* r128_cleanup is called via cleanup_module at module unload time. */ -static void r128_cleanup(void) +static void __exit r128_cleanup(void) { drm_device_t *dev = &r128_device; @@ -423,8 +424,8 @@ module_init(r128_init); module_exit(r128_cleanup); -int r128_version(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) +int r128_version(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { drm_version_t version; int len; @@ -516,8 +517,8 @@ int r128_release(struct inode *inode, struct file *filp) } /* r128_ioctl is called whenever a process performs an ioctl on /dev/drm. */ -int r128_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) +int r128_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { int nr = DRM_IOCTL_NR(cmd); drm_file_t *priv = filp->private_data; @@ -543,7 +544,7 @@ int r128_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, DRM_DEBUG("no function\n"); retcode = -EINVAL; } else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN)) - || (ioctl->auth_needed && !priv->authenticated)) { + || (ioctl->auth_needed && !priv->authenticated)) { retcode = -EACCES; } else { retcode = (func)(inode, filp, cmd, arg); @@ -560,8 +561,8 @@ int r128_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, return retcode; } -int r128_lock(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) +int r128_lock(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; @@ -656,8 +657,8 @@ int r128_lock(struct inode *inode, struct file *filp, unsigned int cmd, } -int r128_unlock(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) +int r128_unlock(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; diff --git a/linux/r128_drv.h b/linux/r128_drv.h index 7f044a33d..cffd08002 100644 --- a/linux/r128_drv.h +++ b/linux/r128_drv.h @@ -73,18 +73,18 @@ typedef struct drm_r128_private { unsigned int fb_bpp; unsigned int front_offset; unsigned int front_pitch; - unsigned int front_x; - unsigned int front_y; unsigned int back_offset; unsigned int back_pitch; - unsigned int back_x; - unsigned int back_y; unsigned int depth_bpp; unsigned int depth_offset; unsigned int depth_pitch; - unsigned int depth_x; - unsigned int depth_y; + unsigned int span_offset; + + u32 front_pitch_offset_c; + u32 back_pitch_offset_c; + u32 depth_pitch_offset_c; + u32 span_pitch_offset_c; drm_map_t *sarea; drm_map_t *fb; @@ -150,6 +150,10 @@ extern int r128_cce_indices( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); extern int r128_cce_blit( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); +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 ); /* r128_bufs.c */ extern int r128_addbufs(struct inode *inode, struct file *filp, @@ -204,6 +208,7 @@ extern int r128_context_switch_complete(drm_device_t *dev, int new); #define R128_AUX3_SC_TOP 0x168c #define R128_AUX3_SC_BOTTOM 0x1690 +#define R128_BRUSH_DATA0 0x1480 #define R128_BUS_CNTL 0x0030 # define R128_BUS_MASTER_DIS (1 << 6) @@ -232,6 +237,7 @@ extern int r128_context_switch_complete(drm_device_t *dev, int new); # define R128_ROP3_P 0x00f00000 #define R128_DP_WRITE_MASK 0x16cc #define R128_DST_PITCH_OFFSET_C 0x1c80 +# define R128_DST_TILE (1 << 31) #define R128_GEN_RESET_CNTL 0x00f0 # define R128_SOFT_RESET_GUI (1 << 0) @@ -379,7 +385,7 @@ extern int r128_context_switch_complete(drm_device_t *dev, int new); #define R128_MAX_VB_VERTS (0xffff) -#define R128_BASE(reg) ((unsigned long)(dev_priv->mmio->handle)) +#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) @@ -420,7 +426,7 @@ extern int R128_READ_PLL(drm_device_t *dev, int addr); #define R128_VERBOSE 0 -#define RING_LOCALS int write; unsigned int mask; volatile u32 *ring; +#define RING_LOCALS int write; unsigned int tail_mask; volatile u32 *ring; #define BEGIN_RING( n ) do { \ if ( R128_VERBOSE ) { \ @@ -433,7 +439,7 @@ extern int R128_READ_PLL(drm_device_t *dev, int addr); dev_priv->ring.space -= n * sizeof(u32); \ ring = dev_priv->ring.start; \ write = dev_priv->ring.tail; \ - mask = dev_priv->ring.tail_mask; \ + tail_mask = dev_priv->ring.tail_mask; \ } while (0) #define ADVANCE_RING() do { \ @@ -452,7 +458,7 @@ extern int R128_READ_PLL(drm_device_t *dev, int addr); (unsigned int)(x), write ); \ } \ ring[write++] = x; \ - write &= mask; \ + write &= tail_mask; \ } while (0) #define R128_PERFORMANCE_BOXES 0 diff --git a/linux/r128_state.c b/linux/r128_state.c index 582280409..3f52c14b3 100644 --- a/linux/r128_state.c +++ b/linux/r128_state.c @@ -33,10 +33,6 @@ #include "r128_drv.h" #include "drm.h" -#define USE_OLD_BLITS 1 - -static drm_r128_blit_rect_t rects[R128_MAX_BLIT_BUFFERS]; - /* ================================================================ * CCE hardware state programming functions @@ -45,7 +41,7 @@ static drm_r128_blit_rect_t rects[R128_MAX_BLIT_BUFFERS]; static void r128_emit_clip_rects( drm_r128_private_t *dev_priv, drm_clip_rect_t *boxes, int count ) { - unsigned int aux_sc_cntl = 0x00000000; + u32 aux_sc_cntl = 0x00000000; RING_LOCALS; DRM_DEBUG( " %s\n", __FUNCTION__ ); @@ -272,9 +268,7 @@ static inline void r128_emit_state( drm_r128_private_t *dev_priv ) /* Turn off the texture cache flushing */ sarea_priv->context_state.tex_cntl_c &= ~R128_TEX_CACHE_FLUSH; - sarea_priv->dirty &= ~(R128_UPLOAD_TEX0IMAGES | - R128_UPLOAD_TEX1IMAGES | - R128_REQUIRE_QUIESCENCE); + sarea_priv->dirty &= ~R128_REQUIRE_QUIESCENCE; } @@ -303,10 +297,11 @@ static void r128_clear_box( drm_r128_private_t *dev_priv, color = ((r << 16) | (g << 8) | b); break; case 32: - default: fb_bpp = R128_GMC_DST_32BPP; color = (((0xff) << 24) | (r << 16) | (g << 8) | b); break; + default: + return; } offset = dev_priv->back_offset; @@ -350,27 +345,25 @@ static void r128_cce_performance_boxes( drm_r128_private_t *dev_priv ) static void r128_print_dirty( const char *msg, unsigned int flags ) { - DRM_DEBUG( "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n", - msg, - flags, - (flags & R128_UPLOAD_CORE) ? "core, " : "", - (flags & R128_UPLOAD_CONTEXT) ? "context, " : "", - (flags & R128_UPLOAD_SETUP) ? "setup, " : "", - (flags & R128_UPLOAD_TEX0) ? "tex0, " : "", - (flags & R128_UPLOAD_TEX1) ? "tex1, " : "", - (flags & R128_UPLOAD_MASKS) ? "masks, " : "", - (flags & R128_UPLOAD_WINDOW) ? "window, " : "", - (flags & R128_UPLOAD_CLIPRECTS) ? "cliprects, " : "", - (flags & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : "" ); + DRM_INFO( "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n", + msg, + flags, + (flags & R128_UPLOAD_CORE) ? "core, " : "", + (flags & R128_UPLOAD_CONTEXT) ? "context, " : "", + (flags & R128_UPLOAD_SETUP) ? "setup, " : "", + (flags & R128_UPLOAD_TEX0) ? "tex0, " : "", + (flags & R128_UPLOAD_TEX1) ? "tex1, " : "", + (flags & R128_UPLOAD_MASKS) ? "masks, " : "", + (flags & R128_UPLOAD_WINDOW) ? "window, " : "", + (flags & R128_UPLOAD_CLIPRECTS) ? "cliprects, " : "", + (flags & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : "" ); } 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, - unsigned int color_mask, - unsigned int depth_mask ) + unsigned int clear_depth ) { drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -387,21 +380,17 @@ static void r128_cce_dispatch_clear( drm_device_t *dev, case 16: fb_bpp = R128_GMC_DST_16BPP; break; - case 24: - fb_bpp = R128_GMC_DST_24BPP; - break; case 32: - default: 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: - depth_bpp = R128_GMC_DST_32BPP; - break; case 32: depth_bpp = R128_GMC_DST_32BPP; break; @@ -423,81 +412,11 @@ static void r128_cce_dispatch_clear( drm_device_t *dev, BEGIN_RING( 2 ); OUT_RING( CCE_PACKET0( R128_DP_WRITE_MASK, 0 ) ); - OUT_RING( color_mask ); + OUT_RING( sarea_priv->context_state.plane_3d_mask_c ); ADVANCE_RING(); } -#if USE_OLD_BLITS - if ( flags & R128_FRONT ) { - int fx = x + dev_priv->front_x; - int fy = y + dev_priv->front_y; - - DRM_DEBUG( "clear front: x=%d y=%d\n", - dev_priv->front_x, dev_priv->front_y ); - BEGIN_RING( 5 ); - - OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 3 ) ); - OUT_RING( 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( clear_color ); - OUT_RING( (fx << 16) | fy ); - OUT_RING( (w << 16) | h ); - - ADVANCE_RING(); - } - - if ( flags & R128_BACK ) { - int bx = x + dev_priv->back_x; - int by = y + dev_priv->back_y; - - DRM_DEBUG( "clear back: x=%d y=%d\n", - dev_priv->back_x, dev_priv->back_y ); - BEGIN_RING( 5 ); - - OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 3 ) ); - OUT_RING( 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( clear_color ); - OUT_RING( (bx << 16) | by ); - OUT_RING( (w << 16) | h ); - - ADVANCE_RING(); - } - - if ( flags & R128_DEPTH ) { - int dx = x + dev_priv->depth_x; - int dy = y + dev_priv->depth_y; - - DRM_DEBUG( "clear depth: x=%d y=%d\n", - dev_priv->depth_x, dev_priv->depth_y ); - BEGIN_RING( 7 ); - - OUT_RING( CCE_PACKET0( R128_DP_WRITE_MASK, 0 ) ); - OUT_RING( depth_mask ); - - OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 3 ) ); - OUT_RING( 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 ); - OUT_RING( clear_depth ); - OUT_RING( (dx << 16) | dy ); - OUT_RING( (w << 16) | h ); - - ADVANCE_RING(); - } -#else if ( flags & R128_FRONT ) { BEGIN_RING( 6 ); @@ -510,8 +429,7 @@ static void r128_cce_dispatch_clear( drm_device_t *dev, | R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_AUX_CLIP_DIS ); - OUT_RING( ((dev_priv->front_pitch/8) << 21) | - (dev_priv->front_offset >> 5) ); + OUT_RING( dev_priv->front_pitch_offset_c ); OUT_RING( clear_color ); OUT_RING( (x << 16) | y ); @@ -532,8 +450,7 @@ static void r128_cce_dispatch_clear( drm_device_t *dev, | R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_AUX_CLIP_DIS ); - OUT_RING( ((dev_priv->back_pitch/8) << 21) | - (dev_priv->back_offset >> 5) ); + OUT_RING( dev_priv->back_pitch_offset_c ); OUT_RING( clear_color ); OUT_RING( (x << 16) | y ); @@ -543,10 +460,7 @@ static void r128_cce_dispatch_clear( drm_device_t *dev, } if ( flags & R128_DEPTH ) { - BEGIN_RING( 8 ); - - OUT_RING( CCE_PACKET0( R128_DP_WRITE_MASK, 0 ) ); - OUT_RING( depth_mask ); + BEGIN_RING( 6 ); OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL @@ -555,10 +469,10 @@ static void r128_cce_dispatch_clear( drm_device_t *dev, | R128_GMC_SRC_DATATYPE_COLOR | R128_ROP3_P | R128_GMC_CLR_CMP_CNTL_DIS - | R128_GMC_AUX_CLIP_DIS ); + | R128_GMC_AUX_CLIP_DIS + | R128_GMC_WR_MSK_DIS ); - OUT_RING( ((dev_priv->depth_pitch/8) << 21) | - (dev_priv->depth_offset >> 5) ); + OUT_RING( dev_priv->depth_pitch_offset_c ); OUT_RING( clear_depth ); OUT_RING( (x << 16) | y ); @@ -566,7 +480,6 @@ static void r128_cce_dispatch_clear( drm_device_t *dev, ADVANCE_RING(); } -#endif } } @@ -593,9 +506,6 @@ static void r128_cce_dispatch_swap( drm_device_t *dev ) case 16: fb_bpp = R128_GMC_DST_16BPP; break; - case 24: - fb_bpp = R128_GMC_DST_24BPP; - break; case 32: default: fb_bpp = R128_GMC_DST_32BPP; @@ -603,60 +513,33 @@ static void r128_cce_dispatch_swap( drm_device_t *dev ) } for ( i = 0 ; i < nbox ; i++ ) { - int fx = pbox[i].x1; - int fy = pbox[i].y1; - int fw = pbox[i].x2 - fx; - int fh = pbox[i].y2 - fy; -#if USE_OLD_BLITS - int bx = fx + dev_priv->back_x; - int by = fy + dev_priv->back_y; - - fx += dev_priv->front_x; - fy += dev_priv->front_x; - - BEGIN_RING( 5 ); - - OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 3 ) ); - OUT_RING( R128_GMC_BRUSH_NONE - | R128_GMC_SRC_DATATYPE_COLOR - | R128_DP_SRC_SOURCE_MEMORY - | fb_bpp - | R128_ROP3_S - | R128_GMC_CLR_CMP_CNTL_DIS - | R128_GMC_AUX_CLIP_DIS - | R128_GMC_WR_MSK_DIS ); - - OUT_RING( (bx << 16) | by ); - OUT_RING( (fx << 16) | fy ); - OUT_RING( (fw << 16) | fh ); + int x = pbox[i].x1; + int y = pbox[i].y1; + int w = pbox[i].x2 - x; + int h = pbox[i].y2 - y; - ADVANCE_RING(); -#else 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 - | R128_GMC_SRC_DATATYPE_COLOR - | R128_DP_SRC_SOURCE_MEMORY | 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/8) << 21) | - (dev_priv->back_offset >> 5) ); - OUT_RING( ((dev_priv->front_pitch/8) << 21) | - (dev_priv->front_offset >> 5) ); + OUT_RING( dev_priv->back_pitch_offset_c ); + OUT_RING( dev_priv->front_pitch_offset_c ); - OUT_RING( (fx << 16) | fy ); - OUT_RING( (fx << 16) | fy ); - OUT_RING( (fw << 16) | fh ); + OUT_RING( (x << 16) | y ); + OUT_RING( (x << 16) | y ); + OUT_RING( (w << 16) | h ); ADVANCE_RING(); -#endif } /* Increment the frame counter. The client-side 3D driver must @@ -679,21 +562,14 @@ static void r128_cce_dispatch_vertex( drm_device_t *dev, drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_buf_priv_t *buf_priv = buf->dev_private; drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - int vertsize = sarea_priv->vertsize; int format = sarea_priv->vc_format; - int index = buf->idx; int offset = dev_priv->buffers->offset + buf->offset - dev->agp->base; int size = buf->used; int prim = buf_priv->prim; int i = 0; RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); - - DRM_DEBUG( "vertex buffer index = %d\n", index ); - DRM_DEBUG( "vertex buffer offset = 0x%x\n", offset ); - DRM_DEBUG( "vertex buffer size = %d vertices\n", size ); - DRM_DEBUG( "vertex size = %d\n", vertsize ); - DRM_DEBUG( "vertex format = 0x%x\n", format ); + DRM_DEBUG( "%s: buf=%d nbox=%d\n", + __FUNCTION__, buf->idx, sarea_priv->nbox ); r128_update_ring_snapshot( dev_priv ); @@ -743,7 +619,7 @@ static void r128_cce_dispatch_vertex( drm_device_t *dev, ADVANCE_RING(); buf->pending = 1; - + buf->used = 0; /* FIXME: Check dispatched field */ buf_priv->dispatched = 0; } @@ -794,21 +670,6 @@ static void r128_cce_dispatch_indirect( drm_device_t *dev, data[dwords++] = R128_CCE_PACKET2; } - DRM_DEBUG( "indirect: offset=0x%x dwords=%d\n", - offset, dwords ); - - if ( 0 ) { - u32 *data = (u32 *) - ((char *)dev_priv->buffers->handle - + buf->offset + start); - int i; - DRM_INFO( "data = %p\n", data ); - for ( i = 0 ; i < dwords ; i++ ) { - DRM_INFO( "data[0x%x] = 0x%08x\n", - i, data[i] ); - } - } - buf_priv->dispatched = 1; /* Fire off the indirect buffer */ @@ -833,6 +694,7 @@ static void r128_cce_dispatch_indirect( drm_device_t *dev, ADVANCE_RING(); buf->pending = 1; + buf->used = 0; /* FIXME: Check dispatched field */ buf_priv->dispatched = 0; } @@ -851,24 +713,20 @@ static void r128_cce_dispatch_indirect( drm_device_t *dev, static void r128_cce_dispatch_indices( drm_device_t *dev, drm_buf_t *buf, - int start, int end ) + int start, int end, + int count ) { drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_buf_priv_t *buf_priv = buf->dev_private; drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - - int vertsize = sarea_priv->vertsize; int format = sarea_priv->vc_format; - int index = buf->idx; int offset = dev_priv->buffers->offset - dev->agp->base; int prim = buf_priv->prim; - u32 *data; - int dwords; int i = 0; RING_LOCALS; - DRM_DEBUG( "%s: start=%d end=%d\n", __FUNCTION__, start, end ); + DRM_DEBUG( "indices: s=%d e=%d c=%d\n", start, end, count ); r128_update_ring_snapshot( dev_priv ); @@ -882,9 +740,6 @@ static void r128_cce_dispatch_indices( drm_device_t *dev, r128_emit_state( dev_priv ); } - /* Adjust start offset to include packet header - */ - start -= R128_INDEX_PRIM_OFFSET; dwords = (end - start + 3) / sizeof(u32); data = (u32 *)((char *)dev_priv->buffers->handle @@ -896,21 +751,12 @@ static void r128_cce_dispatch_indices( drm_device_t *dev, data[2] = R128_MAX_VB_VERTS; data[3] = format; data[4] = (prim | R128_CCE_VC_CNTL_PRIM_WALK_IND | - (R128_MAX_VB_VERTS << 16)); + (count << 16)); - if ( (end - start) & 0x3 ) { + if ( count & 0x1 ) { data[dwords-1] &= 0x0000ffff; } - if ( 0 ) { - int i; - DRM_INFO( "data = %p\n", data ); - for ( i = 0 ; i < dwords ; i++ ) { - DRM_INFO( "data[0x%x] = 0x%08x\n", - i, data[i] ); - } - } - do { /* Emit the next set of up to three cliprects */ if ( i < sarea_priv->nbox ) { @@ -957,17 +803,14 @@ static void r128_cce_dispatch_indices( drm_device_t *dev, } static int r128_cce_dispatch_blit( drm_device_t *dev, - int offset, int pitch, int format, - drm_r128_blit_rect_t *rects, int count ) + drm_r128_blit_t *blit ) { drm_r128_private_t *dev_priv = dev->dev_private; drm_device_dma_t *dma = dev->dma; drm_buf_t *buf; drm_r128_buf_priv_t *buf_priv; - drm_r128_blit_rect_t *rect; u32 *data; int dword_shift, dwords; - int i; RING_LOCALS; DRM_DEBUG( "%s\n", __FUNCTION__ ); @@ -977,7 +820,7 @@ static int r128_cce_dispatch_blit( drm_device_t *dev, * even if the only legal values are powers of two. Thus, we'll * use a shift instead. */ - switch ( format ) { + switch ( blit->format ) { case R128_DATATYPE_ARGB1555: case R128_DATATYPE_RGB565: case R128_DATATYPE_ARGB4444: @@ -987,7 +830,7 @@ static int r128_cce_dispatch_blit( drm_device_t *dev, dword_shift = 0; break; default: - DRM_ERROR( "invalid blit format %d\n", format ); + DRM_ERROR( "invalid blit format %d\n", blit->format ); return -EINVAL; } @@ -1003,53 +846,48 @@ static int r128_cce_dispatch_blit( drm_device_t *dev, ADVANCE_RING(); - /* Dispatch each of the indirect buffers. + /* Dispatch the indirect buffer. */ - for ( i = 0 ; i < count ; i++ ) { - rect = &rects[i]; - buf = dma->buflist[rect->index]; - 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", - rect->index ); - return -EINVAL; - } + buf = dma->buflist[blit->idx]; + buf_priv = buf->dev_private; - buf_priv->discard = 1; + 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", blit->idx ); + return -EINVAL; + } - dwords = (rect->width * rect->height) >> dword_shift; + buf_priv->discard = 1; - data = (u32 *)((char *)dev_priv->buffers->handle - + buf->offset); + dwords = (blit->width * blit->height) >> dword_shift; - data[0] = CCE_PACKET3( R128_CNTL_HOSTDATA_BLT, dwords + 6 ); - data[1] = ( R128_GMC_DST_PITCH_OFFSET_CNTL - | R128_GMC_BRUSH_NONE - | (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 = (u32 *)((char *)dev_priv->buffers->handle + buf->offset); - data[2] = (pitch << 21) | (offset >> 5); - data[3] = 0xffffffff; - data[4] = 0xffffffff; - data[5] = (rect->y << 16) | rect->x; - data[6] = (rect->height << 16) | rect->width; - data[7] = dwords; + 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 ); - buf->used = (dwords + 8) * sizeof(u32); + data[2] = (blit->pitch << 21) | (blit->offset >> 5); + data[3] = 0xffffffff; + data[4] = 0xffffffff; + data[5] = (blit->y << 16) | blit->x; + data[6] = (blit->height << 16) | blit->width; + data[7] = dwords; - r128_cce_dispatch_indirect( dev, buf, 0, buf->used ); - } + buf->used = (dwords + 8) * sizeof(u32); + + r128_cce_dispatch_indirect( dev, buf, 0, buf->used ); /* Flush the pixel cache after the blit completes. This ensures * the texture data is written out to memory before rendering @@ -1067,7 +905,417 @@ static int r128_cce_dispatch_blit( drm_device_t *dev, /* ================================================================ + * Tiled depth buffer management * + * FIXME: These should all set the destination write mask for when we + * have hardware stencil support. + */ + +static int r128_cce_dispatch_write_span( drm_device_t *dev, + drm_r128_depth_t *depth ) +{ + drm_r128_private_t *dev_priv = dev->dev_private; + 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; + } + if ( copy_from_user( &y, depth->y, sizeof(y) ) ) { + return -EFAULT; + } + + buffer = kmalloc( depth->n * sizeof(u32), 0 ); + if ( buffer == NULL ) + return -ENOMEM; + if ( copy_from_user( buffer, depth->buffer, + depth->n * sizeof(u32) ) ) { + kfree( buffer ); + return -EFAULT; + } + + if ( depth->mask ) { + mask = kmalloc( depth->n * sizeof(u8), 0 ); + if ( mask == NULL ) { + kfree( buffer ); + return -ENOMEM; + } + if ( copy_from_user( mask, depth->mask, + depth->n * sizeof(u8) ) ) { + kfree( buffer ); + kfree( mask ); + return -EFAULT; + } + + for ( i = 0 ; i < count ; i++, x++ ) { + 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( dev_priv->depth_pitch_offset_c ); + OUT_RING( buffer[i] ); + + OUT_RING( (x << 16) | y ); + OUT_RING( (1 << 16) | 1 ); + + ADVANCE_RING(); + } + } + + kfree( mask ); + } else { + for ( i = 0 ; i < count ; i++, x++ ) { + 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( dev_priv->depth_pitch_offset_c ); + OUT_RING( buffer[i] ); + + OUT_RING( (x << 16) | y ); + OUT_RING( (1 << 16) | 1 ); + + ADVANCE_RING(); + } + } + + kfree( buffer ); + + return 0; +} + +static int r128_cce_dispatch_write_pixels( drm_device_t *dev, + drm_r128_depth_t *depth ) +{ + drm_r128_private_t *dev_priv = dev->dev_private; + 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 ); + if ( x == NULL ) { + return -ENOMEM; + } + y = kmalloc( count * sizeof(*y), 0 ); + if ( y == NULL ) { + kfree( x ); + return -ENOMEM; + } + if ( copy_from_user( x, depth->x, count * sizeof(int) ) ) { + kfree( x ); + kfree( y ); + return -EFAULT; + } + if ( copy_from_user( y, depth->y, count * sizeof(int) ) ) { + kfree( x ); + kfree( y ); + return -EFAULT; + } + + buffer = kmalloc( depth->n * sizeof(u32), 0 ); + if ( buffer == NULL ) { + kfree( x ); + kfree( y ); + return -ENOMEM; + } + if ( copy_from_user( buffer, depth->buffer, + depth->n * sizeof(u32) ) ) { + kfree( x ); + kfree( y ); + kfree( buffer ); + return -EFAULT; + } + + if ( depth->mask ) { + mask = kmalloc( depth->n * sizeof(u8), 0 ); + if ( mask == NULL ) { + kfree( x ); + kfree( y ); + kfree( buffer ); + return -ENOMEM; + } + if ( copy_from_user( mask, depth->mask, + depth->n * sizeof(u8) ) ) { + kfree( x ); + kfree( y ); + kfree( buffer ); + kfree( mask ); + return -EFAULT; + } + + for ( i = 0 ; i < count ; i++ ) { + 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( dev_priv->depth_pitch_offset_c ); + OUT_RING( buffer[i] ); + + OUT_RING( (x[i] << 16) | y[i] ); + OUT_RING( (1 << 16) | 1 ); + + ADVANCE_RING(); + } + } + + kfree( mask ); + } else { + for ( i = 0 ; i < count ; 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( dev_priv->depth_pitch_offset_c ); + OUT_RING( buffer[i] ); + + OUT_RING( (x[i] << 16) | y[i] ); + OUT_RING( (1 << 16) | 1 ); + + ADVANCE_RING(); + } + } + + kfree( x ); + kfree( y ); + kfree( buffer ); + + return 0; +} + +static int r128_cce_dispatch_read_span( drm_device_t *dev, + drm_r128_depth_t *depth ) +{ + 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; + } + if ( copy_from_user( &y, depth->y, sizeof(y) ) ) { + return -EFAULT; + } + + 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( dev_priv->depth_pitch_offset_c ); + OUT_RING( dev_priv->span_pitch_offset_c ); + + OUT_RING( (x << 16) | y ); + OUT_RING( (0 << 16) | 0 ); + OUT_RING( (count << 16) | 1 ); + + ADVANCE_RING(); + + return 0; +} + +static int r128_cce_dispatch_read_pixels( drm_device_t *dev, + drm_r128_depth_t *depth ) +{ + 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; + } + + x = kmalloc( count * sizeof(*x), 0 ); + if ( x == NULL ) { + return -ENOMEM; + } + y = kmalloc( count * sizeof(*y), 0 ); + if ( y == NULL ) { + kfree( x ); + return -ENOMEM; + } + if ( copy_from_user( x, depth->x, count * sizeof(int) ) ) { + kfree( x ); + kfree( y ); + return -EFAULT; + } + if ( copy_from_user( y, depth->y, count * sizeof(int) ) ) { + kfree( x ); + kfree( y ); + return -EFAULT; + } + + for ( i = 0 ; i < count ; i++ ) { + 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( dev_priv->depth_pitch_offset_c ); + OUT_RING( dev_priv->span_pitch_offset_c ); + + OUT_RING( (x[i] << 16) | y[i] ); + OUT_RING( (i << 16) | 0 ); + OUT_RING( (1 << 16) | 1 ); + + ADVANCE_RING(); + } + + kfree( x ); + kfree( y ); + + return 0; +} + + +/* ================================================================ + * Polygon stipple + */ + +static void r128_cce_dispatch_stipple( drm_device_t *dev, u32 *stipple ) +{ + drm_r128_private_t *dev_priv = dev->dev_private; + int i; + RING_LOCALS; + DRM_DEBUG( "%s\n", __FUNCTION__ ); + + r128_update_ring_snapshot( dev_priv ); + + BEGIN_RING( 33 ); + + OUT_RING( CCE_PACKET0( R128_BRUSH_DATA0, 31 ) ); + for ( i = 0 ; i < 32 ; i++ ) { + OUT_RING( stipple[i] ); + } + + ADVANCE_RING(); +} + + +/* ================================================================ + * IOCTL functions */ int r128_cce_clear( struct inode *inode, struct file *filp, @@ -1095,8 +1343,7 @@ int r128_cce_clear( struct inode *inode, struct file *filp, r128_cce_dispatch_clear( dev, clear.flags, clear.x, clear.y, clear.w, clear.h, - clear.clear_color, clear.clear_depth, - clear.color_mask, clear.depth_mask ); + clear.clear_color, clear.clear_depth ); /* Make sure we restore the 3D state next time. */ @@ -1204,6 +1451,7 @@ int r128_cce_indices( struct inode *inode, struct file *filp, drm_buf_t *buf; drm_r128_buf_priv_t *buf_priv; drm_r128_indices_t elts; + int count; if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || dev->lock.pid != current->pid ) { @@ -1219,7 +1467,7 @@ int r128_cce_indices( struct inode *inode, struct file *filp, sizeof(elts) ) ) return -EFAULT; - DRM_DEBUG( "%s: pid=%d index=%d start=%d end=%d discard=%d\n", + DRM_DEBUG( "%s: pid=%d buf=%d s=%d e=%d d=%d\n", __FUNCTION__, current->pid, elts.idx, elts.start, elts.end, elts.discard ); @@ -1246,15 +1494,24 @@ int r128_cce_indices( struct inode *inode, struct file *filp, DRM_ERROR( "sending pending buffer %d\n", elts.idx ); return -EINVAL; } - if ( (buf->offset + elts.start) & 0x3 ) { - DRM_ERROR( "buffer start 0x%x\n", buf->offset + elts.start ); + + count = (elts.end - elts.start) / sizeof(u16); + elts.start -= R128_INDEX_PRIM_OFFSET; + + if ( elts.start & 0x7 ) { + DRM_ERROR( "misaligned buffer 0x%x\n", elts.start ); + return -EINVAL; + } + if ( elts.start < buf->used ) { + DRM_ERROR( "no header 0x%x - 0x%x\n", elts.start, buf->used ); return -EINVAL; } + buf->used = elts.end; buf_priv->prim = elts.prim; buf_priv->discard = elts.discard; - r128_cce_dispatch_indices( dev, buf, elts.start, elts.end ); + r128_cce_dispatch_indices( dev, buf, elts.start, elts.end, count ); return 0; } @@ -1277,19 +1534,72 @@ int r128_cce_blit( struct inode *inode, struct file *filp, sizeof(blit) ) ) return -EFAULT; - DRM_DEBUG( "%s: pid=%d count=%d\n", - __FUNCTION__, current->pid, blit.count ); + DRM_DEBUG( "%s: pid=%d index=%d\n", + __FUNCTION__, current->pid, blit.idx ); + + if ( blit.idx < 0 || blit.idx >= dma->buf_count ) { + DRM_ERROR( "buffer index %d (of %d max)\n", + blit.idx, dma->buf_count - 1 ); + return -EINVAL; + } + + return r128_cce_dispatch_blit( dev, &blit ); +} + +int r128_cce_depth( 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_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; + } + + if ( copy_from_user( &depth, (drm_r128_depth_t *)arg, + sizeof(depth) ) ) + return -EFAULT; + + switch ( depth.func ) { + case R128_WRITE_SPAN: + return r128_cce_dispatch_write_span( dev, &depth ); + case R128_WRITE_PIXELS: + return r128_cce_dispatch_write_pixels( dev, &depth ); + case R128_READ_SPAN: + return r128_cce_dispatch_read_span( dev, &depth ); + case R128_READ_PIXELS: + return r128_cce_dispatch_read_pixels( dev, &depth ); + } + + return -EINVAL; +} + +int r128_cce_stipple( 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_stipple_t stipple; + u32 mask[32]; - if ( blit.count < 0 || blit.count > dma->buf_count ) { - DRM_ERROR( "sending %d buffers (of %d max)\n", - blit.count, dma->buf_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; } - if ( copy_from_user( &rects, blit.rects, - blit.count * sizeof(drm_r128_blit_rect_t) ) ) + if ( copy_from_user( &stipple, (drm_r128_stipple_t *)arg, + sizeof(stipple) ) ) + return -EFAULT; + + if ( copy_from_user( &mask, stipple.mask, + 32 * sizeof(u32) ) ) return -EFAULT; - return r128_cce_dispatch_blit( dev, blit.offset, blit.pitch, - blit.format, rects, blit.count ); + r128_cce_dispatch_stipple( dev, mask ); + + return 0; } diff --git a/linux/radeon_drv.c b/linux/radeon_drv.c index 9cbb1264f..35539766d 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 "20001108" +#define RADEON_DATE "20001223" #define RADEON_MAJOR 1 #define RADEON_MINOR 0 #define RADEON_PATCHLEVEL 0 @@ -258,8 +258,7 @@ static int radeon_takedown(drm_device_t *dev) } dev->agp->memory = NULL; - if (dev->agp->acquired && drm_agp.release) - (*drm_agp.release)(); + if (dev->agp->acquired) _drm_agp_release(); dev->agp->acquired = 0; dev->agp->enabled = 0; diff --git a/linux/sis_context.c b/linux/sis_context.c index f2fdf6dd3..accd789ae 100644 --- a/linux/sis_context.c +++ b/linux/sis_context.c @@ -106,19 +106,19 @@ int sis_resctx(struct inode *inode, struct file *filp, unsigned int cmd, int i; DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS); - copy_from_user_ret(&res, (drm_ctx_res_t *)arg, sizeof(res), -EFAULT); + if (copy_from_user(&res, (drm_ctx_res_t *)arg, sizeof(res))) + return -EFAULT; if (res.count >= DRM_RESERVED_CONTEXTS) { memset(&ctx, 0, sizeof(ctx)); for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { ctx.handle = i; - copy_to_user_ret(&res.contexts[i], - &i, - sizeof(i), - -EFAULT); + if (copy_to_user(&res.contexts[i], &i, sizeof(i))) + return -EFAULT; } } res.count = DRM_RESERVED_CONTEXTS; - copy_to_user_ret((drm_ctx_res_t *)arg, &res, sizeof(res), -EFAULT); + if (copy_to_user((drm_ctx_res_t *)arg, &res, sizeof(res))) + return -EFAULT; return 0; } @@ -130,7 +130,8 @@ int sis_addctx(struct inode *inode, struct file *filp, unsigned int cmd, drm_device_t *dev = priv->dev; drm_ctx_t ctx; - copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT); + if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) + return -EFAULT; if ((ctx.handle = sis_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) { /* Skip kernel's context and get a new one. */ ctx.handle = sis_alloc_queue(dev); @@ -145,7 +146,8 @@ int sis_addctx(struct inode *inode, struct file *filp, unsigned int cmd, /* new added */ sis_init_context(ctx.handle); - copy_to_user_ret((drm_ctx_t *)arg, &ctx, sizeof(ctx), -EFAULT); + if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx))) + return -EFAULT; return 0; } @@ -154,7 +156,8 @@ int sis_modctx(struct inode *inode, struct file *filp, unsigned int cmd, { drm_ctx_t ctx; - copy_from_user_ret(&ctx, (drm_ctx_t*)arg, sizeof(ctx), -EFAULT); + if (copy_from_user(&ctx, (drm_ctx_t*)arg, sizeof(ctx))) + return -EFAULT; if (ctx.flags==_DRM_CONTEXT_PRESERVED) sis_res_ctx.handle=ctx.handle; return 0; @@ -165,10 +168,12 @@ int sis_getctx(struct inode *inode, struct file *filp, unsigned int cmd, { drm_ctx_t ctx; - copy_from_user_ret(&ctx, (drm_ctx_t*)arg, sizeof(ctx), -EFAULT); + if (copy_from_user(&ctx, (drm_ctx_t*)arg, sizeof(ctx))) + return -EFAULT; /* This is 0, because we don't hanlde any context flags */ ctx.flags = 0; - copy_to_user_ret((drm_ctx_t*)arg, &ctx, sizeof(ctx), -EFAULT); + if (copy_to_user((drm_ctx_t*)arg, &ctx, sizeof(ctx))) + return -EFAULT; return 0; } @@ -179,7 +184,8 @@ int sis_switchctx(struct inode *inode, struct file *filp, unsigned int cmd, drm_device_t *dev = priv->dev; drm_ctx_t ctx; - copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT); + if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) + return -EFAULT; DRM_DEBUG("%d\n", ctx.handle); return sis_context_switch(dev, dev->last_context, ctx.handle); } @@ -191,7 +197,8 @@ int sis_newctx(struct inode *inode, struct file *filp, unsigned int cmd, drm_device_t *dev = priv->dev; drm_ctx_t ctx; - copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT); + if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) + return -EFAULT; DRM_DEBUG("%d\n", ctx.handle); sis_context_switch_complete(dev, ctx.handle); @@ -205,7 +212,8 @@ int sis_rmctx(struct inode *inode, struct file *filp, unsigned int cmd, drm_device_t *dev = priv->dev; drm_ctx_t ctx; - copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT); + if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) + return -EFAULT; DRM_DEBUG("%d\n", ctx.handle); drm_ctxbitmap_free(dev, ctx.handle); diff --git a/linux/sis_drv.c b/linux/sis_drv.c index 2f98e3221..92ec32ddd 100644 --- a/linux/sis_drv.c +++ b/linux/sis_drv.c @@ -250,7 +250,7 @@ static int sis_takedown(drm_device_t *dev) drm_free(temp, sizeof(*temp), DRM_MEM_AGPLISTS); temp = temp_next; } - if (dev->agp->acquired) (*drm_agp.release)(); + if (dev->agp->acquired) _drm_agp_release(); } #endif /* Clear vma list (only built for debugging) */ @@ -394,17 +394,16 @@ int sis_version(struct inode *inode, struct file *filp, unsigned int cmd, drm_version_t version; int len; - copy_from_user_ret(&version, - (drm_version_t *)arg, - sizeof(version), - -EFAULT); + if (copy_from_user(&version, (drm_version_t *)arg, sizeof(version))) + return -EFAULT; #define DRM_COPY(name,value) \ len = strlen(value); \ if (len > name##_len) len = name##_len; \ name##_len = strlen(value); \ if (len && name) { \ - copy_to_user_ret(name, value, len, -EFAULT); \ + if (copy_to_user(name, value, len)) \ + return -EFAULT; \ } version.version_major = SIS_MAJOR; @@ -415,10 +414,8 @@ int sis_version(struct inode *inode, struct file *filp, unsigned int cmd, DRM_COPY(version.date, SIS_DATE); DRM_COPY(version.desc, SIS_DESC); - copy_to_user_ret((drm_version_t *)arg, - &version, - sizeof(version), - -EFAULT); + if (copy_to_user((drm_version_t *)arg, &version, sizeof(version))) + return -EFAULT; return 0; } @@ -533,7 +530,8 @@ int sis_lock(struct inode *inode, struct file *filp, unsigned int cmd, dev->lck_start = start = get_cycles(); #endif - copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT); + if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock))) + return -EFAULT; if (lock.context == DRM_KERNEL_CONTEXT) { DRM_ERROR("Process %d using kernel context %d\n", @@ -667,7 +665,8 @@ int sis_unlock(struct inode *inode, struct file *filp, unsigned int cmd, drm_device_t *dev = priv->dev; drm_lock_t lock; - copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT); + if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock))) + return -EFAULT; if (lock.context == DRM_KERNEL_CONTEXT) { DRM_ERROR("Process %d using kernel context %d\n", diff --git a/linux/sis_mm.c b/linux/sis_mm.c index 9a8f83ea9..4c2b5a6c6 100644 --- a/linux/sis_mm.c +++ b/linux/sis_mm.c @@ -78,7 +78,8 @@ int sis_fb_alloc(struct inode *inode, struct file *filp, unsigned int cmd, struct sis_memreq req; int retval = 0; - copy_from_user_ret(&fb, (drm_sis_mem_t *)arg, sizeof(fb), -EFAULT); + if (copy_from_user(&fb, (drm_sis_mem_t *)arg, sizeof(fb))) + return -EFAULT; req.size = fb.size; sis_malloc(&req); @@ -98,7 +99,7 @@ int sis_fb_alloc(struct inode *inode, struct file *filp, unsigned int cmd, fb.free = 0; } - copy_to_user_ret((drm_sis_mem_t *)arg, &fb, sizeof(fb), -EFAULT); + if (copy_to_user((drm_sis_mem_t *)arg, &fb, sizeof(fb))) return -EFAULT; DRM_DEBUG("alloc fb, size = %d, offset = %ld\n", fb.size, req.offset); @@ -111,7 +112,8 @@ int sis_fb_free(struct inode *inode, struct file *filp, unsigned int cmd, drm_sis_mem_t fb; int retval = 0; - copy_from_user_ret(&fb, (drm_sis_mem_t *)arg, sizeof(fb), -EFAULT); + if (copy_from_user(&fb, (drm_sis_mem_t *)arg, sizeof(fb))) + return -EFAULT; if(!fb.free){ return -1; @@ -152,7 +154,8 @@ int sis_agp_init(struct inode *inode, struct file *filp, unsigned int cmd, { drm_sis_agp_t agp; - copy_from_user_ret(&agp, (drm_sis_agp_t *)arg, sizeof(agp), -EFAULT); + if (copy_from_user(&agp, (drm_sis_agp_t *)arg, sizeof(agp))) + return -EFAULT; AgpHeap = mmInit(agp.offset, agp.size); @@ -171,7 +174,8 @@ int sis_agp_alloc(struct inode *inode, struct file *filp, unsigned int cmd, if(!AgpHeap) return -1; - copy_from_user_ret(&agp, (drm_sis_mem_t *)arg, sizeof(agp), -EFAULT); + if (copy_from_user(&agp, (drm_sis_mem_t *)arg, sizeof(agp))) + return -EFAULT; block = mmAllocMem(AgpHeap, agp.size, 0, 0); if(block){ @@ -190,7 +194,7 @@ int sis_agp_alloc(struct inode *inode, struct file *filp, unsigned int cmd, agp.free = 0; } - copy_to_user_ret((drm_sis_mem_t *)arg, &agp, sizeof(agp), -EFAULT); + if (copy_to_user((drm_sis_mem_t *)arg, &agp, sizeof(agp))) return -EFAULT; DRM_DEBUG("alloc agp, size = %d, offset = %d\n", agp.size, agp.offset); @@ -206,7 +210,8 @@ int sis_agp_free(struct inode *inode, struct file *filp, unsigned int cmd, if(!AgpHeap) return -1; - copy_from_user_ret(&agp, (drm_sis_mem_t *)arg, sizeof(agp), -EFAULT); + if (copy_from_user(&agp, (drm_sis_mem_t *)arg, sizeof(agp))) + return -EFAULT; if(!agp.free){ return -1; diff --git a/linux/tdfx_drv.c b/linux/tdfx_drv.c index 5f2c804af..7d79a013b 100644 --- a/linux/tdfx_drv.c +++ b/linux/tdfx_drv.c @@ -235,7 +235,7 @@ static int tdfx_takedown(drm_device_t *dev) drm_free(temp, sizeof(*temp), DRM_MEM_AGPLISTS); temp = temp_next; } - if (dev->agp->acquired) (*drm_agp.release)(); + if (dev->agp->acquired) _drm_agp_release(); } #endif /* Clear vma list (only built for debugging) */ @@ -298,7 +298,7 @@ static int tdfx_takedown(drm_device_t *dev) /* tdfx_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ -static int tdfx_init(void) +static int __init tdfx_init(void) { int retcode; drm_device_t *dev = &tdfx_device; @@ -346,7 +346,7 @@ static int tdfx_init(void) /* tdfx_cleanup is called via cleanup_module at module unload time. */ -static void tdfx_cleanup(void) +static void __exit tdfx_cleanup(void) { drm_device_t *dev = &tdfx_device; |