diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-08 13:03:28 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-08 13:03:28 -0500 |
commit | 0c0e8caf9fd6c9a49fb9fbdba14a8b7b4239adde (patch) | |
tree | c9b873f23b9d7d1fc7573788233104e0e501d269 /drivers | |
parent | b892afd1e60132a981b963929e352eabf3306ba2 (diff) | |
parent | 1545085a28f226b59c243f88b82ea25393b0d63f (diff) |
Merge branch 'drm-patches' of master.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-patches' of master.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6:
drm: Allow for 44 bit user-tokens (or drm_file offsets)
drm/via: Disable AGP DMA for chips with the new 3D engine.
drm: update core memory manager from git drm tree
drm: remove drm_ioremap and drm_ioremapfree
i810/i830: use drm_core_ioremap instead of drm_ioremap
drm: use vmalloc_user instead of vmalloc_32 for DRM_SHM
via: allow for npot texture pitch alignment
via: add some new chipsets
via: some PCI posting flushes
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/drm/drmP.h | 36 | ||||
-rw-r--r-- | drivers/char/drm/drm_bufs.c | 19 | ||||
-rw-r--r-- | drivers/char/drm/drm_memory.c | 94 | ||||
-rw-r--r-- | drivers/char/drm/drm_memory.h | 20 | ||||
-rw-r--r-- | drivers/char/drm/drm_memory_debug.h | 70 | ||||
-rw-r--r-- | drivers/char/drm/drm_mm.c | 183 | ||||
-rw-r--r-- | drivers/char/drm/drm_pciids.h | 4 | ||||
-rw-r--r-- | drivers/char/drm/drm_proc.c | 4 | ||||
-rw-r--r-- | drivers/char/drm/drm_sman.c | 3 | ||||
-rw-r--r-- | drivers/char/drm/drm_vm.c | 16 | ||||
-rw-r--r-- | drivers/char/drm/i810_dma.c | 34 | ||||
-rw-r--r-- | drivers/char/drm/i810_drv.h | 2 | ||||
-rw-r--r-- | drivers/char/drm/i830_dma.c | 32 | ||||
-rw-r--r-- | drivers/char/drm/i830_drv.h | 2 | ||||
-rw-r--r-- | drivers/char/drm/via_dma.c | 9 | ||||
-rw-r--r-- | drivers/char/drm/via_dmablit.c | 2 | ||||
-rw-r--r-- | drivers/char/drm/via_drv.h | 11 | ||||
-rw-r--r-- | drivers/char/drm/via_irq.c | 16 | ||||
-rw-r--r-- | drivers/char/drm/via_map.c | 3 | ||||
-rw-r--r-- | drivers/char/drm/via_verifier.c | 50 | ||||
-rw-r--r-- | drivers/char/drm/via_verifier.h | 1 |
21 files changed, 304 insertions, 307 deletions
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index 6dcdceb81203..85d99e21e188 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h | |||
@@ -532,11 +532,13 @@ typedef struct drm_mm_node { | |||
532 | int free; | 532 | int free; |
533 | unsigned long start; | 533 | unsigned long start; |
534 | unsigned long size; | 534 | unsigned long size; |
535 | struct drm_mm *mm; | ||
535 | void *private; | 536 | void *private; |
536 | } drm_mm_node_t; | 537 | } drm_mm_node_t; |
537 | 538 | ||
538 | typedef struct drm_mm { | 539 | typedef struct drm_mm { |
539 | drm_mm_node_t root_node; | 540 | struct list_head fl_entry; |
541 | struct list_head ml_entry; | ||
540 | } drm_mm_t; | 542 | } drm_mm_t; |
541 | 543 | ||
542 | /** | 544 | /** |
@@ -843,9 +845,6 @@ extern void drm_mem_init(void); | |||
843 | extern int drm_mem_info(char *buf, char **start, off_t offset, | 845 | extern int drm_mem_info(char *buf, char **start, off_t offset, |
844 | int request, int *eof, void *data); | 846 | int request, int *eof, void *data); |
845 | extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area); | 847 | extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area); |
846 | extern void *drm_ioremap(unsigned long offset, unsigned long size, | ||
847 | drm_device_t * dev); | ||
848 | extern void drm_ioremapfree(void *pt, unsigned long size, drm_device_t * dev); | ||
849 | 848 | ||
850 | extern DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type); | 849 | extern DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type); |
851 | extern int drm_free_agp(DRM_AGP_MEM * handle, int pages); | 850 | extern int drm_free_agp(DRM_AGP_MEM * handle, int pages); |
@@ -1053,33 +1052,18 @@ extern void drm_sysfs_device_remove(struct class_device *class_dev); | |||
1053 | extern drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent, | 1052 | extern drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent, |
1054 | unsigned long size, | 1053 | unsigned long size, |
1055 | unsigned alignment); | 1054 | unsigned alignment); |
1056 | extern void drm_mm_put_block(drm_mm_t *mm, drm_mm_node_t *cur); | 1055 | void drm_mm_put_block(drm_mm_node_t * cur); |
1057 | extern drm_mm_node_t *drm_mm_search_free(const drm_mm_t *mm, unsigned long size, | 1056 | extern drm_mm_node_t *drm_mm_search_free(const drm_mm_t *mm, unsigned long size, |
1058 | unsigned alignment, int best_match); | 1057 | unsigned alignment, int best_match); |
1059 | extern int drm_mm_init(drm_mm_t *mm, unsigned long start, unsigned long size); | 1058 | extern int drm_mm_init(drm_mm_t *mm, unsigned long start, unsigned long size); |
1060 | extern void drm_mm_takedown(drm_mm_t *mm); | 1059 | extern void drm_mm_takedown(drm_mm_t *mm); |
1060 | extern int drm_mm_clean(drm_mm_t *mm); | ||
1061 | extern unsigned long drm_mm_tail_space(drm_mm_t *mm); | ||
1062 | extern int drm_mm_remove_space_from_tail(drm_mm_t *mm, unsigned long size); | ||
1063 | extern int drm_mm_add_space_to_tail(drm_mm_t *mm, unsigned long size); | ||
1061 | 1064 | ||
1062 | /* Inline replacements for DRM_IOREMAP macros */ | 1065 | extern void drm_core_ioremap(struct drm_map *map, struct drm_device *dev); |
1063 | static __inline__ void drm_core_ioremap(struct drm_map *map, | 1066 | extern void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev); |
1064 | struct drm_device *dev) | ||
1065 | { | ||
1066 | map->handle = drm_ioremap(map->offset, map->size, dev); | ||
1067 | } | ||
1068 | |||
1069 | #if 0 | ||
1070 | static __inline__ void drm_core_ioremap_nocache(struct drm_map *map, | ||
1071 | struct drm_device *dev) | ||
1072 | { | ||
1073 | map->handle = drm_ioremap_nocache(map->offset, map->size, dev); | ||
1074 | } | ||
1075 | #endif /* 0 */ | ||
1076 | |||
1077 | static __inline__ void drm_core_ioremapfree(struct drm_map *map, | ||
1078 | struct drm_device *dev) | ||
1079 | { | ||
1080 | if (map->handle && map->size) | ||
1081 | drm_ioremapfree(map->handle, map->size, dev); | ||
1082 | } | ||
1083 | 1067 | ||
1084 | static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev, | 1068 | static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev, |
1085 | unsigned int token) | 1069 | unsigned int token) |
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c index 9f65f5697ba8..a6828cc14e58 100644 --- a/drivers/char/drm/drm_bufs.c +++ b/drivers/char/drm/drm_bufs.c | |||
@@ -79,14 +79,14 @@ static int drm_map_handle(drm_device_t *dev, drm_hash_item_t *hash, | |||
79 | 79 | ||
80 | if (!use_hashed_handle) { | 80 | if (!use_hashed_handle) { |
81 | int ret; | 81 | int ret; |
82 | hash->key = user_token; | 82 | hash->key = user_token >> PAGE_SHIFT; |
83 | ret = drm_ht_insert_item(&dev->map_hash, hash); | 83 | ret = drm_ht_insert_item(&dev->map_hash, hash); |
84 | if (ret != -EINVAL) | 84 | if (ret != -EINVAL) |
85 | return ret; | 85 | return ret; |
86 | } | 86 | } |
87 | return drm_ht_just_insert_please(&dev->map_hash, hash, | 87 | return drm_ht_just_insert_please(&dev->map_hash, hash, |
88 | user_token, 32 - PAGE_SHIFT - 3, | 88 | user_token, 32 - PAGE_SHIFT - 3, |
89 | PAGE_SHIFT, DRM_MAP_HASH_OFFSET); | 89 | 0, DRM_MAP_HASH_OFFSET >> PAGE_SHIFT); |
90 | } | 90 | } |
91 | 91 | ||
92 | /** | 92 | /** |
@@ -178,11 +178,11 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, | |||
178 | } | 178 | } |
179 | } | 179 | } |
180 | if (map->type == _DRM_REGISTERS) | 180 | if (map->type == _DRM_REGISTERS) |
181 | map->handle = drm_ioremap(map->offset, map->size, dev); | 181 | map->handle = ioremap(map->offset, map->size); |
182 | break; | 182 | break; |
183 | 183 | ||
184 | case _DRM_SHM: | 184 | case _DRM_SHM: |
185 | map->handle = vmalloc_32(map->size); | 185 | map->handle = vmalloc_user(map->size); |
186 | DRM_DEBUG("%lu %d %p\n", | 186 | DRM_DEBUG("%lu %d %p\n", |
187 | map->size, drm_order(map->size), map->handle); | 187 | map->size, drm_order(map->size), map->handle); |
188 | if (!map->handle) { | 188 | if (!map->handle) { |
@@ -238,7 +238,7 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, | |||
238 | list = drm_alloc(sizeof(*list), DRM_MEM_MAPS); | 238 | list = drm_alloc(sizeof(*list), DRM_MEM_MAPS); |
239 | if (!list) { | 239 | if (!list) { |
240 | if (map->type == _DRM_REGISTERS) | 240 | if (map->type == _DRM_REGISTERS) |
241 | drm_ioremapfree(map->handle, map->size, dev); | 241 | iounmap(map->handle); |
242 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 242 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); |
243 | return -EINVAL; | 243 | return -EINVAL; |
244 | } | 244 | } |
@@ -255,14 +255,14 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, | |||
255 | ret = drm_map_handle(dev, &list->hash, user_token, 0); | 255 | ret = drm_map_handle(dev, &list->hash, user_token, 0); |
256 | if (ret) { | 256 | if (ret) { |
257 | if (map->type == _DRM_REGISTERS) | 257 | if (map->type == _DRM_REGISTERS) |
258 | drm_ioremapfree(map->handle, map->size, dev); | 258 | iounmap(map->handle); |
259 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 259 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); |
260 | drm_free(list, sizeof(*list), DRM_MEM_MAPS); | 260 | drm_free(list, sizeof(*list), DRM_MEM_MAPS); |
261 | mutex_unlock(&dev->struct_mutex); | 261 | mutex_unlock(&dev->struct_mutex); |
262 | return ret; | 262 | return ret; |
263 | } | 263 | } |
264 | 264 | ||
265 | list->user_token = list->hash.key; | 265 | list->user_token = list->hash.key << PAGE_SHIFT; |
266 | mutex_unlock(&dev->struct_mutex); | 266 | mutex_unlock(&dev->struct_mutex); |
267 | 267 | ||
268 | *maplist = list; | 268 | *maplist = list; |
@@ -347,7 +347,8 @@ int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map) | |||
347 | 347 | ||
348 | if (r_list->map == map) { | 348 | if (r_list->map == map) { |
349 | list_del(list); | 349 | list_del(list); |
350 | drm_ht_remove_key(&dev->map_hash, r_list->user_token); | 350 | drm_ht_remove_key(&dev->map_hash, |
351 | r_list->user_token >> PAGE_SHIFT); | ||
351 | drm_free(list, sizeof(*list), DRM_MEM_MAPS); | 352 | drm_free(list, sizeof(*list), DRM_MEM_MAPS); |
352 | break; | 353 | break; |
353 | } | 354 | } |
@@ -362,7 +363,7 @@ int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map) | |||
362 | 363 | ||
363 | switch (map->type) { | 364 | switch (map->type) { |
364 | case _DRM_REGISTERS: | 365 | case _DRM_REGISTERS: |
365 | drm_ioremapfree(map->handle, map->size, dev); | 366 | iounmap(map->handle); |
366 | /* FALLTHROUGH */ | 367 | /* FALLTHROUGH */ |
367 | case _DRM_FRAME_BUFFER: | 368 | case _DRM_FRAME_BUFFER: |
368 | if (drm_core_has_MTRR(dev) && map->mtrr >= 0) { | 369 | if (drm_core_has_MTRR(dev) && map->mtrr >= 0) { |
diff --git a/drivers/char/drm/drm_memory.c b/drivers/char/drm/drm_memory.c index 5681cae1d404..92a867082376 100644 --- a/drivers/char/drm/drm_memory.c +++ b/drivers/char/drm/drm_memory.c | |||
@@ -79,28 +79,6 @@ void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area) | |||
79 | } | 79 | } |
80 | 80 | ||
81 | #if __OS_HAS_AGP | 81 | #if __OS_HAS_AGP |
82 | /* | ||
83 | * Find the drm_map that covers the range [offset, offset+size). | ||
84 | */ | ||
85 | static drm_map_t *drm_lookup_map(unsigned long offset, | ||
86 | unsigned long size, drm_device_t * dev) | ||
87 | { | ||
88 | struct list_head *list; | ||
89 | drm_map_list_t *r_list; | ||
90 | drm_map_t *map; | ||
91 | |||
92 | list_for_each(list, &dev->maplist->head) { | ||
93 | r_list = (drm_map_list_t *) list; | ||
94 | map = r_list->map; | ||
95 | if (!map) | ||
96 | continue; | ||
97 | if (map->offset <= offset | ||
98 | && (offset + size) <= (map->offset + map->size)) | ||
99 | return map; | ||
100 | } | ||
101 | return NULL; | ||
102 | } | ||
103 | |||
104 | static void *agp_remap(unsigned long offset, unsigned long size, | 82 | static void *agp_remap(unsigned long offset, unsigned long size, |
105 | drm_device_t * dev) | 83 | drm_device_t * dev) |
106 | { | 84 | { |
@@ -169,13 +147,6 @@ int drm_unbind_agp(DRM_AGP_MEM * handle) | |||
169 | } | 147 | } |
170 | 148 | ||
171 | #else /* __OS_HAS_AGP */ | 149 | #else /* __OS_HAS_AGP */ |
172 | |||
173 | static inline drm_map_t *drm_lookup_map(unsigned long offset, | ||
174 | unsigned long size, drm_device_t * dev) | ||
175 | { | ||
176 | return NULL; | ||
177 | } | ||
178 | |||
179 | static inline void *agp_remap(unsigned long offset, unsigned long size, | 150 | static inline void *agp_remap(unsigned long offset, unsigned long size, |
180 | drm_device_t * dev) | 151 | drm_device_t * dev) |
181 | { | 152 | { |
@@ -184,57 +155,28 @@ static inline void *agp_remap(unsigned long offset, unsigned long size, | |||
184 | 155 | ||
185 | #endif /* agp */ | 156 | #endif /* agp */ |
186 | 157 | ||
187 | void *drm_ioremap(unsigned long offset, unsigned long size, | 158 | #endif /* debug_memory */ |
188 | drm_device_t * dev) | ||
189 | { | ||
190 | if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) { | ||
191 | drm_map_t *map = drm_lookup_map(offset, size, dev); | ||
192 | |||
193 | if (map && map->type == _DRM_AGP) | ||
194 | return agp_remap(offset, size, dev); | ||
195 | } | ||
196 | return ioremap(offset, size); | ||
197 | } | ||
198 | EXPORT_SYMBOL(drm_ioremap); | ||
199 | 159 | ||
200 | #if 0 | 160 | void drm_core_ioremap(struct drm_map *map, struct drm_device *dev) |
201 | void *drm_ioremap_nocache(unsigned long offset, | ||
202 | unsigned long size, drm_device_t * dev) | ||
203 | { | 161 | { |
204 | if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) { | 162 | if (drm_core_has_AGP(dev) && |
205 | drm_map_t *map = drm_lookup_map(offset, size, dev); | 163 | dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP) |
206 | 164 | map->handle = agp_remap(map->offset, map->size, dev); | |
207 | if (map && map->type == _DRM_AGP) | 165 | else |
208 | return agp_remap(offset, size, dev); | 166 | map->handle = ioremap(map->offset, map->size); |
209 | } | ||
210 | return ioremap_nocache(offset, size); | ||
211 | } | 167 | } |
212 | #endif /* 0 */ | 168 | EXPORT_SYMBOL(drm_core_ioremap); |
213 | 169 | ||
214 | void drm_ioremapfree(void *pt, unsigned long size, | 170 | void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev) |
215 | drm_device_t * dev) | ||
216 | { | 171 | { |
217 | /* | 172 | if (!map->handle || !map->size) |
218 | * This is a bit ugly. It would be much cleaner if the DRM API would use separate | 173 | return; |
219 | * routines for handling mappings in the AGP space. Hopefully this can be done in | 174 | |
220 | * a future revision of the interface... | 175 | if (drm_core_has_AGP(dev) && |
221 | */ | 176 | dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP) |
222 | if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture | 177 | vunmap(map->handle); |
223 | && ((unsigned long)pt >= VMALLOC_START | 178 | else |
224 | && (unsigned long)pt < VMALLOC_END)) { | 179 | iounmap(map->handle); |
225 | unsigned long offset; | ||
226 | drm_map_t *map; | ||
227 | |||
228 | offset = drm_follow_page(pt) | ((unsigned long)pt & ~PAGE_MASK); | ||
229 | map = drm_lookup_map(offset, size, dev); | ||
230 | if (map && map->type == _DRM_AGP) { | ||
231 | vunmap(pt); | ||
232 | return; | ||
233 | } | ||
234 | } | ||
235 | |||
236 | iounmap(pt); | ||
237 | } | 180 | } |
238 | EXPORT_SYMBOL(drm_ioremapfree); | 181 | EXPORT_SYMBOL(drm_core_ioremapfree); |
239 | 182 | ||
240 | #endif /* debug_memory */ | ||
diff --git a/drivers/char/drm/drm_memory.h b/drivers/char/drm/drm_memory.h index f1b97aff10cf..63e425b5ea82 100644 --- a/drivers/char/drm/drm_memory.h +++ b/drivers/char/drm/drm_memory.h | |||
@@ -56,26 +56,6 @@ | |||
56 | # endif | 56 | # endif |
57 | #endif | 57 | #endif |
58 | 58 | ||
59 | static inline unsigned long drm_follow_page(void *vaddr) | ||
60 | { | ||
61 | pgd_t *pgd = pgd_offset_k((unsigned long)vaddr); | ||
62 | pud_t *pud = pud_offset(pgd, (unsigned long)vaddr); | ||
63 | pmd_t *pmd = pmd_offset(pud, (unsigned long)vaddr); | ||
64 | pte_t *ptep = pte_offset_kernel(pmd, (unsigned long)vaddr); | ||
65 | return pte_pfn(*ptep) << PAGE_SHIFT; | ||
66 | } | ||
67 | |||
68 | #else /* __OS_HAS_AGP */ | 59 | #else /* __OS_HAS_AGP */ |
69 | 60 | ||
70 | static inline unsigned long drm_follow_page(void *vaddr) | ||
71 | { | ||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | #endif | 61 | #endif |
76 | |||
77 | void *drm_ioremap(unsigned long offset, unsigned long size, | ||
78 | drm_device_t * dev); | ||
79 | |||
80 | void drm_ioremapfree(void *pt, unsigned long size, | ||
81 | drm_device_t * dev); | ||
diff --git a/drivers/char/drm/drm_memory_debug.h b/drivers/char/drm/drm_memory_debug.h index 74581af806e1..6463271deea8 100644 --- a/drivers/char/drm/drm_memory_debug.h +++ b/drivers/char/drm/drm_memory_debug.h | |||
@@ -205,76 +205,6 @@ void drm_free (void *pt, size_t size, int area) { | |||
205 | } | 205 | } |
206 | } | 206 | } |
207 | 207 | ||
208 | void *drm_ioremap (unsigned long offset, unsigned long size, | ||
209 | drm_device_t * dev) { | ||
210 | void *pt; | ||
211 | |||
212 | if (!size) { | ||
213 | DRM_MEM_ERROR(DRM_MEM_MAPPINGS, | ||
214 | "Mapping 0 bytes at 0x%08lx\n", offset); | ||
215 | return NULL; | ||
216 | } | ||
217 | |||
218 | if (!(pt = drm_ioremap(offset, size, dev))) { | ||
219 | spin_lock(&drm_mem_lock); | ||
220 | ++drm_mem_stats[DRM_MEM_MAPPINGS].fail_count; | ||
221 | spin_unlock(&drm_mem_lock); | ||
222 | return NULL; | ||
223 | } | ||
224 | spin_lock(&drm_mem_lock); | ||
225 | ++drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count; | ||
226 | drm_mem_stats[DRM_MEM_MAPPINGS].bytes_allocated += size; | ||
227 | spin_unlock(&drm_mem_lock); | ||
228 | return pt; | ||
229 | } | ||
230 | |||
231 | #if 0 | ||
232 | void *drm_ioremap_nocache (unsigned long offset, unsigned long size, | ||
233 | drm_device_t * dev) { | ||
234 | void *pt; | ||
235 | |||
236 | if (!size) { | ||
237 | DRM_MEM_ERROR(DRM_MEM_MAPPINGS, | ||
238 | "Mapping 0 bytes at 0x%08lx\n", offset); | ||
239 | return NULL; | ||
240 | } | ||
241 | |||
242 | if (!(pt = drm_ioremap_nocache(offset, size, dev))) { | ||
243 | spin_lock(&drm_mem_lock); | ||
244 | ++drm_mem_stats[DRM_MEM_MAPPINGS].fail_count; | ||
245 | spin_unlock(&drm_mem_lock); | ||
246 | return NULL; | ||
247 | } | ||
248 | spin_lock(&drm_mem_lock); | ||
249 | ++drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count; | ||
250 | drm_mem_stats[DRM_MEM_MAPPINGS].bytes_allocated += size; | ||
251 | spin_unlock(&drm_mem_lock); | ||
252 | return pt; | ||
253 | } | ||
254 | #endif /* 0 */ | ||
255 | |||
256 | void drm_ioremapfree (void *pt, unsigned long size, drm_device_t * dev) { | ||
257 | int alloc_count; | ||
258 | int free_count; | ||
259 | |||
260 | if (!pt) | ||
261 | DRM_MEM_ERROR(DRM_MEM_MAPPINGS, | ||
262 | "Attempt to free NULL pointer\n"); | ||
263 | else | ||
264 | drm_ioremapfree(pt, size, dev); | ||
265 | |||
266 | spin_lock(&drm_mem_lock); | ||
267 | drm_mem_stats[DRM_MEM_MAPPINGS].bytes_freed += size; | ||
268 | free_count = ++drm_mem_stats[DRM_MEM_MAPPINGS].free_count; | ||
269 | alloc_count = drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count; | ||
270 | spin_unlock(&drm_mem_lock); | ||
271 | if (free_count > alloc_count) { | ||
272 | DRM_MEM_ERROR(DRM_MEM_MAPPINGS, | ||
273 | "Excess frees: %d frees, %d allocs\n", | ||
274 | free_count, alloc_count); | ||
275 | } | ||
276 | } | ||
277 | |||
278 | #if __OS_HAS_AGP | 208 | #if __OS_HAS_AGP |
279 | 209 | ||
280 | DRM_AGP_MEM *drm_alloc_agp (drm_device_t *dev, int pages, u32 type) { | 210 | DRM_AGP_MEM *drm_alloc_agp (drm_device_t *dev, int pages, u32 type) { |
diff --git a/drivers/char/drm/drm_mm.c b/drivers/char/drm/drm_mm.c index 617526bd5b0c..9b46b85027d0 100644 --- a/drivers/char/drm/drm_mm.c +++ b/drivers/char/drm/drm_mm.c | |||
@@ -42,36 +42,131 @@ | |||
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include "drmP.h" | 44 | #include "drmP.h" |
45 | #include <linux/slab.h> | ||
46 | |||
47 | unsigned long drm_mm_tail_space(drm_mm_t *mm) | ||
48 | { | ||
49 | struct list_head *tail_node; | ||
50 | drm_mm_node_t *entry; | ||
51 | |||
52 | tail_node = mm->ml_entry.prev; | ||
53 | entry = list_entry(tail_node, drm_mm_node_t, ml_entry); | ||
54 | if (!entry->free) | ||
55 | return 0; | ||
56 | |||
57 | return entry->size; | ||
58 | } | ||
59 | |||
60 | int drm_mm_remove_space_from_tail(drm_mm_t *mm, unsigned long size) | ||
61 | { | ||
62 | struct list_head *tail_node; | ||
63 | drm_mm_node_t *entry; | ||
64 | |||
65 | tail_node = mm->ml_entry.prev; | ||
66 | entry = list_entry(tail_node, drm_mm_node_t, ml_entry); | ||
67 | if (!entry->free) | ||
68 | return -ENOMEM; | ||
69 | |||
70 | if (entry->size <= size) | ||
71 | return -ENOMEM; | ||
72 | |||
73 | entry->size -= size; | ||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | |||
78 | static int drm_mm_create_tail_node(drm_mm_t *mm, | ||
79 | unsigned long start, | ||
80 | unsigned long size) | ||
81 | { | ||
82 | drm_mm_node_t *child; | ||
83 | |||
84 | child = (drm_mm_node_t *) | ||
85 | drm_alloc(sizeof(*child), DRM_MEM_MM); | ||
86 | if (!child) | ||
87 | return -ENOMEM; | ||
88 | |||
89 | child->free = 1; | ||
90 | child->size = size; | ||
91 | child->start = start; | ||
92 | child->mm = mm; | ||
93 | |||
94 | list_add_tail(&child->ml_entry, &mm->ml_entry); | ||
95 | list_add_tail(&child->fl_entry, &mm->fl_entry); | ||
96 | |||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | |||
101 | int drm_mm_add_space_to_tail(drm_mm_t *mm, unsigned long size) | ||
102 | { | ||
103 | struct list_head *tail_node; | ||
104 | drm_mm_node_t *entry; | ||
105 | |||
106 | tail_node = mm->ml_entry.prev; | ||
107 | entry = list_entry(tail_node, drm_mm_node_t, ml_entry); | ||
108 | if (!entry->free) { | ||
109 | return drm_mm_create_tail_node(mm, entry->start + entry->size, size); | ||
110 | } | ||
111 | entry->size += size; | ||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | static drm_mm_node_t *drm_mm_split_at_start(drm_mm_node_t *parent, | ||
116 | unsigned long size) | ||
117 | { | ||
118 | drm_mm_node_t *child; | ||
119 | |||
120 | child = (drm_mm_node_t *) | ||
121 | drm_alloc(sizeof(*child), DRM_MEM_MM); | ||
122 | if (!child) | ||
123 | return NULL; | ||
124 | |||
125 | INIT_LIST_HEAD(&child->fl_entry); | ||
126 | |||
127 | child->free = 0; | ||
128 | child->size = size; | ||
129 | child->start = parent->start; | ||
130 | child->mm = parent->mm; | ||
131 | |||
132 | list_add_tail(&child->ml_entry, &parent->ml_entry); | ||
133 | INIT_LIST_HEAD(&child->fl_entry); | ||
134 | |||
135 | parent->size -= size; | ||
136 | parent->start += size; | ||
137 | return child; | ||
138 | } | ||
139 | |||
140 | |||
45 | 141 | ||
46 | drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent, | 142 | drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent, |
47 | unsigned long size, unsigned alignment) | 143 | unsigned long size, unsigned alignment) |
48 | { | 144 | { |
49 | 145 | ||
146 | drm_mm_node_t *align_splitoff = NULL; | ||
50 | drm_mm_node_t *child; | 147 | drm_mm_node_t *child; |
148 | unsigned tmp = 0; | ||
51 | 149 | ||
52 | if (alignment) | 150 | if (alignment) |
53 | size += alignment - 1; | 151 | tmp = parent->start % alignment; |
152 | |||
153 | if (tmp) { | ||
154 | align_splitoff = drm_mm_split_at_start(parent, alignment - tmp); | ||
155 | if (!align_splitoff) | ||
156 | return NULL; | ||
157 | } | ||
54 | 158 | ||
55 | if (parent->size == size) { | 159 | if (parent->size == size) { |
56 | list_del_init(&parent->fl_entry); | 160 | list_del_init(&parent->fl_entry); |
57 | parent->free = 0; | 161 | parent->free = 0; |
58 | return parent; | 162 | return parent; |
59 | } else { | 163 | } else { |
60 | child = (drm_mm_node_t *) drm_alloc(sizeof(*child), DRM_MEM_MM); | 164 | child = drm_mm_split_at_start(parent, size); |
61 | if (!child) | 165 | } |
62 | return NULL; | ||
63 | |||
64 | INIT_LIST_HEAD(&child->ml_entry); | ||
65 | INIT_LIST_HEAD(&child->fl_entry); | ||
66 | 166 | ||
67 | child->free = 0; | 167 | if (align_splitoff) |
68 | child->size = size; | 168 | drm_mm_put_block(align_splitoff); |
69 | child->start = parent->start; | ||
70 | 169 | ||
71 | list_add_tail(&child->ml_entry, &parent->ml_entry); | ||
72 | parent->size -= size; | ||
73 | parent->start += size; | ||
74 | } | ||
75 | return child; | 170 | return child; |
76 | } | 171 | } |
77 | 172 | ||
@@ -80,12 +175,12 @@ drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent, | |||
80 | * Otherwise add to the free stack. | 175 | * Otherwise add to the free stack. |
81 | */ | 176 | */ |
82 | 177 | ||
83 | void drm_mm_put_block(drm_mm_t * mm, drm_mm_node_t * cur) | 178 | void drm_mm_put_block(drm_mm_node_t * cur) |
84 | { | 179 | { |
85 | 180 | ||
86 | drm_mm_node_t *list_root = &mm->root_node; | 181 | drm_mm_t *mm = cur->mm; |
87 | struct list_head *cur_head = &cur->ml_entry; | 182 | struct list_head *cur_head = &cur->ml_entry; |
88 | struct list_head *root_head = &list_root->ml_entry; | 183 | struct list_head *root_head = &mm->ml_entry; |
89 | drm_mm_node_t *prev_node = NULL; | 184 | drm_mm_node_t *prev_node = NULL; |
90 | drm_mm_node_t *next_node; | 185 | drm_mm_node_t *next_node; |
91 | 186 | ||
@@ -116,7 +211,7 @@ void drm_mm_put_block(drm_mm_t * mm, drm_mm_node_t * cur) | |||
116 | } | 211 | } |
117 | if (!merged) { | 212 | if (!merged) { |
118 | cur->free = 1; | 213 | cur->free = 1; |
119 | list_add(&cur->fl_entry, &list_root->fl_entry); | 214 | list_add(&cur->fl_entry, &mm->fl_entry); |
120 | } else { | 215 | } else { |
121 | list_del(&cur->ml_entry); | 216 | list_del(&cur->ml_entry); |
122 | drm_free(cur, sizeof(*cur), DRM_MEM_MM); | 217 | drm_free(cur, sizeof(*cur), DRM_MEM_MM); |
@@ -128,20 +223,30 @@ drm_mm_node_t *drm_mm_search_free(const drm_mm_t * mm, | |||
128 | unsigned alignment, int best_match) | 223 | unsigned alignment, int best_match) |
129 | { | 224 | { |
130 | struct list_head *list; | 225 | struct list_head *list; |
131 | const struct list_head *free_stack = &mm->root_node.fl_entry; | 226 | const struct list_head *free_stack = &mm->fl_entry; |
132 | drm_mm_node_t *entry; | 227 | drm_mm_node_t *entry; |
133 | drm_mm_node_t *best; | 228 | drm_mm_node_t *best; |
134 | unsigned long best_size; | 229 | unsigned long best_size; |
230 | unsigned wasted; | ||
135 | 231 | ||
136 | best = NULL; | 232 | best = NULL; |
137 | best_size = ~0UL; | 233 | best_size = ~0UL; |
138 | 234 | ||
139 | if (alignment) | ||
140 | size += alignment - 1; | ||
141 | |||
142 | list_for_each(list, free_stack) { | 235 | list_for_each(list, free_stack) { |
143 | entry = list_entry(list, drm_mm_node_t, fl_entry); | 236 | entry = list_entry(list, drm_mm_node_t, fl_entry); |
144 | if (entry->size >= size) { | 237 | wasted = 0; |
238 | |||
239 | if (entry->size < size) | ||
240 | continue; | ||
241 | |||
242 | if (alignment) { | ||
243 | register unsigned tmp = entry->start % alignment; | ||
244 | if (tmp) | ||
245 | wasted += alignment - tmp; | ||
246 | } | ||
247 | |||
248 | |||
249 | if (entry->size >= size + wasted) { | ||
145 | if (!best_match) | 250 | if (!best_match) |
146 | return entry; | 251 | return entry; |
147 | if (size < best_size) { | 252 | if (size < best_size) { |
@@ -154,40 +259,32 @@ drm_mm_node_t *drm_mm_search_free(const drm_mm_t * mm, | |||
154 | return best; | 259 | return best; |
155 | } | 260 | } |
156 | 261 | ||
157 | int drm_mm_init(drm_mm_t * mm, unsigned long start, unsigned long size) | 262 | int drm_mm_clean(drm_mm_t * mm) |
158 | { | 263 | { |
159 | drm_mm_node_t *child; | 264 | struct list_head *head = &mm->ml_entry; |
160 | |||
161 | INIT_LIST_HEAD(&mm->root_node.ml_entry); | ||
162 | INIT_LIST_HEAD(&mm->root_node.fl_entry); | ||
163 | child = (drm_mm_node_t *) drm_alloc(sizeof(*child), DRM_MEM_MM); | ||
164 | if (!child) | ||
165 | return -ENOMEM; | ||
166 | |||
167 | INIT_LIST_HEAD(&child->ml_entry); | ||
168 | INIT_LIST_HEAD(&child->fl_entry); | ||
169 | 265 | ||
170 | child->start = start; | 266 | return (head->next->next == head); |
171 | child->size = size; | 267 | } |
172 | child->free = 1; | ||
173 | 268 | ||
174 | list_add(&child->fl_entry, &mm->root_node.fl_entry); | 269 | int drm_mm_init(drm_mm_t * mm, unsigned long start, unsigned long size) |
175 | list_add(&child->ml_entry, &mm->root_node.ml_entry); | 270 | { |
271 | INIT_LIST_HEAD(&mm->ml_entry); | ||
272 | INIT_LIST_HEAD(&mm->fl_entry); | ||
176 | 273 | ||
177 | return 0; | 274 | return drm_mm_create_tail_node(mm, start, size); |
178 | } | 275 | } |
179 | 276 | ||
180 | EXPORT_SYMBOL(drm_mm_init); | 277 | EXPORT_SYMBOL(drm_mm_init); |
181 | 278 | ||
182 | void drm_mm_takedown(drm_mm_t * mm) | 279 | void drm_mm_takedown(drm_mm_t * mm) |
183 | { | 280 | { |
184 | struct list_head *bnode = mm->root_node.fl_entry.next; | 281 | struct list_head *bnode = mm->fl_entry.next; |
185 | drm_mm_node_t *entry; | 282 | drm_mm_node_t *entry; |
186 | 283 | ||
187 | entry = list_entry(bnode, drm_mm_node_t, fl_entry); | 284 | entry = list_entry(bnode, drm_mm_node_t, fl_entry); |
188 | 285 | ||
189 | if (entry->ml_entry.next != &mm->root_node.ml_entry || | 286 | if (entry->ml_entry.next != &mm->ml_entry || |
190 | entry->fl_entry.next != &mm->root_node.fl_entry) { | 287 | entry->fl_entry.next != &mm->fl_entry) { |
191 | DRM_ERROR("Memory manager not clean. Delaying takedown\n"); | 288 | DRM_ERROR("Memory manager not clean. Delaying takedown\n"); |
192 | return; | 289 | return; |
193 | } | 290 | } |
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h index 09398d5fbd3f..ad54b845978b 100644 --- a/drivers/char/drm/drm_pciids.h +++ b/drivers/char/drm/drm_pciids.h | |||
@@ -226,12 +226,14 @@ | |||
226 | {0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 226 | {0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
227 | {0x1106, 0x3118, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \ | 227 | {0x1106, 0x3118, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \ |
228 | {0x1106, 0x3122, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 228 | {0x1106, 0x3122, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
229 | {0x1106, 0x7204, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | ||
229 | {0x1106, 0x7205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 230 | {0x1106, 0x7205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
230 | {0x1106, 0x3108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 231 | {0x1106, 0x3108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
231 | {0x1106, 0x3304, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 232 | {0x1106, 0x3304, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
232 | {0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 233 | {0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
233 | {0x1106, 0x3344, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 234 | {0x1106, 0x3344, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
234 | {0x1106, 0x7204, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 235 | {0x1106, 0x3343, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
236 | {0x1106, 0x3230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_DX9_0}, \ | ||
235 | {0, 0, 0} | 237 | {0, 0, 0} |
236 | 238 | ||
237 | #define i810_PCI_IDS \ | 239 | #define i810_PCI_IDS \ |
diff --git a/drivers/char/drm/drm_proc.c b/drivers/char/drm/drm_proc.c index 62d5fe15f046..7fd0da712142 100644 --- a/drivers/char/drm/drm_proc.c +++ b/drivers/char/drm/drm_proc.c | |||
@@ -500,7 +500,7 @@ static int drm__vma_info(char *buf, char **start, off_t offset, int request, | |||
500 | for (pt = dev->vmalist; pt; pt = pt->next) { | 500 | for (pt = dev->vmalist; pt; pt = pt->next) { |
501 | if (!(vma = pt->vma)) | 501 | if (!(vma = pt->vma)) |
502 | continue; | 502 | continue; |
503 | DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx", | 503 | DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx000", |
504 | pt->pid, | 504 | pt->pid, |
505 | vma->vm_start, | 505 | vma->vm_start, |
506 | vma->vm_end, | 506 | vma->vm_end, |
@@ -510,7 +510,7 @@ static int drm__vma_info(char *buf, char **start, off_t offset, int request, | |||
510 | vma->vm_flags & VM_MAYSHARE ? 's' : 'p', | 510 | vma->vm_flags & VM_MAYSHARE ? 's' : 'p', |
511 | vma->vm_flags & VM_LOCKED ? 'l' : '-', | 511 | vma->vm_flags & VM_LOCKED ? 'l' : '-', |
512 | vma->vm_flags & VM_IO ? 'i' : '-', | 512 | vma->vm_flags & VM_IO ? 'i' : '-', |
513 | vma->vm_pgoff << PAGE_SHIFT); | 513 | vma->vm_pgoff); |
514 | 514 | ||
515 | #if defined(__i386__) | 515 | #if defined(__i386__) |
516 | pgprot = pgprot_val(vma->vm_page_prot); | 516 | pgprot = pgprot_val(vma->vm_page_prot); |
diff --git a/drivers/char/drm/drm_sman.c b/drivers/char/drm/drm_sman.c index 19c81d2e13d0..e15db6d6bea9 100644 --- a/drivers/char/drm/drm_sman.c +++ b/drivers/char/drm/drm_sman.c | |||
@@ -101,10 +101,9 @@ static void *drm_sman_mm_allocate(void *private, unsigned long size, | |||
101 | 101 | ||
102 | static void drm_sman_mm_free(void *private, void *ref) | 102 | static void drm_sman_mm_free(void *private, void *ref) |
103 | { | 103 | { |
104 | drm_mm_t *mm = (drm_mm_t *) private; | ||
105 | drm_mm_node_t *node = (drm_mm_node_t *) ref; | 104 | drm_mm_node_t *node = (drm_mm_node_t *) ref; |
106 | 105 | ||
107 | drm_mm_put_block(mm, node); | 106 | drm_mm_put_block(node); |
108 | } | 107 | } |
109 | 108 | ||
110 | static void drm_sman_mm_destroy(void *private) | 109 | static void drm_sman_mm_destroy(void *private) |
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c index b9cfc077f6bc..54a632848955 100644 --- a/drivers/char/drm/drm_vm.c +++ b/drivers/char/drm/drm_vm.c | |||
@@ -70,7 +70,7 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma, | |||
70 | if (!dev->agp || !dev->agp->cant_use_aperture) | 70 | if (!dev->agp || !dev->agp->cant_use_aperture) |
71 | goto vm_nopage_error; | 71 | goto vm_nopage_error; |
72 | 72 | ||
73 | if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff << PAGE_SHIFT, &hash)) | 73 | if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff, &hash)) |
74 | goto vm_nopage_error; | 74 | goto vm_nopage_error; |
75 | 75 | ||
76 | r_list = drm_hash_entry(hash, drm_map_list_t, hash); | 76 | r_list = drm_hash_entry(hash, drm_map_list_t, hash); |
@@ -227,7 +227,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma) | |||
227 | map->size); | 227 | map->size); |
228 | DRM_DEBUG("mtrr_del = %d\n", retcode); | 228 | DRM_DEBUG("mtrr_del = %d\n", retcode); |
229 | } | 229 | } |
230 | drm_ioremapfree(map->handle, map->size, dev); | 230 | iounmap(map->handle); |
231 | break; | 231 | break; |
232 | case _DRM_SHM: | 232 | case _DRM_SHM: |
233 | vfree(map->handle); | 233 | vfree(map->handle); |
@@ -463,8 +463,8 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma) | |||
463 | lock_kernel(); | 463 | lock_kernel(); |
464 | dev = priv->head->dev; | 464 | dev = priv->head->dev; |
465 | dma = dev->dma; | 465 | dma = dev->dma; |
466 | DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n", | 466 | DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n", |
467 | vma->vm_start, vma->vm_end, vma->vm_pgoff << PAGE_SHIFT); | 467 | vma->vm_start, vma->vm_end, vma->vm_pgoff); |
468 | 468 | ||
469 | /* Length must match exact page count */ | 469 | /* Length must match exact page count */ |
470 | if (!dma || (length >> PAGE_SHIFT) != dma->page_count) { | 470 | if (!dma || (length >> PAGE_SHIFT) != dma->page_count) { |
@@ -537,8 +537,8 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) | |||
537 | unsigned long offset = 0; | 537 | unsigned long offset = 0; |
538 | drm_hash_item_t *hash; | 538 | drm_hash_item_t *hash; |
539 | 539 | ||
540 | DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n", | 540 | DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n", |
541 | vma->vm_start, vma->vm_end, vma->vm_pgoff << PAGE_SHIFT); | 541 | vma->vm_start, vma->vm_end, vma->vm_pgoff); |
542 | 542 | ||
543 | if (!priv->authenticated) | 543 | if (!priv->authenticated) |
544 | return -EACCES; | 544 | return -EACCES; |
@@ -547,7 +547,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) | |||
547 | * the AGP mapped at physical address 0 | 547 | * the AGP mapped at physical address 0 |
548 | * --BenH. | 548 | * --BenH. |
549 | */ | 549 | */ |
550 | if (!(vma->vm_pgoff << PAGE_SHIFT) | 550 | if (!vma->vm_pgoff |
551 | #if __OS_HAS_AGP | 551 | #if __OS_HAS_AGP |
552 | && (!dev->agp | 552 | && (!dev->agp |
553 | || dev->agp->agp_info.device->vendor != PCI_VENDOR_ID_APPLE) | 553 | || dev->agp->agp_info.device->vendor != PCI_VENDOR_ID_APPLE) |
@@ -555,7 +555,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) | |||
555 | ) | 555 | ) |
556 | return drm_mmap_dma(filp, vma); | 556 | return drm_mmap_dma(filp, vma); |
557 | 557 | ||
558 | if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff << PAGE_SHIFT, &hash)) { | 558 | if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff, &hash)) { |
559 | DRM_ERROR("Could not find map\n"); | 559 | DRM_ERROR("Could not find map\n"); |
560 | return -EINVAL; | 560 | return -EINVAL; |
561 | } | 561 | } |
diff --git a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c index fa2de70f7401..60cb4e45a75e 100644 --- a/drivers/char/drm/i810_dma.c +++ b/drivers/char/drm/i810_dma.c | |||
@@ -219,8 +219,7 @@ static int i810_dma_cleanup(drm_device_t * dev) | |||
219 | (drm_i810_private_t *) dev->dev_private; | 219 | (drm_i810_private_t *) dev->dev_private; |
220 | 220 | ||
221 | if (dev_priv->ring.virtual_start) { | 221 | if (dev_priv->ring.virtual_start) { |
222 | drm_ioremapfree((void *)dev_priv->ring.virtual_start, | 222 | drm_core_ioremapfree(&dev_priv->ring.map, dev); |
223 | dev_priv->ring.Size, dev); | ||
224 | } | 223 | } |
225 | if (dev_priv->hw_status_page) { | 224 | if (dev_priv->hw_status_page) { |
226 | pci_free_consistent(dev->pdev, PAGE_SIZE, | 225 | pci_free_consistent(dev->pdev, PAGE_SIZE, |
@@ -236,9 +235,9 @@ static int i810_dma_cleanup(drm_device_t * dev) | |||
236 | for (i = 0; i < dma->buf_count; i++) { | 235 | for (i = 0; i < dma->buf_count; i++) { |
237 | drm_buf_t *buf = dma->buflist[i]; | 236 | drm_buf_t *buf = dma->buflist[i]; |
238 | drm_i810_buf_priv_t *buf_priv = buf->dev_private; | 237 | drm_i810_buf_priv_t *buf_priv = buf->dev_private; |
238 | |||
239 | if (buf_priv->kernel_virtual && buf->total) | 239 | if (buf_priv->kernel_virtual && buf->total) |
240 | drm_ioremapfree(buf_priv->kernel_virtual, | 240 | drm_core_ioremapfree(&buf_priv->map, dev); |
241 | buf->total, dev); | ||
242 | } | 241 | } |
243 | } | 242 | } |
244 | return 0; | 243 | return 0; |
@@ -311,8 +310,15 @@ static int i810_freelist_init(drm_device_t * dev, drm_i810_private_t * dev_priv) | |||
311 | 310 | ||
312 | *buf_priv->in_use = I810_BUF_FREE; | 311 | *buf_priv->in_use = I810_BUF_FREE; |
313 | 312 | ||
314 | buf_priv->kernel_virtual = drm_ioremap(buf->bus_address, | 313 | buf_priv->map.offset = buf->bus_address; |
315 | buf->total, dev); | 314 | buf_priv->map.size = buf->total; |
315 | buf_priv->map.type = _DRM_AGP; | ||
316 | buf_priv->map.flags = 0; | ||
317 | buf_priv->map.mtrr = 0; | ||
318 | |||
319 | drm_core_ioremap(&buf_priv->map, dev); | ||
320 | buf_priv->kernel_virtual = buf_priv->map.handle; | ||
321 | |||
316 | } | 322 | } |
317 | return 0; | 323 | return 0; |
318 | } | 324 | } |
@@ -363,18 +369,24 @@ static int i810_dma_initialize(drm_device_t * dev, | |||
363 | dev_priv->ring.End = init->ring_end; | 369 | dev_priv->ring.End = init->ring_end; |
364 | dev_priv->ring.Size = init->ring_size; | 370 | dev_priv->ring.Size = init->ring_size; |
365 | 371 | ||
366 | dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base + | 372 | dev_priv->ring.map.offset = dev->agp->base + init->ring_start; |
367 | init->ring_start, | 373 | dev_priv->ring.map.size = init->ring_size; |
368 | init->ring_size, dev); | 374 | dev_priv->ring.map.type = _DRM_AGP; |
375 | dev_priv->ring.map.flags = 0; | ||
376 | dev_priv->ring.map.mtrr = 0; | ||
369 | 377 | ||
370 | if (dev_priv->ring.virtual_start == NULL) { | 378 | drm_core_ioremap(&dev_priv->ring.map, dev); |
379 | |||
380 | if (dev_priv->ring.map.handle == NULL) { | ||
371 | dev->dev_private = (void *)dev_priv; | 381 | dev->dev_private = (void *)dev_priv; |
372 | i810_dma_cleanup(dev); | 382 | i810_dma_cleanup(dev); |
373 | DRM_ERROR("can not ioremap virtual address for" | 383 | DRM_ERROR("can not ioremap virtual address for" |
374 | " ring buffer\n"); | 384 | " ring buffer\n"); |
375 | return -ENOMEM; | 385 | return DRM_ERR(ENOMEM); |
376 | } | 386 | } |
377 | 387 | ||
388 | dev_priv->ring.virtual_start = dev_priv->ring.map.handle; | ||
389 | |||
378 | dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; | 390 | dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; |
379 | 391 | ||
380 | dev_priv->w = init->w; | 392 | dev_priv->w = init->w; |
diff --git a/drivers/char/drm/i810_drv.h b/drivers/char/drm/i810_drv.h index e8cf3ff606f0..e6df49f4928a 100644 --- a/drivers/char/drm/i810_drv.h +++ b/drivers/char/drm/i810_drv.h | |||
@@ -61,6 +61,7 @@ typedef struct drm_i810_buf_priv { | |||
61 | int currently_mapped; | 61 | int currently_mapped; |
62 | void *virtual; | 62 | void *virtual; |
63 | void *kernel_virtual; | 63 | void *kernel_virtual; |
64 | drm_local_map_t map; | ||
64 | } drm_i810_buf_priv_t; | 65 | } drm_i810_buf_priv_t; |
65 | 66 | ||
66 | typedef struct _drm_i810_ring_buffer { | 67 | typedef struct _drm_i810_ring_buffer { |
@@ -72,6 +73,7 @@ typedef struct _drm_i810_ring_buffer { | |||
72 | int head; | 73 | int head; |
73 | int tail; | 74 | int tail; |
74 | int space; | 75 | int space; |
76 | drm_local_map_t map; | ||
75 | } drm_i810_ring_buffer_t; | 77 | } drm_i810_ring_buffer_t; |
76 | 78 | ||
77 | typedef struct drm_i810_private { | 79 | typedef struct drm_i810_private { |
diff --git a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c index 4f0e5746ab33..95224455ec0c 100644 --- a/drivers/char/drm/i830_dma.c +++ b/drivers/char/drm/i830_dma.c | |||
@@ -223,8 +223,7 @@ static int i830_dma_cleanup(drm_device_t * dev) | |||
223 | (drm_i830_private_t *) dev->dev_private; | 223 | (drm_i830_private_t *) dev->dev_private; |
224 | 224 | ||
225 | if (dev_priv->ring.virtual_start) { | 225 | if (dev_priv->ring.virtual_start) { |
226 | drm_ioremapfree((void *)dev_priv->ring.virtual_start, | 226 | drm_core_ioremapfree(&dev_priv->ring.map, dev); |
227 | dev_priv->ring.Size, dev); | ||
228 | } | 227 | } |
229 | if (dev_priv->hw_status_page) { | 228 | if (dev_priv->hw_status_page) { |
230 | pci_free_consistent(dev->pdev, PAGE_SIZE, | 229 | pci_free_consistent(dev->pdev, PAGE_SIZE, |
@@ -242,8 +241,7 @@ static int i830_dma_cleanup(drm_device_t * dev) | |||
242 | drm_buf_t *buf = dma->buflist[i]; | 241 | drm_buf_t *buf = dma->buflist[i]; |
243 | drm_i830_buf_priv_t *buf_priv = buf->dev_private; | 242 | drm_i830_buf_priv_t *buf_priv = buf->dev_private; |
244 | if (buf_priv->kernel_virtual && buf->total) | 243 | if (buf_priv->kernel_virtual && buf->total) |
245 | drm_ioremapfree(buf_priv->kernel_virtual, | 244 | drm_core_ioremapfree(&buf_priv->map, dev); |
246 | buf->total, dev); | ||
247 | } | 245 | } |
248 | } | 246 | } |
249 | return 0; | 247 | return 0; |
@@ -320,8 +318,14 @@ static int i830_freelist_init(drm_device_t * dev, drm_i830_private_t * dev_priv) | |||
320 | 318 | ||
321 | *buf_priv->in_use = I830_BUF_FREE; | 319 | *buf_priv->in_use = I830_BUF_FREE; |
322 | 320 | ||
323 | buf_priv->kernel_virtual = drm_ioremap(buf->bus_address, | 321 | buf_priv->map.offset = buf->bus_address; |
324 | buf->total, dev); | 322 | buf_priv->map.size = buf->total; |
323 | buf_priv->map.type = _DRM_AGP; | ||
324 | buf_priv->map.flags = 0; | ||
325 | buf_priv->map.mtrr = 0; | ||
326 | |||
327 | drm_core_ioremap(&buf_priv->map, dev); | ||
328 | buf_priv->kernel_virtual = buf_priv->map.handle; | ||
325 | } | 329 | } |
326 | return 0; | 330 | return 0; |
327 | } | 331 | } |
@@ -373,18 +377,24 @@ static int i830_dma_initialize(drm_device_t * dev, | |||
373 | dev_priv->ring.End = init->ring_end; | 377 | dev_priv->ring.End = init->ring_end; |
374 | dev_priv->ring.Size = init->ring_size; | 378 | dev_priv->ring.Size = init->ring_size; |
375 | 379 | ||
376 | dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base + | 380 | dev_priv->ring.map.offset = dev->agp->base + init->ring_start; |
377 | init->ring_start, | 381 | dev_priv->ring.map.size = init->ring_size; |
378 | init->ring_size, dev); | 382 | dev_priv->ring.map.type = _DRM_AGP; |
383 | dev_priv->ring.map.flags = 0; | ||
384 | dev_priv->ring.map.mtrr = 0; | ||
385 | |||
386 | drm_core_ioremap(&dev_priv->ring.map, dev); | ||
379 | 387 | ||
380 | if (dev_priv->ring.virtual_start == NULL) { | 388 | if (dev_priv->ring.map.handle == NULL) { |
381 | dev->dev_private = (void *)dev_priv; | 389 | dev->dev_private = (void *)dev_priv; |
382 | i830_dma_cleanup(dev); | 390 | i830_dma_cleanup(dev); |
383 | DRM_ERROR("can not ioremap virtual address for" | 391 | DRM_ERROR("can not ioremap virtual address for" |
384 | " ring buffer\n"); | 392 | " ring buffer\n"); |
385 | return -ENOMEM; | 393 | return DRM_ERR(ENOMEM); |
386 | } | 394 | } |
387 | 395 | ||
396 | dev_priv->ring.virtual_start = dev_priv->ring.map.handle; | ||
397 | |||
388 | dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; | 398 | dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; |
389 | 399 | ||
390 | dev_priv->w = init->w; | 400 | dev_priv->w = init->w; |
diff --git a/drivers/char/drm/i830_drv.h b/drivers/char/drm/i830_drv.h index 85bc5be6f916..e91f94afb4bb 100644 --- a/drivers/char/drm/i830_drv.h +++ b/drivers/char/drm/i830_drv.h | |||
@@ -68,6 +68,7 @@ typedef struct drm_i830_buf_priv { | |||
68 | int currently_mapped; | 68 | int currently_mapped; |
69 | void __user *virtual; | 69 | void __user *virtual; |
70 | void *kernel_virtual; | 70 | void *kernel_virtual; |
71 | drm_local_map_t map; | ||
71 | } drm_i830_buf_priv_t; | 72 | } drm_i830_buf_priv_t; |
72 | 73 | ||
73 | typedef struct _drm_i830_ring_buffer { | 74 | typedef struct _drm_i830_ring_buffer { |
@@ -79,6 +80,7 @@ typedef struct _drm_i830_ring_buffer { | |||
79 | int head; | 80 | int head; |
80 | int tail; | 81 | int tail; |
81 | int space; | 82 | int space; |
83 | drm_local_map_t map; | ||
82 | } drm_i830_ring_buffer_t; | 84 | } drm_i830_ring_buffer_t; |
83 | 85 | ||
84 | typedef struct drm_i830_private { | 86 | typedef struct drm_i830_private { |
diff --git a/drivers/char/drm/via_dma.c b/drivers/char/drm/via_dma.c index a691ae74129d..c0539c6299cf 100644 --- a/drivers/char/drm/via_dma.c +++ b/drivers/char/drm/via_dma.c | |||
@@ -190,6 +190,11 @@ static int via_initialize(drm_device_t * dev, | |||
190 | return DRM_ERR(EFAULT); | 190 | return DRM_ERR(EFAULT); |
191 | } | 191 | } |
192 | 192 | ||
193 | if (dev_priv->chipset == VIA_DX9_0) { | ||
194 | DRM_ERROR("AGP DMA is not supported on this chip\n"); | ||
195 | return DRM_ERR(EINVAL); | ||
196 | } | ||
197 | |||
193 | dev_priv->ring.map.offset = dev->agp->base + init->offset; | 198 | dev_priv->ring.map.offset = dev->agp->base + init->offset; |
194 | dev_priv->ring.map.size = init->size; | 199 | dev_priv->ring.map.size = init->size; |
195 | dev_priv->ring.map.type = 0; | 200 | dev_priv->ring.map.type = 0; |
@@ -480,6 +485,7 @@ static int via_hook_segment(drm_via_private_t * dev_priv, | |||
480 | VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16)); | 485 | VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16)); |
481 | VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_hi); | 486 | VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_hi); |
482 | VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_lo); | 487 | VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_lo); |
488 | VIA_READ(VIA_REG_TRANSPACE); | ||
483 | } | 489 | } |
484 | } | 490 | } |
485 | return paused; | 491 | return paused; |
@@ -557,8 +563,9 @@ static void via_cmdbuf_start(drm_via_private_t * dev_priv) | |||
557 | 563 | ||
558 | VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_hi); | 564 | VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_hi); |
559 | VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_lo); | 565 | VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_lo); |
560 | 566 | DRM_WRITEMEMORYBARRIER(); | |
561 | VIA_WRITE(VIA_REG_TRANSPACE, command | HC_HAGPCMNT_MASK); | 567 | VIA_WRITE(VIA_REG_TRANSPACE, command | HC_HAGPCMNT_MASK); |
568 | VIA_READ(VIA_REG_TRANSPACE); | ||
562 | } | 569 | } |
563 | 570 | ||
564 | static void via_pad_cache(drm_via_private_t * dev_priv, int qwords) | 571 | static void via_pad_cache(drm_via_private_t * dev_priv, int qwords) |
diff --git a/drivers/char/drm/via_dmablit.c b/drivers/char/drm/via_dmablit.c index 806f9ce5f47b..2054d5773717 100644 --- a/drivers/char/drm/via_dmablit.c +++ b/drivers/char/drm/via_dmablit.c | |||
@@ -218,7 +218,9 @@ via_fire_dmablit(drm_device_t *dev, drm_via_sg_info_t *vsg, int engine) | |||
218 | VIA_WRITE(VIA_PCI_DMA_MR0 + engine*0x04, VIA_DMA_MR_CM | VIA_DMA_MR_TDIE); | 218 | VIA_WRITE(VIA_PCI_DMA_MR0 + engine*0x04, VIA_DMA_MR_CM | VIA_DMA_MR_TDIE); |
219 | VIA_WRITE(VIA_PCI_DMA_BCR0 + engine*0x10, 0); | 219 | VIA_WRITE(VIA_PCI_DMA_BCR0 + engine*0x10, 0); |
220 | VIA_WRITE(VIA_PCI_DMA_DPR0 + engine*0x10, vsg->chain_start); | 220 | VIA_WRITE(VIA_PCI_DMA_DPR0 + engine*0x10, vsg->chain_start); |
221 | DRM_WRITEMEMORYBARRIER(); | ||
221 | VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_DE | VIA_DMA_CSR_TS); | 222 | VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_DE | VIA_DMA_CSR_TS); |
223 | VIA_READ(VIA_PCI_DMA_CSR0 + engine*0x04); | ||
222 | } | 224 | } |
223 | 225 | ||
224 | /* | 226 | /* |
diff --git a/drivers/char/drm/via_drv.h b/drivers/char/drm/via_drv.h index d21b5b75da0f..8b8778d4a423 100644 --- a/drivers/char/drm/via_drv.h +++ b/drivers/char/drm/via_drv.h | |||
@@ -29,10 +29,10 @@ | |||
29 | 29 | ||
30 | #define DRIVER_NAME "via" | 30 | #define DRIVER_NAME "via" |
31 | #define DRIVER_DESC "VIA Unichrome / Pro" | 31 | #define DRIVER_DESC "VIA Unichrome / Pro" |
32 | #define DRIVER_DATE "20060529" | 32 | #define DRIVER_DATE "20061227" |
33 | 33 | ||
34 | #define DRIVER_MAJOR 2 | 34 | #define DRIVER_MAJOR 2 |
35 | #define DRIVER_MINOR 10 | 35 | #define DRIVER_MINOR 11 |
36 | #define DRIVER_PATCHLEVEL 0 | 36 | #define DRIVER_PATCHLEVEL 0 |
37 | 37 | ||
38 | #include "via_verifier.h" | 38 | #include "via_verifier.h" |
@@ -79,7 +79,7 @@ typedef struct drm_via_private { | |||
79 | char pci_buf[VIA_PCI_BUF_SIZE]; | 79 | char pci_buf[VIA_PCI_BUF_SIZE]; |
80 | const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE]; | 80 | const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE]; |
81 | uint32_t num_fire_offsets; | 81 | uint32_t num_fire_offsets; |
82 | int pro_group_a; | 82 | int chipset; |
83 | drm_via_irq_t via_irqs[VIA_NUM_IRQS]; | 83 | drm_via_irq_t via_irqs[VIA_NUM_IRQS]; |
84 | unsigned num_irqs; | 84 | unsigned num_irqs; |
85 | maskarray_t *irq_masks; | 85 | maskarray_t *irq_masks; |
@@ -96,8 +96,9 @@ typedef struct drm_via_private { | |||
96 | } drm_via_private_t; | 96 | } drm_via_private_t; |
97 | 97 | ||
98 | enum via_family { | 98 | enum via_family { |
99 | VIA_OTHER = 0, | 99 | VIA_OTHER = 0, /* Baseline */ |
100 | VIA_PRO_GROUP_A, | 100 | VIA_PRO_GROUP_A, /* Another video engine and DMA commands */ |
101 | VIA_DX9_0 /* Same video as pro_group_a, but 3D is unsupported */ | ||
101 | }; | 102 | }; |
102 | 103 | ||
103 | /* VIA MMIO register access */ | 104 | /* VIA MMIO register access */ |
diff --git a/drivers/char/drm/via_irq.c b/drivers/char/drm/via_irq.c index c33d068cde19..1ac5941ad237 100644 --- a/drivers/char/drm/via_irq.c +++ b/drivers/char/drm/via_irq.c | |||
@@ -258,12 +258,16 @@ void via_driver_irq_preinstall(drm_device_t * dev) | |||
258 | dev_priv->irq_enable_mask = VIA_IRQ_VBLANK_ENABLE; | 258 | dev_priv->irq_enable_mask = VIA_IRQ_VBLANK_ENABLE; |
259 | dev_priv->irq_pending_mask = VIA_IRQ_VBLANK_PENDING; | 259 | dev_priv->irq_pending_mask = VIA_IRQ_VBLANK_PENDING; |
260 | 260 | ||
261 | dev_priv->irq_masks = (dev_priv->pro_group_a) ? | 261 | if (dev_priv->chipset == VIA_PRO_GROUP_A || |
262 | via_pro_group_a_irqs : via_unichrome_irqs; | 262 | dev_priv->chipset == VIA_DX9_0) { |
263 | dev_priv->num_irqs = (dev_priv->pro_group_a) ? | 263 | dev_priv->irq_masks = via_pro_group_a_irqs; |
264 | via_num_pro_group_a : via_num_unichrome; | 264 | dev_priv->num_irqs = via_num_pro_group_a; |
265 | dev_priv->irq_map = (dev_priv->pro_group_a) ? | 265 | dev_priv->irq_map = via_irqmap_pro_group_a; |
266 | via_irqmap_pro_group_a : via_irqmap_unichrome; | 266 | } else { |
267 | dev_priv->irq_masks = via_unichrome_irqs; | ||
268 | dev_priv->num_irqs = via_num_unichrome; | ||
269 | dev_priv->irq_map = via_irqmap_unichrome; | ||
270 | } | ||
267 | 271 | ||
268 | for (i = 0; i < dev_priv->num_irqs; ++i) { | 272 | for (i = 0; i < dev_priv->num_irqs; ++i) { |
269 | atomic_set(&cur_irq->irq_received, 0); | 273 | atomic_set(&cur_irq->irq_received, 0); |
diff --git a/drivers/char/drm/via_map.c b/drivers/char/drm/via_map.c index 782011e0a58d..4e3fc072aa3b 100644 --- a/drivers/char/drm/via_map.c +++ b/drivers/char/drm/via_map.c | |||
@@ -106,8 +106,7 @@ int via_driver_load(drm_device_t *dev, unsigned long chipset) | |||
106 | 106 | ||
107 | dev->dev_private = (void *)dev_priv; | 107 | dev->dev_private = (void *)dev_priv; |
108 | 108 | ||
109 | if (chipset == VIA_PRO_GROUP_A) | 109 | dev_priv->chipset = chipset; |
110 | dev_priv->pro_group_a = 1; | ||
111 | 110 | ||
112 | ret = drm_sman_init(&dev_priv->sman, 2, 12, 8); | 111 | ret = drm_sman_init(&dev_priv->sman, 2, 12, 8); |
113 | if (ret) { | 112 | if (ret) { |
diff --git a/drivers/char/drm/via_verifier.c b/drivers/char/drm/via_verifier.c index 70c897c88766..2e7e08078287 100644 --- a/drivers/char/drm/via_verifier.c +++ b/drivers/char/drm/via_verifier.c | |||
@@ -306,6 +306,7 @@ static __inline__ int finish_current_sequence(drm_via_state_t * cur_seq) | |||
306 | unsigned long lo = ~0, hi = 0, tmp; | 306 | unsigned long lo = ~0, hi = 0, tmp; |
307 | uint32_t *addr, *pitch, *height, tex; | 307 | uint32_t *addr, *pitch, *height, tex; |
308 | unsigned i; | 308 | unsigned i; |
309 | int npot; | ||
309 | 310 | ||
310 | if (end > 9) | 311 | if (end > 9) |
311 | end = 9; | 312 | end = 9; |
@@ -316,12 +317,15 @@ static __inline__ int finish_current_sequence(drm_via_state_t * cur_seq) | |||
316 | &(cur_seq->t_addr[tex = cur_seq->texture][start]); | 317 | &(cur_seq->t_addr[tex = cur_seq->texture][start]); |
317 | pitch = &(cur_seq->pitch[tex][start]); | 318 | pitch = &(cur_seq->pitch[tex][start]); |
318 | height = &(cur_seq->height[tex][start]); | 319 | height = &(cur_seq->height[tex][start]); |
319 | 320 | npot = cur_seq->tex_npot[tex]; | |
320 | for (i = start; i <= end; ++i) { | 321 | for (i = start; i <= end; ++i) { |
321 | tmp = *addr++; | 322 | tmp = *addr++; |
322 | if (tmp < lo) | 323 | if (tmp < lo) |
323 | lo = tmp; | 324 | lo = tmp; |
324 | tmp += (*height++ << *pitch++); | 325 | if (i == 0 && npot) |
326 | tmp += (*height++ * *pitch++); | ||
327 | else | ||
328 | tmp += (*height++ << *pitch++); | ||
325 | if (tmp > hi) | 329 | if (tmp > hi) |
326 | hi = tmp; | 330 | hi = tmp; |
327 | } | 331 | } |
@@ -443,13 +447,21 @@ investigate_hazard(uint32_t cmd, hazard_t hz, drm_via_state_t * cur_seq) | |||
443 | return 0; | 447 | return 0; |
444 | case check_texture_addr3: | 448 | case check_texture_addr3: |
445 | cur_seq->unfinished = tex_address; | 449 | cur_seq->unfinished = tex_address; |
446 | tmp = ((cmd >> 24) - 0x2B); | 450 | tmp = ((cmd >> 24) - HC_SubA_HTXnL0Pit); |
447 | cur_seq->pitch[cur_seq->texture][tmp] = | 451 | if (tmp == 0 && |
448 | (cmd & 0x00F00000) >> 20; | 452 | (cmd & HC_HTXnEnPit_MASK)) { |
449 | if (!tmp && (cmd & 0x000FFFFF)) { | 453 | cur_seq->pitch[cur_seq->texture][tmp] = |
450 | DRM_ERROR | 454 | (cmd & HC_HTXnLnPit_MASK); |
451 | ("Unimplemented texture level 0 pitch mode.\n"); | 455 | cur_seq->tex_npot[cur_seq->texture] = 1; |
452 | return 2; | 456 | } else { |
457 | cur_seq->pitch[cur_seq->texture][tmp] = | ||
458 | (cmd & HC_HTXnLnPitE_MASK) >> HC_HTXnLnPitE_SHIFT; | ||
459 | cur_seq->tex_npot[cur_seq->texture] = 0; | ||
460 | if (cmd & 0x000FFFFF) { | ||
461 | DRM_ERROR | ||
462 | ("Unimplemented texture level 0 pitch mode.\n"); | ||
463 | return 2; | ||
464 | } | ||
453 | } | 465 | } |
454 | return 0; | 466 | return 0; |
455 | case check_texture_addr4: | 467 | case check_texture_addr4: |
@@ -961,7 +973,13 @@ via_verify_command_stream(const uint32_t * buf, unsigned int size, | |||
961 | uint32_t cmd; | 973 | uint32_t cmd; |
962 | const uint32_t *buf_end = buf + (size >> 2); | 974 | const uint32_t *buf_end = buf + (size >> 2); |
963 | verifier_state_t state = state_command; | 975 | verifier_state_t state = state_command; |
964 | int pro_group_a = dev_priv->pro_group_a; | 976 | int cme_video; |
977 | int supported_3d; | ||
978 | |||
979 | cme_video = (dev_priv->chipset == VIA_PRO_GROUP_A || | ||
980 | dev_priv->chipset == VIA_DX9_0); | ||
981 | |||
982 | supported_3d = dev_priv->chipset != VIA_DX9_0; | ||
965 | 983 | ||
966 | hc_state->dev = dev; | 984 | hc_state->dev = dev; |
967 | hc_state->unfinished = no_sequence; | 985 | hc_state->unfinished = no_sequence; |
@@ -986,17 +1004,21 @@ via_verify_command_stream(const uint32_t * buf, unsigned int size, | |||
986 | state = via_check_vheader6(&buf, buf_end); | 1004 | state = via_check_vheader6(&buf, buf_end); |
987 | break; | 1005 | break; |
988 | case state_command: | 1006 | case state_command: |
989 | if (HALCYON_HEADER2 == (cmd = *buf)) | 1007 | if ((HALCYON_HEADER2 == (cmd = *buf)) && |
1008 | supported_3d) | ||
990 | state = state_header2; | 1009 | state = state_header2; |
991 | else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) | 1010 | else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) |
992 | state = state_header1; | 1011 | state = state_header1; |
993 | else if (pro_group_a | 1012 | else if (cme_video |
994 | && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5) | 1013 | && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5) |
995 | state = state_vheader5; | 1014 | state = state_vheader5; |
996 | else if (pro_group_a | 1015 | else if (cme_video |
997 | && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6) | 1016 | && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6) |
998 | state = state_vheader6; | 1017 | state = state_vheader6; |
999 | else { | 1018 | else if ((cmd == HALCYON_HEADER2) && !supported_3d) { |
1019 | DRM_ERROR("Accelerated 3D is not supported on this chipset yet.\n"); | ||
1020 | state = state_error; | ||
1021 | } else { | ||
1000 | DRM_ERROR | 1022 | DRM_ERROR |
1001 | ("Invalid / Unimplemented DMA HEADER command. 0x%x\n", | 1023 | ("Invalid / Unimplemented DMA HEADER command. 0x%x\n", |
1002 | cmd); | 1024 | cmd); |
diff --git a/drivers/char/drm/via_verifier.h b/drivers/char/drm/via_verifier.h index 256590fcc22a..b77f59df0278 100644 --- a/drivers/char/drm/via_verifier.h +++ b/drivers/char/drm/via_verifier.h | |||
@@ -43,6 +43,7 @@ typedef struct { | |||
43 | uint32_t tex_level_lo[2]; | 43 | uint32_t tex_level_lo[2]; |
44 | uint32_t tex_level_hi[2]; | 44 | uint32_t tex_level_hi[2]; |
45 | uint32_t tex_palette_size[2]; | 45 | uint32_t tex_palette_size[2]; |
46 | uint32_t tex_npot[2]; | ||
46 | drm_via_sequence_t unfinished; | 47 | drm_via_sequence_t unfinished; |
47 | int agp_texture; | 48 | int agp_texture; |
48 | int multitex; | 49 | int multitex; |