summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Hartmann <jhartmann@valinux.com>2003-01-11 05:42:38 +0000
committerJeff Hartmann <jhartmann@valinux.com>2003-01-11 05:42:38 +0000
commitced519be2077857f7b8f04daed06204af7c937dd (patch)
tree459f1cb9f4e7e8b4e78e582a37b9a9df7b4d2216
parenta1fc6af2d8937fcc4eef25119d777e168e62b2ea (diff)
Initial Checkin for agp 3.0 infrastructure support.
-rw-r--r--linux-core/drmP.h41
-rw-r--r--linux-core/drm_agpsupport.c574
-rw-r--r--linux-core/drm_bufs.c21
-rw-r--r--linux-core/drm_drv.c20
-rw-r--r--linux-core/drm_memory.h18
-rw-r--r--linux-core/drm_vm.c6
-rw-r--r--linux/agp_30_symbols.h109
-rw-r--r--linux/drm.h111
-rw-r--r--linux/drmP.h41
-rw-r--r--linux/drm_agpsupport.h574
-rw-r--r--linux/drm_bufs.h21
-rw-r--r--linux/drm_drv.h20
-rw-r--r--linux/drm_memory.h18
-rw-r--r--linux/drm_vm.h6
-rw-r--r--linux/gamma.h2
-rw-r--r--linux/gamma_drm.h10
-rw-r--r--linux/i810.h2
-rw-r--r--linux/sis.h4
-rw-r--r--shared-core/drm.h111
-rw-r--r--shared/drm.h111
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