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 */
38static 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 */
55static 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 */
68static 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 */
85static 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 */
118static 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 */
140static 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 */
161static 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