agp: add chipset flushing support to AGP interface
authorDave Airlie <airlied@linux.ie>
Mon, 29 Oct 2007 05:14:03 +0000 (15:14 +1000)
committerDave Airlie <airlied@redhat.com>
Tue, 5 Feb 2008 04:33:32 +0000 (14:33 +1000)
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>
drivers/char/agp/agp.h
drivers/char/agp/backend.c
drivers/char/agp/compat_ioctl.c
drivers/char/agp/compat_ioctl.h
drivers/char/agp/frontend.c
drivers/char/agp/generic.c
include/linux/agp_backend.h
include/linux/agpgart.h

index b83824c41329f3d4f4459de76b981c67ec946ba5..9ec9374ccc42c3aae4eac35c032121a54a24bacb 100644 (file)
@@ -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 {
index 2720882e66fec157dd987f0c665ae732171aa8df..b1bdd015165c092a5f850f606b1d9a8ed948d409 100644 (file)
@@ -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,
index ecd4248861b9dfda6475e29d0acfcc9c6c547f96..39275794fe63a433edd5760b740af63ee12bf062 100644 (file)
@@ -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:
index 71939d637236c9e260e80a41ee74d1d8a69f8a05..0c9678ac03716809fa22ef01deaee895ffc40002 100644 (file)
@@ -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 */
index 7791e98de51c81a34ed3b4aed1b007cb4b728e46..9bd5a958954c0c293248fb0391f5f78871fdcae6 100644 (file)
@@ -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:
index 1a4674ce0c718f4c1c3a9bceb8342551fc5e73b8..7484bc759c4ccb8e2fb2fa407e68ae38e5936dae 100644 (file)
@@ -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
index abc521cfb08464a7e5a9c3cf11ca60d80f0529af..03e34547d489132632b6a15b2286c7dc2ac8ffa5 100644 (file)
@@ -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 */
index 09fbf7e5a6cbbbba0b3fe6991f4aefa494e937a4..62aef589eb940936d6adb53889165b4e1f17dba2 100644 (file)
@@ -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"