2 * Support for Intel Camera Imaging ISP subsystem.
3 * Copyright (c) 2010-2015, Intel Corporation.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 #include "ia_css_rmgr.h"
17 #include <type_support.h>
18 #include <assert_support.h>
19 #include <platform_support.h> /* memset */
20 #include <memory_access.h> /* mmmgr_malloc, mhmm_free */
21 #include <ia_css_debug.h>
24 * @brief VBUF resource handles
26 #define NUM_HANDLES 1000
27 struct ia_css_rmgr_vbuf_handle handle_table[NUM_HANDLES];
30 * @brief VBUF resource pool - refpool
32 struct ia_css_rmgr_vbuf_pool refpool = {
33 false, /* copy_on_write */
41 * @brief VBUF resource pool - writepool
43 struct ia_css_rmgr_vbuf_pool writepool = {
44 true, /* copy_on_write */
52 * @brief VBUF resource pool - hmmbufferpool
54 struct ia_css_rmgr_vbuf_pool hmmbufferpool = {
55 true, /* copy_on_write */
62 struct ia_css_rmgr_vbuf_pool *vbuf_ref = &refpool;
63 struct ia_css_rmgr_vbuf_pool *vbuf_write = &writepool;
64 struct ia_css_rmgr_vbuf_pool *hmm_buffer_pool = &hmmbufferpool;
67 * @brief Initialize the reference count (host, vbuf)
69 static void rmgr_refcount_init_vbuf(void)
71 /* initialize the refcount table */
72 memset(&handle_table, 0, sizeof(handle_table));
76 * @brief Retain the reference count for a handle (host, vbuf)
78 * @param handle The pointer to the handle
80 void ia_css_rmgr_refcount_retain_vbuf(struct ia_css_rmgr_vbuf_handle **handle)
83 struct ia_css_rmgr_vbuf_handle *h;
84 if ((handle == NULL) || (*handle == NULL)) {
85 IA_CSS_LOG("Invalid inputs");
88 /* new vbuf to count on */
89 if ((*handle)->count == 0) {
92 for (i = 0; i < NUM_HANDLES; i++) {
93 if (handle_table[i].count == 0) {
94 *handle = &handle_table[i];
98 /* if the loop dus not break and *handle == NULL
99 this is an error handle and report it.
101 if (*handle == NULL) {
102 ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR,
103 "ia_css_i_host_refcount_retain_vbuf() failed to find empty slot!\n");
106 (*handle)->vptr = h->vptr;
107 (*handle)->size = h->size;
113 * @brief Release the reference count for a handle (host, vbuf)
115 * @param handle The pointer to the handle
117 void ia_css_rmgr_refcount_release_vbuf(struct ia_css_rmgr_vbuf_handle **handle)
119 if ((handle == NULL) || ((*handle) == NULL) || (((*handle)->count) == 0)) {
120 ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR,
121 "ia_css_rmgr_refcount_release_vbuf() invalid arguments!\n");
124 /* decrease reference count */
126 /* remove from admin */
127 if ((*handle)->count == 0) {
128 (*handle)->vptr = 0x0;
135 * @brief Initialize the resource pool (host, vbuf)
137 * @param pool The pointer to the pool
139 enum ia_css_err ia_css_rmgr_init_vbuf(struct ia_css_rmgr_vbuf_pool *pool)
141 enum ia_css_err err = IA_CSS_SUCCESS;
143 rmgr_refcount_init_vbuf();
144 assert(pool != NULL);
146 return IA_CSS_ERR_INVALID_ARGUMENTS;
147 /* initialize the recycle pool if used */
148 if (pool->recycle && pool->size) {
149 /* allocate memory for storing the handles */
153 pool->handles = sh_css_malloc(bytes_needed);
154 if (pool->handles != NULL)
155 memset(pool->handles, 0, bytes_needed);
157 err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
159 /* just in case, set the size to 0 */
161 pool->handles = NULL;
167 * @brief Uninitialize the resource pool (host, vbuf)
169 * @param pool The pointer to the pool
171 void ia_css_rmgr_uninit_vbuf(struct ia_css_rmgr_vbuf_pool *pool)
174 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_rmgr_uninit_vbuf()\n");
176 ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR, "ia_css_rmgr_uninit_vbuf(): NULL argument\n");
179 if (pool->handles != NULL) {
180 /* free the hmm buffers */
181 for (i = 0; i < pool->size; i++) {
182 if (pool->handles[i] != NULL) {
183 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
184 " freeing/releasing %x (count=%d)\n",
185 pool->handles[i]->vptr,
186 pool->handles[i]->count);
188 hmm_free(pool->handles[i]->vptr);
189 /* remove from refcount admin */
190 ia_css_rmgr_refcount_release_vbuf(
194 /* now free the pool handles list */
195 sh_css_free(pool->handles);
196 pool->handles = NULL;
201 * @brief Push a handle to the pool
203 * @param pool The pointer to the pool
204 * @param handle The pointer to the handle
207 void rmgr_push_handle(struct ia_css_rmgr_vbuf_pool *pool,
208 struct ia_css_rmgr_vbuf_handle **handle)
212 assert(pool != NULL);
213 assert(pool->recycle);
214 assert(pool->handles != NULL);
215 assert(handle != NULL);
216 for (i = 0; i < pool->size; i++) {
217 if (pool->handles[i] == NULL) {
218 ia_css_rmgr_refcount_retain_vbuf(handle);
219 pool->handles[i] = *handle;
228 * @brief Pop a handle from the pool
230 * @param pool The pointer to the pool
231 * @param handle The pointer to the handle
234 void rmgr_pop_handle(struct ia_css_rmgr_vbuf_pool *pool,
235 struct ia_css_rmgr_vbuf_handle **handle)
239 assert(pool != NULL);
240 assert(pool->recycle);
241 assert(pool->handles != NULL);
242 assert(handle != NULL);
243 assert(*handle != NULL);
244 for (i = 0; i < pool->size; i++) {
245 if ((pool->handles[i] != NULL) &&
246 (pool->handles[i]->size == (*handle)->size)) {
247 *handle = pool->handles[i];
248 pool->handles[i] = NULL;
249 /* dont release, we are returning it...
250 ia_css_rmgr_refcount_release_vbuf(handle); */
258 * @brief Acquire a handle from the pool (host, vbuf)
260 * @param pool The pointer to the pool
261 * @param handle The pointer to the handle
263 void ia_css_rmgr_acq_vbuf(struct ia_css_rmgr_vbuf_pool *pool,
264 struct ia_css_rmgr_vbuf_handle **handle)
266 struct ia_css_rmgr_vbuf_handle h;
268 if ((pool == NULL) || (handle == NULL) || (*handle == NULL)) {
269 IA_CSS_LOG("Invalid inputs");
273 if (pool->copy_on_write) {
274 /* only one reference, reuse (no new retain) */
275 if ((*handle)->count == 1)
277 /* more than one reference, release current buffer */
278 if ((*handle)->count > 1) {
279 /* store current values */
281 h.size = (*handle)->size;
282 /* release ref to current buffer */
283 ia_css_rmgr_refcount_release_vbuf(handle);
286 /* get new buffer for needed size */
287 if ((*handle)->vptr == 0x0) {
289 /* try and pop from pool */
290 rmgr_pop_handle(pool, handle);
292 if ((*handle)->vptr == 0x0) {
293 /* we need to allocate */
294 (*handle)->vptr = mmgr_malloc((*handle)->size);
296 /* we popped a buffer */
301 /* Note that handle will change to an internally maintained one */
302 ia_css_rmgr_refcount_retain_vbuf(handle);
306 * @brief Release a handle to the pool (host, vbuf)
308 * @param pool The pointer to the pool
309 * @param handle The pointer to the handle
311 void ia_css_rmgr_rel_vbuf(struct ia_css_rmgr_vbuf_pool *pool,
312 struct ia_css_rmgr_vbuf_handle **handle)
314 if ((pool == NULL) || (handle == NULL) || (*handle == NULL)) {
315 IA_CSS_LOG("Invalid inputs");
318 /* release the handle */
319 if ((*handle)->count == 1) {
320 if (!pool->recycle) {
321 /* non recycling pool, free mem */
322 hmm_free((*handle)->vptr);
324 /* recycle to pool */
325 rmgr_push_handle(pool, handle);
328 ia_css_rmgr_refcount_release_vbuf(handle);