2009-04-08 17:11:16 +02:00
/**************************************************************************
*
* Copyright 2006 - 2008 Tungsten Graphics , Inc . , Cedar Park , TX . USA .
* All Rights Reserved .
*
* Permission is hereby granted , free of charge , to any person obtaining a
* copy of this software and associated documentation files ( the
* " Software " ) , to deal in the Software without restriction , including
* without limitation the rights to use , copy , modify , merge , publish ,
* distribute , sub license , and / or sell copies of the Software , and to
* permit persons to whom the Software is furnished to do so , subject to
* the following conditions :
*
* The above copyright notice and this permission notice ( including the
* next paragraph ) shall be included in all copies or substantial portions
* of the Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NON - INFRINGEMENT . IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS , AUTHORS AND / OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM ,
* DAMAGES OR OTHER LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR
* OTHERWISE , ARISING FROM , OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE .
*
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Authors :
* Thomas Hellstrom < thomas - at - tungstengraphics - dot - com >
*/
# ifndef _DRM_MM_H_
# define _DRM_MM_H_
/*
* Generic range manager structs
*/
# include <linux/list.h>
2009-09-08 11:32:08 +10:00
# ifdef CONFIG_DEBUG_FS
# include <linux/seq_file.h>
# endif
2009-04-08 17:11:16 +02:00
struct drm_mm_node {
2010-07-02 15:02:14 +01:00
struct list_head node_list ;
2011-02-18 17:59:12 +01:00
struct list_head hole_stack ;
unsigned hole_follows : 1 ;
2010-07-02 15:02:16 +01:00
unsigned scanned_block : 1 ;
unsigned scanned_prev_free : 1 ;
unsigned scanned_next_free : 1 ;
2011-02-18 17:59:12 +01:00
unsigned scanned_preceeds_hole : 1 ;
2011-02-18 17:59:14 +01:00
unsigned allocated : 1 ;
2012-07-10 11:15:23 +01:00
unsigned long color ;
2009-04-08 17:11:16 +02:00
unsigned long start ;
unsigned long size ;
struct drm_mm * mm ;
} ;
struct drm_mm {
2011-03-30 22:57:33 -03:00
/* List of all memory nodes that immediately precede a free hole. */
2011-02-18 17:59:12 +01:00
struct list_head hole_stack ;
/* head_node.node_list is the list of all memory nodes, ordered
* according to the ( increasing ) start address of the memory node . */
struct drm_mm_node head_node ;
2009-04-08 17:11:16 +02:00
struct list_head unused_nodes ;
int num_unused ;
spinlock_t unused_lock ;
2010-09-16 15:13:11 +02:00
unsigned int scan_check_range : 1 ;
2010-07-02 15:02:16 +01:00
unsigned scan_alignment ;
2012-07-10 11:15:23 +01:00
unsigned long scan_color ;
2010-07-02 15:02:16 +01:00
unsigned long scan_size ;
unsigned long scan_hit_start ;
2012-12-19 16:51:06 +00:00
unsigned long scan_hit_end ;
2010-07-02 15:02:16 +01:00
unsigned scanned_blocks ;
2010-09-16 15:13:11 +02:00
unsigned long scan_start ;
unsigned long scan_end ;
2011-02-18 17:59:15 +01:00
struct drm_mm_node * prev_scanned_node ;
2012-07-10 11:15:23 +01:00
void ( * color_adjust ) ( struct drm_mm_node * node , unsigned long color ,
unsigned long * start , unsigned long * end ) ;
2009-04-08 17:11:16 +02:00
} ;
2011-02-18 17:59:14 +01:00
static inline bool drm_mm_node_allocated ( struct drm_mm_node * node )
{
return node - > allocated ;
}
2011-02-18 17:59:11 +01:00
static inline bool drm_mm_initialized ( struct drm_mm * mm )
{
2011-02-18 17:59:12 +01:00
return mm - > hole_stack . next ;
2011-02-18 17:59:11 +01:00
}
2011-02-18 17:59:12 +01:00
# define drm_mm_for_each_node(entry, mm) list_for_each_entry(entry, \
& ( mm ) - > head_node . node_list , \
2011-05-06 23:47:53 +02:00
node_list )
2011-02-18 17:59:15 +01:00
# define drm_mm_for_each_scanned_node_reverse(entry, n, mm) \
for ( entry = ( mm ) - > prev_scanned_node , \
next = entry ? list_entry ( entry - > node_list . next , \
struct drm_mm_node , node_list ) : NULL ; \
entry ! = NULL ; entry = next , \
next = entry ? list_entry ( entry - > node_list . next , \
struct drm_mm_node , node_list ) : NULL ) \
2009-04-08 17:11:16 +02:00
/*
* Basic range manager support ( drm_mm . c )
*/
2009-06-17 12:29:56 +02:00
extern struct drm_mm_node * drm_mm_get_block_generic ( struct drm_mm_node * node ,
unsigned long size ,
unsigned alignment ,
2012-07-10 11:15:23 +01:00
unsigned long color ,
2009-06-17 12:29:56 +02:00
int atomic ) ;
2009-12-07 15:52:56 +01:00
extern struct drm_mm_node * drm_mm_get_block_range_generic (
struct drm_mm_node * node ,
unsigned long size ,
unsigned alignment ,
2012-07-10 11:15:23 +01:00
unsigned long color ,
2009-12-07 15:52:56 +01:00
unsigned long start ,
unsigned long end ,
int atomic ) ;
2009-06-17 12:29:56 +02:00
static inline struct drm_mm_node * drm_mm_get_block ( struct drm_mm_node * parent ,
2009-04-08 17:11:16 +02:00
unsigned long size ,
2009-06-17 12:29:56 +02:00
unsigned alignment )
{
2012-07-10 11:15:23 +01:00
return drm_mm_get_block_generic ( parent , size , alignment , 0 , 0 ) ;
2009-06-17 12:29:56 +02:00
}
static inline struct drm_mm_node * drm_mm_get_block_atomic ( struct drm_mm_node * parent ,
unsigned long size ,
unsigned alignment )
{
2012-07-10 11:15:23 +01:00
return drm_mm_get_block_generic ( parent , size , alignment , 0 , 1 ) ;
2009-06-17 12:29:56 +02:00
}
2009-12-07 15:52:56 +01:00
static inline struct drm_mm_node * drm_mm_get_block_range (
struct drm_mm_node * parent ,
unsigned long size ,
unsigned alignment ,
unsigned long start ,
unsigned long end )
{
2012-07-10 11:15:23 +01:00
return drm_mm_get_block_range_generic ( parent , size , alignment , 0 ,
start , end , 0 ) ;
}
static inline struct drm_mm_node * drm_mm_get_color_block_range (
struct drm_mm_node * parent ,
unsigned long size ,
unsigned alignment ,
unsigned long color ,
unsigned long start ,
unsigned long end )
{
return drm_mm_get_block_range_generic ( parent , size , alignment , color ,
start , end , 0 ) ;
2009-12-07 15:52:56 +01:00
}
static inline struct drm_mm_node * drm_mm_get_block_atomic_range (
struct drm_mm_node * parent ,
unsigned long size ,
unsigned alignment ,
unsigned long start ,
unsigned long end )
{
2012-07-10 11:15:23 +01:00
return drm_mm_get_block_range_generic ( parent , size , alignment , 0 ,
2009-12-07 15:52:56 +01:00
start , end , 1 ) ;
}
2012-12-07 20:37:06 +00:00
extern int drm_mm_insert_node ( struct drm_mm * mm ,
struct drm_mm_node * node ,
unsigned long size ,
unsigned alignment ) ;
2011-02-18 17:59:14 +01:00
extern int drm_mm_insert_node_in_range ( struct drm_mm * mm ,
struct drm_mm_node * node ,
2012-12-07 20:37:06 +00:00
unsigned long size ,
unsigned alignment ,
unsigned long start ,
unsigned long end ) ;
extern int drm_mm_insert_node_generic ( struct drm_mm * mm ,
struct drm_mm_node * node ,
unsigned long size ,
unsigned alignment ,
unsigned long color ) ;
extern int drm_mm_insert_node_in_range_generic ( struct drm_mm * mm ,
struct drm_mm_node * node ,
unsigned long size ,
unsigned alignment ,
unsigned long color ,
unsigned long start ,
unsigned long end ) ;
2009-04-08 17:11:16 +02:00
extern void drm_mm_put_block ( struct drm_mm_node * cur ) ;
2011-02-18 17:59:14 +01:00
extern void drm_mm_remove_node ( struct drm_mm_node * node ) ;
extern void drm_mm_replace_node ( struct drm_mm_node * old , struct drm_mm_node * new ) ;
2012-07-10 11:15:23 +01:00
extern struct drm_mm_node * drm_mm_search_free_generic ( const struct drm_mm * mm ,
unsigned long size ,
unsigned alignment ,
unsigned long color ,
bool best_match ) ;
extern struct drm_mm_node * drm_mm_search_free_in_range_generic (
const struct drm_mm * mm ,
unsigned long size ,
unsigned alignment ,
unsigned long color ,
unsigned long start ,
unsigned long end ,
bool best_match ) ;
static inline struct drm_mm_node * drm_mm_search_free ( const struct drm_mm * mm ,
unsigned long size ,
unsigned alignment ,
bool best_match )
{
return drm_mm_search_free_generic ( mm , size , alignment , 0 , best_match ) ;
}
static inline struct drm_mm_node * drm_mm_search_free_in_range (
2009-12-07 15:52:56 +01:00
const struct drm_mm * mm ,
unsigned long size ,
unsigned alignment ,
unsigned long start ,
unsigned long end ,
2012-07-10 11:15:23 +01:00
bool best_match )
{
return drm_mm_search_free_in_range_generic ( mm , size , alignment , 0 ,
start , end , best_match ) ;
}
static inline struct drm_mm_node * drm_mm_search_free_color ( const struct drm_mm * mm ,
unsigned long size ,
unsigned alignment ,
unsigned long color ,
bool best_match )
{
return drm_mm_search_free_generic ( mm , size , alignment , color , best_match ) ;
}
static inline struct drm_mm_node * drm_mm_search_free_in_range_color (
const struct drm_mm * mm ,
unsigned long size ,
unsigned alignment ,
unsigned long color ,
unsigned long start ,
unsigned long end ,
bool best_match )
{
return drm_mm_search_free_in_range_generic ( mm , size , alignment , color ,
start , end , best_match ) ;
}
extern int drm_mm_init ( struct drm_mm * mm ,
unsigned long start ,
2009-04-08 17:11:16 +02:00
unsigned long size ) ;
extern void drm_mm_takedown ( struct drm_mm * mm ) ;
extern int drm_mm_clean ( struct drm_mm * mm ) ;
extern int drm_mm_pre_get ( struct drm_mm * mm ) ;
static inline struct drm_mm * drm_get_mm ( struct drm_mm_node * block )
{
return block - > mm ;
}
2012-07-10 11:15:23 +01:00
void drm_mm_init_scan ( struct drm_mm * mm ,
unsigned long size ,
unsigned alignment ,
unsigned long color ) ;
void drm_mm_init_scan_with_range ( struct drm_mm * mm ,
unsigned long size ,
2010-09-16 15:13:11 +02:00
unsigned alignment ,
2012-07-10 11:15:23 +01:00
unsigned long color ,
2010-09-16 15:13:11 +02:00
unsigned long start ,
unsigned long end ) ;
2010-07-02 15:02:16 +01:00
int drm_mm_scan_add_block ( struct drm_mm_node * node ) ;
int drm_mm_scan_remove_block ( struct drm_mm_node * node ) ;
2009-12-09 21:55:09 +01:00
extern void drm_mm_debug_table ( struct drm_mm * mm , const char * prefix ) ;
2009-08-26 13:13:37 +10:00
# ifdef CONFIG_DEBUG_FS
int drm_mm_dump_table ( struct seq_file * m , struct drm_mm * mm ) ;
# endif
2009-04-08 17:11:16 +02:00
# endif