Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
drm_mm.h
Go to the documentation of this file.
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 <thomas-at-tungstengraphics-dot-com>
31  */
32 
33 #ifndef _DRM_MM_H_
34 #define _DRM_MM_H_
35 
36 /*
37  * Generic range manager structs
38  */
39 #include <linux/list.h>
40 #ifdef CONFIG_DEBUG_FS
41 #include <linux/seq_file.h>
42 #endif
43 
44 struct drm_mm_node {
47  unsigned hole_follows : 1;
48  unsigned scanned_block : 1;
49  unsigned scanned_prev_free : 1;
50  unsigned scanned_next_free : 1;
51  unsigned scanned_preceeds_hole : 1;
52  unsigned allocated : 1;
53  unsigned long color;
54  unsigned long start;
55  unsigned long size;
56  struct drm_mm *mm;
57 };
58 
59 struct drm_mm {
60  /* List of all memory nodes that immediately precede a free hole. */
62  /* head_node.node_list is the list of all memory nodes, ordered
63  * according to the (increasing) start address of the memory node. */
68  unsigned int scan_check_range : 1;
69  unsigned scan_alignment;
70  unsigned long scan_color;
71  unsigned long scan_size;
72  unsigned long scan_hit_start;
73  unsigned scan_hit_size;
74  unsigned scanned_blocks;
75  unsigned long scan_start;
76  unsigned long scan_end;
78 
79  void (*color_adjust)(struct drm_mm_node *node, unsigned long color,
80  unsigned long *start, unsigned long *end);
81 };
82 
83 static inline bool drm_mm_node_allocated(struct drm_mm_node *node)
84 {
85  return node->allocated;
86 }
87 
88 static inline bool drm_mm_initialized(struct drm_mm *mm)
89 {
90  return mm->hole_stack.next;
91 }
92 #define drm_mm_for_each_node(entry, mm) list_for_each_entry(entry, \
93  &(mm)->head_node.node_list, \
94  node_list)
95 #define drm_mm_for_each_scanned_node_reverse(entry, n, mm) \
96  for (entry = (mm)->prev_scanned_node, \
97  next = entry ? list_entry(entry->node_list.next, \
98  struct drm_mm_node, node_list) : NULL; \
99  entry != NULL; entry = next, \
100  next = entry ? list_entry(entry->node_list.next, \
101  struct drm_mm_node, node_list) : NULL) \
102 /*
103  * Basic range manager support (drm_mm.c)
104  */
106  unsigned long size,
107  unsigned alignment,
108  unsigned long color,
109  int atomic);
111  struct drm_mm_node *node,
112  unsigned long size,
113  unsigned alignment,
114  unsigned long color,
115  unsigned long start,
116  unsigned long end,
117  int atomic);
118 static inline struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *parent,
119  unsigned long size,
120  unsigned alignment)
121 {
122  return drm_mm_get_block_generic(parent, size, alignment, 0, 0);
123 }
124 static inline struct drm_mm_node *drm_mm_get_block_atomic(struct drm_mm_node *parent,
125  unsigned long size,
126  unsigned alignment)
127 {
128  return drm_mm_get_block_generic(parent, size, alignment, 0, 1);
129 }
130 static inline struct drm_mm_node *drm_mm_get_block_range(
131  struct drm_mm_node *parent,
132  unsigned long size,
133  unsigned alignment,
134  unsigned long start,
135  unsigned long end)
136 {
137  return drm_mm_get_block_range_generic(parent, size, alignment, 0,
138  start, end, 0);
139 }
140 static inline struct drm_mm_node *drm_mm_get_color_block_range(
141  struct drm_mm_node *parent,
142  unsigned long size,
143  unsigned alignment,
144  unsigned long color,
145  unsigned long start,
146  unsigned long end)
147 {
148  return drm_mm_get_block_range_generic(parent, size, alignment, color,
149  start, end, 0);
150 }
151 static inline struct drm_mm_node *drm_mm_get_block_atomic_range(
152  struct drm_mm_node *parent,
153  unsigned long size,
154  unsigned alignment,
155  unsigned long start,
156  unsigned long end)
157 {
158  return drm_mm_get_block_range_generic(parent, size, alignment, 0,
159  start, end, 1);
160 }
161 extern int drm_mm_insert_node(struct drm_mm *mm, struct drm_mm_node *node,
162  unsigned long size, unsigned alignment);
163 extern int drm_mm_insert_node_in_range(struct drm_mm *mm,
164  struct drm_mm_node *node,
165  unsigned long size, unsigned alignment,
166  unsigned long start, unsigned long end);
167 extern void drm_mm_put_block(struct drm_mm_node *cur);
168 extern void drm_mm_remove_node(struct drm_mm_node *node);
169 extern void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new);
170 extern struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm,
171  unsigned long size,
172  unsigned alignment,
173  unsigned long color,
174  bool best_match);
176  const struct drm_mm *mm,
177  unsigned long size,
178  unsigned alignment,
179  unsigned long color,
180  unsigned long start,
181  unsigned long end,
182  bool best_match);
183 static inline struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm,
184  unsigned long size,
185  unsigned alignment,
186  bool best_match)
187 {
188  return drm_mm_search_free_generic(mm,size, alignment, 0, best_match);
189 }
190 static inline struct drm_mm_node *drm_mm_search_free_in_range(
191  const struct drm_mm *mm,
192  unsigned long size,
193  unsigned alignment,
194  unsigned long start,
195  unsigned long end,
196  bool best_match)
197 {
198  return drm_mm_search_free_in_range_generic(mm, size, alignment, 0,
199  start, end, best_match);
200 }
201 static inline struct drm_mm_node *drm_mm_search_free_color(const struct drm_mm *mm,
202  unsigned long size,
203  unsigned alignment,
204  unsigned long color,
205  bool best_match)
206 {
207  return drm_mm_search_free_generic(mm,size, alignment, color, best_match);
208 }
209 static inline struct drm_mm_node *drm_mm_search_free_in_range_color(
210  const struct drm_mm *mm,
211  unsigned long size,
212  unsigned alignment,
213  unsigned long color,
214  unsigned long start,
215  unsigned long end,
216  bool best_match)
217 {
218  return drm_mm_search_free_in_range_generic(mm, size, alignment, color,
219  start, end, best_match);
220 }
221 extern int drm_mm_init(struct drm_mm *mm,
222  unsigned long start,
223  unsigned long size);
224 extern void drm_mm_takedown(struct drm_mm *mm);
225 extern int drm_mm_clean(struct drm_mm *mm);
226 extern int drm_mm_pre_get(struct drm_mm *mm);
227 
228 static inline struct drm_mm *drm_get_mm(struct drm_mm_node *block)
229 {
230  return block->mm;
231 }
232 
233 void drm_mm_init_scan(struct drm_mm *mm,
234  unsigned long size,
235  unsigned alignment,
236  unsigned long color);
237 void drm_mm_init_scan_with_range(struct drm_mm *mm,
238  unsigned long size,
239  unsigned alignment,
240  unsigned long color,
241  unsigned long start,
242  unsigned long end);
245 
246 extern void drm_mm_debug_table(struct drm_mm *mm, const char *prefix);
247 #ifdef CONFIG_DEBUG_FS
248 int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm);
249 #endif
250 
251 #endif