Index: amd64/conf/NOTES =================================================================== RCS file: /home/ncvs/src/sys/amd64/conf/NOTES,v retrieving revision 1.48 diff -u -r1.48 NOTES --- amd64/conf/NOTES 11 Nov 2005 09:57:29 -0000 1.48 +++ amd64/conf/NOTES 23 Nov 2005 10:24:41 -0000 @@ -214,6 +214,7 @@ device mgadrm # AGP Matrox G200, G400, G450, G550 device r128drm # ATI Rage 128 device radeondrm # ATI Radeon +device savagedrm # S3 Savage3D, Savage4 device sisdrm # SiS 300/305, 540, 630 device tdfxdrm # 3dfx Voodoo 3/4/5 and Banshee options DRM_DEBUG # Include debug printfs (slow) Index: i386/conf/NOTES =================================================================== RCS file: /home/ncvs/src/sys/i386/conf/NOTES,v retrieving revision 1.1213 diff -u -r1.1213 NOTES --- i386/conf/NOTES 22 Nov 2005 22:54:42 -0000 1.1213 +++ i386/conf/NOTES 23 Nov 2005 10:25:30 -0000 @@ -478,6 +478,7 @@ device mgadrm # AGP Matrox G200, G400, G450, G550 device r128drm # ATI Rage 128 device radeondrm # ATI Radeon +device savagedrm # S3 Savage3D, Savage4 device sisdrm # SiS 300/305, 540, 630 device tdfxdrm # 3dfx Voodoo 3/4/5 and Banshee options DRM_DEBUG # Include debug printfs (slow) Index: conf/files =================================================================== RCS file: /home/ncvs/src/sys/conf/files,v retrieving revision 1.1066 diff -u -r1.1066 files --- conf/files 22 Nov 2005 17:12:48 -0000 1.1066 +++ conf/files 23 Nov 2005 10:14:24 -0000 @@ -583,6 +583,9 @@ dev/drm/radeon_irq.c optional radeondrm dev/drm/radeon_mem.c optional radeondrm dev/drm/radeon_state.c optional radeondrm +dev/drm/savage_bci.c optional savagedrm +dev/drm/savage_drv.c optional savagedrm +dev/drm/savage_state.c optional savagedrm dev/drm/sis_drv.c optional sisdrm dev/drm/sis_ds.c optional sisdrm dev/drm/sis_mm.c optional sisdrm Index: dev/drm/ati_pcigart.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/ati_pcigart.c,v retrieving revision 1.2 diff -u -r1.2 ati_pcigart.c --- dev/drm/ati_pcigart.c 20 Jul 2005 21:10:57 -0000 1.2 +++ dev/drm/ati_pcigart.c 23 Nov 2005 10:13:23 -0000 @@ -27,66 +27,58 @@ * Authors: * Gareth Hughes * - * $FreeBSD: src/sys/dev/drm/ati_pcigart.c,v 1.2 2005/07/20 21:10:57 anholt Exp $ */ -#include "dev/drm/drmP.h" +#include +__FBSDID("$FreeBSD$"); -#if PAGE_SIZE == 8192 -# define ATI_PCIGART_TABLE_ORDER 2 -# define ATI_PCIGART_TABLE_PAGES (1 << 2) -#elif PAGE_SIZE == 4096 -# define ATI_PCIGART_TABLE_ORDER 3 -# define ATI_PCIGART_TABLE_PAGES (1 << 3) -#elif -# error - PAGE_SIZE not 8K or 4K -#endif +#include "dev/drm/drmP.h" -# define ATI_MAX_PCIGART_PAGES 8192 /* 32 MB aperture, 4K pages */ -# define ATI_PCIGART_PAGE_SIZE 4096 /* PCI GART page size */ +#define ATI_PCIGART_PAGE_SIZE 4096 /* PCI GART page size */ +#define ATI_MAX_PCIGART_PAGES 8192 /* 32 MB aperture, 4K pages */ +#define ATI_PCIGART_TABLE_SIZE 32768 -int drm_ati_pcigart_init(drm_device_t *dev, unsigned long *addr, - dma_addr_t *bus_addr, int is_pcie) +int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) { - drm_sg_mem_t *entry = dev->sg; - unsigned long address = 0; unsigned long pages; - u32 *pci_gart=0, page_base, bus_address = 0; - int i, j, ret = 0; + u32 *pci_gart = NULL, page_base; + int i, j; - if ( !entry ) { + if (dev->sg == NULL) { DRM_ERROR( "no scatter/gather memory!\n" ); - goto done; + return 0; } - address = (long)contigmalloc((1 << ATI_PCIGART_TABLE_ORDER) * PAGE_SIZE, - M_DRM, M_NOWAIT, 0ul, 0xfffffffful, PAGE_SIZE, 0); - if ( !address ) { - DRM_ERROR( "cannot allocate PCI GART page!\n" ); - goto done; + if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { + /* GART table in system memory */ + dev->sg->dmah = drm_pci_alloc(dev, ATI_PCIGART_TABLE_SIZE, 0, + 0xfffffffful); + if (dev->sg->dmah == NULL) { + DRM_ERROR("cannot allocate PCI GART table!\n"); + return 0; + } + + gart_info->addr = (void *)dev->sg->dmah->vaddr; + gart_info->bus_addr = dev->sg->dmah->busaddr; + pci_gart = (u32 *)dev->sg->dmah->vaddr; + } else { + /* GART table in framebuffer memory */ + pci_gart = gart_info->addr; } + + pages = DRM_MIN(dev->sg->pages, ATI_MAX_PCIGART_PAGES); - /* XXX: we need to busdma this */ - bus_address = vtophys( address ); - - pci_gart = (u32 *)address; + bzero(pci_gart, ATI_PCIGART_TABLE_SIZE); - pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES ) - ? entry->pages : ATI_MAX_PCIGART_PAGES; - - bzero( pci_gart, ATI_MAX_PCIGART_PAGES * sizeof(u32) ); + KASSERT(PAGE_SIZE >= ATI_PCIGART_PAGE_SIZE, ("page size too small")); for ( i = 0 ; i < pages ; i++ ) { - entry->busaddr[i] = vtophys( entry->handle + (i*PAGE_SIZE) ); - page_base = (u32) entry->busaddr[i]; + page_base = (u32) dev->sg->busaddr[i]; for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { - if (is_pcie) { - *pci_gart = (cpu_to_le32(page_base)>>8) | 0xc; - DRM_DEBUG("PCIE: %d %08X %08X to %p\n", i, - page_base, (cpu_to_le32(page_base)>>8)|0xc, - pci_gart); - } else + if (gart_info->is_pcie) + *pci_gart = (cpu_to_le32(page_base) >> 8) | 0xc; + else *pci_gart = cpu_to_le32(page_base); pci_gart++; page_base += ATI_PCIGART_PAGE_SIZE; @@ -95,29 +87,17 @@ DRM_MEMORYBARRIER(); - ret = 1; - -done: - *addr = address; - *bus_addr = bus_address; - return ret; + return 1; } -int drm_ati_pcigart_cleanup(drm_device_t *dev, unsigned long addr, - dma_addr_t bus_addr) +int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info) { - drm_sg_mem_t *entry = dev->sg; - - /* we need to support large memory configurations */ - if ( !entry ) { + if (dev->sg == NULL) { DRM_ERROR( "no scatter/gather memory!\n" ); return 0; } -#if __FreeBSD_version > 500000 - /* Not available on 4.x */ - contigfree((void *)addr, (1 << ATI_PCIGART_TABLE_ORDER) * PAGE_SIZE, - M_DRM); -#endif + drm_pci_free(dev, dev->sg->dmah); + return 1; } Index: dev/drm/drm-preprocess.sh =================================================================== RCS file: dev/drm/drm-preprocess.sh diff -N dev/drm/drm-preprocess.sh --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ dev/drm/drm-preprocess.sh 23 Nov 2005 10:00:46 -0000 @@ -0,0 +1,11 @@ +#!/bin/sh + +cp /usr/src/drm/bsd-core/*.[ch] . +rm i810*.[ch] +rm via*.[ch] + +for i in `ls *.[ch]`; do + mv $i $i.orig + perl drm-subprocess.pl < $i.orig > $i +done + Index: dev/drm/drm-subprocess.pl =================================================================== RCS file: dev/drm/drm-subprocess.pl diff -N dev/drm/drm-subprocess.pl --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ dev/drm/drm-subprocess.pl 23 Nov 2005 10:07:57 -0000 @@ -0,0 +1,48 @@ +# Props to Daniel Stone for starting this script for me. I hate perl. + +my $lastline = ""; +my $foundopening = 0; +my $foundclosing = 0; + +while (<>) { + $curline = $_; + if (!$foundopening) { + if (/Copyright/) { + $foundopening = 1; + # print the previous line we buffered, but with /*- + if ($lastline !~ /\/\*-/) { + $lastline =~ s/\/\*/\/\*-/; + } + print $lastline; + # now, print the current line. + print $curline; + } else { + # print the previous line and continue on + print $lastline; + } + } elsif ($foundopening && !$foundclosing && /\*\//) { + # print the $FreeBSD$ bits after the end of the license block + $foundclosing = 1; + print; + print "\n"; + print "#include \n"; + print "__FBSDID(\"\$FreeBSD\$\");\n"; + } elsif ($foundopening) { + # Replace headers with the system's paths. the headers we're + # concerned with are drm*.h, *_drm.h and *_drv.h + # + s/#include "(.*)_drv.h/#include "dev\/drm\/\1_drv.h/; + s/#include "(.*)_drm.h/#include "dev\/drm\/\1_drm.h/; + s/#include "mga_ucode.h/#include "dev\/drm\/mga_ucode.h/; + s/#include "r300_reg.h/#include "dev\/drm\/r300_reg.h/; + s/#include "sis_ds.h/#include "dev\/drm\/sis_ds.h/; + s/#include "drm/#include "dev\/drm\/drm/; + print; + } + $lastline = $curline; +} + +# if we never found the copyright header, then we're still a line behind. +if (!$foundopening) { + print $lastline; +} \ No newline at end of file Index: dev/drm/drm.h =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/drm.h,v retrieving revision 1.9 diff -u -r1.9 drm.h --- dev/drm/drm.h 16 Apr 2005 03:44:43 -0000 1.9 +++ dev/drm/drm.h 23 Nov 2005 10:13:23 -0000 @@ -31,10 +31,11 @@ * 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. - * - * $FreeBSD: src/sys/dev/drm/drm.h,v 1.9 2005/04/16 03:44:43 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + /** * \mainpage * @@ -64,8 +65,16 @@ #define __user #endif +#ifdef __GNUC__ +# define DEPRECATED __attribute__ ((deprecated)) +#else +# define DEPRECATED +#endif + #if defined(__linux__) +#if defined(__KERNEL__) #include +#endif #include /* For _IO* macros */ #define DRM_IOCTL_NR(n) _IOC_NR(n) #define DRM_IOC_VOID _IOC_NONE @@ -73,7 +82,7 @@ #define DRM_IOC_WRITE _IOC_WRITE #define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE #define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) -#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) #if defined(__FreeBSD__) && defined(IN_MODULE) /* Prevent name collision when including sys/ioccom.h */ #undef ioctl @@ -127,7 +136,11 @@ #define _DRM_LOCK_IS_CONT(lock) ((lock) & _DRM_LOCK_CONT) #define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT)) +#if defined(__linux__) +typedef unsigned int drm_handle_t; +#else typedef unsigned long drm_handle_t; /**< To mapped regions */ +#endif typedef unsigned int drm_context_t; /**< GLXContext handle */ typedef unsigned int drm_drawable_t; typedef unsigned int drm_magic_t; /**< Magic for authentication */ @@ -439,7 +452,11 @@ */ typedef struct drm_buf_map { int count; /**< Length of the buffer list */ +#if defined(__cplusplus) + void __user *c_virtual; +#else void __user *virtual; /**< Mmap'd area in user-virtual */ +#endif drm_buf_pub_t __user *list; /**< Buffer information */ } drm_buf_map_t; Index: dev/drm/drmP.h =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/drmP.h,v retrieving revision 1.14 diff -u -r1.14 drmP.h --- dev/drm/drmP.h 20 Jul 2005 21:10:57 -0000 1.14 +++ dev/drm/drmP.h 23 Nov 2005 10:13:23 -0000 @@ -29,9 +29,11 @@ * Rickard E. (Rik) Faith * Gareth Hughes * - * $FreeBSD: src/sys/dev/drm/drmP.h,v 1.14 2005/07/20 21:10:57 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #ifndef _DRM_P_H_ #define _DRM_P_H_ @@ -216,6 +218,13 @@ #define IRQ_HANDLED /* nothing */ #define IRQ_NONE /* nothing */ +enum { + DRM_IS_NOT_AGP, + DRM_MIGHT_BE_AGP, + DRM_IS_AGP +}; +#define DRM_AGP_MEM struct agp_memory_info + #if defined(__FreeBSD__) #define DRM_DEVICE \ drm_device_t *dev = kdev->si_drv1 @@ -223,7 +232,8 @@ int flags, DRM_STRUCTPROC *p, DRMFILE filp #define PAGE_ALIGN(addr) round_page(addr) -#define DRM_SUSER(p) suser(p) +/* DRM_SUSER returns true if the user is superuser */ +#define DRM_SUSER(p) (suser(p) == 0) #define DRM_AGP_FIND_DEVICE() agp_find_device() #define DRM_MTRR_WC MDF_WRITECOMBINE #define jiffies ticks @@ -243,7 +253,8 @@ #define CDEV_MAJOR 34 #define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK) -#define DRM_SUSER(p) suser(p->p_ucred, &p->p_acflag) +/* DRM_SUSER returns true if the user is superuser */ +#define DRM_SUSER(p) (suser(p->p_ucred, &p->p_acflag) == 0) #define DRM_AGP_FIND_DEVICE() agp_find_device(0) #define DRM_MTRR_WC MTRR_TYPE_WC #define jiffies hardclock_ticks @@ -440,10 +451,12 @@ char *name; } drm_pci_id_list_t; +#define DRM_AUTH 0x1 +#define DRM_MASTER 0x2 +#define DRM_ROOT_ONLY 0x4 typedef struct drm_ioctl_desc { int (*func)(DRM_IOCTL_ARGS); - int auth_needed; - int root_only; + int flags; } drm_ioctl_desc_t; typedef struct drm_magic_entry { @@ -491,14 +504,24 @@ int high_mark; /* High water mark */ } drm_freelist_t; +typedef struct drm_dma_handle { + void *vaddr; + bus_addr_t busaddr; +#if defined(__FreeBSD__) + bus_dma_tag_t tag; + bus_dmamap_t map; +#elif defined(__NetBSD__) + bus_dma_segment_t seg; +#endif +} drm_dma_handle_t; + typedef struct drm_buf_entry { int buf_size; int buf_count; drm_buf_t *buflist; int seg_count; + drm_dma_handle_t **seglist; int page_order; - vm_offset_t *seglist; - dma_addr_t *seglist_bus; drm_freelist_t freelist; } drm_buf_entry_t; @@ -507,6 +530,7 @@ struct drm_file { TAILQ_ENTRY(drm_file) link; int authenticated; + int master; int minor; pid_t pid; uid_t uid; @@ -571,6 +595,7 @@ void *virtual; int pages; dma_addr_t *busaddr; + drm_dma_handle_t *dmah; /* Handle to PCI memory for ATI PCIGART table */ } drm_sg_mem_t; typedef TAILQ_HEAD(drm_map_list, drm_local_map) drm_map_list_t; @@ -585,10 +610,10 @@ int mtrr; /* Boolean: MTRR used */ /* Private data */ int rid; /* PCI resource ID for bus_space */ - int kernel_owned; /* Boolean: 1 = initmapped, 0 = addmapped */ struct resource *bsr; bus_space_tag_t bst; bus_space_handle_t bsh; + drm_dma_handle_t *dmah; TAILQ_ENTRY(drm_local_map) link; } drm_local_map_t; @@ -600,25 +625,27 @@ int pid; } drm_vbl_sig_t; -/** - * DRM device functions structure - */ -struct drm_device { -#if defined(__NetBSD__) || defined(__OpenBSD__) - struct device device; /* softc is an extension of struct device */ -#endif - - /* Beginning of driver-config section */ - int (*preinit)(struct drm_device *, unsigned long flags); - int (*postinit)(struct drm_device *, unsigned long flags); - void (*prerelease)(struct drm_device *, void *filp); - void (*pretakedown)(struct drm_device *); - int (*postcleanup)(struct drm_device *); - int (*presetup)(struct drm_device *); - int (*postsetup)(struct drm_device *); - int (*open_helper)(struct drm_device *, drm_file_t *); - void (*free_filp_priv)(struct drm_device *, drm_file_t *); - void (*release)(struct drm_device *, void *filp); +/* location of GART table */ +#define DRM_ATI_GART_MAIN 1 +#define DRM_ATI_GART_FB 2 + +typedef struct ati_pcigart_info { + int gart_table_location; + int is_pcie; + void *addr; + dma_addr_t bus_addr; + drm_local_map_t mapping; +} drm_ati_pcigart_info; + +struct drm_driver_info { + int (*load)(struct drm_device *, unsigned long flags); + int (*firstopen)(struct drm_device *); + int (*open)(struct drm_device *, drm_file_t *); + void (*preclose)(struct drm_device *, void *filp); + void (*postclose)(struct drm_device *, drm_file_t *); + void (*lastclose)(struct drm_device *); + int (*unload)(struct drm_device *); + void (*reclaim_buffers_locked)(struct drm_device *, void *filp); int (*dma_ioctl)(DRM_IOCTL_ARGS); void (*dma_ready)(struct drm_device *); int (*dma_quiescent)(struct drm_device *); @@ -637,17 +664,32 @@ void (*irq_handler)(DRM_IRQ_ARGS); int (*vblank_wait)(drm_device_t *dev, unsigned int *sequence); - drm_ioctl_desc_t *driver_ioctls; - int max_driver_ioctl; - - int dev_priv_size; + drm_pci_id_list_t *id_entry; /* PCI ID, name, and chipset private */ - int driver_major; - int driver_minor; - int driver_patchlevel; - const char *driver_name; /* Simple driver name */ - const char *driver_desc; /* Longer driver name */ - const char *driver_date; /* Date of last major changes. */ + /** + * Called by \c drm_device_is_agp. Typically used to determine if a + * card is really attached to AGP or not. + * + * \param dev DRM device handle + * + * \returns + * One of three values is returned depending on whether or not the + * card is absolutely \b not AGP (return of 0), absolutely \b is AGP + * (return of 1), or may or may not be AGP (return of 2). + */ + int (*device_is_agp) (struct drm_device * dev); + + drm_ioctl_desc_t *ioctls; + int max_ioctl; + + int buf_priv_size; + + int major; + int minor; + int patchlevel; + const char *name; /* Simple driver name */ + const char *desc; /* Longer driver name */ + const char *date; /* Date of last major changes. */ unsigned use_agp :1; unsigned require_agp :1; @@ -658,7 +700,21 @@ unsigned use_irq :1; unsigned use_vbl_irq :1; unsigned use_mtrr :1; - /* End of driver-config section */ +}; + +/* Length for the array of resource pointers for drm_get_resource_*. */ +#define DRM_MAX_PCI_RESOURCE 3 + +/** + * DRM device functions structure + */ +struct drm_device { +#if defined(__NetBSD__) || defined(__OpenBSD__) + struct device device; /* softc is an extension of struct device */ +#endif + + struct drm_driver_info driver; + drm_pci_id_list_t *id_entry; /* PCI ID, name, and chipset private */ char *unique; /* Unique identifier: e.g., busid */ int unique_len; /* Length of unique field */ @@ -708,10 +764,13 @@ struct resource *irqr; /* Resource for interrupt used by board */ #elif defined(__NetBSD__) || defined(__OpenBSD__) struct pci_attach_args pa; - pci_intr_handle_t ih; #endif void *irqh; /* Handle from bus_setup_intr */ + /* Storage of resource pointers for drm_get_resource_* */ + struct resource *pcir[DRM_MAX_PCI_RESOURCE]; + int pcirid[DRM_MAX_PCI_RESOURCE]; + int pci_domain; int pci_bus; int pci_slot; @@ -735,6 +794,7 @@ drm_sg_mem_t *sg; /* Scatter gather memory */ atomic_t *ctx_bitmap; void *dev_private; + unsigned int agp_buffer_token; drm_local_map_t *agp_buffer_map; }; @@ -786,7 +846,7 @@ void *drm_ioremap(drm_device_t *dev, drm_local_map_t *map); void drm_ioremapfree(drm_local_map_t *map); int drm_mtrr_add(unsigned long offset, size_t size, int flags); -int drm_mtrr_del(unsigned long offset, size_t size, int flags); +int drm_mtrr_del(int handle, unsigned long offset, size_t size, int flags); int drm_context_switch(drm_device_t *dev, int old, int new); int drm_context_switch_complete(drm_device_t *dev, int new); @@ -809,16 +869,21 @@ /* Buffer management support (drm_bufs.c) */ unsigned long drm_get_resource_start(drm_device_t *dev, unsigned int resource); unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource); -int drm_initmap(drm_device_t *dev, unsigned long start, unsigned long len, - unsigned int resource, int type, int flags); -void drm_remove_map(drm_device_t *dev, drm_local_map_t *map); +void drm_rmmap(drm_device_t *dev, drm_local_map_t *map); int drm_order(unsigned long size); +int drm_addmap(drm_device_t * dev, unsigned long offset, unsigned long size, + drm_map_type_t type, drm_map_flags_t flags, + drm_local_map_t **map_ptr); +int drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request); +int drm_addbufs_sg(drm_device_t *dev, drm_buf_desc_t *request); +int drm_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request); /* DMA support (drm_dma.c) */ int drm_dma_setup(drm_device_t *dev); void drm_dma_takedown(drm_device_t *dev); void drm_free_buffer(drm_device_t *dev, drm_buf_t *buf); void drm_reclaim_buffers(drm_device_t *dev, DRMFILE filp); +#define drm_core_reclaim_buffers drm_reclaim_buffers /* IRQ support (drm_irq.c) */ int drm_irq_install(drm_device_t *dev); @@ -834,12 +899,18 @@ int drm_device_is_agp(drm_device_t *dev); int drm_device_is_pcie(drm_device_t *dev); drm_agp_head_t *drm_agp_init(void); -void drm_agp_uninit(void); -void drm_agp_do_release(void); +int drm_agp_acquire(drm_device_t *dev); +int drm_agp_release(drm_device_t *dev); +int drm_agp_info(drm_device_t * dev, drm_agp_info_t *info); +int drm_agp_enable(drm_device_t *dev, drm_agp_mode_t mode); void *drm_agp_allocate_memory(size_t pages, u32 type); int drm_agp_free_memory(void *handle); int drm_agp_bind_memory(void *handle, off_t start); int drm_agp_unbind_memory(void *handle); +int drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request); +int drm_agp_free(drm_device_t *dev, drm_agp_buffer_t *request); +int drm_agp_bind(drm_device_t *dev, drm_agp_binding_t *request); +int drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request); /* Scatter Gather Support (drm_scatter.c) */ void drm_sg_cleanup(drm_sg_mem_t *entry); @@ -851,10 +922,10 @@ #endif /* __FreeBSD__ */ /* ATI PCIGART support (ati_pcigart.c) */ -int drm_ati_pcigart_init(drm_device_t *dev, unsigned long *addr, - dma_addr_t *bus_addr, int is_pcie); -int drm_ati_pcigart_cleanup(drm_device_t *dev, unsigned long addr, - dma_addr_t bus_addr); +int drm_ati_pcigart_init(drm_device_t *dev, + drm_ati_pcigart_info *gart_info); +int drm_ati_pcigart_cleanup(drm_device_t *dev, + drm_ati_pcigart_info *gart_info); /* Locking IOCTL support (drm_drv.c) */ int drm_lock(DRM_IOCTL_ARGS); @@ -891,9 +962,9 @@ int drm_authmagic(DRM_IOCTL_ARGS); /* Buffer management support (drm_bufs.c) */ -int drm_addmap(DRM_IOCTL_ARGS); -int drm_rmmap(DRM_IOCTL_ARGS); -int drm_addbufs(DRM_IOCTL_ARGS); +int drm_addmap_ioctl(DRM_IOCTL_ARGS); +int drm_rmmap_ioctl(DRM_IOCTL_ARGS); +int drm_addbufs_ioctl(DRM_IOCTL_ARGS); int drm_infobufs(DRM_IOCTL_ARGS); int drm_markbufs(DRM_IOCTL_ARGS); int drm_freebufs(DRM_IOCTL_ARGS); @@ -907,24 +978,23 @@ int drm_wait_vblank(DRM_IOCTL_ARGS); /* AGP/GART support (drm_agpsupport.c) */ -int drm_agp_acquire(DRM_IOCTL_ARGS); -int drm_agp_release(DRM_IOCTL_ARGS); -int drm_agp_enable(DRM_IOCTL_ARGS); -int drm_agp_info(DRM_IOCTL_ARGS); -int drm_agp_alloc(DRM_IOCTL_ARGS); -int drm_agp_free(DRM_IOCTL_ARGS); -int drm_agp_unbind(DRM_IOCTL_ARGS); -int drm_agp_bind(DRM_IOCTL_ARGS); +int drm_agp_acquire_ioctl(DRM_IOCTL_ARGS); +int drm_agp_release_ioctl(DRM_IOCTL_ARGS); +int drm_agp_enable_ioctl(DRM_IOCTL_ARGS); +int drm_agp_info_ioctl(DRM_IOCTL_ARGS); +int drm_agp_alloc_ioctl(DRM_IOCTL_ARGS); +int drm_agp_free_ioctl(DRM_IOCTL_ARGS); +int drm_agp_unbind_ioctl(DRM_IOCTL_ARGS); +int drm_agp_bind_ioctl(DRM_IOCTL_ARGS); /* Scatter Gather Support (drm_scatter.c) */ int drm_sg_alloc(DRM_IOCTL_ARGS); int drm_sg_free(DRM_IOCTL_ARGS); /* consistent PCI memory functions (drm_pci.c) */ -void *drm_pci_alloc(drm_device_t *dev, size_t size, size_t align, - dma_addr_t maxaddr, dma_addr_t *busaddr); -void drm_pci_free(drm_device_t *dev, size_t size, void *vaddr, - dma_addr_t busaddr); +drm_dma_handle_t *drm_pci_alloc(drm_device_t *dev, size_t size, size_t align, + dma_addr_t maxaddr); +void drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah); /* Inline replacements for DRM_IOREMAP macros */ static __inline__ void drm_core_ioremap(struct drm_local_map *map, struct drm_device *dev) Index: dev/drm/drm_agpsupport.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/drm_agpsupport.c,v retrieving revision 1.2 diff -u -r1.2 drm_agpsupport.c --- dev/drm/drm_agpsupport.c 20 Jul 2005 21:10:57 -0000 1.2 +++ dev/drm/drm_agpsupport.c 23 Nov 2005 10:13:23 -0000 @@ -29,9 +29,11 @@ * Rickard E. (Rik) Faith * Gareth Hughes * - * $FreeBSD: src/sys/dev/drm/drm_agpsupport.c,v 1.2 2005/07/20 21:10:57 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" #ifdef __FreeBSD__ @@ -39,9 +41,20 @@ #include #endif +/* Returns 1 if AGP or 0 if not. */ static int drm_device_find_capability(drm_device_t *dev, int cap) { + int ret; + + if (dev->driver.device_is_agp != NULL) { + ret = (*dev->driver.device_is_agp)(dev); + + if (ret != DRM_MIGHT_BE_AGP) { + return ret == 2; + } + } + #ifdef __FreeBSD__ /* Code taken from agp.c. IWBNI that was a public interface. */ u_int32_t status; @@ -77,87 +90,95 @@ #endif } -int -drm_device_is_agp(drm_device_t *dev) +int drm_device_is_agp(drm_device_t *dev) { return (drm_device_find_capability(dev, PCIY_AGP)); } -int -drm_device_is_pcie(drm_device_t *dev) +int drm_device_is_pcie(drm_device_t *dev) { return (drm_device_find_capability(dev, PCIY_EXPRESS)); } -int drm_agp_info(DRM_IOCTL_ARGS) +int drm_agp_info(drm_device_t * dev, drm_agp_info_t *info) { - DRM_DEVICE; struct agp_info *kern; - drm_agp_info_t info; if (!dev->agp || !dev->agp->acquired) return EINVAL; kern = &dev->agp->info; agp_get_info(dev->agp->agpdev, kern); - info.agp_version_major = 1; - info.agp_version_minor = 0; - info.mode = kern->ai_mode; - info.aperture_base = kern->ai_aperture_base; - info.aperture_size = kern->ai_aperture_size; - info.memory_allowed = kern->ai_memory_allowed; - info.memory_used = kern->ai_memory_used; - info.id_vendor = kern->ai_devid & 0xffff; - info.id_device = kern->ai_devid >> 16; + info->agp_version_major = 1; + info->agp_version_minor = 0; + info->mode = kern->ai_mode; + info->aperture_base = kern->ai_aperture_base; + info->aperture_size = kern->ai_aperture_size; + info->memory_allowed = kern->ai_memory_allowed; + info->memory_used = kern->ai_memory_used; + info->id_vendor = kern->ai_devid & 0xffff; + info->id_device = kern->ai_devid >> 16; + + return 0; +} + +int drm_agp_info_ioctl(DRM_IOCTL_ARGS) +{ + int err; + drm_agp_info_t info; + DRM_DEVICE; + + err = drm_agp_info(dev, &info); + if (err != 0) + return err; *(drm_agp_info_t *) data = info; return 0; } -int drm_agp_acquire(DRM_IOCTL_ARGS) +int drm_agp_acquire_ioctl(DRM_IOCTL_ARGS) { DRM_DEVICE; - int retcode; + + return drm_agp_acquire(dev); +} + +int drm_agp_acquire(drm_device_t *dev) +{ + int retcode; if (!dev->agp || dev->agp->acquired) return EINVAL; + retcode = agp_acquire(dev->agp->agpdev); if (retcode) return retcode; + dev->agp->acquired = 1; return 0; } -int drm_agp_release(DRM_IOCTL_ARGS) +int drm_agp_release_ioctl(DRM_IOCTL_ARGS) { DRM_DEVICE; + return drm_agp_release(dev); +} + +int drm_agp_release(drm_device_t * dev) +{ if (!dev->agp || !dev->agp->acquired) return EINVAL; agp_release(dev->agp->agpdev); dev->agp->acquired = 0; return 0; - } -void drm_agp_do_release(void) +int drm_agp_enable(drm_device_t *dev, drm_agp_mode_t mode) { - device_t agpdev; - - agpdev = DRM_AGP_FIND_DEVICE(); - if (agpdev) - agp_release(agpdev); -} - -int drm_agp_enable(DRM_IOCTL_ARGS) -{ - DRM_DEVICE; - drm_agp_mode_t mode; if (!dev->agp || !dev->agp->acquired) return EINVAL; - - mode = *(drm_agp_mode_t *) data; dev->agp->mode = mode.mode; agp_enable(dev->agp->agpdev, mode.mode); @@ -166,10 +187,18 @@ return 0; } -int drm_agp_alloc(DRM_IOCTL_ARGS) +int drm_agp_enable_ioctl(DRM_IOCTL_ARGS) { + drm_agp_mode_t mode; DRM_DEVICE; - drm_agp_buffer_t request; + + mode = *(drm_agp_mode_t *) data; + + return drm_agp_enable(dev, mode); +} + +int drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request) +{ drm_agp_mem_t *entry; void *handle; unsigned long pages; @@ -179,16 +208,17 @@ if (!dev->agp || !dev->agp->acquired) return EINVAL; - request = *(drm_agp_buffer_t *) data; - entry = malloc(sizeof(*entry), M_DRM, M_NOWAIT | M_ZERO); if (entry == NULL) return ENOMEM; - pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE; - type = (u_int32_t) request.type; + pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE; + type = (u_int32_t) request->type; - if (!(handle = drm_agp_allocate_memory(pages, type))) { + DRM_UNLOCK(); + handle = drm_agp_allocate_memory(pages, type); + DRM_LOCK(); + if (handle == NULL) { free(entry, M_DRM); return ENOMEM; } @@ -204,12 +234,27 @@ agp_memory_info(dev->agp->agpdev, entry->handle, &info); - request.handle = (unsigned long) entry->handle; - request.physical = info.ami_physical; + request->handle = (unsigned long) entry->handle; + request->physical = info.ami_physical; + + return 0; +} + +int drm_agp_alloc_ioctl(DRM_IOCTL_ARGS) +{ + DRM_DEVICE; + drm_agp_buffer_t request; + int retcode; + + request = *(drm_agp_buffer_t *) data; + + DRM_LOCK(); + retcode = drm_agp_alloc(dev, &request); + DRM_UNLOCK(); *(drm_agp_buffer_t *) data = request; - return 0; + return retcode; } static drm_agp_mem_t * drm_agp_lookup_entry(drm_device_t *dev, void *handle) @@ -222,64 +267,94 @@ return NULL; } -int drm_agp_unbind(DRM_IOCTL_ARGS) +int drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request) { - DRM_DEVICE; - drm_agp_binding_t request; drm_agp_mem_t *entry; int retcode; if (!dev->agp || !dev->agp->acquired) return EINVAL; - request = *(drm_agp_binding_t *) data; - if (!(entry = drm_agp_lookup_entry(dev, (void *)request.handle))) + + entry = drm_agp_lookup_entry(dev, (void *)request->handle); + if (entry == NULL || !entry->bound) return EINVAL; - if (!entry->bound) return EINVAL; + + DRM_UNLOCK(); retcode = drm_agp_unbind_memory(entry->handle); - if (!retcode) - { - entry->bound=0; - return 0; - } - else - return retcode; + DRM_LOCK(); + + if (retcode == 0) + entry->bound = 0; + + return retcode; } -int drm_agp_bind(DRM_IOCTL_ARGS) +int drm_agp_unbind_ioctl(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_agp_binding_t request; + int retcode; + + request = *(drm_agp_binding_t *) data; + + DRM_LOCK(); + retcode = drm_agp_unbind(dev, &request); + DRM_UNLOCK(); + + return retcode; +} + +int drm_agp_bind(drm_device_t *dev, drm_agp_binding_t *request) +{ drm_agp_mem_t *entry; int retcode; int page; - DRM_DEBUG("agp_bind, page_size=%x\n", PAGE_SIZE); if (!dev->agp || !dev->agp->acquired) return EINVAL; - request = *(drm_agp_binding_t *) data; - if (!(entry = drm_agp_lookup_entry(dev, (void *)request.handle))) + + DRM_DEBUG("agp_bind, page_size=%x\n", PAGE_SIZE); + + entry = drm_agp_lookup_entry(dev, (void *)request->handle); + if (entry == NULL || entry->bound) return EINVAL; - if (entry->bound) return EINVAL; - page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE; - if ((retcode = drm_agp_bind_memory(entry->handle, page))) - return retcode; - entry->bound = dev->agp->base + (page << PAGE_SHIFT); - return 0; + + page = (request->offset + PAGE_SIZE - 1) / PAGE_SIZE; + + DRM_UNLOCK(); + retcode = drm_agp_bind_memory(entry->handle, page); + DRM_LOCK(); + if (retcode == 0) + entry->bound = dev->agp->base + (page << PAGE_SHIFT); + + return retcode; } -int drm_agp_free(DRM_IOCTL_ARGS) +int drm_agp_bind_ioctl(DRM_IOCTL_ARGS) { DRM_DEVICE; - drm_agp_buffer_t request; + drm_agp_binding_t request; + int retcode; + + request = *(drm_agp_binding_t *) data; + + DRM_LOCK(); + retcode = drm_agp_bind(dev, &request); + DRM_UNLOCK(); + + return retcode; +} + +int drm_agp_free(drm_device_t *dev, drm_agp_buffer_t *request) +{ drm_agp_mem_t *entry; if (!dev->agp || !dev->agp->acquired) return EINVAL; - request = *(drm_agp_buffer_t *) data; - if (!(entry = drm_agp_lookup_entry(dev, (void*)request.handle))) + + entry = drm_agp_lookup_entry(dev, (void*)request->handle); + if (entry == NULL) return EINVAL; - if (entry->bound) - drm_agp_unbind_memory(entry->handle); if (entry->prev) entry->prev->next = entry->next; @@ -287,9 +362,32 @@ dev->agp->memory = entry->next; if (entry->next) entry->next->prev = entry->prev; + + DRM_UNLOCK(); + if (entry->bound) + drm_agp_unbind_memory(entry->handle); drm_agp_free_memory(entry->handle); + DRM_LOCK(); + free(entry, M_DRM); + return 0; + +} + +int drm_agp_free_ioctl(DRM_IOCTL_ARGS) +{ + DRM_DEVICE; + drm_agp_buffer_t request; + int retcode; + + request = *(drm_agp_buffer_t *) data; + + DRM_LOCK(); + retcode = drm_agp_free(dev, &request); + DRM_UNLOCK(); + + return retcode; } drm_agp_head_t *drm_agp_init(void) @@ -318,12 +416,6 @@ return head; } -void drm_agp_uninit(void) -{ -/* FIXME: What goes here */ -} - - void *drm_agp_allocate_memory(size_t pages, u32 type) { device_t agpdev; Index: dev/drm/drm_atomic.h =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/drm_atomic.h,v retrieving revision 1.1 diff -u -r1.1 drm_atomic.h --- dev/drm/drm_atomic.h 16 Apr 2005 03:44:43 -0000 1.1 +++ dev/drm/drm_atomic.h 23 Nov 2005 10:13:23 -0000 @@ -27,10 +27,11 @@ * 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. - * - * $FreeBSD: src/sys/dev/drm/drm_atomic.h,v 1.1 2005/04/16 03:44:43 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + /* Many of these implementations are rather fake, but good enough. */ typedef u_int32_t atomic_t; Index: dev/drm/drm_auth.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/drm_auth.c,v retrieving revision 1.1 diff -u -r1.1 drm_auth.c --- dev/drm/drm_auth.c 16 Apr 2005 03:44:43 -0000 1.1 +++ dev/drm/drm_auth.c 23 Nov 2005 10:13:23 -0000 @@ -29,9 +29,11 @@ * Rickard E. (Rik) Faith * Gareth Hughes * - * $FreeBSD: src/sys/dev/drm/drm_auth.c,v 1.1 2005/04/16 03:44:43 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" static int drm_hash_magic(drm_magic_t magic) Index: dev/drm/drm_bufs.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/drm_bufs.c,v retrieving revision 1.2 diff -u -r1.2 drm_bufs.c --- dev/drm/drm_bufs.c 24 Apr 2005 19:03:32 -0000 1.2 +++ dev/drm/drm_bufs.c 23 Nov 2005 10:13:23 -0000 @@ -29,9 +29,13 @@ * Rickard E. (Rik) Faith * Gareth Hughes * - * $FreeBSD: src/sys/dev/drm/drm_bufs.c,v 1.2 2005/04/24 19:03:32 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + +#include "dev/pci/pcireg.h" + #include "dev/drm/drmP.h" /* @@ -50,146 +54,98 @@ return order; } -unsigned long drm_get_resource_start(drm_device_t *dev, unsigned int resource) +/* Allocation of PCI memory resources (framebuffer, registers, etc.) for + * drm_get_resource_*. Note that they are not RF_ACTIVE, so there's no virtual + * address for accessing them. Cleaned up at unload. + */ +static int drm_alloc_resource(drm_device_t *dev, int resource) { - struct resource *bsr; - unsigned long offset; - - resource = resource * 4 + 0x10; + if (resource >= DRM_MAX_PCI_RESOURCE) { + DRM_ERROR("Resource %d too large\n", resource); + return 1; + } - bsr = bus_alloc_resource_any(dev->device, SYS_RES_MEMORY, &resource, - RF_ACTIVE | RF_SHAREABLE); - if (bsr == NULL) { - DRM_ERROR("Couldn't find resource 0x%x\n", resource); + DRM_UNLOCK(); + if (dev->pcir[resource] != NULL) { + DRM_LOCK(); return 0; } - offset = rman_get_start(bsr); - - bus_release_resource(dev->device, SYS_RES_MEMORY, resource, bsr); - - return offset; -} - -unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource) -{ - struct resource *bsr; - unsigned long len; - - resource = resource * 4 + 0x10; + dev->pcirid[resource] = PCIR_BAR(resource); + dev->pcir[resource] = bus_alloc_resource_any(dev->device, + SYS_RES_MEMORY, &dev->pcirid[resource], RF_SHAREABLE); + DRM_LOCK(); - bsr = bus_alloc_resource_any(dev->device, SYS_RES_MEMORY, &resource, - RF_ACTIVE | RF_SHAREABLE); - if (bsr == NULL) { + if (dev->pcir[resource] == NULL) { DRM_ERROR("Couldn't find resource 0x%x\n", resource); - return ENOMEM; + return 1; } - len = rman_get_size(bsr); - - bus_release_resource(dev->device, SYS_RES_MEMORY, resource, bsr); - - return len; + return 0; } -int drm_initmap(drm_device_t *dev, unsigned long start, unsigned long len, - unsigned int resource, int type, int flags) +unsigned long drm_get_resource_start(drm_device_t *dev, unsigned int resource) { - drm_local_map_t *map; - struct resource *bsr; - - if (type != _DRM_REGISTERS && type != _DRM_FRAME_BUFFER) - return EINVAL; - if (len == 0) - return EINVAL; - - map = malloc(sizeof(*map), M_DRM, M_ZERO | M_NOWAIT); - if (map == NULL) - return ENOMEM; - - map->rid = resource * 4 + 0x10; - bsr = bus_alloc_resource_any(dev->device, SYS_RES_MEMORY, &map->rid, - RF_ACTIVE | RF_SHAREABLE); - if (bsr == NULL) { - DRM_ERROR("Couldn't allocate %s resource\n", - ((type == _DRM_REGISTERS) ? "mmio" : "framebuffer")); - free(map, M_DRM); - return ENOMEM; - } - - map->kernel_owned = 1; - map->type = type; - map->flags = flags; - map->bsr = bsr; - map->bst = rman_get_bustag(bsr); - map->bsh = rman_get_bushandle(bsr); - map->offset = start; - map->size = len; - - if (type == _DRM_REGISTERS) - map->handle = rman_get_virtual(bsr); - - DRM_DEBUG("initmap %d,0x%x@0x%lx/0x%lx\n", map->type, map->flags, - map->offset, map->size); - - if (map->flags & _DRM_WRITE_COMBINING) { - int err; + if (drm_alloc_resource(dev, resource) != 0) + return 0; - err = drm_mtrr_add(map->offset, map->size, DRM_MTRR_WC); - if (err == 0) - map->mtrr = 1; - } + return rman_get_start(dev->pcir[resource]); +} - DRM_LOCK(); - TAILQ_INSERT_TAIL(&dev->maplist, map, link); - DRM_UNLOCK(); +unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource) +{ + if (drm_alloc_resource(dev, resource) != 0) + return 0; - return 0; + return rman_get_size(dev->pcir[resource]); } -int drm_addmap(DRM_IOCTL_ARGS) +int drm_addmap(drm_device_t * dev, unsigned long offset, unsigned long size, + drm_map_type_t type, drm_map_flags_t flags, drm_local_map_t **map_ptr) { - DRM_DEVICE; - drm_map_t request; drm_local_map_t *map; - dma_addr_t bus_addr; - - if (!(dev->flags & (FREAD|FWRITE))) - return DRM_ERR(EACCES); /* Require read/write */ - - DRM_COPY_FROM_USER_IOCTL( request, (drm_map_t *)data, sizeof(drm_map_t) ); + int align; + /*drm_agp_mem_t *entry; + int valid;*/ /* Only allow shared memory to be removable since we only keep enough * book keeping information about shared memory to allow for removal * when processes fork. */ - if ((request.flags & _DRM_REMOVABLE) && request.type != _DRM_SHM) + if ((flags & _DRM_REMOVABLE) && type != _DRM_SHM) { + DRM_ERROR("Requested removable map for non-DRM_SHM\n"); return EINVAL; - if ((request.offset & PAGE_MASK) || (request.size & PAGE_MASK)) + } + if ((offset & PAGE_MASK) || (size & PAGE_MASK)) { + DRM_ERROR("offset/size not page aligned: 0x%lx/0x%lx\n", + offset, size); return EINVAL; - if (request.offset + request.size < request.offset) + } + if (offset + size < offset) { + DRM_ERROR("offset and size wrap around: 0x%lx/0x%lx\n", + offset, size); return EINVAL; + } - DRM_DEBUG("offset = 0x%08lx, size = 0x%08lx, type = %d\n", - request.offset, request.size, request.type); + DRM_DEBUG("offset = 0x%08lx, size = 0x%08lx, type = %d\n", offset, + size, type); /* Check if this is just another version of a kernel-allocated map, and * just hand that back if so. */ - if (request.type == _DRM_REGISTERS || request.type == _DRM_FRAME_BUFFER) - { - DRM_LOCK(); + if (type == _DRM_REGISTERS || type == _DRM_FRAME_BUFFER || + type == _DRM_SHM) { TAILQ_FOREACH(map, &dev->maplist, link) { - if (map->kernel_owned && map->type == request.type && - map->offset == request.offset) { - /* XXX: this size setting is questionable. */ - map->size = request.size; - DRM_DEBUG("Found kernel map %d\n", request.type); + if (map->type == type && (map->offset == offset || + (map->type == _DRM_SHM && + map->flags == _DRM_CONTAINS_LOCK))) { + map->size = size; + DRM_DEBUG("Found kernel map %d\n", type); goto done; } } - DRM_UNLOCK(); } + DRM_UNLOCK(); /* Allocate a new map structure, fill it in, and do any type-specific * initialization necessary. @@ -198,10 +154,10 @@ if ( !map ) return DRM_ERR(ENOMEM); - map->offset = request.offset; - map->size = request.size; - map->type = request.type; - map->flags = request.flags; + map->offset = offset; + map->size = size; + map->type = type; + map->flags = flags; switch ( map->type ) { case _DRM_REGISTERS: @@ -236,8 +192,21 @@ } break; case _DRM_AGP: + /*valid = 0;*/ map->offset += dev->agp->base; map->mtrr = dev->agp->mtrr; /* for getmap */ + /*for (entry = dev->agp->memory; entry; entry = entry->next) { + if ((map->offset >= entry->bound) && + (map->offset + map->size <= + entry->bound + entry->pages * PAGE_SIZE)) { + valid = 1; + break; + } + } + if (!valid) { + free(map, M_DRM); + return DRM_ERR(EACCES); + }*/ break; case _DRM_SCATTER_GATHER: if (!dev->sg) { @@ -247,15 +216,25 @@ map->offset = map->offset + dev->sg->handle; break; case _DRM_CONSISTENT: - map->handle = drm_pci_alloc(dev, map->size, map->size, - 0xfffffffful, &bus_addr); - if (map->handle == NULL) { + /* Unfortunately, we don't get any alignment specification from + * the caller, so we have to guess. drm_pci_alloc requires + * a power-of-two alignment, so try to align the bus address of + * the map to it size if possible, otherwise just assume + * PAGE_SIZE alignment. + */ + align = map->size; + if ((align & (align - 1)) != 0) + align = PAGE_SIZE; + map->dmah = drm_pci_alloc(dev, map->size, align, 0xfffffffful); + if (map->dmah == NULL) { free(map, M_DRM); - return ENOMEM; + return DRM_ERR(ENOMEM); } - map->offset = (unsigned long)bus_addr; + map->handle = map->dmah->vaddr; + map->offset = map->dmah->busaddr; break; default: + DRM_ERROR("Bad map type %d\n", map->type); free(map, M_DRM); return DRM_ERR(EINVAL); } @@ -265,26 +244,53 @@ done: /* Jumped to, with lock held, when a kernel map is found. */ + + DRM_DEBUG("Added map %d 0x%lx/0x%lx\n", map->type, map->offset, + map->size); + + *map_ptr = map; + + return 0; +} + +int drm_addmap_ioctl(DRM_IOCTL_ARGS) +{ + drm_map_t request; + drm_local_map_t *map; + int err; + DRM_DEVICE; + + if (!(dev->flags & (FREAD|FWRITE))) + return DRM_ERR(EACCES); /* Require read/write */ + + DRM_COPY_FROM_USER_IOCTL(request, (drm_map_t *)data, sizeof(drm_map_t)); + + if (!DRM_SUSER(p) && request.type != _DRM_AGP) + return DRM_ERR(EACCES); + + DRM_LOCK(); + err = drm_addmap(dev, request.offset, request.size, request.type, + request.flags, &map); + DRM_UNLOCK(); + if (err != 0) + return err; + request.offset = map->offset; request.size = map->size; request.type = map->type; request.flags = map->flags; request.mtrr = map->mtrr; request.handle = map->handle; - DRM_UNLOCK(); - DRM_DEBUG("Added map %d 0x%lx/0x%lx\n", request.type, request.offset, request.size); - - if ( request.type != _DRM_SHM ) { + if (request.type != _DRM_SHM) { request.handle = (void *)request.offset; } - - DRM_COPY_TO_USER_IOCTL( (drm_map_t *)data, request, sizeof(drm_map_t) ); + DRM_COPY_TO_USER_IOCTL((drm_map_t *)data, request, sizeof(drm_map_t)); return 0; } -void drm_remove_map(drm_device_t *dev, drm_local_map_t *map) +void drm_rmmap(drm_device_t *dev, drm_local_map_t *map) { DRM_SPINLOCK_ASSERT(&dev->dev_lock); @@ -299,7 +305,7 @@ if (map->mtrr) { int __unused retcode; - retcode = drm_mtrr_del(map->offset, map->size, + retcode = drm_mtrr_del(0, map->offset, map->size, DRM_MTRR_WC); DRM_DEBUG("mtrr_del = %d\n", retcode); } @@ -311,7 +317,7 @@ case _DRM_SCATTER_GATHER: break; case _DRM_CONSISTENT: - drm_pci_free(dev, map->size, map->handle, map->offset); + drm_pci_free(dev, map->dmah); break; } @@ -327,7 +333,7 @@ * isn't in use. */ -int drm_rmmap(DRM_IOCTL_ARGS) +int drm_rmmap_ioctl(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_local_map_t *map; @@ -348,7 +354,7 @@ return DRM_ERR(EINVAL); } - drm_remove_map(dev, map); + drm_rmmap(dev, map); DRM_UNLOCK(); @@ -362,12 +368,9 @@ if (entry->seg_count) { for (i = 0; i < entry->seg_count; i++) { - drm_pci_free(dev, entry->buf_size, - (void *)entry->seglist[i], - entry->seglist_bus[i]); + drm_pci_free(dev, entry->seglist[i]); } free(entry->seglist, M_DRM); - free(entry->seglist_bus, M_DRM); entry->seg_count = 0; } @@ -382,10 +385,12 @@ } } -static int drm_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request) +static int drm_do_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request) { drm_device_dma_t *dma = dev->dma; drm_buf_entry_t *entry; + /*drm_agp_mem_t *agp_entry; + int valid*/ drm_buf_t *buf; unsigned long offset; unsigned long agp_offset; @@ -419,6 +424,26 @@ DRM_DEBUG( "page_order: %d\n", page_order ); DRM_DEBUG( "total: %d\n", total ); + /* Make sure buffers are located in AGP memory that we own */ + /* Breaks MGA due to drm_alloc_agp not setting up entries for the + * memory. Safe to ignore for now because these ioctls are still + * root-only. + */ + /*valid = 0; + for (agp_entry = dev->agp->memory; agp_entry; + agp_entry = agp_entry->next) { + if ((agp_offset >= agp_entry->bound) && + (agp_offset + total * count <= + agp_entry->bound + agp_entry->pages * PAGE_SIZE)) { + valid = 1; + break; + } + } + if (!valid) { + DRM_DEBUG("zone invalid\n"); + return DRM_ERR(EINVAL); + }*/ + entry = &dma->bufs[order]; entry->buflist = malloc(count * sizeof(*entry->buflist), M_DRM, @@ -446,7 +471,7 @@ buf->pending = 0; buf->filp = NULL; - buf->dev_priv_size = dev->dev_priv_size; + buf->dev_priv_size = dev->driver.buf_priv_size; buf->dev_private = malloc(buf->dev_priv_size, M_DRM, M_NOWAIT | M_ZERO); if (buf->dev_private == NULL) { @@ -491,7 +516,7 @@ return 0; } -static int drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request) +static int drm_do_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request) { drm_device_dma_t *dma = dev->dma; int count; @@ -500,7 +525,6 @@ int total; int page_order; drm_buf_entry_t *entry; - vm_offset_t vaddr; drm_buf_t *buf; int alignment; unsigned long offset; @@ -509,7 +533,6 @@ int page_count; unsigned long *temp_pagelist; drm_buf_t **temp_buflist; - dma_addr_t bus_addr; count = request->count; order = drm_order(request->size); @@ -529,8 +552,6 @@ M_NOWAIT | M_ZERO); entry->seglist = malloc(count * sizeof(*entry->seglist), M_DRM, M_NOWAIT | M_ZERO); - entry->seglist_bus = malloc(count * sizeof(*entry->seglist_bus), M_DRM, - M_NOWAIT | M_ZERO); /* Keep the original pagelist until we know all the allocations * have succeeded @@ -539,10 +560,9 @@ sizeof(*dma->pagelist), M_DRM, M_NOWAIT); if (entry->buflist == NULL || entry->seglist == NULL || - entry->seglist_bus == NULL || temp_pagelist == NULL) { + temp_pagelist == NULL) { free(entry->buflist, M_DRM); free(entry->seglist, M_DRM); - free(entry->seglist_bus, M_DRM); return DRM_ERR(ENOMEM); } @@ -558,9 +578,9 @@ page_count = 0; while ( entry->buf_count < count ) { - vaddr = (vm_offset_t)drm_pci_alloc(dev, size, alignment, - 0xfffffffful, &bus_addr); - if (vaddr == 0) { + drm_dma_handle_t *dmah = drm_pci_alloc(dev, size, alignment, + 0xfffffffful); + if (dmah == NULL) { /* Set count correctly so we free the proper amount. */ entry->buf_count = count; entry->seg_count = count; @@ -568,15 +588,14 @@ free(temp_pagelist, M_DRM); return DRM_ERR(ENOMEM); } - - entry->seglist_bus[entry->seg_count] = bus_addr; - entry->seglist[entry->seg_count++] = vaddr; + + entry->seglist[entry->seg_count++] = dmah; for ( i = 0 ; i < (1 << page_order) ; i++ ) { - DRM_DEBUG( "page %d @ 0x%08lx\n", + DRM_DEBUG( "page %d @ %p\n", dma->page_count + page_count, - (long)vaddr + PAGE_SIZE * i ); + (char *)dmah->vaddr + PAGE_SIZE * i ); temp_pagelist[dma->page_count + page_count++] = - vaddr + PAGE_SIZE * i; + (long)dmah->vaddr + PAGE_SIZE * i; } for ( offset = 0 ; offset + size <= total && entry->buf_count < count ; @@ -587,13 +606,13 @@ buf->order = order; buf->used = 0; buf->offset = (dma->byte_count + byte_count + offset); - buf->address = (void *)(vaddr + offset); - buf->bus_address = bus_addr + offset; + buf->address = ((char *)dmah->vaddr + offset); + buf->bus_address = dmah->busaddr + offset; buf->next = NULL; buf->pending = 0; buf->filp = NULL; - buf->dev_priv_size = dev->dev_priv_size; + buf->dev_priv_size = dev->driver.buf_priv_size; buf->dev_private = malloc(buf->dev_priv_size, M_DRM, M_NOWAIT | M_ZERO); if (buf->dev_private == NULL) { @@ -644,7 +663,7 @@ } -static int drm_addbufs_sg(drm_device_t *dev, drm_buf_desc_t *request) +static int drm_do_addbufs_sg(drm_device_t *dev, drm_buf_desc_t *request) { drm_device_dma_t *dma = dev->dma; drm_buf_entry_t *entry; @@ -707,7 +726,7 @@ buf->pending = 0; buf->filp = NULL; - buf->dev_priv_size = dev->dev_priv_size; + buf->dev_priv_size = dev->driver.buf_priv_size; buf->dev_private = malloc(buf->dev_priv_size, M_DRM, M_NOWAIT | M_ZERO); if (buf->dev_private == NULL) { @@ -755,23 +774,87 @@ return 0; } -int drm_addbufs(DRM_IOCTL_ARGS) +int drm_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request) { - DRM_DEVICE; - drm_buf_desc_t request; - int err; - int order; + int order, ret; - DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_desc_t *)data, sizeof(request) ); + DRM_SPINLOCK(&dev->dma_lock); - if (request.count < 0 || request.count > 4096) + if (request->count < 0 || request->count > 4096) + return DRM_ERR(EINVAL); + + order = drm_order(request->size); + if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return DRM_ERR(EINVAL); - order = drm_order(request.size); + /* No more allocations after first buffer-using ioctl. */ + if (dev->buf_use != 0) { + DRM_SPINUNLOCK(&dev->dma_lock); + return DRM_ERR(EBUSY); + } + /* No more than one allocation per order */ + if (dev->dma->bufs[order].buf_count != 0) { + DRM_SPINUNLOCK(&dev->dma_lock); + return DRM_ERR(ENOMEM); + } + + ret = drm_do_addbufs_agp(dev, request); + + DRM_SPINUNLOCK(&dev->dma_lock); + + return ret; +} + +int drm_addbufs_sg(drm_device_t *dev, drm_buf_desc_t *request) +{ + int order, ret; + + DRM_SPINLOCK(&dev->dma_lock); + + if (!DRM_SUSER(DRM_CURPROC)) + return DRM_ERR(EACCES); + + if (request->count < 0 || request->count > 4096) + return DRM_ERR(EINVAL); + + order = drm_order(request->size); if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return DRM_ERR(EINVAL); + /* No more allocations after first buffer-using ioctl. */ + if (dev->buf_use != 0) { + DRM_SPINUNLOCK(&dev->dma_lock); + return DRM_ERR(EBUSY); + } + /* No more than one allocation per order */ + if (dev->dma->bufs[order].buf_count != 0) { + DRM_SPINUNLOCK(&dev->dma_lock); + return DRM_ERR(ENOMEM); + } + + ret = drm_do_addbufs_sg(dev, request); + + DRM_SPINUNLOCK(&dev->dma_lock); + + return ret; +} + +int drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request) +{ + int order, ret; + DRM_SPINLOCK(&dev->dma_lock); + + if (!DRM_SUSER(DRM_CURPROC)) + return DRM_ERR(EACCES); + + if (request->count < 0 || request->count > 4096) + return DRM_ERR(EINVAL); + + order = drm_order(request->size); + if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) + return DRM_ERR(EINVAL); + /* No more allocations after first buffer-using ioctl. */ if (dev->buf_use != 0) { DRM_SPINUNLOCK(&dev->dma_lock); @@ -783,16 +866,31 @@ return DRM_ERR(ENOMEM); } - if ( request.flags & _DRM_AGP_BUFFER ) + ret = drm_do_addbufs_pci(dev, request); + + DRM_SPINUNLOCK(&dev->dma_lock); + + return ret; +} + +int drm_addbufs_ioctl(DRM_IOCTL_ARGS) +{ + DRM_DEVICE; + drm_buf_desc_t request; + int err; + + DRM_COPY_FROM_USER_IOCTL(request, (drm_buf_desc_t *)data, + sizeof(request)); + + if (request.flags & _DRM_AGP_BUFFER) err = drm_addbufs_agp(dev, &request); - else - if ( request.flags & _DRM_SG_BUFFER ) + else if (request.flags & _DRM_SG_BUFFER) err = drm_addbufs_sg(dev, &request); else err = drm_addbufs_pci(dev, &request); - DRM_SPINUNLOCK(&dev->dma_lock); - DRM_COPY_TO_USER_IOCTL((drm_buf_desc_t *)data, request, sizeof(request)); + DRM_COPY_TO_USER_IOCTL((drm_buf_desc_t *)data, request, + sizeof(request)); return err; } @@ -937,7 +1035,8 @@ vm_offset_t vaddr; #elif defined(__NetBSD__) || defined(__OpenBSD__) struct vnode *vn; - vm_size_t size; + voff_t foff; + vsize_t size; vaddr_t vaddr; #endif /* __NetBSD__ || __OpenBSD__ */ @@ -964,8 +1063,8 @@ if (request.count < dma->buf_count) goto done; - if ((dev->use_agp && (dma->flags & _DRM_DMA_USE_AGP)) || - (dev->use_sg && (dma->flags & _DRM_DMA_USE_SG))) { + if ((dev->driver.use_agp && (dma->flags & _DRM_DMA_USE_AGP)) || + (dev->driver.use_sg && (dma->flags & _DRM_DMA_USE_SG))) { drm_local_map_t *map = dev->agp_buffer_map; if (map == NULL) { Index: dev/drm/drm_context.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/drm_context.c,v retrieving revision 1.1 diff -u -r1.1 drm_context.c --- dev/drm/drm_context.c 16 Apr 2005 03:44:43 -0000 1.1 +++ dev/drm/drm_context.c 23 Nov 2005 10:13:23 -0000 @@ -29,9 +29,11 @@ * Rickard E. (Rik) Faith * Gareth Hughes * - * $FreeBSD: src/sys/dev/drm/drm_context.c,v 1.1 2005/04/16 03:44:43 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" /* ================================================================ @@ -229,14 +231,17 @@ int drm_resctx(DRM_IOCTL_ARGS) { drm_ctx_res_t res; + drm_ctx_t ctx; int i; DRM_COPY_FROM_USER_IOCTL( res, (drm_ctx_res_t *)data, sizeof(res) ); if ( res.count >= DRM_RESERVED_CONTEXTS ) { + bzero(&ctx, sizeof(ctx)); for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) { + ctx.handle = i; if ( DRM_COPY_TO_USER( &res.contexts[i], - &i, sizeof(i) ) ) + &ctx, sizeof(ctx) ) ) return DRM_ERR(EFAULT); } } @@ -266,9 +271,9 @@ return DRM_ERR(ENOMEM); } - if (dev->context_ctor && ctx.handle != DRM_KERNEL_CONTEXT) { + if (dev->driver.context_ctor && ctx.handle != DRM_KERNEL_CONTEXT) { DRM_LOCK(); - dev->context_ctor(dev, ctx.handle); + dev->driver.context_ctor(dev, ctx.handle); DRM_UNLOCK(); } @@ -330,9 +335,9 @@ DRM_DEBUG( "%d\n", ctx.handle ); if ( ctx.handle != DRM_KERNEL_CONTEXT ) { - if (dev->context_dtor) { + if (dev->driver.context_dtor) { DRM_LOCK(); - dev->context_dtor(dev, ctx.handle); + dev->driver.context_dtor(dev, ctx.handle); DRM_UNLOCK(); } Index: dev/drm/drm_dma.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/drm_dma.c,v retrieving revision 1.1 diff -u -r1.1 drm_dma.c --- dev/drm/drm_dma.c 16 Apr 2005 03:44:43 -0000 1.1 +++ dev/drm/drm_dma.c 23 Nov 2005 10:13:23 -0000 @@ -29,9 +29,11 @@ * Rickard E. (Rik) Faith * Gareth Hughes * - * $FreeBSD: src/sys/dev/drm/drm_dma.c,v 1.1 2005/04/16 03:44:43 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" int drm_dma_setup(drm_device_t *dev) @@ -63,12 +65,9 @@ dma->bufs[i].buf_count, dma->bufs[i].seg_count); for (j = 0; j < dma->bufs[i].seg_count; j++) { - drm_pci_free(dev, dma->bufs[i].buf_size, - (void *)dma->bufs[i].seglist[j], - dma->bufs[i].seglist_bus[j]); + drm_pci_free(dev, dma->bufs[i].seglist[j]); } free(dma->bufs[i].seglist, M_DRM); - free(dma->bufs[i].seglist_bus, M_DRM); } if (dma->bufs[i].buf_count) { @@ -125,8 +124,8 @@ { DRM_DEVICE; - if (dev->dma_ioctl) { - return dev->dma_ioctl(kdev, cmd, data, flags, p, filp); + if (dev->driver.dma_ioctl) { + return dev->driver.dma_ioctl(kdev, cmd, data, flags, p, filp); } else { DRM_DEBUG("DMA ioctl on driver with no dma handler\n"); return EINVAL; Index: dev/drm/drm_drawable.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/drm_drawable.c,v retrieving revision 1.1 diff -u -r1.1 drm_drawable.c --- dev/drm/drm_drawable.c 16 Apr 2005 03:44:43 -0000 1.1 +++ dev/drm/drm_drawable.c 23 Nov 2005 10:13:23 -0000 @@ -29,9 +29,11 @@ * Rickard E. (Rik) Faith * Gareth Hughes * - * $FreeBSD: src/sys/dev/drm/drm_drawable.c,v 1.1 2005/04/16 03:44:43 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" int drm_adddraw(DRM_IOCTL_ARGS) Index: dev/drm/drm_drv.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/drm_drv.c,v retrieving revision 1.1 diff -u -r1.1 drm_drv.c --- dev/drm/drm_drv.c 16 Apr 2005 03:44:43 -0000 1.1 +++ dev/drm/drm_drv.c 23 Nov 2005 10:13:23 -0000 @@ -29,16 +29,21 @@ * Rickard E. (Rik) Faith * Gareth Hughes * - * $FreeBSD: src/sys/dev/drm/drm_drv.c,v 1.1 2005/04/16 03:44:43 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" #include "dev/drm/drm.h" +#include "dev/drm/drm_sarea.h" int drm_debug_flag = 0; -static int drm_init(device_t nbdev); -static void drm_cleanup(drm_device_t *dev); +static int drm_load(drm_device_t *dev); +static void drm_unload(drm_device_t *dev); +static drm_pci_id_list_t *drm_find_description(int vendor, int device, + drm_pci_id_list_t *idlist); #ifdef __FreeBSD__ #define DRIVER_SOFTC(unit) \ @@ -58,67 +63,65 @@ #endif /* __NetBSD__ || __OpenBSD__ */ static drm_ioctl_desc_t drm_ioctls[256] = { - [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { drm_version, 0, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { drm_getunique, 0, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { drm_getmagic, 0, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { drm_irq_by_busid, 0, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = { drm_getmap, 0, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = { drm_getclient, 0, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = { drm_getstats, 0, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)] = { drm_setversion, 0, 1 }, - - [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { drm_setunique, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { drm_noop, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_noop, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, 1, 1 }, - - [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = { drm_rmmap, 1, 0 }, - - [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = { drm_setsareactx, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = { drm_getsareactx, 1, 0 }, - - [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { drm_addctx, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { drm_rmctx, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { drm_modctx, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { drm_getctx, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { drm_switchctx, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { drm_newctx, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { drm_resctx, 1, 0 }, - - [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { drm_adddraw, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { drm_rmdraw, 1, 1 }, - - [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { drm_lock, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { drm_unlock, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_noop, 1, 0 }, - - [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { drm_addbufs, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { drm_markbufs, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { drm_infobufs, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { drm_mapbufs, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { drm_freebufs, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { drm_dma, 1, 0 }, - - [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { drm_control, 1, 1 }, - - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { drm_agp_enable, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { drm_agp_info, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { drm_agp_alloc, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { drm_version, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { drm_getunique, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { drm_getmagic, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY}, + [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = { drm_getmap, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = { drm_getclient, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = { drm_getstats, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)] = { drm_setversion, DRM_MASTER|DRM_ROOT_ONLY }, + + [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, + [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, + [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, + [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, + + [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, + [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = { drm_rmmap_ioctl, DRM_AUTH }, + + [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = { drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, + [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = { drm_getsareactx, DRM_AUTH }, + + [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { drm_addctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, + [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, + [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, + [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { drm_getctx, DRM_AUTH }, + [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, + [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { drm_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, + [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { drm_resctx, DRM_AUTH }, + + [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { drm_adddraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, + [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { drm_rmdraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, + + [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { drm_lock, DRM_AUTH }, + [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { drm_unlock, DRM_AUTH }, + [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_noop, DRM_AUTH }, + + [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { drm_addbufs_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, + [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { drm_markbufs, DRM_AUTH|DRM_MASTER }, + [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { drm_infobufs, DRM_AUTH }, + [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { drm_mapbufs, DRM_AUTH }, + [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { drm_freebufs, DRM_AUTH }, + [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { drm_dma, DRM_AUTH }, + + [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, + + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { drm_agp_info_ioctl, DRM_AUTH }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, - [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = { drm_sg_alloc, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = { drm_sg_free, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = { drm_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, + [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = { drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, - [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = { drm_wait_vblank, 0, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = { drm_wait_vblank, 0 }, }; -const char *drm_find_description(int vendor, int device, drm_pci_id_list_t *idlist); - #ifdef __FreeBSD__ static struct cdevsw drm_cdevsw = { #if __FreeBSD_version >= 502103 @@ -144,29 +147,55 @@ int drm_probe(device_t dev, drm_pci_id_list_t *idlist) { - const char *s = NULL; + drm_pci_id_list_t *id_entry; int vendor, device; vendor = pci_get_vendor(dev); device = pci_get_device(dev); - s = drm_find_description(vendor, device, idlist); - if (s != NULL) { - device_set_desc(dev, s); + id_entry = drm_find_description(vendor, device, idlist); + if (id_entry != NULL) { + device_set_desc(dev, id_entry->name); return 0; } return ENXIO; } -int drm_attach(device_t dev, drm_pci_id_list_t *idlist) +int drm_attach(device_t nbdev, drm_pci_id_list_t *idlist) { - return drm_init(dev); + drm_device_t *dev; + drm_pci_id_list_t *id_entry; + int unit; + + unit = device_get_unit(nbdev); + dev = device_get_softc(nbdev); + + if (!strcmp(device_get_name(nbdev), "drmsub")) + dev->device = device_get_parent(nbdev); + else + dev->device = nbdev; + + dev->devnode = make_dev(&drm_cdevsw, + unit, + DRM_DEV_UID, + DRM_DEV_GID, + DRM_DEV_MODE, + "dri/card%d", unit); +#if __FreeBSD_version >= 500000 + mtx_init(&dev->dev_lock, "drm device", NULL, MTX_DEF); +#endif + + id_entry = drm_find_description(pci_get_vendor(nbdev), + pci_get_device(nbdev), idlist); + dev->id_entry = id_entry; + + return drm_load(dev); } int drm_detach(device_t dev) { - drm_cleanup(device_get_softc(dev)); + drm_unload(device_get_softc(dev)); return 0; } @@ -203,7 +232,7 @@ int drm_lkmentry(struct lkm_table *lkmtp, int cmd, int ver); static int drm_lkmhandle(struct lkm_table *lkmtp, int cmd); -int drm_modprobe(); +int drm_modprobe(void); int drm_probe(struct pci_attach_args *pa); void drm_attach(struct pci_attach_args *pa, dev_t kdev); @@ -213,10 +242,7 @@ static int drm_lkmhandle(struct lkm_table *lkmtp, int cmd) { - int j, error = 0; -#if defined(__NetBSD__) && (__NetBSD_Version__ > 106080000) - struct lkm_dev *args = lkmtp->private.lkm_dev; -#endif + int error = 0; switch(cmd) { case LKM_E_LOAD: @@ -243,7 +269,8 @@ return error; } -int drm_modprobe() { +int drm_modprobe(void) +{ struct pci_attach_args pa; int error; @@ -257,10 +284,11 @@ int drm_probe(struct pci_attach_args *pa, drm_pci_id_list_t idlist) { const char *desc; + drm_pci_id_list_t *id_entry; - desc = drm_find_description(PCI_VENDOR(pa->pa_id), + id_entry = drm_find_description(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id), idlist); - if (desc != NULL) { + if (id_entry != NULL) { return 1; } @@ -272,6 +300,7 @@ { int i; drm_device_t *dev; + drm_pci_id_list_t *id_entry; config_makeroom(kdev, &drm_cd); drm_cd.cd_devs[(kdev)] = malloc(sizeof(drm_device_t), M_DRM, M_WAITOK); @@ -280,13 +309,24 @@ memset(dev, 0, sizeof(drm_device_t)); memcpy(&dev->pa, pa, sizeof(dev->pa)); - DRM_INFO("%s", drm_find_description(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id), idlist)); - drm_init(dev); + dev->irq = pa->pa_intrline; + dev->pci_domain = 0; + dev->pci_bus = pa->pa_bus; + dev->pci_slot = pa->pa_device; + dev->pci_func = pa->pa_function; + dev->dma_tag = pa->pa_dmat; + + id_entry = drm_find_description(PCI_VENDOR(pa->pa_id), + PCI_PRODUCT(pa->pa_id), idlist); + dev->driver.pci_id_entry = id_entry; + + DRM_INFO("%s", id_entry->name); + drm_load(dev); } int drm_detach(struct device *self, int flags) { - drm_cleanup((drm_device_t *)self); + drm_unload((drm_device_t *)self); return 0; } @@ -305,31 +345,39 @@ } #endif /* __NetBSD__ || __OpenBSD__ */ -const char *drm_find_description(int vendor, int device, drm_pci_id_list_t *idlist) { +drm_pci_id_list_t *drm_find_description(int vendor, int device, + drm_pci_id_list_t *idlist) +{ int i = 0; for (i = 0; idlist[i].vendor != 0; i++) { if ((idlist[i].vendor == vendor) && (idlist[i].device == device)) { - return idlist[i].name; + return &idlist[i]; } } return NULL; } -/* Initialize the DRM on first open. */ -static int drm_setup(drm_device_t *dev) +static int drm_firstopen(drm_device_t *dev) { + drm_local_map_t *map; int i; DRM_SPINLOCK_ASSERT(&dev->dev_lock); - if (dev->presetup) - dev->presetup(dev); + /* prebuild the SAREA */ + i = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM, + _DRM_CONTAINS_LOCK, &map); + if (i != 0) + return i; + + if (dev->driver.firstopen) + dev->driver.firstopen(dev); dev->buf_use = 0; - if (dev->use_dma) { + if (dev->driver.use_dma) { i = drm_dma_setup(dev); if (i != 0) return i; @@ -351,7 +399,6 @@ dev->magiclist[i].tail = NULL; } - dev->lock.hw_lock = NULL; dev->lock.lock_queue = 0; dev->irq_enabled = 0; dev->context_flag = 0; @@ -366,14 +413,10 @@ DRM_DEBUG( "\n" ); - if (dev->postsetup) - dev->postsetup(dev); - return 0; } -/* Free resources associated with the DRM on the last close. */ -static int drm_takedown(drm_device_t *dev) +static int drm_lastclose(drm_device_t *dev) { drm_magic_entry_t *pt, *next; drm_local_map_t *map, *mapsave; @@ -383,8 +426,8 @@ DRM_DEBUG( "\n" ); - if (dev->pretakedown != NULL) - dev->pretakedown(dev); + if (dev->driver.lastclose != NULL) + dev->driver.lastclose(dev); if (dev->irq_enabled) drm_irq_uninstall(dev); @@ -408,8 +451,9 @@ drm_agp_mem_t *entry; drm_agp_mem_t *nexte; - /* Remove AGP resources, but leave dev->agp - intact until drm_cleanup is called. */ + /* Remove AGP resources, but leave dev->agp intact until + * drm_unload is called. + */ for ( entry = dev->agp->memory ; entry ; entry = nexte ) { nexte = entry->next; if ( entry->bound ) @@ -420,7 +464,7 @@ dev->agp->memory = NULL; if (dev->agp->acquired) - drm_agp_do_release(); + drm_agp_release(dev); dev->agp->acquired = 0; dev->agp->enabled = 0; @@ -430,12 +474,11 @@ dev->sg = NULL; } - /* Clean up maps that weren't set up by the driver. */ TAILQ_FOREACH_SAFE(map, &dev->maplist, link, mapsave) { - if (!map->kernel_owned) - drm_remove_map(dev, map); + drm_rmmap(dev, map); } + drm_dma_takedown(dev); if ( dev->lock.hw_lock ) { dev->lock.hw_lock = NULL; /* SHM removed */ @@ -446,39 +489,11 @@ return 0; } -/* linux: drm_init is called via init_module at module load time, or via - * linux/init/main.c (this is not currently supported). - * bsd: drm_init is called via the attach function per device. - */ -static int drm_init(device_t nbdev) +static int drm_load(drm_device_t *dev) { - int unit; - drm_device_t *dev; int retcode; - DRM_DEBUG( "\n" ); - -#ifdef __FreeBSD__ - unit = device_get_unit(nbdev); - dev = device_get_softc(nbdev); - if (!strcmp(device_get_name(nbdev), "drmsub")) - dev->device = device_get_parent(nbdev); - else - dev->device = nbdev; - - dev->devnode = make_dev(&drm_cdevsw, - unit, - DRM_DEV_UID, - DRM_DEV_GID, - DRM_DEV_MODE, - "dri/card%d", unit); -#if __FreeBSD_version >= 500000 - mtx_init(&dev->dev_lock, "drm device", NULL, MTX_DEF); -#endif -#elif defined(__NetBSD__) || defined(__OpenBSD__) - dev = nbdev; - unit = minor(dev->device.dv_unit); -#endif + DRM_DEBUG( "\n" ); dev->irq = pci_get_irq(dev->device); /* XXX Fix domain number (alpha hoses) */ @@ -495,16 +510,18 @@ #endif TAILQ_INIT(&dev->files); - if (dev->preinit != NULL) { - retcode = dev->preinit(dev, 0); + if (dev->driver.load != NULL) { + DRM_LOCK(); + retcode = dev->driver.load(dev, dev->id_entry->driver_private); + DRM_UNLOCK(); if (retcode != 0) goto error; } - if (dev->use_agp) { + if (dev->driver.use_agp) { if (drm_device_is_agp(dev)) dev->agp = drm_agp_init(); - if (dev->require_agp && dev->agp == NULL) { + if (dev->driver.require_agp && dev->agp == NULL) { DRM_ERROR("Card isn't AGP, or couldn't initialize " "AGP.\n"); retcode = DRM_ERR(ENOMEM); @@ -523,16 +540,12 @@ goto error; } - DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d\n", - dev->driver_name, - dev->driver_major, - dev->driver_minor, - dev->driver_patchlevel, - dev->driver_date, - unit ); - - if (dev->postinit != NULL) - dev->postinit(dev, 0); + DRM_INFO("Initialized %s %d.%d.%d %s\n", + dev->driver.name, + dev->driver.major, + dev->driver.minor, + dev->driver.patchlevel, + dev->driver.date); return 0; @@ -541,7 +554,7 @@ drm_sysctl_cleanup(dev); #endif DRM_LOCK(); - drm_takedown(dev); + drm_lastclose(dev); DRM_UNLOCK(); #ifdef __FreeBSD__ destroy_dev(dev->devnode); @@ -552,13 +565,9 @@ return retcode; } -/* linux: drm_cleanup is called via cleanup_module at module unload time. - * bsd: drm_cleanup is called per device at module unload time. - * FIXME: NetBSD - */ -static void drm_cleanup(drm_device_t *dev) +static void drm_unload(drm_device_t *dev) { - drm_local_map_t *map; + int i; DRM_DEBUG( "\n" ); @@ -572,28 +581,35 @@ if (dev->agp && dev->agp->mtrr) { int __unused retcode; - retcode = drm_mtrr_del(dev->agp->info.ai_aperture_base, + retcode = drm_mtrr_del(0, dev->agp->info.ai_aperture_base, dev->agp->info.ai_aperture_size, DRM_MTRR_WC); DRM_DEBUG("mtrr_del = %d", retcode); } DRM_LOCK(); - drm_takedown(dev); + drm_lastclose(dev); DRM_UNLOCK(); - /* Clean up any maps left over that had been allocated by the driver. */ - while ((map = TAILQ_FIRST(&dev->maplist)) != NULL) { - drm_remove_map(dev, map); + /* Clean up PCI resources allocated by drm_bufs.c. We're not really + * worried about resource consumption while the DRM is inactive (between + * lastclose and firstopen or unload) because these aren't actually + * taking up KVA, just keeping the PCI resource allocated. + */ + for (i = 0; i < DRM_MAX_PCI_RESOURCE; i++) { + if (dev->pcir[i] == NULL) + continue; + bus_release_resource(dev->device, SYS_RES_MEMORY, + dev->pcirid[i], dev->pcir[i]); + dev->pcir[i] = NULL; } if ( dev->agp ) { - drm_agp_uninit(); free(dev->agp, M_DRM); dev->agp = NULL; } - if (dev->postcleanup != NULL) - dev->postcleanup(dev); + if (dev->driver.unload != NULL) + dev->driver.unload(dev); drm_mem_uninit(); #if defined(__FreeBSD__) && __FreeBSD_version >= 500000 @@ -619,13 +635,13 @@ return DRM_ERR(EFAULT); \ } - version.version_major = dev->driver_major; - version.version_minor = dev->driver_minor; - version.version_patchlevel = dev->driver_patchlevel; - - DRM_COPY(version.name, dev->driver_name); - DRM_COPY(version.date, dev->driver_date); - DRM_COPY(version.desc, dev->driver_desc); + version.version_major = dev->driver.major; + version.version_minor = dev->driver.minor; + version.version_patchlevel = dev->driver.patchlevel; + + DRM_COPY(version.name, dev->driver.name); + DRM_COPY(version.date, dev->driver.date); + DRM_COPY(version.desc, dev->driver.desc); DRM_COPY_TO_USER_IOCTL( (drm_version_t *)data, version, sizeof(version) ); @@ -650,7 +666,7 @@ device_busy(dev->device); #endif if ( !dev->open_count++ ) - retcode = drm_setup(dev); + retcode = drm_firstopen(dev); DRM_UNLOCK(); } @@ -675,8 +691,8 @@ return EINVAL; } - if (dev->prerelease != NULL) - dev->prerelease(dev, filp); + if (dev->driver.preclose != NULL) + dev->driver.preclose(dev, filp); /* ======================================================== * Begin inline drm_release @@ -695,8 +711,8 @@ DRM_DEBUG("Process %d dead, freeing lock for context %d\n", DRM_CURRENTPID, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); - if (dev->release != NULL) - dev->release(dev, filp); + if (dev->driver.reclaim_buffers_locked != NULL) + dev->driver.reclaim_buffers_locked(dev, filp); drm_lock_free(dev, &dev->lock.hw_lock->lock, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); @@ -705,7 +721,8 @@ hardware at this point, possibly processed via a callback to the X server. */ - } else if (dev->release != NULL && dev->lock.hw_lock != NULL) { + } else if (dev->driver.reclaim_buffers_locked != NULL && + dev->lock.hw_lock != NULL) { /* The lock is required to reclaim buffers */ for (;;) { if ( !dev->lock.hw_lock ) { @@ -732,14 +749,14 @@ break; } if (retcode == 0) { - dev->release(dev, filp); + dev->driver.reclaim_buffers_locked(dev, filp); drm_lock_free(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT); } } - if (dev->use_dma) - drm_reclaim_buffers(dev, (void *)(uintptr_t)priv->pid); + if (dev->driver.use_dma && !dev->driver.reclaim_buffers_locked) + drm_reclaim_buffers(dev, filp); #if defined (__FreeBSD__) && (__FreeBSD_version >= 500000) funsetown(&dev->buf_sigio); @@ -750,8 +767,8 @@ #endif /* __NetBSD__ || __OpenBSD__ */ if (--priv->refs == 0) { - if (dev->free_filp_priv != NULL) - dev->free_filp_priv(dev, priv); + if (dev->driver.postclose != NULL) + dev->driver.postclose(dev, priv); TAILQ_REMOVE(&dev->files, priv, link); free(priv, M_DRM); } @@ -765,7 +782,7 @@ device_unbusy(dev->device); #endif if (--dev->open_count == 0) { - retcode = drm_takedown(dev); + retcode = drm_lastclose(dev); } DRM_UNLOCK(); @@ -844,12 +861,12 @@ if (ioctl->func == NULL && nr >= DRM_COMMAND_BASE) { /* The array entries begin at DRM_COMMAND_BASE ioctl nr */ nr -= DRM_COMMAND_BASE; - if (nr > dev->max_driver_ioctl) { + if (nr > dev->driver.max_ioctl) { DRM_DEBUG("Bad driver ioctl number, 0x%x (of 0x%x)\n", - nr, dev->max_driver_ioctl); + nr, dev->driver.max_ioctl); return EINVAL; } - ioctl = &dev->driver_ioctls[nr]; + ioctl = &dev->driver.ioctls[nr]; is_driver_ioctl = 1; } func = ioctl->func; @@ -858,8 +875,12 @@ DRM_DEBUG( "no function\n" ); return EINVAL; } - if ((ioctl->root_only && DRM_SUSER(p)) || (ioctl->auth_needed && - !priv->authenticated)) + /* ioctl->master check should be against something in the filp set up + * for the first opener, but it doesn't matter yet. + */ + if (((ioctl->flags & DRM_ROOT_ONLY) && !DRM_SUSER(p)) || + ((ioctl->flags & DRM_AUTH) && !priv->authenticated) || + ((ioctl->flags & DRM_MASTER) && !priv->master)) return EACCES; if (is_driver_ioctl) Index: dev/drm/drm_fops.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/drm_fops.c,v retrieving revision 1.1 diff -u -r1.1 drm_fops.c --- dev/drm/drm_fops.c 16 Apr 2005 03:44:43 -0000 1.1 +++ dev/drm/drm_fops.c 23 Nov 2005 10:13:23 -0000 @@ -30,9 +30,11 @@ * Daryll Strauss * Gareth Hughes * - * $FreeBSD: src/sys/dev/drm/drm_fops.c,v 1.1 2005/04/16 03:44:43 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" drm_file_t *drm_find_file_by_proc(drm_device_t *dev, DRM_STRUCTPROC *p) @@ -89,10 +91,12 @@ priv->refs = 1; priv->minor = m; priv->ioctl_count = 0; - priv->authenticated = !DRM_SUSER(p); - if (dev->open_helper) { - retcode = dev->open_helper(dev, priv); + /* for compatibility root is always authenticated */ + priv->authenticated = DRM_SUSER(p); + + if (dev->driver.open) { + retcode = dev->driver.open(dev, priv); if (retcode != 0) { free(priv, M_DRM); DRM_UNLOCK(); @@ -100,6 +104,9 @@ } } + /* first opener automatically becomes master */ + priv->master = TAILQ_EMPTY(&dev->files); + TAILQ_INSERT_TAIL(&dev->files, priv, link); } DRM_UNLOCK(); Index: dev/drm/drm_ioctl.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/drm_ioctl.c,v retrieving revision 1.1 diff -u -r1.1 drm_ioctl.c --- dev/drm/drm_ioctl.c 16 Apr 2005 03:44:44 -0000 1.1 +++ dev/drm/drm_ioctl.c 23 Nov 2005 10:13:23 -0000 @@ -29,9 +29,11 @@ * Rickard E. (Rik) Faith * Gareth Hughes * - * $FreeBSD: src/sys/dev/drm/drm_ioctl.c,v 1.1 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" /* @@ -262,8 +264,8 @@ retv.drm_di_major = DRM_IF_MAJOR; retv.drm_di_minor = DRM_IF_MINOR; - retv.drm_dd_major = dev->driver_major; - retv.drm_dd_minor = dev->driver_minor; + retv.drm_dd_major = dev->driver.major; + retv.drm_dd_minor = dev->driver.minor; DRM_COPY_TO_USER_IOCTL((drm_set_version_t *)data, retv, sizeof(sv)); @@ -282,8 +284,8 @@ } if (sv.drm_dd_major != -1) { - if (sv.drm_dd_major != dev->driver_major || - sv.drm_dd_minor < 0 || sv.drm_dd_minor > dev->driver_minor) + if (sv.drm_dd_major != dev->driver.major || + sv.drm_dd_minor < 0 || sv.drm_dd_minor > dev->driver.minor) return EINVAL; } return 0; Index: dev/drm/drm_irq.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/drm_irq.c,v retrieving revision 1.1 diff -u -r1.1 drm_irq.c --- dev/drm/drm_irq.c 16 Apr 2005 03:44:44 -0000 1.1 +++ dev/drm/drm_irq.c 23 Nov 2005 10:13:23 -0000 @@ -1,4 +1,4 @@ -/* drm_dma.c -- DMA IOCTL and function support +/* drm_irq.c -- IRQ IOCTL and function support * Created: Fri Oct 18 2003 by anholt@FreeBSD.org */ /*- @@ -26,9 +26,11 @@ * Authors: * Eric Anholt * - * $FreeBSD: src/sys/dev/drm/drm_irq.c,v 1.1 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" #include "dev/drm/drm.h" @@ -62,7 +64,7 @@ drm_device_t *dev = (drm_device_t *)arg; DRM_SPINLOCK(&dev->irq_lock); - dev->irq_handler(arg); + dev->driver.irq_handler(arg); DRM_SPINUNLOCK(&dev->irq_lock); } #endif @@ -70,6 +72,9 @@ int drm_irq_install(drm_device_t *dev) { int retcode; +#ifdef __NetBSD__ + pci_intr_handle_t ih; +#endif if (dev->irq == 0 || dev->dev_private == NULL) return DRM_ERR(EINVAL); @@ -88,7 +93,7 @@ DRM_SPININIT(dev->irq_lock, "DRM IRQ lock"); /* Before installing handler */ - dev->irq_preinstall(dev); + dev->driver.irq_preinstall(dev); DRM_UNLOCK(); /* Install handler */ @@ -110,12 +115,12 @@ if (retcode != 0) goto err; #elif defined(__NetBSD__) || defined(__OpenBSD__) - if (pci_intr_map(&dev->pa, &dev->ih) != 0) { + if (pci_intr_map(&dev->pa, &ih) != 0) { retcode = ENOENT; goto err; } - dev->irqh = pci_intr_establish(&dev->pa.pa_pc, dev->ih, IPL_TTY, - (irqreturn_t (*)(DRM_IRQ_ARGS))dev->irq_handler, dev); + dev->irqh = pci_intr_establish(&dev->pa.pa_pc, ih, IPL_TTY, + (irqreturn_t (*)(void *))dev->irq_handler, dev); if (!dev->irqh) { retcode = ENOENT; goto err; @@ -124,7 +129,7 @@ /* After installing handler */ DRM_LOCK(); - dev->irq_postinstall(dev); + dev->driver.irq_postinstall(dev); DRM_UNLOCK(); return 0; @@ -145,18 +150,22 @@ int drm_irq_uninstall(drm_device_t *dev) { +#ifdef __FreeBSD__ int irqrid; +#endif if (!dev->irq_enabled) return DRM_ERR(EINVAL); dev->irq_enabled = 0; +#ifdef __FreeBSD__ irqrid = dev->irqrid; dev->irqrid = 0; +#endif DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, dev->irq ); - dev->irq_uninstall(dev); + dev->driver.irq_uninstall(dev); #ifdef __FreeBSD__ DRM_UNLOCK(); @@ -184,14 +193,14 @@ /* Handle drivers whose DRM used to require IRQ setup but the * no longer does. */ - if (!dev->use_irq) + if (!dev->driver.use_irq) return 0; if (dev->if_version < DRM_IF_VERSION(1, 2) && ctl.irq != dev->irq) return DRM_ERR(EINVAL); return drm_irq_install(dev); case DRM_UNINST_HANDLER: - if (!dev->use_irq) + if (!dev->driver.use_irq) return 0; DRM_LOCK(); err = drm_irq_uninstall(dev); @@ -242,7 +251,7 @@ ret = EINVAL; } else { DRM_LOCK(); - ret = dev->vblank_wait(dev, &vblwait.request.sequence); + ret = dev->driver.vblank_wait(dev, &vblwait.request.sequence); DRM_UNLOCK(); microtime(&now); Index: dev/drm/drm_linux_list.h =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/drm_linux_list.h,v retrieving revision 1.3 diff -u -r1.3 drm_linux_list.h --- dev/drm/drm_linux_list.h 16 Apr 2005 03:44:44 -0000 1.3 +++ dev/drm/drm_linux_list.h 23 Nov 2005 10:13:23 -0000 @@ -27,9 +27,11 @@ * Authors: * Eric Anholt * - * $FreeBSD: src/sys/dev/drm/drm_linux_list.h,v 1.3 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + struct list_head { struct list_head *next, *prev; }; Index: dev/drm/drm_lock.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/drm_lock.c,v retrieving revision 1.1 diff -u -r1.1 drm_lock.c --- dev/drm/drm_lock.c 16 Apr 2005 03:44:44 -0000 1.1 +++ dev/drm/drm_lock.c 23 Nov 2005 10:13:23 -0000 @@ -29,9 +29,11 @@ * Rickard E. (Rik) Faith * Gareth Hughes * - * $FreeBSD: src/sys/dev/drm/drm_lock.c,v 1.1 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context) @@ -113,7 +115,7 @@ DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n", lock.context, DRM_CURRENTPID, dev->lock.hw_lock->lock, lock.flags); - if (dev->use_dma_queue && lock.context < 0) + if (dev->driver.use_dma_queue && lock.context < 0) return EINVAL; DRM_LOCK(); @@ -144,8 +146,9 @@ /* XXX: Add signal blocking here */ - if (dev->dma_quiescent != NULL && (lock.flags & _DRM_LOCK_QUIESCENT)) - dev->dma_quiescent(dev); + if (dev->driver.dma_quiescent != NULL && + (lock.flags & _DRM_LOCK_QUIESCENT)) + dev->driver.dma_quiescent(dev); return 0; } Index: dev/drm/drm_memory.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/drm_memory.c,v retrieving revision 1.1 diff -u -r1.1 drm_memory.c --- dev/drm/drm_memory.c 16 Apr 2005 03:44:44 -0000 1.1 +++ dev/drm/drm_memory.c 23 Nov 2005 10:13:23 -0000 @@ -29,9 +29,11 @@ * Rickard E. (Rik) Faith * Gareth Hughes * - * $FreeBSD: src/sys/dev/drm/drm_memory.c,v 1.1 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" MALLOC_DEFINE(M_DRM, "drm", "DRM Data Structures"); @@ -114,7 +116,7 @@ } int -drm_mtrr_del(unsigned long offset, size_t size, int flags) +drm_mtrr_del(int __unused handle, unsigned long offset, size_t size, int flags) { int act; struct mem_range_desc mrdesc; Index: dev/drm/drm_pci.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/drm_pci.c,v retrieving revision 1.1 diff -u -r1.1 drm_pci.c --- dev/drm/drm_pci.c 16 Apr 2005 03:44:44 -0000 1.1 +++ dev/drm/drm_pci.c 23 Nov 2005 10:13:23 -0000 @@ -26,44 +26,119 @@ * AUTHOR 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. - * - * $FreeBSD: src/sys/dev/drm/drm_pci.c,v 1.1 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" /**********************************************************************/ /** \name PCI memory */ /*@{*/ +#if defined(__FreeBSD__) +static void +drm_pci_busdma_callback(void *arg, bus_dma_segment_t *segs, int nsegs, int error) +{ + drm_dma_handle_t *dmah = arg; + + if (error != 0) + return; + + KASSERT(nsegs == 1, ("drm_pci_busdma_callback: bad dma segment count")); + dmah->busaddr = segs[0].ds_addr; +} +#endif + /** * \brief Allocate a physically contiguous DMA-accessible consistent * memory block. */ -void * -drm_pci_alloc(drm_device_t *dev, size_t size, size_t align, dma_addr_t maxaddr, - dma_addr_t *busaddr) +drm_dma_handle_t * +drm_pci_alloc(drm_device_t *dev, size_t size, size_t align, dma_addr_t maxaddr) { - void *vaddr; + drm_dma_handle_t *dmah; + int ret; + + /* Need power-of-two alignment, so fail the allocation if it isn't. */ + if ((align & (align - 1)) != 0) { + DRM_ERROR("drm_pci_alloc with non-power-of-two alignment %d\n", + (int)align); + return NULL; + } + + dmah = malloc(sizeof(drm_dma_handle_t), M_DRM, M_ZERO | M_NOWAIT); + if (dmah == NULL) + return NULL; + +#ifdef __FreeBSD__ + ret = bus_dma_tag_create(NULL, align, 0, /* tag, align, boundary */ + maxaddr, BUS_SPACE_MAXADDR, /* lowaddr, highaddr */ + NULL, NULL, /* filtfunc, filtfuncargs */ + size, 1, size, /* maxsize, nsegs, maxsegsize */ + BUS_DMA_ALLOCNOW, NULL, NULL, /* flags, lockfunc, lockfuncargs */ + &dmah->tag); + if (ret != 0) { + free(dmah, M_DRM); + return NULL; + } + + ret = bus_dmamem_alloc(dmah->tag, &dmah->vaddr, BUS_DMA_NOWAIT, + &dmah->map); + if (ret != 0) { + bus_dma_tag_destroy(dmah->tag); + free(dmah, M_DRM); + return NULL; + } + + ret = bus_dmamap_load(dmah->tag, dmah->map, dmah->vaddr, size, + drm_pci_busdma_callback, dmah, 0); + if (ret != 0) { + bus_dmamem_free(dmah->tag, dmah->vaddr, dmah->map); + bus_dma_tag_destroy(dmah->tag); + free(dmah, M_DRM); + return NULL; + } +#elif defined(__NetBSD__) + ret = bus_dmamem_alloc(dev->dma_tag, size, align, PAGE_SIZE, + &dmah->seg, 1, &nsegs, BUS_DMA_NOWAIT); + if ((ret != 0) || (nsegs != 1)) { + free(dmah, M_DRM); + return NULL; + } + + ret = bus_dmamem_map(dev->dma_tag, &dmah->seg, 1, size, &dmah->addr, + BUS_DMA_NOWAIT); + if (ret != 0) { + bus_dmamem_free(dev->dma_tag, &dmah->seg, 1); + free(dmah, M_DRM); + return NULL; + } + + dmah->dmaaddr = h->seg.ds_addr; +#endif - vaddr = contigmalloc(size, M_DRM, M_NOWAIT, 0ul, maxaddr, align, - 0); - *busaddr = vtophys(vaddr); - - return vaddr; + return dmah; } /** * \brief Free a DMA-accessible consistent memory block. */ void -drm_pci_free(drm_device_t *dev, size_t size, void *vaddr, dma_addr_t busaddr) +drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah) { -#if __FreeBSD_version > 500000 - if (vaddr == NULL) + if (dmah == NULL) return; - contigfree(vaddr, size, M_DRM); /* Not available on 4.x */ + +#if defined(__FreeBSD__) + bus_dmamem_free(dmah->tag, dmah->vaddr, dmah->map); + bus_dma_tag_destroy(dmah->tag); +#elif defined(__NetBSD__) + bus_dmamem_free(dev->dma_tag, &dmah->seg, 1); #endif + + free(dmah, M_DRM); } /*@}*/ Index: dev/drm/drm_pciids.h =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/drm_pciids.h,v retrieving revision 1.3 diff -u -r1.3 drm_pciids.h --- dev/drm/drm_pciids.h 20 Jul 2005 21:10:57 -0000 1.3 +++ dev/drm/drm_pciids.h 23 Nov 2005 10:13:23 -0000 @@ -1,8 +1,4 @@ /* - * $FreeBSD: src/sys/dev/drm/drm_pciids.h,v 1.3 2005/07/20 21:10:57 anholt Exp $ - */ - -/* This file is auto-generated from the drm_pciids.txt in the DRM CVS Please contact dri-devel@lists.sf.net to add new cards to this list */ @@ -50,6 +46,7 @@ {0x1002, 0x4E50, CHIP_RV350|CHIP_IS_MOBILITY, "ATI Radeon RV300 Mobility 9600 M10"}, \ {0x1002, 0x4E51, CHIP_RV350|CHIP_IS_MOBILITY, "ATI Radeon RV350 Mobility 9600 M10 NQ"}, \ {0x1002, 0x4E54, CHIP_RV350|CHIP_IS_MOBILITY, "ATI Radeon FireGL T2 128"}, \ + {0x1002, 0x4E56, CHIP_RV350|CHIP_IS_MOBILITY, "ATI Radeon FireGL Mobility T2e"}, \ {0x1002, 0x5144, CHIP_R100|CHIP_SINGLE_CRTC, "ATI Radeon QD R100"}, \ {0x1002, 0x5145, CHIP_R100|CHIP_SINGLE_CRTC, "ATI Radeon QE R100"}, \ {0x1002, 0x5146, CHIP_R100|CHIP_SINGLE_CRTC, "ATI Radeon QF R100"}, \ @@ -66,12 +63,14 @@ {0x1002, 0x5158, CHIP_RV200, "ATI Radeon QX RV200 7500"}, \ {0x1002, 0x5159, CHIP_RV100, "ATI Radeon QY RV100 7000/VE"}, \ {0x1002, 0x515A, CHIP_RV100, "ATI Radeon QZ RV100 7000/VE"}, \ + {0x1002, 0x515E, CHIP_RV100, "ATI ES1000 RN50"}, \ {0x1002, 0x5168, CHIP_R200, "ATI Radeon Qh R200"}, \ {0x1002, 0x5169, CHIP_R200, "ATI Radeon Qi R200"}, \ {0x1002, 0x516A, CHIP_R200, "ATI Radeon Qj R200"}, \ {0x1002, 0x516B, CHIP_R200, "ATI Radeon Qk R200"}, \ {0x1002, 0x516C, CHIP_R200, "ATI Radeon Ql R200"}, \ {0x1002, 0x5460, CHIP_RV350, "ATI Radeon X300"}, \ + {0x1002, 0x554F, CHIP_R350, "ATI Radeon X800"}, \ {0x1002, 0x5834, CHIP_RS300|CHIP_IS_IGP, "ATI Radeon RS300 IGP"}, \ {0x1002, 0x5835, CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY, "ATI Radeon RS300 Mobility IGP"}, \ {0x1002, 0x5836, CHIP_RS300|CHIP_IS_IGP, "ATI Radeon RS300 IGP"}, \ @@ -85,10 +84,12 @@ {0x1002, 0x5969, CHIP_RV100, "ATI ES1000 RN50"}, \ {0x1002, 0x596A, CHIP_RV280, "ATI Radeon RV280 9200"}, \ {0x1002, 0x596B, CHIP_RV280, "ATI Radeon RV280 9200"}, \ + {0x1002, 0x5b60, CHIP_RV350, "ATI Radeon RV370 X300SE"}, \ {0x1002, 0x5c61, CHIP_RV280|CHIP_IS_MOBILITY, "ATI Radeon RV280 Mobility"}, \ {0x1002, 0x5c62, CHIP_RV280, "ATI Radeon RV280"}, \ {0x1002, 0x5c63, CHIP_RV280|CHIP_IS_MOBILITY, "ATI Radeon RV280 Mobility"}, \ {0x1002, 0x5c64, CHIP_RV280, "ATI Radeon RV280"}, \ + {0x1002, 0x5d4d, CHIP_R350, "ATI Radeon R480"}, \ {0, 0, 0, NULL} #define r128_PCI_IDS \ @@ -132,9 +133,10 @@ {0, 0, 0, NULL} #define mga_PCI_IDS \ - {0x102b, 0x0521, 0, "Matrox G200 (AGP)"}, \ - {0x102b, 0x0525, 0, "Matrox G400/G450 (AGP)"}, \ - {0x102b, 0x2527, 0, "Matrox G550 (AGP)"}, \ + {0x102b, 0x0520, MGA_CARD_TYPE_G200, "Matrox G200 (PCI)"}, \ + {0x102b, 0x0521, MGA_CARD_TYPE_G200, "Matrox G200 (AGP)"}, \ + {0x102b, 0x0525, MGA_CARD_TYPE_G400, "Matrox G400/G450 (AGP)"}, \ + {0x102b, 0x2527, MGA_CARD_TYPE_G550, "Matrox G550 (AGP)"}, \ {0, 0, 0, NULL} #define mach64_PCI_IDS \ @@ -178,10 +180,10 @@ #define viadrv_PCI_IDS \ {0x1106, 0x3022, 0, "VIA CLE266 3022"}, \ - {0x1106, 0x3118, 0, "VIA CN400"}, \ + {0x1106, 0x3118, VIA_PRO_GROUP_A, "VIA CN400 / PM8X0"}, \ {0x1106, 0x3122, 0, "VIA CLE266"}, \ {0x1106, 0x7205, 0, "VIA KM400"}, \ - {0x1106, 0x7204, 0, "VIA K8M800"}, \ + {0x1106, 0x3108, 0, "VIA K8M800"}, \ {0, 0, 0, NULL} #define i810_PCI_IDS \ @@ -237,6 +239,194 @@ {0x8086, 0x3582, 0, "Intel i852GM/i855GM GMCH"}, \ {0x8086, 0x2572, 0, "Intel i865G GMCH"}, \ {0x8086, 0x2582, 0, "Intel i915G"}, \ - {0x8086, 0x2982, 0, "Intel i915GM"}, \ + {0x8086, 0x2592, 0, "Intel i915GM"}, \ + {0x8086, 0x2772, 0, "Intel i945G"}, \ {0, 0, 0, NULL} +#define imagine_PCI_IDS \ + {0x105d, 0x2309, IMAGINE_128, "Imagine 128"}, \ + {0x105d, 0x2339, IMAGINE_128_2, "Imagine 128-II"}, \ + {0x105d, 0x493d, IMAGINE_T2R, "Ticket to Ride"}, \ + {0x105d, 0x5348, IMAGINE_REV4, "Revolution IV"}, \ + {0, 0, 0, NULL} + +#define nv_PCI_IDS \ + {0x10DE, 0x0020, NV04, "NVidia RIVA TNT"}, \ + {0x10DE, 0x0028, NV04, "NVidia RIVA TNT2"}, \ + {0x10DE, 0x002A, NV04, "NVidia Unknown TNT2"}, \ + {0x10DE, 0x002C, NV04, "NVidia Vanta"}, \ + {0x10DE, 0x0029, NV04, "NVidia RIVA TNT2 Ultra"}, \ + {0x10DE, 0x002D, NV04, "NVidia RIVA TNT2 Model 64"}, \ + {0x10DE, 0x00A0, NV04, "NVidia Aladdin TNT2"}, \ + {0x10DE, 0x0100, NV10, "NVidia GeForce 256"}, \ + {0x10DE, 0x0101, NV10, "NVidia GeForce DDR"}, \ + {0x10DE, 0x0103, NV10, "NVidia Quadro"}, \ + {0x10DE, 0x0110, NV10, "NVidia GeForce2 MX/MX 400"}, \ + {0x10DE, 0x0111, NV10, "NVidia GeForce2 MX 100/200"}, \ + {0x10DE, 0x0112, NV10, "NVidia GeForce2 Go"}, \ + {0x10DE, 0x0113, NV10, "NVidia Quadro2 MXR/EX/Go"}, \ + {0x10DE, 0x0150, NV10, "NVidia GeForce2 GTS"}, \ + {0x10DE, 0x0151, NV10, "NVidia GeForce2 Ti"}, \ + {0x10DE, 0x0152, NV10, "NVidia GeForce2 Ultra"}, \ + {0x10DE, 0x0153, NV10, "NVidia Quadro2 Pro"}, \ + {0x10DE, 0x0170, NV10, "NVidia GeForce4 MX 460"}, \ + {0x10DE, 0x0171, NV10, "NVidia GeForce4 MX 440"}, \ + {0x10DE, 0x0172, NV10, "NVidia GeForce4 MX 420"}, \ + {0x10DE, 0x0173, NV10, "NVidia GeForce4 MX 440-SE"}, \ + {0x10DE, 0x0174, NV10, "NVidia GeForce4 440 Go"}, \ + {0x10DE, 0x0175, NV10, "NVidia GeForce4 420 Go"}, \ + {0x10DE, 0x0176, NV10, "NVidia GeForce4 420 Go 32M"}, \ + {0x10DE, 0x0177, NV10, "NVidia GeForce4 460 Go"}, \ + {0x10DE, 0x0178, NV10, "NVidia Quadro4 550 XGL"}, \ + {0x10DE, 0x0179, NV10, "NVidia GeForce4"}, \ + {0x10DE, 0x017A, NV10, "NVidia Quadro4 NVS"}, \ + {0x10DE, 0x017C, NV10, "NVidia Quadro4 500 GoGL"}, \ + {0x10DE, 0x017D, NV10, "NVidia GeForce4 410 Go 16M"}, \ + {0x10DE, 0x0181, NV10, "NVidia GeForce4 MX 440 with AGP8X"}, \ + {0x10DE, 0x0182, NV10, "NVidia GeForce4 MX 440SE with AGP8X"}, \ + {0x10DE, 0x0183, NV10, "NVidia GeForce4 MX 420 with AGP8X"}, \ + {0x10DE, 0x0185, NV10, "NVidia GeForce4 MX 4000"}, \ + {0x10DE, 0x0186, NV10, "NVidia GeForce4 448 Go"}, \ + {0x10DE, 0x0187, NV10, "NVidia GeForce4 488 Go"}, \ + {0x10DE, 0x0188, NV10, "NVidia Quadro4 580 XGL"}, \ + {0x10DE, 0x0189, NV10, "NVidia GeForce4 MX with AGP8X (Mac)"}, \ + {0x10DE, 0x018A, NV10, "NVidia Quadro4 280 NVS"}, \ + {0x10DE, 0x018B, NV10, "NVidia Quadro4 380 XGL"}, \ + {0x10DE, 0x018C, NV10, "NVidia Quadro NVS 50 PCI"}, \ + {0x10DE, 0x018D, NV10, "NVidia GeForce4 448 Go"}, \ + {0x10DE, 0x01A0, NV10, "NVidia GeForce2 Integrated GPU"}, \ + {0x10DE, 0x01F0, NV10, "NVidia GeForce4 MX Integrated GPU"}, \ + {0x10DE, 0x0200, NV20, "NVidia GeForce3"}, \ + {0x10DE, 0x0201, NV20, "NVidia GeForce3 Ti 200"}, \ + {0x10DE, 0x0202, NV20, "NVidia GeForce3 Ti 500"}, \ + {0x10DE, 0x0203, NV20, "NVidia Quadro DCC"}, \ + {0x10DE, 0x0250, NV20, "NVidia GeForce4 Ti 4600"}, \ + {0x10DE, 0x0251, NV20, "NVidia GeForce4 Ti 4400"}, \ + {0x10DE, 0x0252, NV20, "NVidia 0x0252"}, \ + {0x10DE, 0x0253, NV20, "NVidia GeForce4 Ti 4200"}, \ + {0x10DE, 0x0258, NV20, "NVidia Quadro4 900 XGL"}, \ + {0x10DE, 0x0259, NV20, "NVidia Quadro4 750 XGL"}, \ + {0x10DE, 0x025B, NV20, "NVidia Quadro4 700 XGL"}, \ + {0x10DE, 0x0280, NV20, "NVidia GeForce4 Ti 4800"}, \ + {0x10DE, 0x0281, NV20, "NVidia GeForce4 Ti 4200 with AGP8X"}, \ + {0x10DE, 0x0282, NV20, "NVidia GeForce4 Ti 4800 SE"}, \ + {0x10DE, 0x0286, NV20, "NVidia GeForce4 4200 Go"}, \ + {0x10DE, 0x028C, NV20, "NVidia Quadro4 700 GoGL"}, \ + {0x10DE, 0x0288, NV20, "NVidia Quadro4 980 XGL"}, \ + {0x10DE, 0x0289, NV20, "NVidia Quadro4 780 XGL"}, \ + {0x10DE, 0x0301, NV30, "NVidia GeForce FX 5800 Ultra"}, \ + {0x10DE, 0x0302, NV30, "NVidia GeForce FX 5800"}, \ + {0x10DE, 0x0308, NV30, "NVidia Quadro FX 2000"}, \ + {0x10DE, 0x0309, NV30, "NVidia Quadro FX 1000"}, \ + {0x10DE, 0x0311, NV30, "NVidia GeForce FX 5600 Ultra"}, \ + {0x10DE, 0x0312, NV30, "NVidia GeForce FX 5600"}, \ + {0x10DE, 0x0313, NV30, "NVidia 0x0313"},}, \ + {0x10DE, 0x0314, NV30, "NVidia GeForce FX 5600SE"}, \ + {0x10DE, 0x0316, NV30, "NVidia 0x0316"}, \ + {0x10DE, 0x0317, NV30, "NVidia 0x0317"}, \ + {0x10DE, 0x031A, NV30, "NVidia GeForce FX Go5600"}, \ + {0x10DE, 0x031B, NV30, "NVidia GeForce FX Go5650"}, \ + {0x10DE, 0x031C, NV30, "NVidia Quadro FX Go700"}, \ + {0x10DE, 0x031D, NV30, "NVidia 0x031D"}, \ + {0x10DE, 0x031E, NV30, "NVidia 0x031E"}, \ + {0x10DE, 0x031F, NV30, "NVidia 0x031F"}, \ + {0x10DE, 0x0320, NV30, "NVidia GeForce FX 5200"}, \ + {0x10DE, 0x0321, NV30, "NVidia GeForce FX 5200 Ultra"}, \ + {0x10DE, 0x0322, NV30, "NVidia GeForce FX 5200"}, \ + {0x10DE, 0x0323, NV30, "NVidia GeForce FX 5200SE"}, \ + {0x10DE, 0x0324, NV30, "NVidia GeForce FX Go5200"}, \ + {0x10DE, 0x0325, NV30, "NVidia GeForce FX Go5250"}, \ + {0x10DE, 0x0326, NV30, "NVidia GeForce FX 5500"}, \ + {0x10DE, 0x0327, NV30, "NVidia GeForce FX 5100"}, \ + {0x10DE, 0x0328, NV30, "NVidia GeForce FX Go5200 32M/64M"}, \ + {0x10DE, 0x0329, NV30, "NVidia GeForce FX 5200 (Mac)"}, \ + {0x10DE, 0x032A, NV30, "NVidia Quadro NVS 280 PCI"}, \ + {0x10DE, 0x032B, NV30, "NVidia Quadro FX 500/600 PCI"}, \ + {0x10DE, 0x032C, NV30, "NVidia GeForce FX Go53xx Series"}, \ + {0x10DE, 0x032D, NV30, "NVidia GeForce FX Go5100"}, \ + {0x10DE, 0x032F, NV30, "NVidia 0x032F"}, \ + {0x10DE, 0x0330, NV30, "NVidia GeForce FX 5900 Ultra"}, \ + {0x10DE, 0x0331, NV30, "NVidia GeForce FX 5900"}, \ + {0x10DE, 0x0332, NV30, "NVidia GeForce FX 5900XT"}, \ + {0x10DE, 0x0333, NV30, "NVidia GeForce FX 5950 Ultra"}, \ + {0x10DE, 0x033F, NV30, "NVidia Quadro FX 700"}, \ + {0x10DE, 0x0334, NV30, "NVidia GeForce FX 5900ZT"}, \ + {0x10DE, 0x0338, NV30, "NVidia Quadro FX 3000"}, \ + {0x10DE, 0x0341, NV30, "NVidia GeForce FX 5700 Ultra"}, \ + {0x10DE, 0x0342, NV30, "NVidia GeForce FX 5700"}, \ + {0x10DE, 0x0343, NV30, "NVidia GeForce FX 5700LE"}, \ + {0x10DE, 0x0344, NV30, "NVidia GeForce FX 5700VE"}, \ + {0x10DE, 0x0345, NV30, "NVidia 0x0345"}, \ + {0x10DE, 0x0347, NV30, "NVidia GeForce FX Go5700"}, \ + {0x10DE, 0x0348, NV30, "NVidia GeForce FX Go5700"}, \ + {0x10DE, 0x0349, NV30, "NVidia 0x0349"}, \ + {0x10DE, 0x034B, NV30, "NVidia 0x034B"}, \ + {0x10DE, 0x034C, NV30, "NVidia Quadro FX Go1000"}, \ + {0x10DE, 0x034E, NV30, "NVidia Quadro FX 1100"}, \ + {0x10DE, 0x034F, NV30, "NVidia 0x034F"}, \ + {0x10DE, 0x0040, NV40, "NVidia GeForce 6800 Ultra"}, \ + {0x10DE, 0x0041, NV40, "NVidia GeForce 6800"}, \ + {0x10DE, 0x0042, NV40, "NVidia GeForce 6800 LE"}, \ + {0x10DE, 0x0043, NV40, "NVidia 0x0043"}, \ + {0x10DE, 0x0045, NV40, "NVidia GeForce 6800 GT"}, \ + {0x10DE, 0x0046, NV40, "NVidia GeForce 6800 GT"}, \ + {0x10DE, 0x0049, NV40, "NVidia 0x0049"}, \ + {0x10DE, 0x004E, NV40, "NVidia Quadro FX 4000"}, \ + {0x10DE, 0x00C0, NV40, "NVidia 0x00C0"}, \ + {0x10DE, 0x00C1, NV40, "NVidia GeForce 6800"}, \ + {0x10DE, 0x00C2, NV40, "NVidia GeForce 6800 LE"}, \ + {0x10DE, 0x00C8, NV40, "NVidia GeForce Go 6800"}, \ + {0x10DE, 0x00C9, NV40, "NVidia GeForce Go 6800 Ultra"}, \ + {0x10DE, 0x00CC, NV40, "NVidia Quadro FX Go1400"}, \ + {0x10DE, 0x00CD, NV40, "NVidia Quadro FX 3450/4000 SDI"}, \ + {0x10DE, 0x00CE, NV40, "NVidia Quadro FX 1400"}, \ + {0x10de, 0x00f0, NV40, "Nvidia GeForce 6600 GT"}, \ + {0x10de, 0x00f1, NV40, "Nvidia GeForce 6600 GT"}, \ + {0x10DE, 0x0140, NV40, "NVidia GeForce 6600 GT"}, \ + {0x10DE, 0x0141, NV40, "NVidia GeForce 6600"}, \ + {0x10DE, 0x0142, NV40, "NVidia GeForce 6600 LE"}, \ + {0x10DE, 0x0143, NV40, "NVidia 0x0143"}, \ + {0x10DE, 0x0144, NV40, "NVidia GeForce Go 6600"}, \ + {0x10DE, 0x0145, NV40, "NVidia GeForce 6610 XL"}, \ + {0x10DE, 0x0146, NV40, "NVidia GeForce Go 6600 TE/6200 TE"}, \ + {0x10DE, 0x0147, NV40, "NVidia GeForce 6700 XL"}, \ + {0x10DE, 0x0148, NV40, "NVidia GeForce Go 6600"}, \ + {0x10DE, 0x0149, NV40, "NVidia GeForce Go 6600 GT"}, \ + {0x10DE, 0x014B, NV40, "NVidia 0x014B"}, \ + {0x10DE, 0x014C, NV40, "NVidia 0x014C"}, \ + {0x10DE, 0x014D, NV40, "NVidia 0x014D"}, \ + {0x10DE, 0x014E, NV40, "NVidia Quadro FX 540"}, \ + {0x10DE, 0x014F, NV40, "NVidia GeForce 6200"}, \ + {0x10DE, 0x0160, NV40, "NVidia 0x0160"}, \ + {0x10DE, 0x0161, NV40, "NVidia GeForce 6200 TurboCache(TM)"}, \ + {0x10DE, 0x0162, NV40, "NVidia GeForce 6200SE TurboCache(TM)"}, \ + {0x10DE, 0x0163, NV40, "NVidia 0x0163"}, \ + {0x10DE, 0x0164, NV40, "NVidia GeForce Go 6200"}, \ + {0x10DE, 0x0165, NV40, "NVidia Quadro NVS 285"}, \ + {0x10DE, 0x0166, NV40, "NVidia GeForce Go 6400"}, \ + {0x10DE, 0x0167, NV40, "NVidia GeForce Go 6200"}, \ + {0x10DE, 0x0168, NV40, "NVidia GeForce Go 6400"}, \ + {0x10DE, 0x0169, NV40, "NVidia 0x0169"}, \ + {0x10DE, 0x016B, NV40, "NVidia 0x016B"}, \ + {0x10DE, 0x016C, NV40, "NVidia 0x016C"}, \ + {0x10DE, 0x016D, NV40, "NVidia 0x016D"}, \ + {0x10DE, 0x016E, NV40, "NVidia 0x016E"}, \ + {0x10DE, 0x0210, NV40, "NVidia 0x0210"}, \ + {0x10DE, 0x0211, NV40, "NVidia GeForce 6800"}, \ + {0x10DE, 0x0212, NV40, "NVidia GeForce 6800 LE"}, \ + {0x10DE, 0x0215, NV40, "NVidia GeForce 6800 GT"}, \ + {0x10DE, 0x0220, NV40, "NVidia 0x0220"}, \ + {0x10DE, 0x0221, NV40, "NVidia GeForce 6200"}, \ + {0x10DE, 0x0222, NV40, "NVidia 0x0222"}, \ + {0x10DE, 0x0228, NV40, "NVidia 0x0228"}, \ + {0x10DE, 0x0090, NV40, "NVidia 0x0090"}, \ + {0x10DE, 0x0091, NV40, "NVidia GeForce 7800 GTX"}, \ + {0x10DE, 0x0092, NV40, "NVidia 0x0092"}, \ + {0x10DE, 0x0093, NV40, "NVidia 0x0093"}, \ + {0x10DE, 0x0094, NV40, "NVidia 0x0094"}, \ + {0x10DE, 0x0098, NV40, "NVidia 0x0098"}, \ + {0x10DE, 0x0099, NV40, "NVidia GeForce Go 7800 GTX"}, \ + {0x10DE, 0x009C, NV40, "NVidia 0x009C"}, \ + {0x10DE, 0x009D, NV40, "NVidia Quadro FX 4500"}, \ + {0x10DE, 0x009E, NV40, "NVidia 0x009E"}, \ + {0, 0, 0, NULL} Index: dev/drm/drm_sarea.h =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/drm_sarea.h,v retrieving revision 1.5 diff -u -r1.5 drm_sarea.h --- dev/drm/drm_sarea.h 16 Apr 2005 03:44:44 -0000 1.5 +++ dev/drm/drm_sarea.h 23 Nov 2005 10:13:23 -0000 @@ -27,10 +27,11 @@ * 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. - * - * $FreeBSD: src/sys/dev/drm/drm_sarea.h,v 1.5 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #ifndef _DRM_SAREA_H_ #define _DRM_SAREA_H_ Index: dev/drm/drm_scatter.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/drm_scatter.c,v retrieving revision 1.1 diff -u -r1.1 drm_scatter.c --- dev/drm/drm_scatter.c 16 Apr 2005 03:44:44 -0000 1.1 +++ dev/drm/drm_scatter.c 23 Nov 2005 10:13:23 -0000 @@ -27,16 +27,18 @@ * Gareth Hughes * Eric Anholt * - * $FreeBSD: src/sys/dev/drm/drm_scatter.c,v 1.1 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" #define DEBUG_SCATTER 0 void drm_sg_cleanup(drm_sg_mem_t *entry) { - free(entry->virtual, M_DRM); + free((void *)entry->handle, M_DRM); free(entry->busaddr, M_DRM); free(entry, M_DRM); } @@ -47,6 +49,7 @@ drm_scatter_gather_t request; drm_sg_mem_t *entry; unsigned long pages; + int i; DRM_DEBUG( "%s\n", __FUNCTION__ ); @@ -72,16 +75,18 @@ return ENOMEM; } - entry->virtual = malloc(pages << PAGE_SHIFT, M_DRM, M_WAITOK | M_ZERO); - if ( !entry->virtual ) { + entry->handle = (long)malloc(pages << PAGE_SHIFT, M_DRM, + M_WAITOK | M_ZERO); + if (entry->handle == 0) { drm_sg_cleanup(entry); return ENOMEM; } - entry->handle = (unsigned long)entry->virtual; + for (i = 0; i < pages; i++) { + entry->busaddr[i] = vtophys(entry->handle + i * PAGE_SIZE); + } DRM_DEBUG( "sg alloc handle = %08lx\n", entry->handle ); - DRM_DEBUG( "sg alloc virtual = %p\n", entry->virtual ); request.handle = entry->handle; @@ -118,7 +123,7 @@ if ( !entry || entry->handle != request.handle ) return EINVAL; - DRM_DEBUG( "sg free virtual = %p\n", entry->virtual ); + DRM_DEBUG( "sg free virtual = 0x%lx\n", entry->handle ); drm_sg_cleanup(entry); Index: dev/drm/drm_sysctl.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/drm_sysctl.c,v retrieving revision 1.1 diff -u -r1.1 drm_sysctl.c --- dev/drm/drm_sysctl.c 16 Apr 2005 03:44:44 -0000 1.1 +++ dev/drm/drm_sysctl.c 23 Nov 2005 10:13:23 -0000 @@ -19,10 +19,11 @@ * ERIC ANHOLT 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. - * - * $FreeBSD: src/sys/dev/drm/drm_sysctl.c,v 1.1 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" #include "dev/drm/drm.h" @@ -129,7 +130,7 @@ int retcode; int hasunique = 0; - DRM_SYSCTL_PRINT("%s 0x%x", dev->driver_name, dev2udev(dev->devnode)); + DRM_SYSCTL_PRINT("%s 0x%x", dev->driver.name, dev2udev(dev->devnode)); DRM_LOCK(); if (dev->unique) { Index: dev/drm/drm_vm.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/drm_vm.c,v retrieving revision 1.1 diff -u -r1.1 drm_vm.c --- dev/drm/drm_vm.c 16 Apr 2005 03:44:44 -0000 1.1 +++ dev/drm/drm_vm.c 23 Nov 2005 10:13:23 -0000 @@ -19,10 +19,11 @@ * ERIC ANHOLT 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. - * - * $FreeBSD: src/sys/dev/drm/drm_vm.c,v 1.1 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" #include "dev/drm/drm.h" @@ -39,6 +40,11 @@ drm_local_map_t *map; drm_file_t *priv; drm_map_type_t type; +#ifdef __FreeBSD__ + vm_paddr_t phys; +#else + paddr_t phys; +#endif DRM_LOCK(); priv = drm_find_file_by_proc(dev, DRM_CURPROC); @@ -51,10 +57,11 @@ if (!priv->authenticated) return DRM_ERR(EACCES); - DRM_SPINLOCK(&dev->dma_lock); if (dev->dma && offset >= 0 && offset < ptoa(dev->dma->page_count)) { drm_device_dma_t *dma = dev->dma; + DRM_SPINLOCK(&dev->dma_lock); + if (dma->pagelist != NULL) { unsigned long page = offset >> PAGE_SHIFT; unsigned long phys = dma->pagelist[page]; @@ -70,8 +77,8 @@ DRM_SPINUNLOCK(&dev->dma_lock); return -1; } + DRM_SPINUNLOCK(&dev->dma_lock); } - DRM_SPINUNLOCK(&dev->dma_lock); /* A sequential search of a linked list is fine here because: 1) there will only be @@ -91,7 +98,7 @@ DRM_DEBUG("can't find map\n"); return -1; } - if (((map->flags&_DRM_RESTRICTED) && DRM_SUSER(DRM_CURPROC))) { + if (((map->flags&_DRM_RESTRICTED) && !DRM_SUSER(DRM_CURPROC))) { DRM_UNLOCK(); DRM_DEBUG("restricted map\n"); return -1; @@ -103,25 +110,25 @@ case _DRM_FRAME_BUFFER: case _DRM_REGISTERS: case _DRM_AGP: -#if defined(__FreeBSD__) && __FreeBSD_version >= 500102 - *paddr = offset; - return 0; -#else - return atop(offset); -#endif + phys = offset; + break; + case _DRM_CONSISTENT: + phys = vtophys((char *)map->handle + (offset - map->offset)); + break; case _DRM_SCATTER_GATHER: case _DRM_SHM: -#if defined(__FreeBSD__) && __FreeBSD_version >= 500102 - *paddr = vtophys(offset); - return 0; -#else - return atop(vtophys(offset)); -#endif + phys = vtophys(offset); + break; default: + DRM_ERROR("bad map type %d\n", type); return -1; /* This should never happen. */ } - DRM_DEBUG("bailing out\n"); - return -1; +#if defined(__FreeBSD__) && __FreeBSD_version >= 500102 + *paddr = phys; + return 0; +#else + return atop(phys); +#endif } Index: dev/drm/i915_dma.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/i915_dma.c,v retrieving revision 1.1 diff -u -r1.1 i915_dma.c --- dev/drm/i915_dma.c 16 Apr 2005 03:44:44 -0000 1.1 +++ dev/drm/i915_dma.c 23 Nov 2005 10:13:23 -0000 @@ -1,18 +1,38 @@ /* i915_dma.c -- DMA support for the I915 -*- linux-c -*- - * - * $FreeBSD: src/sys/dev/drm/i915_dma.c,v 1.1 2005/04/16 03:44:44 anholt Exp $ */ -/************************************************************************** - * +/*- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS 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. + * + */ + +#include +__FBSDID("$FreeBSD$"); -#include "drmP.h" -#include "drm.h" -#include "i915_drm.h" -#include "i915_drv.h" +#include "dev/drm/drmP.h" +#include "dev/drm/drm.h" +#include "dev/drm/i915_drm.h" +#include "dev/drm/i915_drv.h" /* 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 @@ -77,9 +97,8 @@ drm_core_ioremapfree(&dev_priv->ring.map, dev); } - if (dev_priv->hw_status_page) { - drm_pci_free(dev, PAGE_SIZE, dev_priv->hw_status_page, - dev_priv->dma_status_page); + if (dev_priv->status_page_dmah) { + drm_pci_free(dev, dev_priv->status_page_dmah); /* Need to rewrite hardware status page */ I915_WRITE(0x02080, 0x1ffff000); } @@ -156,15 +175,18 @@ dev_priv->allow_batchbuffer = 1; /* Program Hardware Status Page */ - dev_priv->hw_status_page = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, - 0xffffffff, &dev_priv->dma_status_page); + dev_priv->status_page_dmah = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, + 0xffffffff); - if (!dev_priv->hw_status_page) { + if (!dev_priv->status_page_dmah) { dev->dev_private = (void *)dev_priv; i915_dma_cleanup(dev); DRM_ERROR("Can not allocate hardware status page\n"); return DRM_ERR(ENOMEM); } + dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr; + dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; + memset(dev_priv->hw_status_page, 0, PAGE_SIZE); DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); @@ -690,7 +712,19 @@ return 0; } -void i915_driver_pretakedown(drm_device_t * dev) +int i915_driver_load(drm_device_t *dev, unsigned long flags) +{ + /* i915 has 4 more counters */ + dev->counters += 4; + dev->types[6] = _DRM_STAT_IRQ; + dev->types[7] = _DRM_STAT_PRIMARY; + dev->types[8] = _DRM_STAT_SECONDARY; + dev->types[9] = _DRM_STAT_DMA; + + return 0; +} + +void i915_driver_lastclose(drm_device_t * dev) { if (dev->dev_private) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -699,7 +733,7 @@ i915_dma_cleanup(dev); } -void i915_driver_prerelease(drm_device_t * dev, DRMFILE filp) +void i915_driver_preclose(drm_device_t * dev, DRMFILE filp) { if (dev->dev_private) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -711,18 +745,34 @@ } 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} + [DRM_IOCTL_NR(DRM_I915_INIT)] = {i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, + [DRM_IOCTL_NR(DRM_I915_FLUSH)] = {i915_flush_ioctl, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_I915_FLIP)] = {i915_flip_bufs, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_I915_BATCHBUFFER)] = {i915_batchbuffer, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_I915_IRQ_EMIT)] = {i915_irq_emit, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_I915_IRQ_WAIT)] = {i915_irq_wait, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_I915_GETPARAM)] = {i915_getparam, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_I915_SETPARAM)] = {i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, + [DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, + [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, DRM_AUTH} }; int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); + +/** + * Determine if the device really is AGP or not. + * + * All Intel graphics chipsets are treated as AGP, even if they are really + * PCI-e. + * + * \param dev The device to be tested. + * + * \returns + * A value of 1 is always retured to indictate every i9x5 is AGP. + */ +int i915_driver_device_is_agp(drm_device_t * dev) +{ + return 1; +} Index: dev/drm/i915_drm.h =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/i915_drm.h,v retrieving revision 1.1 diff -u -r1.1 i915_drm.h --- dev/drm/i915_drm.h 16 Apr 2005 03:44:44 -0000 1.1 +++ dev/drm/i915_drm.h 23 Nov 2005 10:13:23 -0000 @@ -1,4 +1,31 @@ -/* $FreeBSD: src/sys/dev/drm/i915_drm.h,v 1.1 2005/04/16 03:44:44 anholt Exp $ */ +/*- + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS 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. + * + */ + +#include +__FBSDID("$FreeBSD$"); #ifndef _I915_DRM_H_ #define _I915_DRM_H_ @@ -7,7 +34,7 @@ * subject to backwards-compatibility constraints. */ -#include "drm.h" +#include "dev/drm/drm.h" /* Each region is a minimum of 16k, and there are at most 255 of them. */ Index: dev/drm/i915_drv.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/i915_drv.c,v retrieving revision 1.1 diff -u -r1.1 i915_drv.c --- dev/drm/i915_drv.c 16 Apr 2005 03:44:44 -0000 1.1 +++ dev/drm/i915_drv.c 23 Nov 2005 10:13:23 -0000 @@ -27,47 +27,48 @@ * Authors: * Gareth Hughes * - * $FreeBSD: src/sys/dev/drm/i915_drv.c,v 1.1 2005/04/16 03:44:44 anholt Exp $ */ -#include "drmP.h" -#include "drm.h" -#include "i915_drm.h" -#include "i915_drv.h" -#include "drm_pciids.h" +#include +__FBSDID("$FreeBSD$"); + +#include "dev/drm/drmP.h" +#include "dev/drm/drm.h" +#include "dev/drm/i915_drm.h" +#include "dev/drm/i915_drv.h" +#include "dev/drm/drm_pciids.h" /* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */ static drm_pci_id_list_t i915_pciidlist[] = { i915_PCI_IDS }; -extern drm_ioctl_desc_t i915_ioctls[]; -extern int i915_max_ioctl; - static void i915_configure(drm_device_t *dev) { - dev->dev_priv_size = 1; /* No dev_priv */ - dev->prerelease = i915_driver_prerelease; - dev->pretakedown = i915_driver_pretakedown; - dev->irq_preinstall = i915_driver_irq_preinstall; - dev->irq_postinstall = i915_driver_irq_postinstall; - dev->irq_uninstall = i915_driver_irq_uninstall; - dev->irq_handler = i915_driver_irq_handler; - - dev->driver_ioctls = i915_ioctls; - dev->max_driver_ioctl = i915_max_ioctl; - - dev->driver_name = DRIVER_NAME; - dev->driver_desc = DRIVER_DESC; - dev->driver_date = DRIVER_DATE; - dev->driver_major = DRIVER_MAJOR; - dev->driver_minor = DRIVER_MINOR; - dev->driver_patchlevel = DRIVER_PATCHLEVEL; - - dev->use_agp = 1; - dev->require_agp = 1; - dev->use_mtrr = 1; - dev->use_irq = 1; + dev->driver.buf_priv_size = 1; /* No dev_priv */ + dev->driver.load = i915_driver_load; + dev->driver.preclose = i915_driver_preclose; + dev->driver.lastclose = i915_driver_lastclose; + dev->driver.device_is_agp = i915_driver_device_is_agp, + dev->driver.irq_preinstall = i915_driver_irq_preinstall; + dev->driver.irq_postinstall = i915_driver_irq_postinstall; + dev->driver.irq_uninstall = i915_driver_irq_uninstall; + dev->driver.irq_handler = i915_driver_irq_handler; + + dev->driver.ioctls = i915_ioctls; + dev->driver.max_ioctl = i915_max_ioctl; + + dev->driver.name = DRIVER_NAME; + dev->driver.desc = DRIVER_DESC; + dev->driver.date = DRIVER_DATE; + dev->driver.major = DRIVER_MAJOR; + dev->driver.minor = DRIVER_MINOR; + dev->driver.patchlevel = DRIVER_PATCHLEVEL; + + dev->driver.use_agp = 1; + dev->driver.require_agp = 1; + dev->driver.use_mtrr = 1; + dev->driver.use_irq = 1; } #ifdef __FreeBSD__ Index: dev/drm/i915_drv.h =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/i915_drv.h,v retrieving revision 1.1 diff -u -r1.1 i915_drv.h --- dev/drm/i915_drv.h 16 Apr 2005 03:44:44 -0000 1.1 +++ dev/drm/i915_drv.h 23 Nov 2005 10:13:23 -0000 @@ -1,13 +1,34 @@ /* i915_drv.h -- Private header for the I915 driver -*- linux-c -*- - * - * $FreeBSD: src/sys/dev/drm/i915_drv.h,v 1.1 2005/04/16 03:44:44 anholt Exp $ */ -/************************************************************************** - * +/* + * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS 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. + * + */ + +#include +__FBSDID("$FreeBSD$"); #ifndef _I915_DRV_H_ #define _I915_DRV_H_ @@ -57,9 +78,10 @@ drm_i915_sarea_t *sarea_priv; drm_i915_ring_buffer_t ring; + drm_dma_handle_t *status_page_dmah; void *hw_status_page; - unsigned long counter; dma_addr_t dma_status_page; + unsigned long counter; int back_offset; int front_offset; @@ -77,10 +99,17 @@ unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; } drm_i915_private_t; +extern drm_ioctl_desc_t i915_ioctls[]; +extern int i915_max_ioctl; + /* i915_dma.c */ extern void i915_kernel_lost_context(drm_device_t * dev); -extern void i915_driver_pretakedown(drm_device_t * dev); -extern void i915_driver_prerelease(drm_device_t * dev, DRMFILE filp); +extern int i915_driver_load(struct drm_device *, unsigned long flags); +extern void i915_driver_lastclose(drm_device_t * dev); +extern void i915_driver_preclose(drm_device_t * dev, DRMFILE filp); +extern int i915_driver_device_is_agp(drm_device_t * dev); +extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg); /* i915_irq.c */ extern int i915_irq_emit(DRM_IOCTL_ARGS); Index: dev/drm/i915_irq.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/i915_irq.c,v retrieving revision 1.1 diff -u -r1.1 i915_irq.c --- dev/drm/i915_irq.c 16 Apr 2005 03:44:44 -0000 1.1 +++ dev/drm/i915_irq.c 23 Nov 2005 10:13:23 -0000 @@ -1,18 +1,38 @@ -/* i915_dma.c -- DMA support for the I915 -*- linux-c -*- - * - * $FreeBSD: src/sys/dev/drm/i915_irq.c,v 1.1 2005/04/16 03:44:44 anholt Exp $ +/* i915_irq.c -- IRQ support for the I915 -*- linux-c -*- */ -/************************************************************************** - * +/*- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS 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. + * + */ + +#include +__FBSDID("$FreeBSD$"); -#include "drmP.h" -#include "drm.h" -#include "i915_drm.h" -#include "i915_drv.h" +#include "dev/drm/drmP.h" +#include "dev/drm/drm.h" +#include "dev/drm/i915_drm.h" +#include "dev/drm/i915_drv.h" #define USER_INT_FLAG 0x2 #define MAX_NOPID ((u32)~0) Index: dev/drm/i915_mem.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/i915_mem.c,v retrieving revision 1.1 diff -u -r1.1 i915_mem.c --- dev/drm/i915_mem.c 16 Apr 2005 03:44:44 -0000 1.1 +++ dev/drm/i915_mem.c 23 Nov 2005 10:13:23 -0000 @@ -1,18 +1,38 @@ /* i915_mem.c -- Simple agp/fb memory manager for i915 -*- linux-c -*- - * - * $FreeBSD: src/sys/dev/drm/i915_mem.c,v 1.1 2005/04/16 03:44:44 anholt Exp $ */ -/************************************************************************** - * +/*- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS 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. + * + */ + +#include +__FBSDID("$FreeBSD$"); -#include "drmP.h" -#include "drm.h" -#include "i915_drm.h" -#include "i915_drv.h" +#include "dev/drm/drmP.h" +#include "dev/drm/drm.h" +#include "dev/drm/i915_drm.h" +#include "dev/drm/i915_drv.h" /* This memory manager is integrated into the global/local lru * mechanisms used by the clients. Specifically, it operates by Index: dev/drm/mach64_dma.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/mach64_dma.c,v retrieving revision 1.1 diff -u -r1.1 mach64_dma.c --- dev/drm/mach64_dma.c 16 Apr 2005 03:44:44 -0000 1.1 +++ dev/drm/mach64_dma.c 23 Nov 2005 10:13:23 -0000 @@ -9,7 +9,7 @@ * \author Jose Fonseca */ -/* +/*- * Copyright 2000 Gareth Hughes * Copyright 2002 Frank C. Earl * Copyright 2002-2003 Leif Delgass @@ -32,10 +32,11 @@ * THE COPYRIGHT OWNER(S) 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. - * - * $FreeBSD: src/sys/dev/drm/mach64_dma.c,v 1.1 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" #include "dev/drm/drm.h" #include "dev/drm/mach64_drm.h" @@ -577,8 +578,7 @@ static int mach64_bm_dma_test(drm_device_t * dev) { drm_mach64_private_t *dev_priv = dev->dev_private; - dma_addr_t data_handle; - void *cpu_addr_data; + drm_dma_handle_t *cpu_addr_dmah; u32 data_addr; u32 *table, *data; u32 expected[2]; @@ -591,14 +591,14 @@ /* FIXME: get a dma buffer from the freelist here */ DRM_DEBUG("Allocating data memory ...\n"); - cpu_addr_data = - drm_pci_alloc(dev, 0x1000, 0x1000, 0xfffffffful, &data_handle); - if (!cpu_addr_data || !data_handle) { + cpu_addr_dmah = + drm_pci_alloc(dev, 0x1000, 0x1000, 0xfffffffful); + if (!cpu_addr_dmah) { DRM_INFO("data-memory allocation failed!\n"); return DRM_ERR(ENOMEM); } else { - data = (u32 *) cpu_addr_data; - data_addr = (u32) data_handle; + data = (u32 *) cpu_addr_dmah->vaddr; + data_addr = (u32) cpu_addr_dmah->busaddr; } /* Save the X server's value for SRC_CNTL and restore it @@ -626,7 +626,7 @@ DRM_INFO("resetting engine ...\n"); mach64_do_engine_reset(dev_priv); DRM_INFO("freeing data buffer memory.\n"); - drm_pci_free(dev, 0x1000, cpu_addr_data, data_handle); + drm_pci_free(dev, cpu_addr_dmah); return DRM_ERR(EIO); } } @@ -681,7 +681,7 @@ MACH64_WRITE(MACH64_PAT_REG0, pat_reg0); MACH64_WRITE(MACH64_PAT_REG1, pat_reg1); DRM_INFO("freeing data buffer memory.\n"); - drm_pci_free(dev, 0x1000, cpu_addr_data, data_handle); + drm_pci_free(dev, cpu_addr_dmah); return i; } DRM_DEBUG("waiting for idle...done\n"); @@ -717,7 +717,7 @@ MACH64_WRITE(MACH64_PAT_REG0, pat_reg0); MACH64_WRITE(MACH64_PAT_REG1, pat_reg1); DRM_INFO("freeing data buffer memory.\n"); - drm_pci_free(dev, 0x1000, cpu_addr_data, data_handle); + drm_pci_free(dev, cpu_addr_dmah); return i; } @@ -745,7 +745,7 @@ MACH64_WRITE(MACH64_PAT_REG1, pat_reg1); DRM_DEBUG("freeing data buffer memory.\n"); - drm_pci_free(dev, 0x1000, cpu_addr_data, data_handle); + drm_pci_free(dev, cpu_addr_dmah); DRM_DEBUG("returning ...\n"); return failed; @@ -898,16 +898,17 @@ dev_priv->ring.size = 0x4000; /* 16KB */ if (dev_priv->is_pci) { - dev_priv->ring.start = drm_pci_alloc(dev, dev_priv->ring.size, + dev_priv->ring.dmah = drm_pci_alloc(dev, dev_priv->ring.size, dev_priv->ring.size, - 0xfffffffful, - &dev_priv->ring.handle); + 0xfffffffful); - if (!dev_priv->ring.start || !dev_priv->ring.handle) { + if (!dev_priv->ring.dmah) { DRM_ERROR("Allocating dma descriptor ring failed\n"); return DRM_ERR(ENOMEM); } else { - dev_priv->ring.start_addr = (u32) dev_priv->ring.handle; + dev_priv->ring.start = dev_priv->ring.dmah->vaddr; + dev_priv->ring.start_addr = + (u32) dev_priv->ring.dmah->busaddr; } } else { dev_priv->ring.start = dev_priv->ring_map->handle; @@ -1151,11 +1152,8 @@ drm_mach64_private_t *dev_priv = dev->dev_private; if (dev_priv->is_pci) { - if ((dev_priv->ring.start != NULL) - && dev_priv->ring.handle) { - drm_pci_free(dev, dev_priv->ring.size, - dev_priv->ring.start, - dev_priv->ring.handle); + if (dev_priv->ring.dmah) { + drm_pci_free(dev, dev_priv->ring.dmah); } } else { if (dev_priv->ring_map) @@ -1524,7 +1522,7 @@ return ret; } -void mach64_driver_pretakedown(drm_device_t * dev) +void mach64_driver_lastclose(drm_device_t * dev) { mach64_do_cleanup_dma(dev); } Index: dev/drm/mach64_drm.h =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/mach64_drm.h,v retrieving revision 1.1 diff -u -r1.1 mach64_drm.h --- dev/drm/mach64_drm.h 16 Apr 2005 03:44:44 -0000 1.1 +++ dev/drm/mach64_drm.h 23 Nov 2005 10:13:23 -0000 @@ -1,6 +1,7 @@ /* mach64_drm.h -- Public header for the mach64 driver -*- linux-c -*- * Created: Thu Nov 30 20:04:32 2000 by gareth@valinux.com - * + */ +/*- * Copyright 2000 Gareth Hughes * Copyright 2002 Frank C. Earl * Copyright 2002-2003 Leif Delgass @@ -28,10 +29,11 @@ * Gareth Hughes * Frank C. Earl * Leif Delgass - * - * $FreeBSD: src/sys/dev/drm/mach64_drm.h,v 1.1 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #ifndef __MACH64_DRM_H__ #define __MACH64_DRM_H__ Index: dev/drm/mach64_drv.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/mach64_drv.c,v retrieving revision 1.1 diff -u -r1.1 mach64_drv.c --- dev/drm/mach64_drv.c 16 Apr 2005 03:44:44 -0000 1.1 +++ dev/drm/mach64_drv.c 23 Nov 2005 10:13:23 -0000 @@ -28,10 +28,11 @@ * Authors: * Rickard E. (Rik) Faith * Gareth Hughes - * - * $FreeBSD: src/sys/dev/drm/mach64_drv.c,v 1.1 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include @@ -46,36 +47,33 @@ mach64_PCI_IDS }; -extern drm_ioctl_desc_t mach64_ioctls[]; -extern int mach64_max_ioctl; - static void mach64_configure(drm_device_t *dev) { - dev->dev_priv_size = 1; /* No dev_priv */ - dev->pretakedown = mach64_driver_pretakedown; - dev->vblank_wait = mach64_driver_vblank_wait; - dev->irq_preinstall = mach64_driver_irq_preinstall; - dev->irq_postinstall = mach64_driver_irq_postinstall; - dev->irq_uninstall = mach64_driver_irq_uninstall; - dev->irq_handler = mach64_driver_irq_handler; - dev->dma_ioctl = mach64_dma_buffers; - - dev->driver_ioctls = mach64_ioctls; - dev->max_driver_ioctl = mach64_max_ioctl; - - dev->driver_name = DRIVER_NAME; - dev->driver_desc = DRIVER_DESC; - dev->driver_date = DRIVER_DATE; - dev->driver_major = DRIVER_MAJOR; - dev->driver_minor = DRIVER_MINOR; - dev->driver_patchlevel = DRIVER_PATCHLEVEL; - - dev->use_agp = 1; - dev->use_mtrr = 1; - dev->use_pci_dma = 1; - dev->use_dma = 1; - dev->use_irq = 1; - dev->use_vbl_irq = 1; + dev->driver.buf_priv_size = 1; /* No dev_priv */ + dev->driver.lastclose = mach64_driver_lastclose; + dev->driver.vblank_wait = mach64_driver_vblank_wait; + dev->driver.irq_preinstall = mach64_driver_irq_preinstall; + dev->driver.irq_postinstall = mach64_driver_irq_postinstall; + dev->driver.irq_uninstall = mach64_driver_irq_uninstall; + dev->driver.irq_handler = mach64_driver_irq_handler; + dev->driver.dma_ioctl = mach64_dma_buffers; + + dev->driver.ioctls = mach64_ioctls; + dev->driver.max_ioctl = mach64_max_ioctl; + + dev->driver.name = DRIVER_NAME; + dev->driver.desc = DRIVER_DESC; + dev->driver.date = DRIVER_DATE; + dev->driver.major = DRIVER_MAJOR; + dev->driver.minor = DRIVER_MINOR; + dev->driver.patchlevel = DRIVER_PATCHLEVEL; + + dev->driver.use_agp = 1; + dev->driver.use_mtrr = 1; + dev->driver.use_pci_dma = 1; + dev->driver.use_dma = 1; + dev->driver.use_irq = 1; + dev->driver.use_vbl_irq = 1; } #ifdef __FreeBSD__ Index: dev/drm/mach64_drv.h =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/mach64_drv.h,v retrieving revision 1.1 diff -u -r1.1 mach64_drv.h --- dev/drm/mach64_drv.h 16 Apr 2005 03:44:44 -0000 1.1 +++ dev/drm/mach64_drv.h 23 Nov 2005 10:13:23 -0000 @@ -1,6 +1,7 @@ /* mach64_drv.h -- Private header for mach64 driver -*- linux-c -*- * Created: Fri Nov 24 22:07:58 2000 by gareth@valinux.com - * + */ +/*- * Copyright 2000 Gareth Hughes * Copyright 2002 Frank C. Earl * Copyright 2002-2003 Leif Delgass @@ -29,10 +30,11 @@ * Frank C. Earl * Leif Delgass * Jos�Fonseca - * - * $FreeBSD: src/sys/dev/drm/mach64_drv.h,v 1.1 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #ifndef __MACH64_DRV_H__ #define __MACH64_DRV_H__ @@ -62,7 +64,7 @@ } drm_mach64_freelist_t; typedef struct drm_mach64_descriptor_ring { - dma_addr_t handle; /* handle (bus address) of ring returned by pci_alloc_consistent() */ + drm_dma_handle_t *dmah; /* Handle to pci dma memory */ void *start; /* write pointer (cpu address) to start of descriptor ring */ u32 start_addr; /* bus address of beginning of descriptor ring */ int size; /* size of ring in bytes */ @@ -110,13 +112,16 @@ drm_local_map_t *agp_textures; } drm_mach64_private_t; +extern drm_ioctl_desc_t mach64_ioctls[]; +extern int mach64_max_ioctl; + /* mach64_dma.c */ extern int mach64_dma_init(DRM_IOCTL_ARGS); extern int mach64_dma_idle(DRM_IOCTL_ARGS); extern int mach64_dma_flush(DRM_IOCTL_ARGS); extern int mach64_engine_reset(DRM_IOCTL_ARGS); extern int mach64_dma_buffers(DRM_IOCTL_ARGS); -extern void mach64_driver_pretakedown(drm_device_t * dev); +extern void mach64_driver_lastclose(drm_device_t * dev); extern int mach64_init_freelist(drm_device_t * dev); extern void mach64_destroy_freelist(drm_device_t * dev); Index: dev/drm/mach64_irq.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/mach64_irq.c,v retrieving revision 1.1 diff -u -r1.1 mach64_irq.c --- dev/drm/mach64_irq.c 16 Apr 2005 03:44:44 -0000 1.1 +++ dev/drm/mach64_irq.c 23 Nov 2005 10:13:23 -0000 @@ -1,6 +1,7 @@ /* mach64_irq.c -- IRQ handling for ATI Mach64 -*- linux-c -*- * Created: Tue Feb 25, 2003 by Leif Delgass, based on radeon_irq.c/r128_irq.c - * + */ +/*- * Copyright (C) The Weather Channel, Inc. 2002. * Copyright 2003 Leif Delgass * All Rights Reserved. @@ -32,10 +33,11 @@ * Keith Whitwell * Eric Anholt * Leif Delgass - * - * $FreeBSD: src/sys/dev/drm/mach64_irq.c,v 1.1 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" #include "dev/drm/drm.h" #include "dev/drm/mach64_drm.h" Index: dev/drm/mach64_state.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/mach64_state.c,v retrieving revision 1.1 diff -u -r1.1 mach64_state.c --- dev/drm/mach64_state.c 16 Apr 2005 03:44:44 -0000 1.1 +++ dev/drm/mach64_state.c 23 Nov 2005 10:13:23 -0000 @@ -1,6 +1,7 @@ /* mach64_state.c -- State support for mach64 (Rage Pro) driver -*- linux-c -*- * Created: Sun Dec 03 19:20:26 2000 by gareth@valinux.com - * + */ +/*- * Copyright 2000 Gareth Hughes * Copyright 2002-2003 Leif Delgass * All Rights Reserved. @@ -27,10 +28,11 @@ * Gareth Hughes * Leif Delgass * Jos�Fonseca - * - * $FreeBSD: src/sys/dev/drm/mach64_state.c,v 1.1 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" #include "dev/drm/drm.h" #include "dev/drm/mach64_drm.h" @@ -42,15 +44,15 @@ * */ drm_ioctl_desc_t mach64_ioctls[] = { - [DRM_IOCTL_NR(DRM_MACH64_INIT)] = {mach64_dma_init, 1, 1}, - [DRM_IOCTL_NR(DRM_MACH64_CLEAR)] = {mach64_dma_clear, 1, 0}, - [DRM_IOCTL_NR(DRM_MACH64_SWAP)] = {mach64_dma_swap, 1, 0}, - [DRM_IOCTL_NR(DRM_MACH64_IDLE)] = {mach64_dma_idle, 1, 0}, - [DRM_IOCTL_NR(DRM_MACH64_RESET)] = {mach64_engine_reset, 1, 0}, - [DRM_IOCTL_NR(DRM_MACH64_VERTEX)] = {mach64_dma_vertex, 1, 0}, - [DRM_IOCTL_NR(DRM_MACH64_BLIT)] = {mach64_dma_blit, 1, 0}, - [DRM_IOCTL_NR(DRM_MACH64_FLUSH)] = {mach64_dma_flush, 1, 0}, - [DRM_IOCTL_NR(DRM_MACH64_GETPARAM)] = {mach64_get_param, 1, 0}, + [DRM_IOCTL_NR(DRM_MACH64_INIT)] = {mach64_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, + [DRM_IOCTL_NR(DRM_MACH64_CLEAR)] = {mach64_dma_clear, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_MACH64_SWAP)] = {mach64_dma_swap, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_MACH64_IDLE)] = {mach64_dma_idle, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_MACH64_RESET)] = {mach64_engine_reset, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_MACH64_VERTEX)] = {mach64_dma_vertex, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_MACH64_BLIT)] = {mach64_dma_blit, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_MACH64_FLUSH)] = {mach64_dma_flush, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_MACH64_GETPARAM)] = {mach64_get_param, DRM_AUTH}, }; int mach64_max_ioctl = DRM_ARRAY_SIZE(mach64_ioctls); @@ -481,25 +483,29 @@ /* Copy and verify a client submited buffer. * FIXME: Make an assembly optimized version */ -static __inline__ int copy_and_verify_from_user(u32 * to, const u32 * from, +static __inline__ int copy_and_verify_from_user(u32 *to, + const u32 __user *ufrom, unsigned long bytes) { unsigned long n = bytes; /* dwords remaining in buffer */ + u32 *from, *orig_from; + + from = drm_alloc(bytes, DRM_MEM_DRIVER); + if (from == NULL) + return ENOMEM; - if (DRM_VERIFYAREA_READ(from, n)) { - DRM_ERROR("%s: verify_area\n", __FUNCTION__); + if (DRM_COPY_FROM_USER(from, ufrom, bytes)) { + drm_free(from, bytes, DRM_MEM_DRIVER); return DRM_ERR(EFAULT); } + orig_from = from; /* we'll be modifying the "from" ptr, so save it */ n >>= 2; while (n > 1) { u32 data, reg, count; - if (DRM_GET_USER_UNCHECKED(data, from++)) { - DRM_ERROR("%s: get_user\n", __FUNCTION__); - return DRM_ERR(EFAULT); - } + data = *from++; n--; @@ -515,28 +521,25 @@ if ((reg >= 0x0190 && reg < 0x01c1) || (reg >= 0x01ca && reg <= 0x01cf)) { *to++ = data; - if (DRM_COPY_FROM_USER_UNCHECKED - (to, from, count << 2)) { - DRM_ERROR("%s: copy_from_user\n", - __FUNCTION__); - return DRM_ERR(EFAULT); - } + memcpy(to, from, count << 2); + from += count; to += count; } else { DRM_ERROR("%s: Got bad command: 0x%04x\n", __FUNCTION__, reg); + drm_free(orig_from, bytes, DRM_MEM_DRIVER); return DRM_ERR(EACCES); } - - from += count; } else { DRM_ERROR ("%s: Got bad command count(=%u) dwords remaining=%lu\n", __FUNCTION__, count, n); + drm_free(orig_from, bytes, DRM_MEM_DRIVER); return DRM_ERR(EINVAL); } } + drm_free(orig_from, bytes, DRM_MEM_DRIVER); if (n == 0) return 0; else { Index: dev/drm/mga_dma.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/mga_dma.c,v retrieving revision 1.12 diff -u -r1.12 mga_dma.c --- dev/drm/mga_dma.c 16 Apr 2005 03:44:44 -0000 1.12 +++ dev/drm/mga_dma.c 23 Nov 2005 10:13:23 -0000 @@ -1,7 +1,7 @@ /* mga_dma.c -- DMA support for mga g200/g400 -*- linux-c -*- - * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com */ -/*- - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. + * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com + */ +/* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * All Rights Reserved. * @@ -23,27 +23,33 @@ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Rickard E. (Rik) Faith - * Jeff Hartmann - * Keith Whitwell - * - * Rewritten by: - * Gareth Hughes - * - * $FreeBSD: src/sys/dev/drm/mga_dma.c,v 1.12 2005/04/16 03:44:44 anholt Exp $ + */ + +#include +__FBSDID("$FreeBSD$"); + +/** + * \file mga_dma.c + * DMA support for MGA G200 / G400. + * + * \author Rickard E. (Rik) Faith + * \author Jeff Hartmann + * \author Keith Whitwell + * \author Gareth Hughes */ #include "dev/drm/drmP.h" #include "dev/drm/drm.h" +#include "dev/drm/drm_sarea.h" #include "dev/drm/mga_drm.h" #include "dev/drm/mga_drv.h" #define MGA_DEFAULT_USEC_TIMEOUT 10000 #define MGA_FREELIST_DEBUG 0 -static int mga_do_cleanup_dma(drm_device_t * dev); +#define MINIMAL_CLEANUP 0 +#define FULL_CLEANUP 1 +static int mga_do_cleanup_dma(drm_device_t * dev, int full_cleanup); /* ================================================================ * Engine control @@ -150,7 +156,7 @@ DRM_DEBUG(" space = 0x%06x\n", primary->space); mga_flush_write_combine(); - MGA_WRITE(MGA_PRIMEND, tail | MGA_PAGPXFER); + MGA_WRITE(MGA_PRIMEND, tail | dev_priv->dma_access); DRM_DEBUG("done.\n"); } @@ -190,7 +196,7 @@ DRM_DEBUG(" space = 0x%06x\n", primary->space); mga_flush_write_combine(); - MGA_WRITE(MGA_PRIMEND, tail | MGA_PAGPXFER); + MGA_WRITE(MGA_PRIMEND, tail | dev_priv->dma_access); set_bit(0, &primary->wrapped); DRM_DEBUG("done.\n"); @@ -390,21 +396,420 @@ * DMA initialization, cleanup */ -static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init) +int mga_driver_load(drm_device_t *dev, unsigned long flags) { - drm_mga_private_t *dev_priv; - int ret; - DRM_DEBUG("\n"); + drm_mga_private_t * dev_priv; dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER); if (!dev_priv) return DRM_ERR(ENOMEM); + dev->dev_private = (void *)dev_priv; memset(dev_priv, 0, sizeof(drm_mga_private_t)); - dev_priv->chipset = init->chipset; - dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT; + dev_priv->chipset = flags; + + dev_priv->mmio_base = drm_get_resource_start(dev, 1); + dev_priv->mmio_size = drm_get_resource_len(dev, 1); + + dev->counters += 3; + dev->types[6] = _DRM_STAT_IRQ; + dev->types[7] = _DRM_STAT_PRIMARY; + dev->types[8] = _DRM_STAT_SECONDARY; + + return 0; +} + +/** + * Bootstrap the driver for AGP DMA. + * + * \todo + * Investigate whether there is any benifit to storing the WARP microcode in + * AGP memory. If not, the microcode may as well always be put in PCI + * memory. + * + * \todo + * This routine needs to set dma_bs->agp_mode to the mode actually configured + * in the hardware. Looking just at the Linux AGP driver code, I don't see + * an easy way to determine this. + * + * \sa mga_do_dma_bootstrap, mga_do_pci_dma_bootstrap + */ +static int mga_do_agp_dma_bootstrap(drm_device_t * dev, + drm_mga_dma_bootstrap_t * dma_bs) +{ + drm_mga_private_t * const dev_priv = (drm_mga_private_t *) dev->dev_private; + unsigned int warp_size = mga_warp_microcode_size(dev_priv); + int err; + unsigned offset; + const unsigned secondary_size = dma_bs->secondary_bin_count + * dma_bs->secondary_bin_size; + const unsigned agp_size = (dma_bs->agp_size << 20); + drm_buf_desc_t req; + drm_agp_mode_t mode; + drm_agp_info_t info; + drm_agp_buffer_t agp_req; + drm_agp_binding_t bind_req; + + /* Acquire AGP. */ + err = drm_agp_acquire(dev); + if (err) { + DRM_ERROR("Unable to acquire AGP: %d\n", err); + return err; + } + + err = drm_agp_info(dev, &info); + if (err) { + DRM_ERROR("Unable to get AGP info: %d\n", err); + return err; + } + + mode.mode = (info.mode & ~0x07) | dma_bs->agp_mode; + err = drm_agp_enable(dev, mode); + if (err) { + DRM_ERROR("Unable to enable AGP (mode = 0x%lx)\n", mode.mode); + return err; + } + + /* In addition to the usual AGP mode configuration, the G200 AGP cards + * need to have the AGP mode "manually" set. + */ + + if (dev_priv->chipset == MGA_CARD_TYPE_G200) { + if (mode.mode & 0x02) { + MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_ENABLE); + } else { + MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_DISABLE); + } + } + + + /* Allocate and bind AGP memory. */ + agp_req.size = agp_size; + agp_req.type = 0; + err = drm_agp_alloc( dev, & agp_req ); + if (err) { + dev_priv->agp_size = 0; + DRM_ERROR("Unable to allocate %uMB AGP memory\n", + dma_bs->agp_size); + return err; + } + + dev_priv->agp_size = agp_size; + dev_priv->agp_handle = agp_req.handle; + + bind_req.handle = agp_req.handle; + bind_req.offset = 0; + err = drm_agp_bind( dev, &bind_req ); + if (err) { + DRM_ERROR("Unable to bind AGP memory: %d\n", err); + return err; + } + + /* Make drm_addbufs happy by not trying to create a mapping for less + * than a page. + */ + if (warp_size < PAGE_SIZE) + warp_size = PAGE_SIZE; + + offset = 0; + err = drm_addmap( dev, offset, warp_size, + _DRM_AGP, _DRM_READ_ONLY, & dev_priv->warp ); + if (err) { + DRM_ERROR("Unable to map WARP microcode: %d\n", err); + return err; + } + + offset += warp_size; + err = drm_addmap( dev, offset, dma_bs->primary_size, + _DRM_AGP, _DRM_READ_ONLY, & dev_priv->primary ); + if (err) { + DRM_ERROR("Unable to map primary DMA region: %d\n", err); + return err; + } + + offset += dma_bs->primary_size; + err = drm_addmap( dev, offset, secondary_size, + _DRM_AGP, 0, & dev->agp_buffer_map ); + if (err) { + DRM_ERROR("Unable to map secondary DMA region: %d\n", err); + return err; + } + + (void) memset( &req, 0, sizeof(req) ); + req.count = dma_bs->secondary_bin_count; + req.size = dma_bs->secondary_bin_size; + req.flags = _DRM_AGP_BUFFER; + req.agp_start = offset; + + err = drm_addbufs_agp( dev, & req ); + if (err) { + DRM_ERROR("Unable to add secondary DMA buffers: %d\n", err); + return err; + } + +#ifdef __linux__ + { + drm_map_list_t *_entry; + unsigned long agp_token = 0; + + list_for_each_entry(_entry, &dev->maplist->head, head) { + if (_entry->map == dev->agp_buffer_map) + agp_token = _entry->user_token; + } + if (!agp_token) + return -EFAULT; + + dev->agp_buffer_token = agp_token; + } +#endif + + offset += secondary_size; + err = drm_addmap( dev, offset, agp_size - offset, + _DRM_AGP, 0, & dev_priv->agp_textures ); + if (err) { + DRM_ERROR("Unable to map AGP texture region: %d\n", err); + return err; + } + + drm_core_ioremap(dev_priv->warp, dev); + drm_core_ioremap(dev_priv->primary, dev); + drm_core_ioremap(dev->agp_buffer_map, dev); + + if (!dev_priv->warp->handle || + !dev_priv->primary->handle || !dev->agp_buffer_map->handle) { + DRM_ERROR("failed to ioremap agp regions! (%p, %p, %p)\n", + dev_priv->warp->handle, dev_priv->primary->handle, + dev->agp_buffer_map->handle); + return DRM_ERR(ENOMEM); + } + + dev_priv->dma_access = MGA_PAGPXFER; + dev_priv->wagp_enable = MGA_WAGP_ENABLE; + + DRM_INFO("Initialized card for AGP DMA.\n"); + return 0; +} + +/** + * Bootstrap the driver for PCI DMA. + * + * \todo + * The algorithm for decreasing the size of the primary DMA buffer could be + * better. The size should be rounded up to the nearest page size, then + * decrease the request size by a single page each pass through the loop. + * + * \todo + * Determine whether the maximum address passed to drm_pci_alloc is correct. + * The same goes for drm_addbufs_pci. + * + * \sa mga_do_dma_bootstrap, mga_do_agp_dma_bootstrap + */ +static int mga_do_pci_dma_bootstrap(drm_device_t * dev, + drm_mga_dma_bootstrap_t * dma_bs) +{ + drm_mga_private_t * const dev_priv = (drm_mga_private_t *) dev->dev_private; + unsigned int warp_size = mga_warp_microcode_size(dev_priv); + unsigned int primary_size; + unsigned int bin_count; + int err; + drm_buf_desc_t req; + + + if (dev->dma == NULL) { + DRM_ERROR("dev->dma is NULL\n"); + return DRM_ERR(EFAULT); + } + + /* Make drm_addbufs happy by not trying to create a mapping for less + * than a page. + */ + if (warp_size < PAGE_SIZE) + warp_size = PAGE_SIZE; + + /* The proper alignment is 0x100 for this mapping */ + err = drm_addmap(dev, 0, warp_size, _DRM_CONSISTENT, + _DRM_READ_ONLY, &dev_priv->warp); + if (err != 0) { + DRM_ERROR("Unable to create mapping for WARP microcode: %d\n", + err); + return err; + } + + /* Other than the bottom two bits being used to encode other + * information, there don't appear to be any restrictions on the + * alignment of the primary or secondary DMA buffers. + */ + + for ( primary_size = dma_bs->primary_size + ; primary_size != 0 + ; primary_size >>= 1 ) { + /* The proper alignment for this mapping is 0x04 */ + err = drm_addmap(dev, 0, primary_size, _DRM_CONSISTENT, + _DRM_READ_ONLY, &dev_priv->primary); + if (!err) + break; + } + + if (err != 0) { + DRM_ERROR("Unable to allocate primary DMA region: %d\n", err); + return DRM_ERR(ENOMEM); + } + + if (dev_priv->primary->size != dma_bs->primary_size) { + DRM_INFO("Primary DMA buffer size reduced from %u to %u.\n", + dma_bs->primary_size, + (unsigned) dev_priv->primary->size); + dma_bs->primary_size = dev_priv->primary->size; + } + + for ( bin_count = dma_bs->secondary_bin_count + ; bin_count > 0 + ; bin_count-- ) { + (void) memset( &req, 0, sizeof(req) ); + req.count = bin_count; + req.size = dma_bs->secondary_bin_size; + + err = drm_addbufs_pci( dev, & req ); + if (!err) { + break; + } + } + + if (bin_count == 0) { + DRM_ERROR("Unable to add secondary DMA buffers: %d\n", err); + return err; + } + + if (bin_count != dma_bs->secondary_bin_count) { + DRM_INFO("Secondary PCI DMA buffer bin count reduced from %u " + "to %u.\n", dma_bs->secondary_bin_count, bin_count); + + dma_bs->secondary_bin_count = bin_count; + } + + dev_priv->dma_access = 0; + dev_priv->wagp_enable = 0; + + dma_bs->agp_mode = 0; + + DRM_INFO("Initialized card for PCI DMA.\n"); + return 0; +} + + +static int mga_do_dma_bootstrap(drm_device_t * dev, + drm_mga_dma_bootstrap_t * dma_bs) +{ + const int is_agp = (dma_bs->agp_mode != 0) && drm_device_is_agp(dev); + int err; + drm_mga_private_t * const dev_priv = + (drm_mga_private_t *) dev->dev_private; + + + dev_priv->used_new_dma_init = 1; + + /* The first steps are the same for both PCI and AGP based DMA. Map + * the cards MMIO registers and map a status page. + */ + err = drm_addmap( dev, dev_priv->mmio_base, dev_priv->mmio_size, + _DRM_REGISTERS, _DRM_READ_ONLY, & dev_priv->mmio ); + if (err) { + DRM_ERROR("Unable to map MMIO region: %d\n", err); + return err; + } + + + err = drm_addmap( dev, 0, SAREA_MAX, _DRM_SHM, + _DRM_READ_ONLY | _DRM_LOCKED | _DRM_KERNEL, + & dev_priv->status ); + if (err) { + DRM_ERROR("Unable to map status region: %d\n", err); + return err; + } + + + /* The DMA initialization procedure is slightly different for PCI and + * AGP cards. AGP cards just allocate a large block of AGP memory and + * carve off portions of it for internal uses. The remaining memory + * is returned to user-mode to be used for AGP textures. + */ + + if (is_agp) { + err = mga_do_agp_dma_bootstrap(dev, dma_bs); + } + + /* If we attempted to initialize the card for AGP DMA but failed, + * clean-up any mess that may have been created. + */ + + if (err) { + mga_do_cleanup_dma(dev, MINIMAL_CLEANUP); + } + + + /* Not only do we want to try and initialized PCI cards for PCI DMA, + * but we also try to initialized AGP cards that could not be + * initialized for AGP DMA. This covers the case where we have an AGP + * card in a system with an unsupported AGP chipset. In that case the + * card will be detected as AGP, but we won't be able to allocate any + * AGP memory, etc. + */ + + if (!is_agp || err) { + err = mga_do_pci_dma_bootstrap(dev, dma_bs); + } + + + return err; +} + +int mga_dma_bootstrap(DRM_IOCTL_ARGS) +{ + DRM_DEVICE; + drm_mga_dma_bootstrap_t bootstrap; + int err; + static const int modes[] = { 0, 1, 2, 2, 4, 4, 4, 4 }; + const drm_mga_private_t * const dev_priv = + (drm_mga_private_t *) dev->dev_private; + + + DRM_COPY_FROM_USER_IOCTL(bootstrap, + (drm_mga_dma_bootstrap_t __user *) data, + sizeof(bootstrap)); + + err = mga_do_dma_bootstrap(dev, & bootstrap); + if (err) { + mga_do_cleanup_dma(dev, FULL_CLEANUP); + return err; + } + + if (dev_priv->agp_textures != NULL) { + bootstrap.texture_handle = dev_priv->agp_textures->offset; + bootstrap.texture_size = dev_priv->agp_textures->size; + } else { + bootstrap.texture_handle = 0; + bootstrap.texture_size = 0; + } + + bootstrap.agp_mode = modes[bootstrap.agp_mode & 0x07]; + + DRM_COPY_TO_USER_IOCTL((drm_mga_dma_bootstrap_t __user *)data, + bootstrap, sizeof(bootstrap)); + + return 0; +} + + +static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init) +{ + drm_mga_private_t *dev_priv; + int ret; + DRM_DEBUG("\n"); + + + dev_priv = dev->dev_private; if (init->sgram) { dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_BLK; @@ -432,85 +837,68 @@ if (!dev_priv->sarea) { DRM_ERROR("failed to find sarea!\n"); - /* Assign dev_private so we can do cleanup. */ - dev->dev_private = (void *)dev_priv; - mga_do_cleanup_dma(dev); return DRM_ERR(EINVAL); } - dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset); - if (!dev_priv->mmio) { - DRM_ERROR("failed to find mmio region!\n"); - /* Assign dev_private so we can do cleanup. */ - dev->dev_private = (void *)dev_priv; - mga_do_cleanup_dma(dev); - return DRM_ERR(EINVAL); - } - dev_priv->status = drm_core_findmap(dev, init->status_offset); - if (!dev_priv->status) { - DRM_ERROR("failed to find status page!\n"); - /* Assign dev_private so we can do cleanup. */ - dev->dev_private = (void *)dev_priv; - mga_do_cleanup_dma(dev); - return DRM_ERR(EINVAL); - } - dev_priv->warp = drm_core_findmap(dev, init->warp_offset); - if (!dev_priv->warp) { - DRM_ERROR("failed to find warp microcode region!\n"); - /* Assign dev_private so we can do cleanup. */ - dev->dev_private = (void *)dev_priv; - mga_do_cleanup_dma(dev); - return DRM_ERR(EINVAL); - } - dev_priv->primary = drm_core_findmap(dev, init->primary_offset); - if (!dev_priv->primary) { - DRM_ERROR("failed to find primary dma region!\n"); - /* Assign dev_private so we can do cleanup. */ - dev->dev_private = (void *)dev_priv; - mga_do_cleanup_dma(dev); - return DRM_ERR(EINVAL); - } - dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); - if (!dev->agp_buffer_map) { - DRM_ERROR("failed to find dma buffer region!\n"); - /* Assign dev_private so we can do cleanup. */ - dev->dev_private = (void *)dev_priv; - mga_do_cleanup_dma(dev); - return DRM_ERR(EINVAL); + if (! dev_priv->used_new_dma_init) { + + dev_priv->dma_access = MGA_PAGPXFER; + dev_priv->wagp_enable = MGA_WAGP_ENABLE; + + dev_priv->status = drm_core_findmap(dev, init->status_offset); + if (!dev_priv->status) { + DRM_ERROR("failed to find status page!\n"); + return DRM_ERR(EINVAL); + } + dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset); + if (!dev_priv->mmio) { + DRM_ERROR("failed to find mmio region!\n"); + return DRM_ERR(EINVAL); + } + dev_priv->warp = drm_core_findmap(dev, init->warp_offset); + if (!dev_priv->warp) { + DRM_ERROR("failed to find warp microcode region!\n"); + return DRM_ERR(EINVAL); + } + dev_priv->primary = drm_core_findmap(dev, init->primary_offset); + if (!dev_priv->primary) { + DRM_ERROR("failed to find primary dma region!\n"); + return DRM_ERR(EINVAL); + } + dev->agp_buffer_token = init->buffers_offset; + dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); + if (!dev->agp_buffer_map) { + DRM_ERROR("failed to find dma buffer region!\n"); + return DRM_ERR(EINVAL); + } + + drm_core_ioremap(dev_priv->warp, dev); + drm_core_ioremap(dev_priv->primary, dev); + drm_core_ioremap(dev->agp_buffer_map, dev); } dev_priv->sarea_priv = (drm_mga_sarea_t *) ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset); - drm_core_ioremap(dev_priv->warp, dev); - drm_core_ioremap(dev_priv->primary, dev); - drm_core_ioremap(dev->agp_buffer_map, dev); - if (!dev_priv->warp->handle || - !dev_priv->primary->handle || !dev->agp_buffer_map->handle) { + !dev_priv->primary->handle || + ((dev_priv->dma_access != 0) && + ((dev->agp_buffer_map == NULL) || + (dev->agp_buffer_map->handle == NULL)))) { DRM_ERROR("failed to ioremap agp regions!\n"); - /* Assign dev_private so we can do cleanup. */ - dev->dev_private = (void *)dev_priv; - mga_do_cleanup_dma(dev); return DRM_ERR(ENOMEM); } ret = mga_warp_install_microcode(dev_priv); - if (ret < 0) { - DRM_ERROR("failed to install WARP ucode!\n"); - /* Assign dev_private so we can do cleanup. */ - dev->dev_private = (void *)dev_priv; - mga_do_cleanup_dma(dev); + if (ret != 0) { + DRM_ERROR("failed to install WARP ucode: %d!\n", ret); return ret; } ret = mga_warp_init(dev_priv); - if (ret < 0) { - DRM_ERROR("failed to init WARP engine!\n"); - /* Assign dev_private so we can do cleanup. */ - dev->dev_private = (void *)dev_priv; - mga_do_cleanup_dma(dev); + if (ret != 0) { + DRM_ERROR("failed to init WARP engine: %d!\n", ret); return ret; } @@ -549,19 +937,15 @@ if (mga_freelist_init(dev, dev_priv) < 0) { DRM_ERROR("could not initialize freelist\n"); - /* Assign dev_private so we can do cleanup. */ - dev->dev_private = (void *)dev_priv; - mga_do_cleanup_dma(dev); return DRM_ERR(ENOMEM); } - /* Make dev_private visable to others. */ - dev->dev_private = (void *)dev_priv; return 0; } -static int mga_do_cleanup_dma(drm_device_t * dev) +static int mga_do_cleanup_dma(drm_device_t * dev, int full_cleanup) { + int err = 0; DRM_DEBUG("\n"); /* Make sure interrupts are disabled here because the uninstall ioctl @@ -574,22 +958,57 @@ if (dev->dev_private) { drm_mga_private_t *dev_priv = dev->dev_private; - if (dev_priv->warp != NULL) + if ((dev_priv->warp != NULL) + && (dev_priv->warp->type != _DRM_CONSISTENT)) drm_core_ioremapfree(dev_priv->warp, dev); - if (dev_priv->primary != NULL) + + if ((dev_priv->primary != NULL) + && (dev_priv->primary->type != _DRM_CONSISTENT)) drm_core_ioremapfree(dev_priv->primary, dev); - if (dev->agp_buffer_map != NULL) { + + if (dev->agp_buffer_map != NULL) drm_core_ioremapfree(dev->agp_buffer_map, dev); - dev->agp_buffer_map = NULL; + + if (dev_priv->used_new_dma_init) { + if (dev_priv->agp_handle != 0) { + drm_agp_binding_t unbind_req; + drm_agp_buffer_t free_req; + + unbind_req.handle = dev_priv->agp_handle; + drm_agp_unbind(dev, &unbind_req); + + free_req.handle = dev_priv->agp_handle; + drm_agp_free(dev, &free_req); + + dev_priv->agp_textures = NULL; + dev_priv->agp_size = 0; + dev_priv->agp_handle = 0; + } + + if ((dev->agp != NULL) && dev->agp->acquired) { + err = drm_agp_release(dev); + } + } + + dev_priv->warp = NULL; + dev_priv->primary = NULL; + dev_priv->sarea = NULL; + dev_priv->sarea_priv = NULL; + dev->agp_buffer_map = NULL; + + if (full_cleanup) { + dev_priv->mmio = NULL; + dev_priv->status = NULL; + dev_priv->used_new_dma_init = 0; } + memset(&dev_priv->prim, 0, sizeof(dev_priv->prim)); + dev_priv->warp_pipe = 0; + memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys)); + if (dev_priv->head != NULL) { mga_freelist_cleanup(dev); } - - drm_free(dev->dev_private, sizeof(drm_mga_private_t), - DRM_MEM_DRIVER); - dev->dev_private = NULL; } return 0; @@ -599,6 +1018,7 @@ { DRM_DEVICE; drm_mga_init_t init; + int err; LOCK_TEST_WITH_RETURN(dev, filp); @@ -607,9 +1027,13 @@ switch (init.func) { case MGA_INIT_DMA: - return mga_do_init_dma(dev, &init); + err = mga_do_init_dma(dev, &init); + if (err) { + (void) mga_do_cleanup_dma(dev, FULL_CLEANUP); + } + return err; case MGA_CLEANUP_DMA: - return mga_do_cleanup_dma(dev); + return mga_do_cleanup_dma(dev, FULL_CLEANUP); } return DRM_ERR(EINVAL); @@ -735,9 +1159,23 @@ return ret; } -void mga_driver_pretakedown(drm_device_t * dev) +/** + * Called just before the module is unloaded. + */ +int mga_driver_unload(drm_device_t * dev) +{ + drm_free(dev->dev_private, sizeof(drm_mga_private_t), DRM_MEM_DRIVER); + dev->dev_private = NULL; + + return 0; +} + +/** + * Called when the last opener of the device is closed. + */ +void mga_driver_lastclose(drm_device_t * dev) { - mga_do_cleanup_dma(dev); + mga_do_cleanup_dma(dev, FULL_CLEANUP); } int mga_driver_dma_quiescent(drm_device_t * dev) Index: dev/drm/mga_drm.h =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/mga_drm.h,v retrieving revision 1.6 diff -u -r1.6 mga_drm.h --- dev/drm/mga_drm.h 16 Apr 2005 03:44:44 -0000 1.6 +++ dev/drm/mga_drm.h 23 Nov 2005 10:13:23 -0000 @@ -1,6 +1,6 @@ /* mga_drm.h -- Public header for the Matrox g200/g400 driver -*- linux-c -*- - * Created: Tue Jan 25 01:50:01 1999 by jhartmann@precisioninsight.com */ -/*- + * Created: Tue Jan 25 01:50:01 1999 by jhartmann@precisioninsight.com + * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * All rights reserved. @@ -30,10 +30,11 @@ * * Rewritten by: * Gareth Hughes - * - * $FreeBSD: src/sys/dev/drm/mga_drm.h,v 1.6 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #ifndef __MGA_DRM_H__ #define __MGA_DRM_H__ @@ -75,6 +76,8 @@ #define MGA_CARD_TYPE_G200 1 #define MGA_CARD_TYPE_G400 2 +#define MGA_CARD_TYPE_G450 3 /* not currently used */ +#define MGA_CARD_TYPE_G550 4 #define MGA_FRONT 0x1 #define MGA_BACK 0x2 @@ -224,9 +227,6 @@ int ctxOwner; } drm_mga_sarea_t; -/* WARNING: If you change any of these defines, make sure to change the - * defines in the Xserver file (xf86drmMga.h) - */ /* MGA specific ioctls * The device specific ioctl range is 0x40 to 0x79. @@ -242,6 +242,14 @@ #define DRM_MGA_BLIT 0x08 #define DRM_MGA_GETPARAM 0x09 +/* 3.2: + * ioctls for operating on fences. + */ +#define DRM_MGA_SET_FENCE 0x0a +#define DRM_MGA_WAIT_FENCE 0x0b +#define DRM_MGA_DMA_BOOTSTRAP 0x0c + + #define DRM_IOCTL_MGA_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_INIT, drm_mga_init_t) #define DRM_IOCTL_MGA_FLUSH DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_FLUSH, drm_lock_t) #define DRM_IOCTL_MGA_RESET DRM_IO( DRM_COMMAND_BASE + DRM_MGA_RESET) @@ -252,6 +260,9 @@ #define DRM_IOCTL_MGA_ILOAD DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_ILOAD, drm_mga_iload_t) #define DRM_IOCTL_MGA_BLIT DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_BLIT, drm_mga_blit_t) #define DRM_IOCTL_MGA_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_GETPARAM, drm_mga_getparam_t) +#define DRM_IOCTL_MGA_SET_FENCE DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_SET_FENCE, uint32_t) +#define DRM_IOCTL_MGA_WAIT_FENCE DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_WAIT_FENCE, uint32_t) +#define DRM_IOCTL_MGA_DMA_BOOTSTRAP DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_DMA_BOOTSTRAP, drm_mga_dma_bootstrap_t) typedef struct _drm_mga_warp_index { int installed; @@ -290,12 +301,73 @@ unsigned long buffers_offset; } drm_mga_init_t; -typedef struct drm_mga_fullscreen { - enum { - MGA_INIT_FULLSCREEN = 0x01, - MGA_CLEANUP_FULLSCREEN = 0x02 - } func; -} drm_mga_fullscreen_t; + +typedef struct drm_mga_dma_bootstrap { + /** + * \name AGP texture region + * + * On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, these fields will + * be filled in with the actual AGP texture settings. + * + * \warning + * If these fields are non-zero, but dma_mga_dma_bootstrap::agp_mode + * is zero, it means that PCI memory (most likely through the use of + * an IOMMU) is being used for "AGP" textures. + */ + /*@{*/ + unsigned long texture_handle; /**< Handle used to map AGP textures. */ + uint32_t texture_size; /**< Size of the AGP texture region. */ + /*@}*/ + + + /** + * Requested size of the primary DMA region. + * + * On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, this field will be + * filled in with the actual AGP mode. If AGP was not available + */ + uint32_t primary_size; + + + /** + * Requested number of secondary DMA buffers. + * + * On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, this field will be + * filled in with the actual number of secondary DMA buffers + * allocated. Particularly when PCI DMA is used, this may be + * (subtantially) less than the number requested. + */ + uint32_t secondary_bin_count; + + + /** + * Requested size of each secondary DMA buffer. + * + * While the kernel \b is free to reduce + * dma_mga_dma_bootstrap::secondary_bin_count, it is \b not allowed + * to reduce dma_mga_dma_bootstrap::secondary_bin_size. + */ + uint32_t secondary_bin_size; + + + /** + * Bit-wise mask of AGPSTAT2_* values. Currently only \c AGPSTAT2_1X, + * \c AGPSTAT2_2X, and \c AGPSTAT2_4X are supported. If this value is + * zero, it means that PCI DMA should be used, even if AGP is + * possible. + * + * On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, this field will be + * filled in with the actual AGP mode. If AGP was not available + * (i.e., PCI DMA was used), this value will be zero. + */ + uint32_t agp_mode; + + + /** + * Desired AGP GART size, measured in megabytes. + */ + uint8_t agp_size; +} drm_mga_dma_bootstrap_t; typedef struct drm_mga_clear { unsigned int flags; @@ -340,6 +412,14 @@ */ #define MGA_PARAM_IRQ_NR 1 +/* 3.2: Query the actual card type. The DDX only distinguishes between + * G200 chips and non-G200 chips, which it calls G400. It turns out that + * there are some very sublte differences between the G4x0 chips and the G550 + * chips. Using this parameter query, a client-side driver can detect the + * difference between a G4x0 and a G550. + */ +#define MGA_PARAM_CARD_TYPE 2 + typedef struct drm_mga_getparam { int param; void __user *value; Index: dev/drm/mga_drv.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/mga_drv.c,v retrieving revision 1.9 diff -u -r1.9 mga_drv.c --- dev/drm/mga_drv.c 16 Apr 2005 03:44:44 -0000 1.9 +++ dev/drm/mga_drv.c 23 Nov 2005 10:13:23 -0000 @@ -29,9 +29,11 @@ * Rickard E. (Rik) Faith * Gareth Hughes * - * $FreeBSD: src/sys/dev/drm/mga_drv.c,v 1.9 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" #include "dev/drm/drm.h" #include "dev/drm/mga_drm.h" @@ -43,40 +45,63 @@ mga_PCI_IDS }; -extern drm_ioctl_desc_t mga_ioctls[]; -extern int mga_max_ioctl; +/** + * Determine if the device really is AGP or not. + * + * In addition to the usual tests performed by \c drm_device_is_agp, this + * function detects PCI G450 cards that appear to the system exactly like + * AGP G450 cards. + * + * \param dev The device to be tested. + * + * \returns + * If the device is a PCI G450, zero is returned. Otherwise non-zero is + * returned. + * + * \bug + * This function needs to be filled in! The implementation in + * linux-core/mga_drv.c shows what needs to be done. + */ +static int mga_driver_device_is_agp(drm_device_t * dev) +{ + return 1; +} static void mga_configure(drm_device_t *dev) { - dev->dev_priv_size = sizeof(drm_mga_buf_priv_t); - /* XXX dev->prerelease = mga_driver_prerelease; */ - dev->pretakedown = mga_driver_pretakedown; - dev->vblank_wait = mga_driver_vblank_wait; - dev->irq_preinstall = mga_driver_irq_preinstall; - dev->irq_postinstall = mga_driver_irq_postinstall; - dev->irq_uninstall = mga_driver_irq_uninstall; - dev->irq_handler = mga_driver_irq_handler; - dev->dma_ioctl = mga_dma_buffers; - dev->dma_quiescent = mga_driver_dma_quiescent; - - dev->driver_ioctls = mga_ioctls; - dev->max_driver_ioctl = mga_max_ioctl; - - dev->driver_name = DRIVER_NAME; - dev->driver_desc = DRIVER_DESC; - dev->driver_date = DRIVER_DATE; - dev->driver_major = DRIVER_MAJOR; - dev->driver_minor = DRIVER_MINOR; - dev->driver_patchlevel = DRIVER_PATCHLEVEL; - - dev->use_agp = 1; - dev->require_agp = 1; - dev->use_mtrr = 1; - dev->use_dma = 1; - dev->use_irq = 1; - dev->use_vbl_irq = 1; + dev->driver.buf_priv_size = sizeof(drm_mga_buf_priv_t); + dev->driver.load = mga_driver_load; + dev->driver.unload = mga_driver_unload; + dev->driver.lastclose = mga_driver_lastclose; + dev->driver.vblank_wait = mga_driver_vblank_wait; + dev->driver.irq_preinstall = mga_driver_irq_preinstall; + dev->driver.irq_postinstall = mga_driver_irq_postinstall; + dev->driver.irq_uninstall = mga_driver_irq_uninstall; + dev->driver.irq_handler = mga_driver_irq_handler; + dev->driver.dma_ioctl = mga_dma_buffers; + dev->driver.dma_quiescent = mga_driver_dma_quiescent; + dev->driver.device_is_agp = mga_driver_device_is_agp; + + dev->driver.ioctls = mga_ioctls; + dev->driver.max_ioctl = mga_max_ioctl; + + dev->driver.name = DRIVER_NAME; + dev->driver.desc = DRIVER_DESC; + dev->driver.date = DRIVER_DATE; + dev->driver.major = DRIVER_MAJOR; + dev->driver.minor = DRIVER_MINOR; + dev->driver.patchlevel = DRIVER_PATCHLEVEL; + + dev->driver.use_agp = 1; + dev->driver.require_agp = 1; + dev->driver.use_mtrr = 1; + dev->driver.use_dma = 1; + dev->driver.use_irq = 1; + dev->driver.use_vbl_irq = 1; } + + #ifdef __FreeBSD__ static int mga_probe(device_t dev) @@ -114,5 +139,10 @@ MODULE_DEPEND(mga, drm, 1, 1, 1); #elif defined(__NetBSD__) || defined(__OpenBSD__) +#ifdef _LKM CFDRIVER_DECL(mga, DV_TTY, NULL); +#else +CFATTACH_DECL(mga, sizeof(drm_device_t), drm_probe, drm_attach, drm_detach, + drm_activate); +#endif #endif Index: dev/drm/mga_drv.h =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/mga_drv.h,v retrieving revision 1.9 diff -u -r1.9 mga_drv.h --- dev/drm/mga_drv.h 16 Apr 2005 03:44:44 -0000 1.9 +++ dev/drm/mga_drv.h 23 Nov 2005 10:13:23 -0000 @@ -1,6 +1,6 @@ /* mga_drv.h -- Private header for the Matrox G200/G400 driver -*- linux-c -*- - * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com */ -/*- + * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com + * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * All rights reserved. @@ -26,10 +26,11 @@ * * Authors: * Gareth Hughes - * - * $FreeBSD: src/sys/dev/drm/mga_drv.h,v 1.9 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #ifndef __MGA_DRV_H__ #define __MGA_DRV_H__ @@ -40,11 +41,11 @@ #define DRIVER_NAME "mga" #define DRIVER_DESC "Matrox G200/G400" -#define DRIVER_DATE "20021029" +#define DRIVER_DATE "20051102" #define DRIVER_MAJOR 3 -#define DRIVER_MINOR 1 -#define DRIVER_PATCHLEVEL 0 +#define DRIVER_MINOR 2 +#define DRIVER_PATCHLEVEL 1 typedef struct drm_mga_primary_buffer { u8 *start; @@ -89,9 +90,43 @@ int chipset; int usec_timeout; + /** + * If set, the new DMA initialization sequence was used. This is + * primarilly used to select how the driver should uninitialized its + * internal DMA structures. + */ + int used_new_dma_init; + + /** + * If AGP memory is used for DMA buffers, this will be the value + * \c MGA_PAGPXFER. Otherwise, it will be zero (for a PCI transfer). + */ + u32 dma_access; + + /** + * If AGP memory is used for DMA buffers, this will be the value + * \c MGA_WAGP_ENABLE. Otherwise, it will be zero (for a PCI + * transfer). + */ + u32 wagp_enable; + + /** + * \name MMIO region parameters. + * + * \sa drm_mga_private_t::mmio + */ + /*@{*/ + u32 mmio_base; /**< Bus address of base of MMIO. */ + u32 mmio_size; /**< Size of the MMIO region. */ + /*@}*/ + u32 clear_cmd; u32 maccess; + wait_queue_head_t fence_queue; + atomic_t last_fence_retired; + u32 next_fence_to_post; + unsigned int fb_cpp; unsigned int front_offset; unsigned int front_pitch; @@ -110,16 +145,24 @@ drm_local_map_t *status; drm_local_map_t *warp; drm_local_map_t *primary; - drm_local_map_t *buffers; drm_local_map_t *agp_textures; + + unsigned long agp_handle; + unsigned int agp_size; } drm_mga_private_t; +extern drm_ioctl_desc_t mga_ioctls[]; +extern int mga_max_ioctl; + /* mga_dma.c */ +extern int mga_dma_bootstrap(DRM_IOCTL_ARGS); extern int mga_dma_init(DRM_IOCTL_ARGS); extern int mga_dma_flush(DRM_IOCTL_ARGS); extern int mga_dma_reset(DRM_IOCTL_ARGS); extern int mga_dma_buffers(DRM_IOCTL_ARGS); -extern void mga_driver_pretakedown(drm_device_t * dev); +extern int mga_driver_load(drm_device_t *dev, unsigned long flags); +extern int mga_driver_unload(drm_device_t * dev); +extern void mga_driver_lastclose(drm_device_t * dev); extern int mga_driver_dma_quiescent(drm_device_t * dev); extern int mga_do_wait_for_idle(drm_mga_private_t * dev_priv); @@ -131,14 +174,19 @@ extern int mga_freelist_put(drm_device_t * dev, drm_buf_t * buf); /* mga_warp.c */ +extern unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv); extern int mga_warp_install_microcode(drm_mga_private_t * dev_priv); extern int mga_warp_init(drm_mga_private_t * dev_priv); + /* mga_irq.c */ +extern int mga_driver_fence_wait(drm_device_t * dev, unsigned int *sequence); extern int mga_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence); extern irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS); extern void mga_driver_irq_preinstall(drm_device_t * dev); extern void mga_driver_irq_postinstall(drm_device_t * dev); extern void mga_driver_irq_uninstall(drm_device_t * dev); +extern long mga_compat_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg); #define mga_flush_write_combine() DRM_WRITEMEMORYBARRIER() @@ -183,7 +231,7 @@ #define MGA_EMIT_STATE( dev_priv, dirty ) \ do { \ if ( (dirty) & ~MGA_UPLOAD_CLIPRECTS ) { \ - if ( dev_priv->chipset == MGA_CARD_TYPE_G400 ) { \ + if ( dev_priv->chipset >= MGA_CARD_TYPE_G400 ) { \ mga_g400_emit_state( dev_priv ); \ } else { \ mga_g200_emit_state( dev_priv ); \ @@ -520,6 +568,12 @@ */ #define MGA_EXEC 0x0100 +/* AGP PLL encoding (for G200 only). + */ +#define MGA_AGP_PLL 0x1e4c +# define MGA_AGP2XPLL_DISABLE (0 << 0) +# define MGA_AGP2XPLL_ENABLE (1 << 0) + /* Warp registers */ #define MGA_WR0 0x2d00 Index: dev/drm/mga_irq.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/mga_irq.c,v retrieving revision 1.5 diff -u -r1.5 mga_irq.c --- dev/drm/mga_irq.c 16 Apr 2005 03:44:44 -0000 1.5 +++ dev/drm/mga_irq.c 23 Nov 2005 10:13:23 -0000 @@ -1,4 +1,5 @@ -/* mga_irq.c -- IRQ handling for radeon -*- linux-c -*- */ +/* mga_irq.c -- IRQ handling for radeon -*- linux-c -*- + */ /*- * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. * @@ -28,10 +29,11 @@ * Authors: * Keith Whitwell * Eric Anholt - * - * $FreeBSD: src/sys/dev/drm/mga_irq.c,v 1.5 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" #include "dev/drm/drm.h" #include "dev/drm/mga_drm.h" @@ -42,6 +44,7 @@ drm_device_t *dev = (drm_device_t *) arg; drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; int status; + int handled = 0; status = MGA_READ(MGA_STATUS); @@ -51,6 +54,30 @@ atomic_inc(&dev->vbl_received); DRM_WAKEUP(&dev->vbl_queue); drm_vbl_send_signals(dev); + handled = 1; + } + + /* SOFTRAP interrupt */ + if (status & MGA_SOFTRAPEN) { + const u32 prim_start = MGA_READ(MGA_PRIMADDRESS); + const u32 prim_end = MGA_READ(MGA_PRIMEND); + + + MGA_WRITE(MGA_ICLEAR, MGA_SOFTRAPICLR); + + /* In addition to clearing the interrupt-pending bit, we + * have to write to MGA_PRIMEND to re-start the DMA operation. + */ + if ( (prim_start & ~0x03) != (prim_end & ~0x03) ) { + MGA_WRITE(MGA_PRIMEND, prim_end); + } + + atomic_inc(&dev_priv->last_fence_retired); + DRM_WAKEUP(&dev_priv->fence_queue); + handled = 1; + } + + if ( handled ) { return IRQ_HANDLED; } return IRQ_NONE; @@ -74,6 +101,25 @@ return ret; } +int mga_driver_fence_wait(drm_device_t * dev, unsigned int *sequence) +{ + drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; + unsigned int cur_fence; + int ret = 0; + + /* Assume that the user has missed the current sequence number + * by about a day rather than she wants to wait for years + * using fences. + */ + DRM_WAIT_ON(ret, dev_priv->fence_queue, 3 * DRM_HZ, + (((cur_fence = atomic_read(&dev_priv->last_fence_retired)) + - *sequence) <= (1 << 23))); + + *sequence = cur_fence; + + return ret; +} + void mga_driver_irq_preinstall(drm_device_t * dev) { drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; @@ -88,8 +134,10 @@ { drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - /* Turn on VBL interrupt */ - MGA_WRITE(MGA_IEN, MGA_VLINEIEN); + DRM_INIT_WAITQUEUE( &dev_priv->fence_queue ); + + /* Turn on vertical blank interrupt and soft trap interrupt. */ + MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); } void mga_driver_irq_uninstall(drm_device_t * dev) @@ -100,4 +148,6 @@ /* Disable *all* interrupts */ MGA_WRITE(MGA_IEN, 0); + + dev->irq_enabled = 0; } Index: dev/drm/mga_state.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/mga_state.c,v retrieving revision 1.10 diff -u -r1.10 mga_state.c --- dev/drm/mga_state.c 16 Apr 2005 03:44:44 -0000 1.10 +++ dev/drm/mga_state.c 23 Nov 2005 10:13:23 -0000 @@ -1,5 +1,6 @@ /* mga_state.c -- State support for MGA G200/G400 -*- linux-c -*- - * Created: Thu Jan 27 02:53:43 2000 by jhartmann@precisioninsight.com */ + * Created: Thu Jan 27 02:53:43 2000 by jhartmann@precisioninsight.com + */ /*- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. @@ -30,11 +31,11 @@ * * Rewritten by: * Gareth Hughes - * $FreeBSD: src/sys/dev/drm/mga_state.c,v 1.10 2005/04/16 03:44:44 anholt Exp $ - * - * $FreeBSD: src/sys/dev/drm/mga_state.c,v 1.10 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" #include "dev/drm/drm.h" #include "dev/drm/mga_drm.h" @@ -56,7 +57,7 @@ /* Force reset of DWGCTL on G400 (eliminates clip disable bit). */ - if (dev_priv->chipset == MGA_CARD_TYPE_G400) { + if (dev_priv->chipset >= MGA_CARD_TYPE_G400) { DMA_BLOCK(MGA_DWGCTL, ctx->dwgctl, MGA_LEN + MGA_EXEC, 0x80000000, MGA_DWGCTL, ctx->dwgctl, @@ -267,7 +268,7 @@ MGA_DMAPAD, 0xffffffff, MGA_DMAPAD, 0xffffffff, MGA_WIADDR, (dev_priv->warp_pipe_phys[pipe] | - MGA_WMODE_START | MGA_WAGP_ENABLE)); + MGA_WMODE_START | dev_priv->wagp_enable)); ADVANCE_DMA(); } @@ -348,7 +349,7 @@ MGA_DMAPAD, 0xffffffff, MGA_DMAPAD, 0xffffffff, MGA_WIADDR2, (dev_priv->warp_pipe_phys[pipe] | - MGA_WMODE_START | MGA_WAGP_ENABLE)); + MGA_WMODE_START | dev_priv->wagp_enable)); ADVANCE_DMA(); } @@ -458,7 +459,7 @@ if (dirty & MGA_UPLOAD_TEX0) ret |= mga_verify_tex(dev_priv, 0); - if (dev_priv->chipset == MGA_CARD_TYPE_G400) { + if (dev_priv->chipset >= MGA_CARD_TYPE_G400) { if (dirty & MGA_UPLOAD_TEX1) ret |= mga_verify_tex(dev_priv, 1); @@ -682,7 +683,7 @@ MGA_SECADDRESS, (address | MGA_DMA_VERTEX), MGA_SECEND, ((address + length) | - MGA_PAGPXFER)); + dev_priv->dma_access)); ADVANCE_DMA(); } while (++i < sarea_priv->nbox); @@ -728,7 +729,7 @@ MGA_DMAPAD, 0x00000000, MGA_SETUPADDRESS, address + start, MGA_SETUPEND, ((address + end) | - MGA_PAGPXFER)); + dev_priv->dma_access)); ADVANCE_DMA(); } while (++i < sarea_priv->nbox); @@ -755,7 +756,7 @@ drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_buf_priv_t *buf_priv = buf->dev_private; drm_mga_context_regs_t *ctx = &dev_priv->sarea_priv->context_state; - u32 srcorg = buf->bus_address | MGA_SRCACC_AGP | MGA_SRCMAP_SYSMEM; + u32 srcorg = buf->bus_address | dev_priv->dma_access | MGA_SRCMAP_SYSMEM; u32 y2; DMA_LOCALS; DRM_DEBUG("buf=%d used=%d\n", buf->idx, buf->used); @@ -1090,6 +1091,9 @@ case MGA_PARAM_IRQ_NR: value = dev->irq; break; + case MGA_PARAM_CARD_TYPE: + value = dev_priv->chipset; + break; default: return DRM_ERR(EINVAL); } @@ -1102,17 +1106,76 @@ return 0; } +static int mga_set_fence(DRM_IOCTL_ARGS) +{ + DRM_DEVICE; + drm_mga_private_t *dev_priv = dev->dev_private; + u32 temp; + DMA_LOCALS; + + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); + return DRM_ERR(EINVAL); + } + + DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); + + /* I would normal do this assignment in the declaration of temp, + * but dev_priv may be NULL. + */ + + temp = dev_priv->next_fence_to_post; + dev_priv->next_fence_to_post++; + + BEGIN_DMA(1); + DMA_BLOCK(MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_SOFTRAP, 0x00000000); + ADVANCE_DMA(); + + DRM_COPY_TO_USER_IOCTL((u32 __user *)data, temp, sizeof(u32)); + + return 0; +} + +static int mga_wait_fence(DRM_IOCTL_ARGS) +{ + DRM_DEVICE; + drm_mga_private_t *dev_priv = dev->dev_private; + u32 fence; + + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); + return DRM_ERR(EINVAL); + } + + DRM_COPY_FROM_USER_IOCTL(fence, (u32 __user *) data, sizeof(u32)); + + DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); + + mga_driver_fence_wait(dev, & fence); + + DRM_COPY_TO_USER_IOCTL((u32 __user *)data, fence, sizeof(u32)); + + return 0; +} + 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}, + [DRM_IOCTL_NR(DRM_MGA_INIT)] = {mga_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, + [DRM_IOCTL_NR(DRM_MGA_FLUSH)] = {mga_dma_flush, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_MGA_RESET)] = {mga_dma_reset, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_MGA_SWAP)] = {mga_dma_swap, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_MGA_CLEAR)] = {mga_dma_clear, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_MGA_VERTEX)] = {mga_dma_vertex, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_MGA_INDICES)] = {mga_dma_indices, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_MGA_ILOAD)] = {mga_dma_iload, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_MGA_BLIT)] = {mga_dma_blit, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_MGA_GETPARAM)] = {mga_getparam, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_MGA_SET_FENCE)] = {mga_set_fence, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_MGA_WAIT_FENCE)] = {mga_wait_fence, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_MGA_DMA_BOOTSTRAP)] = {mga_dma_bootstrap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, + }; int mga_max_ioctl = DRM_ARRAY_SIZE(mga_ioctls); Index: dev/drm/mga_ucode.h =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/mga_ucode.h,v retrieving revision 1.3 diff -u -r1.3 mga_ucode.h --- dev/drm/mga_ucode.h 16 Apr 2005 03:44:44 -0000 1.3 +++ dev/drm/mga_ucode.h 23 Nov 2005 10:13:23 -0000 @@ -1,6 +1,6 @@ /* mga_ucode.h -- Matrox G200/G400 WARP engine microcode -*- linux-c -*- - * Created: Thu Jan 11 21:20:43 2001 by gareth@valinux.com */ -/*- + * Created: Thu Jan 11 21:20:43 2001 by gareth@valinux.com + * * Copyright 1999 Matrox Graphics Inc. * All Rights Reserved. * @@ -24,10 +24,11 @@ * * Kernel-based WARP engine management: * Gareth Hughes - * - * $FreeBSD: src/sys/dev/drm/mga_ucode.h,v 1.3 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + /* * WARP pipes are named according to the functions they perform, where: * Index: dev/drm/mga_warp.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/mga_warp.c,v retrieving revision 1.7 diff -u -r1.7 mga_warp.c --- dev/drm/mga_warp.c 16 Apr 2005 03:44:44 -0000 1.7 +++ dev/drm/mga_warp.c 23 Nov 2005 10:13:23 -0000 @@ -1,5 +1,6 @@ /* mga_warp.c -- Matrox G200/G400 WARP engine management -*- linux-c -*- - * Created: Thu Jan 11 21:29:32 2001 by gareth@valinux.com */ + * Created: Thu Jan 11 21:29:32 2001 by gareth@valinux.com + */ /*- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * All Rights Reserved. @@ -25,10 +26,11 @@ * * Authors: * Gareth Hughes - * - * $FreeBSD: src/sys/dev/drm/mga_warp.c,v 1.7 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" #include "dev/drm/drm.h" #include "dev/drm/mga_drm.h" @@ -49,11 +51,8 @@ vcbase += WARP_UCODE_SIZE( which ); \ } while (0) -static unsigned int mga_warp_g400_microcode_size(drm_mga_private_t * dev_priv) -{ - unsigned int size; - - size = (WARP_UCODE_SIZE(warp_g400_tgz) + +static const unsigned int mga_warp_g400_microcode_size = + (WARP_UCODE_SIZE(warp_g400_tgz) + WARP_UCODE_SIZE(warp_g400_tgza) + WARP_UCODE_SIZE(warp_g400_tgzaf) + WARP_UCODE_SIZE(warp_g400_tgzf) + @@ -70,17 +69,8 @@ WARP_UCODE_SIZE(warp_g400_t2gzsaf) + WARP_UCODE_SIZE(warp_g400_t2gzsf)); - size = PAGE_ALIGN(size); - - DRM_DEBUG("G400 ucode size = %d bytes\n", size); - return size; -} - -static unsigned int mga_warp_g200_microcode_size(drm_mga_private_t * dev_priv) -{ - unsigned int size; - - size = (WARP_UCODE_SIZE(warp_g200_tgz) + +static const unsigned int mga_warp_g200_microcode_size = + (WARP_UCODE_SIZE(warp_g200_tgz) + WARP_UCODE_SIZE(warp_g200_tgza) + WARP_UCODE_SIZE(warp_g200_tgzaf) + WARP_UCODE_SIZE(warp_g200_tgzf) + @@ -89,24 +79,25 @@ WARP_UCODE_SIZE(warp_g200_tgzsaf) + WARP_UCODE_SIZE(warp_g200_tgzsf)); - size = PAGE_ALIGN(size); - DRM_DEBUG("G200 ucode size = %d bytes\n", size); - return size; +unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv) +{ + switch (dev_priv->chipset) { + case MGA_CARD_TYPE_G400: + case MGA_CARD_TYPE_G550: + return PAGE_ALIGN(mga_warp_g400_microcode_size); + case MGA_CARD_TYPE_G200: + return PAGE_ALIGN(mga_warp_g200_microcode_size); + default: + DRM_ERROR("Unknown chipset value: 0x%x\n", dev_priv->chipset); + return 0; + } } static int mga_warp_install_g400_microcode(drm_mga_private_t * dev_priv) { unsigned char *vcbase = dev_priv->warp->handle; unsigned long pcbase = dev_priv->warp->offset; - unsigned int size; - - size = mga_warp_g400_microcode_size(dev_priv); - if (size > dev_priv->warp->size) { - DRM_ERROR("microcode too large! (%u > %lu)\n", - size, dev_priv->warp->size); - return DRM_ERR(ENOMEM); - } memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys)); @@ -135,14 +126,6 @@ { unsigned char *vcbase = dev_priv->warp->handle; unsigned long pcbase = dev_priv->warp->offset; - unsigned int size; - - size = mga_warp_g200_microcode_size(dev_priv); - if (size > dev_priv->warp->size) { - DRM_ERROR("microcode too large! (%u > %lu)\n", - size, dev_priv->warp->size); - return DRM_ERR(ENOMEM); - } memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys)); @@ -160,8 +143,18 @@ int mga_warp_install_microcode(drm_mga_private_t * dev_priv) { + const unsigned int size = mga_warp_microcode_size(dev_priv); + + DRM_DEBUG("MGA ucode size = %d bytes\n", size); + if (size > dev_priv->warp->size) { + DRM_ERROR("microcode too large! (%u > %lu)\n", + size, dev_priv->warp->size); + return DRM_ERR(ENOMEM); + } + switch (dev_priv->chipset) { case MGA_CARD_TYPE_G400: + case MGA_CARD_TYPE_G550: return mga_warp_install_g400_microcode(dev_priv); case MGA_CARD_TYPE_G200: return mga_warp_install_g200_microcode(dev_priv); @@ -180,6 +173,7 @@ */ switch (dev_priv->chipset) { case MGA_CARD_TYPE_G400: + case MGA_CARD_TYPE_G550: MGA_WRITE(MGA_WIADDR2, MGA_WMODE_SUSPEND); MGA_WRITE(MGA_WGETMSB, 0x00000E00); MGA_WRITE(MGA_WVRTXSZ, 0x00001807); Index: dev/drm/r128_cce.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/r128_cce.c,v retrieving revision 1.13 diff -u -r1.13 r128_cce.c --- dev/drm/r128_cce.c 20 Jul 2005 21:10:57 -0000 1.13 +++ dev/drm/r128_cce.c 23 Nov 2005 10:13:23 -0000 @@ -1,5 +1,6 @@ /* r128_cce.c -- ATI Rage 128 driver -*- linux-c -*- - * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com */ + * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com + */ /*- * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. @@ -26,10 +27,11 @@ * * Authors: * Gareth Hughes - * - * $FreeBSD: src/sys/dev/drm/r128_cce.c,v 1.13 2005/07/20 21:10:57 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" #include "dev/drm/drm.h" #include "dev/drm/r128_drm.h" @@ -325,7 +327,8 @@ ring_start = dev_priv->cce_ring->offset - dev->agp->base; else #endif - ring_start = dev_priv->cce_ring->offset - dev->sg->handle; + ring_start = dev_priv->cce_ring->offset - + (unsigned long)dev->sg->virtual; R128_WRITE(R128_PM4_BUFFER_OFFSET, ring_start | R128_AGP_OFFSET); @@ -486,6 +489,7 @@ r128_do_cleanup_cce(dev); return DRM_ERR(EINVAL); } + dev->agp_buffer_token = init->buffers_offset; dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); if (!dev->agp_buffer_map) { DRM_ERROR("could not find dma buffer region!\n"); @@ -537,7 +541,7 @@ dev_priv->cce_buffers_offset = dev->agp->base; else #endif - dev_priv->cce_buffers_offset = dev->sg->handle; + dev_priv->cce_buffers_offset = (unsigned long)dev->sg->virtual; dev_priv->ring.start = (u32 *) dev_priv->cce_ring->handle; dev_priv->ring.end = ((u32 *) dev_priv->cce_ring->handle @@ -558,14 +562,17 @@ #if __OS_HAS_AGP if (dev_priv->is_pci) { #endif - if (!drm_ati_pcigart_init(dev, &dev_priv->phys_pci_gart, - &dev_priv->bus_pci_gart, 0)) { + dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; + dev_priv->gart_info.addr = NULL; + dev_priv->gart_info.bus_addr = 0; + dev_priv->gart_info.is_pcie = 0; + if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { DRM_ERROR("failed to init PCI GART!\n"); dev->dev_private = (void *)dev_priv; r128_do_cleanup_cce(dev); return DRM_ERR(ENOMEM); } - R128_WRITE(R128_PCI_GART_PAGE, dev_priv->bus_pci_gart); + R128_WRITE(R128_PCI_GART_PAGE, dev_priv->gart_info.bus_addr); #if __OS_HAS_AGP } #endif @@ -606,10 +613,9 @@ } else #endif { - if (!drm_ati_pcigart_cleanup(dev, - dev_priv->phys_pci_gart, - dev_priv->bus_pci_gart)) - DRM_ERROR("failed to cleanup PCI GART!\n"); + if (dev_priv->gart_info.bus_addr) + if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info)) + DRM_ERROR("failed to cleanup PCI GART!\n"); } drm_free(dev->dev_private, sizeof(drm_r128_private_t), Index: dev/drm/r128_drm.h =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/r128_drm.h,v retrieving revision 1.7 diff -u -r1.7 r128_drm.h --- dev/drm/r128_drm.h 16 Apr 2005 03:44:44 -0000 1.7 +++ dev/drm/r128_drm.h 23 Nov 2005 10:13:23 -0000 @@ -1,5 +1,6 @@ /* r128_drm.h -- Public header for the r128 driver -*- linux-c -*- - * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com */ + * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com + */ /*- * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. @@ -27,10 +28,11 @@ * Authors: * Gareth Hughes * Kevin E. Martin - * - * $FreeBSD: src/sys/dev/drm/r128_drm.h,v 1.7 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #ifndef __R128_DRM_H__ #define __R128_DRM_H__ @@ -215,7 +217,7 @@ #define DRM_IOCTL_R128_INDIRECT DRM_IOWR(DRM_COMMAND_BASE + DRM_R128_INDIRECT, drm_r128_indirect_t) #define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( DRM_COMMAND_BASE + DRM_R128_FULLSCREEN, drm_r128_fullscreen_t) #define DRM_IOCTL_R128_CLEAR2 DRM_IOW( DRM_COMMAND_BASE + DRM_R128_CLEAR2, drm_r128_clear2_t) -#define DRM_IOCTL_R128_GETPARAM DRM_IOW( DRM_COMMAND_BASE + DRM_R128_GETPARAM, drm_r128_getparam_t) +#define DRM_IOCTL_R128_GETPARAM DRM_IOWR( DRM_COMMAND_BASE + DRM_R128_GETPARAM, drm_r128_getparam_t) #define DRM_IOCTL_R128_FLIP DRM_IO( DRM_COMMAND_BASE + DRM_R128_FLIP) typedef struct drm_r128_init { Index: dev/drm/r128_drv.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/r128_drv.c,v retrieving revision 1.9 diff -u -r1.9 r128_drv.c --- dev/drm/r128_drv.c 16 Apr 2005 03:44:44 -0000 1.9 +++ dev/drm/r128_drv.c 23 Nov 2005 10:13:23 -0000 @@ -29,9 +29,11 @@ * Rickard E. (Rik) Faith * Gareth Hughes * - * $FreeBSD: src/sys/dev/drm/r128_drv.c,v 1.9 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" #include "dev/drm/drm.h" #include "dev/drm/r128_drm.h" @@ -43,38 +45,35 @@ r128_PCI_IDS }; -extern drm_ioctl_desc_t r128_ioctls[]; -extern int r128_max_ioctl; - static void r128_configure(drm_device_t *dev) { - dev->dev_priv_size = sizeof(drm_r128_buf_priv_t); - dev->prerelease = r128_driver_prerelease; - dev->pretakedown = r128_driver_pretakedown; - dev->vblank_wait = r128_driver_vblank_wait; - dev->irq_preinstall = r128_driver_irq_preinstall; - dev->irq_postinstall = r128_driver_irq_postinstall; - dev->irq_uninstall = r128_driver_irq_uninstall; - dev->irq_handler = r128_driver_irq_handler; - dev->dma_ioctl = r128_cce_buffers; - - dev->driver_ioctls = r128_ioctls; - dev->max_driver_ioctl = r128_max_ioctl; - - dev->driver_name = DRIVER_NAME; - dev->driver_desc = DRIVER_DESC; - dev->driver_date = DRIVER_DATE; - dev->driver_major = DRIVER_MAJOR; - dev->driver_minor = DRIVER_MINOR; - dev->driver_patchlevel = DRIVER_PATCHLEVEL; - - dev->use_agp = 1; - dev->use_mtrr = 1; - dev->use_pci_dma = 1; - dev->use_sg = 1; - dev->use_dma = 1; - dev->use_irq = 1; - dev->use_vbl_irq = 1; + dev->driver.buf_priv_size = sizeof(drm_r128_buf_priv_t); + dev->driver.preclose = r128_driver_preclose; + dev->driver.lastclose = r128_driver_lastclose; + dev->driver.vblank_wait = r128_driver_vblank_wait; + dev->driver.irq_preinstall = r128_driver_irq_preinstall; + dev->driver.irq_postinstall = r128_driver_irq_postinstall; + dev->driver.irq_uninstall = r128_driver_irq_uninstall; + dev->driver.irq_handler = r128_driver_irq_handler; + dev->driver.dma_ioctl = r128_cce_buffers; + + dev->driver.ioctls = r128_ioctls; + dev->driver.max_ioctl = r128_max_ioctl; + + dev->driver.name = DRIVER_NAME; + dev->driver.desc = DRIVER_DESC; + dev->driver.date = DRIVER_DATE; + dev->driver.major = DRIVER_MAJOR; + dev->driver.minor = DRIVER_MINOR; + dev->driver.patchlevel = DRIVER_PATCHLEVEL; + + dev->driver.use_agp = 1; + dev->driver.use_mtrr = 1; + dev->driver.use_pci_dma = 1; + dev->driver.use_sg = 1; + dev->driver.use_dma = 1; + dev->driver.use_irq = 1; + dev->driver.use_vbl_irq = 1; } #ifdef __FreeBSD__ @@ -114,5 +113,10 @@ MODULE_DEPEND(r128, drm, 1, 1, 1); #elif defined(__NetBSD__) || defined(__OpenBSD__) +#ifdef _LKM CFDRIVER_DECL(r128, DV_TTY, NULL); +#else +CFATTACH_DECL(r128, sizeof(drm_device_t), drm_probe, drm_attach, drm_detach, + drm_activate); +#endif #endif Index: dev/drm/r128_drv.h =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/r128_drv.h,v retrieving revision 1.10 diff -u -r1.10 r128_drv.h --- dev/drm/r128_drv.h 16 Apr 2005 03:44:44 -0000 1.10 +++ dev/drm/r128_drv.h 23 Nov 2005 10:13:23 -0000 @@ -1,5 +1,6 @@ /* r128_drv.h -- Private header for r128 driver -*- linux-c -*- - * Created: Mon Dec 13 09:51:11 1999 by faith@precisioninsight.com */ + * Created: Mon Dec 13 09:51:11 1999 by faith@precisioninsight.com + */ /*- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. @@ -29,10 +30,11 @@ * Kevin E. Martin * Gareth Hughes * Michel D�zer - * - * $FreeBSD: src/sys/dev/drm/r128_drv.h,v 1.10 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #ifndef __R128_DRV_H__ #define __R128_DRV_H__ @@ -89,8 +91,6 @@ int usec_timeout; int is_pci; - unsigned long phys_pci_gart; - dma_addr_t bus_pci_gart; unsigned long cce_buffers_offset; atomic_t idle_count; @@ -121,6 +121,7 @@ drm_local_map_t *cce_ring; drm_local_map_t *ring_rptr; drm_local_map_t *agp_textures; + drm_ati_pcigart_info gart_info; } drm_r128_private_t; typedef struct drm_r128_buf_priv { @@ -131,6 +132,9 @@ drm_r128_freelist_t *list_entry; } drm_r128_buf_priv_t; +extern drm_ioctl_desc_t r128_ioctls[]; +extern int r128_max_ioctl; + /* r128_cce.c */ extern int r128_cce_init(DRM_IOCTL_ARGS); extern int r128_cce_start(DRM_IOCTL_ARGS); @@ -154,8 +158,11 @@ extern void r128_driver_irq_preinstall(drm_device_t * dev); extern void r128_driver_irq_postinstall(drm_device_t * dev); extern void r128_driver_irq_uninstall(drm_device_t * dev); -extern void r128_driver_pretakedown(drm_device_t * dev); -extern void r128_driver_prerelease(drm_device_t * dev, DRMFILE filp); +extern void r128_driver_lastclose(drm_device_t * dev); +extern void r128_driver_preclose(drm_device_t * dev, DRMFILE filp); + +extern long r128_compat_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg); /* Register definitions, register access macros and drmAddMap constants * for Rage 128 kernel driver. Index: dev/drm/r128_irq.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/r128_irq.c,v retrieving revision 1.5 diff -u -r1.5 r128_irq.c --- dev/drm/r128_irq.c 16 Apr 2005 03:44:44 -0000 1.5 +++ dev/drm/r128_irq.c 23 Nov 2005 10:13:23 -0000 @@ -1,4 +1,5 @@ -/* r128_irq.c -- IRQ handling for radeon -*- linux-c -*- */ +/* r128_irq.c -- IRQ handling for radeon -*- linux-c -*- + */ /*- * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. * @@ -28,10 +29,11 @@ * Authors: * Keith Whitwell * Eric Anholt - * - * $FreeBSD: src/sys/dev/drm/r128_irq.c,v 1.5 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" #include "dev/drm/drm.h" #include "dev/drm/r128_drm.h" Index: dev/drm/r128_state.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/r128_state.c,v retrieving revision 1.12 diff -u -r1.12 r128_state.c --- dev/drm/r128_state.c 16 Apr 2005 03:44:44 -0000 1.12 +++ dev/drm/r128_state.c 23 Nov 2005 10:13:23 -0000 @@ -1,5 +1,6 @@ /* r128_state.c -- State support for r128 -*- linux-c -*- - * Created: Thu Jan 27 02:53:43 2000 by gareth@valinux.com */ + * Created: Thu Jan 27 02:53:43 2000 by gareth@valinux.com + */ /*- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * All Rights Reserved. @@ -25,10 +26,11 @@ * * Authors: * Gareth Hughes - * - * $FreeBSD: src/sys/dev/drm/r128_state.c,v 1.12 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" #include "dev/drm/drm.h" #include "dev/drm/r128_drm.h" @@ -1529,12 +1531,16 @@ switch (depth.func) { case R128_WRITE_SPAN: ret = r128_cce_dispatch_write_span(dev, &depth); + break; case R128_WRITE_PIXELS: ret = r128_cce_dispatch_write_pixels(dev, &depth); + break; case R128_READ_SPAN: ret = r128_cce_dispatch_read_span(dev, &depth); + break; case R128_READ_PIXELS: ret = r128_cce_dispatch_read_pixels(dev, &depth); + break; } COMMIT_RING(); @@ -1672,7 +1678,7 @@ return 0; } -void r128_driver_prerelease(drm_device_t * dev, DRMFILE filp) +void r128_driver_preclose(drm_device_t * dev, DRMFILE filp) { if (dev->dev_private) { drm_r128_private_t *dev_priv = dev->dev_private; @@ -1682,29 +1688,29 @@ } } -void r128_driver_pretakedown(drm_device_t * dev) +void r128_driver_lastclose(drm_device_t * dev) { r128_do_cleanup_cce(dev); } 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}, + [DRM_IOCTL_NR(DRM_R128_INIT)] = {r128_cce_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, + [DRM_IOCTL_NR(DRM_R128_CCE_START)] = {r128_cce_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, + [DRM_IOCTL_NR(DRM_R128_CCE_STOP)] = {r128_cce_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, + [DRM_IOCTL_NR(DRM_R128_CCE_RESET)] = {r128_cce_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, + [DRM_IOCTL_NR(DRM_R128_CCE_IDLE)] = {r128_cce_idle, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_R128_RESET)] = {r128_engine_reset, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_R128_FULLSCREEN)] = {r128_fullscreen, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_R128_SWAP)] = {r128_cce_swap, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_R128_FLIP)] = {r128_cce_flip, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_R128_CLEAR)] = {r128_cce_clear, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_R128_VERTEX)] = {r128_cce_vertex, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_R128_INDICES)] = {r128_cce_indices, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_R128_BLIT)] = {r128_cce_blit, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_R128_DEPTH)] = {r128_cce_depth, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_R128_STIPPLE)] = {r128_cce_stipple, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_R128_INDIRECT)] = {r128_cce_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, + [DRM_IOCTL_NR(DRM_R128_GETPARAM)] = {r128_getparam, DRM_AUTH}, }; int r128_max_ioctl = DRM_ARRAY_SIZE(r128_ioctls); Index: dev/drm/r300_cmdbuf.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/r300_cmdbuf.c,v retrieving revision 1.2 diff -u -r1.2 r300_cmdbuf.c --- dev/drm/r300_cmdbuf.c 1 Aug 2005 17:50:19 -0000 1.2 +++ dev/drm/r300_cmdbuf.c 23 Nov 2005 10:13:23 -0000 @@ -29,10 +29,11 @@ * * Authors: * Nicolai Haehnle - * - * $FreeBSD: src/sys/dev/drm/r300_cmdbuf.c,v 1.2 2005/08/01 17:50:19 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" #include "dev/drm/drm.h" #include "dev/drm/radeon_drm.h" Index: dev/drm/r300_reg.h =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/r300_reg.h,v retrieving revision 1.1 diff -u -r1.1 r300_reg.h --- dev/drm/r300_reg.h 20 Jul 2005 21:10:57 -0000 1.1 +++ dev/drm/r300_reg.h 23 Nov 2005 10:13:23 -0000 @@ -23,9 +23,8 @@ **************************************************************************/ -/* - * $FreeBSD: src/sys/dev/drm/r300_reg.h,v 1.1 2005/07/20 21:10:57 anholt Exp $ - */ +#include +__FBSDID("$FreeBSD$"); #ifndef _R300_REG_H #define _R300_REG_H Index: dev/drm/radeon_cp.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/radeon_cp.c,v retrieving revision 1.16 diff -u -r1.16 radeon_cp.c --- dev/drm/radeon_cp.c 20 Jul 2005 21:10:57 -0000 1.16 +++ dev/drm/radeon_cp.c 23 Nov 2005 10:13:23 -0000 @@ -26,10 +26,11 @@ * Authors: * Kevin E. Martin * Gareth Hughes - * - * $FreeBSD: src/sys/dev/drm/radeon_cp.c,v 1.16 2005/07/20 21:10:57 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" #include "dev/drm/drm.h" #include "dev/drm/radeon_drm.h" @@ -1138,7 +1139,7 @@ } else #endif ring_start = (dev_priv->cp_ring->offset - - dev->sg->handle + dev_priv->gart_vm_start); + - (unsigned long)dev->sg->virtual + dev_priv->gart_vm_start); RADEON_WRITE(RADEON_CP_RB_BASE, ring_start); @@ -1165,7 +1166,7 @@ drm_sg_mem_t *entry = dev->sg; unsigned long tmp_ofs, page_ofs; - tmp_ofs = dev_priv->ring_rptr->offset - dev->sg->handle; + tmp_ofs = dev_priv->ring_rptr->offset - (unsigned long)dev->sg->virtual; page_ofs = tmp_ofs >> PAGE_SHIFT; RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, entry->busaddr[page_ofs]); @@ -1208,6 +1209,10 @@ dev_priv->writeback_works = 0; DRM_DEBUG("writeback test failed\n"); } + if (radeon_no_wb == 1) { + dev_priv->writeback_works = 0; + DRM_DEBUG("writeback forced off\n"); + } dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0; RADEON_WRITE(RADEON_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame); @@ -1247,25 +1252,27 @@ u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); if (on) { - DRM_DEBUG("programming pcie %08X %08lX %08X\n", dev_priv->gart_vm_start, dev_priv->bus_pci_gart,dev_priv->gart_size); + DRM_DEBUG("programming pcie %08X %08lX %08X\n", + dev_priv->gart_vm_start, (long)dev_priv->gart_info.bus_addr, + dev_priv->gart_size); RADEON_WRITE_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_LO, dev_priv->gart_vm_start); - RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_BASE, dev_priv->bus_pci_gart); + RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_BASE, dev_priv->gart_info.bus_addr); RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_START_LO, dev_priv->gart_vm_start); RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_END_LO, dev_priv->gart_vm_start + dev_priv->gart_size - 1); RADEON_WRITE(RADEON_MC_AGP_LOCATION, 0xffffffc0); /* ?? */ - RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, RADEON_PCIE_TX_GART_EN | RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD | RADEON_PCIE_TX_GART_CHK_RW_VALID_EN); + RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, RADEON_PCIE_TX_GART_EN); } else { - RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN); + RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, (tmp & ~RADEON_PCIE_TX_GART_EN) | RADEON_PCIE_TX_GART_INVALIDATE_TLB); } } /* Enable or disable PCI GART on the chip */ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) { - u32 tmp = RADEON_READ(RADEON_AIC_CNTL); + u32 tmp; if (dev_priv->flags & CHIP_IS_PCIE) { @@ -1273,13 +1280,15 @@ return; } + tmp = RADEON_READ(RADEON_AIC_CNTL); + if (on) { RADEON_WRITE(RADEON_AIC_CNTL, tmp | RADEON_PCIGART_TRANSLATE_EN); /* set PCI GART page-table base address */ - RADEON_WRITE(RADEON_AIC_PT_BASE, dev_priv->bus_pci_gart); + RADEON_WRITE(RADEON_AIC_PT_BASE, dev_priv->gart_info.bus_addr); /* set address range for PCI address translate */ @@ -1302,6 +1311,12 @@ drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG("\n"); + if (init->is_pci && (dev_priv->flags & CHIP_IS_AGP)) + { + DRM_DEBUG("Forcing AGP card to PCI mode\n"); + dev_priv->flags &= ~CHIP_IS_AGP; + } + if ((!(dev_priv->flags & CHIP_IS_AGP)) && !dev->sg) { DRM_ERROR("PCI GART memory not allocated!\n"); radeon_do_cleanup_cp(dev); @@ -1400,8 +1415,6 @@ DRM_GETSAREA(); - dev_priv->fb_offset = init->fb_offset; - dev_priv->mmio_offset = init->mmio_offset; dev_priv->ring_offset = init->ring_offset; dev_priv->ring_rptr_offset = init->ring_rptr_offset; dev_priv->buffers_offset = init->buffers_offset; @@ -1413,12 +1426,6 @@ return DRM_ERR(EINVAL); } - dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset); - if (!dev_priv->mmio) { - DRM_ERROR("could not find mmio region!\n"); - radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); - } dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset); if (!dev_priv->cp_ring) { DRM_ERROR("could not find cp ring region!\n"); @@ -1431,6 +1438,7 @@ radeon_do_cleanup_cp(dev); return DRM_ERR(EINVAL); } + dev->agp_buffer_token = init->buffers_offset; dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); if (!dev->agp_buffer_map) { DRM_ERROR("could not find dma buffer region!\n"); @@ -1508,7 +1516,7 @@ else #endif dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset - - dev->sg->handle + - (unsigned long)dev->sg->virtual + dev_priv->gart_vm_start); DRM_DEBUG("dev_priv->gart_size %d\n", dev_priv->gart_size); @@ -1533,8 +1541,32 @@ } else #endif { - if (!drm_ati_pcigart_init(dev, &dev_priv->phys_pci_gart, - &dev_priv->bus_pci_gart, (dev_priv->flags & CHIP_IS_PCIE))) { + /* if we have an offset set from userspace */ + if (dev_priv->pcigart_offset) { + dev_priv->gart_info.bus_addr = dev_priv->pcigart_offset + dev_priv->fb_location; + dev_priv->gart_info.mapping.offset = dev_priv->gart_info.bus_addr; + dev_priv->gart_info.mapping.size = RADEON_PCIGART_TABLE_SIZE; + drm_core_ioremap(&dev_priv->gart_info.mapping, dev); + dev_priv->gart_info.addr = dev_priv->gart_info.mapping.handle; + + dev_priv->gart_info.is_pcie = !!(dev_priv->flags & CHIP_IS_PCIE); + dev_priv->gart_info.gart_table_location = DRM_ATI_GART_FB; + + DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n", dev_priv->gart_info.addr, dev_priv->pcigart_offset); + } + else { + dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; + dev_priv->gart_info.addr = NULL; + dev_priv->gart_info.bus_addr = 0; + if (dev_priv->flags & CHIP_IS_PCIE) + { + DRM_ERROR("Cannot use PCI Express without GART in FB memory\n"); + radeon_do_cleanup_cp(dev); + return DRM_ERR(EINVAL); + } + } + + if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { DRM_ERROR("failed to init PCI GART!\n"); radeon_do_cleanup_cp(dev); return DRM_ERR(ENOMEM); @@ -1583,10 +1615,19 @@ } else #endif { - if (!drm_ati_pcigart_cleanup(dev, - dev_priv->phys_pci_gart, - dev_priv->bus_pci_gart)) - DRM_ERROR("failed to cleanup PCI GART!\n"); + + if (dev_priv->gart_info.bus_addr) { + /* Turn off PCI GART */ + radeon_set_pcigart(dev_priv, 0); + if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info)) + DRM_ERROR("failed to cleanup PCI GART!\n"); + } + + if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) + { + drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); + dev_priv->gart_info.addr = 0; + } } /* only clear to the start of flags */ memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags)); @@ -1742,8 +1783,13 @@ #ifdef __linux__ schedule(); #else +#if defined(__FreeBSD__) && __FreeBSD_version > 500000 + msleep(&ret, &dev->dev_lock, PZERO, "rdnrel", + 1); +#else tsleep(&ret, PZERO, "rdnrel", 1); #endif +#endif } radeon_do_cp_stop(dev_priv); radeon_do_engine_reset(dev); @@ -2043,8 +2089,7 @@ return ret; } -/* Always create a map record for MMIO and FB memory, done from DRIVER_POSTINIT */ -int radeon_preinit(struct drm_device *dev, unsigned long flags) +int radeon_driver_load(struct drm_device *dev, unsigned long flags) { drm_radeon_private_t *dev_priv; int ret = 0; @@ -2070,28 +2115,6 @@ break; } - /* Disable initmaps because it is broken on FreeBSD, and results in - * crashes on startup for some. The proper fix will involve being - * smarter about allocating PCI resources. - */ - /* - ret = drm_initmap(dev, drm_get_resource_start(dev, 2), - drm_get_resource_len(dev, 2), 2, _DRM_REGISTERS, - _DRM_READ_ONLY); - if (ret != 0) - return ret; - - ret = drm_initmap(dev, drm_get_resource_start(dev, 0), - drm_get_resource_len(dev, 0), 0, _DRM_FRAME_BUFFER, - _DRM_WRITE_COMBINING); - if (ret != 0) - return ret; - */ - - /* The original method of detecting AGP is known to not work correctly, - * according to Mike Harris. The solution is to walk the capabilities - * list, which should be done in drm_device_is_agp(). - */ if (drm_device_is_agp(dev)) dev_priv->flags |= CHIP_IS_AGP; @@ -2101,26 +2124,38 @@ DRM_DEBUG("%s card detected\n", ((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : (((dev_priv->flags & CHIP_IS_PCIE) ? "PCIE" : "PCI")))); -#if defined(__linux__) - /* Check if we need a reset */ - if (! - (dev_priv->mmio = - drm_core_findmap(dev, pci_resource_start(dev->pdev, 2)))) - return DRM_ERR(ENOMEM); - - ret = radeon_create_i2c_busses(dev); -#endif return ret; } -int radeon_postcleanup(struct drm_device *dev) +/* Create mappings for registers and framebuffer so userland doesn't necessarily + * have to find them. + */ +int radeon_driver_firstopen(struct drm_device *dev) +{ + int ret; + drm_local_map_t *map; + drm_radeon_private_t *dev_priv = dev->dev_private; + + ret = drm_addmap(dev, drm_get_resource_start(dev, 2), + drm_get_resource_len(dev, 2), _DRM_REGISTERS, + _DRM_READ_ONLY, &dev_priv->mmio); + if (ret != 0) + return ret; + + ret = drm_addmap(dev, drm_get_resource_start(dev, 0), + drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER, + _DRM_WRITE_COMBINING, &map); + if (ret != 0) + return ret; + + return 0; +} + +int radeon_driver_unload(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG("\n"); -#if defined(__linux__) - radeon_delete_i2c_busses(dev); -#endif drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); dev->dev_private = NULL; Index: dev/drm/radeon_drm.h =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/radeon_drm.h,v retrieving revision 1.11 diff -u -r1.11 radeon_drm.h --- dev/drm/radeon_drm.h 20 Jul 2005 21:10:57 -0000 1.11 +++ dev/drm/radeon_drm.h 23 Nov 2005 10:13:23 -0000 @@ -1,5 +1,5 @@ -/* radeon_drm.h -- Public header for the radeon driver -*- linux-c -*- */ -/*- +/* radeon_drm.h -- Public header for the radeon driver -*- linux-c -*- + * * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Fremont, California. * Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas. @@ -28,10 +28,11 @@ * Kevin E. Martin * Gareth Hughes * Keith Whitwell - * - * $FreeBSD: src/sys/dev/drm/radeon_drm.h,v 1.11 2005/07/20 21:10:57 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #ifndef __RADEON_DRM_H__ #define __RADEON_DRM_H__ @@ -154,7 +155,16 @@ #define RADEON_EMIT_PP_CUBIC_FACES_2 82 #define RADEON_EMIT_PP_CUBIC_OFFSETS_T2 83 #define R200_EMIT_PP_TRI_PERF_CNTL 84 -#define RADEON_MAX_STATE_PACKETS 85 +#define R200_EMIT_PP_AFS_0 85 +#define R200_EMIT_PP_AFS_1 86 +#define R200_EMIT_ATF_TFACTOR 87 +#define R200_EMIT_PP_TXCTLALL_0 88 +#define R200_EMIT_PP_TXCTLALL_1 89 +#define R200_EMIT_PP_TXCTLALL_2 90 +#define R200_EMIT_PP_TXCTLALL_3 91 +#define R200_EMIT_PP_TXCTLALL_4 92 +#define R200_EMIT_PP_TXCTLALL_5 93 +#define RADEON_MAX_STATE_PACKETS 94 /* Commands understood by cmd_buffer ioctl. More can be added but * obviously these can't be removed or changed: @@ -494,7 +504,7 @@ RADEON_INIT_R300_CP = 0x04 } func; unsigned long sarea_priv_offset; - int is_pci; /* not used, driver asks hardware */ + int is_pci; /* for overriding only */ int cp_mode; int gart_size; int ring_size; @@ -506,8 +516,8 @@ unsigned int depth_bpp; unsigned int depth_offset, depth_pitch; - unsigned long fb_offset; - unsigned long mmio_offset; + unsigned long fb_offset DEPRECATED; /* deprecated, driver asks hardware */ + unsigned long mmio_offset DEPRECATED; /* deprecated, driver asks hardware */ unsigned long ring_offset; unsigned long ring_rptr_offset; unsigned long buffers_offset; @@ -683,6 +693,7 @@ #define RADEON_SETPARAM_FB_LOCATION 1 /* determined framebuffer location */ #define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */ +#define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */ /* 1.14: Clients can allocate/free a surface */ Index: dev/drm/radeon_drv.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/radeon_drv.c,v retrieving revision 1.12 diff -u -r1.12 radeon_drv.c --- dev/drm/radeon_drv.c 16 Apr 2005 03:44:44 -0000 1.12 +++ dev/drm/radeon_drv.c 23 Nov 2005 10:13:23 -0000 @@ -27,56 +27,58 @@ * Authors: * Gareth Hughes * - * $FreeBSD: src/sys/dev/drm/radeon_drv.c,v 1.12 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" #include "dev/drm/drm.h" #include "dev/drm/radeon_drm.h" #include "dev/drm/radeon_drv.h" #include "dev/drm/drm_pciids.h" +int radeon_no_wb; + /* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */ static drm_pci_id_list_t radeon_pciidlist[] = { radeon_PCI_IDS }; -extern drm_ioctl_desc_t radeon_ioctls[]; -extern int radeon_max_ioctl; - static void radeon_configure(drm_device_t *dev) { - dev->dev_priv_size = sizeof(drm_radeon_buf_priv_t); - dev->preinit = radeon_preinit; - dev->postcleanup = radeon_postcleanup; - dev->prerelease = radeon_driver_prerelease; - dev->pretakedown = radeon_driver_pretakedown; - dev->open_helper = radeon_driver_open_helper; - dev->free_filp_priv = radeon_driver_free_filp_priv; - dev->vblank_wait = radeon_driver_vblank_wait; - dev->irq_preinstall = radeon_driver_irq_preinstall; - dev->irq_postinstall = radeon_driver_irq_postinstall; - dev->irq_uninstall = radeon_driver_irq_uninstall; - dev->irq_handler = radeon_driver_irq_handler; - dev->dma_ioctl = radeon_cp_buffers; - - dev->driver_ioctls = radeon_ioctls; - dev->max_driver_ioctl = radeon_max_ioctl; - - dev->driver_name = DRIVER_NAME; - dev->driver_desc = DRIVER_DESC; - dev->driver_date = DRIVER_DATE; - dev->driver_major = DRIVER_MAJOR; - dev->driver_minor = DRIVER_MINOR; - dev->driver_patchlevel = DRIVER_PATCHLEVEL; - - dev->use_agp = 1; - dev->use_mtrr = 1; - dev->use_pci_dma = 1; - dev->use_sg = 1; - dev->use_dma = 1; - dev->use_irq = 1; - dev->use_vbl_irq = 1; + dev->driver.buf_priv_size = sizeof(drm_radeon_buf_priv_t); + dev->driver.load = radeon_driver_load; + dev->driver.unload = radeon_driver_unload; + dev->driver.firstopen = radeon_driver_firstopen; + dev->driver.open = radeon_driver_open; + dev->driver.preclose = radeon_driver_preclose; + dev->driver.postclose = radeon_driver_postclose; + dev->driver.lastclose = radeon_driver_lastclose; + dev->driver.vblank_wait = radeon_driver_vblank_wait; + dev->driver.irq_preinstall = radeon_driver_irq_preinstall; + dev->driver.irq_postinstall = radeon_driver_irq_postinstall; + dev->driver.irq_uninstall = radeon_driver_irq_uninstall; + dev->driver.irq_handler = radeon_driver_irq_handler; + dev->driver.dma_ioctl = radeon_cp_buffers; + + dev->driver.ioctls = radeon_ioctls; + dev->driver.max_ioctl = radeon_max_ioctl; + + dev->driver.name = DRIVER_NAME; + dev->driver.desc = DRIVER_DESC; + dev->driver.date = DRIVER_DATE; + dev->driver.major = DRIVER_MAJOR; + dev->driver.minor = DRIVER_MINOR; + dev->driver.patchlevel = DRIVER_PATCHLEVEL; + + dev->driver.use_agp = 1; + dev->driver.use_mtrr = 1; + dev->driver.use_pci_dma = 1; + dev->driver.use_sg = 1; + dev->driver.use_dma = 1; + dev->driver.use_irq = 1; + dev->driver.use_vbl_irq = 1; } #ifdef __FreeBSD__ @@ -116,5 +118,10 @@ MODULE_DEPEND(radeon, drm, 1, 1, 1); #elif defined(__NetBSD__) || defined(__OpenBSD__) +#ifdef _LKM CFDRIVER_DECL(radeon, DV_TTY, NULL); +#else +CFATTACH_DECL(radeon, sizeof(drm_device_t), drm_probe, drm_attach, drm_detach, + drm_activate); +#endif #endif /* __FreeBSD__ */ Index: dev/drm/radeon_drv.h =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/radeon_drv.h,v retrieving revision 1.13 diff -u -r1.13 radeon_drv.h --- dev/drm/radeon_drv.h 20 Jul 2005 21:10:57 -0000 1.13 +++ dev/drm/radeon_drv.h 23 Nov 2005 10:13:23 -0000 @@ -1,5 +1,5 @@ -/* radeon_drv.h -- Private header for radeon driver -*- linux-c -*- */ -/*- +/* radeon_drv.h -- Private header for radeon driver -*- linux-c -*- + * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Fremont, California. * All rights reserved. @@ -26,17 +26,14 @@ * Authors: * Kevin E. Martin * Gareth Hughes - * - * $FreeBSD: src/sys/dev/drm/radeon_drv.h,v 1.13 2005/07/20 21:10:57 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #ifndef __RADEON_DRV_H__ #define __RADEON_DRV_H__ -#ifdef __linux__ -#include "radeon_i2c.h" -#endif /* __linux__ */ - /* General customization: */ @@ -44,7 +41,7 @@ #define DRIVER_NAME "radeon" #define DRIVER_DESC "ATI Radeon" -#define DRIVER_DATE "20050311" +#define DRIVER_DATE "20050911" /* Interface history: * @@ -88,18 +85,23 @@ * - Add support for r100 cube maps * 1.16- Add R200_EMIT_PP_TRI_PERF_CNTL packet to support brilinear * texture filtering on r200 + * 1.17- Add initial support for R300 (3D). + * 1.18- Add support for GL_ATI_fragment_shader, new packets R200_EMIT_PP_AFS_0/1, + R200_EMIT_PP_TXCTLALL_0-5 (replaces R200_EMIT_PP_TXFILTER_0-5, 2 more regs) + and R200_EMIT_ATF_TFACTOR (replaces R200_EMIT_TFACTOR_0 (8 consts instead of 6) + * 1.19- Add support for gart table in FB memory and PCIE r300 */ #define DRIVER_MAJOR 1 -#define DRIVER_MINOR 16 +#define DRIVER_MINOR 19 #define DRIVER_PATCHLEVEL 0 enum radeon_family { CHIP_R100, CHIP_RS100, CHIP_RV100, - CHIP_R200, CHIP_RV200, + CHIP_R200, CHIP_RS200, CHIP_R250, CHIP_RS250, @@ -213,9 +215,6 @@ int microcode_version; - unsigned long phys_pci_gart; - dma_addr_t bus_pci_gart; - struct { u32 boxes; int freelist_timeouts; @@ -247,8 +246,6 @@ drm_radeon_depth_clear_t depth_clear; - unsigned long fb_offset; - unsigned long mmio_offset; unsigned long ring_offset; unsigned long ring_rptr_offset; unsigned long buffers_offset; @@ -269,19 +266,22 @@ struct radeon_surface surfaces[RADEON_MAX_SURFACES]; struct radeon_virt_surface virt_surfaces[2*RADEON_MAX_SURFACES]; - + + unsigned long pcigart_offset; + drm_ati_pcigart_info gart_info; /* starting from here on, data is preserved accross an open */ uint32_t flags; /* see radeon_chip_flags */ -#ifdef __linux__ - struct radeon_i2c_chan i2c[4]; -#endif /* __linux__ */ } drm_radeon_private_t; typedef struct drm_radeon_buf_priv { u32 age; } drm_radeon_buf_priv_t; +extern int radeon_no_wb; +extern drm_ioctl_desc_t radeon_ioctls[]; +extern int radeon_max_ioctl; + /* radeon_cp.c */ extern int radeon_cp_init(DRM_IOCTL_ARGS); extern int radeon_cp_start(DRM_IOCTL_ARGS); @@ -317,12 +317,16 @@ extern void radeon_driver_irq_preinstall(drm_device_t * dev); extern void radeon_driver_irq_postinstall(drm_device_t * dev); extern void radeon_driver_irq_uninstall(drm_device_t * dev); -extern void radeon_driver_prerelease(drm_device_t * dev, DRMFILE filp); -extern void radeon_driver_pretakedown(drm_device_t * dev); -extern int radeon_driver_open_helper(drm_device_t * dev, - drm_file_t * filp_priv); -extern void radeon_driver_free_filp_priv(drm_device_t * dev, - drm_file_t * filp_priv); + +extern int radeon_driver_load(struct drm_device *dev, unsigned long flags); +extern int radeon_driver_unload(struct drm_device *dev); +extern int radeon_driver_firstopen(struct drm_device *dev); +extern void radeon_driver_preclose(drm_device_t * dev, DRMFILE filp); +extern void radeon_driver_postclose(drm_device_t * dev, drm_file_t * filp); +extern void radeon_driver_lastclose(drm_device_t * dev); +extern int radeon_driver_open(drm_device_t * dev, drm_file_t * filp_priv); +extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg); /* r300_cmdbuf.c */ extern void r300_init_reg_flags(void); @@ -876,6 +880,39 @@ #define R200_PP_TRI_PERF 0x2cf8 +#define R200_PP_AFS_0 0x2f80 +#define R200_PP_AFS_1 0x2f00 /* same as txcblend_0 */ + +/* MPEG settings from VHA code */ +#define RADEON_VHA_SETTO16_1 0x2694 +#define RADEON_VHA_SETTO16_2 0x2680 +#define RADEON_VHA_SETTO0_1 0x1840 +#define RADEON_VHA_FB_OFFSET 0x19e4 +#define RADEON_VHA_SETTO1AND70S 0x19d8 +#define RADEON_VHA_DST_PITCH 0x1408 + +// set as reference header +#define RADEON_VHA_BACKFRAME0_OFF_Y 0x1840 +#define RADEON_VHA_BACKFRAME1_OFF_PITCH_Y 0x1844 +#define RADEON_VHA_BACKFRAME0_OFF_U 0x1848 +#define RADEON_VHA_BACKFRAME1_OFF_PITCH_U 0x184c +#define RADOEN_VHA_BACKFRAME0_OFF_V 0x1850 +#define RADEON_VHA_BACKFRAME1_OFF_PITCH_V 0x1854 +#define RADEON_VHA_FORWFRAME0_OFF_Y 0x1858 +#define RADEON_VHA_FORWFRAME1_OFF_PITCH_Y 0x185c +#define RADEON_VHA_FORWFRAME0_OFF_U 0x1860 +#define RADEON_VHA_FORWFRAME1_OFF_PITCH_U 0x1864 +#define RADEON_VHA_FORWFRAME0_OFF_V 0x1868 +#define RADEON_VHA_FORWFRAME0_OFF_PITCH_V 0x1880 +#define RADEON_VHA_BACKFRAME0_OFF_Y_2 0x1884 +#define RADEON_VHA_BACKFRAME1_OFF_PITCH_Y_2 0x1888 +#define RADEON_VHA_BACKFRAME0_OFF_U_2 0x188c +#define RADEON_VHA_BACKFRAME1_OFF_PITCH_U_2 0x1890 +#define RADEON_VHA_BACKFRAME0_OFF_V_2 0x1894 +#define RADEON_VHA_BACKFRAME1_OFF_PITCH_V_2 0x1898 + + + /* Constants */ #define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */ @@ -890,6 +927,8 @@ #define RADEON_RING_HIGH_MARK 128 +#define RADEON_PCIGART_TABLE_SIZE (32*1024) + #define RADEON_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) #define RADEON_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) ) #define RADEON_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) ) @@ -909,9 +948,6 @@ RADEON_WRITE( RADEON_PCIE_DATA, (val) ); \ } while (0) -extern int radeon_preinit(struct drm_device *dev, unsigned long flags); -extern int radeon_postcleanup(struct drm_device *dev); - #define CP_PACKET0( reg, n ) \ (RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2)) #define CP_PACKET0_TABLE( reg, n ) \ Index: dev/drm/radeon_irq.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/radeon_irq.c,v retrieving revision 1.6 diff -u -r1.6 radeon_irq.c --- dev/drm/radeon_irq.c 16 Apr 2005 03:44:44 -0000 1.6 +++ dev/drm/radeon_irq.c 23 Nov 2005 10:13:23 -0000 @@ -28,15 +28,25 @@ * Authors: * Keith Whitwell * Michel D�zer - * - * $FreeBSD: src/sys/dev/drm/radeon_irq.c,v 1.6 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" #include "dev/drm/drm.h" #include "dev/drm/radeon_drm.h" #include "dev/drm/radeon_drv.h" +static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv, + u32 mask) +{ + u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask; + if (irqs) + RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs); + return irqs; +} + /* Interrupts - Used for device synchronization and flushing in the * following circumstances: * @@ -65,8 +75,8 @@ /* Only consider the bits we're interested in - others could be used * outside the DRM */ - stat = RADEON_READ(RADEON_GEN_INT_STATUS) - & (RADEON_SW_INT_TEST | RADEON_CRTC_VBLANK_STAT); + stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | + RADEON_CRTC_VBLANK_STAT)); if (!stat) return IRQ_NONE; @@ -82,19 +92,9 @@ drm_vbl_send_signals(dev); } - /* Acknowledge interrupts we handle */ - RADEON_WRITE(RADEON_GEN_INT_STATUS, stat); return IRQ_HANDLED; } -static __inline__ void radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv) -{ - u32 tmp = RADEON_READ(RADEON_GEN_INT_STATUS) - & (RADEON_SW_INT_TEST_ACK | RADEON_CRTC_VBLANK_STAT); - if (tmp) - RADEON_WRITE(RADEON_GEN_INT_STATUS, tmp); -} - static int radeon_emit_irq(drm_device_t * dev) { drm_radeon_private_t *dev_priv = dev->dev_private; @@ -124,11 +124,6 @@ dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - /* This is a hack to work around mysterious freezes on certain - * systems: - */ - radeon_acknowledge_irqs(dev_priv); - DRM_WAIT_ON(ret, dev_priv->swi_queue, 3 * DRM_HZ, RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr); @@ -147,7 +142,7 @@ return DRM_ERR(EINVAL); } - radeon_acknowledge_irqs(dev_priv); + radeon_acknowledge_irqs(dev_priv, RADEON_CRTC_VBLANK_STAT); dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; @@ -223,7 +218,8 @@ RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); /* Clear bits if they're already high */ - radeon_acknowledge_irqs(dev_priv); + radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | + RADEON_CRTC_VBLANK_STAT)); } void radeon_driver_irq_postinstall(drm_device_t * dev) Index: dev/drm/radeon_mem.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/radeon_mem.c,v retrieving revision 1.7 diff -u -r1.7 radeon_mem.c --- dev/drm/radeon_mem.c 16 Apr 2005 03:44:44 -0000 1.7 +++ dev/drm/radeon_mem.c 23 Nov 2005 10:13:23 -0000 @@ -27,10 +27,11 @@ * * Authors: * Keith Whitwell - * - * $FreeBSD: src/sys/dev/drm/radeon_mem.c,v 1.7 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" #include "dev/drm/drm.h" #include "dev/drm/radeon_drm.h" Index: dev/drm/radeon_state.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/radeon_state.c,v retrieving revision 1.16 diff -u -r1.16 radeon_state.c --- dev/drm/radeon_state.c 20 Jul 2005 21:10:57 -0000 1.16 +++ dev/drm/radeon_state.c 23 Nov 2005 10:13:23 -0000 @@ -25,10 +25,11 @@ * Authors: * Gareth Hughes * Kevin E. Martin - * - * $FreeBSD: src/sys/dev/drm/radeon_state.c,v 1.16 2005/07/20 21:10:57 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" #include "dev/drm/drm.h" #include "dev/drm/drm_sarea.h" @@ -212,6 +213,15 @@ case RADEON_EMIT_PP_CUBIC_FACES_1: case RADEON_EMIT_PP_CUBIC_FACES_2: case R200_EMIT_PP_TRI_PERF_CNTL: + case R200_EMIT_PP_AFS_0: + case R200_EMIT_PP_AFS_1: + case R200_EMIT_ATF_TFACTOR: + case R200_EMIT_PP_TXCTLALL_0: + case R200_EMIT_PP_TXCTLALL_1: + case R200_EMIT_PP_TXCTLALL_2: + case R200_EMIT_PP_TXCTLALL_3: + case R200_EMIT_PP_TXCTLALL_4: + case R200_EMIT_PP_TXCTLALL_5: /* These packets don't contain memory offsets */ break; @@ -492,100 +502,103 @@ int len; const char *name; } packet[RADEON_MAX_STATE_PACKETS] = { - { - RADEON_PP_MISC, 7, "RADEON_PP_MISC"}, { - RADEON_PP_CNTL, 3, "RADEON_PP_CNTL"}, { - RADEON_RB3D_COLORPITCH, 1, "RADEON_RB3D_COLORPITCH"}, { - RADEON_RE_LINE_PATTERN, 2, "RADEON_RE_LINE_PATTERN"}, { - RADEON_SE_LINE_WIDTH, 1, "RADEON_SE_LINE_WIDTH"}, { - RADEON_PP_LUM_MATRIX, 1, "RADEON_PP_LUM_MATRIX"}, { - RADEON_PP_ROT_MATRIX_0, 2, "RADEON_PP_ROT_MATRIX_0"}, { - RADEON_RB3D_STENCILREFMASK, 3, "RADEON_RB3D_STENCILREFMASK"}, { - RADEON_SE_VPORT_XSCALE, 6, "RADEON_SE_VPORT_XSCALE"}, { - RADEON_SE_CNTL, 2, "RADEON_SE_CNTL"}, { - RADEON_SE_CNTL_STATUS, 1, "RADEON_SE_CNTL_STATUS"}, { - RADEON_RE_MISC, 1, "RADEON_RE_MISC"}, { - RADEON_PP_TXFILTER_0, 6, "RADEON_PP_TXFILTER_0"}, { - RADEON_PP_BORDER_COLOR_0, 1, "RADEON_PP_BORDER_COLOR_0"}, { - RADEON_PP_TXFILTER_1, 6, "RADEON_PP_TXFILTER_1"}, { - RADEON_PP_BORDER_COLOR_1, 1, "RADEON_PP_BORDER_COLOR_1"}, { - RADEON_PP_TXFILTER_2, 6, "RADEON_PP_TXFILTER_2"}, { - RADEON_PP_BORDER_COLOR_2, 1, "RADEON_PP_BORDER_COLOR_2"}, { - RADEON_SE_ZBIAS_FACTOR, 2, "RADEON_SE_ZBIAS_FACTOR"}, { - RADEON_SE_TCL_OUTPUT_VTX_FMT, 11, "RADEON_SE_TCL_OUTPUT_VTX_FMT"}, { - RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED, 17, - "RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED"}, { - R200_PP_TXCBLEND_0, 4, "R200_PP_TXCBLEND_0"}, { - R200_PP_TXCBLEND_1, 4, "R200_PP_TXCBLEND_1"}, { - R200_PP_TXCBLEND_2, 4, "R200_PP_TXCBLEND_2"}, { - R200_PP_TXCBLEND_3, 4, "R200_PP_TXCBLEND_3"}, { - R200_PP_TXCBLEND_4, 4, "R200_PP_TXCBLEND_4"}, { - R200_PP_TXCBLEND_5, 4, "R200_PP_TXCBLEND_5"}, { - R200_PP_TXCBLEND_6, 4, "R200_PP_TXCBLEND_6"}, { - R200_PP_TXCBLEND_7, 4, "R200_PP_TXCBLEND_7"}, { - R200_SE_TCL_LIGHT_MODEL_CTL_0, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0"}, - { - R200_PP_TFACTOR_0, 6, "R200_PP_TFACTOR_0"}, { - R200_SE_VTX_FMT_0, 4, "R200_SE_VTX_FMT_0"}, { - R200_SE_VAP_CNTL, 1, "R200_SE_VAP_CNTL"}, { - R200_SE_TCL_MATRIX_SEL_0, 5, "R200_SE_TCL_MATRIX_SEL_0"}, { - R200_SE_TCL_TEX_PROC_CTL_2, 5, "R200_SE_TCL_TEX_PROC_CTL_2"}, { - R200_SE_TCL_UCP_VERT_BLEND_CTL, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL"}, - { - R200_PP_TXFILTER_0, 6, "R200_PP_TXFILTER_0"}, { - R200_PP_TXFILTER_1, 6, "R200_PP_TXFILTER_1"}, { - R200_PP_TXFILTER_2, 6, "R200_PP_TXFILTER_2"}, { - R200_PP_TXFILTER_3, 6, "R200_PP_TXFILTER_3"}, { - R200_PP_TXFILTER_4, 6, "R200_PP_TXFILTER_4"}, { - R200_PP_TXFILTER_5, 6, "R200_PP_TXFILTER_5"}, { - R200_PP_TXOFFSET_0, 1, "R200_PP_TXOFFSET_0"}, { - R200_PP_TXOFFSET_1, 1, "R200_PP_TXOFFSET_1"}, { - R200_PP_TXOFFSET_2, 1, "R200_PP_TXOFFSET_2"}, { - R200_PP_TXOFFSET_3, 1, "R200_PP_TXOFFSET_3"}, { - R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4"}, { - R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5"}, { - R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL"}, { - R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1, "R200_SE_TCL_OUTPUT_VTX_COMP_SEL"}, - { - R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3"}, { - R200_PP_CNTL_X, 1, "R200_PP_CNTL_X"}, { - R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET"}, { - R200_RE_AUX_SCISSOR_CNTL, 1, "R200_RE_AUX_SCISSOR_CNTL"}, { - R200_RE_SCISSOR_TL_0, 2, "R200_RE_SCISSOR_TL_0"}, { - R200_RE_SCISSOR_TL_1, 2, "R200_RE_SCISSOR_TL_1"}, { - R200_RE_SCISSOR_TL_2, 2, "R200_RE_SCISSOR_TL_2"}, { - R200_SE_VAP_CNTL_STATUS, 1, "R200_SE_VAP_CNTL_STATUS"}, { - R200_SE_VTX_STATE_CNTL, 1, "R200_SE_VTX_STATE_CNTL"}, { - R200_RE_POINTSIZE, 1, "R200_RE_POINTSIZE"}, { - R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4, - "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0"}, { - R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0"}, /* 61 */ - { - R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0"}, /* 62 */ - { - R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1"}, { - R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1"}, { - R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2"}, { - R200_PP_CUBIC_OFFSET_F1_2, 5, "R200_PP_CUBIC_OFFSET_F1_2"}, { - R200_PP_CUBIC_FACES_3, 1, "R200_PP_CUBIC_FACES_3"}, { - R200_PP_CUBIC_OFFSET_F1_3, 5, "R200_PP_CUBIC_OFFSET_F1_3"}, { - R200_PP_CUBIC_FACES_4, 1, "R200_PP_CUBIC_FACES_4"}, { - R200_PP_CUBIC_OFFSET_F1_4, 5, "R200_PP_CUBIC_OFFSET_F1_4"}, { - R200_PP_CUBIC_FACES_5, 1, "R200_PP_CUBIC_FACES_5"}, { - R200_PP_CUBIC_OFFSET_F1_5, 5, "R200_PP_CUBIC_OFFSET_F1_5"}, { - RADEON_PP_TEX_SIZE_0, 2, "RADEON_PP_TEX_SIZE_0"}, { - RADEON_PP_TEX_SIZE_1, 2, "RADEON_PP_TEX_SIZE_1"}, { - RADEON_PP_TEX_SIZE_2, 2, "RADEON_PP_TEX_SIZE_2"}, { - R200_RB3D_BLENDCOLOR, 3, "R200_RB3D_BLENDCOLOR"}, { - R200_SE_TCL_POINT_SPRITE_CNTL, 1, "R200_SE_TCL_POINT_SPRITE_CNTL"}, - { - RADEON_PP_CUBIC_FACES_0, 1, "RADEON_PP_CUBIC_FACES_0"}, { - RADEON_PP_CUBIC_OFFSET_T0_0, 5, "RADEON_PP_CUBIC_OFFSET_T0_0"}, { - RADEON_PP_CUBIC_FACES_1, 1, "RADEON_PP_CUBIC_FACES_1"}, { - RADEON_PP_CUBIC_OFFSET_T1_0, 5, "RADEON_PP_CUBIC_OFFSET_T1_0"}, { - RADEON_PP_CUBIC_FACES_2, 1, "RADEON_PP_CUBIC_FACES_2"}, { - RADEON_PP_CUBIC_OFFSET_T2_0, 5, "RADEON_PP_CUBIC_OFFSET_T2_0"}, { - R200_PP_TRI_PERF, 2, "R200_PP_TRI_PERF"}, + {RADEON_PP_MISC, 7, "RADEON_PP_MISC"}, + {RADEON_PP_CNTL, 3, "RADEON_PP_CNTL"}, + {RADEON_RB3D_COLORPITCH, 1, "RADEON_RB3D_COLORPITCH"}, + {RADEON_RE_LINE_PATTERN, 2, "RADEON_RE_LINE_PATTERN"}, + {RADEON_SE_LINE_WIDTH, 1, "RADEON_SE_LINE_WIDTH"}, + {RADEON_PP_LUM_MATRIX, 1, "RADEON_PP_LUM_MATRIX"}, + {RADEON_PP_ROT_MATRIX_0, 2, "RADEON_PP_ROT_MATRIX_0"}, + {RADEON_RB3D_STENCILREFMASK, 3, "RADEON_RB3D_STENCILREFMASK"}, + {RADEON_SE_VPORT_XSCALE, 6, "RADEON_SE_VPORT_XSCALE"}, + {RADEON_SE_CNTL, 2, "RADEON_SE_CNTL"}, + {RADEON_SE_CNTL_STATUS, 1, "RADEON_SE_CNTL_STATUS"}, + {RADEON_RE_MISC, 1, "RADEON_RE_MISC"}, + {RADEON_PP_TXFILTER_0, 6, "RADEON_PP_TXFILTER_0"}, + {RADEON_PP_BORDER_COLOR_0, 1, "RADEON_PP_BORDER_COLOR_0"}, + {RADEON_PP_TXFILTER_1, 6, "RADEON_PP_TXFILTER_1"}, + {RADEON_PP_BORDER_COLOR_1, 1, "RADEON_PP_BORDER_COLOR_1"}, + {RADEON_PP_TXFILTER_2, 6, "RADEON_PP_TXFILTER_2"}, + {RADEON_PP_BORDER_COLOR_2, 1, "RADEON_PP_BORDER_COLOR_2"}, + {RADEON_SE_ZBIAS_FACTOR, 2, "RADEON_SE_ZBIAS_FACTOR"}, + {RADEON_SE_TCL_OUTPUT_VTX_FMT, 11, "RADEON_SE_TCL_OUTPUT_VTX_FMT"}, + {RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED, 17, + "RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED"}, + {R200_PP_TXCBLEND_0, 4, "R200_PP_TXCBLEND_0"}, + {R200_PP_TXCBLEND_1, 4, "R200_PP_TXCBLEND_1"}, + {R200_PP_TXCBLEND_2, 4, "R200_PP_TXCBLEND_2"}, + {R200_PP_TXCBLEND_3, 4, "R200_PP_TXCBLEND_3"}, + {R200_PP_TXCBLEND_4, 4, "R200_PP_TXCBLEND_4"}, + {R200_PP_TXCBLEND_5, 4, "R200_PP_TXCBLEND_5"}, + {R200_PP_TXCBLEND_6, 4, "R200_PP_TXCBLEND_6"}, + {R200_PP_TXCBLEND_7, 4, "R200_PP_TXCBLEND_7"}, + {R200_SE_TCL_LIGHT_MODEL_CTL_0, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0"}, + {R200_PP_TFACTOR_0, 6, "R200_PP_TFACTOR_0"}, + {R200_SE_VTX_FMT_0, 4, "R200_SE_VTX_FMT_0"}, + {R200_SE_VAP_CNTL, 1, "R200_SE_VAP_CNTL"}, + {R200_SE_TCL_MATRIX_SEL_0, 5, "R200_SE_TCL_MATRIX_SEL_0"}, + {R200_SE_TCL_TEX_PROC_CTL_2, 5, "R200_SE_TCL_TEX_PROC_CTL_2"}, + {R200_SE_TCL_UCP_VERT_BLEND_CTL, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL"}, + {R200_PP_TXFILTER_0, 6, "R200_PP_TXFILTER_0"}, + {R200_PP_TXFILTER_1, 6, "R200_PP_TXFILTER_1"}, + {R200_PP_TXFILTER_2, 6, "R200_PP_TXFILTER_2"}, + {R200_PP_TXFILTER_3, 6, "R200_PP_TXFILTER_3"}, + {R200_PP_TXFILTER_4, 6, "R200_PP_TXFILTER_4"}, + {R200_PP_TXFILTER_5, 6, "R200_PP_TXFILTER_5"}, + {R200_PP_TXOFFSET_0, 1, "R200_PP_TXOFFSET_0"}, + {R200_PP_TXOFFSET_1, 1, "R200_PP_TXOFFSET_1"}, + {R200_PP_TXOFFSET_2, 1, "R200_PP_TXOFFSET_2"}, + {R200_PP_TXOFFSET_3, 1, "R200_PP_TXOFFSET_3"}, + {R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4"}, + {R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5"}, + {R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL"}, + {R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1, + "R200_SE_TCL_OUTPUT_VTX_COMP_SEL"}, + {R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3"}, + {R200_PP_CNTL_X, 1, "R200_PP_CNTL_X"}, + {R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET"}, + {R200_RE_AUX_SCISSOR_CNTL, 1, "R200_RE_AUX_SCISSOR_CNTL"}, + {R200_RE_SCISSOR_TL_0, 2, "R200_RE_SCISSOR_TL_0"}, + {R200_RE_SCISSOR_TL_1, 2, "R200_RE_SCISSOR_TL_1"}, + {R200_RE_SCISSOR_TL_2, 2, "R200_RE_SCISSOR_TL_2"}, + {R200_SE_VAP_CNTL_STATUS, 1, "R200_SE_VAP_CNTL_STATUS"}, + {R200_SE_VTX_STATE_CNTL, 1, "R200_SE_VTX_STATE_CNTL"}, + {R200_RE_POINTSIZE, 1, "R200_RE_POINTSIZE"}, + {R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4, + "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0"}, + {R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0"}, /* 61 */ + {R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0"}, /* 62 */ + {R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1"}, + {R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1"}, + {R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2"}, + {R200_PP_CUBIC_OFFSET_F1_2, 5, "R200_PP_CUBIC_OFFSET_F1_2"}, + {R200_PP_CUBIC_FACES_3, 1, "R200_PP_CUBIC_FACES_3"}, + {R200_PP_CUBIC_OFFSET_F1_3, 5, "R200_PP_CUBIC_OFFSET_F1_3"}, + {R200_PP_CUBIC_FACES_4, 1, "R200_PP_CUBIC_FACES_4"}, + {R200_PP_CUBIC_OFFSET_F1_4, 5, "R200_PP_CUBIC_OFFSET_F1_4"}, + {R200_PP_CUBIC_FACES_5, 1, "R200_PP_CUBIC_FACES_5"}, + {R200_PP_CUBIC_OFFSET_F1_5, 5, "R200_PP_CUBIC_OFFSET_F1_5"}, + {RADEON_PP_TEX_SIZE_0, 2, "RADEON_PP_TEX_SIZE_0"}, + {RADEON_PP_TEX_SIZE_1, 2, "RADEON_PP_TEX_SIZE_1"}, + {RADEON_PP_TEX_SIZE_2, 2, "RADEON_PP_TEX_SIZE_2"}, + {R200_RB3D_BLENDCOLOR, 3, "R200_RB3D_BLENDCOLOR"}, + {R200_SE_TCL_POINT_SPRITE_CNTL, 1, "R200_SE_TCL_POINT_SPRITE_CNTL"}, + {RADEON_PP_CUBIC_FACES_0, 1, "RADEON_PP_CUBIC_FACES_0"}, + {RADEON_PP_CUBIC_OFFSET_T0_0, 5, "RADEON_PP_CUBIC_OFFSET_T0_0"}, + {RADEON_PP_CUBIC_FACES_1, 1, "RADEON_PP_CUBIC_FACES_1"}, + {RADEON_PP_CUBIC_OFFSET_T1_0, 5, "RADEON_PP_CUBIC_OFFSET_T1_0"}, + {RADEON_PP_CUBIC_FACES_2, 1, "RADEON_PP_CUBIC_FACES_2"}, + {RADEON_PP_CUBIC_OFFSET_T2_0, 5, "RADEON_PP_CUBIC_OFFSET_T2_0"}, + {R200_PP_TRI_PERF, 2, "R200_PP_TRI_PERF"}, + {R200_PP_AFS_0, 32, "R200_PP_AFS_0"}, /* 85 */ + {R200_PP_AFS_1, 32, "R200_PP_AFS_1"}, + {R200_PP_TFACTOR_0, 8, "R200_ATF_TFACTOR"}, + {R200_PP_TXFILTER_0, 8, "R200_PP_TXCTLALL_0"}, + {R200_PP_TXFILTER_1, 8, "R200_PP_TXCTLALL_1"}, + {R200_PP_TXFILTER_2, 8, "R200_PP_TXCTLALL_2"}, + {R200_PP_TXFILTER_3, 8, "R200_PP_TXCTLALL_3"}, + {R200_PP_TXFILTER_4, 8, "R200_PP_TXCTLALL_4"}, + {R200_PP_TXFILTER_5, 8, "R200_PP_TXCTLALL_5"}, }; /* ================================================================ @@ -2084,7 +2097,7 @@ DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; drm_file_t *filp_priv; - drm_radeon_sarea_t *sarea_priv; + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_device_dma_t *dma = dev->dma; drm_buf_t *buf; drm_radeon_vertex_t vertex; @@ -2096,7 +2109,6 @@ DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return DRM_ERR(EINVAL); } - sarea_priv = dev_priv->sarea_priv; DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); @@ -2173,7 +2185,7 @@ DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; drm_file_t *filp_priv; - drm_radeon_sarea_t *sarea_priv; + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_device_dma_t *dma = dev->dma; drm_buf_t *buf; drm_radeon_indices_t elts; @@ -2186,7 +2198,6 @@ DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return DRM_ERR(EINVAL); } - sarea_priv = dev_priv->sarea_priv; DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); @@ -2402,7 +2413,7 @@ DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; drm_file_t *filp_priv; - drm_radeon_sarea_t *sarea_priv; + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_device_dma_t *dma = dev->dma; drm_buf_t *buf; drm_radeon_vertex2_t vertex; @@ -2415,7 +2426,6 @@ DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return DRM_ERR(EINVAL); } - sarea_priv = dev_priv->sarea_priv; DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); @@ -2922,7 +2932,7 @@ value = dev_priv->gart_vm_start; break; case RADEON_PARAM_REGISTER_HANDLE: - value = dev_priv->mmio_offset; + value = dev_priv->mmio->offset; break; case RADEON_PARAM_STATUS_HANDLE: value = dev_priv->ring_rptr_offset; @@ -2994,6 +3004,9 @@ dev_priv->sarea_priv->tiling_enabled = 1; } break; + case RADEON_SETPARAM_PCIGART_LOCATION: + dev_priv->pcigart_offset = sp.value; + break; default: DRM_DEBUG("Invalid parameter %d\n", sp.param); return DRM_ERR(EINVAL); @@ -3009,7 +3022,7 @@ * * DRM infrastructure takes care of reclaiming dma buffers. */ -void radeon_driver_prerelease(drm_device_t * dev, DRMFILE filp) +void radeon_driver_preclose(drm_device_t * dev, DRMFILE filp) { if (dev->dev_private) { drm_radeon_private_t *dev_priv = dev->dev_private; @@ -3022,12 +3035,12 @@ } } -void radeon_driver_pretakedown(drm_device_t * dev) +void radeon_driver_lastclose(drm_device_t * dev) { radeon_do_release(dev); } -int radeon_driver_open_helper(drm_device_t * dev, drm_file_t * filp_priv) +int radeon_driver_open(drm_device_t * dev, drm_file_t * filp_priv) { drm_radeon_private_t *dev_priv = dev->dev_private; struct drm_radeon_driver_file_fields *radeon_priv; @@ -3049,7 +3062,7 @@ return 0; } -void radeon_driver_free_filp_priv(drm_device_t * dev, drm_file_t * filp_priv) +void radeon_driver_postclose(drm_device_t * dev, drm_file_t * filp_priv) { struct drm_radeon_driver_file_fields *radeon_priv = filp_priv->driver_priv; @@ -3058,33 +3071,33 @@ } 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} + [DRM_IOCTL_NR(DRM_RADEON_CP_INIT)] = {radeon_cp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, + [DRM_IOCTL_NR(DRM_RADEON_CP_START)] = {radeon_cp_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, + [DRM_IOCTL_NR(DRM_RADEON_CP_STOP)] = {radeon_cp_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, + [DRM_IOCTL_NR(DRM_RADEON_CP_RESET)] = {radeon_cp_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, + [DRM_IOCTL_NR(DRM_RADEON_CP_IDLE)] = {radeon_cp_idle, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_RADEON_CP_RESUME)] = {radeon_cp_resume, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_RADEON_RESET)] = {radeon_engine_reset, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_RADEON_FULLSCREEN)] = {radeon_fullscreen, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_RADEON_SWAP)] = {radeon_cp_swap, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_RADEON_CLEAR)] = {radeon_cp_clear, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_RADEON_VERTEX)] = {radeon_cp_vertex, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_RADEON_INDICES)] = {radeon_cp_indices, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_RADEON_TEXTURE)] = {radeon_cp_texture, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_RADEON_STIPPLE)] = {radeon_cp_stipple, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_RADEON_INDIRECT)] = {radeon_cp_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, + [DRM_IOCTL_NR(DRM_RADEON_VERTEX2)] = {radeon_cp_vertex2, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_RADEON_CMDBUF)] = {radeon_cp_cmdbuf, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_RADEON_GETPARAM)] = {radeon_cp_getparam, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_RADEON_FLIP)] = {radeon_cp_flip, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_RADEON_ALLOC)] = {radeon_mem_alloc, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_RADEON_FREE)] = {radeon_mem_free, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_RADEON_INIT_HEAP)] = {radeon_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, + [DRM_IOCTL_NR(DRM_RADEON_IRQ_EMIT)] = {radeon_irq_emit, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_RADEON_IRQ_WAIT)] = {radeon_irq_wait, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_RADEON_SETPARAM)] = {radeon_cp_setparam, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_RADEON_SURF_ALLOC)] = {radeon_surface_alloc, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_RADEON_SURF_FREE)] = {radeon_surface_free, DRM_AUTH} }; int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls); Index: dev/drm/savage_bci.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/savage_bci.c,v retrieving revision 1.1 diff -u -r1.1 savage_bci.c --- dev/drm/savage_bci.c 16 Apr 2005 03:44:44 -0000 1.1 +++ dev/drm/savage_bci.c 23 Nov 2005 10:13:24 -0000 @@ -21,13 +21,13 @@ * 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. - * - * $FreeBSD: src/sys/dev/drm/savage_bci.c,v 1.1 2005/04/16 03:44:44 anholt Exp $ */ -#include "drmP.h" -#include "savage_drm.h" -#include "savage_drv.h" +#include +__FBSDID("$FreeBSD$"); +#include "dev/drm/drmP.h" +#include "dev/drm/savage_drm.h" +#include "dev/drm/savage_drv.h" /* Need a long timeout for shadow status updates can take a while * and so can waiting for events when the queue is full. */ @@ -165,8 +165,8 @@ uint16_t savage_bci_emit_event(drm_savage_private_t *dev_priv, unsigned int flags) { - BCI_LOCALS; uint16_t count; + BCI_LOCALS; if (dev_priv->status_ptr) { /* coordinate with Xserver */ @@ -419,12 +419,12 @@ static void savage_dma_flush(drm_savage_private_t *dev_priv) { - BCI_LOCALS; unsigned int first = dev_priv->first_dma_page; unsigned int cur = dev_priv->current_dma_page; uint16_t event; unsigned int wrap, pad, align, len, i; unsigned long phys_addr; + BCI_LOCALS; if (first == cur && dev_priv->dma_pages[cur].used == dev_priv->dma_pages[cur].flushed) @@ -504,8 +504,9 @@ static void savage_fake_dma_flush(drm_savage_private_t *dev_priv) { - BCI_LOCALS; unsigned int i, j; + BCI_LOCALS; + if (dev_priv->first_dma_page == dev_priv->current_dma_page && dev_priv->dma_pages[dev_priv->current_dma_page].used == 0) return; @@ -538,21 +539,9 @@ dev_priv->first_dma_page = dev_priv->current_dma_page = 0; } -/* - * Initalize permanent mappings. On Savage4 and SavageIX the alignment - * and size of the aperture is not suitable for automatic MTRR setup - * in drm_initmap. Therefore we do it manually before the maps are - * initialized. We also need to take care of deleting the MTRRs in - * postcleanup. - * - * FIXME: this is linux-specific - */ -int savage_preinit(drm_device_t *dev, unsigned long chipset) +int savage_driver_load(drm_device_t *dev, unsigned long chipset) { drm_savage_private_t *dev_priv; - unsigned long mmio_base, fb_base, fb_size, aperture_base; - unsigned int fb_rsrc, aper_rsrc; - int ret = 0; dev_priv = drm_alloc(sizeof(drm_savage_private_t), DRM_MEM_DRIVER); if (dev_priv == NULL) @@ -560,8 +549,29 @@ memset(dev_priv, 0, sizeof(drm_savage_private_t)); dev->dev_private = (void *)dev_priv; + dev_priv->chipset = (enum savage_family)chipset; + return 0; +} + +/* + * Initalize mappings. On Savage4 and SavageIX the alignment + * and size of the aperture is not suitable for automatic MTRR setup + * in drm_addmap. Therefore we add them manually before the maps are + * initialized, and tear them down on last close. + */ +int savage_driver_firstopen(drm_device_t *dev) +{ + drm_savage_private_t *dev_priv = dev->dev_private; + unsigned long mmio_base, fb_base, fb_size, aperture_base; + /* fb_rsrc and aper_rsrc aren't really used currently, but still exist + * in case we decide we need information on the BAR for BSD in the + * future. + */ + unsigned int fb_rsrc, aper_rsrc; + int ret = 0; + dev_priv->mtrr[0].handle = -1; dev_priv->mtrr[1].handle = -1; dev_priv->mtrr[2].handle = -1; @@ -578,24 +588,25 @@ * MTRRs. */ dev_priv->mtrr[0].base = fb_base; dev_priv->mtrr[0].size = 0x01000000; - dev_priv->mtrr[0].handle = mtrr_add( + dev_priv->mtrr[0].handle = drm_mtrr_add( dev_priv->mtrr[0].base, dev_priv->mtrr[0].size, - MTRR_TYPE_WRCOMB, 1); + DRM_MTRR_WC); dev_priv->mtrr[1].base = fb_base+0x02000000; dev_priv->mtrr[1].size = 0x02000000; - dev_priv->mtrr[1].handle = mtrr_add( + dev_priv->mtrr[1].handle = drm_mtrr_add( dev_priv->mtrr[1].base, dev_priv->mtrr[1].size, - MTRR_TYPE_WRCOMB, 1); + DRM_MTRR_WC); dev_priv->mtrr[2].base = fb_base+0x04000000; dev_priv->mtrr[2].size = 0x04000000; - dev_priv->mtrr[2].handle = mtrr_add( + dev_priv->mtrr[2].handle = drm_mtrr_add( dev_priv->mtrr[2].base, dev_priv->mtrr[2].size, - MTRR_TYPE_WRCOMB, 1); + DRM_MTRR_WC); } else { DRM_ERROR("strange pci_resource_len %08lx\n", drm_get_resource_len(dev, 0)); } - } else if (chipset != S3_SUPERSAVAGE && chipset != S3_SAVAGE2000) { + } else if (dev_priv->chipset != S3_SUPERSAVAGE && + dev_priv->chipset != S3_SAVAGE2000) { mmio_base = drm_get_resource_start(dev, 0); fb_rsrc = 1; fb_base = drm_get_resource_start(dev, 1); @@ -608,9 +619,9 @@ * aperture. */ dev_priv->mtrr[0].base = fb_base; dev_priv->mtrr[0].size = 0x08000000; - dev_priv->mtrr[0].handle = mtrr_add( + dev_priv->mtrr[0].handle = drm_mtrr_add( dev_priv->mtrr[0].base, dev_priv->mtrr[0].size, - MTRR_TYPE_WRCOMB, 1); + DRM_MTRR_WC); } else { DRM_ERROR("strange pci_resource_len %08lx\n", drm_get_resource_len(dev, 1)); @@ -625,24 +636,21 @@ /* Automatic MTRR setup will do the right thing. */ } - if ((ret = drm_initmap(dev, mmio_base, SAVAGE_MMIO_SIZE, 0, - _DRM_REGISTERS, 0))) + ret = drm_addmap(dev, mmio_base, SAVAGE_MMIO_SIZE, _DRM_REGISTERS, + _DRM_READ_ONLY, &dev_priv->mmio); + if (ret) return ret; - if (!(dev_priv->mmio = drm_core_findmap (dev, mmio_base))) - return DRM_ERR(ENOMEM); - if ((ret = drm_initmap(dev, fb_base, fb_size, fb_rsrc, - _DRM_FRAME_BUFFER, _DRM_WRITE_COMBINING))) + ret = drm_addmap(dev, fb_base, fb_size, _DRM_FRAME_BUFFER, + _DRM_WRITE_COMBINING, &dev_priv->fb); + if (ret) return ret; - if (!(dev_priv->fb = drm_core_findmap (dev, fb_base))) - return DRM_ERR(ENOMEM); - if ((ret = drm_initmap(dev, aperture_base, SAVAGE_APERTURE_SIZE, - aper_rsrc, - _DRM_FRAME_BUFFER, _DRM_WRITE_COMBINING))) + ret = drm_addmap(dev, aperture_base, SAVAGE_APERTURE_SIZE, + _DRM_FRAME_BUFFER, _DRM_WRITE_COMBINING, + &dev_priv->aperture); + if (ret) return ret; - if (!(dev_priv->aperture = drm_core_findmap (dev, aperture_base))) - return DRM_ERR(ENOMEM); return ret; } @@ -650,16 +658,22 @@ /* * Delete MTRRs and free device-private data. */ -int savage_postcleanup(drm_device_t *dev) +void savage_driver_lastclose(drm_device_t *dev) { drm_savage_private_t *dev_priv = dev->dev_private; int i; for (i = 0; i < 3; ++i) if (dev_priv->mtrr[i].handle >= 0) - mtrr_del(dev_priv->mtrr[i].handle, - dev_priv->mtrr[i].base, - dev_priv->mtrr[i].size); + drm_mtrr_del(dev_priv->mtrr[i].handle, + dev_priv->mtrr[i].base, + dev_priv->mtrr[i].size, + DRM_MTRR_WC); +} + +int savage_driver_unload(drm_device_t *dev) +{ + drm_savage_private_t *dev_priv = dev->dev_private; drm_free(dev_priv, sizeof(drm_savage_private_t), DRM_MEM_DRIVER); @@ -916,7 +930,7 @@ return 0; } -int savage_bci_init(DRM_IOCTL_ARGS) +static int savage_bci_init(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_savage_init_t init; @@ -936,7 +950,7 @@ return DRM_ERR(EINVAL); } -int savage_bci_event_emit(DRM_IOCTL_ARGS) +static int savage_bci_event_emit(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_savage_private_t *dev_priv = dev->dev_private; @@ -951,12 +965,12 @@ event.count = savage_bci_emit_event(dev_priv, event.flags); event.count |= dev_priv->event_wrap << 16; - DRM_COPY_TO_USER_IOCTL(&((drm_savage_event_emit_t __user *)data)->count, - event.count, sizeof(event.count)); + DRM_COPY_TO_USER_IOCTL((drm_savage_event_emit_t __user *)data, + event, sizeof(event)); return 0; } -int savage_bci_event_wait(DRM_IOCTL_ARGS) +static int savage_bci_event_wait(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_savage_private_t *dev_priv = dev->dev_private; @@ -1087,3 +1101,13 @@ drm_core_reclaim_buffers(dev, filp); } + +drm_ioctl_desc_t savage_ioctls[] = { + [DRM_IOCTL_NR(DRM_SAVAGE_BCI_INIT)] = {savage_bci_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, + [DRM_IOCTL_NR(DRM_SAVAGE_BCI_CMDBUF)] = {savage_bci_cmdbuf, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_EMIT)] = {savage_bci_event_emit, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_WAIT)] = {savage_bci_event_wait, DRM_AUTH}, +}; + +int savage_max_ioctl = DRM_ARRAY_SIZE(savage_ioctls); + Index: dev/drm/savage_drm.h =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/savage_drm.h,v retrieving revision 1.1 diff -u -r1.1 savage_drm.h --- dev/drm/savage_drm.h 16 Apr 2005 03:44:44 -0000 1.1 +++ dev/drm/savage_drm.h 23 Nov 2005 10:13:24 -0000 @@ -21,10 +21,11 @@ * 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. - * - * $FreeBSD: src/sys/dev/drm/savage_drm.h,v 1.1 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #ifndef __SAVAGE_DRM_H__ #define __SAVAGE_DRM_H__ Index: dev/drm/savage_drv.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/savage_drv.c,v retrieving revision 1.1 diff -u -r1.1 savage_drv.c --- dev/drm/savage_drv.c 16 Apr 2005 03:44:44 -0000 1.1 +++ dev/drm/savage_drv.c 23 Nov 2005 10:13:24 -0000 @@ -24,46 +24,46 @@ * * Authors: * Eric Anholt - * - * $FreeBSD: src/sys/dev/drm/savage_drv.c,v 1.1 2005/04/16 03:44:44 anholt Exp $ */ -#include "drmP.h" -#include "drm.h" -#include "savage_drm.h" -#include "savage_drv.h" -#include "drm_pciids.h" +#include +__FBSDID("$FreeBSD$"); + +#include "dev/drm/drmP.h" +#include "dev/drm/drm.h" +#include "dev/drm/savage_drm.h" +#include "dev/drm/savage_drv.h" +#include "dev/drm/drm_pciids.h" /* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */ static drm_pci_id_list_t savage_pciidlist[] = { savage_PCI_IDS }; -extern drm_ioctl_desc_t savage_ioctls[]; -extern int savage_max_ioctl; - static void savage_configure(drm_device_t *dev) { - dev->dev_priv_size = sizeof(drm_savage_buf_priv_t); - dev->preinit = savage_preinit; - dev->postcleanup = savage_postcleanup; - dev->reclaim_buffers = savage_reclaim_buffers; - dev->dma_ioctl = savage_bci_buffers; - - dev->driver_ioctls = savage_ioctls; - dev->max_driver_ioctl = savage_max_ioctl; - - dev->driver_name = DRIVER_NAME; - dev->driver_desc = DRIVER_DESC; - dev->driver_date = DRIVER_DATE; - dev->driver_major = DRIVER_MAJOR; - dev->driver_minor = DRIVER_MINOR; - dev->driver_patchlevel = DRIVER_PATCHLEVEL; - - dev->use_agp = 1; - dev->use_mtrr = 1; - dev->use_pci_dma = 1; - dev->use_dma = 1; + dev->driver.buf_priv_size = sizeof(drm_savage_buf_priv_t); + dev->driver.load = savage_driver_load; + dev->driver.firstopen = savage_driver_firstopen; + dev->driver.lastclose = savage_driver_lastclose; + dev->driver.unload = savage_driver_unload; + dev->driver.reclaim_buffers_locked = savage_reclaim_buffers; + dev->driver.dma_ioctl = savage_bci_buffers; + + dev->driver.ioctls = savage_ioctls; + dev->driver.max_ioctl = savage_max_ioctl; + + dev->driver.name = DRIVER_NAME; + dev->driver.desc = DRIVER_DESC; + dev->driver.date = DRIVER_DATE; + dev->driver.major = DRIVER_MAJOR; + dev->driver.minor = DRIVER_MINOR; + dev->driver.patchlevel = DRIVER_PATCHLEVEL; + + dev->driver.use_agp = 1; + dev->driver.use_mtrr = 1; + dev->driver.use_pci_dma = 1; + dev->driver.use_dma = 1; } #ifdef __FreeBSD__ Index: dev/drm/savage_drv.h =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/savage_drv.h,v retrieving revision 1.1 diff -u -r1.1 savage_drv.h --- dev/drm/savage_drv.h 16 Apr 2005 03:44:44 -0000 1.1 +++ dev/drm/savage_drv.h 23 Nov 2005 10:13:24 -0000 @@ -1,5 +1,5 @@ -/* savage_drv.h -- Private header for the savage driver - * +/* savage_drv.h -- Private header for the savage driver */ +/*- * Copyright 2004 Felix Kuehling * All Rights Reserved. * @@ -21,10 +21,11 @@ * 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. - * - * $FreeBSD: src/sys/dev/drm/savage_drv.h,v 1.1 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #ifndef __SAVAGE_DRV_H__ #define __SAVAGE_DRV_H__ @@ -106,6 +107,9 @@ S3_LAST }; +extern drm_ioctl_desc_t savage_ioctls[]; +extern int savage_max_ioctl; + #define S3_SAVAGE3D_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE_MX)) #define S3_SAVAGE4_SERIES(chip) ((chip==S3_SAVAGE4) \ @@ -191,15 +195,12 @@ /* Err, there is a macro wait_event in include/linux/wait.h. * Avoid unwanted macro expansion. */ void (*emit_clip_rect)(struct drm_savage_private *dev_priv, - drm_clip_rect_t *pbox); + const drm_clip_rect_t *pbox); void (*dma_flush)(struct drm_savage_private *dev_priv); } drm_savage_private_t; /* ioctls */ -extern int savage_bci_init(DRM_IOCTL_ARGS); extern int savage_bci_cmdbuf(DRM_IOCTL_ARGS); -extern int savage_bci_event_emit(DRM_IOCTL_ARGS); -extern int savage_bci_event_wait(DRM_IOCTL_ARGS); extern int savage_bci_buffers(DRM_IOCTL_ARGS); /* BCI functions */ @@ -210,16 +211,18 @@ extern void savage_dma_wait(drm_savage_private_t *dev_priv, unsigned int page); extern uint32_t *savage_dma_alloc(drm_savage_private_t *dev_priv, unsigned int n); -extern int savage_preinit(drm_device_t *dev, unsigned long chipset); -extern int savage_postcleanup(drm_device_t *dev); +extern int savage_driver_load(drm_device_t *dev, unsigned long chipset); +extern int savage_driver_firstopen(drm_device_t *dev); +extern void savage_driver_lastclose(drm_device_t *dev); +extern int savage_driver_unload(drm_device_t *dev); extern int savage_do_cleanup_bci(drm_device_t *dev); extern void savage_reclaim_buffers(drm_device_t *dev, DRMFILE filp); /* state functions */ extern void savage_emit_clip_rect_s3d(drm_savage_private_t *dev_priv, - drm_clip_rect_t *pbox); + const drm_clip_rect_t *pbox); extern void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv, - drm_clip_rect_t *pbox); + const drm_clip_rect_t *pbox); #define SAVAGE_FB_SIZE_S3 0x01000000 /* 16MB */ #define SAVAGE_FB_SIZE_S4 0x02000000 /* 32MB */ @@ -502,15 +505,6 @@ #define BCI_WRITE( val ) *bci_ptr++ = (uint32_t)(val) -#define BCI_COPY_FROM_USER(src,n) do { \ - unsigned int i; \ - for (i = 0; i < n; ++i) { \ - uint32_t val; \ - DRM_GET_USER_UNCHECKED(val, &((uint32_t*)(src))[i]); \ - BCI_WRITE(val); \ - } \ -} while(0) - /* * command DMA support */ @@ -536,8 +530,8 @@ #define DMA_WRITE( val ) *dma_ptr++ = (uint32_t)(val) -#define DMA_COPY_FROM_USER(src,n) do { \ - DRM_COPY_FROM_USER_UNCHECKED(dma_ptr, (src), (n)*4); \ +#define DMA_COPY(src, n) do { \ + memcpy(dma_ptr, (src), (n)*4); \ dma_ptr += n; \ } while(0) Index: dev/drm/savage_state.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/savage_state.c,v retrieving revision 1.1 diff -u -r1.1 savage_state.c --- dev/drm/savage_state.c 16 Apr 2005 03:44:44 -0000 1.1 +++ dev/drm/savage_state.c 23 Nov 2005 10:13:24 -0000 @@ -21,16 +21,16 @@ * 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. - * - * $FreeBSD: src/sys/dev/drm/savage_state.c,v 1.1 2005/04/16 03:44:44 anholt Exp $ */ -#include "drmP.h" -#include "savage_drm.h" -#include "savage_drv.h" +#include +__FBSDID("$FreeBSD$"); +#include "dev/drm/drmP.h" +#include "dev/drm/savage_drm.h" +#include "dev/drm/savage_drv.h" void savage_emit_clip_rect_s3d(drm_savage_private_t *dev_priv, - drm_clip_rect_t *pbox) + const drm_clip_rect_t *pbox) { uint32_t scstart = dev_priv->state.s3d.new_scstart; uint32_t scend = dev_priv->state.s3d.new_scend; @@ -56,7 +56,7 @@ } void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv, - drm_clip_rect_t *pbox) + const drm_clip_rect_t *pbox) { uint32_t drawctrl0 = dev_priv->state.s4.new_drawctrl0; uint32_t drawctrl1 = dev_priv->state.s4.new_drawctrl1; @@ -116,18 +116,18 @@ #define SAVE_STATE(reg,where) \ if(start <= reg && start+count > reg) \ - DRM_GET_USER_UNCHECKED(dev_priv->state.where, ®s[reg-start]) + dev_priv->state.where = regs[reg - start] #define SAVE_STATE_MASK(reg,where,mask) do { \ if(start <= reg && start+count > reg) { \ uint32_t tmp; \ - DRM_GET_USER_UNCHECKED(tmp, ®s[reg-start]); \ + tmp = regs[reg - start]; \ dev_priv->state.where = (tmp & (mask)) | \ (dev_priv->state.where & ~(mask)); \ } \ } while (0) static int savage_verify_state_s3d(drm_savage_private_t *dev_priv, unsigned int start, unsigned int count, - const uint32_t __user *regs) + const uint32_t *regs) { if (start < SAVAGE_TEXPALADDR_S3D || start+count-1 > SAVAGE_DESTTEXRWWATERMARK_S3D) { @@ -157,7 +157,7 @@ static int savage_verify_state_s4(drm_savage_private_t *dev_priv, unsigned int start, unsigned int count, - const uint32_t __user *regs) + const uint32_t *regs) { int ret = 0; @@ -195,21 +195,18 @@ static int savage_dispatch_state(drm_savage_private_t *dev_priv, const drm_savage_cmd_header_t *cmd_header, - const uint32_t __user *regs) + const uint32_t *regs) { - DMA_LOCALS; unsigned int count = cmd_header->state.count; unsigned int start = cmd_header->state.start; unsigned int count2 = 0; unsigned int bci_size; int ret; + DMA_LOCALS; if (!count) return 0; - if (DRM_VERIFYAREA_READ(regs, count*4)) - return DRM_ERR(EFAULT); - if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { ret = savage_verify_state_s3d(dev_priv, start, count, regs); if (ret != 0) @@ -260,7 +257,7 @@ while (count > 0) { unsigned int n = count < 255 ? count : 255; DMA_SET_REGISTERS(start, n); - DMA_COPY_FROM_USER(regs, n); + DMA_COPY(regs, n); count -= n; start += n; regs += n; @@ -280,13 +277,13 @@ const drm_savage_cmd_header_t *cmd_header, const drm_buf_t *dmabuf) { - BCI_LOCALS; unsigned char reorder = 0; unsigned int prim = cmd_header->prim.prim; unsigned int skip = cmd_header->prim.skip; unsigned int n = cmd_header->prim.count; unsigned int start = cmd_header->prim.start; unsigned int i; + BCI_LOCALS; if (!dmabuf) { DRM_ERROR("called without dma buffers!\n"); @@ -418,11 +415,9 @@ static int savage_dispatch_vb_prim(drm_savage_private_t *dev_priv, const drm_savage_cmd_header_t *cmd_header, - const uint32_t __user *vtxbuf, - unsigned int vb_size, + const uint32_t *vtxbuf, unsigned int vb_size, unsigned int vb_stride) { - DMA_LOCALS; unsigned char reorder = 0; unsigned int prim = cmd_header->prim.prim; unsigned int skip = cmd_header->prim.skip; @@ -430,6 +425,7 @@ unsigned int start = cmd_header->prim.start; unsigned int vtx_size; unsigned int i; + DMA_LOCALS; if (!n) return 0; @@ -504,8 +500,7 @@ for (i = start; i < start+count; ++i) { unsigned int j = i + reorder[i % 3]; - DMA_COPY_FROM_USER(&vtxbuf[vb_stride*j], - vtx_size); + DMA_COPY(&vtxbuf[vb_stride*j], vtx_size); } DMA_COMMIT(); @@ -514,13 +509,12 @@ DMA_DRAW_PRIMITIVE(count, prim, skip); if (vb_stride == vtx_size) { - DMA_COPY_FROM_USER(&vtxbuf[vb_stride*start], - vtx_size*count); + DMA_COPY(&vtxbuf[vb_stride*start], + vtx_size*count); } else { for (i = start; i < start+count; ++i) { - DMA_COPY_FROM_USER( - &vtxbuf[vb_stride*i], - vtx_size); + DMA_COPY(&vtxbuf[vb_stride*i], + vtx_size); } } @@ -538,15 +532,15 @@ static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv, const drm_savage_cmd_header_t *cmd_header, - const uint16_t __user *usr_idx, + const uint16_t *idx, const drm_buf_t *dmabuf) { - BCI_LOCALS; unsigned char reorder = 0; unsigned int prim = cmd_header->idx.prim; unsigned int skip = cmd_header->idx.skip; unsigned int n = cmd_header->idx.count; unsigned int i; + BCI_LOCALS; if (!dmabuf) { DRM_ERROR("called without dma buffers!\n"); @@ -628,11 +622,8 @@ while (n != 0) { /* Can emit up to 255 indices (85 triangles) at once. */ unsigned int count = n > 255 ? 255 : n; - /* Is it ok to allocate 510 bytes on the stack in an ioctl? */ - uint16_t idx[255]; - /* Copy and check indices */ - DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count*2); + /* check indices */ for (i = 0; i < count; ++i) { if (idx[i] > dmabuf->total/32) { DRM_ERROR("idx[%u]=%u out of range (0-%u)\n", @@ -673,7 +664,7 @@ BCI_WRITE(idx[i]); } - usr_idx += count; + idx += count; n -= count; prim |= BCI_CMD_DRAW_CONT; @@ -684,18 +675,18 @@ static int savage_dispatch_vb_idx(drm_savage_private_t *dev_priv, const drm_savage_cmd_header_t *cmd_header, - const uint16_t __user *usr_idx, - const uint32_t __user *vtxbuf, + const uint16_t *idx, + const uint32_t *vtxbuf, unsigned int vb_size, unsigned int vb_stride) { - DMA_LOCALS; unsigned char reorder = 0; unsigned int prim = cmd_header->idx.prim; unsigned int skip = cmd_header->idx.skip; unsigned int n = cmd_header->idx.count; unsigned int vtx_size; unsigned int i; + DMA_LOCALS; if (!n) return 0; @@ -752,11 +743,8 @@ while (n != 0) { /* Can emit up to 255 vertices (85 triangles) at once. */ unsigned int count = n > 255 ? 255 : n; - /* Is it ok to allocate 510 bytes on the stack in an ioctl? */ - uint16_t idx[255]; - /* Copy and check indices */ - DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count*2); + /* Check indices */ for (i = 0; i < count; ++i) { if (idx[i] > vb_size / (vb_stride*4)) { DRM_ERROR("idx[%u]=%u out of range (0-%u)\n", @@ -776,8 +764,7 @@ for (i = 0; i < count; ++i) { unsigned int j = idx[i + reorder[i % 3]]; - DMA_COPY_FROM_USER(&vtxbuf[vb_stride*j], - vtx_size); + DMA_COPY(&vtxbuf[vb_stride*j], vtx_size); } DMA_COMMIT(); @@ -787,14 +774,13 @@ for (i = 0; i < count; ++i) { unsigned int j = idx[i]; - DMA_COPY_FROM_USER(&vtxbuf[vb_stride*j], - vtx_size); + DMA_COPY(&vtxbuf[vb_stride*j], vtx_size); } DMA_COMMIT(); } - usr_idx += count; + idx += count; n -= count; prim |= BCI_CMD_DRAW_CONT; @@ -805,23 +791,18 @@ static int savage_dispatch_clear(drm_savage_private_t *dev_priv, const drm_savage_cmd_header_t *cmd_header, - const drm_savage_cmd_header_t __user *data, + const drm_savage_cmd_header_t *data, unsigned int nbox, - const drm_clip_rect_t __user *usr_boxes) + const drm_clip_rect_t *boxes) { - DMA_LOCALS; - unsigned int flags = cmd_header->clear0.flags, mask, value; + unsigned int flags = cmd_header->clear0.flags; unsigned int clear_cmd; unsigned int i, nbufs; + DMA_LOCALS; if (nbox == 0) return 0; - DRM_GET_USER_UNCHECKED(mask, &((drm_savage_cmd_header_t*)data) - ->clear1.mask); - DRM_GET_USER_UNCHECKED(value, &((drm_savage_cmd_header_t*)data) - ->clear1.value); - clear_cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP | BCI_CMD_SEND_COLOR | BCI_CMD_DEST_PBD_NEW; BCI_CMD_SET_ROP(clear_cmd,0xCC); @@ -832,21 +813,20 @@ if (nbufs == 0) return 0; - if (mask != 0xffffffff) { + if (data->clear1.mask != 0xffffffff) { /* set mask */ BEGIN_DMA(2); DMA_SET_REGISTERS(SAVAGE_BITPLANEWTMASK, 1); - DMA_WRITE(mask); + DMA_WRITE(data->clear1.mask); DMA_COMMIT(); } for (i = 0; i < nbox; ++i) { - drm_clip_rect_t box; unsigned int x, y, w, h; unsigned int buf; - DRM_COPY_FROM_USER_UNCHECKED(&box, &usr_boxes[i], sizeof(box)); - x = box.x1, y = box.y1; - w = box.x2 - box.x1; - h = box.y2 - box.y1; + + x = boxes[i].x1, y = boxes[i].y1; + w = boxes[i].x2 - boxes[i].x1; + h = boxes[i].y2 - boxes[i].y1; BEGIN_DMA(nbufs*6); for (buf = SAVAGE_FRONT; buf <= SAVAGE_DEPTH; buf <<= 1) { if (!(flags & buf)) @@ -866,13 +846,13 @@ DMA_WRITE(dev_priv->depth_bd); break; } - DMA_WRITE(value); + DMA_WRITE(data->clear1.value); DMA_WRITE(BCI_X_Y(x, y)); DMA_WRITE(BCI_W_H(w, h)); } DMA_COMMIT(); } - if (mask != 0xffffffff) { + if (data->clear1.mask != 0xffffffff) { /* reset mask */ BEGIN_DMA(2); DMA_SET_REGISTERS(SAVAGE_BITPLANEWTMASK, 1); @@ -884,12 +864,11 @@ } static int savage_dispatch_swap(drm_savage_private_t *dev_priv, - unsigned int nbox, - const drm_clip_rect_t __user *usr_boxes) + unsigned int nbox, const drm_clip_rect_t *boxes) { - DMA_LOCALS; unsigned int swap_cmd; unsigned int i; + DMA_LOCALS; if (nbox == 0) return 0; @@ -899,16 +878,14 @@ BCI_CMD_SET_ROP(swap_cmd,0xCC); for (i = 0; i < nbox; ++i) { - drm_clip_rect_t box; - DRM_COPY_FROM_USER_UNCHECKED(&box, &usr_boxes[i], sizeof(box)); - BEGIN_DMA(6); DMA_WRITE(swap_cmd); DMA_WRITE(dev_priv->back_offset); DMA_WRITE(dev_priv->back_bd); - DMA_WRITE(BCI_X_Y(box.x1, box.y1)); - DMA_WRITE(BCI_X_Y(box.x1, box.y1)); - DMA_WRITE(BCI_W_H(box.x2-box.x1, box.y2-box.y1)); + DMA_WRITE(BCI_X_Y(boxes[i].x1, boxes[i].y1)); + DMA_WRITE(BCI_X_Y(boxes[i].x1, boxes[i].y1)); + DMA_WRITE(BCI_W_H(boxes[i].x2-boxes[i].x1, + boxes[i].y2-boxes[i].y1)); DMA_COMMIT(); } @@ -916,29 +893,26 @@ } static int savage_dispatch_draw(drm_savage_private_t *dev_priv, - const drm_savage_cmd_header_t __user *start, - const drm_savage_cmd_header_t __user *end, + const drm_savage_cmd_header_t *start, + const drm_savage_cmd_header_t *end, const drm_buf_t *dmabuf, - const unsigned int __user *usr_vtxbuf, + const unsigned int *vtxbuf, unsigned int vb_size, unsigned int vb_stride, unsigned int nbox, - const drm_clip_rect_t __user *usr_boxes) + const drm_clip_rect_t *boxes) { unsigned int i, j; int ret; for (i = 0; i < nbox; ++i) { - drm_clip_rect_t box; - const drm_savage_cmd_header_t __user *usr_cmdbuf; - DRM_COPY_FROM_USER_UNCHECKED(&box, &usr_boxes[i], sizeof(box)); - dev_priv->emit_clip_rect(dev_priv, &box); + const drm_savage_cmd_header_t *cmdbuf; + dev_priv->emit_clip_rect(dev_priv, &boxes[i]); - usr_cmdbuf = start; - while (usr_cmdbuf < end) { + cmdbuf = start; + while (cmdbuf < end) { drm_savage_cmd_header_t cmd_header; - DRM_COPY_FROM_USER_UNCHECKED(&cmd_header, usr_cmdbuf, - sizeof(cmd_header)); - usr_cmdbuf++; + cmd_header = *cmdbuf; + cmdbuf++; switch (cmd_header.cmd.cmd) { case SAVAGE_CMD_DMA_PRIM: ret = savage_dispatch_dma_prim( @@ -947,27 +921,24 @@ case SAVAGE_CMD_VB_PRIM: ret = savage_dispatch_vb_prim( dev_priv, &cmd_header, - (uint32_t __user *)usr_vtxbuf, - vb_size, vb_stride); + vtxbuf, vb_size, vb_stride); break; case SAVAGE_CMD_DMA_IDX: j = (cmd_header.idx.count + 3) / 4; /* j was check in savage_bci_cmdbuf */ - ret = savage_dispatch_dma_idx( - dev_priv, &cmd_header, - (uint16_t __user *)usr_cmdbuf, + ret = savage_dispatch_dma_idx(dev_priv, + &cmd_header, (const uint16_t *)cmdbuf, dmabuf); - usr_cmdbuf += j; + cmdbuf += j; break; case SAVAGE_CMD_VB_IDX: j = (cmd_header.idx.count + 3) / 4; /* j was check in savage_bci_cmdbuf */ - ret = savage_dispatch_vb_idx( - dev_priv, &cmd_header, - (uint16_t __user *)usr_cmdbuf, - (uint32_t __user *)usr_vtxbuf, - vb_size, vb_stride); - usr_cmdbuf += j; + ret = savage_dispatch_vb_idx(dev_priv, + &cmd_header, (const uint16_t *)cmdbuf, + (const uint32_t *)vtxbuf, vb_size, + vb_stride); + cmdbuf += j; break; default: /* What's the best return code? EFAULT? */ @@ -992,10 +963,10 @@ drm_device_dma_t *dma = dev->dma; drm_buf_t *dmabuf; drm_savage_cmdbuf_t cmdbuf; - drm_savage_cmd_header_t __user *usr_cmdbuf; - drm_savage_cmd_header_t __user *first_draw_cmd; - unsigned int __user *usr_vtxbuf; - drm_clip_rect_t __user *usr_boxes; + drm_savage_cmd_header_t *kcmd_addr = NULL; + drm_savage_cmd_header_t *first_draw_cmd; + unsigned int *kvb_addr = NULL; + drm_clip_rect_t *kbox_addr = NULL; unsigned int i, j; int ret = 0; @@ -1017,15 +988,53 @@ dmabuf = NULL; } - usr_cmdbuf = (drm_savage_cmd_header_t __user *)cmdbuf.cmd_addr; - usr_vtxbuf = (unsigned int __user *)cmdbuf.vb_addr; - usr_boxes = (drm_clip_rect_t __user *)cmdbuf.box_addr; - if ((cmdbuf.size && DRM_VERIFYAREA_READ(usr_cmdbuf, cmdbuf.size*8)) || - (cmdbuf.vb_size && DRM_VERIFYAREA_READ( - usr_vtxbuf, cmdbuf.vb_size)) || - (cmdbuf.nbox && DRM_VERIFYAREA_READ( - usr_boxes, cmdbuf.nbox*sizeof(drm_clip_rect_t)))) - return DRM_ERR(EFAULT); + /* Copy the user buffers into kernel temporary areas. This hasn't been + * a performance loss compared to VERIFYAREA_READ/ + * COPY_FROM_USER_UNCHECKED when done in other drivers, and is correct + * for locking on FreeBSD. + */ + if (cmdbuf.size) { + kcmd_addr = drm_alloc(cmdbuf.size * 8, DRM_MEM_DRIVER); + if (kcmd_addr == NULL) + return ENOMEM; + + if (DRM_COPY_FROM_USER(kcmd_addr, cmdbuf.cmd_addr, + cmdbuf.size * 8)) + { + drm_free(kcmd_addr, cmdbuf.size * 8, DRM_MEM_DRIVER); + return DRM_ERR(EFAULT); + } + cmdbuf.cmd_addr = kcmd_addr; + } + if (cmdbuf.vb_size) { + kvb_addr = drm_alloc(cmdbuf.vb_size, DRM_MEM_DRIVER); + if (kvb_addr == NULL) { + ret = DRM_ERR(ENOMEM); + goto done; + } + + if (DRM_COPY_FROM_USER(kvb_addr, cmdbuf.vb_addr, + cmdbuf.vb_size)) { + ret = DRM_ERR(EFAULT); + goto done; + } + cmdbuf.vb_addr = kvb_addr; + } + if (cmdbuf.nbox) { + kbox_addr = drm_alloc(cmdbuf.nbox * sizeof(drm_clip_rect_t), + DRM_MEM_DRIVER); + if (kbox_addr == NULL) { + ret = DRM_ERR(ENOMEM); + goto done; + } + + if (DRM_COPY_FROM_USER(kbox_addr, cmdbuf.box_addr, + cmdbuf.nbox * sizeof(drm_clip_rect_t))) { + ret = DRM_ERR(EFAULT); + goto done; + } + cmdbuf.box_addr = kbox_addr; + } /* Make sure writes to DMA buffers are finished before sending * DMA commands to the graphics hardware. */ @@ -1039,9 +1048,8 @@ first_draw_cmd = NULL; while (i < cmdbuf.size) { drm_savage_cmd_header_t cmd_header; - DRM_COPY_FROM_USER_UNCHECKED(&cmd_header, usr_cmdbuf, - sizeof(cmd_header)); - usr_cmdbuf++; + cmd_header = *(drm_savage_cmd_header_t *)cmdbuf.cmd_addr; + cmdbuf.cmd_addr++; i++; /* Group drawing commands with same state to minimize @@ -1061,17 +1069,18 @@ case SAVAGE_CMD_DMA_PRIM: case SAVAGE_CMD_VB_PRIM: if (!first_draw_cmd) - first_draw_cmd = usr_cmdbuf-1; - usr_cmdbuf += j; + first_draw_cmd = cmdbuf.cmd_addr-1; + cmdbuf.cmd_addr += j; i += j; break; default: if (first_draw_cmd) { ret = savage_dispatch_draw ( - dev_priv, first_draw_cmd, usr_cmdbuf-1, - dmabuf, usr_vtxbuf, cmdbuf.vb_size, + dev_priv, first_draw_cmd, + cmdbuf.cmd_addr-1, + dmabuf, cmdbuf.vb_addr, cmdbuf.vb_size, cmdbuf.vb_stride, - cmdbuf.nbox, usr_boxes); + cmdbuf.nbox, cmdbuf.box_addr); if (ret != 0) return ret; first_draw_cmd = NULL; @@ -1087,12 +1096,12 @@ DRM_ERROR("command SAVAGE_CMD_STATE extends " "beyond end of command buffer\n"); DMA_FLUSH(); - return DRM_ERR(EINVAL); + ret = DRM_ERR(EINVAL); + goto done; } - ret = savage_dispatch_state( - dev_priv, &cmd_header, - (uint32_t __user *)usr_cmdbuf); - usr_cmdbuf += j; + ret = savage_dispatch_state(dev_priv, &cmd_header, + (const uint32_t *)cmdbuf.cmd_addr); + cmdbuf.cmd_addr += j; i += j; break; case SAVAGE_CMD_CLEAR: @@ -1100,38 +1109,40 @@ DRM_ERROR("command SAVAGE_CMD_CLEAR extends " "beyond end of command buffer\n"); DMA_FLUSH(); - return DRM_ERR(EINVAL); + ret = DRM_ERR(EINVAL); + goto done; } ret = savage_dispatch_clear(dev_priv, &cmd_header, - usr_cmdbuf, - cmdbuf.nbox, usr_boxes); - usr_cmdbuf++; + cmdbuf.cmd_addr, + cmdbuf.nbox, cmdbuf.box_addr); + cmdbuf.cmd_addr++; i++; break; case SAVAGE_CMD_SWAP: - ret = savage_dispatch_swap(dev_priv, - cmdbuf.nbox, usr_boxes); + ret = savage_dispatch_swap(dev_priv, cmdbuf.nbox, + cmdbuf.box_addr); break; default: DRM_ERROR("invalid command 0x%x\n", cmd_header.cmd.cmd); DMA_FLUSH(); - return DRM_ERR(EINVAL); + ret = DRM_ERR(EINVAL); + goto done; } if (ret != 0) { DMA_FLUSH(); - return ret; + goto done; } } if (first_draw_cmd) { ret = savage_dispatch_draw ( - dev_priv, first_draw_cmd, usr_cmdbuf, dmabuf, - usr_vtxbuf, cmdbuf.vb_size, cmdbuf.vb_stride, - cmdbuf.nbox, usr_boxes); + dev_priv, first_draw_cmd, cmdbuf.cmd_addr, dmabuf, + cmdbuf.vb_addr, cmdbuf.vb_size, cmdbuf.vb_stride, + cmdbuf.nbox, cmdbuf.box_addr); if (ret != 0) { DMA_FLUSH(); - return ret; + goto done; } } @@ -1145,5 +1156,12 @@ savage_freelist_put(dev, dmabuf); } - return 0; +done: + /* If we didn't need to allocate them, these'll be NULL */ + drm_free(kcmd_addr, cmdbuf.size * 8, DRM_MEM_DRIVER); + drm_free(kvb_addr, cmdbuf.vb_size, DRM_MEM_DRIVER); + drm_free(kbox_addr, cmdbuf.nbox * sizeof(drm_clip_rect_t), + DRM_MEM_DRIVER); + + return ret; } Index: dev/drm/sis_drm.h =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/sis_drm.h,v retrieving revision 1.5 diff -u -r1.5 sis_drm.h --- dev/drm/sis_drm.h 16 Apr 2005 03:44:44 -0000 1.5 +++ dev/drm/sis_drm.h 23 Nov 2005 10:13:24 -0000 @@ -1,6 +1,3 @@ -/* - * $FreeBSD: src/sys/dev/drm/sis_drm.h,v 1.5 2005/04/16 03:44:44 anholt Exp $ - */ #ifndef __SIS_DRM_H__ #define __SIS_DRM_H__ Index: dev/drm/sis_drv.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/sis_drv.c,v retrieving revision 1.5 diff -u -r1.5 sis_drv.c --- dev/drm/sis_drv.c 16 Apr 2005 03:44:44 -0000 1.5 +++ dev/drm/sis_drv.c 23 Nov 2005 10:13:24 -0000 @@ -24,9 +24,11 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * - * $FreeBSD: src/sys/dev/drm/sis_drv.c,v 1.5 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" #include "dev/drm/sis_drm.h" #include "dev/drm/sis_drv.h" @@ -37,27 +39,24 @@ sis_PCI_IDS }; -extern drm_ioctl_desc_t sis_ioctls[]; -extern int sis_max_ioctl; - static void sis_configure(drm_device_t *dev) { - dev->dev_priv_size = 1; /* No dev_priv */ - dev->context_ctor = sis_init_context; - dev->context_dtor = sis_final_context; - - dev->driver_ioctls = sis_ioctls; - dev->max_driver_ioctl = sis_max_ioctl; - - dev->driver_name = DRIVER_NAME; - dev->driver_desc = DRIVER_DESC; - dev->driver_date = DRIVER_DATE; - dev->driver_major = DRIVER_MAJOR; - dev->driver_minor = DRIVER_MINOR; - dev->driver_patchlevel = DRIVER_PATCHLEVEL; + dev->driver.buf_priv_size = 1; /* No dev_priv */ + dev->driver.context_ctor = sis_init_context; + dev->driver.context_dtor = sis_final_context; + + dev->driver.ioctls = sis_ioctls; + dev->driver.max_ioctl = sis_max_ioctl; + + dev->driver.name = DRIVER_NAME; + dev->driver.desc = DRIVER_DESC; + dev->driver.date = DRIVER_DATE; + dev->driver.major = DRIVER_MAJOR; + dev->driver.minor = DRIVER_MINOR; + dev->driver.patchlevel = DRIVER_PATCHLEVEL; - dev->use_agp = 1; - dev->use_mtrr = 1; + dev->driver.use_agp = 1; + dev->driver.use_mtrr = 1; } #ifdef __FreeBSD__ @@ -97,5 +96,10 @@ MODULE_DEPEND(sisdrm, drm, 1, 1, 1); #elif defined(__NetBSD__) || defined(__OpenBSD__) +#ifdef _LKM CFDRIVER_DECL(sis, DV_TTY, NULL); +#else +CFATTACH_DECL(sis, sizeof(drm_device_t), drm_probe, drm_attach, drm_detach, + drm_activate); +#endif #endif Index: dev/drm/sis_drv.h =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/sis_drv.h,v retrieving revision 1.3 diff -u -r1.3 sis_drv.h --- dev/drm/sis_drv.h 16 Apr 2005 03:44:44 -0000 1.3 +++ dev/drm/sis_drv.h 23 Nov 2005 10:13:24 -0000 @@ -23,9 +23,11 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * - * $FreeBSD: src/sys/dev/drm/sis_drv.h,v 1.3 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #ifndef _SIS_DRV_H_ #define _SIS_DRV_H_ @@ -50,4 +52,7 @@ extern int sis_init_context(drm_device_t * dev, int context); extern int sis_final_context(drm_device_t * dev, int context); +extern drm_ioctl_desc_t sis_ioctls[]; +extern int sis_max_ioctl; + #endif Index: dev/drm/sis_ds.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/sis_ds.c,v retrieving revision 1.3 diff -u -r1.3 sis_ds.c --- dev/drm/sis_ds.c 16 Apr 2005 03:44:44 -0000 1.3 +++ dev/drm/sis_ds.c 23 Nov 2005 10:13:24 -0000 @@ -1,6 +1,6 @@ /* sis_ds.c -- Private header for Direct Rendering Manager -*- linux-c -*- - * Created: Mon Jan 4 10:05:05 1999 by sclin@sis.com.tw */ -/*- + * Created: Mon Jan 4 10:05:05 1999 by sclin@sis.com.tw + * * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. * All rights reserved. * @@ -26,9 +26,11 @@ * Authors: * Sung-Ching Lin * - * $FreeBSD: src/sys/dev/drm/sis_ds.c,v 1.3 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #include "dev/drm/drmP.h" #include "dev/drm/drm.h" #include "dev/drm/sis_ds.h" Index: dev/drm/sis_ds.h =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/sis_ds.h,v retrieving revision 1.4 diff -u -r1.4 sis_ds.h --- dev/drm/sis_ds.h 16 Apr 2005 03:44:44 -0000 1.4 +++ dev/drm/sis_ds.h 23 Nov 2005 10:13:24 -0000 @@ -1,5 +1,6 @@ /* sis_ds.h -- Private header for Direct Rendering Manager -*- linux-c -*- - * Created: Mon Jan 4 10:05:05 1999 by sclin@sis.com.tw */ + * Created: Mon Jan 4 10:05:05 1999 by sclin@sis.com.tw + */ /*- * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. * All rights reserved. @@ -26,9 +27,11 @@ * Authors: * Sung-Ching Lin * - * $FreeBSD: src/sys/dev/drm/sis_ds.h,v 1.4 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #ifndef __SIS_DS_H__ #define __SIS_DS_H__ Index: dev/drm/sis_mm.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/sis_mm.c,v retrieving revision 1.7 diff -u -r1.7 sis_mm.c --- dev/drm/sis_mm.c 16 Apr 2005 03:44:44 -0000 1.7 +++ dev/drm/sis_mm.c 23 Nov 2005 10:13:24 -0000 @@ -1,6 +1,6 @@ /* sis_mm.c -- Private header for Direct Rendering Manager -*- linux-c -*- - * Created: Mon Jan 4 10:05:05 1999 by sclin@sis.com.tw */ -/*- + * Created: Mon Jan 4 10:05:05 1999 by sclin@sis.com.tw + * * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. * All rights reserved. * @@ -26,9 +26,11 @@ * Authors: * Sung-Ching Lin * - * $FreeBSD: src/sys/dev/drm/sis_mm.c,v 1.7 2005/04/16 03:44:44 anholt Exp $ */ +#include +__FBSDID("$FreeBSD$"); + #if defined(__linux__) && defined(CONFIG_FB_SIS) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) #include