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