/************************************************************************** * * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., 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 */ /* Notes: * * We store bo pointer in drm_mm_node struct so we know which bo own a * specific node. There is no protection on the pointer, thus to make * sure things don't go berserk you have to access this pointer while * holding the global lru lock and make sure anytime you free a node you * reset the pointer to NULL. */ #include "ttm/ttm_module.h" #include "ttm/ttm_bo_driver.h" #include "ttm/ttm_placement.h" #include int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type, unsigned long p_size) { int ret = -EINVAL; struct ttm_mem_type_manager *man; if (type >= TTM_NUM_MEM_TYPES) { printk(KERN_ERR TTM_PFX "Illegal memory type %d\n", type); return ret; } man = &bdev->man[type]; if (man->has_type) { printk(KERN_ERR TTM_PFX "Memory manager already initialized for type %d\n", type); return ret; } ret = bdev->driver->init_mem_type(bdev, type, man); if (ret) return ret; ret = 0; if (type != TTM_PL_SYSTEM) { if (!p_size) { printk(KERN_ERR TTM_PFX "Zero size memory manager type %d\n", type); return ret; } ret = drm_mm_init(&man->manager, 0, p_size); if (ret) return ret; } man->has_type = true; man->use_type = true; man->size = p_size; INIT_LIST_HEAD(&man->lru); return 0; } EXPORT_SYMBOL(ttm_bo_init_mm); int ttm_bo_global_init(struct ttm_global_reference *ref) { struct ttm_bo_global_ref *bo_ref = container_of(ref, struct ttm_bo_global_ref, ref); struct ttm_bo_global *glob = ref->object; int ret; // mutex_init(&glob->device_list_mutex); // spin_lock_init(&glob->lru_lock); glob->mem_glob = bo_ref->mem_glob; // glob->dummy_read_page = alloc_page(__GFP_ZERO | GFP_DMA32); if (unlikely(glob->dummy_read_page == NULL)) { ret = -ENOMEM; goto out_no_drp; } INIT_LIST_HEAD(&glob->swap_lru); INIT_LIST_HEAD(&glob->device_list); // ttm_mem_init_shrink(&glob->shrink, ttm_bo_swapout); ret = ttm_mem_register_shrink(glob->mem_glob, &glob->shrink); if (unlikely(ret != 0)) { printk(KERN_ERR TTM_PFX "Could not register buffer object swapout.\n"); goto out_no_shrink; } glob->ttm_bo_extra_size = ttm_round_pot(sizeof(struct ttm_tt)) + ttm_round_pot(sizeof(struct ttm_backend)); glob->ttm_bo_size = glob->ttm_bo_extra_size + ttm_round_pot(sizeof(struct ttm_buffer_object)); atomic_set(&glob->bo_count, 0); // kobject_init(&glob->kobj, &ttm_bo_glob_kobj_type); // ret = kobject_add(&glob->kobj, ttm_get_kobj(), "buffer_objects"); // if (unlikely(ret != 0)) // kobject_put(&glob->kobj); return ret; out_no_shrink: __free_page(glob->dummy_read_page); out_no_drp: kfree(glob); return ret; } EXPORT_SYMBOL(ttm_bo_global_init);