diff options
author | Dave Airlie <airlied@linux.ie> | 2007-10-29 01:14:03 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2008-02-04 23:33:32 -0500 |
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 b83824c41329..9ec9374ccc42 100644 --- a/drivers/char/agp/agp.h +++ b/drivers/char/agp/agp.h | |||
@@ -117,7 +117,8 @@ struct agp_bridge_driver { | |||
117 | void (*free_by_type)(struct agp_memory *); | 117 | void (*free_by_type)(struct agp_memory *); |
118 | void *(*agp_alloc_page)(struct agp_bridge_data *); | 118 | void *(*agp_alloc_page)(struct agp_bridge_data *); |
119 | void (*agp_destroy_page)(void *, int flags); | 119 | void (*agp_destroy_page)(void *, int flags); |
120 | int (*agp_type_to_mask_type) (struct agp_bridge_data *, int); | 120 | int (*agp_type_to_mask_type) (struct agp_bridge_data *, int); |
121 | void (*chipset_flush)(struct agp_bridge_data *); | ||
121 | }; | 122 | }; |
122 | 123 | ||
123 | struct agp_bridge_data { | 124 | struct agp_bridge_data { |
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c index 2720882e66fe..b1bdd015165c 100644 --- a/drivers/char/agp/backend.c +++ b/drivers/char/agp/backend.c | |||
@@ -43,7 +43,7 @@ | |||
43 | * fix some real stupidity. It's only by chance we can bump | 43 | * fix some real stupidity. It's only by chance we can bump |
44 | * past 0.99 at all due to some boolean logic error. */ | 44 | * past 0.99 at all due to some boolean logic error. */ |
45 | #define AGPGART_VERSION_MAJOR 0 | 45 | #define AGPGART_VERSION_MAJOR 0 |
46 | #define AGPGART_VERSION_MINOR 102 | 46 | #define AGPGART_VERSION_MINOR 103 |
47 | static const struct agp_version agp_current_version = | 47 | static const struct agp_version agp_current_version = |
48 | { | 48 | { |
49 | .major = AGPGART_VERSION_MAJOR, | 49 | .major = AGPGART_VERSION_MAJOR, |
diff --git a/drivers/char/agp/compat_ioctl.c b/drivers/char/agp/compat_ioctl.c index ecd4248861b9..39275794fe63 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) | |||
273 | case AGPIOC_UNBIND32: | 273 | case AGPIOC_UNBIND32: |
274 | ret_val = compat_agpioc_unbind_wrap(curr_priv, (void __user *) arg); | 274 | ret_val = compat_agpioc_unbind_wrap(curr_priv, (void __user *) arg); |
275 | break; | 275 | break; |
276 | |||
277 | case AGPIOC_CHIPSET_FLUSH32: | ||
278 | ret_val = agpioc_chipset_flush_wrap(curr_priv); | ||
279 | break; | ||
276 | } | 280 | } |
277 | 281 | ||
278 | ioctl_out: | 282 | ioctl_out: |
diff --git a/drivers/char/agp/compat_ioctl.h b/drivers/char/agp/compat_ioctl.h index 71939d637236..0c9678ac0371 100644 --- a/drivers/char/agp/compat_ioctl.h +++ b/drivers/char/agp/compat_ioctl.h | |||
@@ -39,6 +39,7 @@ | |||
39 | #define AGPIOC_DEALLOCATE32 _IOW (AGPIOC_BASE, 7, compat_int_t) | 39 | #define AGPIOC_DEALLOCATE32 _IOW (AGPIOC_BASE, 7, compat_int_t) |
40 | #define AGPIOC_BIND32 _IOW (AGPIOC_BASE, 8, compat_uptr_t) | 40 | #define AGPIOC_BIND32 _IOW (AGPIOC_BASE, 8, compat_uptr_t) |
41 | #define AGPIOC_UNBIND32 _IOW (AGPIOC_BASE, 9, compat_uptr_t) | 41 | #define AGPIOC_UNBIND32 _IOW (AGPIOC_BASE, 9, compat_uptr_t) |
42 | #define AGPIOC_CHIPSET_FLUSH32 _IO (AGPIOC_BASE, 10) | ||
42 | 43 | ||
43 | struct agp_info32 { | 44 | struct agp_info32 { |
44 | struct agp_version version; /* version of the driver */ | 45 | struct agp_version version; /* version of the driver */ |
@@ -101,5 +102,6 @@ void agp_free_memory_wrap(struct agp_memory *memory); | |||
101 | struct agp_memory *agp_allocate_memory_wrap(size_t pg_count, u32 type); | 102 | struct agp_memory *agp_allocate_memory_wrap(size_t pg_count, u32 type); |
102 | struct agp_memory *agp_find_mem_by_key(int key); | 103 | struct agp_memory *agp_find_mem_by_key(int key); |
103 | struct agp_client *agp_find_client_by_pid(pid_t id); | 104 | struct agp_client *agp_find_client_by_pid(pid_t id); |
105 | int agpioc_chipset_flush_wrap(struct agp_file_private *priv); | ||
104 | 106 | ||
105 | #endif /* _AGP_COMPAT_H */ | 107 | #endif /* _AGP_COMPAT_H */ |
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c index 7791e98de51c..9bd5a958954c 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) | |||
960 | return agp_unbind_memory(memory); | 960 | return agp_unbind_memory(memory); |
961 | } | 961 | } |
962 | 962 | ||
963 | int agpioc_chipset_flush_wrap(struct agp_file_private *priv) | ||
964 | { | ||
965 | DBG(""); | ||
966 | agp_flush_chipset(agp_bridge); | ||
967 | return 0; | ||
968 | } | ||
969 | |||
963 | static int agp_ioctl(struct inode *inode, struct file *file, | 970 | static int agp_ioctl(struct inode *inode, struct file *file, |
964 | unsigned int cmd, unsigned long arg) | 971 | unsigned int cmd, unsigned long arg) |
965 | { | 972 | { |
@@ -1033,6 +1040,10 @@ static int agp_ioctl(struct inode *inode, struct file *file, | |||
1033 | case AGPIOC_UNBIND: | 1040 | case AGPIOC_UNBIND: |
1034 | ret_val = agpioc_unbind_wrap(curr_priv, (void __user *) arg); | 1041 | ret_val = agpioc_unbind_wrap(curr_priv, (void __user *) arg); |
1035 | break; | 1042 | break; |
1043 | |||
1044 | case AGPIOC_CHIPSET_FLUSH: | ||
1045 | ret_val = agpioc_chipset_flush_wrap(curr_priv); | ||
1046 | break; | ||
1036 | } | 1047 | } |
1037 | 1048 | ||
1038 | ioctl_out: | 1049 | ioctl_out: |
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index 1a4674ce0c71..7484bc759c4c 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c | |||
@@ -80,6 +80,13 @@ static int agp_get_key(void) | |||
80 | return -1; | 80 | return -1; |
81 | } | 81 | } |
82 | 82 | ||
83 | void agp_flush_chipset(struct agp_bridge_data *bridge) | ||
84 | { | ||
85 | if (bridge->driver->chipset_flush) | ||
86 | bridge->driver->chipset_flush(bridge); | ||
87 | } | ||
88 | EXPORT_SYMBOL(agp_flush_chipset); | ||
89 | |||
83 | /* | 90 | /* |
84 | * Use kmalloc if possible for the page list. Otherwise fall back to | 91 | * Use kmalloc if possible for the page list. Otherwise fall back to |
85 | * vmalloc. This speeds things up and also saves memory for small AGP | 92 | * 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 abc521cfb084..03e34547d489 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 *); | |||
109 | extern void agp_enable(struct agp_bridge_data *, u32); | 109 | extern void agp_enable(struct agp_bridge_data *, u32); |
110 | extern struct agp_bridge_data *agp_backend_acquire(struct pci_dev *); | 110 | extern struct agp_bridge_data *agp_backend_acquire(struct pci_dev *); |
111 | extern void agp_backend_release(struct agp_bridge_data *); | 111 | extern void agp_backend_release(struct agp_bridge_data *); |
112 | extern void agp_flush_chipset(struct agp_bridge_data *); | ||
112 | 113 | ||
113 | #endif /* __KERNEL__ */ | 114 | #endif /* __KERNEL__ */ |
114 | #endif /* _AGP_BACKEND_H */ | 115 | #endif /* _AGP_BACKEND_H */ |
diff --git a/include/linux/agpgart.h b/include/linux/agpgart.h index 09fbf7e5a6cb..62aef589eb94 100644 --- a/include/linux/agpgart.h +++ b/include/linux/agpgart.h | |||
@@ -38,6 +38,7 @@ | |||
38 | #define AGPIOC_DEALLOCATE _IOW (AGPIOC_BASE, 7, int) | 38 | #define AGPIOC_DEALLOCATE _IOW (AGPIOC_BASE, 7, int) |
39 | #define AGPIOC_BIND _IOW (AGPIOC_BASE, 8, struct agp_bind*) | 39 | #define AGPIOC_BIND _IOW (AGPIOC_BASE, 8, struct agp_bind*) |
40 | #define AGPIOC_UNBIND _IOW (AGPIOC_BASE, 9, struct agp_unbind*) | 40 | #define AGPIOC_UNBIND _IOW (AGPIOC_BASE, 9, struct agp_unbind*) |
41 | #define AGPIOC_CHIPSET_FLUSH _IO (AGPIOC_BASE, 10) | ||
41 | 42 | ||
42 | #define AGP_DEVICE "/dev/agpgart" | 43 | #define AGP_DEVICE "/dev/agpgart" |
43 | 44 | ||