1203287Srnoland/************************************************************************** 2203287Srnoland * 3203287Srnoland * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA. 4203287Srnoland * All Rights Reserved. 5203287Srnoland * 6203287Srnoland * Permission is hereby granted, free of charge, to any person obtaining a 7203287Srnoland * copy of this software and associated documentation files (the 8203287Srnoland * "Software"), to deal in the Software without restriction, including 9203287Srnoland * without limitation the rights to use, copy, modify, merge, publish, 10203287Srnoland * distribute, sub license, and/or sell copies of the Software, and to 11203287Srnoland * permit persons to whom the Software is furnished to do so, subject to 12203287Srnoland * the following conditions: 13203287Srnoland * 14203287Srnoland * The above copyright notice and this permission notice (including the 15203287Srnoland * next paragraph) shall be included in all copies or substantial portions 16203287Srnoland * of the Software. 17203287Srnoland * 18203287Srnoland * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19203287Srnoland * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20203287Srnoland * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 21203287Srnoland * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 22203287Srnoland * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 23203287Srnoland * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 24203287Srnoland * USE OR OTHER DEALINGS IN THE SOFTWARE. 25203287Srnoland * 26203287Srnoland * 27203287Srnoland **************************************************************************/ 28203287Srnoland 29203287Srnoland#include <sys/cdefs.h> 30203287Srnoland__FBSDID("$FreeBSD$"); 31203287Srnoland 32203287Srnoland/* 33203287Srnoland * Simple memory MANager interface that keeps track on allocate regions on a 34203287Srnoland * per "owner" basis. All regions associated with an "owner" can be released 35203287Srnoland * with a simple call. Typically if the "owner" exists. The owner is any 36203287Srnoland * "unsigned long" identifier. Can typically be a pointer to a file private 37203287Srnoland * struct or a context identifier. 38203287Srnoland * 39203287Srnoland * Authors: 40203287Srnoland * Thomas Hellstr��m <thomas-at-tungstengraphics-dot-com> 41203287Srnoland */ 42203287Srnoland 43203287Srnoland#ifndef DRM_SMAN_H 44203287Srnoland#define DRM_SMAN_H 45203287Srnoland 46203287Srnoland#include "dev/drm/drm_hashtab.h" 47203287Srnoland#include "dev/drm/drm_linux_list.h" 48203287Srnoland#include "dev/drm/drm_mm.h" 49203287Srnoland 50203287Srnoland/* 51203287Srnoland * A class that is an abstration of a simple memory allocator. 52203287Srnoland * The sman implementation provides a default such allocator 53203287Srnoland * using the drm_mm.c implementation. But the user can replace it. 54203287Srnoland * See the SiS implementation, which may use the SiS FB kernel module 55203287Srnoland * for memory management. 56203287Srnoland */ 57203287Srnoland 58203287Srnolandstruct drm_sman_mm { 59203287Srnoland /* private info. If allocated, needs to be destroyed by the destroy 60203287Srnoland function */ 61203287Srnoland void *private; 62203287Srnoland 63203287Srnoland /* Allocate a memory block with given size and alignment. 64203287Srnoland Return an opaque reference to the memory block */ 65203287Srnoland 66203287Srnoland void *(*allocate) (void *private, unsigned long size, 67203287Srnoland unsigned alignment); 68203287Srnoland 69203287Srnoland /* Free a memory block. "ref" is the opaque reference that we got from 70203287Srnoland the "alloc" function */ 71203287Srnoland 72203287Srnoland void (*free) (void *private, void *ref); 73203287Srnoland 74203287Srnoland /* Free all resources associated with this allocator */ 75203287Srnoland 76203287Srnoland void (*destroy) (void *private); 77203287Srnoland 78203287Srnoland /* Return a memory offset from the opaque reference returned from the 79203287Srnoland "alloc" function */ 80203287Srnoland 81203287Srnoland unsigned long (*offset) (void *private, void *ref); 82203287Srnoland}; 83203287Srnoland 84203287Srnolandstruct drm_memblock_item { 85203287Srnoland struct list_head owner_list; 86203287Srnoland struct drm_hash_item user_hash; 87203287Srnoland void *mm_info; 88203287Srnoland struct drm_sman_mm *mm; 89203287Srnoland struct drm_sman *sman; 90203287Srnoland}; 91203287Srnoland 92203287Srnolandstruct drm_sman { 93203287Srnoland struct drm_sman_mm *mm; 94203287Srnoland int num_managers; 95203287Srnoland struct drm_open_hash owner_hash_tab; 96203287Srnoland struct drm_open_hash user_hash_tab; 97203287Srnoland struct list_head owner_items; 98203287Srnoland}; 99203287Srnoland 100203287Srnoland/* 101203287Srnoland * Take down a memory manager. This function should only be called after a 102203287Srnoland * successful init and after a call to drm_sman_cleanup. 103203287Srnoland */ 104203287Srnoland 105203287Srnolandextern void drm_sman_takedown(struct drm_sman * sman); 106203287Srnoland 107203287Srnoland/* 108203287Srnoland * Allocate structures for a manager. 109203287Srnoland * num_managers are the number of memory pools to manage. (VRAM, AGP, ....) 110203287Srnoland * user_order is the log2 of the number of buckets in the user hash table. 111203287Srnoland * set this to approximately log2 of the max number of memory regions 112203287Srnoland * that will be allocated for _all_ pools together. 113203287Srnoland * owner_order is the log2 of the number of buckets in the owner hash table. 114203287Srnoland * set this to approximately log2 of 115203287Srnoland * the number of client file connections that will 116203287Srnoland * be using the manager. 117203287Srnoland * 118203287Srnoland */ 119203287Srnoland 120203287Srnolandextern int drm_sman_init(struct drm_sman * sman, unsigned int num_managers, 121203287Srnoland unsigned int user_order, unsigned int owner_order); 122203287Srnoland 123203287Srnoland/* 124203287Srnoland * Initialize a drm_mm.c allocator. Should be called only once for each 125203287Srnoland * manager unless a customized allogator is used. 126203287Srnoland */ 127203287Srnoland 128203287Srnolandextern int drm_sman_set_range(struct drm_sman * sman, unsigned int manager, 129203287Srnoland unsigned long start, unsigned long size); 130203287Srnoland 131203287Srnoland/* 132203287Srnoland * Initialize a customized allocator for one of the managers. 133203287Srnoland * (See the SiS module). The object pointed to by "allocator" is copied, 134203287Srnoland * so it can be destroyed after this call. 135203287Srnoland */ 136203287Srnoland 137203287Srnolandextern int drm_sman_set_manager(struct drm_sman * sman, unsigned int mananger, 138203287Srnoland struct drm_sman_mm * allocator); 139203287Srnoland 140203287Srnoland/* 141203287Srnoland * Allocate a memory block. Aligment is not implemented yet. 142203287Srnoland */ 143203287Srnoland 144203287Srnolandextern struct drm_memblock_item *drm_sman_alloc(struct drm_sman * sman, 145203287Srnoland unsigned int manager, 146203287Srnoland unsigned long size, 147203287Srnoland unsigned alignment, 148203287Srnoland unsigned long owner); 149203287Srnoland/* 150203287Srnoland * Free a memory block identified by its user hash key. 151203287Srnoland */ 152203287Srnoland 153203287Srnolandextern int drm_sman_free_key(struct drm_sman * sman, unsigned int key); 154203287Srnoland 155203287Srnoland/* 156203287Srnoland * returns 1 iff there are no stale memory blocks associated with this owner. 157203287Srnoland * Typically called to determine if we need to idle the hardware and call 158203287Srnoland * drm_sman_owner_cleanup. If there are no stale memory blocks, it removes all 159203287Srnoland * resources associated with owner. 160203287Srnoland */ 161203287Srnoland 162203287Srnolandextern int drm_sman_owner_clean(struct drm_sman * sman, unsigned long owner); 163203287Srnoland 164203287Srnoland/* 165203287Srnoland * Frees all stale memory blocks associated with this owner. Note that this 166203287Srnoland * requires that the hardware is finished with all blocks, so the graphics engine 167203287Srnoland * should be idled before this call is made. This function also frees 168203287Srnoland * any resources associated with "owner" and should be called when owner 169203287Srnoland * is not going to be referenced anymore. 170203287Srnoland */ 171203287Srnoland 172203287Srnolandextern void drm_sman_owner_cleanup(struct drm_sman * sman, unsigned long owner); 173203287Srnoland 174203287Srnoland/* 175203287Srnoland * Frees all stale memory blocks associated with the memory manager. 176203287Srnoland * See idling above. 177203287Srnoland */ 178203287Srnoland 179203287Srnolandextern void drm_sman_cleanup(struct drm_sman * sman); 180203287Srnoland 181203287Srnoland#endif 182