aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/samsung/mali/common/mali_block_allocator.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/samsung/mali/common/mali_block_allocator.c')
-rw-r--r--drivers/media/video/samsung/mali/common/mali_block_allocator.c391
1 files changed, 0 insertions, 391 deletions
diff --git a/drivers/media/video/samsung/mali/common/mali_block_allocator.c b/drivers/media/video/samsung/mali/common/mali_block_allocator.c
deleted file mode 100644
index 269e662..0000000
--- a/drivers/media/video/samsung/mali/common/mali_block_allocator.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
- *
- * This program is free software and is provided to you under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
- *
- * A copy of the licence is included with the program, and can also be obtained from Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-#include "mali_kernel_common.h"
-#include "mali_kernel_core.h"
-#include "mali_kernel_memory_engine.h"
-#include "mali_block_allocator.h"
-#include "mali_osk.h"
-
-#define MALI_BLOCK_SIZE (256UL * 1024UL) /* 256 kB, remember to keep the ()s */
-
-typedef struct block_info
-{
- struct block_info * next;
-} block_info;
-
-/* The structure used as the handle produced by block_allocator_allocate,
- * and removed by block_allocator_release */
-typedef struct block_allocator_allocation
-{
- /* The list will be released in reverse order */
- block_info *last_allocated;
- mali_allocation_engine * engine;
- mali_memory_allocation * descriptor;
- u32 start_offset;
- u32 mapping_length;
-} block_allocator_allocation;
-
-
-typedef struct block_allocator
-{
- _mali_osk_lock_t *mutex;
- block_info * all_blocks;
- block_info * first_free;
- u32 base;
- u32 cpu_usage_adjust;
- u32 num_blocks;
-} block_allocator;
-
-MALI_STATIC_INLINE u32 get_phys(block_allocator * info, block_info * block);
-static mali_physical_memory_allocation_result block_allocator_allocate(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info);
-static void block_allocator_release(void * ctx, void * handle);
-static mali_physical_memory_allocation_result block_allocator_allocate_page_table_block(void * ctx, mali_page_table_block * block);
-static void block_allocator_release_page_table_block( mali_page_table_block *page_table_block );
-static void block_allocator_destroy(mali_physical_memory_allocator * allocator);
-static u32 block_allocator_stat(mali_physical_memory_allocator * allocator);
-
-mali_physical_memory_allocator * mali_block_allocator_create(u32 base_address, u32 cpu_usage_adjust, u32 size, const char *name)
-{
- mali_physical_memory_allocator * allocator;
- block_allocator * info;
- u32 usable_size;
- u32 num_blocks;
-
- usable_size = size & ~(MALI_BLOCK_SIZE - 1);
- MALI_DEBUG_PRINT(3, ("Mali block allocator create for region starting at 0x%08X length 0x%08X\n", base_address, size));
- MALI_DEBUG_PRINT(4, ("%d usable bytes\n", usable_size));
- num_blocks = usable_size / MALI_BLOCK_SIZE;
- MALI_DEBUG_PRINT(4, ("which becomes %d blocks\n", num_blocks));
-
- if (usable_size == 0)
- {
- MALI_DEBUG_PRINT(1, ("Memory block of size %d is unusable\n", size));
- return NULL;
- }
-
- allocator = _mali_osk_malloc(sizeof(mali_physical_memory_allocator));
- if (NULL != allocator)
- {
- info = _mali_osk_malloc(sizeof(block_allocator));
- if (NULL != info)
- {
- info->mutex = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED, 0, _MALI_OSK_LOCK_ORDER_MEM_INFO);
- if (NULL != info->mutex)
- {
- info->all_blocks = _mali_osk_malloc(sizeof(block_info) * num_blocks);
- if (NULL != info->all_blocks)
- {
- u32 i;
- info->first_free = NULL;
- info->num_blocks = num_blocks;
-
- info->base = base_address;
- info->cpu_usage_adjust = cpu_usage_adjust;
-
- for ( i = 0; i < num_blocks; i++)
- {
- info->all_blocks[i].next = info->first_free;
- info->first_free = &info->all_blocks[i];
- }
-
- allocator->allocate = block_allocator_allocate;
- allocator->allocate_page_table_block = block_allocator_allocate_page_table_block;
- allocator->destroy = block_allocator_destroy;
- allocator->stat = block_allocator_stat;
- allocator->ctx = info;
- allocator->name = name;
-
- return allocator;
- }
- _mali_osk_lock_term(info->mutex);
- }
- _mali_osk_free(info);
- }
- _mali_osk_free(allocator);
- }
-
- return NULL;
-}
-
-static void block_allocator_destroy(mali_physical_memory_allocator * allocator)
-{
- block_allocator * info;
- MALI_DEBUG_ASSERT_POINTER(allocator);
- MALI_DEBUG_ASSERT_POINTER(allocator->ctx);
- info = (block_allocator*)allocator->ctx;
-
- _mali_osk_free(info->all_blocks);
- _mali_osk_lock_term(info->mutex);
- _mali_osk_free(info);
- _mali_osk_free(allocator);
-}
-
-MALI_STATIC_INLINE u32 get_phys(block_allocator * info, block_info * block)
-{
- return info->base + ((block - info->all_blocks) * MALI_BLOCK_SIZE);
-}
-
-static mali_physical_memory_allocation_result block_allocator_allocate(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info)
-{
- block_allocator * info;
- u32 left;
- block_info * last_allocated = NULL;
- mali_physical_memory_allocation_result result = MALI_MEM_ALLOC_NONE;
- block_allocator_allocation *ret_allocation;
-
- MALI_DEBUG_ASSERT_POINTER(ctx);
- MALI_DEBUG_ASSERT_POINTER(descriptor);
- MALI_DEBUG_ASSERT_POINTER(offset);
- MALI_DEBUG_ASSERT_POINTER(alloc_info);
-
- info = (block_allocator*)ctx;
- left = descriptor->size - *offset;
- MALI_DEBUG_ASSERT(0 != left);
-
- if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) return MALI_MEM_ALLOC_INTERNAL_FAILURE;
-
- ret_allocation = _mali_osk_malloc( sizeof(block_allocator_allocation) );
-
- if ( NULL == ret_allocation )
- {
- /* Failure; try another allocator by returning MALI_MEM_ALLOC_NONE */
- _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
- return result;
- }
-
- ret_allocation->start_offset = *offset;
- ret_allocation->mapping_length = 0;
-
- while ((left > 0) && (info->first_free))
- {
- block_info * block;
- u32 phys_addr;
- u32 padding;
- u32 current_mapping_size;
-
- block = info->first_free;
- info->first_free = info->first_free->next;
- block->next = last_allocated;
- last_allocated = block;
-
- phys_addr = get_phys(info, block);
-
- padding = *offset & (MALI_BLOCK_SIZE-1);
-
- if (MALI_BLOCK_SIZE - padding < left)
- {
- current_mapping_size = MALI_BLOCK_SIZE - padding;
- }
- else
- {
- current_mapping_size = left;
- }
-
- if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, phys_addr + padding, info->cpu_usage_adjust, current_mapping_size))
- {
- MALI_DEBUG_PRINT(1, ("Mapping of physical memory failed\n"));
- result = MALI_MEM_ALLOC_INTERNAL_FAILURE;
- mali_allocation_engine_unmap_physical(engine, descriptor, ret_allocation->start_offset, ret_allocation->mapping_length, (_mali_osk_mem_mapregion_flags_t)0);
-
- /* release all memory back to the pool */
- while (last_allocated)
- {
- /* This relinks every block we've just allocated back into the free-list */
- block = last_allocated->next;
- last_allocated->next = info->first_free;
- info->first_free = last_allocated;
- last_allocated = block;
- }
-
- break;
- }
-
- *offset += current_mapping_size;
- left -= current_mapping_size;
- ret_allocation->mapping_length += current_mapping_size;
- }
-
- _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
-
- if (last_allocated)
- {
- if (left) result = MALI_MEM_ALLOC_PARTIAL;
- else result = MALI_MEM_ALLOC_FINISHED;
-
- /* Record all the information about this allocation */
- ret_allocation->last_allocated = last_allocated;
- ret_allocation->engine = engine;
- ret_allocation->descriptor = descriptor;
-
- alloc_info->ctx = info;
- alloc_info->handle = ret_allocation;
- alloc_info->release = block_allocator_release;
- }
- else
- {
- /* Free the allocation information - nothing to be passed back */
- _mali_osk_free( ret_allocation );
- }
-
- return result;
-}
-
-static void block_allocator_release(void * ctx, void * handle)
-{
- block_allocator * info;
- block_info * block, * next;
- block_allocator_allocation *allocation;
-
- MALI_DEBUG_ASSERT_POINTER(ctx);
- MALI_DEBUG_ASSERT_POINTER(handle);
-
- info = (block_allocator*)ctx;
- allocation = (block_allocator_allocation*)handle;
- block = allocation->last_allocated;
-
- MALI_DEBUG_ASSERT_POINTER(block);
-
- if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW))
- {
- MALI_DEBUG_PRINT(1, ("allocator release: Failed to get mutex\n"));
- return;
- }
-
- /* unmap */
- mali_allocation_engine_unmap_physical(allocation->engine, allocation->descriptor, allocation->start_offset, allocation->mapping_length, (_mali_osk_mem_mapregion_flags_t)0);
-
- while (block)
- {
- MALI_DEBUG_ASSERT(!((block < info->all_blocks) || (block > (info->all_blocks + info->num_blocks))));
-
- next = block->next;
-
- /* relink into free-list */
- block->next = info->first_free;
- info->first_free = block;
-
- /* advance the loop */
- block = next;
- }
-
- _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
-
- _mali_osk_free( allocation );
-}
-
-
-static mali_physical_memory_allocation_result block_allocator_allocate_page_table_block(void * ctx, mali_page_table_block * block)
-{
- block_allocator * info;
- mali_physical_memory_allocation_result result = MALI_MEM_ALLOC_INTERNAL_FAILURE;
-
- MALI_DEBUG_ASSERT_POINTER(ctx);
- MALI_DEBUG_ASSERT_POINTER(block);
- info = (block_allocator*)ctx;
-
- if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) return MALI_MEM_ALLOC_INTERNAL_FAILURE;
-
- if (NULL != info->first_free)
- {
- void * virt;
- u32 phys;
- u32 size;
- block_info * alloc;
- alloc = info->first_free;
-
- phys = get_phys(info, alloc); /* Does not modify info or alloc */
- size = MALI_BLOCK_SIZE; /* Must be multiple of MALI_MMU_PAGE_SIZE */
- virt = _mali_osk_mem_mapioregion( phys, size, "Mali block allocator page tables" );
-
- /* Failure of _mali_osk_mem_mapioregion will result in MALI_MEM_ALLOC_INTERNAL_FAILURE,
- * because it's unlikely another allocator will be able to map in. */
-
- if ( NULL != virt )
- {
- block->ctx = info; /* same as incoming ctx */
- block->handle = alloc;
- block->phys_base = phys;
- block->size = size;
- block->release = block_allocator_release_page_table_block;
- block->mapping = virt;
-
- info->first_free = alloc->next;
-
- alloc->next = NULL; /* Could potentially link many blocks together instead */
-
- result = MALI_MEM_ALLOC_FINISHED;
- }
- }
- else result = MALI_MEM_ALLOC_NONE;
-
- _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
-
- return result;
-}
-
-
-static void block_allocator_release_page_table_block( mali_page_table_block *page_table_block )
-{
- block_allocator * info;
- block_info * block, * next;
-
- MALI_DEBUG_ASSERT_POINTER( page_table_block );
-
- info = (block_allocator*)page_table_block->ctx;
- block = (block_info*)page_table_block->handle;
-
- MALI_DEBUG_ASSERT_POINTER(info);
- MALI_DEBUG_ASSERT_POINTER(block);
-
-
- if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW))
- {
- MALI_DEBUG_PRINT(1, ("allocator release: Failed to get mutex\n"));
- return;
- }
-
- /* Unmap all the physical memory at once */
- _mali_osk_mem_unmapioregion( page_table_block->phys_base, page_table_block->size, page_table_block->mapping );
-
- /** @note This loop handles the case where more than one block_info was linked.
- * Probably unnecessary for page table block releasing. */
- while (block)
- {
- next = block->next;
-
- MALI_DEBUG_ASSERT(!((block < info->all_blocks) || (block > (info->all_blocks + info->num_blocks))));
-
- block->next = info->first_free;
- info->first_free = block;
-
- block = next;
- }
-
- _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
-}
-
-static u32 block_allocator_stat(mali_physical_memory_allocator * allocator)
-{
- block_allocator * info;
- block_info *block;
- u32 free_blocks = 0;
-
- MALI_DEBUG_ASSERT_POINTER(allocator);
-
- info = (block_allocator*)allocator->ctx;
- block = info->first_free;
-
- while(block)
- {
- free_blocks++;
- block = block->next;
- }
- return (info->num_blocks - free_blocks) * MALI_BLOCK_SIZE;
-}