| // SPDX-License-Identifier: GPL-2.0 |
| /* |
| * Support for Intel Camera Imaging ISP subsystem. |
| * Copyright (c) 2015, Intel Corporation. |
| * |
| * This program is free software; you can redistribute it and/or modify it |
| * under the terms and conditions of the GNU General Public License, |
| * version 2, as published by the Free Software Foundation. |
| * |
| * This program is distributed in the hope it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
| * more details. |
| */ |
| |
| #include "system_global.h" |
| |
| #include "assert_support.h" |
| #include "platform_support.h" |
| #include "ia_css_isys.h" |
| #include "ibuf_ctrl_rmgr.h" |
| |
| static ibuf_rsrc_t ibuf_rsrc; |
| |
| static ibuf_handle_t *getHandle(uint16_t index) |
| { |
| ibuf_handle_t *handle = NULL; |
| |
| if (index < MAX_IBUF_HANDLES) |
| handle = &ibuf_rsrc.handles[index]; |
| return handle; |
| } |
| |
| void ia_css_isys_ibuf_rmgr_init(void) |
| { |
| memset(&ibuf_rsrc, 0, sizeof(ibuf_rsrc)); |
| ibuf_rsrc.free_size = MAX_INPUT_BUFFER_SIZE; |
| } |
| |
| void ia_css_isys_ibuf_rmgr_uninit(void) |
| { |
| memset(&ibuf_rsrc, 0, sizeof(ibuf_rsrc)); |
| ibuf_rsrc.free_size = MAX_INPUT_BUFFER_SIZE; |
| } |
| |
| bool ia_css_isys_ibuf_rmgr_acquire( |
| u32 size, |
| uint32_t *start_addr) |
| { |
| bool retval = false; |
| bool input_buffer_found = false; |
| u32 aligned_size; |
| ibuf_handle_t *handle = NULL; |
| u16 i; |
| |
| assert(start_addr); |
| assert(size > 0); |
| |
| aligned_size = (size + (IBUF_ALIGN - 1)) & ~(IBUF_ALIGN - 1); |
| |
| /* Check if there is an available un-used handle with the size |
| * that will fulfill the request. |
| */ |
| if (ibuf_rsrc.num_active < ibuf_rsrc.num_allocated) { |
| for (i = 0; i < ibuf_rsrc.num_allocated; i++) { |
| handle = getHandle(i); |
| if (!handle->active) { |
| if (handle->size >= aligned_size) { |
| handle->active = true; |
| input_buffer_found = true; |
| ibuf_rsrc.num_active++; |
| break; |
| } |
| } |
| } |
| } |
| |
| if (!input_buffer_found) { |
| /* There were no available handles that fulfilled the |
| * request. Allocate a new handle with the requested size. |
| */ |
| if ((ibuf_rsrc.num_allocated < MAX_IBUF_HANDLES) && |
| (ibuf_rsrc.free_size >= aligned_size)) { |
| handle = getHandle(ibuf_rsrc.num_allocated); |
| handle->start_addr = ibuf_rsrc.free_start_addr; |
| handle->size = aligned_size; |
| handle->active = true; |
| |
| ibuf_rsrc.free_start_addr += aligned_size; |
| ibuf_rsrc.free_size -= aligned_size; |
| ibuf_rsrc.num_active++; |
| ibuf_rsrc.num_allocated++; |
| |
| input_buffer_found = true; |
| } |
| } |
| |
| if (input_buffer_found && handle) { |
| *start_addr = handle->start_addr; |
| retval = true; |
| } |
| |
| return retval; |
| } |
| |
| void ia_css_isys_ibuf_rmgr_release( |
| uint32_t *start_addr) |
| { |
| u16 i; |
| ibuf_handle_t *handle = NULL; |
| |
| assert(start_addr); |
| |
| for (i = 0; i < ibuf_rsrc.num_allocated; i++) { |
| handle = getHandle(i); |
| if (handle->active && handle->start_addr == *start_addr) { |
| handle->active = false; |
| ibuf_rsrc.num_active--; |
| break; |
| } |
| } |
| } |