drm_mm.h revision 235783
1235783Skib/************************************************************************** 2235783Skib * 3235783Skib * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX. USA. 4235783Skib * All Rights Reserved. 5235783Skib * 6235783Skib * Permission is hereby granted, free of charge, to any person obtaining a 7235783Skib * copy of this software and associated documentation files (the 8235783Skib * "Software"), to deal in the Software without restriction, including 9235783Skib * without limitation the rights to use, copy, modify, merge, publish, 10235783Skib * distribute, sub license, and/or sell copies of the Software, and to 11235783Skib * permit persons to whom the Software is furnished to do so, subject to 12235783Skib * the following conditions: 13235783Skib * 14235783Skib * The above copyright notice and this permission notice (including the 15235783Skib * next paragraph) shall be included in all copies or substantial portions 16235783Skib * of the Software. 17235783Skib * 18235783Skib * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19235783Skib * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20235783Skib * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 21235783Skib * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 22235783Skib * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 23235783Skib * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 24235783Skib * USE OR OTHER DEALINGS IN THE SOFTWARE. 25235783Skib * 26235783Skib * 27235783Skib **************************************************************************/ 28235783Skib 29235783Skib#include <sys/cdefs.h> 30235783Skib__FBSDID("$FreeBSD: head/sys/dev/drm2/drm_mm.h 235783 2012-05-22 11:07:44Z kib $"); 31235783Skib 32235783Skib/* 33235783Skib * Authors: 34235783Skib * Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> 35235783Skib */ 36235783Skib 37235783Skib#ifndef _DRM_MM_H_ 38235783Skib#define _DRM_MM_H_ 39235783Skib 40235783Skib#include <dev/drm2/drm_linux_list.h> 41235783Skib 42235783Skibstruct drm_mm_node { 43235783Skib struct list_head node_list; 44235783Skib struct list_head hole_stack; 45235783Skib unsigned hole_follows : 1; 46235783Skib unsigned scanned_block : 1; 47235783Skib unsigned scanned_prev_free : 1; 48235783Skib unsigned scanned_next_free : 1; 49235783Skib unsigned scanned_preceeds_hole : 1; 50235783Skib unsigned allocated : 1; 51235783Skib unsigned long start; 52235783Skib unsigned long size; 53235783Skib struct drm_mm *mm; 54235783Skib void *private; 55235783Skib}; 56235783Skib 57235783Skibstruct drm_mm { 58235783Skib struct list_head hole_stack; 59235783Skib struct drm_mm_node head_node; 60235783Skib struct list_head unused_nodes; 61235783Skib int num_unused; 62235783Skib struct mtx unused_lock; 63235783Skib unsigned int scan_check_range : 1; 64235783Skib unsigned scan_alignment; 65235783Skib unsigned long scan_size; 66235783Skib unsigned long scan_hit_start; 67235783Skib unsigned scan_hit_size; 68235783Skib unsigned scanned_blocks; 69235783Skib unsigned long scan_start; 70235783Skib unsigned long scan_end; 71235783Skib struct drm_mm_node *prev_scanned_node; 72235783Skib}; 73235783Skib 74235783Skibstatic inline bool drm_mm_node_allocated(struct drm_mm_node *node) 75235783Skib{ 76235783Skib return node->allocated; 77235783Skib} 78235783Skib 79235783Skibstatic inline bool drm_mm_initialized(struct drm_mm *mm) 80235783Skib{ 81235783Skib return (mm->hole_stack.next != NULL); 82235783Skib} 83235783Skib#define drm_mm_for_each_node(entry, mm) list_for_each_entry(entry, \ 84235783Skib &(mm)->head_node.node_list, \ 85235783Skib node_list) 86235783Skib#define drm_mm_for_each_scanned_node_reverse(entry, n, mm) \ 87235783Skib for (entry = (mm)->prev_scanned_node, \ 88235783Skib next = entry ? list_entry(entry->node_list.next, \ 89235783Skib struct drm_mm_node, node_list) : NULL; \ 90235783Skib entry != NULL; entry = next, \ 91235783Skib next = entry ? list_entry(entry->node_list.next, \ 92235783Skib struct drm_mm_node, node_list) : NULL) 93235783Skib 94235783Skib/* 95235783Skib * Basic range manager support (drm_mm.c) 96235783Skib */ 97235783Skibextern struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node, 98235783Skib unsigned long size, 99235783Skib unsigned alignment, 100235783Skib int atomic); 101235783Skibextern struct drm_mm_node *drm_mm_get_block_range_generic( 102235783Skib struct drm_mm_node *node, 103235783Skib unsigned long size, 104235783Skib unsigned alignment, 105235783Skib unsigned long start, 106235783Skib unsigned long end, 107235783Skib int atomic); 108235783Skibstatic inline struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *parent, 109235783Skib unsigned long size, 110235783Skib unsigned alignment) 111235783Skib{ 112235783Skib return drm_mm_get_block_generic(parent, size, alignment, 0); 113235783Skib} 114235783Skibstatic inline struct drm_mm_node *drm_mm_get_block_atomic(struct drm_mm_node *parent, 115235783Skib unsigned long size, 116235783Skib unsigned alignment) 117235783Skib{ 118235783Skib return drm_mm_get_block_generic(parent, size, alignment, 1); 119235783Skib} 120235783Skibstatic inline struct drm_mm_node *drm_mm_get_block_range( 121235783Skib struct drm_mm_node *parent, 122235783Skib unsigned long size, 123235783Skib unsigned alignment, 124235783Skib unsigned long start, 125235783Skib unsigned long end) 126235783Skib{ 127235783Skib return drm_mm_get_block_range_generic(parent, size, alignment, 128235783Skib start, end, 0); 129235783Skib} 130235783Skibstatic inline struct drm_mm_node *drm_mm_get_block_atomic_range( 131235783Skib struct drm_mm_node *parent, 132235783Skib unsigned long size, 133235783Skib unsigned alignment, 134235783Skib unsigned long start, 135235783Skib unsigned long end) 136235783Skib{ 137235783Skib return drm_mm_get_block_range_generic(parent, size, alignment, 138235783Skib start, end, 1); 139235783Skib} 140235783Skibextern int drm_mm_insert_node(struct drm_mm *mm, struct drm_mm_node *node, 141235783Skib unsigned long size, unsigned alignment); 142235783Skibextern int drm_mm_insert_node_in_range(struct drm_mm *mm, 143235783Skib struct drm_mm_node *node, 144235783Skib unsigned long size, unsigned alignment, 145235783Skib unsigned long start, unsigned long end); 146235783Skibextern void drm_mm_put_block(struct drm_mm_node *cur); 147235783Skibextern void drm_mm_remove_node(struct drm_mm_node *node); 148235783Skibextern void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new); 149235783Skibextern struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, 150235783Skib unsigned long size, 151235783Skib unsigned alignment, 152235783Skib int best_match); 153235783Skibextern struct drm_mm_node *drm_mm_search_free_in_range( 154235783Skib const struct drm_mm *mm, 155235783Skib unsigned long size, 156235783Skib unsigned alignment, 157235783Skib unsigned long start, 158235783Skib unsigned long end, 159235783Skib int best_match); 160235783Skibextern int drm_mm_init(struct drm_mm *mm, unsigned long start, 161235783Skib unsigned long size); 162235783Skibextern void drm_mm_takedown(struct drm_mm *mm); 163235783Skibextern int drm_mm_clean(struct drm_mm *mm); 164235783Skibextern unsigned long drm_mm_tail_space(struct drm_mm *mm); 165235783Skibextern int drm_mm_remove_space_from_tail(struct drm_mm *mm, 166235783Skib unsigned long size); 167235783Skibextern int drm_mm_add_space_to_tail(struct drm_mm *mm, 168235783Skib unsigned long size, int atomic); 169235783Skibextern int drm_mm_pre_get(struct drm_mm *mm); 170235783Skib 171235783Skibstatic inline struct drm_mm *drm_get_mm(struct drm_mm_node *block) 172235783Skib{ 173235783Skib return block->mm; 174235783Skib} 175235783Skib 176235783Skibvoid drm_mm_init_scan(struct drm_mm *mm, unsigned long size, 177235783Skib unsigned alignment); 178235783Skibvoid drm_mm_init_scan_with_range(struct drm_mm *mm, unsigned long size, 179235783Skib unsigned alignment, 180235783Skib unsigned long start, 181235783Skib unsigned long end); 182235783Skibint drm_mm_scan_add_block(struct drm_mm_node *node); 183235783Skibint drm_mm_scan_remove_block(struct drm_mm_node *node); 184235783Skib 185235783Skib#endif 186