aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2011-10-26 16:22:59 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2011-12-21 18:33:23 -0500
commitbe2fb9da32cb88a1311350de3d1db8f9e461ae9f (patch)
treea261a7a230e7055ed41e5037b1cb1ac3ca9dd908 /drivers/gpu
parent977b4f6edd7a960dd80c1a614a7644068f866c5b (diff)
drm/sis: use drm_mm instead of drm_sman
v2: Smash compile fix from Tormod Volden <debian.tormod@gmail.com> for CONFIG_FB_SIS on top of this. Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/sis/sis_drv.c4
-rw-r--r--drivers/gpu/drm/sis/sis_drv.h5
-rw-r--r--drivers/gpu/drm/sis/sis_mm.c137
3 files changed, 68 insertions, 78 deletions
diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c
index 64d329f7d9b6..06da063ece2e 100644
--- a/drivers/gpu/drm/sis/sis_drv.c
+++ b/drivers/gpu/drm/sis/sis_drv.c
@@ -49,9 +49,6 @@ static int sis_driver_load(struct drm_device *dev, unsigned long chipset)
49 dev->dev_private = (void *)dev_priv; 49 dev->dev_private = (void *)dev_priv;
50 dev_priv->chipset = chipset; 50 dev_priv->chipset = chipset;
51 idr_init(&dev->object_name_idr); 51 idr_init(&dev->object_name_idr);
52 ret = drm_sman_init(&dev_priv->sman, 2, 12, 8);
53 if (ret)
54 kfree(dev_priv);
55 52
56 return ret; 53 return ret;
57} 54}
@@ -60,7 +57,6 @@ static int sis_driver_unload(struct drm_device *dev)
60{ 57{
61 drm_sis_private_t *dev_priv = dev->dev_private; 58 drm_sis_private_t *dev_priv = dev->dev_private;
62 59
63 drm_sman_takedown(&dev_priv->sman);
64 idr_remove_all(&dev_priv->object_idr); 60 idr_remove_all(&dev_priv->object_idr);
65 idr_destroy(&dev_priv->object_idr); 61 idr_destroy(&dev_priv->object_idr);
66 62
diff --git a/drivers/gpu/drm/sis/sis_drv.h b/drivers/gpu/drm/sis/sis_drv.h
index fcdd06ad5dc3..573758b2d2d6 100644
--- a/drivers/gpu/drm/sis/sis_drv.h
+++ b/drivers/gpu/drm/sis/sis_drv.h
@@ -44,7 +44,7 @@ enum sis_family {
44 SIS_CHIP_315 = 1, 44 SIS_CHIP_315 = 1,
45}; 45};
46 46
47#include "drm_sman.h" 47#include "drm_mm.h"
48 48
49 49
50#define SIS_BASE (dev_priv->mmio) 50#define SIS_BASE (dev_priv->mmio)
@@ -54,12 +54,13 @@ enum sis_family {
54typedef struct drm_sis_private { 54typedef struct drm_sis_private {
55 drm_local_map_t *mmio; 55 drm_local_map_t *mmio;
56 unsigned int idle_fault; 56 unsigned int idle_fault;
57 struct drm_sman sman;
58 unsigned int chipset; 57 unsigned int chipset;
59 int vram_initialized; 58 int vram_initialized;
60 int agp_initialized; 59 int agp_initialized;
61 unsigned long vram_offset; 60 unsigned long vram_offset;
62 unsigned long agp_offset; 61 unsigned long agp_offset;
62 struct drm_mm vram_mm;
63 struct drm_mm agp_mm;
63 /** Mapping of userspace keys to mm objects */ 64 /** Mapping of userspace keys to mm objects */
64 struct idr object_idr; 65 struct idr object_idr;
65} drm_sis_private_t; 66} drm_sis_private_t;
diff --git a/drivers/gpu/drm/sis/sis_mm.c b/drivers/gpu/drm/sis/sis_mm.c
index 21d36df02a88..46cb2bce6cc5 100644
--- a/drivers/gpu/drm/sis/sis_mm.c
+++ b/drivers/gpu/drm/sis/sis_mm.c
@@ -41,40 +41,18 @@
41#define AGP_TYPE 1 41#define AGP_TYPE 1
42 42
43 43
44struct sis_memblock {
45 struct drm_mm_node mm_node;
46 struct sis_memreq req;
47 struct list_head owner_list;
48};
49
44#if defined(CONFIG_FB_SIS) || defined(CONFIG_FB_SIS_MODULE) 50#if defined(CONFIG_FB_SIS) || defined(CONFIG_FB_SIS_MODULE)
45/* fb management via fb device */ 51/* fb management via fb device */
46 52
47#define SIS_MM_ALIGN_SHIFT 0 53#define SIS_MM_ALIGN_SHIFT 0
48#define SIS_MM_ALIGN_MASK 0 54#define SIS_MM_ALIGN_MASK 0
49 55
50static void *sis_sman_mm_allocate(void *private, unsigned long size,
51 unsigned alignment)
52{
53 struct sis_memreq req;
54
55 req.size = size;
56 sis_malloc(&req);
57 if (req.size == 0)
58 return NULL;
59 else
60 return (void *)(unsigned long)~req.offset;
61}
62
63static void sis_sman_mm_free(void *private, void *ref)
64{
65 sis_free(~((unsigned long)ref));
66}
67
68static void sis_sman_mm_destroy(void *private)
69{
70 ;
71}
72
73static unsigned long sis_sman_mm_offset(void *private, void *ref)
74{
75 return ~((unsigned long)ref);
76}
77
78#else /* CONFIG_FB_SIS[_MODULE] */ 56#else /* CONFIG_FB_SIS[_MODULE] */
79 57
80#define SIS_MM_ALIGN_SHIFT 4 58#define SIS_MM_ALIGN_SHIFT 4
@@ -86,30 +64,11 @@ static int sis_fb_init(struct drm_device *dev, void *data, struct drm_file *file
86{ 64{
87 drm_sis_private_t *dev_priv = dev->dev_private; 65 drm_sis_private_t *dev_priv = dev->dev_private;
88 drm_sis_fb_t *fb = data; 66 drm_sis_fb_t *fb = data;
89 int ret;
90 67
91 mutex_lock(&dev->struct_mutex); 68 mutex_lock(&dev->struct_mutex);
92#if defined(CONFIG_FB_SIS) || defined(CONFIG_FB_SIS_MODULE) 69 /* Unconditionally init the drm_mm, even though we don't use it when the
93 { 70 * fb sis driver is available - make cleanup easier. */
94 struct drm_sman_mm sman_mm; 71 drm_mm_init(&dev_priv->vram_mm, 0, fb->size >> SIS_MM_ALIGN_SHIFT);
95 sman_mm.private = (void *)0xFFFFFFFF;
96 sman_mm.allocate = sis_sman_mm_allocate;
97 sman_mm.free = sis_sman_mm_free;
98 sman_mm.destroy = sis_sman_mm_destroy;
99 sman_mm.offset = sis_sman_mm_offset;
100 ret =
101 drm_sman_set_manager(&dev_priv->sman, VIDEO_TYPE, &sman_mm);
102 }
103#else
104 ret = drm_sman_set_range(&dev_priv->sman, VIDEO_TYPE, 0,
105 fb->size >> SIS_MM_ALIGN_SHIFT);
106#endif
107
108 if (ret) {
109 DRM_ERROR("VRAM memory manager initialisation error\n");
110 mutex_unlock(&dev->struct_mutex);
111 return ret;
112 }
113 72
114 dev_priv->vram_initialized = 1; 73 dev_priv->vram_initialized = 1;
115 dev_priv->vram_offset = fb->offset; 74 dev_priv->vram_offset = fb->offset;
@@ -126,8 +85,9 @@ static int sis_drm_alloc(struct drm_device *dev, struct drm_file *file,
126 drm_sis_private_t *dev_priv = dev->dev_private; 85 drm_sis_private_t *dev_priv = dev->dev_private;
127 drm_sis_mem_t *mem = data; 86 drm_sis_mem_t *mem = data;
128 int retval = 0, user_key; 87 int retval = 0, user_key;
129 struct drm_memblock_item *item; 88 struct sis_memblock *item;
130 struct sis_file_private *file_priv = file->driver_priv; 89 struct sis_file_private *file_priv = file->driver_priv;
90 unsigned long offset;
131 91
132 mutex_lock(&dev->struct_mutex); 92 mutex_lock(&dev->struct_mutex);
133 93
@@ -139,13 +99,35 @@ static int sis_drm_alloc(struct drm_device *dev, struct drm_file *file,
139 return -EINVAL; 99 return -EINVAL;
140 } 100 }
141 101
142 mem->size = (mem->size + SIS_MM_ALIGN_MASK) >> SIS_MM_ALIGN_SHIFT; 102 item = kzalloc(sizeof(*item), GFP_KERNEL);
143 item = drm_sman_alloc(&dev_priv->sman, pool, mem->size, 0, 0);
144 if (!item) { 103 if (!item) {
145 retval = -ENOMEM; 104 retval = -ENOMEM;
146 goto fail_alloc; 105 goto fail_alloc;
147 } 106 }
148 107
108 mem->size = (mem->size + SIS_MM_ALIGN_MASK) >> SIS_MM_ALIGN_SHIFT;
109 if (pool == AGP_TYPE) {
110 retval = drm_mm_insert_node(&dev_priv->agp_mm,
111 &item->mm_node,
112 mem->size, 0);
113 offset = item->mm_node.start;
114 } else {
115#if defined(CONFIG_FB_SIS) || defined(CONFIG_FB_SIS_MODULE)
116 item->req.size = mem->size;
117 sis_malloc(&item->req);
118 if (item->req.size == 0)
119 retval = -ENOMEM;
120 offset = item->req.offset;
121#else
122 retval = drm_mm_insert_node(&dev_priv->vram_mm,
123 &item->mm_node,
124 mem->size, 0);
125 offset = item->mm_node.start;
126#endif
127 }
128 if (retval)
129 goto fail_alloc;
130
149again: 131again:
150 if (idr_pre_get(&dev_priv->object_idr, GFP_KERNEL) == 0) { 132 if (idr_pre_get(&dev_priv->object_idr, GFP_KERNEL) == 0) {
151 retval = -ENOMEM; 133 retval = -ENOMEM;
@@ -163,16 +145,16 @@ again:
163 145
164 mem->offset = ((pool == 0) ? 146 mem->offset = ((pool == 0) ?
165 dev_priv->vram_offset : dev_priv->agp_offset) + 147 dev_priv->vram_offset : dev_priv->agp_offset) +
166 (item->mm-> 148 (offset << SIS_MM_ALIGN_SHIFT);
167 offset(item->mm, item->mm_info) << SIS_MM_ALIGN_SHIFT);
168 mem->free = user_key; 149 mem->free = user_key;
169 mem->size = mem->size << SIS_MM_ALIGN_SHIFT; 150 mem->size = mem->size << SIS_MM_ALIGN_SHIFT;
170 151
171 return 0; 152 return 0;
172 153
173fail_idr: 154fail_idr:
174 drm_sman_free(item); 155 drm_mm_remove_node(&item->mm_node);
175fail_alloc: 156fail_alloc:
157 kfree(item);
176 mutex_unlock(&dev->struct_mutex); 158 mutex_unlock(&dev->struct_mutex);
177 159
178 mem->offset = 0; 160 mem->offset = 0;
@@ -189,7 +171,7 @@ static int sis_drm_free(struct drm_device *dev, void *data, struct drm_file *fil
189{ 171{
190 drm_sis_private_t *dev_priv = dev->dev_private; 172 drm_sis_private_t *dev_priv = dev->dev_private;
191 drm_sis_mem_t *mem = data; 173 drm_sis_mem_t *mem = data;
192 struct drm_memblock_item *obj; 174 struct sis_memblock *obj;
193 int ret; 175 int ret;
194 176
195 mutex_lock(&dev->struct_mutex); 177 mutex_lock(&dev->struct_mutex);
@@ -200,7 +182,14 @@ static int sis_drm_free(struct drm_device *dev, void *data, struct drm_file *fil
200 } 182 }
201 183
202 idr_remove(&dev_priv->object_idr, mem->free); 184 idr_remove(&dev_priv->object_idr, mem->free);
203 drm_sman_free(obj); 185 list_del(&obj->owner_list);
186 if (drm_mm_node_allocated(&obj->mm_node))
187 drm_mm_remove_node(&obj->mm_node);
188#if defined(CONFIG_FB_SIS) || defined(CONFIG_FB_SIS_MODULE)
189 else
190 sis_free(obj->req.offset);
191#endif
192 kfree(obj);
204 mutex_unlock(&dev->struct_mutex); 193 mutex_unlock(&dev->struct_mutex);
205 DRM_DEBUG("free = 0x%lx\n", mem->free); 194 DRM_DEBUG("free = 0x%lx\n", mem->free);
206 195
@@ -218,18 +207,10 @@ static int sis_ioctl_agp_init(struct drm_device *dev, void *data,
218{ 207{
219 drm_sis_private_t *dev_priv = dev->dev_private; 208 drm_sis_private_t *dev_priv = dev->dev_private;
220 drm_sis_agp_t *agp = data; 209 drm_sis_agp_t *agp = data;
221 int ret;
222 dev_priv = dev->dev_private; 210 dev_priv = dev->dev_private;
223 211
224 mutex_lock(&dev->struct_mutex); 212 mutex_lock(&dev->struct_mutex);
225 ret = drm_sman_set_range(&dev_priv->sman, AGP_TYPE, 0, 213 drm_mm_init(&dev_priv->agp_mm, 0, agp->size >> SIS_MM_ALIGN_SHIFT);
226 agp->size >> SIS_MM_ALIGN_SHIFT);
227
228 if (ret) {
229 DRM_ERROR("AGP memory manager initialisation error\n");
230 mutex_unlock(&dev->struct_mutex);
231 return ret;
232 }
233 214
234 dev_priv->agp_initialized = 1; 215 dev_priv->agp_initialized = 1;
235 dev_priv->agp_offset = agp->offset; 216 dev_priv->agp_offset = agp->offset;
@@ -323,9 +304,14 @@ void sis_lastclose(struct drm_device *dev)
323 return; 304 return;
324 305
325 mutex_lock(&dev->struct_mutex); 306 mutex_lock(&dev->struct_mutex);
326 drm_sman_cleanup(&dev_priv->sman); 307 if (dev_priv->vram_initialized) {
327 dev_priv->vram_initialized = 0; 308 drm_mm_takedown(&dev_priv->vram_mm);
328 dev_priv->agp_initialized = 0; 309 dev_priv->vram_initialized = 0;
310 }
311 if (dev_priv->agp_initialized) {
312 drm_mm_takedown(&dev_priv->agp_mm);
313 dev_priv->agp_initialized = 0;
314 }
329 dev_priv->mmio = NULL; 315 dev_priv->mmio = NULL;
330 mutex_unlock(&dev->struct_mutex); 316 mutex_unlock(&dev->struct_mutex);
331} 317}
@@ -334,7 +320,7 @@ void sis_reclaim_buffers_locked(struct drm_device *dev,
334 struct drm_file *file) 320 struct drm_file *file)
335{ 321{
336 struct sis_file_private *file_priv = file->driver_priv; 322 struct sis_file_private *file_priv = file->driver_priv;
337 struct drm_memblock_item *entry, *next; 323 struct sis_memblock *entry, *next;
338 324
339 mutex_lock(&dev->struct_mutex); 325 mutex_lock(&dev->struct_mutex);
340 if (list_empty(&file_priv->obj_list)) { 326 if (list_empty(&file_priv->obj_list)) {
@@ -348,7 +334,14 @@ void sis_reclaim_buffers_locked(struct drm_device *dev,
348 334
349 list_for_each_entry_safe(entry, next, &file_priv->obj_list, 335 list_for_each_entry_safe(entry, next, &file_priv->obj_list,
350 owner_list) { 336 owner_list) {
351 drm_sman_free(entry); 337 list_del(&entry->owner_list);
338 if (drm_mm_node_allocated(&entry->mm_node))
339 drm_mm_remove_node(&entry->mm_node);
340#if defined(CONFIG_FB_SIS) || defined(CONFIG_FB_SIS_MODULE)
341 else
342 sis_free(entry->req.offset);
343#endif
344 kfree(entry);
352 } 345 }
353 mutex_unlock(&dev->struct_mutex); 346 mutex_unlock(&dev->struct_mutex);
354 return; 347 return;