]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blob - drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/rmgr/src/rmgr_vbuf.c
staging/atomisp: Add support for the Intel IPU v2
[mirror_ubuntu-jammy-kernel.git] / drivers / staging / media / atomisp / pci / atomisp2 / css2400 / runtime / rmgr / src / rmgr_vbuf.c
1 #ifndef ISP2401
2 /*
3 * Support for Intel Camera Imaging ISP subsystem.
4 * Copyright (c) 2015, Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 */
15 #else
16 /**
17 Support for Intel Camera Imaging ISP subsystem.
18 Copyright (c) 2010 - 2015, Intel Corporation.
19
20 This program is free software; you can redistribute it and/or modify it
21 under the terms and conditions of the GNU General Public License,
22 version 2, as published by the Free Software Foundation.
23
24 This program is distributed in the hope it will be useful, but WITHOUT
25 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
26 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
27 more details.
28 */
29 #endif
30
31 #include "ia_css_rmgr.h"
32
33 #include <type_support.h>
34 #include <assert_support.h>
35 #include <platform_support.h> /* memset */
36 #include <memory_access.h> /* mmmgr_malloc, mmmgr_free */
37 #include <ia_css_debug.h>
38
39 /**
40 * @brief VBUF resource handles
41 */
42 #define NUM_HANDLES 1000
43 struct ia_css_rmgr_vbuf_handle handle_table[NUM_HANDLES];
44
45 /**
46 * @brief VBUF resource pool - refpool
47 */
48 struct ia_css_rmgr_vbuf_pool refpool = {
49 false, /* copy_on_write */
50 false, /* recycle */
51 0, /* size */
52 0, /* index */
53 NULL, /* handles */
54 };
55
56 /**
57 * @brief VBUF resource pool - writepool
58 */
59 struct ia_css_rmgr_vbuf_pool writepool = {
60 true, /* copy_on_write */
61 false, /* recycle */
62 0, /* size */
63 0, /* index */
64 NULL, /* handles */
65 };
66
67 /**
68 * @brief VBUF resource pool - hmmbufferpool
69 */
70 struct ia_css_rmgr_vbuf_pool hmmbufferpool = {
71 true, /* copy_on_write */
72 true, /* recycle */
73 32, /* size */
74 0, /* index */
75 NULL, /* handles */
76 };
77
78 struct ia_css_rmgr_vbuf_pool *vbuf_ref = &refpool;
79 struct ia_css_rmgr_vbuf_pool *vbuf_write = &writepool;
80 struct ia_css_rmgr_vbuf_pool *hmm_buffer_pool = &hmmbufferpool;
81
82 /**
83 * @brief Initialize the reference count (host, vbuf)
84 */
85 static void rmgr_refcount_init_vbuf(void)
86 {
87 /* initialize the refcount table */
88 memset(&handle_table, 0, sizeof(handle_table));
89 }
90
91 /**
92 * @brief Retain the reference count for a handle (host, vbuf)
93 *
94 * @param handle The pointer to the handle
95 */
96 void ia_css_rmgr_refcount_retain_vbuf(struct ia_css_rmgr_vbuf_handle **handle)
97 {
98 int i;
99 struct ia_css_rmgr_vbuf_handle *h;
100 if ((handle == NULL) || (*handle == NULL)) {
101 IA_CSS_LOG("Invalid inputs");
102 return;
103 }
104 /* new vbuf to count on */
105 if ((*handle)->count == 0) {
106 h = *handle;
107 *handle = NULL;
108 for (i = 0; i < NUM_HANDLES; i++) {
109 if (handle_table[i].count == 0) {
110 *handle = &handle_table[i];
111 break;
112 }
113 }
114 /* if the loop dus not break and *handle == NULL
115 this is an error handle and report it.
116 */
117 if (*handle == NULL) {
118 ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR,
119 "ia_css_i_host_refcount_retain_vbuf() failed to find empty slot!\n");
120 return;
121 }
122 (*handle)->vptr = h->vptr;
123 (*handle)->size = h->size;
124 }
125 (*handle)->count++;
126 }
127
128 /**
129 * @brief Release the reference count for a handle (host, vbuf)
130 *
131 * @param handle The pointer to the handle
132 */
133 void ia_css_rmgr_refcount_release_vbuf(struct ia_css_rmgr_vbuf_handle **handle)
134 {
135 if ((handle == NULL) || ((*handle) == NULL) || (((*handle)->count) == 0)) {
136 ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR,
137 "ia_css_rmgr_refcount_release_vbuf() invalid arguments!\n");
138 return;
139 }
140 /* decrease reference count */
141 (*handle)->count--;
142 /* remove from admin */
143 if ((*handle)->count == 0) {
144 (*handle)->vptr = 0x0;
145 (*handle)->size = 0;
146 *handle = NULL;
147 }
148 }
149
150 /**
151 * @brief Initialize the resource pool (host, vbuf)
152 *
153 * @param pool The pointer to the pool
154 */
155 enum ia_css_err ia_css_rmgr_init_vbuf(struct ia_css_rmgr_vbuf_pool *pool)
156 {
157 enum ia_css_err err = IA_CSS_SUCCESS;
158 size_t bytes_needed;
159 rmgr_refcount_init_vbuf();
160 assert(pool != NULL);
161 if (pool == NULL)
162 return IA_CSS_ERR_INVALID_ARGUMENTS;
163 /* initialize the recycle pool if used */
164 if (pool->recycle && pool->size) {
165 /* allocate memory for storing the handles */
166 bytes_needed =
167 sizeof(void *) *
168 pool->size;
169 pool->handles = sh_css_malloc(bytes_needed);
170 if (pool->handles != NULL)
171 memset(pool->handles, 0, bytes_needed);
172 else
173 err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
174 } else {
175 /* just in case, set the size to 0 */
176 pool->size = 0;
177 pool->handles = NULL;
178 }
179 return err;
180 }
181
182 /**
183 * @brief Uninitialize the resource pool (host, vbuf)
184 *
185 * @param pool The pointer to the pool
186 */
187 void ia_css_rmgr_uninit_vbuf(struct ia_css_rmgr_vbuf_pool *pool)
188 {
189 uint32_t i;
190 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_rmgr_uninit_vbuf()\n");
191 if (pool == NULL) {
192 ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR, "ia_css_rmgr_uninit_vbuf(): NULL argument\n");
193 return;
194 }
195 if (pool->handles != NULL) {
196 /* free the hmm buffers */
197 for (i = 0; i < pool->size; i++) {
198 if (pool->handles[i] != NULL) {
199 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
200 " freeing/releasing %x (count=%d)\n",
201 pool->handles[i]->vptr,
202 pool->handles[i]->count);
203 /* free memory */
204 mmgr_free(pool->handles[i]->vptr);
205 /* remove from refcount admin */
206 ia_css_rmgr_refcount_release_vbuf(
207 &pool->handles[i]);
208 }
209 }
210 /* now free the pool handles list */
211 sh_css_free(pool->handles);
212 pool->handles = NULL;
213 }
214 }
215
216 /**
217 * @brief Push a handle to the pool
218 *
219 * @param pool The pointer to the pool
220 * @param handle The pointer to the handle
221 */
222 static
223 void rmgr_push_handle(struct ia_css_rmgr_vbuf_pool *pool,
224 struct ia_css_rmgr_vbuf_handle **handle)
225 {
226 uint32_t i;
227 bool succes = false;
228 assert(pool != NULL);
229 assert(pool->recycle);
230 assert(pool->handles != NULL);
231 assert(handle != NULL);
232 for (i = 0; i < pool->size; i++) {
233 if (pool->handles[i] == NULL) {
234 ia_css_rmgr_refcount_retain_vbuf(handle);
235 pool->handles[i] = *handle;
236 succes = true;
237 break;
238 }
239 }
240 assert(succes);
241 }
242
243 /**
244 * @brief Pop a handle from the pool
245 *
246 * @param pool The pointer to the pool
247 * @param handle The pointer to the handle
248 */
249 static
250 void rmgr_pop_handle(struct ia_css_rmgr_vbuf_pool *pool,
251 struct ia_css_rmgr_vbuf_handle **handle)
252 {
253 uint32_t i;
254 bool succes = false;
255 assert(pool != NULL);
256 assert(pool->recycle);
257 assert(pool->handles != NULL);
258 assert(handle != NULL);
259 assert(*handle != NULL);
260 for (i = 0; i < pool->size; i++) {
261 if ((pool->handles[i] != NULL) &&
262 (pool->handles[i]->size == (*handle)->size)) {
263 *handle = pool->handles[i];
264 pool->handles[i] = NULL;
265 /* dont release, we are returning it...
266 ia_css_rmgr_refcount_release_vbuf(handle); */
267 succes = true;
268 break;
269 }
270 }
271 }
272
273 /**
274 * @brief Acquire a handle from the pool (host, vbuf)
275 *
276 * @param pool The pointer to the pool
277 * @param handle The pointer to the handle
278 */
279 void ia_css_rmgr_acq_vbuf(struct ia_css_rmgr_vbuf_pool *pool,
280 struct ia_css_rmgr_vbuf_handle **handle)
281 {
282 #ifdef __KLOCWORK__
283 /* KW sees the *handle = h; assignment about 20 lines down
284 and thinks that we are assigning a local to a global.
285 What it does not see is that in ia_css_i_host_rmgr_pop_handle
286 a new value is assigned to handle.
287 So this is a false positive KW issue.
288 To fix that we make the struct static for KW so it will
289 think that h remains alive; we do not want this in our
290 production code though as it breaks reentrancy of the code
291 */
292
293 static struct ia_css_rmgr_vbuf_handle h;
294 #else /* __KLOCWORK__ */
295 struct ia_css_rmgr_vbuf_handle h;
296 #endif /* __KLOCWORK__ */
297
298 if ((pool == NULL) || (handle == NULL) || (*handle == NULL)) {
299 IA_CSS_LOG("Invalid inputs");
300 return;
301 }
302
303 if (pool->copy_on_write) {
304 /* only one reference, reuse (no new retain) */
305 if ((*handle)->count == 1)
306 return;
307 /* more than one reference, release current buffer */
308 if ((*handle)->count > 1) {
309 /* store current values */
310 h.vptr = 0x0;
311 h.size = (*handle)->size;
312 /* release ref to current buffer */
313 ia_css_rmgr_refcount_release_vbuf(handle);
314 *handle = &h;
315 }
316 /* get new buffer for needed size */
317 if ((*handle)->vptr == 0x0) {
318 if (pool->recycle) {
319 /* try and pop from pool */
320 rmgr_pop_handle(pool, handle);
321 }
322 if ((*handle)->vptr == 0x0) {
323 /* we need to allocate */
324 (*handle)->vptr = mmgr_malloc((*handle)->size);
325 } else {
326 /* we popped a buffer */
327 return;
328 }
329 }
330 }
331 /* Note that handle will change to an internally maintained one */
332 ia_css_rmgr_refcount_retain_vbuf(handle);
333 }
334
335 /**
336 * @brief Release a handle to the pool (host, vbuf)
337 *
338 * @param pool The pointer to the pool
339 * @param handle The pointer to the handle
340 */
341 void ia_css_rmgr_rel_vbuf(struct ia_css_rmgr_vbuf_pool *pool,
342 struct ia_css_rmgr_vbuf_handle **handle)
343 {
344 if ((pool == NULL) || (handle == NULL) || (*handle == NULL)) {
345 IA_CSS_LOG("Invalid inputs");
346 return;
347 }
348 /* release the handle */
349 if ((*handle)->count == 1) {
350 if (!pool->recycle) {
351 /* non recycling pool, free mem */
352 mmgr_free((*handle)->vptr);
353 } else {
354 /* recycle to pool */
355 rmgr_push_handle(pool, handle);
356 }
357 }
358 ia_css_rmgr_refcount_release_vbuf(handle);
359 *handle = NULL;
360 }