1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36#include <linux/highmem.h>
37#include <linux/export.h>
38#include "drmP.h"
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53int drm_mem_info(char *buf, char **start, off_t offset,
54 int len, int *eof, void *data)
55{
56 return 0;
57}
58
59#if __OS_HAS_AGP
60static void *agp_remap(unsigned long offset, unsigned long size,
61 struct drm_device * dev)
62{
63 unsigned long i, num_pages =
64 PAGE_ALIGN(size) / PAGE_SIZE;
65 struct drm_agp_mem *agpmem;
66 struct page **page_map;
67 struct page **phys_page_map;
68 void *addr;
69
70 size = PAGE_ALIGN(size);
71
72#ifdef __alpha__
73 offset -= dev->hose->mem_space->start;
74#endif
75
76 list_for_each_entry(agpmem, &dev->agp->memory, head)
77 if (agpmem->bound <= offset
78 && (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >=
79 (offset + size))
80 break;
81 if (&agpmem->head == &dev->agp->memory)
82 return NULL;
83
84
85
86
87
88
89
90 page_map = vmalloc(num_pages * sizeof(struct page *));
91 if (!page_map)
92 return NULL;
93
94 phys_page_map = (agpmem->memory->pages + (offset - agpmem->bound) / PAGE_SIZE);
95 for (i = 0; i < num_pages; ++i)
96 page_map[i] = phys_page_map[i];
97 addr = vmap(page_map, num_pages, VM_IOREMAP, PAGE_AGP);
98 vfree(page_map);
99
100 return addr;
101}
102
103
104void drm_free_agp(DRM_AGP_MEM * handle, int pages)
105{
106 agp_free_memory(handle);
107}
108EXPORT_SYMBOL(drm_free_agp);
109
110
111int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start)
112{
113 return agp_bind_memory(handle, start);
114}
115
116
117int drm_unbind_agp(DRM_AGP_MEM * handle)
118{
119 return agp_unbind_memory(handle);
120}
121EXPORT_SYMBOL(drm_unbind_agp);
122
123#else
124static inline void *agp_remap(unsigned long offset, unsigned long size,
125 struct drm_device * dev)
126{
127 return NULL;
128}
129
130#endif
131
132void drm_core_ioremap(struct drm_local_map *map, struct drm_device *dev)
133{
134 if (drm_core_has_AGP(dev) &&
135 dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP)
136 map->handle = agp_remap(map->offset, map->size, dev);
137 else
138 map->handle = ioremap(map->offset, map->size);
139}
140EXPORT_SYMBOL(drm_core_ioremap);
141
142void drm_core_ioremap_wc(struct drm_local_map *map, struct drm_device *dev)
143{
144 if (drm_core_has_AGP(dev) &&
145 dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP)
146 map->handle = agp_remap(map->offset, map->size, dev);
147 else
148 map->handle = ioremap_wc(map->offset, map->size);
149}
150EXPORT_SYMBOL(drm_core_ioremap_wc);
151
152void drm_core_ioremapfree(struct drm_local_map *map, struct drm_device *dev)
153{
154 if (!map->handle || !map->size)
155 return;
156
157 if (drm_core_has_AGP(dev) &&
158 dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP)
159 vunmap(map->handle);
160 else
161 iounmap(map->handle);
162}
163EXPORT_SYMBOL(drm_core_ioremapfree);
164