1 /* SPDX-License-Identifier: GPL-2.0 */
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 
16 #ifndef _IA_CSS_CIRCBUF_DESC_H_
17 #define _IA_CSS_CIRCBUF_DESC_H_
18 
19 #include <type_support.h>
20 #include <math_support.h>
21 #include <platform_support.h>
22 #include <sp.h>
23 #include "ia_css_circbuf_comm.h"
24 /****************************************************************
25  *
26  * Inline functions.
27  *
28  ****************************************************************/
29 /**
30  * @brief Test if the circular buffer is empty.
31  *
32  * @param cb_desc The pointer to the circular buffer descriptor.
33  *
34  * @return
35  *	- true when it is empty.
36  *	- false when it is not empty.
37  */
ia_css_circbuf_desc_is_empty(ia_css_circbuf_desc_t * cb_desc)38 static inline bool ia_css_circbuf_desc_is_empty(
39     ia_css_circbuf_desc_t *cb_desc)
40 {
41 	OP___assert(cb_desc);
42 	return (cb_desc->end == cb_desc->start);
43 }
44 
45 /**
46  * @brief Test if the circular buffer descriptor is full.
47  *
48  * @param cb_desc	The pointer to the circular buffer
49  *			descriptor.
50  *
51  * @return
52  *	- true when it is full.
53  *	- false when it is not full.
54  */
ia_css_circbuf_desc_is_full(ia_css_circbuf_desc_t * cb_desc)55 static inline bool ia_css_circbuf_desc_is_full(
56     ia_css_circbuf_desc_t *cb_desc)
57 {
58 	OP___assert(cb_desc);
59 	return (OP_std_modadd(cb_desc->end, 1, cb_desc->size) == cb_desc->start);
60 }
61 
62 /**
63  * @brief Initialize the circular buffer descriptor
64  *
65  * @param cb_desc	The pointer circular buffer descriptor
66  * @param size		The size of the circular buffer
67  */
ia_css_circbuf_desc_init(ia_css_circbuf_desc_t * cb_desc,int8_t size)68 static inline void ia_css_circbuf_desc_init(
69     ia_css_circbuf_desc_t *cb_desc,
70     int8_t size)
71 {
72 	OP___assert(cb_desc);
73 	cb_desc->size = size;
74 }
75 
76 /**
77  * @brief Get a position in the circular buffer descriptor.
78  *
79  * @param cb     The pointer to the circular buffer descriptor.
80  * @param base   The base position.
81  * @param offset The offset.
82  *
83  * @return the position in the circular buffer descriptor.
84  */
ia_css_circbuf_desc_get_pos_at_offset(ia_css_circbuf_desc_t * cb_desc,u32 base,int offset)85 static inline uint8_t ia_css_circbuf_desc_get_pos_at_offset(
86     ia_css_circbuf_desc_t *cb_desc,
87     u32 base,
88     int offset)
89 {
90 	u8 dest;
91 
92 	OP___assert(cb_desc);
93 	OP___assert(cb_desc->size > 0);
94 
95 	/* step 1: adjust the offset  */
96 	while (offset < 0) {
97 		offset += cb_desc->size;
98 	}
99 
100 	/* step 2: shift and round by the upper limit */
101 	dest = OP_std_modadd(base, offset, cb_desc->size);
102 
103 	return dest;
104 }
105 
106 /**
107  * @brief Get the offset between two positions in the circular buffer
108  * descriptor.
109  * Get the offset from the source position to the terminal position,
110  * along the direction in which the new elements come in.
111  *
112  * @param cb_desc	The pointer to the circular buffer descriptor.
113  * @param src_pos	The source position.
114  * @param dest_pos	The terminal position.
115  *
116  * @return the offset.
117  */
ia_css_circbuf_desc_get_offset(ia_css_circbuf_desc_t * cb_desc,u32 src_pos,uint32_t dest_pos)118 static inline int ia_css_circbuf_desc_get_offset(
119     ia_css_circbuf_desc_t *cb_desc,
120     u32 src_pos,
121     uint32_t dest_pos)
122 {
123 	int offset;
124 
125 	OP___assert(cb_desc);
126 
127 	offset = (int)(dest_pos - src_pos);
128 	offset += (offset < 0) ? cb_desc->size : 0;
129 
130 	return offset;
131 }
132 
133 /**
134  * @brief Get the number of available elements.
135  *
136  * @param cb_desc The pointer to the circular buffer.
137  *
138  * @return The number of available elements.
139  */
ia_css_circbuf_desc_get_num_elems(ia_css_circbuf_desc_t * cb_desc)140 static inline uint32_t ia_css_circbuf_desc_get_num_elems(
141     ia_css_circbuf_desc_t *cb_desc)
142 {
143 	int num;
144 
145 	OP___assert(cb_desc);
146 
147 	num = ia_css_circbuf_desc_get_offset(cb_desc,
148 					     cb_desc->start,
149 					     cb_desc->end);
150 
151 	return (uint32_t)num;
152 }
153 
154 /**
155  * @brief Get the number of free elements.
156  *
157  * @param cb_desc The pointer to the circular buffer descriptor.
158  *
159  * @return: The number of free elements.
160  */
ia_css_circbuf_desc_get_free_elems(ia_css_circbuf_desc_t * cb_desc)161 static inline uint32_t ia_css_circbuf_desc_get_free_elems(
162     ia_css_circbuf_desc_t *cb_desc)
163 {
164 	u32 num;
165 
166 	OP___assert(cb_desc);
167 
168 	num = ia_css_circbuf_desc_get_offset(cb_desc,
169 					     cb_desc->start,
170 					     cb_desc->end);
171 
172 	return (cb_desc->size - num);
173 }
174 #endif /*_IA_CSS_CIRCBUF_DESC_H_ */
175