Subversion Repositories Kolibri OS

Rev

Rev 3391 | Rev 4103 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3391 Rev 4065
1
/**************************************************************************
1
/**************************************************************************
2
 *
2
 *
3
 * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX. USA.
3
 * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX. USA.
4
 * All Rights Reserved.
4
 * All Rights Reserved.
5
 *
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the
7
 * copy of this software and associated documentation files (the
8
 * "Software"), to deal in the Software without restriction, including
8
 * "Software"), to deal in the Software without restriction, including
9
 * without limitation the rights to use, copy, modify, merge, publish,
9
 * without limitation the rights to use, copy, modify, merge, publish,
10
 * distribute, sub license, and/or sell copies of the Software, and to
10
 * distribute, sub license, and/or sell copies of the Software, and to
11
 * permit persons to whom the Software is furnished to do so, subject to
11
 * permit persons to whom the Software is furnished to do so, subject to
12
 * the following conditions:
12
 * the following conditions:
13
 *
13
 *
14
 * The above copyright notice and this permission notice (including the
14
 * The above copyright notice and this permission notice (including the
15
 * next paragraph) shall be included in all copies or substantial portions
15
 * next paragraph) shall be included in all copies or substantial portions
16
 * of the Software.
16
 * of the Software.
17
 *
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
20
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21
 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
21
 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
23
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
24
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25
 *
25
 *
26
 *
26
 *
27
 **************************************************************************/
27
 **************************************************************************/
28
/*
28
/*
29
 * Authors:
29
 * Authors:
30
 * Thomas Hellstrom 
30
 * Thomas Hellstrom 
31
 */
31
 */
32
 
32
 
33
#ifndef _DRM_MM_H_
33
#ifndef _DRM_MM_H_
34
#define _DRM_MM_H_
34
#define _DRM_MM_H_
35
 
35
 
36
/*
36
/*
37
 * Generic range manager structs
37
 * Generic range manager structs
38
 */
38
 */
39
#include 
39
#include 
40
#ifdef CONFIG_DEBUG_FS
40
#ifdef CONFIG_DEBUG_FS
41
#include 
41
#include 
42
#endif
42
#endif
43
 
43
 
44
struct drm_mm_node {
44
struct drm_mm_node {
45
	struct list_head node_list;
45
	struct list_head node_list;
46
	struct list_head hole_stack;
46
	struct list_head hole_stack;
47
	unsigned hole_follows : 1;
47
	unsigned hole_follows : 1;
48
	unsigned scanned_block : 1;
48
	unsigned scanned_block : 1;
49
	unsigned scanned_prev_free : 1;
49
	unsigned scanned_prev_free : 1;
50
	unsigned scanned_next_free : 1;
50
	unsigned scanned_next_free : 1;
51
	unsigned scanned_preceeds_hole : 1;
51
	unsigned scanned_preceeds_hole : 1;
52
	unsigned allocated : 1;
52
	unsigned allocated : 1;
53
	unsigned long color;
53
	unsigned long color;
54
	unsigned long start;
54
	unsigned long start;
55
	unsigned long size;
55
	unsigned long size;
56
	struct drm_mm *mm;
56
	struct drm_mm *mm;
57
};
57
};
58
 
58
 
59
struct drm_mm {
59
struct drm_mm {
60
	/* List of all memory nodes that immediately precede a free hole. */
60
	/* List of all memory nodes that immediately precede a free hole. */
61
	struct list_head hole_stack;
61
	struct list_head hole_stack;
62
	/* head_node.node_list is the list of all memory nodes, ordered
62
	/* head_node.node_list is the list of all memory nodes, ordered
63
	 * according to the (increasing) start address of the memory node. */
63
	 * according to the (increasing) start address of the memory node. */
64
	struct drm_mm_node head_node;
64
	struct drm_mm_node head_node;
65
	struct list_head unused_nodes;
65
	struct list_head unused_nodes;
66
	int num_unused;
66
	int num_unused;
67
	spinlock_t unused_lock;
67
	spinlock_t unused_lock;
68
	unsigned int scan_check_range : 1;
68
	unsigned int scan_check_range : 1;
69
	unsigned scan_alignment;
69
	unsigned scan_alignment;
70
	unsigned long scan_color;
70
	unsigned long scan_color;
71
	unsigned long scan_size;
71
	unsigned long scan_size;
72
	unsigned long scan_hit_start;
72
	unsigned long scan_hit_start;
73
	unsigned long scan_hit_end;
73
	unsigned long scan_hit_end;
74
	unsigned scanned_blocks;
74
	unsigned scanned_blocks;
75
	unsigned long scan_start;
75
	unsigned long scan_start;
76
	unsigned long scan_end;
76
	unsigned long scan_end;
77
	struct drm_mm_node *prev_scanned_node;
77
	struct drm_mm_node *prev_scanned_node;
78
 
78
 
79
	void (*color_adjust)(struct drm_mm_node *node, unsigned long color,
79
	void (*color_adjust)(struct drm_mm_node *node, unsigned long color,
80
			     unsigned long *start, unsigned long *end);
80
			     unsigned long *start, unsigned long *end);
81
};
81
};
82
 
