LCOV - code coverage report
Current view: top level - dev/pci/drm - drm_mm.h (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 17 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 8 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : #ifdef __linux__
      40             : #include <linux/bug.h>
      41             : #include <linux/kernel.h>
      42             : #include <linux/list.h>
      43             : #include <linux/spinlock.h>
      44             : #else
      45             : #include <dev/pci/drm/drm_linux_list.h>
      46             : #endif
      47             : #ifdef CONFIG_DEBUG_FS
      48             : #include <linux/seq_file.h>
      49             : #endif
      50             : 
      51             : enum drm_mm_search_flags {
      52             :         DRM_MM_SEARCH_DEFAULT =         0,
      53             :         DRM_MM_SEARCH_BEST =            1 << 0,
      54             :         DRM_MM_SEARCH_BELOW =           1 << 1,
      55             : };
      56             : 
      57             : enum drm_mm_allocator_flags {
      58             :         DRM_MM_CREATE_DEFAULT =         0,
      59             :         DRM_MM_CREATE_TOP =             1 << 0,
      60             : };
      61             : 
      62             : #define DRM_MM_BOTTOMUP DRM_MM_SEARCH_DEFAULT, DRM_MM_CREATE_DEFAULT
      63             : #define DRM_MM_TOPDOWN DRM_MM_SEARCH_BELOW, DRM_MM_CREATE_TOP
      64             : 
      65             : struct drm_mm_node {
      66             :         struct list_head node_list;
      67             :         struct list_head hole_stack;
      68             :         unsigned hole_follows : 1;
      69             :         unsigned scanned_block : 1;
      70             :         unsigned scanned_prev_free : 1;
      71             :         unsigned scanned_next_free : 1;
      72             :         unsigned scanned_preceeds_hole : 1;
      73             :         unsigned allocated : 1;
      74             :         unsigned long color;
      75             :         u64 start;
      76             :         u64 size;
      77             :         struct drm_mm *mm;
      78             : };
      79             : 
      80             : struct drm_mm {
      81             :         /* List of all memory nodes that immediately precede a free hole. */
      82             :         struct list_head hole_stack;
      83             :         /* head_node.node_list is the list of all memory nodes, ordered
      84             :          * according to the (increasing) start address of the memory node. */
      85             :         struct drm_mm_node head_node;
      86             :         unsigned int scan_check_range : 1;
      87             :         unsigned scan_alignment;
      88             :         unsigned long scan_color;
      89             :         u64 scan_size;
      90             :         u64 scan_hit_start;
      91             :         u64 scan_hit_end;
      92             :         unsigned scanned_blocks;
      93             :         u64 scan_start;
      94             :         u64 scan_end;
      95             :         struct drm_mm_node *prev_scanned_node;
      96             : 
      97             :         void (*color_adjust)(struct drm_mm_node *node, unsigned long color,
      98             :                              u64 *start, u64 *end);
      99             : };
     100             : 
     101             : /**
     102             :  * drm_mm_node_allocated - checks whether a node is allocated
     103             :  * @node: drm_mm_node to check
     104             :  *
     105             :  * Drivers should use this helpers for proper encapusulation of drm_mm
     106             :  * internals.
     107             :  *
     108             :  * Returns:
     109             :  * True if the @node is allocated.
     110             :  */
     111           0 : static inline bool drm_mm_node_allocated(struct drm_mm_node *node)
     112             : {
     113           0 :         return node->allocated;
     114             : }
     115             : 
     116             : /**
     117             :  * drm_mm_initialized - checks whether an allocator is initialized
     118             :  * @mm: drm_mm to check
     119             :  *
     120             :  * Drivers should use this helpers for proper encapusulation of drm_mm
     121             :  * internals.
     122             :  *
     123             :  * Returns:
     124             :  * True if the @mm is initialized.
     125             :  */
     126           0 : static inline bool drm_mm_initialized(struct drm_mm *mm)
     127             : {
     128           0 :         return mm->hole_stack.next;
     129             : }
     130             : 
     131           0 : static inline u64 __drm_mm_hole_node_start(struct drm_mm_node *hole_node)
     132             : {
     133           0 :         return hole_node->start + hole_node->size;
     134             : }
     135             : 
     136             : /**
     137             :  * drm_mm_hole_node_start - computes the start of the hole following @node
     138             :  * @hole_node: drm_mm_node which implicitly tracks the following hole
     139             :  *
     140             :  * This is useful for driver-sepific debug dumpers. Otherwise drivers should not
     141             :  * inspect holes themselves. Drivers must check first whether a hole indeed
     142             :  * follows by looking at node->hole_follows.
     143             :  *
     144             :  * Returns:
     145             :  * Start of the subsequent hole.
     146             :  */
     147           0 : static inline u64 drm_mm_hole_node_start(struct drm_mm_node *hole_node)
     148             : {
     149           0 :         BUG_ON(!hole_node->hole_follows);
     150           0 :         return __drm_mm_hole_node_start(hole_node);
     151             : }
     152             : 
     153           0 : static inline u64 __drm_mm_hole_node_end(struct drm_mm_node *hole_node)
     154             : {
     155           0 :         return list_next_entry(hole_node, node_list)->start;
     156             : }
     157             : 
     158             : /**
     159             :  * drm_mm_hole_node_end - computes the end of the hole following @node
     160             :  * @hole_node: drm_mm_node which implicitly tracks the following hole
     161             :  *
     162             :  * This is useful for driver-sepific debug dumpers. Otherwise drivers should not
     163             :  * inspect holes themselves. Drivers must check first whether a hole indeed
     164             :  * follows by looking at node->hole_follows.
     165             :  *
     166             :  * Returns:
     167             :  * End of the subsequent hole.
     168             :  */
     169           0 : static inline u64 drm_mm_hole_node_end(struct drm_mm_node *hole_node)
     170             : {
     171           0 :         return __drm_mm_hole_node_end(hole_node);
     172             : }
     173             : 
     174             : /**
     175             :  * drm_mm_for_each_node - iterator to walk over all allocated nodes
     176             :  * @entry: drm_mm_node structure to assign to in each iteration step
     177             :  * @mm: drm_mm allocator to walk
     178             :  *
     179             :  * This iterator walks over all nodes in the range allocator. It is implemented
     180             :  * with list_for_each, so not save against removal of elements.
     181             :  */
     182             : #define drm_mm_for_each_node(entry, mm) list_for_each_entry(entry, \
     183             :                                                 &(mm)->head_node.node_list, \
     184             :                                                 node_list)
     185             : 
     186             : #define __drm_mm_for_each_hole(entry, mm, hole_start, hole_end, backwards) \
     187             :         for (entry = list_entry((backwards) ? (mm)->hole_stack.prev : (mm)->hole_stack.next, struct drm_mm_node, hole_stack); \
     188             :              &entry->hole_stack != &(mm)->hole_stack ? \
     189             :              hole_start = drm_mm_hole_node_start(entry), \
     190             :              hole_end = drm_mm_hole_node_end(entry), \
     191             :              1 : 0; \
     192             :              entry = list_entry((backwards) ? entry->hole_stack.prev : entry->hole_stack.next, struct drm_mm_node, hole_stack))
     193             : 
     194             : /**
     195             :  * drm_mm_for_each_hole - iterator to walk over all holes
     196             :  * @entry: drm_mm_node used internally to track progress
     197             :  * @mm: drm_mm allocator to walk
     198             :  * @hole_start: ulong variable to assign the hole start to on each iteration
     199             :  * @hole_end: ulong variable to assign the hole end to on each iteration
     200             :  *
     201             :  * This iterator walks over all holes in the range allocator. It is implemented
     202             :  * with list_for_each, so not save against removal of elements. @entry is used
     203             :  * internally and will not reflect a real drm_mm_node for the very first hole.
     204             :  * Hence users of this iterator may not access it.
     205             :  *
     206             :  * Implementation Note:
     207             :  * We need to inline list_for_each_entry in order to be able to set hole_start
     208             :  * and hole_end on each iteration while keeping the macro sane.
     209             :  *
     210             :  * The __drm_mm_for_each_hole version is similar, but with added support for
     211             :  * going backwards.
     212             :  */
     213             : #define drm_mm_for_each_hole(entry, mm, hole_start, hole_end) \
     214             :         __drm_mm_for_each_hole(entry, mm, hole_start, hole_end, 0)
     215             : 
     216             : /*
     217             :  * Basic range manager support (drm_mm.c)
     218             :  */
     219             : int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node);
     220             : 
     221             : int drm_mm_insert_node_generic(struct drm_mm *mm,
     222             :                                struct drm_mm_node *node,
     223             :                                u64 size,
     224             :                                unsigned alignment,
     225             :                                unsigned long color,
     226             :                                enum drm_mm_search_flags sflags,
     227             :                                enum drm_mm_allocator_flags aflags);
     228             : /**
     229             :  * drm_mm_insert_node - search for space and insert @node
     230             :  * @mm: drm_mm to allocate from
     231             :  * @node: preallocate node to insert
     232             :  * @size: size of the allocation
     233             :  * @alignment: alignment of the allocation
     234             :  * @flags: flags to fine-tune the allocation
     235             :  *
     236             :  * This is a simplified version of drm_mm_insert_node_generic() with @color set
     237             :  * to 0.
     238             :  *
     239             :  * The preallocated node must be cleared to 0.
     240             :  *
     241             :  * Returns:
     242             :  * 0 on success, -ENOSPC if there's no suitable hole.
     243             :  */
     244           0 : static inline int drm_mm_insert_node(struct drm_mm *mm,
     245             :                                      struct drm_mm_node *node,
     246             :                                      u64 size,
     247             :                                      unsigned alignment,
     248             :                                      enum drm_mm_search_flags flags)
     249             : {
     250           0 :         return drm_mm_insert_node_generic(mm, node, size, alignment, 0, flags,
     251             :                                           DRM_MM_CREATE_DEFAULT);
     252             : }
     253             : 
     254             : int drm_mm_insert_node_in_range_generic(struct drm_mm *mm,
     255             :                                         struct drm_mm_node *node,
     256             :                                         u64 size,
     257             :                                         unsigned alignment,
     258             :                                         unsigned long color,
     259             :                                         u64 start,
     260             :                                         u64 end,
     261             :                                         enum drm_mm_search_flags sflags,
     262             :                                         enum drm_mm_allocator_flags aflags);
     263             : /**
     264             :  * drm_mm_insert_node_in_range - ranged search for space and insert @node
     265             :  * @mm: drm_mm to allocate from
     266             :  * @node: preallocate node to insert
     267             :  * @size: size of the allocation
     268             :  * @alignment: alignment of the allocation
     269             :  * @start: start of the allowed range for this node
     270             :  * @end: end of the allowed range for this node
     271             :  * @flags: flags to fine-tune the allocation
     272             :  *
     273             :  * This is a simplified version of drm_mm_insert_node_in_range_generic() with
     274             :  * @color set to 0.
     275             :  *
     276             :  * The preallocated node must be cleared to 0.
     277             :  *
     278             :  * Returns:
     279             :  * 0 on success, -ENOSPC if there's no suitable hole.
     280             :  */
     281           0 : static inline int drm_mm_insert_node_in_range(struct drm_mm *mm,
     282             :                                               struct drm_mm_node *node,
     283             :                                               u64 size,
     284             :                                               unsigned alignment,
     285             :                                               u64 start,
     286             :                                               u64 end,
     287             :                                               enum drm_mm_search_flags flags)
     288             : {
     289           0 :         return drm_mm_insert_node_in_range_generic(mm, node, size, alignment,
     290             :                                                    0, start, end, flags,
     291             :                                                    DRM_MM_CREATE_DEFAULT);
     292             : }
     293             : 
     294             : void drm_mm_remove_node(struct drm_mm_node *node);
     295             : void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new);
     296             : void drm_mm_init(struct drm_mm *mm,
     297             :                  u64 start,
     298             :                  u64 size);
     299             : void drm_mm_takedown(struct drm_mm *mm);
     300             : bool drm_mm_clean(struct drm_mm *mm);
     301             : 
     302             : void drm_mm_init_scan(struct drm_mm *mm,
     303             :                       u64 size,
     304             :                       unsigned alignment,
     305             :                       unsigned long color);
     306             : void drm_mm_init_scan_with_range(struct drm_mm *mm,
     307             :                                  u64 size,
     308             :                                  unsigned alignment,
     309             :                                  unsigned long color,
     310             :                                  u64 start,
     311             :                                  u64 end);
     312             : bool drm_mm_scan_add_block(struct drm_mm_node *node);
     313             : bool drm_mm_scan_remove_block(struct drm_mm_node *node);
     314             : 
     315             : void drm_mm_debug_table(struct drm_mm *mm, const char *prefix);
     316             : #ifdef CONFIG_DEBUG_FS
     317             : int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm);
     318             : #endif
     319             : 
     320             : #endif

Generated by: LCOV version 1.13