diff options
author | Jeff Hartmann <jhartmann@valinux.com> | 2003-01-11 05:42:38 +0000 |
---|---|---|
committer | Jeff Hartmann <jhartmann@valinux.com> | 2003-01-11 05:42:38 +0000 |
commit | ced519be2077857f7b8f04daed06204af7c937dd (patch) | |
tree | 459f1cb9f4e7e8b4e78e582a37b9a9df7b4d2216 | |
parent | a1fc6af2d8937fcc4eef25119d777e168e62b2ea (diff) |
Initial Checkin for agp 3.0 infrastructure support.
-rw-r--r-- | linux-core/drmP.h | 41 | ||||
-rw-r--r-- | linux-core/drm_agpsupport.c | 574 | ||||
-rw-r--r-- | linux-core/drm_bufs.c | 21 | ||||
-rw-r--r-- | linux-core/drm_drv.c | 20 | ||||
-rw-r--r-- | linux-core/drm_memory.h | 18 | ||||
-rw-r--r-- | linux-core/drm_vm.c | 6 | ||||
-rw-r--r-- | linux/agp_30_symbols.h | 109 | ||||
-rw-r--r-- | linux/drm.h | 111 | ||||
-rw-r--r-- | linux/drmP.h | 41 | ||||
-rw-r--r-- | linux/drm_agpsupport.h | 574 | ||||
-rw-r--r-- | linux/drm_bufs.h | 21 | ||||
-rw-r--r-- | linux/drm_drv.h | 20 | ||||
-rw-r--r-- | linux/drm_memory.h | 18 | ||||
-rw-r--r-- | linux/drm_vm.h | 6 | ||||
-rw-r--r-- | linux/gamma.h | 2 | ||||
-rw-r--r-- | linux/gamma_drm.h | 10 | ||||
-rw-r--r-- | linux/i810.h | 2 | ||||
-rw-r--r-- | linux/sis.h | 4 | ||||
-rw-r--r-- | shared-core/drm.h | 111 | ||||
-rw-r--r-- | shared/drm.h | 111 |
20 files changed, 1593 insertions, 227 deletions
diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 004f9637..a898068b 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -496,6 +496,10 @@ typedef struct drm_agp_head { int agp_mtrr; int cant_use_aperture; unsigned long page_mask; + int context; + struct list_head *agp_extended_info; + int num_ctxs; + int agp_page_shift; } drm_agp_head_t; #endif @@ -699,10 +703,10 @@ extern void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size) extern void DRM(ioremapfree)(void *pt, unsigned long size); #if __REALLY_HAVE_AGP -extern agp_memory *DRM(alloc_agp)(int pages, u32 type); -extern int DRM(free_agp)(agp_memory *handle, int pages); -extern int DRM(bind_agp)(agp_memory *handle, unsigned int start); -extern int DRM(unbind_agp)(agp_memory *handle); +extern agp_memory *DRM(alloc_agp)(drm_device_t *dev, int pages, u32 type); +extern int DRM(free_agp)(drm_device_t *dev, agp_memory *handle, int pages); +extern int DRM(bind_agp)(drm_device_t *dev, agp_memory *handle, unsigned int start); +extern int DRM(unbind_agp)(drm_device_t *dev, agp_memory *handle); #endif /* Misc. IOCTL support (drm_ioctl.h) */ @@ -880,10 +884,31 @@ extern int DRM(agp_unbind)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int DRM(agp_bind)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -extern agp_memory *DRM(agp_allocate_memory)(size_t pages, u32 type); -extern int DRM(agp_free_memory)(agp_memory *handle); -extern int DRM(agp_bind_memory)(agp_memory *handle, off_t start); -extern int DRM(agp_unbind_memory)(agp_memory *handle); +extern agp_memory *DRM(agp_allocate_memory)(drm_device_t *dev, + size_t pages, u32 type); +extern int DRM(agp_free_memory)(drm_device_t *dev, + agp_memory *handle); +extern int DRM(agp_bind_memory)(drm_device_t *dev, + agp_memory *handle, off_t start); +extern int DRM(agp_unbind_memory)(drm_device_t *dev, + agp_memory *handle); +/* New functionality provided by agp 3.0 infrastructure. */ +extern int DRM(agp_supports_vma_map)(void); +extern int DRM(agp_usermap)(drm_device_t *dev, drm_map_t *map, + struct vm_area_struct *vma); +extern int DRM(agp_getmap)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int DRM(agp_e_info)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int DRM(agp_e_size)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int DRM(agp_no_ctxs)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int DRM(agp_chg_ctx)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); + + + #endif /* Stub support (drm_stub.h) */ diff --git a/linux-core/drm_agpsupport.c b/linux-core/drm_agpsupport.c index 6d6b5911..8666c859 100644 --- a/linux-core/drm_agpsupport.c +++ b/linux-core/drm_agpsupport.c @@ -30,15 +30,484 @@ */ #define __NO_VERSION__ +/* Cheat, check for an agp 3.0 include symbol after including agp_backend.h + * if its not there, define what we need. + */ +#include "agp_30_symbols.h" #include "drmP.h" + #include <linux/module.h> #if __REALLY_HAVE_AGP #define DRM_AGP_GET (drm_agp_t *)inter_module_get("drm_agp") #define DRM_AGP_PUT inter_module_put("drm_agp") +#define DRM_AGP_GET_3_0 (drm_agp_3_0_t *)inter_module_get("drm_agp_3_0") +#define DRM_AGP_PUT_3_0 do { inter_module_put("drm_agp_3_0"); drm_agp_3_0 = NULL; } while(0) static const drm_agp_t *drm_agp = NULL; +static const drm_agp_3_0_t *drm_agp_3_0 = NULL; + +/* Jeff Hartmann - Rearranged slightly to make supporting the agp 3.0 + * infrastructure a little easier. The kernel functions are provided + * at the top of the file, while the ioctls are at the bottom. + */ +int DRM(agp_supports_vma_map)(void) +{ + if(drm_agp_3_0 && drm_agp_3_0->vma_map_memory) return 1; + return 0; +} + +int DRM(agp_usermap)(drm_device_t *dev, drm_map_t *map, + struct vm_area_struct *vma) +{ + drm_agp_mem_t *entry = (drm_agp_mem_t *)map->handle; + + return drm_agp_3_0->vma_map_memory(dev->agp->context, + vma, + entry->memory, + 0); +} + +static int DRM(agp_has_copy)(void) +{ + printk("%s\n", __func__); + if(drm_agp && drm_agp->copy_info) return 1; + if(drm_agp_3_0 && drm_agp_3_0->copy_info) return 1; + return 0; +} + +static int DRM(agp_has_enable)(void) +{ + printk("%s\n", __func__); + if(drm_agp && drm_agp->enable) return 1; + if(drm_agp_3_0 && drm_agp_3_0->enable) return 1; + return 0; +} + +static int DRM(agp_has_acquire)(void) +{ + printk("%s\n", __func__); + if(drm_agp && drm_agp->acquire) return 1; + if(drm_agp_3_0 && drm_agp_3_0->acquire) return 1; + return 0; +} + +static int DRM(agp_has_release)(void) +{ + printk("%s\n", __func__); + if(drm_agp && drm_agp->release) return 1; + if(drm_agp_3_0 && drm_agp_3_0->release) return 1; + return 0; +} + +static void DRM(agp_call_release)(drm_device_t *dev) +{ + printk("%s\n", __func__); + if(drm_agp) drm_agp->release(); + else if (drm_agp_3_0) drm_agp_3_0->release(dev->agp->context); +} + +static void DRM(agp_call_enable)(drm_device_t *dev, drm_agp_mode_t *mode) +{ + printk("%s\n", __func__); + if(drm_agp) drm_agp->enable(mode->mode); + else if(drm_agp_3_0) drm_agp_3_0->enable(dev->agp->context, mode->mode); +} + +static int DRM(agp_call_acquire)(drm_device_t *dev) +{ + printk("%s\n", __func__); + if(drm_agp) return drm_agp->acquire(); + else if(drm_agp_3_0) return drm_agp_3_0->acquire(dev->agp->context); + return -EINVAL; +} + +/* Revisit when we support more then one agp context. */ +void DRM(agp_do_release)(void) +{ + printk("%s\n", __func__); + if(drm_agp && drm_agp->release) drm_agp->release(); + else if(drm_agp_3_0 && drm_agp_3_0->release) drm_agp_3_0->release(0); +} + +agp_memory *DRM(agp_allocate_memory)(drm_device_t *dev, size_t pages, u32 type) +{ + printk("%s 0\n", __func__); + if(drm_agp) { + printk("%s 0\n", __func__); + if (!drm_agp->allocate_memory) return NULL; + printk("%s 0\n", __func__); + return drm_agp->allocate_memory(pages, type); + } else if (drm_agp_3_0) { + agp_memory *mem; + + printk("%s 1\n", __func__); + if (!drm_agp_3_0->allocate_memory) return NULL; + printk("%s 2\n", __func__); + mem = drm_agp_3_0->allocate_memory(dev->agp->context, + pages, type); + printk("drm_agp_3_0 : %p, mem : %p\n", drm_agp_3_0, mem); + return mem; + } + return NULL; +} + +int DRM(agp_free_memory)(drm_device_t *dev, agp_memory *handle) +{ + printk("%s\n", __func__); + if(drm_agp) { + if (!handle || !drm_agp->free_memory) return 0; + drm_agp->free_memory(handle); + } else if (drm_agp_3_0) { + if (!handle || !drm_agp_3_0->free_memory) return 0; + drm_agp_3_0->free_memory(dev->agp->context, handle); + } else { + return 0; + } + return 1; +} + +int DRM(agp_bind_memory)(drm_device_t *dev, agp_memory *handle, off_t start) +{ + printk("%s\n", __func__); + if(drm_agp) { + if (!handle || !drm_agp->bind_memory) return -EINVAL; + return drm_agp->bind_memory(handle, start); + } else if(drm_agp_3_0) { + if (!handle || !drm_agp_3_0->bind_memory) return -EINVAL; + return drm_agp_3_0->bind_memory(dev->agp->context, handle, start); + } + return -EINVAL; +} + +int DRM(agp_unbind_memory)(drm_device_t *dev, agp_memory *handle) +{ + printk("%s\n", __func__); + if(drm_agp) { + if (!handle || !drm_agp->unbind_memory) return -EINVAL; + return drm_agp->unbind_memory(handle); + } else if(drm_agp_3_0) { + if (!handle || !drm_agp_3_0->unbind_memory) return -EINVAL; + return drm_agp_3_0->unbind_memory(dev->agp->context, handle); + } + return -EINVAL; +} + +drm_agp_mem_t *DRM(agp_lookup_entry)(drm_device_t *dev, + unsigned long handle) +{ + drm_agp_mem_t *entry; + + printk("%s\n", __func__); + + if(!dev->agp) return NULL; + for(entry = dev->agp->memory; entry; entry = entry->next) { + if (entry->handle == handle) return entry; + } + return NULL; +} + +static drm_agp_head_t *DRM(agp_init_old)(void) +{ + drm_agp_head_t *head = NULL; + + drm_agp = DRM_AGP_GET; + if (drm_agp) { + if (!(head = DRM(alloc)(sizeof(*head), DRM_MEM_AGPLISTS))) + return NULL; + memset((void *)head, 0, sizeof(*head)); + drm_agp->copy_info(&head->agp_info); + if (head->agp_info.chipset == NOT_SUPPORTED) { + DRM(free)(head, sizeof(*head), DRM_MEM_AGPLISTS); + return NULL; + } + head->memory = NULL; +#if LINUX_VERSION_CODE <= 0x020408 + head->cant_use_aperture = 0; + head->page_mask = ~(0xfff); +#else + head->cant_use_aperture = head->agp_info.cant_use_aperture; + head->page_mask = head->agp_info.page_mask; +#endif + head->context = 0; + head->agp_extended_info = NULL; + head->agp_page_shift = 12; + + DRM_DEBUG("AGP %d.%d, aperture @ 0x%08lx %ZuMB\n", + head->agp_info.version.major, + head->agp_info.version.minor, + head->agp_info.aper_base, + head->agp_info.aper_size); + } + return head; +} +#if __TRY_AGP_3_0 != 0 +static drm_agp_head_t *DRM(agp_init_3_0)(void) +{ + drm_agp_head_t *head = NULL; + + drm_agp_3_0 = DRM_AGP_GET_3_0; + if (drm_agp_3_0) { + if (!(head = DRM(alloc)(sizeof(*head), DRM_MEM_AGPLISTS))) { + DRM_AGP_PUT_3_0; + return NULL; + } + memset((void *)head, 0, sizeof(*head)); + + head->agp_extended_info = drm_agp_3_0->get_info_list(); + if(!head->agp_extended_info) { + DRM(free)(head, sizeof(*head), DRM_MEM_AGPLISTS); + DRM_AGP_PUT_3_0; + return NULL; + } + head->num_ctxs = drm_agp_3_0->get_num_contexts(); + drm_agp_3_0->copy_info(0, &head->agp_info); + if (head->agp_info.chipset == NOT_SUPPORTED) { + DRM(free)(head, sizeof(*head), DRM_MEM_AGPLISTS); + DRM_AGP_PUT_3_0; + return NULL; + } + head->memory = NULL; +#if LINUX_VERSION_CODE <= 0x020408 + head->cant_use_aperture = 0; + head->page_mask = ~(0xfff); +#else + head->cant_use_aperture = head->agp_info.cant_use_aperture; + head->page_mask = head->agp_info.page_mask; +#endif + /* Not completely kosher. */ + head->agp_page_shift = 12; + head->context = 0; + DRM_DEBUG("AGP 3.0 - %d.%d, aperture @ 0x%08lx %ZuMB\n", + head->agp_info.version.major, + head->agp_info.version.minor, + head->agp_info.aper_base, + head->agp_info.aper_size); + } + return head; +} +#endif + +#if __TRY_AGP_3_0 == 0 +drm_agp_head_t *DRM(agp_init)(void) +{ + return DRM(agp_init_old)(); +} +#else +drm_agp_head_t *DRM(agp_init)(void) +{ + drm_agp_head_t *head; + + head = DRM(agp_init_3_0)(); + if(!head) head = DRM(agp_init_old)(); + return head; +} +#endif + +void DRM(agp_uninit)(void) +{ + if(drm_agp) { + DRM_AGP_PUT; + drm_agp = NULL; + } + if(drm_agp_3_0) { + DRM_AGP_PUT_3_0; + drm_agp_3_0 = NULL; + } +} + +/* Ioctls are provided below */ +int DRM(agp_getmap)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_agp_buffer_info_t info; + drm_agp_mem_t *mem; + agp_memory *agp_mem = NULL; + int ret = 0; + + if(!drm_agp_3_0) return -EINVAL; + + if (copy_from_user(&info, (drm_agp_buffer_info_t *)arg, sizeof(info))) + return -EFAULT; + + mem = DRM(agp_lookup_entry)(dev, info.handle); + if(mem) { + agp_mem = mem->memory; + } else if(drm_agp_3_0->get_map) { + ret = drm_agp_3_0->get_map(dev->agp->context, + (int)info.handle, + &agp_mem); + if(ret) return ret; + } + if(!agp_mem) return -EINVAL; + info.size = agp_mem->page_count << dev->agp->agp_page_shift; + info.type = (unsigned long)agp_mem->type; + info.physical = (unsigned long)agp_mem->physical; + info.offset = (unsigned long)agp_mem->pg_start << + dev->agp->agp_page_shift; + + if (copy_to_user((drm_agp_buffer_info_t *)arg, &info, sizeof(info))) + return -EFAULT; + return 0; +} + +static void DRM(agp_fill_master)(drm_agp_master_t *master, + agp_info_master *info) +{ + master->agp_major_version = info->agp_major_version; + master->agp_minor_version = info->agp_minor_version; + master->vendor_pci_id = info->device->vendor; + master->device_pci_id = info->device->device; + master->num_requests_enqueue = info->num_requests_enqueue; + master->calibration_cycle_ms = info->calibration_cycle_ms; + master->max_bandwidth_bpp = info->max_bandwidth_bpp; + master->num_trans_per_period = info->num_trans_per_period; + master->max_requests = info->max_requests; + master->payload_size = info->payload_size; + master->flags = info->flags; +} + +static void DRM(agp_fill_driver)(drm_agp_driver_info_t *driver, + agp_extended_info *info) +{ + driver->driver_flags = info->driver_flags; + driver->agp_major_version = info->bridge->agp_major_version; + driver->agp_minor_version = info->bridge->agp_minor_version; + driver->num_requests_enqueue = info->bridge->num_requests_enqueue; + driver->calibration_cycle_ms = info->bridge->calibration_cycle_ms; + driver->optimum_request_size = info->bridge->optimum_request_size; + driver->max_bandwidth_bpp = info->bridge->max_bandwidth_bpp; + driver->iso_latency_in_periods = info->bridge->iso_latency_in_periods; + driver->num_trans_per_period = info->bridge->num_trans_per_period; + driver->payload_size = info->bridge->payload_size; + driver->target_device_pci_id = info->bridge->device->device; + driver->target_vendor_pci_id = info->bridge->device->vendor; + driver->target_flags = info->bridge->flags; + driver->aper_base = info->aper_base; + driver->aper_size = info->aper_size; + driver->agp_page_shift = info->agp_page_shift; + driver->agp_page_mask = info->agp_page_mask; + driver->alloc_page_shift = info->alloc_page_shift; + driver->alloc_page_mask = info->alloc_page_mask; + driver->max_system_pages = info->max_system_pages; + driver->current_memory = info->current_memory; + driver->num_masters = info->num_masters; + driver->context_id = info->agp_ctxt_idx; +} + +int DRM(agp_e_info)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + agp_extended_info *info = NULL; + struct list_head *ptr; + int length = 1; + drm_agp_driver_info_t driver; + drm_agp_master_t master; + char *empty = "\0"; + char *pos = (char *)arg; + + if(!drm_agp_3_0) return -EINVAL; + + list_for_each(ptr, dev->agp->agp_extended_info) { + info = list_entry(ptr, agp_extended_info, info_list); + if(info->agp_ctxt_idx == dev->agp->context) break; + info = NULL; + } + if(!info) return -EINVAL; + if(info->driver_name) { + length = strlen(info->driver_name) + 1; + } else { + info->driver_name = empty; + } + DRM(agp_fill_driver)(&driver, info); + pos += sizeof(driver); + driver.driver_name = pos; + if(info->num_masters) { + driver.masters = (drm_agp_master_t *)(pos + length); + } else { + driver.masters = NULL; + } + + if(copy_to_user((void *)arg, &driver, sizeof(driver))) { + if(info->driver_name == empty) info->driver_name = NULL; + return -EFAULT; + } + if(copy_to_user((void *)pos, info->driver_name, length)) { + if(info->driver_name == empty) info->driver_name = NULL; + return -EFAULT; + } + pos += length; + list_for_each(ptr, &info->master_list) { + agp_info_master *minfo = list_entry(ptr, + agp_info_master, + masters); + DRM(agp_fill_master)(&master, minfo); + if(copy_to_user((void *)pos, + &master, sizeof(master))) { + if(info->driver_name == empty) + info->driver_name = NULL; + return -EFAULT; + } + pos += sizeof(master); + } + + if(info->driver_name == empty) info->driver_name = NULL; + return 0; +} + +int DRM(agp_e_size)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + agp_extended_info *info = NULL; + struct list_head *ptr; + int size = 0; + + if(!drm_agp_3_0) return -EINVAL; + + list_for_each(ptr, dev->agp->agp_extended_info) { + info = list_entry(ptr, agp_extended_info, info_list); + if(info->agp_ctxt_idx == dev->agp->context) break; + info = NULL; + } + + if(!info) return -EINVAL; + size = sizeof(drm_agp_driver_info_t); + size += sizeof(drm_agp_master_t) * info->num_masters; + if(info->driver_name) size += strlen(info->driver_name) + 1; + else size += 1; + + return size; +} + +int DRM(agp_no_ctxs)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + + if(!drm_agp_3_0) return -EINVAL; + return dev->agp->num_ctxs; +} + +/* Really a no-op for now. */ +int DRM(agp_chg_ctx)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + + if(!drm_agp_3_0 || arg >= dev->agp->num_ctxs || + arg < 0) return -EINVAL; + + return 0; +} int DRM(agp_info)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) @@ -48,7 +517,7 @@ int DRM(agp_info)(struct inode *inode, struct file *filp, agp_kern_info *kern; drm_agp_info_t info; - if (!dev->agp || !dev->agp->acquired || !drm_agp->copy_info) + if (!dev->agp || !dev->agp->acquired || !DRM(agp_has_copy)()) return -EINVAL; kern = &dev->agp->agp_info; @@ -74,9 +543,9 @@ int DRM(agp_acquire)(struct inode *inode, struct file *filp, drm_device_t *dev = priv->dev; int retcode; - if (!dev->agp || dev->agp->acquired || !drm_agp->acquire) + if (!dev->agp || dev->agp->acquired || !DRM(agp_has_acquire)()) return -EINVAL; - if ((retcode = drm_agp->acquire())) return retcode; + if ((retcode = DRM(agp_call_acquire)(dev))) return retcode; dev->agp->acquired = 1; return 0; } @@ -87,19 +556,14 @@ int DRM(agp_release)(struct inode *inode, struct file *filp, drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; - if (!dev->agp || !dev->agp->acquired || !drm_agp->release) + if (!dev->agp || !dev->agp->acquired || !DRM(agp_has_release)()) return -EINVAL; - drm_agp->release(); + DRM(agp_call_release)(dev); dev->agp->acquired = 0; return 0; } -void DRM(agp_do_release)(void) -{ - if (drm_agp->release) drm_agp->release(); -} - int DRM(agp_enable)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -107,14 +571,14 @@ int DRM(agp_enable)(struct inode *inode, struct file *filp, drm_device_t *dev = priv->dev; drm_agp_mode_t mode; - if (!dev->agp || !dev->agp->acquired || !drm_agp->enable) + if (!dev->agp || !dev->agp->acquired || !DRM(agp_has_enable)()) return -EINVAL; if (copy_from_user(&mode, (drm_agp_mode_t *)arg, sizeof(mode))) return -EFAULT; dev->agp->mode = mode.mode; - drm_agp->enable(mode.mode); + DRM(agp_call_enable)(dev, &mode); dev->agp->base = dev->agp->agp_info.aper_base; dev->agp->enabled = 1; return 0; @@ -142,7 +606,7 @@ int DRM(agp_alloc)(struct inode *inode, struct file *filp, pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE; type = (u32) request.type; - if (!(memory = DRM(alloc_agp)(pages, type))) { + if (!(memory = DRM(alloc_agp)(dev, pages, type))) { DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS); return -ENOMEM; } @@ -162,24 +626,13 @@ int DRM(agp_alloc)(struct inode *inode, struct file *filp, if (copy_to_user((drm_agp_buffer_t *)arg, &request, sizeof(request))) { dev->agp->memory = entry->next; dev->agp->memory->prev = NULL; - DRM(free_agp)(memory, pages); + DRM(free_agp)(dev, memory, pages); DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS); return -EFAULT; } return 0; } -static drm_agp_mem_t *DRM(agp_lookup_entry)(drm_device_t *dev, - unsigned long handle) -{ - drm_agp_mem_t *entry; - - for (entry = dev->agp->memory; entry; entry = entry->next) { - if (entry->handle == handle) return entry; - } - return NULL; -} - int DRM(agp_unbind)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -194,7 +647,7 @@ int DRM(agp_unbind)(struct inode *inode, struct file *filp, if (!(entry = DRM(agp_lookup_entry)(dev, request.handle))) return -EINVAL; if (!entry->bound) return -EINVAL; - return DRM(unbind_agp)(entry->memory); + return DRM(unbind_agp)(dev, entry->memory); } int DRM(agp_bind)(struct inode *inode, struct file *filp, @@ -215,7 +668,7 @@ int DRM(agp_bind)(struct inode *inode, struct file *filp, return -EINVAL; if (entry->bound) return -EINVAL; page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE; - if ((retcode = DRM(bind_agp)(entry->memory, page))) return retcode; + if ((retcode = DRM(bind_agp)(dev, entry->memory, page))) return retcode; entry->bound = dev->agp->base + (page << PAGE_SHIFT); DRM_DEBUG("base = 0x%lx entry->bound = 0x%lx\n", dev->agp->base, entry->bound); @@ -235,77 +688,14 @@ int DRM(agp_free)(struct inode *inode, struct file *filp, return -EFAULT; if (!(entry = DRM(agp_lookup_entry)(dev, request.handle))) return -EINVAL; - if (entry->bound) DRM(unbind_agp)(entry->memory); + if (entry->bound) DRM(unbind_agp)(dev, entry->memory); if (entry->prev) entry->prev->next = entry->next; else dev->agp->memory = entry->next; if (entry->next) entry->next->prev = entry->prev; - DRM(free_agp)(entry->memory, entry->pages); + DRM(free_agp)(dev, entry->memory, entry->pages); DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS); return 0; } -drm_agp_head_t *DRM(agp_init)(void) -{ - drm_agp_head_t *head = NULL; - - drm_agp = DRM_AGP_GET; - if (drm_agp) { - if (!(head = DRM(alloc)(sizeof(*head), DRM_MEM_AGPLISTS))) - return NULL; - memset((void *)head, 0, sizeof(*head)); - drm_agp->copy_info(&head->agp_info); - if (head->agp_info.chipset == NOT_SUPPORTED) { - DRM(free)(head, sizeof(*head), DRM_MEM_AGPLISTS); - return NULL; - } - head->memory = NULL; -#if LINUX_VERSION_CODE <= 0x020408 - head->cant_use_aperture = 0; - head->page_mask = ~(0xfff); -#else - head->cant_use_aperture = head->agp_info.cant_use_aperture; - head->page_mask = head->agp_info.page_mask; -#endif - - DRM_DEBUG("AGP %d.%d, aperture @ 0x%08lx %ZuMB\n", - head->agp_info.version.major, - head->agp_info.version.minor, - head->agp_info.aper_base, - head->agp_info.aper_size); - } - return head; -} - -void DRM(agp_uninit)(void) -{ - DRM_AGP_PUT; - drm_agp = NULL; -} - -agp_memory *DRM(agp_allocate_memory)(size_t pages, u32 type) -{ - if (!drm_agp->allocate_memory) return NULL; - return drm_agp->allocate_memory(pages, type); -} - -int DRM(agp_free_memory)(agp_memory *handle) -{ - if (!handle || !drm_agp->free_memory) return 0; - drm_agp->free_memory(handle); - return 1; -} - -int DRM(agp_bind_memory)(agp_memory *handle, off_t start) -{ - if (!handle || !drm_agp->bind_memory) return -EINVAL; - return drm_agp->bind_memory(handle, start); -} - -int DRM(agp_unbind_memory)(agp_memory *handle) -{ - if (!handle || !drm_agp->unbind_memory) return -EINVAL; - return drm_agp->unbind_memory(handle); -} - #endif /* __REALLY_HAVE_AGP */ diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c index 9ce7cfff..932d7a3f 100644 --- a/linux-core/drm_bufs.c +++ b/linux-core/drm_bufs.c @@ -158,6 +158,26 @@ int DRM(addmap)( struct inode *inode, struct file *filp, map->offset = map->offset + dev->sg->handle; break; + /* The offset here is the agp memory blocks handle, try and find it + * and see if it matches. MMap can now map it using kernel routines. + */ +#if __REALLY_HAVE_AGP + case _DRM_AGP_MEM: + { + drm_agp_mem_t *entry; + + entry = DRM(agp_lookup_entry)(dev, map->offset); + if(!entry || !DRM(agp_supports_vma_map)() || + map->size > + entry->pages << dev->agp->agp_page_shift) { + DRM(free)(map, sizeof(*map), DRM_MEM_MAPS); + return -EINVAL; + } + map->offset = 0; + map->handle = entry; + } + break; +#endif default: DRM(free)( map, sizeof(*map), DRM_MEM_MAPS ); return -EINVAL; @@ -253,6 +273,7 @@ int DRM(rmmap)(struct inode *inode, struct file *filp, break; case _DRM_AGP: case _DRM_SCATTER_GATHER: + case _DRM_AGP_MEM: break; } DRM(free)(map, sizeof(*map), DRM_MEM_MAPS); diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index 3ebe7811..d8128d26 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -48,6 +48,9 @@ * #define DRM(x) mga_##x */ +#ifndef __TRY_AGP_3_0 +#define __TRY_AGP_3_0 0 +#endif #ifndef __MUST_HAVE_AGP #define __MUST_HAVE_AGP 0 #endif @@ -227,6 +230,18 @@ static drm_ioctl_desc_t DRM(ioctls)[] = { #endif DRIVER_IOCTLS + +/* Add these at the end since we are using a larger ioctl number since + * we don't have the room for this many ioctls at a lower number. + * Consider the ioctl range 0x70 -> 0x79 is reserved for agp extensions. + */ +#if __REALLY_HAVE_AGP + [DRM_IOCTL_NR(DRM_IOCTL_AGP_GETMAP)] = { DRM(agp_getmap), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_QUERY)] = { DRM(agp_e_info), 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_QUERY_SZ)] = { DRM(agp_e_size), 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_NUM_CTX)] = { DRM(agp_no_ctxs), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_CHG_CTX)] = { DRM(agp_chg_ctx), 1, 1 }, +#endif }; #define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( DRM(ioctls) ) @@ -399,8 +414,8 @@ static int DRM(takedown)( drm_device_t *dev ) intact until drv_cleanup is called. */ for ( entry = dev->agp->memory ; entry ; entry = nexte ) { nexte = entry->next; - if ( entry->bound ) DRM(unbind_agp)( entry->memory ); - DRM(free_agp)( entry->memory, entry->pages ); + if ( entry->bound ) DRM(unbind_agp)( dev, entry->memory ); + DRM(free_agp)( dev, entry->memory, entry->pages ); DRM(free)( entry, sizeof(*entry), DRM_MEM_AGPLISTS ); } dev->agp->memory = NULL; @@ -450,6 +465,7 @@ static int DRM(takedown)( drm_device_t *dev ) break; case _DRM_AGP: + case _DRM_AGP_MEM: /* Do nothing here, because this is all * handled in the AGP/GART driver. */ diff --git a/linux-core/drm_memory.h b/linux-core/drm_memory.h index 22aab7f4..da4a66f9 100644 --- a/linux-core/drm_memory.h +++ b/linux-core/drm_memory.h @@ -362,7 +362,7 @@ void DRM(ioremapfree)(void *pt, unsigned long size) #if __REALLY_HAVE_AGP -agp_memory *DRM(alloc_agp)(int pages, u32 type) +agp_memory *DRM(alloc_agp)(drm_device_t *dev, int pages, u32 type) { agp_memory *handle; @@ -371,7 +371,8 @@ agp_memory *DRM(alloc_agp)(int pages, u32 type) return NULL; } - if ((handle = DRM(agp_allocate_memory)(pages, type))) { + if ((handle = DRM(agp_allocate_memory)(dev, pages, type))) { + printk("Returning handle : %p\n", handle); spin_lock(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count; DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_allocated @@ -385,7 +386,7 @@ agp_memory *DRM(alloc_agp)(int pages, u32 type) return NULL; } -int DRM(free_agp)(agp_memory *handle, int pages) +int DRM(free_agp)(drm_device_t *dev, agp_memory *handle, int pages) { int alloc_count; int free_count; @@ -397,7 +398,7 @@ int DRM(free_agp)(agp_memory *handle, int pages) return retval;; } - if (DRM(agp_free_memory)(handle)) { + if (DRM(agp_free_memory)(dev, handle)) { spin_lock(&DRM(mem_lock)); free_count = ++DRM(mem_stats)[DRM_MEM_TOTALAGP].free_count; alloc_count = DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count; @@ -414,17 +415,18 @@ int DRM(free_agp)(agp_memory *handle, int pages) return retval; } -int DRM(bind_agp)(agp_memory *handle, unsigned int start) +int DRM(bind_agp)(drm_device_t *dev, agp_memory *handle, unsigned int start) { int retcode = -EINVAL; + printk("%s\n", __func__); if (!handle) { DRM_MEM_ERROR(DRM_MEM_BOUNDAGP, "Attempt to bind NULL AGP handle\n"); return retcode; } - if (!(retcode = DRM(agp_bind_memory)(handle, start))) { + if (!(retcode = DRM(agp_bind_memory)(dev, handle, start))) { spin_lock(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count; DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_allocated @@ -438,7 +440,7 @@ int DRM(bind_agp)(agp_memory *handle, unsigned int start) return retcode; } -int DRM(unbind_agp)(agp_memory *handle) +int DRM(unbind_agp)(drm_device_t *dev, agp_memory *handle) { int alloc_count; int free_count; @@ -450,7 +452,7 @@ int DRM(unbind_agp)(agp_memory *handle) return retcode; } - if ((retcode = DRM(agp_unbind_memory)(handle))) return retcode; + if ((retcode = DRM(agp_unbind_memory)(dev, handle))) return retcode; spin_lock(&DRM(mem_lock)); free_count = ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].free_count; alloc_count = DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count; diff --git a/linux-core/drm_vm.c b/linux-core/drm_vm.c index 683c0857..8839a840 100644 --- a/linux-core/drm_vm.c +++ b/linux-core/drm_vm.c @@ -214,6 +214,7 @@ void DRM(vm_shm_close)(struct vm_area_struct *vma) break; case _DRM_AGP: case _DRM_SCATTER_GATHER: + case _DRM_AGP_MEM: break; } DRM(free)(map, sizeof(*map), DRM_MEM_MAPS); @@ -420,6 +421,11 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma) } switch (map->type) { + case _DRM_AGP_MEM: +#if __REALLY_HAVE_AGP + /* Use agpgart to map this block of agp memory. */ + return DRM(agp_usermap)(dev, map, vma); +#endif case _DRM_AGP: #if defined(__alpha__) /* diff --git a/linux/agp_30_symbols.h b/linux/agp_30_symbols.h new file mode 100644 index 00000000..5e3b7831 --- /dev/null +++ b/linux/agp_30_symbols.h @@ -0,0 +1,109 @@ +#if defined(__linux__) +#include <linux/config.h> +#include <linux/types.h> +#include <linux/agp_backend.h> +#include <linux/list.h> + +#ifndef _AGP_EXTENDED_DEFINES +/* okay cheat, so we can compile. */ +typedef struct { + int (*get_num_contexts)(void); + struct list_head *(*get_info_list)(void); + + void (*free_memory)(int, agp_memory *); + agp_memory *(*allocate_memory)(int, size_t, u32); + int (*bind_memory)(int, agp_memory *, off_t); + int (*unbind_memory)(int, agp_memory *); + void (*enable)(int, u32); + int (*acquire)(int); + void (*release)(int); + int (*copy_info)(int, agp_kern_info *); + int (*get_map)(int, int, agp_memory **); + void *(*kmap)(int, agp_memory *, unsigned long, + unsigned long); + int (*vma_map_memory)(int, struct vm_area_struct *, + agp_memory *, unsigned long); + unsigned long (*usermap)(int, struct file *, agp_memory *, + unsigned long, unsigned long, + unsigned long, unsigned long); +} drm_agp_3_0_t; + +/* No longer report the chipset_type enum, pass a char *driver_name back + * instead since it would be more useful. + */ +typedef struct _agp_info_master { + struct list_head masters; + u8 agp_major_version; + u8 agp_minor_version; + u8 cap_ptr; + struct pci_dev *device; + int num_requests_enqueue; + int calibration_cycle_ms; /* Agp 3.0 field */ + + /* Current isochronous information : Ignore if + * AGP_SUPPORTS_ISOCHRONOUS is not set in the flags field + */ + int max_bandwidth_bpp; /* Max Bandwidth in bytes per period */ + int num_trans_per_period; + int max_requests; + int payload_size; + + u32 flags; +} agp_info_master; + +typedef struct _agp_info_target { + u8 agp_major_version; + u8 agp_minor_version; + u8 cap_ptr; + struct pci_dev *device; + int num_requests_enqueue; + int optimum_request_size; /* Agp 3.0 field */ + int calibration_cycle_ms; /* Agp 3.0 field */ + + /* Current isochronous information : Ignore if + * AGP_SUPPORTS_ISOCHRONOUS is not set in the flags field + */ + int max_bandwidth_bpp; /* Max Bandwidth in bytes per period */ + int iso_latency_in_periods; + int num_trans_per_period; + int payload_size; + + u32 flags; +} agp_info_target; + +typedef struct _agp_extended_info { + struct list_head info_list; + + /* My context id */ + int agp_ctxt_idx; + + /* Information about the target for this aperture. */ + agp_info_target *bridge; + + /* Information about all the masters using this target. */ + struct list_head master_list; + int num_masters; + + /* Agp driver information. */ + char *driver_name; + u32 driver_flags; + + /* Where this targets agp aperture is located and how big it is. */ + off_t aper_base; + size_t aper_size; + + /* Size information and mask - agp page. */ + int agp_page_shift; + unsigned long agp_page_mask; + + /* Size information and mask - alloc page. */ + int alloc_page_shift; + unsigned long alloc_page_mask; + + /* Memory limit information */ + int max_system_pages; /* The maximum number of alloc pages */ + int current_memory; /* The current number of alloc pages */ +} agp_extended_info; + +#endif +#endif diff --git a/linux/drm.h b/linux/drm.h index d1d66943..f480d82c 100644 --- a/linux/drm.h +++ b/linux/drm.h @@ -161,7 +161,8 @@ typedef enum drm_map_type { _DRM_REGISTERS = 1, /* no caching, no core dump */ _DRM_SHM = 2, /* shared, cached */ _DRM_AGP = 3, /* AGP/GART */ - _DRM_SCATTER_GATHER = 4 /* Scatter/gather memory for PCI DMA */ + _DRM_SCATTER_GATHER = 4, /* Scatter/gather memory for PCI DMA */ + _DRM_AGP_MEM = 5, /* AGP/GART memory block */ } drm_map_type_t; typedef enum drm_map_flags { @@ -375,6 +376,104 @@ typedef struct drm_agp_mode { unsigned long mode; } drm_agp_mode_t; +/* Added for agp 3.0 */ +typedef struct drm_agp_buffer_info { + unsigned long size; /* In bytes -- will round to page boundary */ + unsigned long handle; /* Used for BIND/UNBIND ioctls */ + unsigned long type; /* Type of memory to allocate */ + unsigned long physical; /* Physical used by i810 */ + unsigned long offset; /* In bytes -- will round to page boundary */ +} drm_agp_buffer_info_t; + +/* Masters and targets flags */ +#define _DRM_AGP_SUPPORTS_ISOCHRONOUS (1<<0) +#define _DRM_AGP_SUPPORTS_SBA (1<<1) +#define _DRM_AGP_SUPPORTS_AGP_3_0_ENABLED (1<<2) +#define _DRM_AGP_SUPPORTS_OVER4G_ADDR (1<<3) +#define _DRM_AGP_SUPPORTS_FAST_WRITE (1<<4) +#define _DRM_AGP_SUPPORTS_SPEED_1X (1<<5) +#define _DRM_AGP_SUPPORTS_SPEED_2X (1<<6) +#define _DRM_AGP_SUPPORTS_SPEED_4X (1<<7) +#define _DRM_AGP_SUPPORTS_SPEED_8X (1<<8) +#define _DRM_AGP_SUPPORTS_ISO_PAYLOAD_32_B (1<<9) +#define _DRM_AGP_SUPPORTS_ISO_PAYLOAD_64_B (1<<10) +#define _DRM_AGP_SUPPORTS_ISO_PAYLOAD_128_B (1<<11) +#define _DRM_AGP_SUPPORTS_ISO_PAYLOAD_256_B (1<<12) + +/* valid for targets only */ +#define _DRM_AGP_SUPPORTS_CACHED_MEMORY (1<<13) +#define _DRM_AGP_SUPPORTS_APER_MMAP (1<<14) + +/* reserved bits for future use */ +#define _DRM_AGP_SUPPORTS_RESERVED_0 (1<<15) +#define _DRM_AGP_SUPPORTS_RESERVED_1 (1<<16) +#define _DRM_AGP_SUPPORTS_RESERVED_2 (1<<17) +#define _DRM_AGP_SUPPORTS_RESERVED_3 (1<<18) +#define _DRM_AGP_SUPPORTS_RESERVED_4 (1<<19) +#define _DRM_AGP_SUPPORTS_RESERVED_5 (1<<20) +#define _DRM_AGP_SUPPORTS_RESERVED_6 (1<<21) +#define _DRM_AGP_SUPPORTS_RESERVED_7 (1<<22) +#define _DRM_AGP_SUPPORTS_RESERVED_8 (1<<23) +#define _DRM_AGP_SUPPORTS_RESERVED_9 (1<<24) +#define _DRM_AGP_SUPPORTS_RESERVED_10 (1<<25) +#define _DRM_AGP_SUPPORTS_RESERVED_11 (1<<26) +#define _DRM_AGP_SUPPORTS_RESERVED_12 (1<<27) +#define _DRM_AGP_SUPPORTS_RESERVED_13 (1<<28) +#define _DRM_AGP_SUPPORTS_RESERVED_14 (1<<29) +#define _DRM_AGP_SUPPORTS_RESERVED_15 (1<<30) +#define _DRM_AGP_SUPPORTS_RESERVED_16 (1<<31) + +/* Driver flags, all the rest of the values are reserved */ +#define _DRM_AGP_USE_AGP_3_0_MODES (1<<0) +#define _DRM_AGP_CAN_MAP_APERTURE (1<<1) +#define _DRM_AGP_MAPS_USE_CACHE_ATTRS (1<<2) +#define _DRM_AGP_CAN_DO_CACHED (1<<3) +#define _DRM_AGP_DRIVER_ACTIVE (1<<4) + +typedef struct drm_agp_master { + int agp_major_version; + int agp_minor_version; + int vendor_pci_id; + int device_pci_id; + int num_requests_enqueue; + int calibration_cycle_ms; + int max_bandwidth_bpp; + int num_trans_per_period; + int max_requests; + int payload_size; + unsigned long flags; +} drm_agp_master_t; + +typedef struct drm_agp_driver_info { + char *driver_name; /* Driver name or empty string */ + int agp_major_version; + int agp_minor_version; + int num_requests_enqueue; + int calibration_cycle_ms; + int optimum_request_size; + int max_bandwidth_bpp; + int iso_latency_in_periods; + int num_trans_per_period; + int payload_size; + int target_vendor_pci_id; + int target_device_pci_id; + unsigned long target_flags; + unsigned long driver_flags; + unsigned long aper_base; + unsigned long aper_size; + int agp_page_shift; + int alloc_page_shift; + unsigned long agp_page_mask; + unsigned long alloc_page_mask; + int max_system_pages; + int current_memory; + int context_id; + int num_masters; + drm_agp_master_t *masters; /* Pointer to array of master data + * if no masters == NULL. + */ +} drm_agp_driver_info_t; + /* For drm_agp_alloc -- allocated a buffer */ typedef struct drm_agp_buffer { unsigned long size; /* In bytes -- will round to page boundary */ @@ -471,4 +570,14 @@ typedef struct drm_scatter_gather { * The device specific ioctl range is 0x40 to 0x79. */ #define DRM_COMMAND_BASE 0x40 +/* Actually lets use 0x70 -> 0x79 for agp ioctls, not devices. We can + * always extend the ioctl numbers by providing an ioctl which calls + * an extended range of numbers. + */ +#define DRM_IOCTL_AGP_GETMAP 0x70 +#define DRM_IOCTL_AGP_QUERY 0x71 +#define DRM_IOCTL_AGP_QUERY_SZ 0x72 +#define DRM_IOCTL_AGP_NUM_CTX 0x73 +#define DRM_IOCTL_AGP_CHG_CTX 0x74 + #endif diff --git a/linux/drmP.h b/linux/drmP.h index 004f9637..a898068b 100644 --- a/linux/drmP.h +++ b/linux/drmP.h @@ -496,6 +496,10 @@ typedef struct drm_agp_head { int agp_mtrr; int cant_use_aperture; unsigned long page_mask; + int context; + struct list_head *agp_extended_info; + int num_ctxs; + int agp_page_shift; } drm_agp_head_t; #endif @@ -699,10 +703,10 @@ extern void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size) extern void DRM(ioremapfree)(void *pt, unsigned long size); #if __REALLY_HAVE_AGP -extern agp_memory *DRM(alloc_agp)(int pages, u32 type); -extern int DRM(free_agp)(agp_memory *handle, int pages); -extern int DRM(bind_agp)(agp_memory *handle, unsigned int start); -extern int DRM(unbind_agp)(agp_memory *handle); +extern agp_memory *DRM(alloc_agp)(drm_device_t *dev, int pages, u32 type); +extern int DRM(free_agp)(drm_device_t *dev, agp_memory *handle, int pages); +extern int DRM(bind_agp)(drm_device_t *dev, agp_memory *handle, unsigned int start); +extern int DRM(unbind_agp)(drm_device_t *dev, agp_memory *handle); #endif /* Misc. IOCTL support (drm_ioctl.h) */ @@ -880,10 +884,31 @@ extern int DRM(agp_unbind)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int DRM(agp_bind)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -extern agp_memory *DRM(agp_allocate_memory)(size_t pages, u32 type); -extern int DRM(agp_free_memory)(agp_memory *handle); -extern int DRM(agp_bind_memory)(agp_memory *handle, off_t start); -extern int DRM(agp_unbind_memory)(agp_memory *handle); +extern agp_memory *DRM(agp_allocate_memory)(drm_device_t *dev, + size_t pages, u32 type); +extern int DRM(agp_free_memory)(drm_device_t *dev, + agp_memory *handle); +extern int DRM(agp_bind_memory)(drm_device_t *dev, + agp_memory *handle, off_t start); +extern int DRM(agp_unbind_memory)(drm_device_t *dev, + agp_memory *handle); +/* New functionality provided by agp 3.0 infrastructure. */ +extern int DRM(agp_supports_vma_map)(void); +extern int DRM(agp_usermap)(drm_device_t *dev, drm_map_t *map, + struct vm_area_struct *vma); +extern int DRM(agp_getmap)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int DRM(agp_e_info)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int DRM(agp_e_size)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int DRM(agp_no_ctxs)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int DRM(agp_chg_ctx)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); + + + #endif /* Stub support (drm_stub.h) */ diff --git a/linux/drm_agpsupport.h b/linux/drm_agpsupport.h index 6d6b5911..8666c859 100644 --- a/linux/drm_agpsupport.h +++ b/linux/drm_agpsupport.h @@ -30,15 +30,484 @@ */ #define __NO_VERSION__ +/* Cheat, check for an agp 3.0 include symbol after including agp_backend.h + * if its not there, define what we need. + */ +#include "agp_30_symbols.h" #include "drmP.h" + #include <linux/module.h> #if __REALLY_HAVE_AGP #define DRM_AGP_GET (drm_agp_t *)inter_module_get("drm_agp") #define DRM_AGP_PUT inter_module_put("drm_agp") +#define DRM_AGP_GET_3_0 (drm_agp_3_0_t *)inter_module_get("drm_agp_3_0") +#define DRM_AGP_PUT_3_0 do { inter_module_put("drm_agp_3_0"); drm_agp_3_0 = NULL; } while(0) static const drm_agp_t *drm_agp = NULL; +static const drm_agp_3_0_t *drm_agp_3_0 = NULL; + +/* Jeff Hartmann - Rearranged slightly to make supporting the agp 3.0 + * infrastructure a little easier. The kernel functions are provided + * at the top of the file, while the ioctls are at the bottom. + */ +int DRM(agp_supports_vma_map)(void) +{ + if(drm_agp_3_0 && drm_agp_3_0->vma_map_memory) return 1; + return 0; +} + +int DRM(agp_usermap)(drm_device_t *dev, drm_map_t *map, + struct vm_area_struct *vma) +{ + drm_agp_mem_t *entry = (drm_agp_mem_t *)map->handle; + + return drm_agp_3_0->vma_map_memory(dev->agp->context, + vma, + entry->memory, + 0); +} + +static int DRM(agp_has_copy)(void) +{ + printk("%s\n", __func__); + if(drm_agp && drm_agp->copy_info) return 1; + if(drm_agp_3_0 && drm_agp_3_0->copy_info) return 1; + return 0; +} + +static int DRM(agp_has_enable)(void) +{ + printk("%s\n", __func__); + if(drm_agp && drm_agp->enable) return 1; + if(drm_agp_3_0 && drm_agp_3_0->enable) return 1; + return 0; +} + +static int DRM(agp_has_acquire)(void) +{ + printk("%s\n", __func__); + if(drm_agp && drm_agp->acquire) return 1; + if(drm_agp_3_0 && drm_agp_3_0->acquire) return 1; + return 0; +} + +static int DRM(agp_has_release)(void) +{ + printk("%s\n", __func__); + if(drm_agp && drm_agp->release) return 1; + if(drm_agp_3_0 && drm_agp_3_0->release) return 1; + return 0; +} + +static void DRM(agp_call_release)(drm_device_t *dev) +{ + printk("%s\n", __func__); + if(drm_agp) drm_agp->release(); + else if (drm_agp_3_0) drm_agp_3_0->release(dev->agp->context); +} + +static void DRM(agp_call_enable)(drm_device_t *dev, drm_agp_mode_t *mode) +{ + printk("%s\n", __func__); + if(drm_agp) drm_agp->enable(mode->mode); + else if(drm_agp_3_0) drm_agp_3_0->enable(dev->agp->context, mode->mode); +} + +static int DRM(agp_call_acquire)(drm_device_t *dev) +{ + printk("%s\n", __func__); + if(drm_agp) return drm_agp->acquire(); + else if(drm_agp_3_0) return drm_agp_3_0->acquire(dev->agp->context); + return -EINVAL; +} + +/* Revisit when we support more then one agp context. */ +void DRM(agp_do_release)(void) +{ + printk("%s\n", __func__); + if(drm_agp && drm_agp->release) drm_agp->release(); + else if(drm_agp_3_0 && drm_agp_3_0->release) drm_agp_3_0->release(0); +} + +agp_memory *DRM(agp_allocate_memory)(drm_device_t *dev, size_t pages, u32 type) +{ + printk("%s 0\n", __func__); + if(drm_agp) { + printk("%s 0\n", __func__); + if (!drm_agp->allocate_memory) return NULL; + printk("%s 0\n", __func__); + return drm_agp->allocate_memory(pages, type); + } else if (drm_agp_3_0) { + agp_memory *mem; + + printk("%s 1\n", __func__); + if (!drm_agp_3_0->allocate_memory) return NULL; + printk("%s 2\n", __func__); + mem = drm_agp_3_0->allocate_memory(dev->agp->context, + pages, type); + printk("drm_agp_3_0 : %p, mem : %p\n", drm_agp_3_0, mem); + return mem; + } + return NULL; +} + +int DRM(agp_free_memory)(drm_device_t *dev, agp_memory *handle) +{ + printk("%s\n", __func__); + if(drm_agp) { + if (!handle || !drm_agp->free_memory) return 0; + drm_agp->free_memory(handle); + } else if (drm_agp_3_0) { + if (!handle || !drm_agp_3_0->free_memory) return 0; + drm_agp_3_0->free_memory(dev->agp->context, handle); + } else { + return 0; + } + return 1; +} + +int DRM(agp_bind_memory)(drm_device_t *dev, agp_memory *handle, off_t start) +{ + printk("%s\n", __func__); + if(drm_agp) { + if (!handle || !drm_agp->bind_memory) return -EINVAL; + return drm_agp->bind_memory(handle, start); + } else if(drm_agp_3_0) { + if (!handle || !drm_agp_3_0->bind_memory) return -EINVAL; + return drm_agp_3_0->bind_memory(dev->agp->context, handle, start); + } + return -EINVAL; +} + +int DRM(agp_unbind_memory)(drm_device_t *dev, agp_memory *handle) +{ + printk("%s\n", __func__); + if(drm_agp) { + if (!handle || !drm_agp->unbind_memory) return -EINVAL; + return drm_agp->unbind_memory(handle); + } else if(drm_agp_3_0) { + if (!handle || !drm_agp_3_0->unbind_memory) return -EINVAL; + return drm_agp_3_0->unbind_memory(dev->agp->context, handle); + } + return -EINVAL; +} + +drm_agp_mem_t *DRM(agp_lookup_entry)(drm_device_t *dev, + unsigned long handle) +{ + drm_agp_mem_t *entry; + + printk("%s\n", __func__); + + if(!dev->agp) return NULL; + for(entry = dev->agp->memory; entry; entry = entry->next) { + if (entry->handle == handle) return entry; + } + return NULL; +} + +static drm_agp_head_t *DRM(agp_init_old)(void) +{ + drm_agp_head_t *head = NULL; + + drm_agp = DRM_AGP_GET; + if (drm_agp) { + if (!(head = DRM(alloc)(sizeof(*head), DRM_MEM_AGPLISTS))) + return NULL; + memset((void *)head, 0, sizeof(*head)); + drm_agp->copy_info(&head->agp_info); + if (head->agp_info.chipset == NOT_SUPPORTED) { + DRM(free)(head, sizeof(*head), DRM_MEM_AGPLISTS); + return NULL; + } + head->memory = NULL; +#if LINUX_VERSION_CODE <= 0x020408 + head->cant_use_aperture = 0; + head->page_mask = ~(0xfff); +#else + head->cant_use_aperture = head->agp_info.cant_use_aperture; + head->page_mask = head->agp_info.page_mask; +#endif + head->context = 0; + head->agp_extended_info = NULL; + head->agp_page_shift = 12; + + DRM_DEBUG("AGP %d.%d, aperture @ 0x%08lx %ZuMB\n", + head->agp_info.version.major, + head->agp_info.version.minor, + head->agp_info.aper_base, + head->agp_info.aper_size); + } + return head; +} +#if __TRY_AGP_3_0 != 0 +static drm_agp_head_t *DRM(agp_init_3_0)(void) +{ + drm_agp_head_t *head = NULL; + + drm_agp_3_0 = DRM_AGP_GET_3_0; + if (drm_agp_3_0) { + if (!(head = DRM(alloc)(sizeof(*head), DRM_MEM_AGPLISTS))) { + DRM_AGP_PUT_3_0; + return NULL; + } + memset((void *)head, 0, sizeof(*head)); + + head->agp_extended_info = drm_agp_3_0->get_info_list(); + if(!head->agp_extended_info) { + DRM(free)(head, sizeof(*head), DRM_MEM_AGPLISTS); + DRM_AGP_PUT_3_0; + return NULL; + } + head->num_ctxs = drm_agp_3_0->get_num_contexts(); + drm_agp_3_0->copy_info(0, &head->agp_info); + if (head->agp_info.chipset == NOT_SUPPORTED) { + DRM(free)(head, sizeof(*head), DRM_MEM_AGPLISTS); + DRM_AGP_PUT_3_0; + return NULL; + } + head->memory = NULL; +#if LINUX_VERSION_CODE <= 0x020408 + head->cant_use_aperture = 0; + head->page_mask = ~(0xfff); +#else + head->cant_use_aperture = head->agp_info.cant_use_aperture; + head->page_mask = head->agp_info.page_mask; +#endif + /* Not completely kosher. */ + head->agp_page_shift = 12; + head->context = 0; + DRM_DEBUG("AGP 3.0 - %d.%d, aperture @ 0x%08lx %ZuMB\n", + head->agp_info.version.major, + head->agp_info.version.minor, + head->agp_info.aper_base, + head->agp_info.aper_size); + } + return head; +} +#endif + +#if __TRY_AGP_3_0 == 0 +drm_agp_head_t *DRM(agp_init)(void) +{ + return DRM(agp_init_old)(); +} +#else +drm_agp_head_t *DRM(agp_init)(void) +{ + drm_agp_head_t *head; + + head = DRM(agp_init_3_0)(); + if(!head) head = DRM(agp_init_old)(); + return head; +} +#endif + +void DRM(agp_uninit)(void) +{ + if(drm_agp) { + DRM_AGP_PUT; + drm_agp = NULL; + } + if(drm_agp_3_0) { + DRM_AGP_PUT_3_0; + drm_agp_3_0 = NULL; + } +} + +/* Ioctls are provided below */ +int DRM(agp_getmap)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_agp_buffer_info_t info; + drm_agp_mem_t *mem; + agp_memory *agp_mem = NULL; + int ret = 0; + + if(!drm_agp_3_0) return -EINVAL; + + if (copy_from_user(&info, (drm_agp_buffer_info_t *)arg, sizeof(info))) + return -EFAULT; + + mem = DRM(agp_lookup_entry)(dev, info.handle); + if(mem) { + agp_mem = mem->memory; + } else if(drm_agp_3_0->get_map) { + ret = drm_agp_3_0->get_map(dev->agp->context, + (int)info.handle, + &agp_mem); + if(ret) return ret; + } + if(!agp_mem) return -EINVAL; + info.size = agp_mem->page_count << dev->agp->agp_page_shift; + info.type = (unsigned long)agp_mem->type; + info.physical = (unsigned long)agp_mem->physical; + info.offset = (unsigned long)agp_mem->pg_start << + dev->agp->agp_page_shift; + + if (copy_to_user((drm_agp_buffer_info_t *)arg, &info, sizeof(info))) + return -EFAULT; + return 0; +} + +static void DRM(agp_fill_master)(drm_agp_master_t *master, + agp_info_master *info) +{ + master->agp_major_version = info->agp_major_version; + master->agp_minor_version = info->agp_minor_version; + master->vendor_pci_id = info->device->vendor; + master->device_pci_id = info->device->device; + master->num_requests_enqueue = info->num_requests_enqueue; + master->calibration_cycle_ms = info->calibration_cycle_ms; + master->max_bandwidth_bpp = info->max_bandwidth_bpp; + master->num_trans_per_period = info->num_trans_per_period; + master->max_requests = info->max_requests; + master->payload_size = info->payload_size; + master->flags = info->flags; +} + +static void DRM(agp_fill_driver)(drm_agp_driver_info_t *driver, + agp_extended_info *info) +{ + driver->driver_flags = info->driver_flags; + driver->agp_major_version = info->bridge->agp_major_version; + driver->agp_minor_version = info->bridge->agp_minor_version; + driver->num_requests_enqueue = info->bridge->num_requests_enqueue; + driver->calibration_cycle_ms = info->bridge->calibration_cycle_ms; + driver->optimum_request_size = info->bridge->optimum_request_size; + driver->max_bandwidth_bpp = info->bridge->max_bandwidth_bpp; + driver->iso_latency_in_periods = info->bridge->iso_latency_in_periods; + driver->num_trans_per_period = info->bridge->num_trans_per_period; + driver->payload_size = info->bridge->payload_size; + driver->target_device_pci_id = info->bridge->device->device; + driver->target_vendor_pci_id = info->bridge->device->vendor; + driver->target_flags = info->bridge->flags; + driver->aper_base = info->aper_base; + driver->aper_size = info->aper_size; + driver->agp_page_shift = info->agp_page_shift; + driver->agp_page_mask = info->agp_page_mask; + driver->alloc_page_shift = info->alloc_page_shift; + driver->alloc_page_mask = info->alloc_page_mask; + driver->max_system_pages = info->max_system_pages; + driver->current_memory = info->current_memory; + driver->num_masters = info->num_masters; + driver->context_id = info->agp_ctxt_idx; +} + +int DRM(agp_e_info)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + agp_extended_info *info = NULL; + struct list_head *ptr; + int length = 1; + drm_agp_driver_info_t driver; + drm_agp_master_t master; + char *empty = "\0"; + char *pos = (char *)arg; + + if(!drm_agp_3_0) return -EINVAL; + + list_for_each(ptr, dev->agp->agp_extended_info) { + info = list_entry(ptr, agp_extended_info, info_list); + if(info->agp_ctxt_idx == dev->agp->context) break; + info = NULL; + } + if(!info) return -EINVAL; + if(info->driver_name) { + length = strlen(info->driver_name) + 1; + } else { + info->driver_name = empty; + } + DRM(agp_fill_driver)(&driver, info); + pos += sizeof(driver); + driver.driver_name = pos; + if(info->num_masters) { + driver.masters = (drm_agp_master_t *)(pos + length); + } else { + driver.masters = NULL; + } + + if(copy_to_user((void *)arg, &driver, sizeof(driver))) { + if(info->driver_name == empty) info->driver_name = NULL; + return -EFAULT; + } + if(copy_to_user((void *)pos, info->driver_name, length)) { + if(info->driver_name == empty) info->driver_name = NULL; + return -EFAULT; + } + pos += length; + list_for_each(ptr, &info->master_list) { + agp_info_master *minfo = list_entry(ptr, + agp_info_master, + masters); + DRM(agp_fill_master)(&master, minfo); + if(copy_to_user((void *)pos, + &master, sizeof(master))) { + if(info->driver_name == empty) + info->driver_name = NULL; + return -EFAULT; + } + pos += sizeof(master); + } + + if(info->driver_name == empty) info->driver_name = NULL; + return 0; +} + +int DRM(agp_e_size)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + agp_extended_info *info = NULL; + struct list_head *ptr; + int size = 0; + + if(!drm_agp_3_0) return -EINVAL; + + list_for_each(ptr, dev->agp->agp_extended_info) { + info = list_entry(ptr, agp_extended_info, info_list); + if(info->agp_ctxt_idx == dev->agp->context) break; + info = NULL; + } + + if(!info) return -EINVAL; + size = sizeof(drm_agp_driver_info_t); + size += sizeof(drm_agp_master_t) * info->num_masters; + if(info->driver_name) size += strlen(info->driver_name) + 1; + else size += 1; + + return size; +} + +int DRM(agp_no_ctxs)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + + if(!drm_agp_3_0) return -EINVAL; + return dev->agp->num_ctxs; +} + +/* Really a no-op for now. */ +int DRM(agp_chg_ctx)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + + if(!drm_agp_3_0 || arg >= dev->agp->num_ctxs || + arg < 0) return -EINVAL; + + return 0; +} int DRM(agp_info)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) @@ -48,7 +517,7 @@ int DRM(agp_info)(struct inode *inode, struct file *filp, agp_kern_info *kern; drm_agp_info_t info; - if (!dev->agp || !dev->agp->acquired || !drm_agp->copy_info) + if (!dev->agp || !dev->agp->acquired || !DRM(agp_has_copy)()) return -EINVAL; kern = &dev->agp->agp_info; @@ -74,9 +543,9 @@ int DRM(agp_acquire)(struct inode *inode, struct file *filp, drm_device_t *dev = priv->dev; int retcode; - if (!dev->agp || dev->agp->acquired || !drm_agp->acquire) + if (!dev->agp || dev->agp->acquired || !DRM(agp_has_acquire)()) return -EINVAL; - if ((retcode = drm_agp->acquire())) return retcode; + if ((retcode = DRM(agp_call_acquire)(dev))) return retcode; dev->agp->acquired = 1; return 0; } @@ -87,19 +556,14 @@ int DRM(agp_release)(struct inode *inode, struct file *filp, drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; - if (!dev->agp || !dev->agp->acquired || !drm_agp->release) + if (!dev->agp || !dev->agp->acquired || !DRM(agp_has_release)()) return -EINVAL; - drm_agp->release(); + DRM(agp_call_release)(dev); dev->agp->acquired = 0; return 0; } -void DRM(agp_do_release)(void) -{ - if (drm_agp->release) drm_agp->release(); -} - int DRM(agp_enable)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -107,14 +571,14 @@ int DRM(agp_enable)(struct inode *inode, struct file *filp, drm_device_t *dev = priv->dev; drm_agp_mode_t mode; - if (!dev->agp || !dev->agp->acquired || !drm_agp->enable) + if (!dev->agp || !dev->agp->acquired || !DRM(agp_has_enable)()) return -EINVAL; if (copy_from_user(&mode, (drm_agp_mode_t *)arg, sizeof(mode))) return -EFAULT; dev->agp->mode = mode.mode; - drm_agp->enable(mode.mode); + DRM(agp_call_enable)(dev, &mode); dev->agp->base = dev->agp->agp_info.aper_base; dev->agp->enabled = 1; return 0; @@ -142,7 +606,7 @@ int DRM(agp_alloc)(struct inode *inode, struct file *filp, pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE; type = (u32) request.type; - if (!(memory = DRM(alloc_agp)(pages, type))) { + if (!(memory = DRM(alloc_agp)(dev, pages, type))) { DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS); return -ENOMEM; } @@ -162,24 +626,13 @@ int DRM(agp_alloc)(struct inode *inode, struct file *filp, if (copy_to_user((drm_agp_buffer_t *)arg, &request, sizeof(request))) { dev->agp->memory = entry->next; dev->agp->memory->prev = NULL; - DRM(free_agp)(memory, pages); + DRM(free_agp)(dev, memory, pages); DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS); return -EFAULT; } return 0; } -static drm_agp_mem_t *DRM(agp_lookup_entry)(drm_device_t *dev, - unsigned long handle) -{ - drm_agp_mem_t *entry; - - for (entry = dev->agp->memory; entry; entry = entry->next) { - if (entry->handle == handle) return entry; - } - return NULL; -} - int DRM(agp_unbind)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -194,7 +647,7 @@ int DRM(agp_unbind)(struct inode *inode, struct file *filp, if (!(entry = DRM(agp_lookup_entry)(dev, request.handle))) return -EINVAL; if (!entry->bound) return -EINVAL; - return DRM(unbind_agp)(entry->memory); + return DRM(unbind_agp)(dev, entry->memory); } int DRM(agp_bind)(struct inode *inode, struct file *filp, @@ -215,7 +668,7 @@ int DRM(agp_bind)(struct inode *inode, struct file *filp, return -EINVAL; if (entry->bound) return -EINVAL; page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE; - if ((retcode = DRM(bind_agp)(entry->memory, page))) return retcode; + if ((retcode = DRM(bind_agp)(dev, entry->memory, page))) return retcode; entry->bound = dev->agp->base + (page << PAGE_SHIFT); DRM_DEBUG("base = 0x%lx entry->bound = 0x%lx\n", dev->agp->base, entry->bound); @@ -235,77 +688,14 @@ int DRM(agp_free)(struct inode *inode, struct file *filp, return -EFAULT; if (!(entry = DRM(agp_lookup_entry)(dev, request.handle))) return -EINVAL; - if (entry->bound) DRM(unbind_agp)(entry->memory); + if (entry->bound) DRM(unbind_agp)(dev, entry->memory); if (entry->prev) entry->prev->next = entry->next; else dev->agp->memory = entry->next; if (entry->next) entry->next->prev = entry->prev; - DRM(free_agp)(entry->memory, entry->pages); + DRM(free_agp)(dev, entry->memory, entry->pages); DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS); return 0; } -drm_agp_head_t *DRM(agp_init)(void) -{ - drm_agp_head_t *head = NULL; - - drm_agp = DRM_AGP_GET; - if (drm_agp) { - if (!(head = DRM(alloc)(sizeof(*head), DRM_MEM_AGPLISTS))) - return NULL; - memset((void *)head, 0, sizeof(*head)); - drm_agp->copy_info(&head->agp_info); - if (head->agp_info.chipset == NOT_SUPPORTED) { - DRM(free)(head, sizeof(*head), DRM_MEM_AGPLISTS); - return NULL; - } - head->memory = NULL; -#if LINUX_VERSION_CODE <= 0x020408 - head->cant_use_aperture = 0; - head->page_mask = ~(0xfff); -#else - head->cant_use_aperture = head->agp_info.cant_use_aperture; - head->page_mask = head->agp_info.page_mask; -#endif - - DRM_DEBUG("AGP %d.%d, aperture @ 0x%08lx %ZuMB\n", - head->agp_info.version.major, - head->agp_info.version.minor, - head->agp_info.aper_base, - head->agp_info.aper_size); - } - return head; -} - -void DRM(agp_uninit)(void) -{ - DRM_AGP_PUT; - drm_agp = NULL; -} - -agp_memory *DRM(agp_allocate_memory)(size_t pages, u32 type) -{ - if (!drm_agp->allocate_memory) return NULL; - return drm_agp->allocate_memory(pages, type); -} - -int DRM(agp_free_memory)(agp_memory *handle) -{ - if (!handle || !drm_agp->free_memory) return 0; - drm_agp->free_memory(handle); - return 1; -} - -int DRM(agp_bind_memory)(agp_memory *handle, off_t start) -{ - if (!handle || !drm_agp->bind_memory) return -EINVAL; - return drm_agp->bind_memory(handle, start); -} - -int DRM(agp_unbind_memory)(agp_memory *handle) -{ - if (!handle || !drm_agp->unbind_memory) return -EINVAL; - return drm_agp->unbind_memory(handle); -} - #endif /* __REALLY_HAVE_AGP */ diff --git a/linux/drm_bufs.h b/linux/drm_bufs.h index 9ce7cfff..932d7a3f 100644 --- a/linux/drm_bufs.h +++ b/linux/drm_bufs.h @@ -158,6 +158,26 @@ int DRM(addmap)( struct inode *inode, struct file *filp, map->offset = map->offset + dev->sg->handle; break; + /* The offset here is the agp memory blocks handle, try and find it + * and see if it matches. MMap can now map it using kernel routines. + */ +#if __REALLY_HAVE_AGP + case _DRM_AGP_MEM: + { + drm_agp_mem_t *entry; + + entry = DRM(agp_lookup_entry)(dev, map->offset); + if(!entry || !DRM(agp_supports_vma_map)() || + map->size > + entry->pages << dev->agp->agp_page_shift) { + DRM(free)(map, sizeof(*map), DRM_MEM_MAPS); + return -EINVAL; + } + map->offset = 0; + map->handle = entry; + } + break; +#endif default: DRM(free)( map, sizeof(*map), DRM_MEM_MAPS ); return -EINVAL; @@ -253,6 +273,7 @@ int DRM(rmmap)(struct inode *inode, struct file *filp, break; case _DRM_AGP: case _DRM_SCATTER_GATHER: + case _DRM_AGP_MEM: break; } DRM(free)(map, sizeof(*map), DRM_MEM_MAPS); diff --git a/linux/drm_drv.h b/linux/drm_drv.h index 3ebe7811..d8128d26 100644 --- a/linux/drm_drv.h +++ b/linux/drm_drv.h @@ -48,6 +48,9 @@ * #define DRM(x) mga_##x */ +#ifndef __TRY_AGP_3_0 +#define __TRY_AGP_3_0 0 +#endif #ifndef __MUST_HAVE_AGP #define __MUST_HAVE_AGP 0 #endif @@ -227,6 +230,18 @@ static drm_ioctl_desc_t DRM(ioctls)[] = { #endif DRIVER_IOCTLS + +/* Add these at the end since we are using a larger ioctl number since + * we don't have the room for this many ioctls at a lower number. + * Consider the ioctl range 0x70 -> 0x79 is reserved for agp extensions. + */ +#if __REALLY_HAVE_AGP + [DRM_IOCTL_NR(DRM_IOCTL_AGP_GETMAP)] = { DRM(agp_getmap), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_QUERY)] = { DRM(agp_e_info), 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_QUERY_SZ)] = { DRM(agp_e_size), 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_NUM_CTX)] = { DRM(agp_no_ctxs), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_CHG_CTX)] = { DRM(agp_chg_ctx), 1, 1 }, +#endif }; #define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( DRM(ioctls) ) @@ -399,8 +414,8 @@ static int DRM(takedown)( drm_device_t *dev ) intact until drv_cleanup is called. */ for ( entry = dev->agp->memory ; entry ; entry = nexte ) { nexte = entry->next; - if ( entry->bound ) DRM(unbind_agp)( entry->memory ); - DRM(free_agp)( entry->memory, entry->pages ); + if ( entry->bound ) DRM(unbind_agp)( dev, entry->memory ); + DRM(free_agp)( dev, entry->memory, entry->pages ); DRM(free)( entry, sizeof(*entry), DRM_MEM_AGPLISTS ); } dev->agp->memory = NULL; @@ -450,6 +465,7 @@ static int DRM(takedown)( drm_device_t *dev ) break; case _DRM_AGP: + case _DRM_AGP_MEM: /* Do nothing here, because this is all * handled in the AGP/GART driver. */ diff --git a/linux/drm_memory.h b/linux/drm_memory.h index 22aab7f4..da4a66f9 100644 --- a/linux/drm_memory.h +++ b/linux/drm_memory.h @@ -362,7 +362,7 @@ void DRM(ioremapfree)(void *pt, unsigned long size) #if __REALLY_HAVE_AGP -agp_memory *DRM(alloc_agp)(int pages, u32 type) +agp_memory *DRM(alloc_agp)(drm_device_t *dev, int pages, u32 type) { agp_memory *handle; @@ -371,7 +371,8 @@ agp_memory *DRM(alloc_agp)(int pages, u32 type) return NULL; } - if ((handle = DRM(agp_allocate_memory)(pages, type))) { + if ((handle = DRM(agp_allocate_memory)(dev, pages, type))) { + printk("Returning handle : %p\n", handle); spin_lock(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count; DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_allocated @@ -385,7 +386,7 @@ agp_memory *DRM(alloc_agp)(int pages, u32 type) return NULL; } -int DRM(free_agp)(agp_memory *handle, int pages) +int DRM(free_agp)(drm_device_t *dev, agp_memory *handle, int pages) { int alloc_count; int free_count; @@ -397,7 +398,7 @@ int DRM(free_agp)(agp_memory *handle, int pages) return retval;; } - if (DRM(agp_free_memory)(handle)) { + if (DRM(agp_free_memory)(dev, handle)) { spin_lock(&DRM(mem_lock)); free_count = ++DRM(mem_stats)[DRM_MEM_TOTALAGP].free_count; alloc_count = DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count; @@ -414,17 +415,18 @@ int DRM(free_agp)(agp_memory *handle, int pages) return retval; } -int DRM(bind_agp)(agp_memory *handle, unsigned int start) +int DRM(bind_agp)(drm_device_t *dev, agp_memory *handle, unsigned int start) { int retcode = -EINVAL; + printk("%s\n", __func__); if (!handle) { DRM_MEM_ERROR(DRM_MEM_BOUNDAGP, "Attempt to bind NULL AGP handle\n"); return retcode; } - if (!(retcode = DRM(agp_bind_memory)(handle, start))) { + if (!(retcode = DRM(agp_bind_memory)(dev, handle, start))) { spin_lock(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count; DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_allocated @@ -438,7 +440,7 @@ int DRM(bind_agp)(agp_memory *handle, unsigned int start) return retcode; } -int DRM(unbind_agp)(agp_memory *handle) +int DRM(unbind_agp)(drm_device_t *dev, agp_memory *handle) { int alloc_count; int free_count; @@ -450,7 +452,7 @@ int DRM(unbind_agp)(agp_memory *handle) return retcode; } - if ((retcode = DRM(agp_unbind_memory)(handle))) return retcode; + if ((retcode = DRM(agp_unbind_memory)(dev, handle))) return retcode; spin_lock(&DRM(mem_lock)); free_count = ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].free_count; alloc_count = DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count; diff --git a/linux/drm_vm.h b/linux/drm_vm.h index 683c0857..8839a840 100644 --- a/linux/drm_vm.h +++ b/linux/drm_vm.h @@ -214,6 +214,7 @@ void DRM(vm_shm_close)(struct vm_area_struct *vma) break; case _DRM_AGP: case _DRM_SCATTER_GATHER: + case _DRM_AGP_MEM: break; } DRM(free)(map, sizeof(*map), DRM_MEM_MAPS); @@ -420,6 +421,11 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma) } switch (map->type) { + case _DRM_AGP_MEM: +#if __REALLY_HAVE_AGP + /* Use agpgart to map this block of agp memory. */ + return DRM(agp_usermap)(dev, map, vma); +#endif case _DRM_AGP: #if defined(__alpha__) /* diff --git a/linux/gamma.h b/linux/gamma.h index 44d8d5bc..47d9de43 100644 --- a/linux/gamma.h +++ b/linux/gamma.h @@ -51,7 +51,7 @@ #define DRIVER_IOCTLS \ [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { gamma_dma, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_GAMMA_INIT)] = { gamma_dma_init, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_GAMMA_COPY)] = { gamma_dma_copy, 1, 1 } + [DRM_IOCTL_NR(DRM_IOCTL_GAMMA_COPY)] = { gamma_dma_copy, 1, 1 }, #define IOCTL_TABLE_NAME DRM(ioctls) #define IOCTL_FUNC_NAME DRM(ioctl) diff --git a/linux/gamma_drm.h b/linux/gamma_drm.h index d06763ae..0d58b07b 100644 --- a/linux/gamma_drm.h +++ b/linux/gamma_drm.h @@ -48,6 +48,16 @@ typedef struct _drm_gamma_sarea { int vertex_prim; } drm_gamma_sarea_t; +/* WARNING: If you change any of these defines, make sure to change the + * defines in the Xserver file (xf86drmGamma.h) + */ + +/* Gamma specific ioctls + * The device specific ioctl range is 0x40 to 0x79. + */ +#define DRM_IOCTL_GAMMA_INIT DRM_IOW( 0x40, drm_gamma_init_t) +#define DRM_IOCTL_GAMMA_COPY DRM_IOW( 0x41, drm_gamma_copy_t) + typedef struct drm_gamma_copy { unsigned int DMAOutputAddress; unsigned int DMAOutputCount; diff --git a/linux/i810.h b/linux/i810.h index ea1e7fe5..635c94f2 100644 --- a/linux/i810.h +++ b/linux/i810.h @@ -73,7 +73,7 @@ [DRM_IOCTL_NR(DRM_IOCTL_I810_FSTATUS)] = { i810_fstatus, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_I810_OV0FLIP)] = { i810_ov0_flip, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_I810_MC)] = { i810_dma_mc, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_RSTATUS)] = { i810_rstatus, 1, 0 } + [DRM_IOCTL_NR(DRM_IOCTL_I810_RSTATUS)] = { i810_rstatus, 1, 0 }, #define __HAVE_COUNTERS 4 diff --git a/linux/sis.h b/linux/sis.h index 0bf3dfa9..8c289dc2 100644 --- a/linux/sis.h +++ b/linux/sis.h @@ -56,13 +56,13 @@ /* AGP Memory Management */ \ [DRM_IOCTL_NR(SIS_IOCTL_AGP_INIT)] = { sisp_agp_init, 1, 0 }, \ [DRM_IOCTL_NR(SIS_IOCTL_AGP_ALLOC)] = { sisp_agp_alloc, 1, 0 }, \ - [DRM_IOCTL_NR(SIS_IOCTL_AGP_FREE)] = { sisp_agp_free, 1, 0 } + [DRM_IOCTL_NR(SIS_IOCTL_AGP_FREE)] = { sisp_agp_free, 1, 0 }, #if 0 /* these don't appear to be defined */ /* SIS Stereo */ [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { sis_control, 1, 1 }, [DRM_IOCTL_NR(SIS_IOCTL_FLIP)] = { sis_flip, 1, 1 }, [DRM_IOCTL_NR(SIS_IOCTL_FLIP_INIT)] = { sis_flip_init, 1, 1 }, - [DRM_IOCTL_NR(SIS_IOCTL_FLIP_FINAL)] = { sis_flip_final, 1, 1 } + [DRM_IOCTL_NR(SIS_IOCTL_FLIP_FINAL)] = { sis_flip_final, 1, 1 }, #endif #define __HAVE_COUNTERS 5 diff --git a/shared-core/drm.h b/shared-core/drm.h index d1d66943..f480d82c 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -161,7 +161,8 @@ typedef enum drm_map_type { _DRM_REGISTERS = 1, /* no caching, no core dump */ _DRM_SHM = 2, /* shared, cached */ _DRM_AGP = 3, /* AGP/GART */ - _DRM_SCATTER_GATHER = 4 /* Scatter/gather memory for PCI DMA */ + _DRM_SCATTER_GATHER = 4, /* Scatter/gather memory for PCI DMA */ + _DRM_AGP_MEM = 5, /* AGP/GART memory block */ } drm_map_type_t; typedef enum drm_map_flags { @@ -375,6 +376,104 @@ typedef struct drm_agp_mode { unsigned long mode; } drm_agp_mode_t; +/* Added for agp 3.0 */ +typedef struct drm_agp_buffer_info { + unsigned long size; /* In bytes -- will round to page boundary */ + unsigned long handle; /* Used for BIND/UNBIND ioctls */ + unsigned long type; /* Type of memory to allocate */ + unsigned long physical; /* Physical used by i810 */ + unsigned long offset; /* In bytes -- will round to page boundary */ +} drm_agp_buffer_info_t; + +/* Masters and targets flags */ +#define _DRM_AGP_SUPPORTS_ISOCHRONOUS (1<<0) +#define _DRM_AGP_SUPPORTS_SBA (1<<1) +#define _DRM_AGP_SUPPORTS_AGP_3_0_ENABLED (1<<2) +#define _DRM_AGP_SUPPORTS_OVER4G_ADDR (1<<3) +#define _DRM_AGP_SUPPORTS_FAST_WRITE (1<<4) +#define _DRM_AGP_SUPPORTS_SPEED_1X (1<<5) +#define _DRM_AGP_SUPPORTS_SPEED_2X (1<<6) +#define _DRM_AGP_SUPPORTS_SPEED_4X (1<<7) +#define _DRM_AGP_SUPPORTS_SPEED_8X (1<<8) +#define _DRM_AGP_SUPPORTS_ISO_PAYLOAD_32_B (1<<9) +#define _DRM_AGP_SUPPORTS_ISO_PAYLOAD_64_B (1<<10) +#define _DRM_AGP_SUPPORTS_ISO_PAYLOAD_128_B (1<<11) +#define _DRM_AGP_SUPPORTS_ISO_PAYLOAD_256_B (1<<12) + +/* valid for targets only */ +#define _DRM_AGP_SUPPORTS_CACHED_MEMORY (1<<13) +#define _DRM_AGP_SUPPORTS_APER_MMAP (1<<14) + +/* reserved bits for future use */ +#define _DRM_AGP_SUPPORTS_RESERVED_0 (1<<15) +#define _DRM_AGP_SUPPORTS_RESERVED_1 (1<<16) +#define _DRM_AGP_SUPPORTS_RESERVED_2 (1<<17) +#define _DRM_AGP_SUPPORTS_RESERVED_3 (1<<18) +#define _DRM_AGP_SUPPORTS_RESERVED_4 (1<<19) +#define _DRM_AGP_SUPPORTS_RESERVED_5 (1<<20) +#define _DRM_AGP_SUPPORTS_RESERVED_6 (1<<21) +#define _DRM_AGP_SUPPORTS_RESERVED_7 (1<<22) +#define _DRM_AGP_SUPPORTS_RESERVED_8 (1<<23) +#define _DRM_AGP_SUPPORTS_RESERVED_9 (1<<24) +#define _DRM_AGP_SUPPORTS_RESERVED_10 (1<<25) +#define _DRM_AGP_SUPPORTS_RESERVED_11 (1<<26) +#define _DRM_AGP_SUPPORTS_RESERVED_12 (1<<27) +#define _DRM_AGP_SUPPORTS_RESERVED_13 (1<<28) +#define _DRM_AGP_SUPPORTS_RESERVED_14 (1<<29) +#define _DRM_AGP_SUPPORTS_RESERVED_15 (1<<30) +#define _DRM_AGP_SUPPORTS_RESERVED_16 (1<<31) + +/* Driver flags, all the rest of the values are reserved */ +#define _DRM_AGP_USE_AGP_3_0_MODES (1<<0) +#define _DRM_AGP_CAN_MAP_APERTURE (1<<1) +#define _DRM_AGP_MAPS_USE_CACHE_ATTRS (1<<2) +#define _DRM_AGP_CAN_DO_CACHED (1<<3) +#define _DRM_AGP_DRIVER_ACTIVE (1<<4) + +typedef struct drm_agp_master { + int agp_major_version; + int agp_minor_version; + int vendor_pci_id; + int device_pci_id; + int num_requests_enqueue; + int calibration_cycle_ms; + int max_bandwidth_bpp; + int num_trans_per_period; + int max_requests; + int payload_size; + unsigned long flags; +} drm_agp_master_t; + +typedef struct drm_agp_driver_info { + char *driver_name; /* Driver name or empty string */ + int agp_major_version; + int agp_minor_version; + int num_requests_enqueue; + int calibration_cycle_ms; + int optimum_request_size; + int max_bandwidth_bpp; + int iso_latency_in_periods; + int num_trans_per_period; + int payload_size; + int target_vendor_pci_id; + int target_device_pci_id; + unsigned long target_flags; + unsigned long driver_flags; + unsigned long aper_base; + unsigned long aper_size; + int agp_page_shift; + int alloc_page_shift; + unsigned long agp_page_mask; + unsigned long alloc_page_mask; + int max_system_pages; + int current_memory; + int context_id; + int num_masters; + drm_agp_master_t *masters; /* Pointer to array of master data + * if no masters == NULL. + */ +} drm_agp_driver_info_t; + /* For drm_agp_alloc -- allocated a buffer */ typedef struct drm_agp_buffer { unsigned long size; /* In bytes -- will round to page boundary */ @@ -471,4 +570,14 @@ typedef struct drm_scatter_gather { * The device specific ioctl range is 0x40 to 0x79. */ #define DRM_COMMAND_BASE 0x40 +/* Actually lets use 0x70 -> 0x79 for agp ioctls, not devices. We can + * always extend the ioctl numbers by providing an ioctl which calls + * an extended range of numbers. + */ +#define DRM_IOCTL_AGP_GETMAP 0x70 +#define DRM_IOCTL_AGP_QUERY 0x71 +#define DRM_IOCTL_AGP_QUERY_SZ 0x72 +#define DRM_IOCTL_AGP_NUM_CTX 0x73 +#define DRM_IOCTL_AGP_CHG_CTX 0x74 + #endif diff --git a/shared/drm.h b/shared/drm.h index d1d66943..f480d82c 100644 --- a/shared/drm.h +++ b/shared/drm.h @@ -161,7 +161,8 @@ typedef enum drm_map_type { _DRM_REGISTERS = 1, /* no caching, no core dump */ _DRM_SHM = 2, /* shared, cached */ _DRM_AGP = 3, /* AGP/GART */ - _DRM_SCATTER_GATHER = 4 /* Scatter/gather memory for PCI DMA */ + _DRM_SCATTER_GATHER = 4, /* Scatter/gather memory for PCI DMA */ + _DRM_AGP_MEM = 5, /* AGP/GART memory block */ } drm_map_type_t; typedef enum drm_map_flags { @@ -375,6 +376,104 @@ typedef struct drm_agp_mode { unsigned long mode; } drm_agp_mode_t; +/* Added for agp 3.0 */ +typedef struct drm_agp_buffer_info { + unsigned long size; /* In bytes -- will round to page boundary */ + unsigned long handle; /* Used for BIND/UNBIND ioctls */ + unsigned long type; /* Type of memory to allocate */ + unsigned long physical; /* Physical used by i810 */ + unsigned long offset; /* In bytes -- will round to page boundary */ +} drm_agp_buffer_info_t; + +/* Masters and targets flags */ +#define _DRM_AGP_SUPPORTS_ISOCHRONOUS (1<<0) +#define _DRM_AGP_SUPPORTS_SBA (1<<1) +#define _DRM_AGP_SUPPORTS_AGP_3_0_ENABLED (1<<2) +#define _DRM_AGP_SUPPORTS_OVER4G_ADDR (1<<3) +#define _DRM_AGP_SUPPORTS_FAST_WRITE (1<<4) +#define _DRM_AGP_SUPPORTS_SPEED_1X (1<<5) +#define _DRM_AGP_SUPPORTS_SPEED_2X (1<<6) +#define _DRM_AGP_SUPPORTS_SPEED_4X (1<<7) +#define _DRM_AGP_SUPPORTS_SPEED_8X (1<<8) +#define _DRM_AGP_SUPPORTS_ISO_PAYLOAD_32_B (1<<9) +#define _DRM_AGP_SUPPORTS_ISO_PAYLOAD_64_B (1<<10) +#define _DRM_AGP_SUPPORTS_ISO_PAYLOAD_128_B (1<<11) +#define _DRM_AGP_SUPPORTS_ISO_PAYLOAD_256_B (1<<12) + +/* valid for targets only */ +#define _DRM_AGP_SUPPORTS_CACHED_MEMORY (1<<13) +#define _DRM_AGP_SUPPORTS_APER_MMAP (1<<14) + +/* reserved bits for future use */ +#define _DRM_AGP_SUPPORTS_RESERVED_0 (1<<15) +#define _DRM_AGP_SUPPORTS_RESERVED_1 (1<<16) +#define _DRM_AGP_SUPPORTS_RESERVED_2 (1<<17) +#define _DRM_AGP_SUPPORTS_RESERVED_3 (1<<18) +#define _DRM_AGP_SUPPORTS_RESERVED_4 (1<<19) +#define _DRM_AGP_SUPPORTS_RESERVED_5 (1<<20) +#define _DRM_AGP_SUPPORTS_RESERVED_6 (1<<21) +#define _DRM_AGP_SUPPORTS_RESERVED_7 (1<<22) +#define _DRM_AGP_SUPPORTS_RESERVED_8 (1<<23) +#define _DRM_AGP_SUPPORTS_RESERVED_9 (1<<24) +#define _DRM_AGP_SUPPORTS_RESERVED_10 (1<<25) +#define _DRM_AGP_SUPPORTS_RESERVED_11 (1<<26) +#define _DRM_AGP_SUPPORTS_RESERVED_12 (1<<27) +#define _DRM_AGP_SUPPORTS_RESERVED_13 (1<<28) +#define _DRM_AGP_SUPPORTS_RESERVED_14 (1<<29) +#define _DRM_AGP_SUPPORTS_RESERVED_15 (1<<30) +#define _DRM_AGP_SUPPORTS_RESERVED_16 (1<<31) + +/* Driver flags, all the rest of the values are reserved */ +#define _DRM_AGP_USE_AGP_3_0_MODES (1<<0) +#define _DRM_AGP_CAN_MAP_APERTURE (1<<1) +#define _DRM_AGP_MAPS_USE_CACHE_ATTRS (1<<2) +#define _DRM_AGP_CAN_DO_CACHED (1<<3) +#define _DRM_AGP_DRIVER_ACTIVE (1<<4) + +typedef struct drm_agp_master { + int agp_major_version; + int agp_minor_version; + int vendor_pci_id; + int device_pci_id; + int num_requests_enqueue; + int calibration_cycle_ms; + int max_bandwidth_bpp; + int num_trans_per_period; + int max_requests; + int payload_size; + unsigned long flags; +} drm_agp_master_t; + +typedef struct drm_agp_driver_info { + char *driver_name; /* Driver name or empty string */ + int agp_major_version; + int agp_minor_version; + int num_requests_enqueue; + int calibration_cycle_ms; + int optimum_request_size; + int max_bandwidth_bpp; + int iso_latency_in_periods; + int num_trans_per_period; + int payload_size; + int target_vendor_pci_id; + int target_device_pci_id; + unsigned long target_flags; + unsigned long driver_flags; + unsigned long aper_base; + unsigned long aper_size; + int agp_page_shift; + int alloc_page_shift; + unsigned long agp_page_mask; + unsigned long alloc_page_mask; + int max_system_pages; + int current_memory; + int context_id; + int num_masters; + drm_agp_master_t *masters; /* Pointer to array of master data + * if no masters == NULL. + */ +} drm_agp_driver_info_t; + /* For drm_agp_alloc -- allocated a buffer */ typedef struct drm_agp_buffer { unsigned long size; /* In bytes -- will round to page boundary */ @@ -471,4 +570,14 @@ typedef struct drm_scatter_gather { * The device specific ioctl range is 0x40 to 0x79. */ #define DRM_COMMAND_BASE 0x40 +/* Actually lets use 0x70 -> 0x79 for agp ioctls, not devices. We can + * always extend the ioctl numbers by providing an ioctl which calls + * an extended range of numbers. + */ +#define DRM_IOCTL_AGP_GETMAP 0x70 +#define DRM_IOCTL_AGP_QUERY 0x71 +#define DRM_IOCTL_AGP_QUERY_SZ 0x72 +#define DRM_IOCTL_AGP_NUM_CTX 0x73 +#define DRM_IOCTL_AGP_CHG_CTX 0x74 + #endif |