Subversion Repositories Kolibri OS

Rev

Rev 4065 | Rev 4110 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1408 serge 1
/**************************************************************************
2
 *
3
 * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX. USA.
4
 * All Rights Reserved.
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the
8
 * "Software"), to deal in the Software without restriction, including
9
 * without limitation the rights to use, copy, modify, merge, publish,
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
12
 * the following conditions:
13
 *
14
 * The above copyright notice and this permission notice (including the
15
 * next paragraph) shall be included in all copies or substantial portions
16
 * of the Software.
17
 *
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,
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,
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
24
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25
 *
26
 *
27
 **************************************************************************/
28
/*
29
 * Authors:
30
 * Thomas Hellstrom 
31
 */
32
 
33
#ifndef _DRM_MM_H_
34
#define _DRM_MM_H_
35
 
36
/*
37
 * Generic range manager structs
38
 */
39
#include 
40
#ifdef CONFIG_DEBUG_FS
41
#include 
42
#endif
43
 
4103 Serge 44
enum drm_mm_search_flags {
45
	DRM_MM_SEARCH_DEFAULT =		0,
46
	DRM_MM_SEARCH_BEST =		1 << 0,
47
};
48
 
1408 serge 49
struct drm_mm_node {
1964 serge 50
	struct list_head node_list;
51
	struct list_head hole_stack;
52
	unsigned hole_follows : 1;
53
	unsigned scanned_block : 1;
54
	unsigned scanned_prev_free : 1;
55
	unsigned scanned_next_free : 1;
56
	unsigned scanned_preceeds_hole : 1;
57
	unsigned allocated : 1;
3031 serge 58
	unsigned long color;
1408 serge 59
	unsigned long start;
60
	unsigned long size;
61
	struct drm_mm *mm;
62
};
63
 
64
struct drm_mm {
1964 serge 65
	/* List of all memory nodes that immediately precede a free hole. */
66
	struct list_head hole_stack;
67
	/* head_node.node_list is the list of all memory nodes, ordered
68
	 * according to the (increasing) start address of the memory node. */
69
	struct drm_mm_node head_node;
70
	unsigned int scan_check_range : 1;
71
	unsigned scan_alignment;
3031 serge 72
	unsigned long scan_color;
1964 serge 73
	unsigned long scan_size;
74
	unsigned long scan_hit_start;
3192 Serge 75
	unsigned long scan_hit_end;
1964 serge 76
	unsigned scanned_blocks;
77
	unsigned long scan_start;
78
	unsigned long scan_end;
79
	struct drm_mm_node *prev_scanned_node;
3031 serge 80
 
81
	void (*color_adjust)(struct drm_mm_node *node, unsigned long color,
82
			     unsigned long *start, unsigned long *end);
1408 serge 83
};
84
 
1964 serge 85
static inline bool drm_mm_node_allocated(struct drm_mm_node *node)
86
{
87
	return node->allocated;
88
}
89
 
90
static inline bool drm_mm_initialized(struct drm_mm *mm)
91
{
92
	return mm->hole_stack.next;
93
}
3391 Serge 94
 
95
static inline unsigned long __drm_mm_hole_node_start(struct drm_mm_node *hole_node)
96
{
97
	return hole_node->start + hole_node->size;
98
}
99
 
100
static inline unsigned long drm_mm_hole_node_start(struct drm_mm_node *hole_node)
101
{
102
	BUG_ON(!hole_node->hole_follows);
103
	return __drm_mm_hole_node_start(hole_node);
104
}
105
 
106
static inline unsigned long __drm_mm_hole_node_end(struct drm_mm_node *hole_node)
107
{
108
	return list_entry(hole_node->node_list.next,
109
			  struct drm_mm_node, node_list)->start;
110
}
111
 
112
static inline unsigned long drm_mm_hole_node_end(struct drm_mm_node *hole_node)
113
{
114
	return __drm_mm_hole_node_end(hole_node);
115
}
116
 
