1235783Skib/************************************************************************** 2235783Skib * 3235783Skib * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., 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$"); 31235783Skib 32235783Skib/* 33235783Skib * Simple memory MANager interface that keeps track on allocate regions on a 34235783Skib * per "owner" basis. All regions associated with an "owner" can be released 35235783Skib * with a simple call. Typically if the "owner" exists. The owner is any 36235783Skib * "unsigned long" identifier. Can typically be a pointer to a file private 37235783Skib * struct or a context identifier. 38235783Skib * 39235783Skib * Authors: 40235783Skib * Thomas Hellstr��m <thomas-at-tungstengraphics-dot-com> 41235783Skib */ 42235783Skib 43235783Skib#ifndef DRM_SMAN_H 44235783Skib#define DRM_SMAN_H 45235783Skib 46235783Skib#include <dev/drm2/drm_hashtab.h> 47235783Skib#include <dev/drm2/drm_linux_list.h> 48235783Skib#include <dev/drm2/drm_mm.h> 49235783Skib 50235783Skib/* 51235783Skib * A class that is an abstration of a simple memory allocator. 52235783Skib * The sman implementation provides a default such allocator 53235783Skib * using the drm_mm.c implementation. But the user can replace it. 54235783Skib * See the SiS implementation, which may use the SiS FB kernel module 55235783Skib * for memory management. 56235783Skib */ 57235783Skib 58235783Skibstruct drm_sman_mm { 59235783Skib /* private info. If allocated, needs to be destroyed by the destroy 60235783Skib function */ 61235783Skib void *private; 62235783Skib 63235783Skib /* Allocate a memory block with given size and alignment. 64235783Skib Return an opaque reference to the memory block */ 65235783Skib 66235783Skib void *(*allocate) (void *private, unsigned long size, 67235783Skib unsigned alignment); 68235783Skib 69235783Skib /* Free a memory block. "ref" is the opaque reference that we got from 70235783Skib the "alloc" function */ 71235783Skib 72235783Skib void (*free) (void *private, void *ref); 73235783Skib 74235783Skib /* Free all resources associated with this allocator */ 75235783Skib 76235783Skib void (*destroy) (void *private); 77235783Skib 78235783Skib /* Return a memory offset from the opaque reference returned from the 79235783Skib "alloc" function */ 80235783Skib 81235783Skib unsigned long (*offset) (void *private, void *ref); 82235783Skib}; 83235783Skib 84235783Skibstruct drm_memblock_item { 85235783Skib struct list_head owner_list; 86235783Skib struct drm_hash_item user_hash; 87235783Skib void *mm_info; 88235783Skib struct drm_sman_mm *mm; 89235783Skib struct drm_sman *sman; 90235783Skib}; 91235783Skib 92235783Skibstruct drm_sman { 93235783Skib struct drm_sman_mm *mm; 94235783Skib int num_managers; 95235783Skib struct drm_open_hash owner_hash_tab; 96235783Skib struct drm_open_hash user_hash_tab; 97235783Skib struct list_head owner_items; 98235783Skib}; 99235783Skib 100235783Skib/* 101235783Skib * Take down a memory manager. This function should only be called after a 102235783Skib * successful init and after a call to drm_sman_cleanup. 103235783Skib */ 104235783Skib 105235783Skibextern void drm_sman_takedown(struct drm_sman * sman); 106235783Skib 107235783Skib/* 108235783Skib * Allocate structures for a manager. 109235783Skib * num_managers are the number of memory pools to manage. (VRAM, AGP, ....) 110235783Skib * user_order is the log2 of the number of buckets in the user hash table. 111235783Skib * set this to approximately log2 of the max number of memory regions 112235783Skib * that will be allocated for _all_ pools together. 113235783Skib * owner_order is the log2 of the number of buckets in the owner hash table. 114235783Skib * set this to approximately log2 of 115235783Skib * the number of client file connections that will 116235783Skib * be using the manager. 117235783Skib * 118235783Skib */ 119235783Skib 120235783Skibextern int drm_sman_init(struct drm_sman * sman, unsigned int num_managers, 121235783Skib unsigned int user_order, unsigned int owner_order); 122235783Skib 123235783Skib/* 124235783Skib * Initialize a drm_mm.c allocator. Should be called only once for each 125235783Skib * manager unless a customized allogator is used. 126235783Skib */ 127235783Skib 128235783Skibextern int drm_sman_set_range(struct drm_sman * sman, unsigned int manager, 129235783Skib unsigned long start, unsigned long size); 130235783Skib 131235783Skib/* 132235783Skib * Initialize a customized allocator for one of the managers. 133235783Skib * (See the SiS module). The object pointed to by "allocator" is copied, 134235783Skib * so it can be destroyed after this call. 135235783Skib */ 136235783Skib 137235783Skibextern int drm_sman_set_manager(struct drm_sman * sman, unsigned int mananger, 138235783Skib struct drm_sman_mm * allocator); 139235783Skib 140235783Skib/* 141235783Skib * Allocate a memory block. Aligment is not implemented yet. 142235783Skib */ 143235783Skib 144235783Skibextern struct drm_memblock_item *drm_sman_alloc(struct drm_sman * sman, 145235783Skib unsigned int manager, 146235783Skib unsigned long size, 147235783Skib unsigned alignment, 148235783Skib unsigned long owner); 149235783Skib/* 150235783Skib * Free a memory block identified by its user hash key. 151235783Skib */ 152235783Skib 153235783Skibextern int drm_sman_free_key(struct drm_sman * sman, unsigned int key); 154235783Skib 155235783Skib/* 156235783Skib * returns 1 iff there are no stale memory blocks associated with this owner. 157235783Skib * Typically called to determine if we need to idle the hardware and call 158235783Skib * drm_sman_owner_cleanup. If there are no stale memory blocks, it removes all 159235783Skib * resources associated with owner. 160235783Skib */ 161235783Skib 162235783Skibextern int drm_sman_owner_clean(struct drm_sman * sman, unsigned long owner); 163235783Skib 164235783Skib/* 165235783Skib * Frees all stale memory blocks associated with this owner. Note that this 166235783Skib * requires that the hardware is finished with all blocks, so the graphics engine 167235783Skib * should be idled before this call is made. This function also frees 168235783Skib * any resources associated with "owner" and should be called when owner 169235783Skib * is not going to be referenced anymore. 170235783Skib */ 171235783Skib 172235783Skibextern void drm_sman_owner_cleanup(struct drm_sman * sman, unsigned long owner); 173235783Skib 174235783Skib/* 175235783Skib * Frees all stale memory blocks associated with the memory manager. 176235783Skib * See idling above. 177235783Skib */ 178235783Skib 179235783Skibextern void drm_sman_cleanup(struct drm_sman * sman); 180235783Skib 181235783Skib#endif 182