82
 
83
static inline bool drm_mm_node_allocated(struct drm_mm_node *node)
83
static inline bool drm_mm_node_allocated(struct drm_mm_node *node)
84
{
84
{
85
	return node->allocated;
85
	return node->allocated;
86
}
86
}
87
 
87
 
88
static inline bool drm_mm_initialized(struct drm_mm *mm)
88
static inline bool drm_mm_initialized(struct drm_mm *mm)
89
{
89
{
90
	return mm->hole_stack.next;
90
	return mm->hole_stack.next;
91
}
91
}
92
 
92
 
93
static inline unsigned long __drm_mm_hole_node_start(struct drm_mm_node *hole_node)
93
static inline unsigned long __drm_mm_hole_node_start(struct drm_mm_node *hole_node)
94
{
94
{
95
	return hole_node->start + hole_node->size;
95
	return hole_node->start + hole_node->size;
96
}
96
}
97
 
97
 
98
static inline unsigned long drm_mm_hole_node_start(struct drm_mm_node *hole_node)
98
static inline unsigned long drm_mm_hole_node_start(struct drm_mm_node *hole_node)
99
{
99
{
100
	BUG_ON(!hole_node->hole_follows);
100
	BUG_ON(!hole_node->hole_follows);
101
	return __drm_mm_hole_node_start(hole_node);
101
	return __drm_mm_hole_node_start(hole_node);
102
}
102
}
103
 
103
 
104
static inline unsigned long __drm_mm_hole_node_end(struct drm_mm_node *hole_node)
104
static inline unsigned long __drm_mm_hole_node_end(struct drm_mm_node *hole_node)
105
{
105
{
106
	return list_entry(hole_node->node_list.next,
106
	return list_entry(hole_node->node_list.next,
107
			  struct drm_mm_node, node_list)->start;
107
			  struct drm_mm_node, node_list)->start;
108
}
108
}
109
 
109
 
110
static inline unsigned long drm_mm_hole_node_end(struct drm_mm_node *hole_node)
110
static inline unsigned long drm_mm_hole_node_end(struct drm_mm_node *hole_node)
111
{
111
{
112
	return __drm_mm_hole_node_end(hole_node);
112
	return __drm_mm_hole_node_end(hole_node);
113
}
113
}
114
 
114
 
115
#define drm_mm_for_each_node(entry, mm) list_for_each_entry(entry, \
115
#define drm_mm_for_each_node(entry, mm) list_for_each_entry(entry, \
116
						&(mm)->head_node.node_list, \
116
						&(mm)->head_node.node_list, \
117
						node_list)
117
						node_list)
118
#define drm_mm_for_each_scanned_node_reverse(entry, n, mm) \
118
#define drm_mm_for_each_scanned_node_reverse(entry, n, mm) \
119
	for (entry = (mm)->prev_scanned_node, \
119
	for (entry = (mm)->prev_scanned_node, \
120
		next = entry ? list_entry(entry->node_list.next, \
120
		next = entry ? list_entry(entry->node_list.next, \
121
			struct drm_mm_node, node_list) : NULL; \
121
			struct drm_mm_node, node_list) : NULL; \
122
	     entry != NULL; entry = next, \
122
	     entry != NULL; entry = next, \
123
		next = entry ? list_entry(entry->node_list.next, \
123
		next = entry ? list_entry(entry->node_list.next, \
124
			struct drm_mm_node, node_list) : NULL) \
124
			struct drm_mm_node, node_list) : NULL) \
125
 
125
 
126
/* Note that we need to unroll list_for_each_entry in order to inline
126
/* Note that we need to unroll list_for_each_entry in order to inline
127
 * setting hole_start and hole_end on each iteration and keep the
127
 * setting hole_start and hole_end on each iteration and keep the
128
 * macro sane.
128
 * macro sane.
129
 */
129
 */
130
#define drm_mm_for_each_hole(entry, mm, hole_start, hole_end) \
130
#define drm_mm_for_each_hole(entry, mm, hole_start, hole_end) \
131
	for (entry = list_entry((mm)->hole_stack.next, struct drm_mm_node, hole_stack); \
131
	for (entry = list_entry((mm)->hole_stack.next, struct drm_mm_node, hole_stack); \
132
	     &entry->hole_stack != &(mm)->hole_stack ? \
132
	     &entry->hole_stack != &(mm)->hole_stack ? \
133
	     hole_start = drm_mm_hole_node_start(entry), \
133
	     hole_start = drm_mm_hole_node_start(entry), \
134
	     hole_end = drm_mm_hole_node_end(entry), \
134
	     hole_end = drm_mm_hole_node_end(entry), \
135
	     1 : 0; \
135
	     1 : 0; \
136
	     entry = list_entry(entry->hole_stack.next, struct drm_mm_node, hole_stack))
136
	     entry = list_entry(entry->hole_stack.next, struct drm_mm_node, hole_stack))
137
 
137
 
138
/*
138
/*
139
 * Basic range manager support (drm_mm.c)
139
 * Basic range manager support (drm_mm.c)
140
 */
140
 */
141
extern struct drm_mm_node *drm_mm_create_block(struct drm_mm *mm,
141
extern struct drm_mm_node *drm_mm_create_block(struct drm_mm *mm,
142
					       unsigned long start,
142
					       unsigned long start,
143
					       unsigned long size,
143
					       unsigned long size,
144
					       bool atomic);
144
					       bool atomic);
145
extern struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node,
145
extern struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node,
146
						    unsigned long size,
146
						    unsigned long size,
147
						    unsigned alignment,
147
						    unsigned alignment,
148
						    unsigned long color,
148
						    unsigned long color,
149
						    int atomic);
149
						    int atomic);
150
extern struct drm_mm_node *drm_mm_get_block_range_generic(
150
extern struct drm_mm_node *drm_mm_get_block_range_generic(
151
						struct drm_mm_node *node,
151
						struct drm_mm_node *node,
152
						unsigned long size,
152
						unsigned long size,
153
						unsigned alignment,
153
						unsigned alignment,
154
						unsigned long color,
154
						unsigned long color,
155
						unsigned long start,
155
						unsigned long start,
156
						unsigned long end,
156
						unsigned long end,
157
						int atomic);
157
						int atomic);
158
static inline struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *parent,
158
static inline struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *parent,
159
						   unsigned long size,
159
						   unsigned long size,
160
						   unsigned alignment)
160
						   unsigned alignment)
161
{
161
{
162
	return drm_mm_get_block_generic(parent, size, alignment, 0, 0);
162
	return drm_mm_get_block_generic(parent, size, alignment, 0, 0);
163
}
163
}
164
static inline struct drm_mm_node *drm_mm_get_block_atomic(struct drm_mm_node *parent,
164
static inline struct drm_mm_node *drm_mm_get_block_atomic(struct drm_mm_node *parent,
165
							  unsigned long size,
165
							  unsigned long size,
166
							  unsigned alignment)
166
							  unsigned alignment)
167
{
167
{
168
	return drm_mm_get_block_generic(parent, size, alignment, 0, 1);
168
	return drm_mm_get_block_generic(parent, size, alignment, 0, 1);
169
}
169
}
170
static inline struct drm_mm_node *drm_mm_get_block_range(
170
static inline struct drm_mm_node *drm_mm_get_block_range(
171
						struct drm_mm_node *parent,
171
						struct drm_mm_node *parent,
172
						unsigned long size,
172
						unsigned long size,
173
						unsigned alignment,
173
						unsigned alignment,
174
						unsigned long start,
174
						unsigned long start,
175
						unsigned long end)
175
						unsigned long end)
176
{
176
{
177
	return drm_mm_get_block_range_generic(parent, size, alignment, 0,
177
	return drm_mm_get_block_range_generic(parent, size, alignment, 0,
178
					      start, end, 0);
178
					      start, end, 0);
179
}
179
}
180
static inline struct drm_mm_node *drm_mm_get_color_block_range(
-
 
181
						struct drm_mm_node *parent,
-
 
182
						unsigned long size,
-
 
183
						unsigned alignment,
-
 
184
						unsigned long color,
-
 
185
						unsigned long start,
-
 
186
						unsigned long end)
