diff options
author | Dave Airlie <airlied@linux.ie> | 2007-10-29 15:14:03 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2008-02-05 14:33:32 +1000 |
commit | a13af4b4d842da6d7065b8c73fa8f0ac58fea1b6 (patch) | |
tree | 3269002c62ee1f10728cfa5a9782225329166d6b | |
parent | 9ef9dc69d4167276c04590d67ee55de8380bc1ad (diff) |
agp: add chipset flushing support to AGP interface
This bumps the AGP interface to 0.103.
Certain Intel chipsets contains a global write buffer, and this can require
flushing from the drm or X.org to make sure all data has hit RAM before
initiating a GPU transfer, due to a lack of coherency with the integrated
graphics device and this buffer.
This just adds generic support to the AGP interfaces, a follow-on patch
will add support to the Intel driver to use this interface.
Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r-- | drivers/char/agp/agp.h | 3 | ||||
-rw-r--r-- | drivers/char/agp/backend.c | 2 | ||||
-rw-r--r-- | drivers/char/agp/compat_ioctl.c | 4 | ||||
-rw-r--r-- | drivers/char/agp/compat_ioctl.h | 2 | ||||
-rw-r--r-- | drivers/char/agp/frontend.c | 11 | ||||
-rw-r--r-- | drivers/char/agp/generic.c | 7 | ||||
-rw-r--r-- | include/linux/agp_backend.h | 1 | ||||
-rw-r--r-- | include/linux/agpgart.h | 1 |
8 files changed, 29 insertions, 2 deletions
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h index b83824c4132..9ec9374ccc4 100644 --- a/drivers/char/agp/agp.h +++ b/drivers/char/agp/agp.h @@ -117,7 +117,8 @@ struct agp_bridge_driver { void (*free_by_type)(struct agp_memory *); void *(*agp_alloc_page)(struct agp_bridge_data *); void (*agp_destroy_page)(void *, int flags); - int (*agp_type_to_mask_type) (struct agp_bridge_data *, int); + int (*agp_type_to_mask_type) (struct agp_bridge_data *, int); + void (*chipset_flush)(struct agp_bridge_data *); }; struct agp_bridge_data { diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c index 2720882e66f..b1bdd015165 100644 --- a/drivers/char/agp/backend.c +++ b/drivers/char/agp/backend.c @@ -43,7 +43,7 @@ * fix some real stupidity. It's only by chance we can bump * past 0.99 at all due to some boolean logic error. */ #define AGPGART_VERSION_MAJOR 0 -#define AGPGART_VERSION_MINOR 102 +#define AGPGART_VERSION_MINOR 103 static const struct agp_version agp_current_version = { .major = AGPGART_VERSION_MAJOR, diff --git a/drivers/char/agp/compat_ioctl.c b/drivers/char/agp/compat_ioctl.c index ecd4248861b..39275794fe6 100644 --- a/drivers/char/agp/compat_ioctl.c +++ b/drivers/char/agp/compat_ioctl.c @@ -273,6 +273,10 @@ long compat_agp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case AGPIOC_UNBIND32: ret_val = compat_agpioc_unbind_wrap(curr_priv, (void __user *) arg); break; + + case AGPIOC_CHIPSET_FLUSH32: + ret_val = agpioc_chipset_flush_wrap(curr_priv); + break; } ioctl_out: diff --git a/drivers/char/agp/compat_ioctl.h b/drivers/char/agp/compat_ioctl.h index 71939d63723..0c9678ac037 100644 --- a/drivers/char/agp/compat_ioctl.h +++ b/drivers/char/agp/compat_ioctl.h @@ -39,6 +39,7 @@ #define AGPIOC_DEALLOCATE32 _IOW (AGPIOC_BASE, 7, compat_int_t) #define AGPIOC_BIND32 _IOW (AGPIOC_BASE, 8, compat_uptr_t) #define AGPIOC_UNBIND32 _IOW (AGPIOC_BASE, 9, compat_uptr_t) +#define AGPIOC_CHIPSET_FLUSH32 _IO (AGPIOC_BASE, 10) struct agp_info32 { struct agp_version version; /* version of the driver */ @@ -101,5 +102,6 @@ void agp_free_memory_wrap(struct agp_memory *memory); struct agp_memory *agp_allocate_memory_wrap(size_t pg_count, u32 type); struct agp_memory *agp_find_mem_by_key(int key); struct agp_client *agp_find_client_by_pid(pid_t id); +int agpioc_chipset_flush_wrap(struct agp_file_private *priv); #endif /* _AGP_COMPAT_H */ diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c index 7791e98de51..9bd5a958954 100644 --- a/drivers/char/agp/frontend.c +++ b/drivers/char/agp/frontend.c @@ -960,6 +960,13 @@ static int agpioc_unbind_wrap(struct agp_file_private *priv, void __user *arg) return agp_unbind_memory(memory); } +int agpioc_chipset_flush_wrap(struct agp_file_private *priv) +{ + DBG(""); + agp_flush_chipset(agp_bridge); + return 0; +} + static int agp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { @@ -1033,6 +1040,10 @@ static int agp_ioctl(struct inode *inode, struct file *file, case AGPIOC_UNBIND: ret_val = agpioc_unbind_wrap(curr_priv, (void __user *) arg); break; + + case AGPIOC_CHIPSET_FLUSH: + ret_val = agpioc_chipset_flush_wrap(curr_priv); + break; } ioctl_out: diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index 1a4674ce0c7..7484bc759c4 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c @@ -80,6 +80,13 @@ static int agp_get_key(void) return -1; } +void agp_flush_chipset(struct agp_bridge_data *bridge) +{ + if (bridge->driver->chipset_flush) + bridge->driver->chipset_flush(bridge); +} +EXPORT_SYMBOL(agp_flush_chipset); + /* * Use kmalloc if possible for the page list. Otherwise fall back to * vmalloc. This speeds things up and also saves memory for small AGP diff --git a/include/linux/agp_backend.h b/include/linux/agp_backend.h index abc521cfb08..03e34547d48 100644 --- a/include/linux/agp_backend.h +++ b/include/linux/agp_backend.h @@ -109,6 +109,7 @@ extern int agp_unbind_memory(struct agp_memory *); extern void agp_enable(struct agp_bridge_data *, u32); extern struct agp_bridge_data *agp_backend_acquire(struct pci_dev *); extern void agp_backend_release(struct agp_bridge_data *); +extern void agp_flush_chipset(struct agp_bridge_data *); #endif /* __KERNEL__ */ #endif /* _AGP_BACKEND_H */ diff --git a/include/linux/agpgart.h b/include/linux/agpgart.h index 09fbf7e5a6c..62aef589eb9 100644 --- a/include/linux/agpgart.h +++ b/include/linux/agpgart.h @@ -38,6 +38,7 @@ #define AGPIOC_DEALLOCATE _IOW (AGPIOC_BASE, 7, int) #define AGPIOC_BIND _IOW (AGPIOC_BASE, 8, struct agp_bind*) #define AGPIOC_UNBIND _IOW (AGPIOC_BASE, 9, struct agp_unbind*) +#define AGPIOC_CHIPSET_FLUSH _IO (AGPIOC_BASE, 10) #define AGP_DEVICE "/dev/agpgart" |