aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/drm_gem.c2
-rw-r--r--drivers/gpu/drm/drm_mm.c169
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c6
-rw-r--r--drivers/gpu/drm/i915/i915_gem_evict.c9
-rw-r--r--include/drm/drm_mm.h93
5 files changed, 191 insertions, 88 deletions
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index d58e69da1fb5..fbe0842038b5 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -354,7 +354,7 @@ drm_gem_create_mmap_offset(struct drm_gem_object *obj)
354 354
355 /* Get a DRM GEM mmap offset allocated... */ 355 /* Get a DRM GEM mmap offset allocated... */
356 list->file_offset_node = drm_mm_search_free(&mm->offset_manager, 356 list->file_offset_node = drm_mm_search_free(&mm->offset_manager,
357 obj->size / PAGE_SIZE, 0, 0); 357 obj->size / PAGE_SIZE, 0, false);
358 358
359 if (!list->file_offset_node) { 359 if (!list->file_offset_node) {
360 DRM_ERROR("failed to allocate offset for bo %d\n", obj->name); 360 DRM_ERROR("failed to allocate offset for bo %d\n", obj->name);
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 961fb54f4266..9bb82f7f0061 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -118,45 +118,53 @@ static inline unsigned long drm_mm_hole_node_end(struct drm_mm_node *hole_node)
118 118
119static void drm_mm_insert_helper(struct drm_mm_node *hole_node, 119static void drm_mm_insert_helper(struct drm_mm_node *hole_node,
120 struct drm_mm_node *node, 120 struct drm_mm_node *node,
121 unsigned long size, unsigned alignment) 121 unsigned long size, unsigned alignment,
122 unsigned long color)
122{ 123{
123 struct drm_mm *mm = hole_node->mm; 124 struct drm_mm *mm = hole_node->mm;
124 unsigned long tmp = 0, wasted = 0;
125 unsigned long hole_start = drm_mm_hole_node_start(hole_node); 125 unsigned long hole_start = drm_mm_hole_node_start(hole_node);
126 unsigned long hole_end = drm_mm_hole_node_end(hole_node); 126 unsigned long hole_end = drm_mm_hole_node_end(hole_node);
127 unsigned long adj_start = hole_start;
128 unsigned long adj_end = hole_end;
127 129
128 BUG_ON(!hole_node->hole_follows || node->allocated); 130 BUG_ON(!hole_node->hole_follows || node->allocated);
129 131
130 if (alignment) 132 if (mm->color_adjust)
131 tmp = hole_start % alignment; 133 mm->color_adjust(hole_node, color, &adj_start, &adj_end);
132 134
133 if (!tmp) { 135 if (alignment) {
136 unsigned tmp = adj_start % alignment;
137 if (tmp)
138 adj_start += alignment - tmp;
139 }
140
141 if (adj_start == hole_start) {
134 hole_node->hole_follows = 0; 142 hole_node->hole_follows = 0;
135 list_del_init(&hole_node->hole_stack); 143 list_del(&hole_node->hole_stack);
136 } else 144 }
137 wasted = alignment - tmp;
138 145
139 node->start = hole_start + wasted; 146 node->start = adj_start;
140 node->size = size; 147 node->size = size;
141 node->mm = mm; 148 node->mm = mm;
149 node->color = color;
142 node->allocated = 1; 150 node->allocated = 1;
143 151
144 INIT_LIST_HEAD(&node->hole_stack); 152 INIT_LIST_HEAD(&node->hole_stack);
145 list_add(&node->node_list, &hole_node->node_list); 153 list_add(&node->node_list, &hole_node->node_list);
146 154
147 BUG_ON(node->start + node->size > hole_end); 155 BUG_ON(node->start + node->size > adj_end);
148 156
157 node->hole_follows = 0;
149 if (node->start + node->size < hole_end) { 158 if (node->start + node->size < hole_end) {
150 list_add(&node->hole_stack, &mm->hole_stack); 159 list_add(&node->hole_stack, &mm->hole_stack);
151 node->hole_follows = 1; 160 node->hole_follows = 1;
152 } else {
153 node->hole_follows = 0;
154 } 161 }
155} 162}
156 163
157struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *hole_node, 164struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *hole_node,
158 unsigned long size, 165 unsigned long size,
159 unsigned alignment, 166 unsigned alignment,
167 unsigned long color,
160 int atomic) 168 int atomic)
161{ 169{
162 struct drm_mm_node *node; 170 struct drm_mm_node *node;
@@ -165,7 +173,7 @@ struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *hole_node,
165 if (unlikely(node == NULL)) 173 if (unlikely(node == NULL))
166 return NULL; 174 return NULL;
167 175
168 drm_mm_insert_helper(hole_node, node, size, alignment); 176 drm_mm_insert_helper(hole_node, node, size, alignment, color);
169 177
170 return node; 178 return node;
171} 179}
@@ -181,11 +189,11 @@ int drm_mm_insert_node(struct drm_mm *mm, struct drm_mm_node *node,
181{ 189{
182 struct drm_mm_node *hole_node; 190 struct drm_mm_node *hole_node;
183 191
184 hole_node = drm_mm_search_free(mm, size, alignment, 0); 192 hole_node = drm_mm_search_free(mm, size, alignment, false);
185 if (!hole_node) 193 if (!hole_node)
186 return -ENOSPC; 194 return -ENOSPC;
187 195
188 drm_mm_insert_helper(hole_node, node, size, alignment); 196 drm_mm_insert_helper(hole_node, node, size, alignment, 0);
189 197
190 return 0; 198 return 0;
191} 199}
@@ -194,50 +202,57 @@ EXPORT_SYMBOL(drm_mm_insert_node);
194static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node, 202static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node,
195 struct drm_mm_node *node, 203 struct drm_mm_node *node,
196 unsigned long size, unsigned alignment, 204 unsigned long size, unsigned alignment,
205 unsigned long color,
197 unsigned long start, unsigned long end) 206 unsigned long start, unsigned long end)
198{ 207{
199 struct drm_mm *mm = hole_node->mm; 208 struct drm_mm *mm = hole_node->mm;
200 unsigned long tmp = 0, wasted = 0;
201 unsigned long hole_start = drm_mm_hole_node_start(hole_node); 209 unsigned long hole_start = drm_mm_hole_node_start(hole_node);
202 unsigned long hole_end = drm_mm_hole_node_end(hole_node); 210 unsigned long hole_end = drm_mm_hole_node_end(hole_node);
211 unsigned long adj_start = hole_start;
212 unsigned long adj_end = hole_end;
203 213
204 BUG_ON(!hole_node->hole_follows || node->allocated); 214 BUG_ON(!hole_node->hole_follows || node->allocated);
205 215
206 if (hole_start < start) 216 if (mm->color_adjust)
207 wasted += start - hole_start; 217 mm->color_adjust(hole_node, color, &adj_start, &adj_end);
208 if (alignment)
209 tmp = (hole_start + wasted) % alignment;
210 218
211 if (tmp) 219 if (adj_start < start)
212 wasted += alignment - tmp; 220 adj_start = start;
221
222 if (alignment) {
223 unsigned tmp = adj_start % alignment;
224 if (tmp)
225 adj_start += alignment - tmp;
226 }
213 227
214 if (!wasted) { 228 if (adj_start == hole_start) {
215 hole_node->hole_follows = 0; 229 hole_node->hole_follows = 0;
216 list_del_init(&hole_node->hole_stack); 230 list_del(&hole_node->hole_stack);
217 } 231 }
218 232
219 node->start = hole_start + wasted; 233 node->start = adj_start;
220 node->size = size; 234 node->size = size;
221 node->mm = mm; 235 node->mm = mm;
236 node->color = color;
222 node->allocated = 1; 237 node->allocated = 1;
223 238
224 INIT_LIST_HEAD(&node->hole_stack); 239 INIT_LIST_HEAD(&node->hole_stack);
225 list_add(&node->node_list, &hole_node->node_list); 240 list_add(&node->node_list, &hole_node->node_list);
226 241
227 BUG_ON(node->start + node->size > hole_end); 242 BUG_ON(node->start + node->size > adj_end);
228 BUG_ON(node->start + node->size > end); 243 BUG_ON(node->start + node->size > end);
229 244
245 node->hole_follows = 0;
230 if (node->start + node->size < hole_end) { 246 if (node->start + node->size < hole_end) {
231 list_add(&node->hole_stack, &mm->hole_stack); 247 list_add(&node->hole_stack, &mm->hole_stack);
232 node->hole_follows = 1; 248 node->hole_follows = 1;
233 } else {
234 node->hole_follows = 0;
235 } 249 }
236} 250}
237 251
238struct drm_mm_node *drm_mm_get_block_range_generic(struct drm_mm_node *hole_node, 252struct drm_mm_node *drm_mm_get_block_range_generic(struct drm_mm_node *hole_node,
239 unsigned long size, 253 unsigned long size,
240 unsigned alignment, 254 unsigned alignment,
255 unsigned long color,
241 unsigned long start, 256 unsigned long start,
242 unsigned long end, 257 unsigned long end,
243 int atomic) 258 int atomic)
@@ -248,7 +263,7 @@ struct drm_mm_node *drm_mm_get_block_range_generic(struct drm_mm_node *hole_node
248 if (unlikely(node == NULL)) 263 if (unlikely(node == NULL))
249 return NULL; 264 return NULL;
250 265
251 drm_mm_insert_helper_range(hole_node, node, size, alignment, 266 drm_mm_insert_helper_range(hole_node, node, size, alignment, color,
252 start, end); 267 start, end);
253 268
254 return node; 269 return node;
@@ -267,11 +282,11 @@ int drm_mm_insert_node_in_range(struct drm_mm *mm, struct drm_mm_node *node,
267 struct drm_mm_node *hole_node; 282 struct drm_mm_node *hole_node;
268 283
269 hole_node = drm_mm_search_free_in_range(mm, size, alignment, 284 hole_node = drm_mm_search_free_in_range(mm, size, alignment,
270 start, end, 0); 285 start, end, false);
271 if (!hole_node) 286 if (!hole_node)
272 return -ENOSPC; 287 return -ENOSPC;
273 288
274 drm_mm_insert_helper_range(hole_node, node, size, alignment, 289 drm_mm_insert_helper_range(hole_node, node, size, alignment, 0,
275 start, end); 290 start, end);
276 291
277 return 0; 292 return 0;
@@ -336,27 +351,23 @@ EXPORT_SYMBOL(drm_mm_put_block);
336static int check_free_hole(unsigned long start, unsigned long end, 351static int check_free_hole(unsigned long start, unsigned long end,
337 unsigned long size, unsigned alignment) 352 unsigned long size, unsigned alignment)
338{ 353{
339 unsigned wasted = 0;
340
341 if (end - start < size) 354 if (end - start < size)
342 return 0; 355 return 0;
343 356
344 if (alignment) { 357 if (alignment) {
345 unsigned tmp = start % alignment; 358 unsigned tmp = start % alignment;
346 if (tmp) 359 if (tmp)
347 wasted = alignment - tmp; 360 start += alignment - tmp;
348 }
349
350 if (end >= start + size + wasted) {
351 return 1;
352 } 361 }
353 362
354 return 0; 363 return end >= start + size;
355} 364}
356 365
357struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, 366struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm,
358 unsigned long size, 367 unsigned long size,
359 unsigned alignment, int best_match) 368 unsigned alignment,
369 unsigned long color,
370 bool best_match)
360{ 371{
361 struct drm_mm_node *entry; 372 struct drm_mm_node *entry;
362 struct drm_mm_node *best; 373 struct drm_mm_node *best;
@@ -368,10 +379,17 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm,
368 best_size = ~0UL; 379 best_size = ~0UL;
369 380
370 list_for_each_entry(entry, &mm->hole_stack, hole_stack) { 381 list_for_each_entry(entry, &mm->hole_stack, hole_stack) {
382 unsigned long adj_start = drm_mm_hole_node_start(entry);
383 unsigned long adj_end = drm_mm_hole_node_end(entry);
384
385 if (mm->color_adjust) {
386 mm->color_adjust(entry, color, &adj_start, &adj_end);
387 if (adj_end <= adj_start)
388 continue;
389 }
390
371 BUG_ON(!entry->hole_follows); 391 BUG_ON(!entry->hole_follows);
372 if (!check_free_hole(drm_mm_hole_node_start(entry), 392 if (!check_free_hole(adj_start, adj_end, size, alignment))
373 drm_mm_hole_node_end(entry),
374 size, alignment))
375 continue; 393 continue;
376 394
377 if (!best_match) 395 if (!best_match)
@@ -385,14 +403,15 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm,
385 403
386 return best; 404 return best;
387} 405}
388EXPORT_SYMBOL(drm_mm_search_free); 406EXPORT_SYMBOL(drm_mm_search_free_generic);
389 407
390struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, 408struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct drm_mm *mm,
391 unsigned long size, 409 unsigned long size,
392 unsigned alignment, 410 unsigned alignment,
393 unsigned long start, 411 unsigned long color,
394 unsigned long end, 412 unsigned long start,
395 int best_match) 413 unsigned long end,
414 bool best_match)
396{ 415{
397 struct drm_mm_node *entry; 416 struct drm_mm_node *entry;
398 struct drm_mm_node *best; 417 struct drm_mm_node *best;
@@ -410,6 +429,13 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm,
410 end : drm_mm_hole_node_end(entry); 429 end : drm_mm_hole_node_end(entry);
411 430
412 BUG_ON(!entry->hole_follows); 431 BUG_ON(!entry->hole_follows);
432
433 if (mm->color_adjust) {
434 mm->color_adjust(entry, color, &adj_start, &adj_end);
435 if (adj_end <= adj_start)
436 continue;
437 }
438
413 if (!check_free_hole(adj_start, adj_end, size, alignment)) 439 if (!check_free_hole(adj_start, adj_end, size, alignment))
414 continue; 440 continue;
415 441
@@ -424,7 +450,7 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm,
424 450
425 return best; 451 return best;
426} 452}
427EXPORT_SYMBOL(drm_mm_search_free_in_range); 453EXPORT_SYMBOL(drm_mm_search_free_in_range_generic);
428 454
429/** 455/**
430 * Moves an allocation. To be used with embedded struct drm_mm_node. 456 * Moves an allocation. To be used with embedded struct drm_mm_node.
@@ -437,6 +463,7 @@ void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new)
437 new->mm = old->mm; 463 new->mm = old->mm;
438 new->start = old->start; 464 new->start = old->start;
439 new->size = old->size; 465 new->size = old->size;
466 new->color = old->color;
440 467
441 old->allocated = 0; 468 old->allocated = 0;
442 new->allocated = 1; 469 new->allocated = 1;
@@ -452,9 +479,12 @@ EXPORT_SYMBOL(drm_mm_replace_node);
452 * Warning: As long as the scan list is non-empty, no other operations than 479 * Warning: As long as the scan list is non-empty, no other operations than
453 * adding/removing nodes to/from the scan list are allowed. 480 * adding/removing nodes to/from the scan list are allowed.
454 */ 481 */
455void drm_mm_init_scan(struct drm_mm *mm, unsigned long size, 482void drm_mm_init_scan(struct drm_mm *mm,
456 unsigned alignment) 483 unsigned long size,
484 unsigned alignment,
485 unsigned long color)
457{ 486{
487 mm->scan_color = color;
458 mm->scan_alignment = alignment; 488 mm->scan_alignment = alignment;
459 mm->scan_size = size; 489 mm->scan_size = size;
460 mm->scanned_blocks = 0; 490 mm->scanned_blocks = 0;
@@ -474,11 +504,14 @@ EXPORT_SYMBOL(drm_mm_init_scan);
474 * Warning: As long as the scan list is non-empty, no other operations than 504 * Warning: As long as the scan list is non-empty, no other operations than
475 * adding/removing nodes to/from the scan list are allowed. 505 * adding/removing nodes to/from the scan list are allowed.
476 */ 506 */
477void drm_mm_init_scan_with_range(struct drm_mm *mm, unsigned long size, 507void drm_mm_init_scan_with_range(struct drm_mm *mm,
508 unsigned long size,
478 unsigned alignment, 509 unsigned alignment,
510 unsigned long color,
479 unsigned long start, 511 unsigned long start,
480 unsigned long end) 512 unsigned long end)
481{ 513{
514 mm->scan_color = color;
482 mm->scan_alignment = alignment; 515 mm->scan_alignment = alignment;
483 mm->scan_size = size; 516 mm->scan_size = size;
484 mm->scanned_blocks = 0; 517 mm->scanned_blocks = 0;
@@ -522,17 +555,21 @@ int drm_mm_scan_add_block(struct drm_mm_node *node)
522 555
523 hole_start = drm_mm_hole_node_start(prev_node); 556 hole_start = drm_mm_hole_node_start(prev_node);
524 hole_end = drm_mm_hole_node_end(prev_node); 557 hole_end = drm_mm_hole_node_end(prev_node);
558
559 adj_start = hole_start;
560 adj_end = hole_end;
561
562 if (mm->color_adjust)
563 mm->color_adjust(prev_node, mm->scan_color, &adj_start, &adj_end);
564
525 if (mm->scan_check_range) { 565 if (mm->scan_check_range) {
526 adj_start = hole_start < mm->scan_start ? 566 if (adj_start < mm->scan_start)
527 mm->scan_start : hole_start; 567 adj_start = mm->scan_start;
528 adj_end = hole_end > mm->scan_end ? 568 if (adj_end > mm->scan_end)
529 mm->scan_end : hole_end; 569 adj_end = mm->scan_end;
530 } else {
531 adj_start = hole_start;
532 adj_end = hole_end;
533 } 570 }
534 571
535 if (check_free_hole(adj_start , adj_end, 572 if (check_free_hole(adj_start, adj_end,
536 mm->scan_size, mm->scan_alignment)) { 573 mm->scan_size, mm->scan_alignment)) {
537 mm->scan_hit_start = hole_start; 574 mm->scan_hit_start = hole_start;
538 mm->scan_hit_size = hole_end; 575 mm->scan_hit_size = hole_end;
@@ -616,6 +653,8 @@ int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size)
616 mm->head_node.size = start - mm->head_node.start; 653 mm->head_node.size = start - mm->head_node.start;
617 list_add_tail(&mm->head_node.hole_stack, &mm->hole_stack); 654 list_add_tail(&mm->head_node.hole_stack, &mm->hole_stack);
618 655
656 mm->color_adjust = NULL;
657
619 return 0; 658 return 0;
620} 659}
621EXPORT_SYMBOL(drm_mm_init); 660EXPORT_SYMBOL(drm_mm_init);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 2b54142a46ed..0fdb3d29cbbb 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2748,8 +2748,8 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj,
2748 if (map_and_fenceable) 2748 if (map_and_fenceable)
2749 free_space = 2749 free_space =
2750 drm_mm_search_free_in_range(&dev_priv->mm.gtt_space, 2750 drm_mm_search_free_in_range(&dev_priv->mm.gtt_space,
2751 size, alignment, 0, 2751 size, alignment,
2752 dev_priv->mm.gtt_mappable_end, 2752 0, dev_priv->mm.gtt_mappable_end,
2753 0); 2753 0);
2754 else 2754 else
2755 free_space = drm_mm_search_free(&dev_priv->mm.gtt_space, 2755 free_space = drm_mm_search_free(&dev_priv->mm.gtt_space,
@@ -2760,7 +2760,7 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj,
2760 obj->gtt_space = 2760 obj->gtt_space =
2761 drm_mm_get_block_range_generic(free_space, 2761 drm_mm_get_block_range_generic(free_space,
2762 size, alignment, 0, 2762 size, alignment, 0,
2763 dev_priv->mm.gtt_mappable_end, 2763 0, dev_priv->mm.gtt_mappable_end,
2764 0); 2764 0);
2765 else 2765 else
2766 obj->gtt_space = 2766 obj->gtt_space =
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
index ae7c24e12e52..eba0308f10e3 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -78,11 +78,12 @@ i915_gem_evict_something(struct drm_device *dev, int min_size,
78 78
79 INIT_LIST_HEAD(&unwind_list); 79 INIT_LIST_HEAD(&unwind_list);
80 if (mappable) 80 if (mappable)
81 drm_mm_init_scan_with_range(&dev_priv->mm.gtt_space, min_size, 81 drm_mm_init_scan_with_range(&dev_priv->mm.gtt_space,
82 alignment, 0, 82 min_size, alignment, 0,
83 dev_priv->mm.gtt_mappable_end); 83 0, dev_priv->mm.gtt_mappable_end);
84 else 84 else
85 drm_mm_init_scan(&dev_priv->mm.gtt_space, min_size, alignment); 85 drm_mm_init_scan(&dev_priv->mm.gtt_space,
86 min_size, alignment, 0);
86 87
87 /* First see if there is a large enough contiguous idle region... */ 88 /* First see if there is a large enough contiguous idle region... */
88 list_for_each_entry(obj, &dev_priv->mm.inactive_list, mm_list) { 89 list_for_each_entry(obj, &dev_priv->mm.inactive_list, mm_list) {
diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h
index 564b14aa7e16..06d7f798a08c 100644
--- a/include/drm/drm_mm.h
+++ b/include/drm/drm_mm.h
@@ -50,6 +50,7 @@ struct drm_mm_node {
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 start; 54 unsigned long start;
54 unsigned long size; 55 unsigned long size;
55 struct drm_mm *mm; 56 struct drm_mm *mm;
@@ -66,6 +67,7 @@ struct drm_mm {
66 spinlock_t unused_lock; 67 spinlock_t unused_lock;
67 unsigned int scan_check_range : 1; 68 unsigned int scan_check_range : 1;
68 unsigned scan_alignment; 69 unsigned scan_alignment;
70 unsigned long scan_color;
69 unsigned long scan_size; 71 unsigned long scan_size;
70 unsigned long scan_hit_start; 72 unsigned long scan_hit_start;
71 unsigned scan_hit_size; 73 unsigned scan_hit_size;
@@ -73,6 +75,9 @@ struct drm_mm {
73 unsigned long scan_start; 75 unsigned long scan_start;
74 unsigned long scan_end; 76 unsigned long scan_end;
75 struct drm_mm_node *prev_scanned_node; 77 struct drm_mm_node *prev_scanned_node;
78
79 void (*color_adjust)(struct drm_mm_node *node, unsigned long color,
80 unsigned long *start, unsigned long *end);
76}; 81};
77 82
78static inline bool drm_mm_node_allocated(struct drm_mm_node *node) 83static inline bool drm_mm_node_allocated(struct drm_mm_node *node)
@@ -100,11 +105,13 @@ static inline bool drm_mm_initialized(struct drm_mm *mm)
100extern struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node, 105extern struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node,
101 unsigned long size, 106 unsigned long size,
102 unsigned alignment, 107 unsigned alignment,
108 unsigned long color,
103 int atomic); 109 int atomic);
104extern struct drm_mm_node *drm_mm_get_block_range_generic( 110extern struct drm_mm_node *drm_mm_get_block_range_generic(
105 struct drm_mm_node *node, 111 struct drm_mm_node *node,
106 unsigned long size, 112 unsigned long size,
107 unsigned alignment, 113 unsigned alignment,
114 unsigned long color,
108 unsigned long start, 115 unsigned long start,
109 unsigned long end, 116 unsigned long end,
110 int atomic); 117 int atomic);
@@ -112,13 +119,13 @@ static inline struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *parent,
112 unsigned long size, 119 unsigned long size,
113 unsigned alignment) 120 unsigned alignment)
114{ 121{
115 return drm_mm_get_block_generic(parent, size, alignment, 0); 122 return drm_mm_get_block_generic(parent, size, alignment, 0, 0);
116} 123}
117static inline struct drm_mm_node *drm_mm_get_block_atomic(struct drm_mm_node *parent, 124static inline struct drm_mm_node *drm_mm_get_block_atomic(struct drm_mm_node *parent,
118 unsigned long size, 125 unsigned long size,
119 unsigned alignment) 126 unsigned alignment)
120{ 127{
121 return drm_mm_get_block_generic(parent, size, alignment, 1); 128 return drm_mm_get_block_generic(parent, size, alignment, 0, 1);
122} 129}
123static inline struct drm_mm_node *drm_mm_get_block_range( 130static inline struct drm_mm_node *drm_mm_get_block_range(
124 struct drm_mm_node *parent, 131 struct drm_mm_node *parent,
@@ -127,8 +134,19 @@ static inline struct drm_mm_node *drm_mm_get_block_range(
127 unsigned long start, 134 unsigned long start,
128 unsigned long end) 135 unsigned long end)
129{ 136{
130 return drm_mm_get_block_range_generic(parent, size, alignment, 137 return drm_mm_get_block_range_generic(parent, size, alignment, 0,
131 start, end, 0); 138 start, end, 0);
139}
140static 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);
132} 150}
133static inline struct drm_mm_node *drm_mm_get_block_atomic_range( 151static inline struct drm_mm_node *drm_mm_get_block_atomic_range(
134 struct drm_mm_node *parent, 152 struct drm_mm_node *parent,
@@ -137,7 +155,7 @@ static inline struct drm_mm_node *drm_mm_get_block_atomic_range(
137 unsigned long start, 155 unsigned long start,
138 unsigned long end) 156 unsigned long end)
139{ 157{
140 return drm_mm_get_block_range_generic(parent, size, alignment, 158 return drm_mm_get_block_range_generic(parent, size, alignment, 0,
141 start, end, 1); 159 start, end, 1);
142} 160}
143extern int drm_mm_insert_node(struct drm_mm *mm, struct drm_mm_node *node, 161extern int drm_mm_insert_node(struct drm_mm *mm, struct drm_mm_node *node,
@@ -149,18 +167,59 @@ extern int drm_mm_insert_node_in_range(struct drm_mm *mm,
149extern void drm_mm_put_block(struct drm_mm_node *cur); 167extern void drm_mm_put_block(struct drm_mm_node *cur);
150extern void drm_mm_remove_node(struct drm_mm_node *node); 168extern void drm_mm_remove_node(struct drm_mm_node *node);
151extern void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new); 169extern void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new);
152extern struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, 170extern struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm,
153 unsigned long size, 171 unsigned long size,
154 unsigned alignment, 172 unsigned alignment,
155 int best_match); 173 unsigned long color,
156extern struct drm_mm_node *drm_mm_search_free_in_range( 174 bool best_match);
175extern struct drm_mm_node *drm_mm_search_free_in_range_generic(
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);
183static 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}
190static inline struct drm_mm_node *drm_mm_search_free_in_range(
157 const struct drm_mm *mm, 191 const struct drm_mm *mm,
158 unsigned long size, 192 unsigned long size,
159 unsigned alignment, 193 unsigned alignment,
160 unsigned long start, 194 unsigned long start,
161 unsigned long end, 195 unsigned long end,
162 int best_match); 196 bool best_match)
163extern int drm_mm_init(struct drm_mm *mm, unsigned long start, 197{
198 return drm_mm_search_free_in_range_generic(mm, size, alignment, 0,
199 start, end, best_match);
200}
201static 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}
209static 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}
221extern int drm_mm_init(struct drm_mm *mm,
222 unsigned long start,
164 unsigned long size); 223 unsigned long size);
165extern void drm_mm_takedown(struct drm_mm *mm); 224extern void drm_mm_takedown(struct drm_mm *mm);
166extern int drm_mm_clean(struct drm_mm *mm); 225extern int drm_mm_clean(struct drm_mm *mm);
@@ -171,10 +230,14 @@ static inline struct drm_mm *drm_get_mm(struct drm_mm_node *block)
171 return block->mm; 230 return block->mm;
172} 231}
173 232
174void drm_mm_init_scan(struct drm_mm *mm, unsigned long size, 233void drm_mm_init_scan(struct drm_mm *mm,
175 unsigned alignment); 234 unsigned long size,
176void drm_mm_init_scan_with_range(struct drm_mm *mm, unsigned long size, 235 unsigned alignment,
236 unsigned long color);
237void drm_mm_init_scan_with_range(struct drm_mm *mm,
238 unsigned long size,
177 unsigned alignment, 239 unsigned alignment,
240 unsigned long color,
178 unsigned long start, 241 unsigned long start,
179 unsigned long end); 242 unsigned long end);
180int drm_mm_scan_add_block(struct drm_mm_node *node); 243int drm_mm_scan_add_block(struct drm_mm_node *node);