Commit 20f865ba authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://drm.bkbits.net/drm-linus

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents e51ec143 2f7fc60d
...@@ -5,7 +5,8 @@ ...@@ -5,7 +5,8 @@
drm-objs := drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \ drm-objs := drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \
drm_drv.o drm_fops.o drm_init.o drm_ioctl.o drm_irq.o \ drm_drv.o drm_fops.o drm_init.o drm_ioctl.o drm_irq.o \
drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \
drm_sysfs.o
gamma-objs := gamma_drv.o gamma_dma.o gamma-objs := gamma_drv.o gamma_dma.o
tdfx-objs := tdfx_drv.o tdfx-objs := tdfx_drv.o
......
...@@ -557,7 +557,7 @@ typedef struct drm_vbl_sig { ...@@ -557,7 +557,7 @@ typedef struct drm_vbl_sig {
struct drm_device; struct drm_device;
struct drm_driver { struct drm_driver {
int (*preinit)(struct drm_device *); int (*preinit)(struct drm_device *, unsigned long flags);
void (*prerelease)(struct drm_device *, struct file *filp); void (*prerelease)(struct drm_device *, struct file *filp);
void (*pretakedown)(struct drm_device *); void (*pretakedown)(struct drm_device *);
int (*postcleanup)(struct drm_device *); int (*postcleanup)(struct drm_device *);
...@@ -960,7 +960,7 @@ extern int drm_put_minor(drm_device_t *dev); ...@@ -960,7 +960,7 @@ extern int drm_put_minor(drm_device_t *dev);
extern unsigned int drm_debug; extern unsigned int drm_debug;
extern unsigned int drm_cards_limit; extern unsigned int drm_cards_limit;
extern drm_minor_t *drm_minors; extern drm_minor_t *drm_minors;
extern struct class_simple *drm_class; extern struct drm_sysfs_class *drm_class;
extern struct proc_dir_entry *drm_proc_root; extern struct proc_dir_entry *drm_proc_root;
/* Proc support (drm_proc.h) */ /* Proc support (drm_proc.h) */
...@@ -987,6 +987,24 @@ extern int drm_ati_pcigart_cleanup(drm_device_t *dev, ...@@ -987,6 +987,24 @@ extern int drm_ati_pcigart_cleanup(drm_device_t *dev,
unsigned long addr, unsigned long addr,
dma_addr_t bus_addr); dma_addr_t bus_addr);
extern void *drm_pci_alloc(drm_device_t * dev, size_t size,
size_t align, dma_addr_t maxaddr,
dma_addr_t * busaddr);
extern void drm_pci_free(drm_device_t * dev, size_t size,
void *vaddr, dma_addr_t busaddr);
/* sysfs support (drm_sysfs.c) */
struct drm_sysfs_class;
extern struct drm_sysfs_class *drm_sysfs_create(struct module *owner,
char *name);
extern void drm_sysfs_destroy(struct drm_sysfs_class *cs);
extern struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs,
dev_t dev,
struct device *device,
const char *fmt, ...);
extern void drm_sysfs_device_remove(dev_t dev);
/* Inline replacements for DRM_IOREMAP macros */ /* Inline replacements for DRM_IOREMAP macros */
static __inline__ void drm_core_ioremap(struct drm_map *map, struct drm_device *dev) static __inline__ void drm_core_ioremap(struct drm_map *map, struct drm_device *dev)
......
...@@ -403,7 +403,7 @@ static int __init drm_core_init(void) ...@@ -403,7 +403,7 @@ static int __init drm_core_init(void)
if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops)) if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops))
goto err_p1; goto err_p1;
drm_class = class_simple_create(THIS_MODULE, "drm"); drm_class = drm_sysfs_create(THIS_MODULE, "drm");
if (IS_ERR(drm_class)) { if (IS_ERR(drm_class)) {
printk (KERN_ERR "DRM: Error creating drm class.\n"); printk (KERN_ERR "DRM: Error creating drm class.\n");
ret = PTR_ERR(drm_class); ret = PTR_ERR(drm_class);
...@@ -426,7 +426,7 @@ static int __init drm_core_init(void) ...@@ -426,7 +426,7 @@ static int __init drm_core_init(void)
); );
return 0; return 0;
err_p3: err_p3:
class_simple_destroy(drm_class); drm_sysfs_destroy(drm_class);
err_p2: err_p2:
unregister_chrdev(DRM_MAJOR, "drm"); unregister_chrdev(DRM_MAJOR, "drm");
drm_free(drm_minors, sizeof(*drm_minors) * drm_cards_limit, DRM_MEM_STUB); drm_free(drm_minors, sizeof(*drm_minors) * drm_cards_limit, DRM_MEM_STUB);
...@@ -437,7 +437,7 @@ static int __init drm_core_init(void) ...@@ -437,7 +437,7 @@ static int __init drm_core_init(void)
static void __exit drm_core_exit (void) static void __exit drm_core_exit (void)
{ {
remove_proc_entry("dri", NULL); remove_proc_entry("dri", NULL);
class_simple_destroy(drm_class); drm_sysfs_destroy(drm_class);
unregister_chrdev(DRM_MAJOR, "drm"); unregister_chrdev(DRM_MAJOR, "drm");
......
...@@ -304,6 +304,17 @@ int drm_getstats( struct inode *inode, struct file *filp, ...@@ -304,6 +304,17 @@ int drm_getstats( struct inode *inode, struct file *filp,
return 0; return 0;
} }
/**
* Setversion ioctl.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument, pointing to a drm_lock structure.
* \return zero on success or negative number on failure.
*
* Sets the requested interface version
*/
int drm_setversion(DRM_IOCTL_ARGS) int drm_setversion(DRM_IOCTL_ARGS)
{ {
DRM_DEVICE; DRM_DEVICE;
...@@ -311,13 +322,15 @@ int drm_setversion(DRM_IOCTL_ARGS) ...@@ -311,13 +322,15 @@ int drm_setversion(DRM_IOCTL_ARGS)
drm_set_version_t retv; drm_set_version_t retv;
int if_version; int if_version;
drm_set_version_t __user *argp = (void __user *)data; drm_set_version_t __user *argp = (void __user *)data;
drm_version_t version;
DRM_COPY_FROM_USER_IOCTL(sv, argp, sizeof(sv)); DRM_COPY_FROM_USER_IOCTL(sv, argp, sizeof(sv));
dev->driver->version(&version);
retv.drm_di_major = DRM_IF_MAJOR; retv.drm_di_major = DRM_IF_MAJOR;
retv.drm_di_minor = DRM_IF_MINOR; retv.drm_di_minor = DRM_IF_MINOR;
retv.drm_dd_major = DRIVER_MAJOR; retv.drm_dd_major = version.version_major;
retv.drm_dd_minor = DRIVER_MINOR; retv.drm_dd_minor = version.version_minor;
DRM_COPY_TO_USER_IOCTL(argp, retv, sizeof(sv)); DRM_COPY_TO_USER_IOCTL(argp, retv, sizeof(sv));
...@@ -336,8 +349,8 @@ int drm_setversion(DRM_IOCTL_ARGS) ...@@ -336,8 +349,8 @@ int drm_setversion(DRM_IOCTL_ARGS)
} }
if (sv.drm_dd_major != -1) { if (sv.drm_dd_major != -1) {
if (sv.drm_dd_major != DRIVER_MAJOR || if (sv.drm_dd_major != version.version_major ||
sv.drm_dd_minor < 0 || sv.drm_dd_minor > DRIVER_MINOR) sv.drm_dd_minor < 0 || sv.drm_dd_minor > version.version_minor)
return EINVAL; return EINVAL;
if (dev->driver->set_version) if (dev->driver->set_version)
......
...@@ -57,8 +57,6 @@ ...@@ -57,8 +57,6 @@
# endif # endif
#endif #endif
#include <asm/tlbflush.h>
/* /*
* Find the drm_map that covers the range [offset, offset+size). * Find the drm_map that covers the range [offset, offset+size).
*/ */
......
/* drm_pci.h -- PCI DMA memory management wrappers for DRM -*- linux-c -*- */
/**
* \file drm_pci.c
* \brief Functions and ioctls to manage PCI memory
*
* \warning These interfaces aren't stable yet.
*
* \todo Implement the remaining ioctl's for the PCI pools.
* \todo The wrappers here are so thin that they would be better off inlined..
*
* \author Jose Fonseca <jrfonseca@tungstengraphics.com>
* \author Leif Delgass <ldelgass@retinalburn.net>
*/
/*
* Copyright 2003 Jos�Fonseca.
* Copyright 2003 Leif Delgass.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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 THE
* AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 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.
*/
#include <linux/pci.h>
#include "drmP.h"
/**********************************************************************/
/** \name PCI memory */
/*@{*/
/**
* \brief Allocate a PCI consistent memory block, for DMA.
*/
void *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
dma_addr_t maxaddr, dma_addr_t * busaddr)
{
void *address;
#if DRM_DEBUG_MEMORY
int area = DRM_MEM_DMA;
spin_lock(&drm_mem_lock);
if ((drm_ram_used >> PAGE_SHIFT)
> (DRM_RAM_PERCENT * drm_ram_available) / 100) {
spin_unlock(&drm_mem_lock);
return 0;
}
spin_unlock(&drm_mem_lock);
#endif
/* pci_alloc_consistent only guarantees alignment to the smallest
* PAGE_SIZE order which is greater than or equal to the requested size.
* Return NULL here for now to make sure nobody tries for larger alignment
*/
if (align > size)
return NULL;
if (pci_set_dma_mask(dev->pdev, maxaddr) != 0) {
DRM_ERROR("Setting pci dma mask failed\n");
return NULL;
}
address = pci_alloc_consistent(dev->pdev, size, busaddr);
#if DRM_DEBUG_MEMORY
if (address == NULL) {
spin_lock(&drm_mem_lock);
++drm_mem_stats[area].fail_count;
spin_unlock(&drm_mem_lock);
return NULL;
}
spin_lock(&drm_mem_lock);
++drm_mem_stats[area].succeed_count;
drm_mem_stats[area].bytes_allocated += size;
drm_ram_used += size;
spin_unlock(&drm_mem_lock);
#else
if (address == NULL)
return NULL;
#endif
memset(address, 0, size);
return address;
}
EXPORT_SYMBOL(drm_pci_alloc);
/**
* \brief Free a PCI consistent memory block.
*/
void
drm_pci_free(drm_device_t * dev, size_t size, void *vaddr, dma_addr_t busaddr)
{
#if DRM_DEBUG_MEMORY
int area = DRM_MEM_DMA;
int alloc_count;
int free_count;
#endif
if (!vaddr) {
#if DRM_DEBUG_MEMORY
DRM_MEM_ERROR(area, "Attempt to free address 0\n");
#endif
} else {
pci_free_consistent(dev->pdev, size, vaddr, busaddr);
}
#if DRM_DEBUG_MEMORY
spin_lock(&drm_mem_lock);
free_count = ++drm_mem_stats[area].free_count;
alloc_count = drm_mem_stats[area].succeed_count;
drm_mem_stats[area].bytes_freed += size;
drm_ram_used -= size;
spin_unlock(&drm_mem_lock);
if (free_count > alloc_count) {
DRM_MEM_ERROR(area,
"Excess frees: %d frees, %d allocs\n",
free_count, alloc_count);
}
#endif
}
EXPORT_SYMBOL(drm_pci_free);
/*@}*/
...@@ -3,64 +3,75 @@ ...@@ -3,64 +3,75 @@
Please contact dri-devel@lists.sf.net to add new cards to this list Please contact dri-devel@lists.sf.net to add new cards to this list
*/ */
#define radeon_PCI_IDS \ #define radeon_PCI_IDS \
{0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|CHIP_IS_IGP}, \
{0x1002, 0x4137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP}, \
{0x1002, 0x4237, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
{0x1002, 0x4242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
{0x1002, 0x4242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
{0x1002, 0x4336, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
{0x1002, 0x4337, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
{0x1002, 0x4437, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4151, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
{0x1002, 0x4964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
{0x1002, 0x4965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4153, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
{0x1002, 0x4966, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
{0x1002, 0x4967, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4156, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
{0x1002, 0x4C57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4237, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS250|CHIP_IS_IGP}, \
{0x1002, 0x4C58, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
{0x1002, 0x4C59, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4243, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
{0x1002, 0x4C5A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4336, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \
{0x1002, 0x4C64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4337, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \
{0x1002, 0x4C65, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4437, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS250|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \
{0x1002, 0x4C66, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \
{0x1002, 0x4C67, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \
{0x1002, 0x5144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4966, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \
{0x1002, 0x5145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4967, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \
{0x1002, 0x5146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4C57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|CHIP_IS_MOBILITY}, \
{0x1002, 0x5147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4C58, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|CHIP_IS_MOBILITY}, \
{0x1002, 0x5148, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4C59, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|CHIP_IS_MOBILITY}, \
{0x1002, 0x5149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4C5A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|CHIP_IS_MOBILITY}, \
{0x1002, 0x514A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4C64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \
{0x1002, 0x514B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4C65, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \
{0x1002, 0x514C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4C66, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \
{0x1002, 0x514D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4C67, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \
{0x1002, 0x514E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x4E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
{0x1002, 0x514F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x5144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \
{0x1002, 0x5157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x5145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \
{0x1002, 0x5158, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x5146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \
{0x1002, 0x5159, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x5147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \
{0x1002, 0x515A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x5148, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
{0x1002, 0x5168, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x5149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
{0x1002, 0x5169, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x514A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
{0x1002, 0x516A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x514B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
{0x1002, 0x516B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x514C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
{0x1002, 0x516C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x514D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
{0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x514E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
{0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x514F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
{0x1002, 0x5836, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x5157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200}, \
{0x1002, 0x5837, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x5158, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200}, \
{0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x5159, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
{0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x515A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
{0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x5168, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
{0x1002, 0x5963, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x5169, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
{0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x516A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
{0x1002, 0x5968, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x516B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
{0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x516C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
{0x1002, 0x596A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \
{0x1002, 0x596B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \
{0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x5836, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \
{0x1002, 0x5c62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x5837, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \
{0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5c64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5963, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5968, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x596A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x596B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \
{0x1002, 0x5c62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \
{0x1002, 0x5c64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0, 0, 0} {0, 0, 0}
#define r128_PCI_IDS \ #define r128_PCI_IDS \
...@@ -207,5 +218,6 @@ ...@@ -207,5 +218,6 @@
{0x8086, 0x3582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x8086, 0x3582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x2582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x8086, 0x2582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x2982, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0} {0, 0, 0}
...@@ -50,7 +50,7 @@ module_param_named(cards_limit, drm_cards_limit, int, 0444); ...@@ -50,7 +50,7 @@ module_param_named(cards_limit, drm_cards_limit, int, 0444);
module_param_named(debug, drm_debug, int, 0666); module_param_named(debug, drm_debug, int, 0666);
drm_minor_t *drm_minors; drm_minor_t *drm_minors;
struct class_simple *drm_class; struct drm_sysfs_class *drm_class;
struct proc_dir_entry *drm_proc_root; struct proc_dir_entry *drm_proc_root;
static int drm_fill_in_dev(drm_device_t *dev, struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver *driver) static int drm_fill_in_dev(drm_device_t *dev, struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver *driver)
...@@ -87,7 +87,7 @@ static int drm_fill_in_dev(drm_device_t *dev, struct pci_dev *pdev, const struct ...@@ -87,7 +87,7 @@ static int drm_fill_in_dev(drm_device_t *dev, struct pci_dev *pdev, const struct
dev->driver = driver; dev->driver = driver;
if (dev->driver->preinit) if (dev->driver->preinit)
if ((retcode = dev->driver->preinit(dev))) if ((retcode = dev->driver->preinit(dev, ent->driver_data)))
goto error_out_unreg; goto error_out_unreg;
if (drm_core_has_AGP(dev)) { if (drm_core_has_AGP(dev)) {
...@@ -205,10 +205,13 @@ int drm_probe(struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_ ...@@ -205,10 +205,13 @@ int drm_probe(struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_
} }
dev_class = class_simple_device_add(drm_class, dev_class = drm_sysfs_device_add(drm_class,
MKDEV(DRM_MAJOR, minor), &pdev->dev, "card%d", minor); MKDEV(DRM_MAJOR,
minor),
&pdev->dev,
"card%d", minor);
if (IS_ERR(dev_class)) { if (IS_ERR(dev_class)) {
printk(KERN_ERR "DRM: Error class_simple_device_add.\n"); printk(KERN_ERR "DRM: Error sysfs_device_add.\n");
ret = PTR_ERR(dev_class); ret = PTR_ERR(dev_class);
goto err_g2; goto err_g2;
} }
...@@ -246,7 +249,7 @@ int drm_put_minor(drm_device_t *dev) ...@@ -246,7 +249,7 @@ int drm_put_minor(drm_device_t *dev)
DRM_DEBUG("release minor %d\n", dev->minor); DRM_DEBUG("release minor %d\n", dev->minor);
drm_proc_cleanup(dev->minor, drm_proc_root, minors->dev_root); drm_proc_cleanup(dev->minor, drm_proc_root, minors->dev_root);
class_simple_device_remove(MKDEV(DRM_MAJOR, dev->minor)); drm_sysfs_device_remove(MKDEV(DRM_MAJOR, dev->minor));
*minors = (drm_minor_t){.dev = NULL, .type = DRM_MINOR_FREE}; *minors = (drm_minor_t){.dev = NULL, .type = DRM_MINOR_FREE};
drm_free(dev, sizeof(*dev), DRM_MEM_STUB); drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
......
/*
* drm_sysfs.c - Modifications to drm_sysfs_class.c to support
* extra sysfs attribute from DRM. Normal drm_sysfs_class
* does not allow adding attributes.
*
* Copyright (c) 2004 Jon Smirl <jonsmirl@gmail.com>
* Copyright (c) 2003-2004 Greg Kroah-Hartman <greg@kroah.com>
* Copyright (c) 2003-2004 IBM Corp.
*
* This file is released under the GPLv2
*
*/
#include <linux/config.h>
#include <linux/device.h>
#include <linux/kdev_t.h>
#include <linux/err.h>
#include "drm_core.h"
struct drm_sysfs_class {
struct class_device_attribute attr;
struct class class;
};
#define to_drm_sysfs_class(d) container_of(d, struct drm_sysfs_class, class)
struct simple_dev {
struct list_head node;
dev_t dev;
struct class_device class_dev;
};
#define to_simple_dev(d) container_of(d, struct simple_dev, class_dev)
static LIST_HEAD(simple_dev_list);
static DEFINE_SPINLOCK(simple_dev_list_lock);
static void release_simple_dev(struct class_device *class_dev)
{
struct simple_dev *s_dev = to_simple_dev(class_dev);
kfree(s_dev);
}
static ssize_t show_dev(struct class_device *class_dev, char *buf)
{
struct simple_dev *s_dev = to_simple_dev(class_dev);
return print_dev_t(buf, s_dev->dev);
}
static void drm_sysfs_class_release(struct class *class)
{
struct drm_sysfs_class *cs = to_drm_sysfs_class(class);
kfree(cs);
}
/* Display the version of drm_core. This doesn't work right in current design */
static ssize_t version_show(struct class *dev, char *buf)
{
return sprintf(buf, "%s %d.%d.%d %s\n", DRIVER_NAME, DRIVER_MAJOR,
DRIVER_MINOR, DRIVER_PATCHLEVEL, DRIVER_DATE);
}
static CLASS_ATTR(version, S_IRUGO, version_show, NULL);
/**
* drm_sysfs_create - create a struct drm_sysfs_class structure
* @owner: pointer to the module that is to "own" this struct drm_sysfs_class
* @name: pointer to a string for the name of this class.
*
* This is used to create a struct drm_sysfs_class pointer that can then be used
* in calls to drm_sysfs_device_add().
*
* Note, the pointer created here is to be destroyed when finished by making a
* call to drm_sysfs_destroy().
*/
struct drm_sysfs_class *drm_sysfs_create(struct module *owner, char *name)
{
struct drm_sysfs_class *cs;
int retval;
cs = kmalloc(sizeof(*cs), GFP_KERNEL);
if (!cs) {
retval = -ENOMEM;
goto error;
}
memset(cs, 0x00, sizeof(*cs));
cs->class.name = name;
cs->class.class_release = drm_sysfs_class_release;
cs->class.release = release_simple_dev;
cs->attr.attr.name = "dev";
cs->attr.attr.mode = S_IRUGO;
cs->attr.attr.owner = owner;
cs->attr.show = show_dev;
cs->attr.store = NULL;
retval = class_register(&cs->class);
if (retval)
goto error;
class_create_file(&cs->class, &class_attr_version);
return cs;
error:
kfree(cs);
return ERR_PTR(retval);
}
/**
* drm_sysfs_destroy - destroys a struct drm_sysfs_class structure
* @cs: pointer to the struct drm_sysfs_class that is to be destroyed
*
* Note, the pointer to be destroyed must have been created with a call to
* drm_sysfs_create().
*/
void drm_sysfs_destroy(struct drm_sysfs_class *cs)
{
if ((cs == NULL) || (IS_ERR(cs)))
return;
class_unregister(&cs->class);
}
/**
* drm_sysfs_device_add - adds a class device to sysfs for a character driver
* @cs: pointer to the struct drm_sysfs_class that this device should be registered to.
* @dev: the dev_t for the device to be added.
* @device: a pointer to a struct device that is assiociated with this class device.
* @fmt: string for the class device's name
*
* A struct class_device will be created in sysfs, registered to the specified
* class. A "dev" file will be created, showing the dev_t for the device. The
* pointer to the struct class_device will be returned from the call. Any further
* sysfs files that might be required can be created using this pointer.
* Note: the struct drm_sysfs_class passed to this function must have previously been
* created with a call to drm_sysfs_create().
*/
struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, dev_t dev,
struct device *device,
const char *fmt, ...)
{
va_list args;
struct simple_dev *s_dev = NULL;
int retval;
if ((cs == NULL) || (IS_ERR(cs))) {
retval = -ENODEV;
goto error;
}
s_dev = kmalloc(sizeof(*s_dev), GFP_KERNEL);
if (!s_dev) {
retval = -ENOMEM;
goto error;
}
memset(s_dev, 0x00, sizeof(*s_dev));
s_dev->dev = dev;
s_dev->class_dev.dev = device;
s_dev->class_dev.class = &cs->class;
va_start(args, fmt);
vsnprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, fmt, args);
va_end(args);
retval = class_device_register(&s_dev->class_dev);
if (retval)
goto error;
class_device_create_file(&s_dev->class_dev, &cs->attr);
spin_lock(&simple_dev_list_lock);
list_add(&s_dev->node, &simple_dev_list);
spin_unlock(&simple_dev_list_lock);
return &s_dev->class_dev;
error:
kfree(s_dev);
return ERR_PTR(retval);
}
/**
* drm_sysfs_device_remove - removes a class device that was created with drm_sysfs_device_add()
* @dev: the dev_t of the device that was previously registered.
*
* This call unregisters and cleans up a class device that was created with a
* call to drm_sysfs_device_add()
*/
void drm_sysfs_device_remove(dev_t dev)
{
struct simple_dev *s_dev = NULL;
int found = 0;
spin_lock(&simple_dev_list_lock);
list_for_each_entry(s_dev, &simple_dev_list, node) {
if (s_dev->dev == dev) {
found = 1;
break;
}
}
if (found) {
list_del(&s_dev->node);
spin_unlock(&simple_dev_list_lock);
class_device_unregister(&s_dev->class_dev);
} else {
spin_unlock(&simple_dev_list_lock);
}
}
/* ffb.h -- ffb DRM template customization -*- linux-c -*-
*/
#ifndef __FFB_H__
#define __FFB_H__
/* This remains constant for all DRM template files.
*/
#define DRM(x) ffb_##x
#endif
/* gamma.c -- 3dlabs GMX 2000 driver -*- linux-c -*-
* Created: Mon Jan 4 08:58:31 1999 by gareth@valinux.com
*
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* 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:
* Gareth Hughes <gareth@valinux.com>
*/
#ifndef __GAMMA_H__
#define __GAMMA_H__
/* This remains constant for all DRM template files.
*/
#define DRM(x) gamma_##x
/* General customization:
*/
#define DRIVER_AUTHOR "VA Linux Systems Inc."
#define DRIVER_NAME "gamma"
#define DRIVER_DESC "3DLabs gamma"
#define DRIVER_DATE "20010624"
#define DRIVER_MAJOR 2
#define DRIVER_MINOR 0
#define DRIVER_PATCHLEVEL 0
#define DRIVER_IOCTLS \
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { gamma_dma, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_GAMMA_INIT)] = { gamma_dma_init, 1, 1 }, \
[DRM_IOCTL_NR(DRM_IOCTL_GAMMA_COPY)] = { gamma_dma_copy, 1, 1 }
#define IOCTL_TABLE_NAME DRM(ioctls)
#define IOCTL_FUNC_NAME DRM(ioctl)
#define __HAVE_COUNTERS 5
#define __HAVE_COUNTER6 _DRM_STAT_IRQ
#define __HAVE_COUNTER7 _DRM_STAT_DMA
#define __HAVE_COUNTER8 _DRM_STAT_PRIMARY
#define __HAVE_COUNTER9 _DRM_STAT_SPECIAL
#define __HAVE_COUNTER10 _DRM_STAT_MISSED
/* Driver customization:
*/
#define DRIVER_PRETAKEDOWN() do { \
gamma_do_cleanup_dma( dev ); \
} while (0)
/* DMA customization:
*/
#define __HAVE_MULTIPLE_DMA_QUEUES 1
#define __HAVE_DMA_WAITQUEUE 1
/* removed from DRM HAVE_DMA_FREELIST & HAVE_DMA_SCHEDULE */
#endif /* __GAMMA_H__ */
/* i810.h -- Intel i810/i815 DRM template customization -*- linux-c -*-
* Created: Thu Feb 15 00:01:12 2001 by gareth@valinux.com
*
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* 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:
* Gareth Hughes <gareth@valinux.com>
*/
#ifndef __I810_H__
#define __I810_H__
/* This remains constant for all DRM template files.
*/
#define DRM(x) i810_##x
/* General customization:
*/
#define DRIVER_AUTHOR "VA Linux Systems Inc."
#define DRIVER_NAME "i810"
#define DRIVER_DESC "Intel i810"
#define DRIVER_DATE "20030605"
/* Interface history
*
* 1.1 - XFree86 4.1
* 1.2 - XvMC interfaces
* - XFree86 4.2
* 1.2.1 - Disable copying code (leave stub ioctls for backwards compatibility)
* - Remove requirement for interrupt (leave stubs again)
* 1.3 - Add page flipping.
* 1.4 - fix DRM interface
*/
#define DRIVER_MAJOR 1
#define DRIVER_MINOR 4
#define DRIVER_PATCHLEVEL 0
#define DRIVER_IOCTLS \
[DRM_IOCTL_NR(DRM_IOCTL_I810_INIT)] = { i810_dma_init, 1, 1 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I810_VERTEX)] = { i810_dma_vertex, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I810_CLEAR)] = { i810_clear_bufs, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I810_FLUSH)] = { i810_flush_ioctl, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I810_GETAGE)] = { i810_getage, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I810_GETBUF)] = { i810_getbuf, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I810_SWAP)] = { i810_swap_bufs, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I810_COPY)] = { i810_copybuf, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I810_DOCOPY)] = { i810_docopy, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I810_OV0INFO)] = { i810_ov0_info, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I810_FSTATUS)] = { i810_fstatus, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I810_OV0FLIP)] = { i810_ov0_flip, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I810_MC)] = { i810_dma_mc, 1, 1 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I810_RSTATUS)] = { i810_rstatus, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I810_FLIP)] = { i810_flip_bufs, 1, 0 }
#endif
...@@ -50,6 +50,26 @@ ...@@ -50,6 +50,26 @@
#define up_write up #define up_write up
#endif #endif
drm_ioctl_desc_t i810_ioctls[] = {
[DRM_IOCTL_NR(DRM_I810_INIT)] = { i810_dma_init, 1, 1 },
[DRM_IOCTL_NR(DRM_I810_VERTEX)] = { i810_dma_vertex, 1, 0 },
[DRM_IOCTL_NR(DRM_I810_CLEAR)] = { i810_clear_bufs, 1, 0 },
[DRM_IOCTL_NR(DRM_I810_FLUSH)] = { i810_flush_ioctl, 1, 0 },
[DRM_IOCTL_NR(DRM_I810_GETAGE)] = { i810_getage, 1, 0 },
[DRM_IOCTL_NR(DRM_I810_GETBUF)] = { i810_getbuf, 1, 0 },
[DRM_IOCTL_NR(DRM_I810_SWAP)] = { i810_swap_bufs, 1, 0 },
[DRM_IOCTL_NR(DRM_I810_COPY)] = { i810_copybuf, 1, 0 },
[DRM_IOCTL_NR(DRM_I810_DOCOPY)] = { i810_docopy, 1, 0 },
[DRM_IOCTL_NR(DRM_I810_OV0INFO)] = { i810_ov0_info, 1, 0 },
[DRM_IOCTL_NR(DRM_I810_FSTATUS)] = { i810_fstatus, 1, 0 },
[DRM_IOCTL_NR(DRM_I810_OV0FLIP)] = { i810_ov0_flip, 1, 0 },
[DRM_IOCTL_NR(DRM_I810_MC)] = { i810_dma_mc, 1, 1 },
[DRM_IOCTL_NR(DRM_I810_RSTATUS)] = { i810_rstatus, 1, 0 },
[DRM_IOCTL_NR(DRM_I810_FLIP)] = { i810_flip_bufs, 1, 0 }
};
int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls);
static drm_buf_t *i810_freelist_get(drm_device_t *dev) static drm_buf_t *i810_freelist_get(drm_device_t *dev)
{ {
drm_device_dma_t *dma = dev->dma; drm_device_dma_t *dma = dev->dma;
......
...@@ -76,23 +76,8 @@ static struct pci_device_id pciidlist[] = { ...@@ -76,23 +76,8 @@ static struct pci_device_id pciidlist[] = {
i810_PCI_IDS i810_PCI_IDS
}; };
static drm_ioctl_desc_t ioctls[] = { extern drm_ioctl_desc_t i810_ioctls[];
[DRM_IOCTL_NR(DRM_I810_INIT)] = { i810_dma_init, 1, 1 }, extern int i810_max_ioctl;
[DRM_IOCTL_NR(DRM_I810_VERTEX)] = { i810_dma_vertex, 1, 0 },
[DRM_IOCTL_NR(DRM_I810_CLEAR)] = { i810_clear_bufs, 1, 0 },
[DRM_IOCTL_NR(DRM_I810_FLUSH)] = { i810_flush_ioctl, 1, 0 },
[DRM_IOCTL_NR(DRM_I810_GETAGE)] = { i810_getage, 1, 0 },
[DRM_IOCTL_NR(DRM_I810_GETBUF)] = { i810_getbuf, 1, 0 },
[DRM_IOCTL_NR(DRM_I810_SWAP)] = { i810_swap_bufs, 1, 0 },
[DRM_IOCTL_NR(DRM_I810_COPY)] = { i810_copybuf, 1, 0 },
[DRM_IOCTL_NR(DRM_I810_DOCOPY)] = { i810_docopy, 1, 0 },
[DRM_IOCTL_NR(DRM_I810_OV0INFO)] = { i810_ov0_info, 1, 0 },
[DRM_IOCTL_NR(DRM_I810_FSTATUS)] = { i810_fstatus, 1, 0 },
[DRM_IOCTL_NR(DRM_I810_OV0FLIP)] = { i810_ov0_flip, 1, 0 },
[DRM_IOCTL_NR(DRM_I810_MC)] = { i810_dma_mc, 1, 1 },
[DRM_IOCTL_NR(DRM_I810_RSTATUS)] = { i810_rstatus, 1, 0 },
[DRM_IOCTL_NR(DRM_I810_FLIP)] = { i810_flip_bufs, 1, 0 }
};
static struct drm_driver driver = { static struct drm_driver driver = {
.driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE, .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE,
...@@ -105,8 +90,7 @@ static struct drm_driver driver = { ...@@ -105,8 +90,7 @@ static struct drm_driver driver = {
.get_reg_ofs = drm_core_get_reg_ofs, .get_reg_ofs = drm_core_get_reg_ofs,
.postinit = postinit, .postinit = postinit,
.version = version, .version = version,
.ioctls = ioctls, .ioctls = i810_ioctls,
.num_ioctls = DRM_ARRAY_SIZE(ioctls),
.fops = { .fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.open = drm_open, .open = drm_open,
...@@ -124,6 +108,7 @@ static struct drm_driver driver = { ...@@ -124,6 +108,7 @@ static struct drm_driver driver = {
static int __init i810_init(void) static int __init i810_init(void)
{ {
driver.num_ioctls = i810_max_ioctl;
return drm_init(&driver); return drm_init(&driver);
} }
......
/* i830.h -- Intel I830 DRM template customization -*- linux-c -*-
* Created: Thu Feb 15 00:01:12 2001 by gareth@valinux.com
*
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* 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:
* Gareth Hughes <gareth@valinux.com>
*/
#ifndef __I830_H__
#define __I830_H__
/* This remains constant for all DRM template files.
*/
#define DRM(x) i830_##x
/* General customization:
*/
#define DRIVER_AUTHOR "VA Linux Systems Inc."
#define DRIVER_NAME "i830"
#define DRIVER_DESC "Intel 830M"
#define DRIVER_DATE "20021108"
/* Interface history:
*
* 1.1: Original.
* 1.2: ?
* 1.3: New irq emit/wait ioctls.
* New pageflip ioctl.
* New getparam ioctl.
* State for texunits 3&4 in sarea.
* New (alternative) layout for texture state.
*/
#define DRIVER_MAJOR 1
#define DRIVER_MINOR 3
#define DRIVER_PATCHLEVEL 2
#define DRIVER_IOCTLS \
[DRM_IOCTL_NR(DRM_IOCTL_I830_INIT)] = { i830_dma_init, 1, 1 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I830_VERTEX)] = { i830_dma_vertex, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I830_CLEAR)] = { i830_clear_bufs, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I830_FLUSH)] = { i830_flush_ioctl, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I830_GETAGE)] = { i830_getage, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I830_GETBUF)] = { i830_getbuf, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I830_SWAP)] = { i830_swap_bufs, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I830_COPY)] = { i830_copybuf, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I830_DOCOPY)] = { i830_docopy, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I830_FLIP)] = { i830_flip_bufs, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I830_IRQ_EMIT)] = { i830_irq_emit, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I830_IRQ_WAIT)] = { i830_irq_wait, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I830_GETPARAM)] = { i830_getparam, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I830_SETPARAM)] = { i830_setparam, 1, 0 }
/* Driver will work either way: IRQ's save cpu time when waiting for
* the card, but are subject to subtle interactions between bios,
* hardware and the driver.
*/
/* XXX: Add vblank support? */
#define USE_IRQS 0
#endif
...@@ -52,6 +52,25 @@ ...@@ -52,6 +52,25 @@
#define up_write up #define up_write up
#endif #endif
drm_ioctl_desc_t i830_ioctls[] = {
[DRM_IOCTL_NR(DRM_I830_INIT)] = { i830_dma_init, 1, 1 },
[DRM_IOCTL_NR(DRM_I830_VERTEX)] = { i830_dma_vertex, 1, 0 },
[DRM_IOCTL_NR(DRM_I830_CLEAR)] = { i830_clear_bufs, 1, 0 },
[DRM_IOCTL_NR(DRM_I830_FLUSH)] = { i830_flush_ioctl, 1, 0 },
[DRM_IOCTL_NR(DRM_I830_GETAGE)] = { i830_getage, 1, 0 },
[DRM_IOCTL_NR(DRM_I830_GETBUF)] = { i830_getbuf, 1, 0 },
[DRM_IOCTL_NR(DRM_I830_SWAP)] = { i830_swap_bufs, 1, 0 },
[DRM_IOCTL_NR(DRM_I830_COPY)] = { i830_copybuf, 1, 0 },
[DRM_IOCTL_NR(DRM_I830_DOCOPY)] = { i830_docopy, 1, 0 },
[DRM_IOCTL_NR(DRM_I830_FLIP)] = { i830_flip_bufs, 1, 0 },
[DRM_IOCTL_NR(DRM_I830_IRQ_EMIT)] = { i830_irq_emit, 1, 0 },
[DRM_IOCTL_NR(DRM_I830_IRQ_WAIT)] = { i830_irq_wait, 1, 0 },
[DRM_IOCTL_NR(DRM_I830_GETPARAM)] = { i830_getparam, 1, 0 },
[DRM_IOCTL_NR(DRM_I830_SETPARAM)] = { i830_setparam, 1, 0 }
};
int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls);
static inline void i830_print_status_page(drm_device_t *dev) static inline void i830_print_status_page(drm_device_t *dev)
{ {
drm_device_dma_t *dma = dev->dma; drm_device_dma_t *dma = dev->dma;
......
...@@ -77,22 +77,8 @@ static struct pci_device_id pciidlist[] = { ...@@ -77,22 +77,8 @@ static struct pci_device_id pciidlist[] = {
i830_PCI_IDS i830_PCI_IDS
}; };
static drm_ioctl_desc_t ioctls[] = { extern drm_ioctl_desc_t i830_ioctls[];
[DRM_IOCTL_NR(DRM_I830_INIT)] = { i830_dma_init, 1, 1 }, extern int i830_max_ioctl;
[DRM_IOCTL_NR(DRM_I830_VERTEX)] = { i830_dma_vertex, 1, 0 },
[DRM_IOCTL_NR(DRM_I830_CLEAR)] = { i830_clear_bufs, 1, 0 },
[DRM_IOCTL_NR(DRM_I830_FLUSH)] = { i830_flush_ioctl, 1, 0 },
[DRM_IOCTL_NR(DRM_I830_GETAGE)] = { i830_getage, 1, 0 },
[DRM_IOCTL_NR(DRM_I830_GETBUF)] = { i830_getbuf, 1, 0 },
[DRM_IOCTL_NR(DRM_I830_SWAP)] = { i830_swap_bufs, 1, 0 },
[DRM_IOCTL_NR(DRM_I830_COPY)] = { i830_copybuf, 1, 0 },
[DRM_IOCTL_NR(DRM_I830_DOCOPY)] = { i830_docopy, 1, 0 },
[DRM_IOCTL_NR(DRM_I830_FLIP)] = { i830_flip_bufs, 1, 0 },
[DRM_IOCTL_NR(DRM_I830_IRQ_EMIT)] = { i830_irq_emit, 1, 0 },
[DRM_IOCTL_NR(DRM_I830_IRQ_WAIT)] = { i830_irq_wait, 1, 0 },
[DRM_IOCTL_NR(DRM_I830_GETPARAM)] = { i830_getparam, 1, 0 },
[DRM_IOCTL_NR(DRM_I830_SETPARAM)] = { i830_setparam, 1, 0 }
};
static struct drm_driver driver = { static struct drm_driver driver = {
.driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE, .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE,
...@@ -114,8 +100,7 @@ static struct drm_driver driver = { ...@@ -114,8 +100,7 @@ static struct drm_driver driver = {
#endif #endif
.postinit = postinit, .postinit = postinit,
.version = version, .version = version,
.ioctls = ioctls, .ioctls = i830_ioctls,
.num_ioctls = DRM_ARRAY_SIZE(ioctls),
.fops = { .fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.open = drm_open, .open = drm_open,
...@@ -134,6 +119,7 @@ static struct drm_driver driver = { ...@@ -134,6 +119,7 @@ static struct drm_driver driver = {
static int __init i830_init(void) static int __init i830_init(void)
{ {
driver.num_ioctls = i830_max_ioctl;
return drm_init(&driver); return drm_init(&driver);
} }
......
/* i915.h -- Intel I915 DRM template customization -*- linux-c -*-
*/
/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
**************************************************************************/
#ifndef __I915_H__
#define __I915_H__
/* This remains constant for all DRM template files.
*/
#define DRM(x) i915_##x
/* General customization:
*/
#define DRIVER_AUTHOR "Tungsten Graphics, Inc."
#define DRIVER_NAME "i915"
#define DRIVER_DESC "Intel Graphics"
#define DRIVER_DATE "20040405"
/* Interface history:
*
* 1.1: Original.
*/
#define DRIVER_MAJOR 1
#define DRIVER_MINOR 1
#define DRIVER_PATCHLEVEL 0
#define DRIVER_IOCTLS \
[DRM_IOCTL_NR(DRM_IOCTL_I915_INIT)] = { i915_dma_init, 1, 1 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I915_FLUSH)] = { i915_flush_ioctl, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I915_FLIP)] = { i915_flip_bufs, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I915_BATCHBUFFER)] = { i915_batchbuffer, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I915_IRQ_EMIT)] = { i915_irq_emit, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I915_IRQ_WAIT)] = { i915_irq_wait, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I915_GETPARAM)] = { i915_getparam, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I915_SETPARAM)] = { i915_setparam, 1, 1 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I915_ALLOC)] = { i915_mem_alloc, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I915_FREE)] = { i915_mem_free, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I915_INIT_HEAP)] = { i915_mem_init_heap, 1, 1 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I915_CMDBUFFER)] = { i915_cmdbuffer, 1, 0 }
/* We use our own dma mechanisms, not the drm template code. However,
* the shared IRQ code is useful to us:
*/
#define __HAVE_PM 1
#endif
...@@ -12,6 +12,23 @@ ...@@ -12,6 +12,23 @@
#include "i915_drm.h" #include "i915_drm.h"
#include "i915_drv.h" #include "i915_drv.h"
drm_ioctl_desc_t i915_ioctls[] = {
[DRM_IOCTL_NR(DRM_I915_INIT)] = {i915_dma_init, 1, 1},
[DRM_IOCTL_NR(DRM_I915_FLUSH)] = {i915_flush_ioctl, 1, 0},
[DRM_IOCTL_NR(DRM_I915_FLIP)] = {i915_flip_bufs, 1, 0},
[DRM_IOCTL_NR(DRM_I915_BATCHBUFFER)] = {i915_batchbuffer, 1, 0},
[DRM_IOCTL_NR(DRM_I915_IRQ_EMIT)] = {i915_irq_emit, 1, 0},
[DRM_IOCTL_NR(DRM_I915_IRQ_WAIT)] = {i915_irq_wait, 1, 0},
[DRM_IOCTL_NR(DRM_I915_GETPARAM)] = {i915_getparam, 1, 0},
[DRM_IOCTL_NR(DRM_I915_SETPARAM)] = {i915_setparam, 1, 1},
[DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, 1, 0},
[DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, 1, 0},
[DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, 1, 1},
[DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, 1, 0}
};
int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
/* Really want an OS-independent resettable timer. Would like to have /* Really want an OS-independent resettable timer. Would like to have
* this loop run for (eg) 3 sec, but have the timer reset every time * this loop run for (eg) 3 sec, but have the timer reset every time
* the head pointer changes, so that EBUSY only happens if the ring * the head pointer changes, so that EBUSY only happens if the ring
...@@ -76,8 +93,7 @@ int i915_dma_cleanup(drm_device_t * dev) ...@@ -76,8 +93,7 @@ int i915_dma_cleanup(drm_device_t * dev)
} }
if (dev_priv->hw_status_page) { if (dev_priv->hw_status_page) {
pci_free_consistent(dev->pdev, PAGE_SIZE, drm_pci_free(dev, PAGE_SIZE, dev_priv->hw_status_page,
dev_priv->hw_status_page,
dev_priv->dma_status_page); dev_priv->dma_status_page);
/* Need to rewrite hardware status page */ /* Need to rewrite hardware status page */
I915_WRITE(0x02080, 0x1ffff000); I915_WRITE(0x02080, 0x1ffff000);
...@@ -155,8 +171,8 @@ static int i915_initialize(drm_device_t * dev, ...@@ -155,8 +171,8 @@ static int i915_initialize(drm_device_t * dev,
dev_priv->allow_batchbuffer = 1; dev_priv->allow_batchbuffer = 1;
/* Program Hardware Status Page */ /* Program Hardware Status Page */
dev_priv->hw_status_page = dev_priv->hw_status_page = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE,
pci_alloc_consistent(dev->pdev, PAGE_SIZE, 0xffffffff,
&dev_priv->dma_status_page); &dev_priv->dma_status_page);
if (!dev_priv->hw_status_page) { if (!dev_priv->hw_status_page) {
......
...@@ -52,20 +52,8 @@ static struct pci_device_id pciidlist[] = { ...@@ -52,20 +52,8 @@ static struct pci_device_id pciidlist[] = {
i915_PCI_IDS i915_PCI_IDS
}; };
static drm_ioctl_desc_t ioctls[] = { extern drm_ioctl_desc_t i915_ioctls[];
[DRM_IOCTL_NR(DRM_I915_INIT)] = { i915_dma_init, 1, 1 }, extern int i915_max_ioctl;
[DRM_IOCTL_NR(DRM_I915_FLUSH)] = { i915_flush_ioctl, 1, 0 },
[DRM_IOCTL_NR(DRM_I915_FLIP)] = { i915_flip_bufs, 1, 0 },
[DRM_IOCTL_NR(DRM_I915_BATCHBUFFER)] = { i915_batchbuffer, 1, 0 },
[DRM_IOCTL_NR(DRM_I915_IRQ_EMIT)] = { i915_irq_emit, 1, 0 },
[DRM_IOCTL_NR(DRM_I915_IRQ_WAIT)] = { i915_irq_wait, 1, 0 },
[DRM_IOCTL_NR(DRM_I915_GETPARAM)] = { i915_getparam, 1, 0 },
[DRM_IOCTL_NR(DRM_I915_SETPARAM)] = { i915_setparam, 1, 1 },
[DRM_IOCTL_NR(DRM_I915_ALLOC)] = { i915_mem_alloc, 1, 0 },
[DRM_IOCTL_NR(DRM_I915_FREE)] = { i915_mem_free, 1, 0 },
[DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = { i915_mem_init_heap, 1, 1 },
[DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = { i915_cmdbuffer, 1, 0 }
};
static struct drm_driver driver = { static struct drm_driver driver = {
.driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR |
...@@ -81,8 +69,7 @@ static struct drm_driver driver = { ...@@ -81,8 +69,7 @@ static struct drm_driver driver = {
.get_reg_ofs = drm_core_get_reg_ofs, .get_reg_ofs = drm_core_get_reg_ofs,
.postinit = postinit, .postinit = postinit,
.version = version, .version = version,
.ioctls = ioctls, .ioctls = i915_ioctls,
.num_ioctls = DRM_ARRAY_SIZE(ioctls),
.fops = { .fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.open = drm_open, .open = drm_open,
...@@ -100,6 +87,7 @@ static struct drm_driver driver = { ...@@ -100,6 +87,7 @@ static struct drm_driver driver = {
static int __init i915_init(void) static int __init i915_init(void)
{ {
driver.num_ioctls = i915_max_ioctl;
return drm_init(&driver); return drm_init(&driver);
} }
......
/* mga.h -- Matrox G200/G400 DRM template customization -*- linux-c -*-
* Created: Thu Jan 11 21:29:32 2001 by gareth@valinux.com
*
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* 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:
* Gareth Hughes <gareth@valinux.com>
*/
#ifndef __MGA_H__
#define __MGA_H__
/* This remains constant for all DRM template files.
*/
#define DRM(x) mga_##x
/* General customization:
*/
#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc."
#define DRIVER_NAME "mga"
#define DRIVER_DESC "Matrox G200/G400"
#define DRIVER_DATE "20021029"
#define DRIVER_MAJOR 3
#define DRIVER_MINOR 1
#define DRIVER_PATCHLEVEL 0
#define DRIVER_IOCTLS \
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma_buffers, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)] = { mga_dma_init, 1, 1 }, \
[DRM_IOCTL_NR(DRM_IOCTL_MGA_FLUSH)] = { mga_dma_flush, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_MGA_RESET)] = { mga_dma_reset, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_dma_swap, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_dma_clear, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_dma_vertex, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_dma_indices, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_dma_iload, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_MGA_BLIT)] = { mga_dma_blit, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_MGA_GETPARAM)]= { mga_getparam, 1, 0 },
#endif
...@@ -74,18 +74,8 @@ static struct pci_device_id pciidlist[] = { ...@@ -74,18 +74,8 @@ static struct pci_device_id pciidlist[] = {
mga_PCI_IDS mga_PCI_IDS
}; };
static drm_ioctl_desc_t ioctls[] = { extern drm_ioctl_desc_t mga_ioctls[];
[DRM_IOCTL_NR(DRM_MGA_INIT)] = { mga_dma_init, 1, 1 }, extern int mga_max_ioctl;
[DRM_IOCTL_NR(DRM_MGA_FLUSH)] = { mga_dma_flush, 1, 0 },
[DRM_IOCTL_NR(DRM_MGA_RESET)] = { mga_dma_reset, 1, 0 },
[DRM_IOCTL_NR(DRM_MGA_SWAP)] = { mga_dma_swap, 1, 0 },
[DRM_IOCTL_NR(DRM_MGA_CLEAR)] = { mga_dma_clear, 1, 0 },
[DRM_IOCTL_NR(DRM_MGA_VERTEX)] = { mga_dma_vertex, 1, 0 },
[DRM_IOCTL_NR(DRM_MGA_INDICES)] = { mga_dma_indices, 1, 0 },
[DRM_IOCTL_NR(DRM_MGA_ILOAD)] = { mga_dma_iload, 1, 0 },
[DRM_IOCTL_NR(DRM_MGA_BLIT)] = { mga_dma_blit, 1, 0 },
[DRM_IOCTL_NR(DRM_MGA_GETPARAM)]= { mga_getparam, 1, 0 },
};
static struct drm_driver driver = { static struct drm_driver driver = {
.driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
...@@ -101,8 +91,7 @@ static struct drm_driver driver = { ...@@ -101,8 +91,7 @@ static struct drm_driver driver = {
.get_reg_ofs = drm_core_get_reg_ofs, .get_reg_ofs = drm_core_get_reg_ofs,
.postinit = postinit, .postinit = postinit,
.version = version, .version = version,
.ioctls = ioctls, .ioctls = mga_ioctls,
.num_ioctls = DRM_ARRAY_SIZE(ioctls),
.dma_ioctl = mga_dma_buffers, .dma_ioctl = mga_dma_buffers,
.fops = { .fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
...@@ -121,6 +110,7 @@ static struct drm_driver driver = { ...@@ -121,6 +110,7 @@ static struct drm_driver driver = {
static int __init mga_init(void) static int __init mga_init(void)
{ {
driver.num_ioctls = mga_max_ioctl;
return drm_init(&driver); return drm_init(&driver);
} }
......
...@@ -37,6 +37,20 @@ ...@@ -37,6 +37,20 @@
#include "mga_drm.h" #include "mga_drm.h"
#include "mga_drv.h" #include "mga_drv.h"
drm_ioctl_desc_t mga_ioctls[] = {
[DRM_IOCTL_NR(DRM_MGA_INIT)] = { mga_dma_init, 1, 1 },
[DRM_IOCTL_NR(DRM_MGA_FLUSH)] = { mga_dma_flush, 1, 0 },
[DRM_IOCTL_NR(DRM_MGA_RESET)] = { mga_dma_reset, 1, 0 },
[DRM_IOCTL_NR(DRM_MGA_SWAP)] = { mga_dma_swap, 1, 0 },
[DRM_IOCTL_NR(DRM_MGA_CLEAR)] = { mga_dma_clear, 1, 0 },
[DRM_IOCTL_NR(DRM_MGA_VERTEX)] = { mga_dma_vertex, 1, 0 },
[DRM_IOCTL_NR(DRM_MGA_INDICES)] = { mga_dma_indices, 1, 0 },
[DRM_IOCTL_NR(DRM_MGA_ILOAD)] = { mga_dma_iload, 1, 0 },
[DRM_IOCTL_NR(DRM_MGA_BLIT)] = { mga_dma_blit, 1, 0 },
[DRM_IOCTL_NR(DRM_MGA_GETPARAM)]= { mga_getparam, 1, 0 },
};
int mga_max_ioctl = DRM_ARRAY_SIZE(mga_ioctls);
/* ================================================================ /* ================================================================
* DMA hardware state programming functions * DMA hardware state programming functions
......
/* r128.h -- ATI Rage 128 DRM template customization -*- linux-c -*-
* Created: Wed Feb 14 16:07:10 2001 by gareth@valinux.com
*
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* 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:
* Gareth Hughes <gareth@valinux.com>
*/
#ifndef __R128_H__
#define __R128_H__
/* This remains constant for all DRM template files.
*/
#define DRM(x) r128_##x
/* General customization:
*/
#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc."
#define DRIVER_NAME "r128"
#define DRIVER_DESC "ATI Rage 128"
#define DRIVER_DATE "20030725"
#define DRIVER_MAJOR 2
#define DRIVER_MINOR 5
#define DRIVER_PATCHLEVEL 0
/* Interface history:
*
* ?? - ??
* 2.4 - Add support for ycbcr textures (no new ioctls)
* 2.5 - Add FLIP ioctl, disable FULLSCREEN.
*/
#define DRIVER_IOCTLS \
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { r128_cce_buffers, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)] = { r128_cce_init, 1, 1 }, \
[DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_START)] = { r128_cce_start, 1, 1 }, \
[DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_STOP)] = { r128_cce_stop, 1, 1 }, \
[DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_RESET)] = { r128_cce_reset, 1, 1 }, \
[DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_IDLE)] = { r128_cce_idle, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)] = { r128_engine_reset, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_R128_FULLSCREEN)] = { r128_fullscreen, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_R128_SWAP)] = { r128_cce_swap, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_R128_FLIP)] = { r128_cce_flip, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_R128_CLEAR)] = { r128_cce_clear, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_cce_vertex, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)] = { r128_cce_indices, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)] = { r128_cce_blit, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_R128_DEPTH)] = { r128_cce_depth, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)] = { r128_cce_stipple, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_R128_INDIRECT)] = { r128_cce_indirect, 1, 1 }, \
[DRM_IOCTL_NR(DRM_IOCTL_R128_GETPARAM)] = { r128_getparam, 1, 0 },
#endif
...@@ -68,31 +68,8 @@ static struct pci_device_id pciidlist[] = { ...@@ -68,31 +68,8 @@ static struct pci_device_id pciidlist[] = {
r128_PCI_IDS r128_PCI_IDS
}; };
/* Interface history: extern drm_ioctl_desc_t r128_ioctls[];
* extern int r128_max_ioctl;
* ?? - ??
* 2.4 - Add support for ycbcr textures (no new ioctls)
* 2.5 - Add FLIP ioctl, disable FULLSCREEN.
*/
static drm_ioctl_desc_t ioctls[] = {
[DRM_IOCTL_NR(DRM_R128_INIT)] = { r128_cce_init, 1, 1 },
[DRM_IOCTL_NR(DRM_R128_CCE_START)] = { r128_cce_start, 1, 1 },
[DRM_IOCTL_NR(DRM_R128_CCE_STOP)] = { r128_cce_stop, 1, 1 },
[DRM_IOCTL_NR(DRM_R128_CCE_RESET)] = { r128_cce_reset, 1, 1 },
[DRM_IOCTL_NR(DRM_R128_CCE_IDLE)] = { r128_cce_idle, 1, 0 },
[DRM_IOCTL_NR(DRM_R128_RESET)] = { r128_engine_reset, 1, 0 },
[DRM_IOCTL_NR(DRM_R128_FULLSCREEN)] = { r128_fullscreen, 1, 0 },
[DRM_IOCTL_NR(DRM_R128_SWAP)] = { r128_cce_swap, 1, 0 },
[DRM_IOCTL_NR(DRM_R128_FLIP)] = { r128_cce_flip, 1, 0 },
[DRM_IOCTL_NR(DRM_R128_CLEAR)] = { r128_cce_clear, 1, 0 },
[DRM_IOCTL_NR(DRM_R128_VERTEX)] = { r128_cce_vertex, 1, 0 },
[DRM_IOCTL_NR(DRM_R128_INDICES)] = { r128_cce_indices, 1, 0 },
[DRM_IOCTL_NR(DRM_R128_BLIT)] = { r128_cce_blit, 1, 0 },
[DRM_IOCTL_NR(DRM_R128_DEPTH)] = { r128_cce_depth, 1, 0 },
[DRM_IOCTL_NR(DRM_R128_STIPPLE)] = { r128_cce_stipple, 1, 0 },
[DRM_IOCTL_NR(DRM_R128_INDIRECT)] = { r128_cce_indirect, 1, 1 },
[DRM_IOCTL_NR(DRM_R128_GETPARAM)] = { r128_getparam, 1, 0 },
};
static struct drm_driver driver = { static struct drm_driver driver = {
.driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
...@@ -109,8 +86,7 @@ static struct drm_driver driver = { ...@@ -109,8 +86,7 @@ static struct drm_driver driver = {
.get_reg_ofs = drm_core_get_reg_ofs, .get_reg_ofs = drm_core_get_reg_ofs,
.postinit = postinit, .postinit = postinit,
.version = version, .version = version,
.ioctls = ioctls, .ioctls = r128_ioctls,
.num_ioctls = DRM_ARRAY_SIZE(ioctls),
.dma_ioctl = r128_cce_buffers, .dma_ioctl = r128_cce_buffers,
.fops = { .fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
...@@ -129,6 +105,7 @@ static struct drm_driver driver = { ...@@ -129,6 +105,7 @@ static struct drm_driver driver = {
static int __init r128_init(void) static int __init r128_init(void)
{ {
driver.num_ioctls = r128_max_ioctl;
return drm_init(&driver); return drm_init(&driver);
} }
......
...@@ -42,6 +42,12 @@ ...@@ -42,6 +42,12 @@
#define DRIVER_DESC "ATI Rage 128" #define DRIVER_DESC "ATI Rage 128"
#define DRIVER_DATE "20030725" #define DRIVER_DATE "20030725"
/* Interface history:
*
* ?? - ??
* 2.4 - Add support for ycbcr textures (no new ioctls)
* 2.5 - Add FLIP ioctl, disable FULLSCREEN.
*/
#define DRIVER_MAJOR 2 #define DRIVER_MAJOR 2
#define DRIVER_MINOR 5 #define DRIVER_MINOR 5
#define DRIVER_PATCHLEVEL 0 #define DRIVER_PATCHLEVEL 0
......
...@@ -32,6 +32,27 @@ ...@@ -32,6 +32,27 @@
#include "r128_drm.h" #include "r128_drm.h"
#include "r128_drv.h" #include "r128_drv.h"
drm_ioctl_desc_t r128_ioctls[] = {
[DRM_IOCTL_NR(DRM_R128_INIT)] = { r128_cce_init, 1, 1 },
[DRM_IOCTL_NR(DRM_R128_CCE_START)] = { r128_cce_start, 1, 1 },
[DRM_IOCTL_NR(DRM_R128_CCE_STOP)] = { r128_cce_stop, 1, 1 },
[DRM_IOCTL_NR(DRM_R128_CCE_RESET)] = { r128_cce_reset, 1, 1 },
[DRM_IOCTL_NR(DRM_R128_CCE_IDLE)] = { r128_cce_idle, 1, 0 },
[DRM_IOCTL_NR(DRM_R128_RESET)] = { r128_engine_reset, 1, 0 },
[DRM_IOCTL_NR(DRM_R128_FULLSCREEN)] = { r128_fullscreen, 1, 0 },
[DRM_IOCTL_NR(DRM_R128_SWAP)] = { r128_cce_swap, 1, 0 },
[DRM_IOCTL_NR(DRM_R128_FLIP)] = { r128_cce_flip, 1, 0 },
[DRM_IOCTL_NR(DRM_R128_CLEAR)] = { r128_cce_clear, 1, 0 },
[DRM_IOCTL_NR(DRM_R128_VERTEX)] = { r128_cce_vertex, 1, 0 },
[DRM_IOCTL_NR(DRM_R128_INDICES)] = { r128_cce_indices, 1, 0 },
[DRM_IOCTL_NR(DRM_R128_BLIT)] = { r128_cce_blit, 1, 0 },
[DRM_IOCTL_NR(DRM_R128_DEPTH)] = { r128_cce_depth, 1, 0 },
[DRM_IOCTL_NR(DRM_R128_STIPPLE)] = { r128_cce_stipple, 1, 0 },
[DRM_IOCTL_NR(DRM_R128_INDIRECT)] = { r128_cce_indirect, 1, 1 },
[DRM_IOCTL_NR(DRM_R128_GETPARAM)] = { r128_getparam, 1, 0 },
};
int r128_max_ioctl = DRM_ARRAY_SIZE(r128_ioctls);
/* ================================================================ /* ================================================================
* CCE hardware state programming functions * CCE hardware state programming functions
......
/* radeon.h -- ATI Radeon DRM template customization -*- linux-c -*-
* Created: Wed Feb 14 17:07:34 2001 by gareth@valinux.com
*
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* 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:
* Gareth Hughes <gareth@valinux.com>
* Keith Whitwell <keith@tungstengraphics.com>
*/
#ifndef __RADEON_H__
#define __RADEON_H__
/* This remains constant for all DRM template files.
*/
#define DRM(x) radeon_##x
/* General customization:
*/
#define DRIVER_AUTHOR "Gareth Hughes, Keith Whitwell, others."
#define DRIVER_NAME "radeon"
#define DRIVER_DESC "ATI Radeon"
#define DRIVER_DATE "20020828"
#define DRIVER_MAJOR 1
#define DRIVER_MINOR 11
#define DRIVER_PATCHLEVEL 0
/* Interface history:
*
* 1.1 - ??
* 1.2 - Add vertex2 ioctl (keith)
* - Add stencil capability to clear ioctl (gareth, keith)
* - Increase MAX_TEXTURE_LEVELS (brian)
* 1.3 - Add cmdbuf ioctl (keith)
* - Add support for new radeon packets (keith)
* - Add getparam ioctl (keith)
* - Add flip-buffers ioctl, deprecate fullscreen foo (keith).
* 1.4 - Add scratch registers to get_param ioctl.
* 1.5 - Add r200 packets to cmdbuf ioctl
* - Add r200 function to init ioctl
* - Add 'scalar2' instruction to cmdbuf
* 1.6 - Add static GART memory manager
* Add irq handler (won't be turned on unless X server knows to)
* Add irq ioctls and irq_active getparam.
* Add wait command for cmdbuf ioctl
* Add GART offset query for getparam
* 1.7 - Add support for cube map registers: R200_PP_CUBIC_FACES_[0..5]
* and R200_PP_CUBIC_OFFSET_F1_[0..5].
* Added packets R200_EMIT_PP_CUBIC_FACES_[0..5] and
* R200_EMIT_PP_CUBIC_OFFSETS_[0..5]. (brian)
* 1.8 - Remove need to call cleanup ioctls on last client exit (keith)
* Add 'GET' queries for starting additional clients on different VT's.
* 1.9 - Add DRM_IOCTL_RADEON_CP_RESUME ioctl.
* Add texture rectangle support for r100.
* 1.10- Add SETPARAM ioctl; first parameter to set is FB_LOCATION, which
* clients use to tell the DRM where they think the framebuffer is
* located in the card's address space
* 1.11- Add packet R200_EMIT_RB3D_BLENDCOLOR to support GL_EXT_blend_color
* and GL_EXT_blend_[func|equation]_separate on r200
*/
#define DRIVER_IOCTLS \
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { radeon_cp_buffers, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_INIT)] = { radeon_cp_init, 1, 1 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_START)] = { radeon_cp_start, 1, 1 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_STOP)] = { radeon_cp_stop, 1, 1 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_RESET)] = { radeon_cp_reset, 1, 1 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_IDLE)] = { radeon_cp_idle, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_RESUME)] = { radeon_cp_resume, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_RESET)] = { radeon_engine_reset, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_FULLSCREEN)] = { radeon_fullscreen, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_SWAP)] = { radeon_cp_swap, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CLEAR)] = { radeon_cp_clear, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX)] = { radeon_cp_vertex, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDICES)] = { radeon_cp_indices, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_TEXTURE)] = { radeon_cp_texture, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_STIPPLE)] = { radeon_cp_stipple, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)] = { radeon_cp_indirect, 1, 1 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX2)] = { radeon_cp_vertex2, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CMDBUF)] = { radeon_cp_cmdbuf, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_GETPARAM)] = { radeon_cp_getparam, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_FLIP)] = { radeon_cp_flip, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_ALLOC)] = { radeon_mem_alloc, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_FREE)] = { radeon_mem_free, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_INIT_HEAP)] = { radeon_mem_init_heap, 1, 1 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_IRQ_EMIT)] = { radeon_irq_emit, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_IRQ_WAIT)] = { radeon_irq_wait, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_SETPARAM)] = { radeon_cp_setparam, 1, 0 }, \
#endif
...@@ -556,6 +556,264 @@ static u32 radeon_cp_microcode[][2] = { ...@@ -556,6 +556,264 @@ static u32 radeon_cp_microcode[][2] = {
{ 0000000000, 0000000000 }, { 0000000000, 0000000000 },
}; };
static u32 R300_cp_microcode[][2] = {
{ 0x4200e000, 0000000000 },
{ 0x4000e000, 0000000000 },
{ 0x000000af, 0x00000008 },
{ 0x000000b3, 0x00000008 },
{ 0x6c5a504f, 0000000000 },
{ 0x4f4f497a, 0000000000 },
{ 0x5a578288, 0000000000 },
{ 0x4f91906a, 0000000000 },
{ 0x4f4f4f4f, 0000000000 },
{ 0x4fe24f44, 0000000000 },
{ 0x4f9c9c9c, 0000000000 },
{ 0xdc4f4fde, 0000000000 },
{ 0xa1cd4f4f, 0000000000 },
{ 0xd29d9d9d, 0000000000 },
{ 0x4f0f9fd7, 0000000000 },
{ 0x000ca000, 0x00000004 },
{ 0x000d0012, 0x00000038 },
{ 0x0000e8b4, 0x00000004 },
{ 0x000d0014, 0x00000038 },
{ 0x0000e8b6, 0x00000004 },
{ 0x000d0016, 0x00000038 },
{ 0x0000e854, 0x00000004 },
{ 0x000d0018, 0x00000038 },
{ 0x0000e855, 0x00000004 },
{ 0x000d001a, 0x00000038 },
{ 0x0000e856, 0x00000004 },
{ 0x000d001c, 0x00000038 },
{ 0x0000e857, 0x00000004 },
{ 0x000d001e, 0x00000038 },
{ 0x0000e824, 0x00000004 },
{ 0x000d0020, 0x00000038 },
{ 0x0000e825, 0x00000004 },
{ 0x000d0022, 0x00000038 },
{ 0x0000e830, 0x00000004 },
{ 0x000d0024, 0x00000038 },
{ 0x0000f0c0, 0x00000004 },
{ 0x000d0026, 0x00000038 },
{ 0x0000f0c1, 0x00000004 },
{ 0x000d0028, 0x00000038 },
{ 0x0000f041, 0x00000004 },
{ 0x000d002a, 0x00000038 },
{ 0x0000f184, 0x00000004 },
{ 0x000d002c, 0x00000038 },
{ 0x0000f185, 0x00000004 },
{ 0x000d002e, 0x00000038 },
{ 0x0000f186, 0x00000004 },
{ 0x000d0030, 0x00000038 },
{ 0x0000f187, 0x00000004 },
{ 0x000d0032, 0x00000038 },
{ 0x0000f180, 0x00000004 },
{ 0x000d0034, 0x00000038 },
{ 0x0000f393, 0x00000004 },
{ 0x000d0036, 0x00000038 },
{ 0x0000f38a, 0x00000004 },
{ 0x000d0038, 0x00000038 },
{ 0x0000f38e, 0x00000004 },
{ 0x0000e821, 0x00000004 },
{ 0x0140a000, 0x00000004 },
{ 0x00000043, 0x00000018 },
{ 0x00cce800, 0x00000004 },
{ 0x001b0001, 0x00000004 },
{ 0x08004800, 0x00000004 },
{ 0x001b0001, 0x00000004 },
{ 0x08004800, 0x00000004 },
{ 0x001b0001, 0x00000004 },
{ 0x08004800, 0x00000004 },
{ 0x0000003a, 0x00000008 },
{ 0x0000a000, 0000000000 },
{ 0x02c0a000, 0x00000004 },
{ 0x000ca000, 0x00000004 },
{ 0x00130000, 0x00000004 },
{ 0x000c2000, 0x00000004 },
{ 0xc980c045, 0x00000008 },
{ 0x2000451d, 0x00000004 },
{ 0x0000e580, 0x00000004 },
{ 0x000ce581, 0x00000004 },
{ 0x08004580, 0x00000004 },
{ 0x000ce581, 0x00000004 },
{ 0x0000004c, 0x00000008 },
{ 0x0000a000, 0000000000 },
{ 0x000c2000, 0x00000004 },
{ 0x0000e50e, 0x00000004 },
{ 0x00032000, 0x00000004 },
{ 0x00022056, 0x00000028 },
{ 0x00000056, 0x00000024 },
{ 0x0800450f, 0x00000004 },
{ 0x0000a050, 0x00000008 },
{ 0x0000e565, 0x00000004 },
{ 0x0000e566, 0x00000004 },
{ 0x00000057, 0x00000008 },
{ 0x03cca5b4, 0x00000004 },
{ 0x05432000, 0x00000004 },
{ 0x00022000, 0x00000004 },
{ 0x4ccce063, 0x00000030 },
{ 0x08274565, 0x00000004 },
{ 0x00000063, 0x00000030 },
{ 0x08004564, 0x00000004 },
{ 0x0000e566, 0x00000004 },
{ 0x0000005a, 0x00000008 },
{ 0x00802066, 0x00000010 },
{ 0x00202000, 0x00000004 },
{ 0x001b00ff, 0x00000004 },
{ 0x01000069, 0x00000010 },
{ 0x001f2000, 0x00000004 },
{ 0x001c00ff, 0x00000004 },
{ 0000000000, 0x0000000c },
{ 0x00000085, 0x00000030 },
{ 0x0000005a, 0x00000008 },
{ 0x0000e576, 0x00000004 },
{ 0x000ca000, 0x00000004 },
{ 0x00012000, 0x00000004 },
{ 0x00082000, 0x00000004 },
{ 0x1800650e, 0x00000004 },
{ 0x00092000, 0x00000004 },
{ 0x000a2000, 0x00000004 },
{ 0x000f0000, 0x00000004 },
{ 0x00400000, 0x00000004 },
{ 0x00000079, 0x00000018 },
{ 0x0000e563, 0x00000004 },
{ 0x00c0e5f9, 0x000000c2 },
{ 0x0000006e, 0x00000008 },
{ 0x0000a06e, 0x00000008 },
{ 0x0000e576, 0x00000004 },
{ 0x0000e577, 0x00000004 },
{ 0x0000e50e, 0x00000004 },
{ 0x0000e50f, 0x00000004 },
{ 0x0140a000, 0x00000004 },
{ 0x0000007c, 0x00000018 },
{ 0x00c0e5f9, 0x000000c2 },
{ 0x0000007c, 0x00000008 },
{ 0x0014e50e, 0x00000004 },
{ 0x0040e50f, 0x00000004 },
{ 0x00c0007f, 0x00000008 },
{ 0x0000e570, 0x00000004 },
{ 0x0000e571, 0x00000004 },
{ 0x0000e572, 0x0000000c },
{ 0x0000a000, 0x00000004 },
{ 0x0140a000, 0x00000004 },
{ 0x0000e568, 0x00000004 },
{ 0x000c2000, 0x00000004 },
{ 0x00000089, 0x00000018 },
{ 0x000b0000, 0x00000004 },
{ 0x18c0e562, 0x00000004 },
{ 0x0000008b, 0x00000008 },
{ 0x00c0008a, 0x00000008 },
{ 0x000700e4, 0x00000004 },
{ 0x00000097, 0x00000038 },
{ 0x000ca099, 0x00000030 },
{ 0x080045bb, 0x00000004 },
{ 0x000c209a, 0x00000030 },
{ 0x0800e5bc, 0000000000 },
{ 0x0000e5bb, 0x00000004 },
{ 0x0000e5bc, 0000000000 },
{ 0x00120000, 0x0000000c },
{ 0x00120000, 0x00000004 },
{ 0x001b0002, 0x0000000c },
{ 0x0000a000, 0x00000004 },
{ 0x0000e821, 0x00000004 },
{ 0x0000e800, 0000000000 },
{ 0x0000e821, 0x00000004 },
{ 0x0000e82e, 0000000000 },
{ 0x02cca000, 0x00000004 },
{ 0x00140000, 0x00000004 },
{ 0x000ce1cc, 0x00000004 },
{ 0x050de1cd, 0x00000004 },
{ 0x000000a7, 0x00000020 },
{ 0x4200e000, 0000000000 },
{ 0x000000ae, 0x00000038 },
{ 0x000ca000, 0x00000004 },
{ 0x00140000, 0x00000004 },
{ 0x000c2000, 0x00000004 },
{ 0x00160000, 0x00000004 },
{ 0x700ce000, 0x00000004 },
{ 0x001400aa, 0x00000008 },
{ 0x4000e000, 0000000000 },
{ 0x02400000, 0x00000004 },
{ 0x400ee000, 0x00000004 },
{ 0x02400000, 0x00000004 },
{ 0x4000e000, 0000000000 },
{ 0x000c2000, 0x00000004 },
{ 0x0240e51b, 0x00000004 },
{ 0x0080e50a, 0x00000005 },
{ 0x0080e50b, 0x00000005 },
{ 0x00220000, 0x00000004 },
{ 0x000700e4, 0x00000004 },
{ 0x000000c1, 0x00000038 },
{ 0x000c209a, 0x00000030 },
{ 0x0880e5bd, 0x00000005 },
{ 0x000c2099, 0x00000030 },
{ 0x0800e5bb, 0x00000005 },
{ 0x000c209a, 0x00000030 },
{ 0x0880e5bc, 0x00000005 },
{ 0x000000c4, 0x00000008 },
{ 0x0080e5bd, 0x00000005 },
{ 0x0000e5bb, 0x00000005 },
{ 0x0080e5bc, 0x00000005 },
{ 0x00210000, 0x00000004 },
{ 0x02800000, 0x00000004 },
{ 0x00c000c8, 0x00000018 },
{ 0x4180e000, 0x00000040 },
{ 0x000000ca, 0x00000024 },
{ 0x01000000, 0x0000000c },
{ 0x0100e51d, 0x0000000c },
{ 0x000045bb, 0x00000004 },
{ 0x000080c4, 0x00000008 },
{ 0x0000f3ce, 0x00000004 },
{ 0x0140a000, 0x00000004 },
{ 0x00cc2000, 0x00000004 },
{ 0x08c053cf, 0x00000040 },
{ 0x00008000, 0000000000 },
{ 0x0000f3d2, 0x00000004 },
{ 0x0140a000, 0x00000004 },
{ 0x00cc2000, 0x00000004 },
{ 0x08c053d3, 0x00000040 },
{ 0x00008000, 0000000000 },
{ 0x0000f39d, 0x00000004 },
{ 0x0140a000, 0x00000004 },
{ 0x00cc2000, 0x00000004 },
{ 0x08c0539e, 0x00000040 },
{ 0x00008000, 0000000000 },
{ 0x03c00830, 0x00000004 },
{ 0x4200e000, 0000000000 },
{ 0x0000a000, 0x00000004 },
{ 0x200045e0, 0x00000004 },
{ 0x0000e5e1, 0000000000 },
{ 0x00000001, 0000000000 },
{ 0x000700e1, 0x00000004 },
{ 0x0800e394, 0000000000 },
{ 0000000000, 0000000000 },
{ 0000000000, 0000000000 },
{ 0000000000, 0000000000 },
{ 0000000000, 0000000000 },
{ 0000000000, 0000000000 },
{ 0000000000, 0000000000 },
{ 0000000000, 0000000000 },
{ 0000000000, 0000000000 },
{ 0000000000, 0000000000 },
{ 0000000000, 0000000000 },
{ 0000000000, 0000000000 },
{ 0000000000, 0000000000 },
{ 0000000000, 0000000000 },
{ 0000000000, 0000000000 },
{ 0000000000, 0000000000 },
{ 0000000000, 0000000000 },
{ 0000000000, 0000000000 },
{ 0000000000, 0000000000 },
{ 0000000000, 0000000000 },
{ 0000000000, 0000000000 },
{ 0000000000, 0000000000 },
{ 0000000000, 0000000000 },
{ 0000000000, 0000000000 },
{ 0000000000, 0000000000 },
{ 0000000000, 0000000000 },
{ 0000000000, 0000000000 },
{ 0000000000, 0000000000 },
{ 0000000000, 0000000000 },
};
int RADEON_READ_PLL(drm_device_t *dev, int addr) int RADEON_READ_PLL(drm_device_t *dev, int addr)
{ {
...@@ -680,8 +938,7 @@ static void radeon_cp_load_microcode( drm_radeon_private_t *dev_priv ) ...@@ -680,8 +938,7 @@ static void radeon_cp_load_microcode( drm_radeon_private_t *dev_priv )
RADEON_WRITE( RADEON_CP_ME_RAM_ADDR, 0 ); RADEON_WRITE( RADEON_CP_ME_RAM_ADDR, 0 );
if (dev_priv->is_r200) if (dev_priv->microcode_version==UCODE_R200) {
{
DRM_INFO("Loading R200 Microcode\n"); DRM_INFO("Loading R200 Microcode\n");
for ( i = 0 ; i < 256 ; i++ ) for ( i = 0 ; i < 256 ; i++ )
{ {
...@@ -690,9 +947,16 @@ static void radeon_cp_load_microcode( drm_radeon_private_t *dev_priv ) ...@@ -690,9 +947,16 @@ static void radeon_cp_load_microcode( drm_radeon_private_t *dev_priv )
RADEON_WRITE( RADEON_CP_ME_RAM_DATAL, RADEON_WRITE( RADEON_CP_ME_RAM_DATAL,
R200_cp_microcode[i][0] ); R200_cp_microcode[i][0] );
} }
} } else if (dev_priv->microcode_version==UCODE_R300) {
else DRM_INFO("Loading R300 Microcode\n");
for ( i = 0 ; i < 256 ; i++ )
{ {
RADEON_WRITE( RADEON_CP_ME_RAM_DATAH,
R300_cp_microcode[i][1] );
RADEON_WRITE( RADEON_CP_ME_RAM_DATAL,
R300_cp_microcode[i][0] );
}
} else {
for ( i = 0 ; i < 256 ; i++ ) { for ( i = 0 ; i < 256 ; i++ ) {
RADEON_WRITE( RADEON_CP_ME_RAM_DATAH, RADEON_WRITE( RADEON_CP_ME_RAM_DATAH,
radeon_cp_microcode[i][1] ); radeon_cp_microcode[i][1] );
...@@ -1002,15 +1266,9 @@ static void radeon_set_pcigart( drm_radeon_private_t *dev_priv, int on ) ...@@ -1002,15 +1266,9 @@ static void radeon_set_pcigart( drm_radeon_private_t *dev_priv, int on )
static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
{ {
drm_radeon_private_t *dev_priv; drm_radeon_private_t *dev_priv = dev->dev_private;;
DRM_DEBUG( "\n" ); DRM_DEBUG( "\n" );
dev_priv = drm_alloc( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER );
if ( dev_priv == NULL )
return DRM_ERR(ENOMEM);
memset( dev_priv, 0, sizeof(drm_radeon_private_t) );
dev_priv->is_pci = init->is_pci; dev_priv->is_pci = init->is_pci;
if ( dev_priv->is_pci && !dev->sg ) { if ( dev_priv->is_pci && !dev->sg ) {
...@@ -1029,7 +1287,17 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) ...@@ -1029,7 +1287,17 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
return DRM_ERR(EINVAL); return DRM_ERR(EINVAL);
} }
dev_priv->is_r200 = (init->func == RADEON_INIT_R200_CP); switch(init->func) {
case RADEON_INIT_R200_CP:
dev_priv->microcode_version=UCODE_R200;
break;
case RADEON_INIT_R300_CP:
dev_priv->microcode_version=UCODE_R300;
break;
default:
dev_priv->microcode_version=UCODE_R100;
}
dev_priv->do_boxes = 0; dev_priv->do_boxes = 0;
dev_priv->cp_mode = init->cp_mode; dev_priv->cp_mode = init->cp_mode;
...@@ -1078,7 +1346,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) ...@@ -1078,7 +1346,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
*/ */
dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE | dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE |
(dev_priv->color_fmt << 10) | (dev_priv->color_fmt << 10) |
(1<<15)); (dev_priv->microcode_version == UCODE_R100 ? RADEON_ZBLOCK16 : 0));
dev_priv->depth_clear.rb3d_zstencilcntl = dev_priv->depth_clear.rb3d_zstencilcntl =
(dev_priv->depth_fmt | (dev_priv->depth_fmt |
...@@ -1272,6 +1540,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) ...@@ -1272,6 +1540,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
int radeon_do_cleanup_cp( drm_device_t *dev ) int radeon_do_cleanup_cp( drm_device_t *dev )
{ {
drm_radeon_private_t *dev_priv = dev->dev_private;
DRM_DEBUG( "\n" ); DRM_DEBUG( "\n" );
/* Make sure interrupts are disabled here because the uninstall ioctl /* Make sure interrupts are disabled here because the uninstall ioctl
...@@ -1280,9 +1549,6 @@ int radeon_do_cleanup_cp( drm_device_t *dev ) ...@@ -1280,9 +1549,6 @@ int radeon_do_cleanup_cp( drm_device_t *dev )
*/ */
if ( dev->irq_enabled ) drm_irq_uninstall(dev); if ( dev->irq_enabled ) drm_irq_uninstall(dev);
if ( dev->dev_private ) {
drm_radeon_private_t *dev_priv = dev->dev_private;
#if __OS_HAS_AGP #if __OS_HAS_AGP
if ( !dev_priv->is_pci ) { if ( !dev_priv->is_pci ) {
if ( dev_priv->cp_ring != NULL ) if ( dev_priv->cp_ring != NULL )
...@@ -1290,7 +1556,10 @@ int radeon_do_cleanup_cp( drm_device_t *dev ) ...@@ -1290,7 +1556,10 @@ int radeon_do_cleanup_cp( drm_device_t *dev )
if ( dev_priv->ring_rptr != NULL ) if ( dev_priv->ring_rptr != NULL )
drm_core_ioremapfree( dev_priv->ring_rptr, dev ); drm_core_ioremapfree( dev_priv->ring_rptr, dev );
if ( dev->agp_buffer_map != NULL ) if ( dev->agp_buffer_map != NULL )
{
drm_core_ioremapfree( dev->agp_buffer_map, dev ); drm_core_ioremapfree( dev->agp_buffer_map, dev );
dev->agp_buffer_map = NULL;
}
} else } else
#endif #endif
{ {
...@@ -1300,10 +1569,8 @@ int radeon_do_cleanup_cp( drm_device_t *dev ) ...@@ -1300,10 +1569,8 @@ int radeon_do_cleanup_cp( drm_device_t *dev )
DRM_ERROR( "failed to cleanup PCI GART!\n" ); DRM_ERROR( "failed to cleanup PCI GART!\n" );
} }
drm_free( dev->dev_private, sizeof(drm_radeon_private_t), /* only clear to the start of flags */
DRM_MEM_DRIVER ); memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags));
dev->dev_private = NULL;
}
return 0; return 0;
} }
...@@ -1360,6 +1627,7 @@ int radeon_cp_init( DRM_IOCTL_ARGS ) ...@@ -1360,6 +1627,7 @@ int radeon_cp_init( DRM_IOCTL_ARGS )
switch ( init.func ) { switch ( init.func ) {
case RADEON_INIT_CP: case RADEON_INIT_CP:
case RADEON_INIT_R200_CP: case RADEON_INIT_R200_CP:
case RADEON_INIT_R300_CP:
return radeon_do_init_cp( dev, &init ); return radeon_do_init_cp( dev, &init );
case RADEON_CLEANUP_CP: case RADEON_CLEANUP_CP:
return radeon_do_cleanup_cp( dev ); return radeon_do_cleanup_cp( dev );
...@@ -1440,7 +1708,7 @@ int radeon_cp_stop( DRM_IOCTL_ARGS ) ...@@ -1440,7 +1708,7 @@ int radeon_cp_stop( DRM_IOCTL_ARGS )
void radeon_do_release( drm_device_t *dev ) void radeon_do_release( drm_device_t *dev )
{ {
drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_private_t *dev_priv = dev->dev_private;
int ret; int i, ret;
if (dev_priv) { if (dev_priv) {
if (dev_priv->cp_running) { if (dev_priv->cp_running) {
...@@ -1458,8 +1726,17 @@ void radeon_do_release( drm_device_t *dev ) ...@@ -1458,8 +1726,17 @@ void radeon_do_release( drm_device_t *dev )
} }
/* Disable *all* interrupts */ /* Disable *all* interrupts */
if (dev_priv->mmio) /* remove this after permanent addmaps */
RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 ); RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 );
if (dev_priv->mmio) {/* remove all surfaces */
for (i = 0; i < RADEON_MAX_SURFACES; i++) {
RADEON_WRITE(RADEON_SURFACE0_INFO + 16*i, 0);
RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16*i, 0);
RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16*i, 0);
}
}
/* Free memory heap structures */ /* Free memory heap structures */
radeon_mem_takedown( &(dev_priv->gart_heap) ); radeon_mem_takedown( &(dev_priv->gart_heap) );
radeon_mem_takedown( &(dev_priv->fb_heap) ); radeon_mem_takedown( &(dev_priv->fb_heap) );
...@@ -1742,3 +2019,42 @@ int radeon_cp_buffers( DRM_IOCTL_ARGS ) ...@@ -1742,3 +2019,42 @@ int radeon_cp_buffers( DRM_IOCTL_ARGS )
return ret; return ret;
} }
int radeon_driver_preinit(struct drm_device *dev, unsigned long flags)
{
drm_radeon_private_t *dev_priv;
int ret = 0;
dev_priv = drm_alloc(sizeof(drm_radeon_private_t), DRM_MEM_DRIVER);
if (dev_priv == NULL)
return DRM_ERR(ENOMEM);
memset(dev_priv, 0, sizeof(drm_radeon_private_t));
dev->dev_private = (void *)dev_priv;
dev_priv->flags = flags;
switch (flags & CHIP_FAMILY_MASK) {
case CHIP_R100:
case CHIP_RV200:
case CHIP_R200:
case CHIP_R300:
dev_priv->flags |= CHIP_HAS_HIERZ;
break;
default:
/* all other chips have no hierarchical z buffer */
break;
}
return ret;
}
int radeon_driver_postcleanup(struct drm_device *dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
DRM_DEBUG("\n");
drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
dev->dev_private = NULL;
return 0;
}
...@@ -145,7 +145,8 @@ ...@@ -145,7 +145,8 @@
#define RADEON_EMIT_PP_TEX_SIZE_1 74 #define RADEON_EMIT_PP_TEX_SIZE_1 74
#define RADEON_EMIT_PP_TEX_SIZE_2 75 #define RADEON_EMIT_PP_TEX_SIZE_2 75
#define R200_EMIT_RB3D_BLENDCOLOR 76 #define R200_EMIT_RB3D_BLENDCOLOR 76
#define RADEON_MAX_STATE_PACKETS 77 #define R200_EMIT_TCL_POINT_SPRITE_CNTL 77
#define RADEON_MAX_STATE_PACKETS 78
/* Commands understood by cmd_buffer ioctl. More can be added but /* Commands understood by cmd_buffer ioctl. More can be added but
...@@ -193,6 +194,9 @@ typedef union { ...@@ -193,6 +194,9 @@ typedef union {
#define RADEON_BACK 0x2 #define RADEON_BACK 0x2
#define RADEON_DEPTH 0x4 #define RADEON_DEPTH 0x4
#define RADEON_STENCIL 0x8 #define RADEON_STENCIL 0x8
#define RADEON_CLEAR_FASTZ 0x80000000
#define RADEON_USE_HIERZ 0x40000000
#define RADEON_USE_COMP_ZBUF 0x20000000
/* Primitive types /* Primitive types
*/ */
...@@ -227,6 +231,8 @@ typedef union { ...@@ -227,6 +231,8 @@ typedef union {
#define RADEON_MAX_TEXTURE_LEVELS 12 #define RADEON_MAX_TEXTURE_LEVELS 12
#define RADEON_MAX_TEXTURE_UNITS 3 #define RADEON_MAX_TEXTURE_UNITS 3
#define RADEON_MAX_SURFACES 8
/* Blits have strict offset rules. All blit offset must be aligned on /* Blits have strict offset rules. All blit offset must be aligned on
* a 1K-byte boundary. * a 1K-byte boundary.
*/ */
...@@ -361,6 +367,7 @@ typedef struct { ...@@ -361,6 +367,7 @@ typedef struct {
int pfState; /* number of 3d windows (0,1,2ormore) */ int pfState; /* number of 3d windows (0,1,2ormore) */
int pfCurrentPage; /* which buffer is being displayed? */ int pfCurrentPage; /* which buffer is being displayed? */
int crtc2_base; /* CRTC2 frame offset */ int crtc2_base; /* CRTC2 frame offset */
int tiling_enabled; /* set by drm, read by 2d + 3d clients */
} drm_radeon_sarea_t; } drm_radeon_sarea_t;
...@@ -399,6 +406,8 @@ typedef struct { ...@@ -399,6 +406,8 @@ typedef struct {
#define DRM_RADEON_IRQ_WAIT 0x17 #define DRM_RADEON_IRQ_WAIT 0x17
#define DRM_RADEON_CP_RESUME 0x18 #define DRM_RADEON_CP_RESUME 0x18
#define DRM_RADEON_SETPARAM 0x19 #define DRM_RADEON_SETPARAM 0x19
#define DRM_RADEON_SURF_ALLOC 0x1a
#define DRM_RADEON_SURF_FREE 0x1b
#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t) #define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t)
#define DRM_IOCTL_RADEON_CP_START DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_START) #define DRM_IOCTL_RADEON_CP_START DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_START)
...@@ -425,12 +434,15 @@ typedef struct { ...@@ -425,12 +434,15 @@ typedef struct {
#define DRM_IOCTL_RADEON_IRQ_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_IRQ_WAIT, drm_radeon_irq_wait_t) #define DRM_IOCTL_RADEON_IRQ_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_IRQ_WAIT, drm_radeon_irq_wait_t)
#define DRM_IOCTL_RADEON_CP_RESUME DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_RESUME) #define DRM_IOCTL_RADEON_CP_RESUME DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_RESUME)
#define DRM_IOCTL_RADEON_SETPARAM DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SETPARAM, drm_radeon_setparam_t) #define DRM_IOCTL_RADEON_SETPARAM DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SETPARAM, drm_radeon_setparam_t)
#define DRM_IOCTL_RADEON_SURF_ALLOC DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_ALLOC, drm_radeon_surface_alloc_t)
#define DRM_IOCTL_RADEON_SURF_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_FREE, drm_radeon_surface_free_t)
typedef struct drm_radeon_init { typedef struct drm_radeon_init {
enum { enum {
RADEON_INIT_CP = 0x01, RADEON_INIT_CP = 0x01,
RADEON_CLEANUP_CP = 0x02, RADEON_CLEANUP_CP = 0x02,
RADEON_INIT_R200_CP = 0x03 RADEON_INIT_R200_CP = 0x03,
RADEON_INIT_R300_CP = 0x04
} func; } func;
unsigned long sarea_priv_offset; unsigned long sarea_priv_offset;
int is_pci; int is_pci;
...@@ -624,6 +636,18 @@ typedef struct drm_radeon_setparam { ...@@ -624,6 +636,18 @@ typedef struct drm_radeon_setparam {
} drm_radeon_setparam_t; } drm_radeon_setparam_t;
#define RADEON_SETPARAM_FB_LOCATION 1 /* determined framebuffer location */ #define RADEON_SETPARAM_FB_LOCATION 1 /* determined framebuffer location */
#define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */
/* 1.14: Clients can allocate/free a surface
*/
typedef struct drm_radeon_surface_alloc {
unsigned int address;
unsigned int size;
unsigned int flags;
} drm_radeon_surface_alloc_t;
typedef struct drm_radeon_surface_free {
unsigned int address;
} drm_radeon_surface_free_t;
#endif #endif
...@@ -69,70 +69,14 @@ static struct pci_device_id pciidlist[] = { ...@@ -69,70 +69,14 @@ static struct pci_device_id pciidlist[] = {
radeon_PCI_IDS radeon_PCI_IDS
}; };
/* Interface history: extern drm_ioctl_desc_t radeon_ioctls[];
* extern int radeon_max_ioctl;
* 1.1 - ??
* 1.2 - Add vertex2 ioctl (keith)
* - Add stencil capability to clear ioctl (gareth, keith)
* - Increase MAX_TEXTURE_LEVELS (brian)
* 1.3 - Add cmdbuf ioctl (keith)
* - Add support for new radeon packets (keith)
* - Add getparam ioctl (keith)
* - Add flip-buffers ioctl, deprecate fullscreen foo (keith).
* 1.4 - Add scratch registers to get_param ioctl.
* 1.5 - Add r200 packets to cmdbuf ioctl
* - Add r200 function to init ioctl
* - Add 'scalar2' instruction to cmdbuf
* 1.6 - Add static GART memory manager
* Add irq handler (won't be turned on unless X server knows to)
* Add irq ioctls and irq_active getparam.
* Add wait command for cmdbuf ioctl
* Add GART offset query for getparam
* 1.7 - Add support for cube map registers: R200_PP_CUBIC_FACES_[0..5]
* and R200_PP_CUBIC_OFFSET_F1_[0..5].
* Added packets R200_EMIT_PP_CUBIC_FACES_[0..5] and
* R200_EMIT_PP_CUBIC_OFFSETS_[0..5]. (brian)
* 1.8 - Remove need to call cleanup ioctls on last client exit (keith)
* Add 'GET' queries for starting additional clients on different VT's.
* 1.9 - Add DRM_IOCTL_RADEON_CP_RESUME ioctl.
* Add texture rectangle support for r100.
* 1.10- Add SETPARAM ioctl; first parameter to set is FB_LOCATION, which
* clients use to tell the DRM where they think the framebuffer is
* located in the card's address space
* 1.11- Add packet R200_EMIT_RB3D_BLENDCOLOR to support GL_EXT_blend_color
* and GL_EXT_blend_[func|equation]_separate on r200
*/
static drm_ioctl_desc_t ioctls[] = {
[DRM_IOCTL_NR(DRM_RADEON_CP_INIT)] = { radeon_cp_init, 1, 1 },
[DRM_IOCTL_NR(DRM_RADEON_CP_START)] = { radeon_cp_start, 1, 1 },
[DRM_IOCTL_NR(DRM_RADEON_CP_STOP)] = { radeon_cp_stop, 1, 1 },
[DRM_IOCTL_NR(DRM_RADEON_CP_RESET)] = { radeon_cp_reset, 1, 1 },
[DRM_IOCTL_NR(DRM_RADEON_CP_IDLE)] = { radeon_cp_idle, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_CP_RESUME)] = { radeon_cp_resume, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_RESET)] = { radeon_engine_reset, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_FULLSCREEN)] = { radeon_fullscreen, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_SWAP)] = { radeon_cp_swap, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_CLEAR)] = { radeon_cp_clear, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_VERTEX)] = { radeon_cp_vertex, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_INDICES)] = { radeon_cp_indices, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_TEXTURE)] = { radeon_cp_texture, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_STIPPLE)] = { radeon_cp_stipple, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_INDIRECT)] = { radeon_cp_indirect, 1, 1 },
[DRM_IOCTL_NR(DRM_RADEON_VERTEX2)] = { radeon_cp_vertex2, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_CMDBUF)] = { radeon_cp_cmdbuf, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_GETPARAM)] = { radeon_cp_getparam, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_FLIP)] = { radeon_cp_flip, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_ALLOC)] = { radeon_mem_alloc, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_FREE)] = { radeon_mem_free, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_INIT_HEAP)] = { radeon_mem_init_heap,1, 1 },
[DRM_IOCTL_NR(DRM_RADEON_IRQ_EMIT)] = { radeon_irq_emit, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_IRQ_WAIT)] = { radeon_irq_wait, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_SETPARAM)] = { radeon_cp_setparam, 1, 0 },
};
static struct drm_driver driver = { static struct drm_driver driver = {
.driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
.dev_priv_size = sizeof(drm_radeon_buf_priv_t), .dev_priv_size = sizeof(drm_radeon_buf_priv_t),
.preinit = radeon_driver_preinit,
.postcleanup = radeon_driver_postcleanup,
.prerelease = radeon_driver_prerelease, .prerelease = radeon_driver_prerelease,
.pretakedown = radeon_driver_pretakedown, .pretakedown = radeon_driver_pretakedown,
.open_helper = radeon_driver_open_helper, .open_helper = radeon_driver_open_helper,
...@@ -147,8 +91,7 @@ static struct drm_driver driver = { ...@@ -147,8 +91,7 @@ static struct drm_driver driver = {
.get_reg_ofs = drm_core_get_reg_ofs, .get_reg_ofs = drm_core_get_reg_ofs,
.postinit = postinit, .postinit = postinit,
.version = version, .version = version,
.ioctls = ioctls, .ioctls = radeon_ioctls,
.num_ioctls = DRM_ARRAY_SIZE(ioctls),
.dma_ioctl = radeon_cp_buffers, .dma_ioctl = radeon_cp_buffers,
.fops = { .fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
...@@ -167,6 +110,7 @@ static struct drm_driver driver = { ...@@ -167,6 +110,7 @@ static struct drm_driver driver = {
static int __init radeon_init(void) static int __init radeon_init(void)
{ {
driver.num_ioctls = radeon_max_ioctl;
return drm_init(&driver); return drm_init(&driver);
} }
......
...@@ -38,15 +38,93 @@ ...@@ -38,15 +38,93 @@
#define DRIVER_NAME "radeon" #define DRIVER_NAME "radeon"
#define DRIVER_DESC "ATI Radeon" #define DRIVER_DESC "ATI Radeon"
#define DRIVER_DATE "20020828" #define DRIVER_DATE "20050125"
/* Interface history:
*
* 1.1 - ??
* 1.2 - Add vertex2 ioctl (keith)
* - Add stencil capability to clear ioctl (gareth, keith)
* - Increase MAX_TEXTURE_LEVELS (brian)
* 1.3 - Add cmdbuf ioctl (keith)
* - Add support for new radeon packets (keith)
* - Add getparam ioctl (keith)
* - Add flip-buffers ioctl, deprecate fullscreen foo (keith).
* 1.4 - Add scratch registers to get_param ioctl.
* 1.5 - Add r200 packets to cmdbuf ioctl
* - Add r200 function to init ioctl
* - Add 'scalar2' instruction to cmdbuf
* 1.6 - Add static GART memory manager
* Add irq handler (won't be turned on unless X server knows to)
* Add irq ioctls and irq_active getparam.
* Add wait command for cmdbuf ioctl
* Add GART offset query for getparam
* 1.7 - Add support for cube map registers: R200_PP_CUBIC_FACES_[0..5]
* and R200_PP_CUBIC_OFFSET_F1_[0..5].
* Added packets R200_EMIT_PP_CUBIC_FACES_[0..5] and
* R200_EMIT_PP_CUBIC_OFFSETS_[0..5]. (brian)
* 1.8 - Remove need to call cleanup ioctls on last client exit (keith)
* Add 'GET' queries for starting additional clients on different VT's.
* 1.9 - Add DRM_IOCTL_RADEON_CP_RESUME ioctl.
* Add texture rectangle support for r100.
* 1.10- Add SETPARAM ioctl; first parameter to set is FB_LOCATION, which
* clients use to tell the DRM where they think the framebuffer is
* located in the card's address space
* 1.11- Add packet R200_EMIT_RB3D_BLENDCOLOR to support GL_EXT_blend_color
* and GL_EXT_blend_[func|equation]_separate on r200
* 1.12- Add R300 CP microcode support - this just loads the CP on r300
* (No 3D support yet - just microcode loading)
* 1.13- Add packet R200_EMIT_TCL_POINT_SPRITE_CNTL for ARB_point_parameters
* - Add hyperz support, add hyperz flags to clear ioctl.
* 1.14- Add support for color tiling
* - Add R100/R200 surface allocation/free support
*/
#define DRIVER_MAJOR 1 #define DRIVER_MAJOR 1
#define DRIVER_MINOR 11 #define DRIVER_MINOR 14
#define DRIVER_PATCHLEVEL 0 #define DRIVER_PATCHLEVEL 0
#define GET_RING_HEAD(dev_priv) DRM_READ32( (dev_priv)->ring_rptr, 0 ) #define GET_RING_HEAD(dev_priv) DRM_READ32( (dev_priv)->ring_rptr, 0 )
#define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) ) #define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) )
/*
* Radeon chip families
*/
enum radeon_family {
CHIP_R100,
CHIP_RS100,
CHIP_RV100,
CHIP_R200,
CHIP_RV200,
CHIP_RS200,
CHIP_R250,
CHIP_RS250,
CHIP_RV250,
CHIP_RV280,
CHIP_R300,
CHIP_RS300,
CHIP_RV350,
CHIP_LAST,
};
enum radeon_cp_microcode_version {
UCODE_R100,
UCODE_R200,
UCODE_R300,
};
/*
* Chip flags
*/
enum radeon_chip_flags {
CHIP_FAMILY_MASK = 0x0000ffffUL,
CHIP_FLAGS_MASK = 0xffff0000UL,
CHIP_IS_MOBILITY = 0x00010000UL,
CHIP_IS_IGP = 0x00020000UL,
CHIP_SINGLE_CRTC = 0x00040000UL,
CHIP_IS_AGP = 0x00080000UL,
CHIP_HAS_HIERZ = 0x00100000UL,
};
typedef struct drm_radeon_freelist { typedef struct drm_radeon_freelist {
unsigned int age; unsigned int age;
drm_buf_t *buf; drm_buf_t *buf;
...@@ -85,6 +163,21 @@ struct mem_block { ...@@ -85,6 +163,21 @@ struct mem_block {
DRMFILE filp; /* 0: free, -1: heap, other: real files */ DRMFILE filp; /* 0: free, -1: heap, other: real files */
}; };
struct radeon_surface {
int refcount;
u32 lower;
u32 upper;
u32 flags;
};
struct radeon_virt_surface {
int surface_index;
u32 lower;
u32 upper;
u32 flags;
DRMFILE filp;
};
typedef struct drm_radeon_private { typedef struct drm_radeon_private {
drm_radeon_ring_buffer_t ring; drm_radeon_ring_buffer_t ring;
drm_radeon_sarea_t *sarea_priv; drm_radeon_sarea_t *sarea_priv;
...@@ -106,7 +199,7 @@ typedef struct drm_radeon_private { ...@@ -106,7 +199,7 @@ typedef struct drm_radeon_private {
int usec_timeout; int usec_timeout;
int is_r200; int microcode_version;
int is_pci; int is_pci;
unsigned long phys_pci_gart; unsigned long phys_pci_gart;
...@@ -163,6 +256,11 @@ typedef struct drm_radeon_private { ...@@ -163,6 +256,11 @@ typedef struct drm_radeon_private {
wait_queue_head_t swi_queue; wait_queue_head_t swi_queue;
atomic_t swi_emitted; atomic_t swi_emitted;
struct radeon_surface surfaces[RADEON_MAX_SURFACES];
struct radeon_virt_surface virt_surfaces[2*RADEON_MAX_SURFACES];
/* starting from here on, data is preserved accross an open */
uint32_t flags; /* see radeon_chip_flags */
} drm_radeon_private_t; } drm_radeon_private_t;
typedef struct drm_radeon_buf_priv { typedef struct drm_radeon_buf_priv {
...@@ -189,6 +287,9 @@ extern int radeon_do_cp_idle( drm_radeon_private_t *dev_priv ); ...@@ -189,6 +287,9 @@ extern int radeon_do_cp_idle( drm_radeon_private_t *dev_priv );
extern int radeon_do_cleanup_cp( drm_device_t *dev ); extern int radeon_do_cleanup_cp( drm_device_t *dev );
extern int radeon_do_cleanup_pageflip( drm_device_t *dev ); extern int radeon_do_cleanup_pageflip( drm_device_t *dev );
extern int radeon_driver_preinit(struct drm_device *dev, unsigned long flags);
extern int radeon_driver_postcleanup(struct drm_device *dev);
/* radeon_state.c */ /* radeon_state.c */
extern int radeon_cp_clear( DRM_IOCTL_ARGS ); extern int radeon_cp_clear( DRM_IOCTL_ARGS );
extern int radeon_cp_swap( DRM_IOCTL_ARGS ); extern int radeon_cp_swap( DRM_IOCTL_ARGS );
...@@ -208,6 +309,8 @@ extern int radeon_mem_free( DRM_IOCTL_ARGS ); ...@@ -208,6 +309,8 @@ extern int radeon_mem_free( DRM_IOCTL_ARGS );
extern int radeon_mem_init_heap( DRM_IOCTL_ARGS ); extern int radeon_mem_init_heap( DRM_IOCTL_ARGS );
extern void radeon_mem_takedown( struct mem_block **heap ); extern void radeon_mem_takedown( struct mem_block **heap );
extern void radeon_mem_release( DRMFILE filp, struct mem_block *heap ); extern void radeon_mem_release( DRMFILE filp, struct mem_block *heap );
extern int radeon_surface_alloc(DRM_IOCTL_ARGS);
extern int radeon_surface_free(DRM_IOCTL_ARGS);
/* radeon_irq.c */ /* radeon_irq.c */
extern int radeon_irq_emit( DRM_IOCTL_ARGS ); extern int radeon_irq_emit( DRM_IOCTL_ARGS );
...@@ -382,7 +485,9 @@ extern int radeon_postcleanup( struct drm_device *dev ); ...@@ -382,7 +485,9 @@ extern int radeon_postcleanup( struct drm_device *dev );
# define RADEON_ROP_ENABLE (1 << 6) # define RADEON_ROP_ENABLE (1 << 6)
# define RADEON_STENCIL_ENABLE (1 << 7) # define RADEON_STENCIL_ENABLE (1 << 7)
# define RADEON_Z_ENABLE (1 << 8) # define RADEON_Z_ENABLE (1 << 8)
# define RADEON_ZBLOCK16 (1 << 15)
#define RADEON_RB3D_DEPTHOFFSET 0x1c24 #define RADEON_RB3D_DEPTHOFFSET 0x1c24
#define RADEON_RB3D_DEPTHCLEARVALUE 0x3230
#define RADEON_RB3D_DEPTHPITCH 0x1c28 #define RADEON_RB3D_DEPTHPITCH 0x1c28
#define RADEON_RB3D_PLANEMASK 0x1d84 #define RADEON_RB3D_PLANEMASK 0x1d84
#define RADEON_RB3D_STENCILREFMASK 0x1d7c #define RADEON_RB3D_STENCILREFMASK 0x1d7c
...@@ -395,11 +500,15 @@ extern int radeon_postcleanup( struct drm_device *dev ); ...@@ -395,11 +500,15 @@ extern int radeon_postcleanup( struct drm_device *dev );
#define RADEON_RB3D_ZSTENCILCNTL 0x1c2c #define RADEON_RB3D_ZSTENCILCNTL 0x1c2c
# define RADEON_Z_TEST_MASK (7 << 4) # define RADEON_Z_TEST_MASK (7 << 4)
# define RADEON_Z_TEST_ALWAYS (7 << 4) # define RADEON_Z_TEST_ALWAYS (7 << 4)
# define RADEON_Z_HIERARCHY_ENABLE (1 << 8)
# define RADEON_STENCIL_TEST_ALWAYS (7 << 12) # define RADEON_STENCIL_TEST_ALWAYS (7 << 12)
# define RADEON_STENCIL_S_FAIL_REPLACE (2 << 16) # define RADEON_STENCIL_S_FAIL_REPLACE (2 << 16)
# define RADEON_STENCIL_ZPASS_REPLACE (2 << 20) # define RADEON_STENCIL_ZPASS_REPLACE (2 << 20)
# define RADEON_STENCIL_ZFAIL_REPLACE (2 << 24) # define RADEON_STENCIL_ZFAIL_REPLACE (2 << 24)
# define RADEON_Z_COMPRESSION_ENABLE (1 << 28)
# define RADEON_FORCE_Z_DIRTY (1 << 29)
# define RADEON_Z_WRITE_ENABLE (1 << 30) # define RADEON_Z_WRITE_ENABLE (1 << 30)
# define RADEON_Z_DECOMPRESSION_ENABLE (1 << 31)
#define RADEON_RBBM_SOFT_RESET 0x00f0 #define RADEON_RBBM_SOFT_RESET 0x00f0
# define RADEON_SOFT_RESET_CP (1 << 0) # define RADEON_SOFT_RESET_CP (1 << 0)
# define RADEON_SOFT_RESET_HI (1 << 1) # define RADEON_SOFT_RESET_HI (1 << 1)
...@@ -478,6 +587,7 @@ extern int radeon_postcleanup( struct drm_device *dev ); ...@@ -478,6 +587,7 @@ extern int radeon_postcleanup( struct drm_device *dev );
# define RADEON_SURF_TILE_MODE_16BIT_Z (3 << 16) # define RADEON_SURF_TILE_MODE_16BIT_Z (3 << 16)
#define RADEON_SURFACE0_LOWER_BOUND 0x0b04 #define RADEON_SURFACE0_LOWER_BOUND 0x0b04
#define RADEON_SURFACE0_UPPER_BOUND 0x0b08 #define RADEON_SURFACE0_UPPER_BOUND 0x0b08
# define RADEON_SURF_ADDRESS_FIXED_MASK (0x3ff << 0)
#define RADEON_SURFACE1_INFO 0x0b1c #define RADEON_SURFACE1_INFO 0x0b1c
#define RADEON_SURFACE1_LOWER_BOUND 0x0b14 #define RADEON_SURFACE1_LOWER_BOUND 0x0b14
#define RADEON_SURFACE1_UPPER_BOUND 0x0b18 #define RADEON_SURFACE1_UPPER_BOUND 0x0b18
...@@ -507,7 +617,7 @@ extern int radeon_postcleanup( struct drm_device *dev ); ...@@ -507,7 +617,7 @@ extern int radeon_postcleanup( struct drm_device *dev );
# define RADEON_WAIT_3D_IDLECLEAN (1 << 17) # define RADEON_WAIT_3D_IDLECLEAN (1 << 17)
# define RADEON_WAIT_HOST_IDLECLEAN (1 << 18) # define RADEON_WAIT_HOST_IDLECLEAN (1 << 18)
#define RADEON_RB3D_ZMASKOFFSET 0x1c34 #define RADEON_RB3D_ZMASKOFFSET 0x3234
#define RADEON_RB3D_ZSTENCILCNTL 0x1c2c #define RADEON_RB3D_ZSTENCILCNTL 0x1c2c
# define RADEON_DEPTH_FORMAT_16BIT_INT_Z (0 << 0) # define RADEON_DEPTH_FORMAT_16BIT_INT_Z (0 << 0)
# define RADEON_DEPTH_FORMAT_24BIT_INT_Z (2 << 0) # define RADEON_DEPTH_FORMAT_24BIT_INT_Z (2 << 0)
...@@ -562,6 +672,8 @@ extern int radeon_postcleanup( struct drm_device *dev ); ...@@ -562,6 +672,8 @@ extern int radeon_postcleanup( struct drm_device *dev );
# define RADEON_3D_DRAW_IMMD 0x00002900 # define RADEON_3D_DRAW_IMMD 0x00002900
# define RADEON_3D_DRAW_INDX 0x00002A00 # define RADEON_3D_DRAW_INDX 0x00002A00
# define RADEON_3D_LOAD_VBPNTR 0x00002F00 # define RADEON_3D_LOAD_VBPNTR 0x00002F00
# define RADEON_3D_CLEAR_ZMASK 0x00003200
# define RADEON_3D_CLEAR_HIZ 0x00003700
# define RADEON_CNTL_HOSTDATA_BLT 0x00009400 # define RADEON_CNTL_HOSTDATA_BLT 0x00009400
# define RADEON_CNTL_PAINT_MULTI 0x00009A00 # define RADEON_CNTL_PAINT_MULTI 0x00009A00
# define RADEON_CNTL_BITBLT_MULTI 0x00009B00 # define RADEON_CNTL_BITBLT_MULTI 0x00009B00
...@@ -720,6 +832,8 @@ extern int radeon_postcleanup( struct drm_device *dev ); ...@@ -720,6 +832,8 @@ extern int radeon_postcleanup( struct drm_device *dev );
#define R200_RB3D_BLENDCOLOR 0x3218 #define R200_RB3D_BLENDCOLOR 0x3218
#define R200_SE_TCL_POINT_SPRITE_CNTL 0x22c4
/* Constants */ /* Constants */
#define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */ #define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */
......
...@@ -33,6 +33,37 @@ ...@@ -33,6 +33,37 @@
#include "radeon_drm.h" #include "radeon_drm.h"
#include "radeon_drv.h" #include "radeon_drv.h"
drm_ioctl_desc_t radeon_ioctls[] = {
[DRM_IOCTL_NR(DRM_RADEON_CP_INIT)] = { radeon_cp_init, 1, 1 },
[DRM_IOCTL_NR(DRM_RADEON_CP_START)] = { radeon_cp_start, 1, 1 },
[DRM_IOCTL_NR(DRM_RADEON_CP_STOP)] = { radeon_cp_stop, 1, 1 },
[DRM_IOCTL_NR(DRM_RADEON_CP_RESET)] = { radeon_cp_reset, 1, 1 },
[DRM_IOCTL_NR(DRM_RADEON_CP_IDLE)] = { radeon_cp_idle, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_CP_RESUME)] = { radeon_cp_resume, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_RESET)] = { radeon_engine_reset, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_FULLSCREEN)] = { radeon_fullscreen, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_SWAP)] = { radeon_cp_swap, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_CLEAR)] = { radeon_cp_clear, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_VERTEX)] = { radeon_cp_vertex, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_INDICES)] = { radeon_cp_indices, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_TEXTURE)] = { radeon_cp_texture, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_STIPPLE)] = { radeon_cp_stipple, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_INDIRECT)] = { radeon_cp_indirect, 1, 1 },
[DRM_IOCTL_NR(DRM_RADEON_VERTEX2)] = { radeon_cp_vertex2, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_CMDBUF)] = { radeon_cp_cmdbuf, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_GETPARAM)] = { radeon_cp_getparam, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_FLIP)] = { radeon_cp_flip, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_ALLOC)] = { radeon_mem_alloc, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_FREE)] = { radeon_mem_free, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_INIT_HEAP)] = { radeon_mem_init_heap,1, 1 },
[DRM_IOCTL_NR(DRM_RADEON_IRQ_EMIT)] = { radeon_irq_emit, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_IRQ_WAIT)] = { radeon_irq_wait, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_SETPARAM)] = { radeon_cp_setparam, 1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_SURF_ALLOC)] = { radeon_surface_alloc,1, 0 },
[DRM_IOCTL_NR(DRM_RADEON_SURF_FREE)] = { radeon_surface_free, 1, 0 }
};
int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls);
/* ================================================================ /* ================================================================
* Helper functions for client state checking and fixup * Helper functions for client state checking and fixup
...@@ -203,6 +234,7 @@ static __inline__ int radeon_check_and_fixup_packets( drm_radeon_private_t *dev_ ...@@ -203,6 +234,7 @@ static __inline__ int radeon_check_and_fixup_packets( drm_radeon_private_t *dev_
case RADEON_EMIT_PP_TEX_SIZE_1: case RADEON_EMIT_PP_TEX_SIZE_1:
case RADEON_EMIT_PP_TEX_SIZE_2: case RADEON_EMIT_PP_TEX_SIZE_2:
case R200_EMIT_RB3D_BLENDCOLOR: case R200_EMIT_RB3D_BLENDCOLOR:
case R200_EMIT_TCL_POINT_SPRITE_CNTL:
/* These packets don't contain memory offsets */ /* These packets don't contain memory offsets */
break; break;
...@@ -567,6 +599,7 @@ static struct { ...@@ -567,6 +599,7 @@ static struct {
{ RADEON_PP_TEX_SIZE_1, 2, "RADEON_PP_TEX_SIZE_1" }, { RADEON_PP_TEX_SIZE_1, 2, "RADEON_PP_TEX_SIZE_1" },
{ RADEON_PP_TEX_SIZE_2, 2, "RADEON_PP_TEX_SIZE_2" }, { RADEON_PP_TEX_SIZE_2, 2, "RADEON_PP_TEX_SIZE_2" },
{ R200_RB3D_BLENDCOLOR, 3, "R200_RB3D_BLENDCOLOR" }, { R200_RB3D_BLENDCOLOR, 3, "R200_RB3D_BLENDCOLOR" },
{ R200_SE_TCL_POINT_SPRITE_CNTL, 1, "R200_SE_TCL_POINT_SPRITE_CNTL" },
}; };
...@@ -778,12 +811,159 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, ...@@ -778,12 +811,159 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev,
} }
} }
/* hyper z clear */
/* no docs available, based on reverse engeneering by Stephane Marchesin */
if ((flags & (RADEON_DEPTH | RADEON_STENCIL)) && (flags & RADEON_CLEAR_FASTZ)) {
int i;
int depthpixperline = dev_priv->depth_fmt==RADEON_DEPTH_FORMAT_16BIT_INT_Z?
(dev_priv->depth_pitch / 2): (dev_priv->depth_pitch / 4);
u32 clearmask;
u32 tempRB3D_DEPTHCLEARVALUE = clear->clear_depth |
((clear->depth_mask & 0xff) << 24);
/* Make sure we restore the 3D state next time.
* we haven't touched any "normal" state - still need this?
*/
dev_priv->sarea_priv->ctx_owner = 0;
if ((dev_priv->flags & CHIP_HAS_HIERZ) && (flags & RADEON_USE_HIERZ)) {
/* FIXME : reverse engineer that for Rx00 cards */
/* FIXME : the mask supposedly contains low-res z values. So can't set
just to the max (0xff? or actually 0x3fff?), need to take z clear
value into account? */
/* pattern seems to work for r100, though get slight
rendering errors with glxgears. If hierz is not enabled for r100,
only 4 bits which indicate clear (15,16,31,32, all zero) matter, the
other ones are ignored, and the same clear mask can be used. That's
very different behaviour than R200 which needs different clear mask
and different number of tiles to clear if hierz is enabled or not !?!
*/
clearmask = (0xff<<22)|(0xff<<6)| 0x003f003f;
}
else {
/* clear mask : chooses the clearing pattern.
rv250: could be used to clear only parts of macrotiles
(but that would get really complicated...)?
bit 0 and 1 (either or both of them ?!?!) are used to
not clear tile (or maybe one of the bits indicates if the tile is
compressed or not), bit 2 and 3 to not clear tile 1,...,.
Pattern is as follows:
| 0,1 | 4,5 | 8,9 |12,13|16,17|20,21|24,25|28,29|
bits -------------------------------------------------
| 2,3 | 6,7 |10,11|14,15|18,19|22,23|26,27|30,31|
rv100: clearmask covers 2x8 4x1 tiles, but one clear still
covers 256 pixels ?!?
*/
clearmask = 0x0;
}
BEGIN_RING( 8 );
RADEON_WAIT_UNTIL_2D_IDLE();
OUT_RING_REG( RADEON_RB3D_DEPTHCLEARVALUE,
tempRB3D_DEPTHCLEARVALUE);
/* what offset is this exactly ? */
OUT_RING_REG( RADEON_RB3D_ZMASKOFFSET, 0 );
/* need ctlstat, otherwise get some strange black flickering */
OUT_RING_REG( RADEON_RB3D_ZCACHE_CTLSTAT, RADEON_RB3D_ZC_FLUSH_ALL );
ADVANCE_RING();
for (i = 0; i < nbox; i++) {
int tileoffset, nrtilesx, nrtilesy, j;
/* it looks like r200 needs rv-style clears, at least if hierz is not enabled? */
if ((dev_priv->flags&CHIP_HAS_HIERZ) && !(dev_priv->microcode_version==UCODE_R200)) {
/* FIXME : figure this out for r200 (when hierz is enabled). Or
maybe r200 actually doesn't need to put the low-res z value into
the tile cache like r100, but just needs to clear the hi-level z-buffer?
Works for R100, both with hierz and without.
R100 seems to operate on 2x1 8x8 tiles, but...
odd: offset/nrtiles need to be 64 pix (4 block) aligned? Potentially
problematic with resolutions which are not 64 pix aligned? */
tileoffset = ((pbox[i].y1 >> 3) * depthpixperline + pbox[i].x1) >> 6;
nrtilesx = ((pbox[i].x2 & ~63) - (pbox[i].x1 & ~63)) >> 4;
nrtilesy = (pbox[i].y2 >> 3) - (pbox[i].y1 >> 3);
for (j = 0; j <= nrtilesy; j++) {
BEGIN_RING( 4 );
OUT_RING( CP_PACKET3( RADEON_3D_CLEAR_ZMASK, 2 ) );
/* first tile */
OUT_RING( tileoffset * 8 );
/* the number of tiles to clear */
OUT_RING( nrtilesx + 4 );
/* clear mask : chooses the clearing pattern. */
OUT_RING( clearmask );
ADVANCE_RING();
tileoffset += depthpixperline >> 6;
}
}
else if (dev_priv->microcode_version==UCODE_R200) {
/* works for rv250. */
/* find first macro tile (8x2 4x4 z-pixels on rv250) */
tileoffset = ((pbox[i].y1 >> 3) * depthpixperline + pbox[i].x1) >> 5;
nrtilesx = (pbox[i].x2 >> 5) - (pbox[i].x1 >> 5);
nrtilesy = (pbox[i].y2 >> 3) - (pbox[i].y1 >> 3);
for (j = 0; j <= nrtilesy; j++) {
BEGIN_RING( 4 );
OUT_RING( CP_PACKET3( RADEON_3D_CLEAR_ZMASK, 2 ) );
/* first tile */
/* judging by the first tile offset needed, could possibly
directly address/clear 4x4 tiles instead of 8x2 * 4x4
macro tiles, though would still need clear mask for
right/bottom if truely 4x4 granularity is desired ? */
OUT_RING( tileoffset * 16 );
/* the number of tiles to clear */
OUT_RING( nrtilesx + 1 );
/* clear mask : chooses the clearing pattern. */
OUT_RING( clearmask );
ADVANCE_RING();
tileoffset += depthpixperline >> 5;
}
}
else { /* rv 100 */
/* rv100 might not need 64 pix alignment, who knows */
/* offsets are, hmm, weird */
tileoffset = ((pbox[i].y1 >> 4) * depthpixperline + pbox[i].x1) >> 6;
nrtilesx = ((pbox[i].x2 & ~63) - (pbox[i].x1 & ~63)) >> 4;
nrtilesy = (pbox[i].y2 >> 4) - (pbox[i].y1 >> 4);
for (j = 0; j <= nrtilesy; j++) {
BEGIN_RING( 4 );
OUT_RING( CP_PACKET3( RADEON_3D_CLEAR_ZMASK, 2 ) );
OUT_RING( tileoffset * 128 );
/* the number of tiles to clear */
OUT_RING( nrtilesx + 4 );
/* clear mask : chooses the clearing pattern. */
OUT_RING( clearmask );
ADVANCE_RING();
tileoffset += depthpixperline >> 6;
}
}
}
/* TODO don't always clear all hi-level z tiles */
if ((dev_priv->flags & CHIP_HAS_HIERZ) && (dev_priv->microcode_version==UCODE_R200)
&& (flags & RADEON_USE_HIERZ))
/* r100 and cards without hierarchical z-buffer have no high-level z-buffer */
/* FIXME : the mask supposedly contains low-res z values. So can't set
just to the max (0xff? or actually 0x3fff?), need to take z clear
value into account? */
{
BEGIN_RING( 4 );
OUT_RING( CP_PACKET3( RADEON_3D_CLEAR_HIZ, 2 ) );
OUT_RING( 0x0 ); /* First tile */
OUT_RING( 0x3cc0 );
OUT_RING( (0xff<<22)|(0xff<<6)| 0x003f003f);
ADVANCE_RING();
}
}
/* We have to clear the depth and/or stencil buffers by /* We have to clear the depth and/or stencil buffers by
* rendering a quad into just those buffers. Thus, we have to * rendering a quad into just those buffers. Thus, we have to
* make sure the 3D engine is configured correctly. * make sure the 3D engine is configured correctly.
*/ */
if ( dev_priv->is_r200 && if ((dev_priv->microcode_version == UCODE_R200) &&
(flags & (RADEON_DEPTH | RADEON_STENCIL)) ) { (flags & (RADEON_DEPTH | RADEON_STENCIL))) {
int tempPP_CNTL; int tempPP_CNTL;
int tempRE_CNTL; int tempRE_CNTL;
...@@ -802,7 +982,6 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, ...@@ -802,7 +982,6 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev,
tempRE_CNTL = 0; tempRE_CNTL = 0;
tempRB3D_CNTL = depth_clear->rb3d_cntl; tempRB3D_CNTL = depth_clear->rb3d_cntl;
tempRB3D_CNTL &= ~(1<<15); /* unset radeon magic flag */
tempRB3D_ZSTENCILCNTL = depth_clear->rb3d_zstencilcntl; tempRB3D_ZSTENCILCNTL = depth_clear->rb3d_zstencilcntl;
tempRB3D_STENCILREFMASK = 0x0; tempRB3D_STENCILREFMASK = 0x0;
...@@ -853,6 +1032,14 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, ...@@ -853,6 +1032,14 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev,
tempRB3D_STENCILREFMASK = 0x00000000; tempRB3D_STENCILREFMASK = 0x00000000;
} }
if (flags & RADEON_USE_COMP_ZBUF) {
tempRB3D_ZSTENCILCNTL |= RADEON_Z_COMPRESSION_ENABLE |
RADEON_Z_DECOMPRESSION_ENABLE;
}
if (flags & RADEON_USE_HIERZ) {
tempRB3D_ZSTENCILCNTL |= RADEON_Z_HIERARCHY_ENABLE;
}
BEGIN_RING( 26 ); BEGIN_RING( 26 );
RADEON_WAIT_UNTIL_2D_IDLE(); RADEON_WAIT_UNTIL_2D_IDLE();
...@@ -907,6 +1094,8 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, ...@@ -907,6 +1094,8 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev,
} }
else if ( (flags & (RADEON_DEPTH | RADEON_STENCIL)) ) { else if ( (flags & (RADEON_DEPTH | RADEON_STENCIL)) ) {
int tempRB3D_ZSTENCILCNTL = depth_clear->rb3d_zstencilcntl;
rb3d_cntl = depth_clear->rb3d_cntl; rb3d_cntl = depth_clear->rb3d_cntl;
if ( flags & RADEON_DEPTH ) { if ( flags & RADEON_DEPTH ) {
...@@ -923,6 +1112,14 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, ...@@ -923,6 +1112,14 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev,
rb3d_stencilrefmask = 0x00000000; rb3d_stencilrefmask = 0x00000000;
} }
if (flags & RADEON_USE_COMP_ZBUF) {
tempRB3D_ZSTENCILCNTL |= RADEON_Z_COMPRESSION_ENABLE |
RADEON_Z_DECOMPRESSION_ENABLE;
}
if (flags & RADEON_USE_HIERZ) {
tempRB3D_ZSTENCILCNTL |= RADEON_Z_HIERARCHY_ENABLE;
}
BEGIN_RING( 13 ); BEGIN_RING( 13 );
RADEON_WAIT_UNTIL_2D_IDLE(); RADEON_WAIT_UNTIL_2D_IDLE();
...@@ -930,8 +1127,7 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, ...@@ -930,8 +1127,7 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev,
OUT_RING( 0x00000000 ); OUT_RING( 0x00000000 );
OUT_RING( rb3d_cntl ); OUT_RING( rb3d_cntl );
OUT_RING_REG( RADEON_RB3D_ZSTENCILCNTL, OUT_RING_REG( RADEON_RB3D_ZSTENCILCNTL, tempRB3D_ZSTENCILCNTL );
depth_clear->rb3d_zstencilcntl );
OUT_RING_REG( RADEON_RB3D_STENCILREFMASK, OUT_RING_REG( RADEON_RB3D_STENCILREFMASK,
rb3d_stencilrefmask ); rb3d_stencilrefmask );
OUT_RING_REG( RADEON_RB3D_PLANEMASK, OUT_RING_REG( RADEON_RB3D_PLANEMASK,
...@@ -1537,10 +1733,203 @@ static void radeon_cp_dispatch_stipple( drm_device_t *dev, u32 *stipple ) ...@@ -1537,10 +1733,203 @@ static void radeon_cp_dispatch_stipple( drm_device_t *dev, u32 *stipple )
ADVANCE_RING(); ADVANCE_RING();
} }
static void radeon_apply_surface_regs(int surf_index, drm_radeon_private_t *dev_priv)
{
if (!dev_priv->mmio)
return;
radeon_do_cp_idle(dev_priv);
RADEON_WRITE(RADEON_SURFACE0_INFO + 16*surf_index,
dev_priv->surfaces[surf_index].flags);
RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16*surf_index,
dev_priv->surfaces[surf_index].lower);
RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16*surf_index,
dev_priv->surfaces[surf_index].upper);
}
/* Allocates a virtual surface
* doesn't always allocate a real surface, will stretch an existing
* surface when possible.
*
* Note that refcount can be at most 2, since during a free refcount=3
* might mean we have to allocate a new surface which might not always
* be available.
* For example : we allocate three contigous surfaces ABC. If B is
* freed, we suddenly need two surfaces to store A and C, which might
* not always be available.
*/
static int alloc_surface(drm_radeon_surface_alloc_t* new, drm_radeon_private_t *dev_priv, DRMFILE filp)
{
struct radeon_virt_surface *s;
int i;
int virt_surface_index;
uint32_t new_upper, new_lower;
new_lower = new->address;
new_upper = new_lower + new->size - 1;
/* sanity check */
if ((new_lower >= new_upper) || (new->flags == 0) || (new->size == 0) ||
((new_upper & RADEON_SURF_ADDRESS_FIXED_MASK) != RADEON_SURF_ADDRESS_FIXED_MASK) ||
((new_lower & RADEON_SURF_ADDRESS_FIXED_MASK) != 0))
return -1;
/* make sure there is no overlap with existing surfaces */
for (i = 0; i < RADEON_MAX_SURFACES; i++) {
if ((dev_priv->surfaces[i].refcount != 0) &&
(( (new_lower >= dev_priv->surfaces[i].lower) &&
(new_lower < dev_priv->surfaces[i].upper) ) ||
( (new_lower < dev_priv->surfaces[i].lower) &&
(new_upper > dev_priv->surfaces[i].lower) )) ){
return -1;}
}
/* find a virtual surface */
for (i = 0; i < 2*RADEON_MAX_SURFACES; i++)
if (dev_priv->virt_surfaces[i].filp == 0)
break;
if (i == 2*RADEON_MAX_SURFACES) {
return -1;}
virt_surface_index = i;
/* try to reuse an existing surface */
for (i = 0; i < RADEON_MAX_SURFACES; i++) {
/* extend before */
if ((dev_priv->surfaces[i].refcount == 1) &&
(new->flags == dev_priv->surfaces[i].flags) &&
(new_upper + 1 == dev_priv->surfaces[i].lower)) {
s = &(dev_priv->virt_surfaces[virt_surface_index]);
s->surface_index = i;
s->lower = new_lower;
s->upper = new_upper;
s->flags = new->flags;
s->filp = filp;
dev_priv->surfaces[i].refcount++;
dev_priv->surfaces[i].lower = s->lower;
radeon_apply_surface_regs(s->surface_index, dev_priv);
return virt_surface_index;
}
/* extend after */
if ((dev_priv->surfaces[i].refcount == 1) &&
(new->flags == dev_priv->surfaces[i].flags) &&
(new_lower == dev_priv->surfaces[i].upper + 1)) {
s = &(dev_priv->virt_surfaces[virt_surface_index]);
s->surface_index = i;
s->lower = new_lower;
s->upper = new_upper;
s->flags = new->flags;
s->filp = filp;
dev_priv->surfaces[i].refcount++;
dev_priv->surfaces[i].upper = s->upper;
radeon_apply_surface_regs(s->surface_index, dev_priv);
return virt_surface_index;
}
}
/* okay, we need a new one */
for (i = 0; i < RADEON_MAX_SURFACES; i++) {
if (dev_priv->surfaces[i].refcount == 0) {
s = &(dev_priv->virt_surfaces[virt_surface_index]);
s->surface_index = i;
s->lower = new_lower;
s->upper = new_upper;
s->flags = new->flags;
s->filp = filp;
dev_priv->surfaces[i].refcount = 1;
dev_priv->surfaces[i].lower = s->lower;
dev_priv->surfaces[i].upper = s->upper;
dev_priv->surfaces[i].flags = s->flags;
radeon_apply_surface_regs(s->surface_index, dev_priv);
return virt_surface_index;
}
}
/* we didn't find anything */
return -1;
}
static int free_surface(DRMFILE filp, drm_radeon_private_t *dev_priv, int lower)
{
struct radeon_virt_surface *s;
int i;
/* find the virtual surface */
for(i = 0; i < 2*RADEON_MAX_SURFACES; i++) {
s = &(dev_priv->virt_surfaces[i]);
if (s->filp) {
if ((lower == s->lower) && (filp == s->filp)) {
if (dev_priv->surfaces[s->surface_index].lower == s->lower)
dev_priv->surfaces[s->surface_index].lower = s->upper;
if (dev_priv->surfaces[s->surface_index].upper == s->upper)
dev_priv->surfaces[s->surface_index].upper = s->lower;
dev_priv->surfaces[s->surface_index].refcount--;
if (dev_priv->surfaces[s->surface_index].refcount == 0)
dev_priv->surfaces[s->surface_index].flags = 0;
s->filp = 0;
radeon_apply_surface_regs(s->surface_index, dev_priv);
return 0;
}
}
}
return 1;
}
static void radeon_surfaces_release(DRMFILE filp, drm_radeon_private_t *dev_priv)
{
int i;
for( i = 0; i < 2*RADEON_MAX_SURFACES; i++)
{
if (dev_priv->virt_surfaces[i].filp == filp)
free_surface(filp, dev_priv, dev_priv->virt_surfaces[i].lower);
}
}
/* ================================================================ /* ================================================================
* IOCTL functions * IOCTL functions
*/ */
int radeon_surface_alloc(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_radeon_surface_alloc_t alloc;
if (!dev_priv) {
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
return DRM_ERR(EINVAL);
}
DRM_COPY_FROM_USER_IOCTL(alloc, (drm_radeon_surface_alloc_t __user *)data,
sizeof(alloc));
if (alloc_surface(&alloc, dev_priv, filp) == -1)
return DRM_ERR(EINVAL);
else
return 0;
}
int radeon_surface_free(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_radeon_surface_free_t memfree;
if (!dev_priv) {
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
return DRM_ERR(EINVAL);
}
DRM_COPY_FROM_USER_IOCTL(memfree, (drm_radeon_mem_free_t __user *)data,
sizeof(memfree) );
if (free_surface(filp, dev_priv, memfree.address))
return DRM_ERR(EINVAL);
else
return 0;
}
int radeon_cp_clear( DRM_IOCTL_ARGS ) int radeon_cp_clear( DRM_IOCTL_ARGS )
{ {
...@@ -2539,6 +2928,20 @@ int radeon_cp_setparam( DRM_IOCTL_ARGS ) { ...@@ -2539,6 +2928,20 @@ int radeon_cp_setparam( DRM_IOCTL_ARGS ) {
radeon_priv = filp_priv->driver_priv; radeon_priv = filp_priv->driver_priv;
radeon_priv->radeon_fb_delta = dev_priv->fb_location - sp.value; radeon_priv->radeon_fb_delta = dev_priv->fb_location - sp.value;
break; break;
case RADEON_SETPARAM_SWITCH_TILING:
if (sp.value == 0) {
DRM_DEBUG( "color tiling disabled\n" );
dev_priv->front_pitch_offset &= ~RADEON_DST_TILE_MACRO;
dev_priv->back_pitch_offset &= ~RADEON_DST_TILE_MACRO;
dev_priv->sarea_priv->tiling_enabled = 0;
}
else if (sp.value == 1) {
DRM_DEBUG( "color tiling enabled\n" );
dev_priv->front_pitch_offset |= RADEON_DST_TILE_MACRO;
dev_priv->back_pitch_offset |= RADEON_DST_TILE_MACRO;
dev_priv->sarea_priv->tiling_enabled = 1;
}
break;
default: default:
DRM_DEBUG( "Invalid parameter %d\n", sp.param ); DRM_DEBUG( "Invalid parameter %d\n", sp.param );
return DRM_ERR( EINVAL ); return DRM_ERR( EINVAL );
...@@ -2562,6 +2965,7 @@ void radeon_driver_prerelease(drm_device_t *dev, DRMFILE filp) ...@@ -2562,6 +2965,7 @@ void radeon_driver_prerelease(drm_device_t *dev, DRMFILE filp)
} }
radeon_mem_release( filp, dev_priv->gart_heap ); radeon_mem_release( filp, dev_priv->gart_heap );
radeon_mem_release( filp, dev_priv->fb_heap ); radeon_mem_release( filp, dev_priv->fb_heap );
radeon_surfaces_release(filp, dev_priv);
} }
} }
......
/* sis_drv.h -- Private header for sis driver -*- linux-c -*-
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* 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.
*
*/
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis.h,v 1.3 2002/10/30 12:52:38 alanh Exp $ */
#ifndef __SIS_H__
#define __SIS_H__
/* This remains constant for all DRM template files.
* Name it sisdrv_##x as there's a conflict with sis_free/malloc in the kernel
* that's used for fb devices
*/
#ifdef __linux__
#define DRM(x) sisdrv_##x
#else
#define DRM(x) sis_##x
#endif
/* General customization:
*/
#define DRIVER_AUTHOR "SIS"
#define DRIVER_NAME "sis"
#define DRIVER_DESC "SIS 300/630/540"
#define DRIVER_DATE "20030826"
#define DRIVER_MAJOR 1
#define DRIVER_MINOR 1
#define DRIVER_PATCHLEVEL 0
#define DRIVER_IOCTLS \
[DRM_IOCTL_NR(DRM_IOCTL_SIS_FB_ALLOC)] = { sis_fb_alloc, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_SIS_FB_FREE)] = { sis_fb_free, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_SIS_AGP_INIT)] = { sis_ioctl_agp_init, 1, 1 }, \
[DRM_IOCTL_NR(DRM_IOCTL_SIS_AGP_ALLOC)] = { sis_ioctl_agp_alloc, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_SIS_AGP_FREE)] = { sis_ioctl_agp_free, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_SIS_FB_INIT)] = { sis_fb_init, 1, 1 }
#endif
...@@ -63,14 +63,8 @@ static struct pci_device_id pciidlist[] = { ...@@ -63,14 +63,8 @@ static struct pci_device_id pciidlist[] = {
sisdrv_PCI_IDS sisdrv_PCI_IDS
}; };
static drm_ioctl_desc_t ioctls[] = { extern drm_ioctl_desc_t sis_ioctls[];
[DRM_IOCTL_NR(DRM_SIS_FB_ALLOC)] = { sis_fb_alloc, 1, 0 }, extern int sis_max_ioctl;
[DRM_IOCTL_NR(DRM_SIS_FB_FREE)] = { sis_fb_free, 1, 0 },
[DRM_IOCTL_NR(DRM_SIS_AGP_INIT)] = { sis_ioctl_agp_init, 1, 1 },
[DRM_IOCTL_NR(DRM_SIS_AGP_ALLOC)] = { sis_ioctl_agp_alloc, 1, 0 },
[DRM_IOCTL_NR(DRM_SIS_AGP_FREE)] = { sis_ioctl_agp_free, 1, 0 },
[DRM_IOCTL_NR(DRM_SIS_FB_INIT)] = { sis_fb_init, 1, 1 }
};
static struct drm_driver driver = { static struct drm_driver driver = {
.driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR, .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR,
...@@ -81,8 +75,7 @@ static struct drm_driver driver = { ...@@ -81,8 +75,7 @@ static struct drm_driver driver = {
.get_reg_ofs = drm_core_get_reg_ofs, .get_reg_ofs = drm_core_get_reg_ofs,
.postinit = postinit, .postinit = postinit,
.version = version, .version = version,
.ioctls = ioctls, .ioctls = sis_ioctls,
.num_ioctls = DRM_ARRAY_SIZE(ioctls),
.fops = { .fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.open = drm_open, .open = drm_open,
...@@ -100,6 +93,7 @@ static struct drm_driver driver = { ...@@ -100,6 +93,7 @@ static struct drm_driver driver = {
static int __init sis_init(void) static int __init sis_init(void)
{ {
driver.num_ioctls = sis_max_ioctl;
return drm_init(&driver); return drm_init(&driver);
} }
......
...@@ -36,6 +36,17 @@ ...@@ -36,6 +36,17 @@
#include <video/sisfb.h> #include <video/sisfb.h>
#endif #endif
drm_ioctl_desc_t sis_ioctls[] = {
[DRM_IOCTL_NR(DRM_SIS_FB_ALLOC)] = { sis_fb_alloc, 1, 0 },
[DRM_IOCTL_NR(DRM_SIS_FB_FREE)] = { sis_fb_free, 1, 0 },
[DRM_IOCTL_NR(DRM_SIS_AGP_INIT)] = { sis_ioctl_agp_init, 1, 1 },
[DRM_IOCTL_NR(DRM_SIS_AGP_ALLOC)] = { sis_ioctl_agp_alloc, 1, 0 },
[DRM_IOCTL_NR(DRM_SIS_AGP_FREE)] = { sis_ioctl_agp_free, 1, 0 },
[DRM_IOCTL_NR(DRM_SIS_FB_INIT)] = { sis_fb_init, 1, 1 }
};
int sis_max_ioctl = DRM_ARRAY_SIZE(sis_ioctls);
#define MAX_CONTEXT 100 #define MAX_CONTEXT 100
#define VIDEO_TYPE 0 #define VIDEO_TYPE 0
#define AGP_TYPE 1 #define AGP_TYPE 1
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment