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 | ||
