2 * Support for Intel Camera Imaging ISP subsystem.
3 * Copyright (c) 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_queue.h"
16 #include <math_support.h>
17 #include <ia_css_circbuf.h>
18 #include <ia_css_circbuf_desc.h>
19 #include "queue_access.h"
21 /*****************************************************************************
23 *****************************************************************************/
24 int ia_css_queue_local_init(
25 ia_css_queue_t *qhandle,
26 ia_css_queue_local_t *desc)
28 if (NULL == qhandle || NULL == desc
29 || NULL == desc->cb_elems || NULL == desc->cb_desc) {
30 /* Invalid parameters, return error*/
34 /* Mark the queue as Local */
35 qhandle->type = IA_CSS_QUEUE_TYPE_LOCAL;
37 /* Create a local circular buffer queue*/
38 ia_css_circbuf_create(&qhandle->desc.cb_local,
45 int ia_css_queue_remote_init(
46 ia_css_queue_t *qhandle,
47 ia_css_queue_remote_t *desc)
49 if (NULL == qhandle || NULL == desc) {
50 /* Invalid parameters, return error*/
54 /* Mark the queue as remote*/
55 qhandle->type = IA_CSS_QUEUE_TYPE_REMOTE;
57 /* Copy over the local queue descriptor*/
58 qhandle->location = desc->location;
59 qhandle->proc_id = desc->proc_id;
60 qhandle->desc.remote.cb_desc_addr = desc->cb_desc_addr;
61 qhandle->desc.remote.cb_elems_addr = desc->cb_elems_addr;
63 /* If queue is remote, we let the local processor
64 * do its init, before using it. This is just to get us
65 * started, we can remove this restriction as we go ahead
71 int ia_css_queue_uninit(
72 ia_css_queue_t *qhandle)
77 /* Load the required queue object */
78 if (qhandle->type == IA_CSS_QUEUE_TYPE_LOCAL) {
79 /* Local queues are created. Destroy it*/
80 ia_css_circbuf_destroy(&qhandle->desc.cb_local);
86 int ia_css_queue_enqueue(
87 ia_css_queue_t *qhandle,
94 /* 1. Load the required queue object */
95 if (qhandle->type == IA_CSS_QUEUE_TYPE_LOCAL) {
96 /* Directly de-ref the object and
97 * operate on the queue
99 if (ia_css_circbuf_is_full(&qhandle->desc.cb_local)) {
100 /* Cannot push the element. Return*/
104 /* Push the element*/
105 ia_css_circbuf_push(&qhandle->desc.cb_local, item);
106 } else if (qhandle->type == IA_CSS_QUEUE_TYPE_REMOTE) {
107 ia_css_circbuf_desc_t cb_desc;
108 ia_css_circbuf_elem_t cb_elem;
109 uint32_t ignore_desc_flags = QUEUE_IGNORE_STEP_FLAG;
111 /* a. Load the queue cb_desc from remote */
112 QUEUE_CB_DESC_INIT(&cb_desc);
113 error = ia_css_queue_load(qhandle, &cb_desc, ignore_desc_flags);
117 /* b. Operate on the queue */
118 if (ia_css_circbuf_desc_is_full(&cb_desc))
123 error = ia_css_queue_item_store(qhandle, cb_desc.end, &cb_elem);
127 cb_desc.end = (cb_desc.end + 1) % cb_desc.size;
129 /* c. Store the queue object */
130 /* Set only fields requiring update with
131 * valid value. Avoids uncessary calls
132 * to load/store functions
134 ignore_desc_flags = QUEUE_IGNORE_SIZE_START_STEP_FLAGS;
136 error = ia_css_queue_store(qhandle, &cb_desc, ignore_desc_flags);
144 int ia_css_queue_dequeue(
145 ia_css_queue_t *qhandle,
149 if (qhandle == NULL || NULL == item)
152 /* 1. Load the required queue object */
153 if (qhandle->type == IA_CSS_QUEUE_TYPE_LOCAL) {
154 /* Directly de-ref the object and
155 * operate on the queue
157 if (ia_css_circbuf_is_empty(&qhandle->desc.cb_local)) {
158 /* Nothing to pop. Return empty queue*/
162 *item = ia_css_circbuf_pop(&qhandle->desc.cb_local);
163 } else if (qhandle->type == IA_CSS_QUEUE_TYPE_REMOTE) {
164 /* a. Load the queue from remote */
165 ia_css_circbuf_desc_t cb_desc;
166 ia_css_circbuf_elem_t cb_elem;
167 uint32_t ignore_desc_flags = QUEUE_IGNORE_STEP_FLAG;
169 QUEUE_CB_DESC_INIT(&cb_desc);
171 error = ia_css_queue_load(qhandle, &cb_desc, ignore_desc_flags);
175 /* b. Operate on the queue */
176 if (ia_css_circbuf_desc_is_empty(&cb_desc))
179 error = ia_css_queue_item_load(qhandle, cb_desc.start, &cb_elem);
185 cb_desc.start = OP_std_modadd(cb_desc.start, 1, cb_desc.size);
187 /* c. Store the queue object */
188 /* Set only fields requiring update with
189 * valid value. Avoids uncessary calls
190 * to load/store functions
192 ignore_desc_flags = QUEUE_IGNORE_SIZE_END_STEP_FLAGS;
193 error = ia_css_queue_store(qhandle, &cb_desc, ignore_desc_flags);
200 int ia_css_queue_is_full(
201 ia_css_queue_t *qhandle,
205 if ((qhandle == NULL) || (is_full == NULL))
208 /* 1. Load the required queue object */
209 if (qhandle->type == IA_CSS_QUEUE_TYPE_LOCAL) {
210 /* Directly de-ref the object and
211 * operate on the queue
213 *is_full = ia_css_circbuf_is_full(&qhandle->desc.cb_local);
215 } else if (qhandle->type == IA_CSS_QUEUE_TYPE_REMOTE) {
216 /* a. Load the queue from remote */
217 ia_css_circbuf_desc_t cb_desc;
218 uint32_t ignore_desc_flags = QUEUE_IGNORE_STEP_FLAG;
219 QUEUE_CB_DESC_INIT(&cb_desc);
220 error = ia_css_queue_load(qhandle, &cb_desc, ignore_desc_flags);
224 /* b. Operate on the queue */
225 *is_full = ia_css_circbuf_desc_is_full(&cb_desc);
232 int ia_css_queue_get_free_space(
233 ia_css_queue_t *qhandle,
237 if ((qhandle == NULL) || (size == NULL))
240 /* 1. Load the required queue object */
241 if (qhandle->type == IA_CSS_QUEUE_TYPE_LOCAL) {
242 /* Directly de-ref the object and
243 * operate on the queue
245 *size = ia_css_circbuf_get_free_elems(&qhandle->desc.cb_local);
247 } else if (qhandle->type == IA_CSS_QUEUE_TYPE_REMOTE) {
248 /* a. Load the queue from remote */
249 ia_css_circbuf_desc_t cb_desc;
250 uint32_t ignore_desc_flags = QUEUE_IGNORE_STEP_FLAG;
251 QUEUE_CB_DESC_INIT(&cb_desc);
252 error = ia_css_queue_load(qhandle, &cb_desc, ignore_desc_flags);
256 /* b. Operate on the queue */
257 *size = ia_css_circbuf_desc_get_free_elems(&cb_desc);
264 int ia_css_queue_get_used_space(
265 ia_css_queue_t *qhandle,
269 if ((qhandle == NULL) || (size == NULL))
272 /* 1. Load the required queue object */
273 if (qhandle->type == IA_CSS_QUEUE_TYPE_LOCAL) {
274 /* Directly de-ref the object and
275 * operate on the queue
277 *size = ia_css_circbuf_get_num_elems(&qhandle->desc.cb_local);
279 } else if (qhandle->type == IA_CSS_QUEUE_TYPE_REMOTE) {
280 /* a. Load the queue from remote */
281 ia_css_circbuf_desc_t cb_desc;
282 uint32_t ignore_desc_flags = QUEUE_IGNORE_STEP_FLAG;
283 QUEUE_CB_DESC_INIT(&cb_desc);
284 error = ia_css_queue_load(qhandle, &cb_desc, ignore_desc_flags);
288 /* b. Operate on the queue */
289 *size = ia_css_circbuf_desc_get_num_elems(&cb_desc);
296 int ia_css_queue_peek(
297 ia_css_queue_t *qhandle,
301 uint32_t num_elems = 0;
304 if ((qhandle == NULL) || (element == NULL))
307 /* 1. Load the required queue object */
308 if (qhandle->type == IA_CSS_QUEUE_TYPE_LOCAL) {
309 /* Directly de-ref the object and
310 * operate on the queue
312 /* Check if offset is valid */
313 num_elems = ia_css_circbuf_get_num_elems(&qhandle->desc.cb_local);
314 if (offset > num_elems)
317 *element = ia_css_circbuf_peek_from_start(&qhandle->desc.cb_local, (int) offset);
319 } else if (qhandle->type == IA_CSS_QUEUE_TYPE_REMOTE) {
320 /* a. Load the queue from remote */
321 ia_css_circbuf_desc_t cb_desc;
322 ia_css_circbuf_elem_t cb_elem;
323 uint32_t ignore_desc_flags = QUEUE_IGNORE_STEP_FLAG;
325 QUEUE_CB_DESC_INIT(&cb_desc);
327 error = ia_css_queue_load(qhandle, &cb_desc, ignore_desc_flags);
331 /* Check if offset is valid */
332 num_elems = ia_css_circbuf_desc_get_num_elems(&cb_desc);
333 if (offset > num_elems)
336 offset = OP_std_modadd(cb_desc.start, offset, cb_desc.size);
337 error = ia_css_queue_item_load(qhandle, (uint8_t)offset, &cb_elem);
341 *element = cb_elem.val;
348 int ia_css_queue_is_empty(
349 ia_css_queue_t *qhandle,
353 if ((qhandle == NULL) || (is_empty == NULL))
356 /* 1. Load the required queue object */
357 if (qhandle->type == IA_CSS_QUEUE_TYPE_LOCAL) {
358 /* Directly de-ref the object and
359 * operate on the queue
361 *is_empty = ia_css_circbuf_is_empty(&qhandle->desc.cb_local);
363 } else if (qhandle->type == IA_CSS_QUEUE_TYPE_REMOTE) {
364 /* a. Load the queue from remote */
365 ia_css_circbuf_desc_t cb_desc;
366 uint32_t ignore_desc_flags = QUEUE_IGNORE_STEP_FLAG;
368 QUEUE_CB_DESC_INIT(&cb_desc);
369 error = ia_css_queue_load(qhandle, &cb_desc, ignore_desc_flags);
373 /* b. Operate on the queue */
374 *is_empty = ia_css_circbuf_desc_is_empty(&cb_desc);
381 int ia_css_queue_get_size(
382 ia_css_queue_t *qhandle,
386 if ((qhandle == NULL) || (size == NULL))
389 /* 1. Load the required queue object */
390 if (qhandle->type == IA_CSS_QUEUE_TYPE_LOCAL) {
391 /* Directly de-ref the object and
392 * operate on the queue
394 /* Return maximum usable capacity */
395 *size = ia_css_circbuf_get_size(&qhandle->desc.cb_local);
396 } else if (qhandle->type == IA_CSS_QUEUE_TYPE_REMOTE) {
397 /* a. Load the queue from remote */
398 ia_css_circbuf_desc_t cb_desc;
399 uint32_t ignore_desc_flags = QUEUE_IGNORE_START_END_STEP_FLAGS;
401 QUEUE_CB_DESC_INIT(&cb_desc);
403 error = ia_css_queue_load(qhandle, &cb_desc, ignore_desc_flags);
407 /* Return maximum usable capacity */
408 *size = cb_desc.size;