1964 serge 117
#define drm_mm_for_each_node(entry, mm) list_for_each_entry(entry, \
118
						&(mm)->head_node.node_list, \
119
						node_list)
3391 Serge 120
 
121
/* Note that we need to unroll list_for_each_entry in order to inline
122
 * setting hole_start and hole_end on each iteration and keep the
123
 * macro sane.
124
 */
125
#define drm_mm_for_each_hole(entry, mm, hole_start, hole_end) \
126
	for (entry = list_entry((mm)->hole_stack.next, struct drm_mm_node, hole_stack); \
127
	     &entry->hole_stack != &(mm)->hole_stack ? \
128
	     hole_start = drm_mm_hole_node_start(entry), \
129
	     hole_end = drm_mm_hole_node_end(entry), \
130
	     1 : 0; \
131
	     entry = list_entry(entry->hole_stack.next, struct drm_mm_node, hole_stack))
132
 
1408 serge 133
/*
134
 * Basic range manager support (drm_mm.c)
135
 */
4103 Serge 136
extern int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node);
137
 
138
extern int drm_mm_insert_node_generic(struct drm_mm *mm,
139
				      struct drm_mm_node *node,
1408 serge 140
						    unsigned long size,
141
						    unsigned alignment,
3031 serge 142
						    unsigned long color,
4103 Serge 143
				      enum drm_mm_search_flags flags);
144
static inline int drm_mm_insert_node(struct drm_mm *mm,
1408 serge 145
						struct drm_mm_node *node,
146
						unsigned long size,
147
						unsigned alignment,
4103 Serge 148
				     enum drm_mm_search_flags flags)
1408 serge 149
{
4103 Serge 150
	return drm_mm_insert_node_generic(mm, node, size, alignment, 0, flags);
1408 serge 151
}
3192 Serge 152
 
153
extern int drm_mm_insert_node_in_range_generic(struct drm_mm *mm,
154
				       struct drm_mm_node *node,
155
				       unsigned long size,
156
				       unsigned alignment,
157
				       unsigned long color,
158
				       unsigned long start,
1408 serge 159
						unsigned long end,
4103 Serge 160
				       enum drm_mm_search_flags flags);
161
static inline int drm_mm_insert_node_in_range(struct drm_mm *mm,
162
					      struct drm_mm_node *node,
3031 serge 163
						unsigned long size,
164
						unsigned alignment,
165
						unsigned long start,
166
						unsigned long end,
4103 Serge 167
					      enum drm_mm_search_flags flags)
3031 serge 168
{
4103 Serge 169
	return drm_mm_insert_node_in_range_generic(mm, node, size, alignment,
170
						   0, start, end, flags);
3031 serge 171
}
4065 Serge 172
 
4103 Serge 173
extern void drm_mm_remove_node(struct drm_mm_node *node);
174
extern void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new);
4065 Serge 175
extern void drm_mm_init(struct drm_mm *mm,
3031 serge 176
		       unsigned long start,
1408 serge 177
		       unsigned long size);
178
extern void drm_mm_takedown(struct drm_mm *mm);
179
extern int drm_mm_clean(struct drm_mm *mm);
180
 
3031 serge 181
void drm_mm_init_scan(struct drm_mm *mm,
182
		      unsigned long size,
1964 serge 183
				 unsigned alignment,
3031 serge 184
		      unsigned long color);
185
void drm_mm_init_scan_with_range(struct drm_mm *mm,
186
				 unsigned long size,
187
				 unsigned alignment,
188
				 unsigned long color,
1964 serge 189
				 unsigned long start,
190
				 unsigned long end);
191
int drm_mm_scan_add_block(struct drm_mm_node *node);
192
int drm_mm_scan_remove_block(struct drm_mm_node *node);
193
 
1408 serge 194
extern void drm_mm_debug_table(struct drm_mm *mm, const char *prefix);
195
#ifdef CONFIG_DEBUG_FS
196
int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm);
197
#endif
198
 
199
#endif