-
 
187
{
-
 
188
	return drm_mm_get_block_range_generic(parent, size, alignment, color,
-
 
189
						start, end, 0);
-
 
190
}
-
 
191
static inline struct drm_mm_node *drm_mm_get_block_atomic_range(
180
static inline struct drm_mm_node *drm_mm_get_block_atomic_range(
192
						struct drm_mm_node *parent,
181
						struct drm_mm_node *parent,
193
						unsigned long size,
182
						unsigned long size,
194
						unsigned alignment,
183
						unsigned alignment,
195
						unsigned long start,
184
						unsigned long start,
196
						unsigned long end)
185
						unsigned long end)
197
{
186
{
198
	return drm_mm_get_block_range_generic(parent, size, alignment, 0,
187
	return drm_mm_get_block_range_generic(parent, size, alignment, 0,
199
						start, end, 1);
188
						start, end, 1);
200
}
189
}
201
 
190
 
202
extern int drm_mm_insert_node(struct drm_mm *mm,
191
extern int drm_mm_insert_node(struct drm_mm *mm,
203
			      struct drm_mm_node *node,
192
			      struct drm_mm_node *node,
204
			      unsigned long size,
193
			      unsigned long size,
205
			      unsigned alignment);
194
			      unsigned alignment);
206
extern int drm_mm_insert_node_in_range(struct drm_mm *mm,
195
extern int drm_mm_insert_node_in_range(struct drm_mm *mm,
207
				       struct drm_mm_node *node,
196
				       struct drm_mm_node *node,
208
				       unsigned long size,
197
				       unsigned long size,
209
				       unsigned alignment,
198
				       unsigned alignment,
210
				       unsigned long start,
199
				       unsigned long start,
211
				       unsigned long end);
200
				       unsigned long end);
212
extern int drm_mm_insert_node_generic(struct drm_mm *mm,
201
extern int drm_mm_insert_node_generic(struct drm_mm *mm,
213
				      struct drm_mm_node *node,
202
				      struct drm_mm_node *node,
214
				      unsigned long size,
203
				      unsigned long size,
215
				      unsigned alignment,
204
				      unsigned alignment,
216
				      unsigned long color);
205
				      unsigned long color);
217
extern int drm_mm_insert_node_in_range_generic(struct drm_mm *mm,
206
extern int drm_mm_insert_node_in_range_generic(struct drm_mm *mm,
218
				       struct drm_mm_node *node,
207
				       struct drm_mm_node *node,
219
				       unsigned long size,
208
				       unsigned long size,
220
				       unsigned alignment,
209
				       unsigned alignment,
221
				       unsigned long color,
210
				       unsigned long color,
222
				       unsigned long start,
211
				       unsigned long start,
223
				       unsigned long end);
212
				       unsigned long end);
224
extern void drm_mm_put_block(struct drm_mm_node *cur);
213
extern void drm_mm_put_block(struct drm_mm_node *cur);
225
extern void drm_mm_remove_node(struct drm_mm_node *node);
214
extern void drm_mm_remove_node(struct drm_mm_node *node);
226
extern void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new);
215
extern void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new);
227
extern struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm,
216
extern struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm,
228
					      unsigned long size,
217
					      unsigned long size,
229
					      unsigned alignment,
218
					      unsigned alignment,
230
						      unsigned long color,
219
						      unsigned long color,
231
						      bool best_match);
220
						      bool best_match);
232
extern struct drm_mm_node *drm_mm_search_free_in_range_generic(
221
extern struct drm_mm_node *drm_mm_search_free_in_range_generic(
233
						const struct drm_mm *mm,
222
						const struct drm_mm *mm,
234
						unsigned long size,
223
						unsigned long size,
235
						unsigned alignment,
224
						unsigned alignment,
236
						unsigned long color,
225
						unsigned long color,
237
						unsigned long start,
226
						unsigned long start,
238
						unsigned long end,
227
						unsigned long end,
239
						bool best_match);
228
						bool best_match);
240
static inline struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm,
229
static inline struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm,
241
						     unsigned long size,
230
						     unsigned long size,
242
						     unsigned alignment,
231
						     unsigned alignment,
243
						     bool best_match)
232
						     bool best_match)
