Subversion Repositories Kolibri OS

Rev

Rev 4103 | Rev 5056 | 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
 */
4110 Serge 39
#include 
40
#include 
1408 serge 41
#include 
4110 Serge 42
#include 
1408 serge 43
#ifdef CONFIG_DEBUG_FS
44
#include 
45
#endif
46
 
4103 Serge 47
enum drm_mm_search_flags {
48
	DRM_MM_SEARCH_DEFAULT =		0,
49
	DRM_MM_SEARCH_BEST =		1 << 0,
50
};
51
 
1408 serge 52
struct drm_mm_node {
1964 serge 53
	struct list_head node_list;
54
	struct list_head hole_stack;
55
	unsigned hole_follows : 1;
56
	unsigned scanned_block : 1;
57
	unsigned scanned_prev_free : 1;
58
	unsigned scanned_next_free : 1;
59
	unsigned scanned_preceeds_hole : 1;
60
	unsigned allocated : 1;
3031 serge 61
	unsigned long color;
1408 serge 62
	unsigned long start;
63
	unsigned long size;
64
	struct drm_mm *mm;
65
};
66
 
67
struct drm_mm {
1964 serge 68
	/* List of all memory nodes that immediately precede a free hole. */
69
	struct list_head hole_stack;
70
	/* head_node.node_list is the list of all memory nodes, ordered
71
	 * according to the (increasing) start address of the memory node. */
72
	struct drm_mm_node head_node;
73
	unsigned int scan_check_range : 1;
74
	unsigned scan_alignment;
3031 serge 75
	unsigned long scan_color;
1964 serge 76
	unsigned long scan_size;
77
	unsigned long scan_hit_start;
3192 Serge 78
	unsigned long scan_hit_end;
1964 serge 79
	unsigned scanned_blocks;
80
	unsigned long scan_start;
81
	unsigned long scan_end;
82
	struct drm_mm_node *prev_scanned_node;
3031 serge 83
 
84
	void (*color_adjust)(struct drm_mm_node *node, unsigned long color,
85
			     unsigned long *start, unsigned long *end);
1408 serge 86
};
87
 
1964 serge 88
static inline bool drm_mm_node_allocated(struct drm_mm_node *node)
89
{
90
	return node->allocated;
91
}
92
 
93
static inline bool drm_mm_initialized(struct drm_mm *mm)
94
{
95
	return mm->hole_stack.next;
96
}
3391 Serge 97
 
98
static inline unsigned long __drm_mm_hole_node_start(struct drm_mm_node *hole_node)
99
{
100
	return hole_node->start + hole_node->size;
101
}
102
 
103
static inline unsigned long drm_mm_hole_node_start(struct drm_mm_node *hole_node)
104
{
105
	BUG_ON(!hole_node->hole_follows);
106
	return __drm_mm_hole_node_start(hole_node);
107
}
108
 
109
static inline unsigned long __drm_mm_hole_node_end(struct drm_mm_node *hole_node)
110
{
111
	return list_entry(hole_node->node_list.next,
112
			  struct drm_mm_node, node_list)->start;
113
}
114
 
115
static inline unsigned long drm_mm_hole_node_end(struct drm_mm_node *hole_node)
116
{
117
	return __drm_mm_hole_node_end(hole_node);
118
}
119
 
1964 serge 120
#define drm_mm_for_each_node(entry, mm) list_for_each_entry(entry, \
121
						&(mm)->head_node.node_list, \
122
						node_list)
3391 Serge 123
 
124
/* Note that we need to unroll list_for_each_entry in order to inline
125
 * setting hole_start and hole_end on each iteration and keep the
126
 * macro sane.
127
 */
128
#define drm_mm_for_each_hole(entry, mm, hole_start, hole_end) \
129
	for (entry = list_entry((mm)->hole_stack.next, struct drm_mm_node, hole_stack); \
130
	     &entry->hole_stack != &(mm)->hole_stack ? \
131
	     hole_start = drm_mm_hole_node_start(entry), \
132
	     hole_end = drm_mm_hole_node_end(entry), \
133
	     1 : 0; \
134
	     entry = list_entry(entry->hole_stack.next, struct drm_mm_node, hole_stack))
135
 
1408 serge 136
/*
137
 * Basic range manager support (drm_mm.c)
138
 */
4103 Serge 139
extern int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node);
140
 
141
extern int drm_mm_insert_node_generic(struct drm_mm *mm,
142
				      struct drm_mm_node *node,
1408 serge 143
						    unsigned long size,
144
						    unsigned alignment,
3031 serge 145
						    unsigned long color,
4103 Serge 146
				      enum drm_mm_search_flags flags);
147
static inline int drm_mm_insert_node(struct drm_mm *mm,
1408 serge 148
						struct drm_mm_node *node,
149
						unsigned long size,
150
						unsigned alignment,
4103 Serge 151
				     enum drm_mm_search_flags flags)
1408 serge 152
{
4103 Serge 153
	return drm_mm_insert_node_generic(mm, node, size, alignment, 0, flags);
1408 serge 154
}
3192 Serge 155
 
156
extern int drm_mm_insert_node_in_range_generic(struct drm_mm *mm,
157
				       struct drm_mm_node *node,
158
				       unsigned long size,
159
				       unsigned alignment,
160
				       unsigned long color,
161
				       unsigned long start,
1408 serge 162
						unsigned long end,
4103 Serge 163
				       enum drm_mm_search_flags flags);
164
static inline int drm_mm_insert_node_in_range(struct drm_mm *mm,
165
					      struct drm_mm_node *node,
3031 serge 166
						unsigned long size,
167
						unsigned alignment,
168
						unsigned long start,
169
						unsigned long end,
4103 Serge 170
					      enum drm_mm_search_flags flags)
3031 serge 171
{
4103 Serge 172
	return drm_mm_insert_node_in_range_generic(mm, node, size, alignment,
173
						   0, start, end, flags);
3031 serge 174
}
4065 Serge 175
 
4103 Serge 176
extern void drm_mm_remove_node(struct drm_mm_node *node);
177
extern void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new);
4065 Serge 178
extern void drm_mm_init(struct drm_mm *mm,
3031 serge 179
		       unsigned long start,
1408 serge 180
		       unsigned long size);
181
extern void drm_mm_takedown(struct drm_mm *mm);
182
extern int drm_mm_clean(struct drm_mm *mm);
183
 
3031 serge 184
void drm_mm_init_scan(struct drm_mm *mm,
185
		      unsigned long size,
1964 serge 186
				 unsigned alignment,
3031 serge 187
		      unsigned long color);
188
void drm_mm_init_scan_with_range(struct drm_mm *mm,
189
				 unsigned long size,
190
				 unsigned alignment,
191
				 unsigned long color,
1964 serge 192
				 unsigned long start,
193
				 unsigned long end);
194
int drm_mm_scan_add_block(struct drm_mm_node *node);
195
int drm_mm_scan_remove_block(struct drm_mm_node *node);
196
 
1408 serge 197
extern void drm_mm_debug_table(struct drm_mm *mm, const char *prefix);
198
#ifdef CONFIG_DEBUG_FS
199
int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm);
200
#endif
201
 
202
#endif