244
{
233
{
245
	return drm_mm_search_free_generic(mm,size, alignment, 0, best_match);
234
	return drm_mm_search_free_generic(mm,size, alignment, 0, best_match);
246
}
235
}
247
static inline  struct drm_mm_node *drm_mm_search_free_in_range(
236
static inline  struct drm_mm_node *drm_mm_search_free_in_range(
248
						const struct drm_mm *mm,
237
						const struct drm_mm *mm,
249
						unsigned long size,
238
						unsigned long size,
250
						unsigned alignment,
239
						unsigned alignment,
251
						unsigned long start,
240
						unsigned long start,
252
						unsigned long end,
241
						unsigned long end,
253
						bool best_match)
242
						bool best_match)
254
{
243
{
255
	return drm_mm_search_free_in_range_generic(mm, size, alignment, 0,
244
	return drm_mm_search_free_in_range_generic(mm, size, alignment, 0,
256
						   start, end, best_match);
245
						   start, end, best_match);
257
}
246
}
258
static inline struct drm_mm_node *drm_mm_search_free_color(const struct drm_mm *mm,
-
 
259
							   unsigned long size,
-
 
260
							   unsigned alignment,
-
 
261
							   unsigned long color,
-
 
262
							   bool best_match)
-
 
263
{
247
 
264
	return drm_mm_search_free_generic(mm,size, alignment, color, best_match);
-
 
265
}
-
 
266
static inline  struct drm_mm_node *drm_mm_search_free_in_range_color(
-
 
267
						const struct drm_mm *mm,
-
 
268
						unsigned long size,
-
 
269
						unsigned alignment,
-
 
270
						unsigned long color,
-
 
271
						unsigned long start,
-
 
272
						unsigned long end,
-
 
273
						bool best_match)
-
 
274
{
-
 
275
	return drm_mm_search_free_in_range_generic(mm, size, alignment, color,
-
 
276
						   start, end, best_match);
-
 
277
}
-
 
278
extern int drm_mm_init(struct drm_mm *mm,
248
extern void drm_mm_init(struct drm_mm *mm,
279
		       unsigned long start,
249
		       unsigned long start,
280
		       unsigned long size);
250
		       unsigned long size);
281
extern void drm_mm_takedown(struct drm_mm *mm);
251
extern void drm_mm_takedown(struct drm_mm *mm);
282
extern int drm_mm_clean(struct drm_mm *mm);
252
extern int drm_mm_clean(struct drm_mm *mm);
283
extern int drm_mm_pre_get(struct drm_mm *mm);
253
extern int drm_mm_pre_get(struct drm_mm *mm);
284
 
254
 
285
static inline struct drm_mm *drm_get_mm(struct drm_mm_node *block)
255
static inline struct drm_mm *drm_get_mm(struct drm_mm_node *block)
286
{
256
{
287
	return block->mm;
257
	return block->mm;
288
}
258
}
289
 
259
 
290
void drm_mm_init_scan(struct drm_mm *mm,
260
void drm_mm_init_scan(struct drm_mm *mm,
291
		      unsigned long size,
261
		      unsigned long size,
292
				 unsigned alignment,
262
				 unsigned alignment,
293
		      unsigned long color);
263
		      unsigned long color);
294
void drm_mm_init_scan_with_range(struct drm_mm *mm,
264
void drm_mm_init_scan_with_range(struct drm_mm *mm,
295
				 unsigned long size,
265
				 unsigned long size,
296
				 unsigned alignment,
266
				 unsigned alignment,
297
				 unsigned long color,
267
				 unsigned long color,
298
				 unsigned long start,
268
				 unsigned long start,
299
				 unsigned long end);
269
				 unsigned long end);
300
int drm_mm_scan_add_block(struct drm_mm_node *node);
270
int drm_mm_scan_add_block(struct drm_mm_node *node);
301
int drm_mm_scan_remove_block(struct drm_mm_node *node);
271
int drm_mm_scan_remove_block(struct drm_mm_node *node);
302
 
272
 
303
extern void drm_mm_debug_table(struct drm_mm *mm, const char *prefix);
273
extern void drm_mm_debug_table(struct drm_mm *mm, const char *prefix);
304
#ifdef CONFIG_DEBUG_FS
274
#ifdef CONFIG_DEBUG_FS
305
int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm);
275
int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm);
306
#endif
276
#endif
307
 
277
 
308
#endif
278
#endif