1f5fbb83fSMauro Carvalho Chehab /* SPDX-License-Identifier: GPL-2.0 */
29d4fa1a1SMauro Carvalho Chehab /*
39d4fa1a1SMauro Carvalho Chehab  * Support for Intel Camera Imaging ISP subsystem.
49d4fa1a1SMauro Carvalho Chehab  * Copyright (c) 2015, Intel Corporation.
59d4fa1a1SMauro Carvalho Chehab  *
69d4fa1a1SMauro Carvalho Chehab  * This program is free software; you can redistribute it and/or modify it
79d4fa1a1SMauro Carvalho Chehab  * under the terms and conditions of the GNU General Public License,
89d4fa1a1SMauro Carvalho Chehab  * version 2, as published by the Free Software Foundation.
99d4fa1a1SMauro Carvalho Chehab  *
109d4fa1a1SMauro Carvalho Chehab  * This program is distributed in the hope it will be useful, but WITHOUT
119d4fa1a1SMauro Carvalho Chehab  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
129d4fa1a1SMauro Carvalho Chehab  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
139d4fa1a1SMauro Carvalho Chehab  * more details.
149d4fa1a1SMauro Carvalho Chehab  */
159d4fa1a1SMauro Carvalho Chehab 
169d4fa1a1SMauro Carvalho Chehab #ifndef _IA_CSS_CIRCBUF_DESC_H_
179d4fa1a1SMauro Carvalho Chehab #define _IA_CSS_CIRCBUF_DESC_H_
189d4fa1a1SMauro Carvalho Chehab 
199d4fa1a1SMauro Carvalho Chehab #include <type_support.h>
209d4fa1a1SMauro Carvalho Chehab #include <math_support.h>
219d4fa1a1SMauro Carvalho Chehab #include <platform_support.h>
229d4fa1a1SMauro Carvalho Chehab #include <sp.h>
239d4fa1a1SMauro Carvalho Chehab #include "ia_css_circbuf_comm.h"
249d4fa1a1SMauro Carvalho Chehab /****************************************************************
259d4fa1a1SMauro Carvalho Chehab  *
269d4fa1a1SMauro Carvalho Chehab  * Inline functions.
279d4fa1a1SMauro Carvalho Chehab  *
289d4fa1a1SMauro Carvalho Chehab  ****************************************************************/
299d4fa1a1SMauro Carvalho Chehab /**
309d4fa1a1SMauro Carvalho Chehab  * @brief Test if the circular buffer is empty.
319d4fa1a1SMauro Carvalho Chehab  *
329d4fa1a1SMauro Carvalho Chehab  * @param cb_desc The pointer to the circular buffer descriptor.
339d4fa1a1SMauro Carvalho Chehab  *
349d4fa1a1SMauro Carvalho Chehab  * @return
359d4fa1a1SMauro Carvalho Chehab  *	- true when it is empty.
369d4fa1a1SMauro Carvalho Chehab  *	- false when it is not empty.
379d4fa1a1SMauro Carvalho Chehab  */
ia_css_circbuf_desc_is_empty(ia_css_circbuf_desc_t * cb_desc)389d4fa1a1SMauro Carvalho Chehab static inline bool ia_css_circbuf_desc_is_empty(
399d4fa1a1SMauro Carvalho Chehab     ia_css_circbuf_desc_t *cb_desc)
409d4fa1a1SMauro Carvalho Chehab {
419d4fa1a1SMauro Carvalho Chehab 	OP___assert(cb_desc);
429d4fa1a1SMauro Carvalho Chehab 	return (cb_desc->end == cb_desc->start);
439d4fa1a1SMauro Carvalho Chehab }
449d4fa1a1SMauro Carvalho Chehab 
459d4fa1a1SMauro Carvalho Chehab /**
469d4fa1a1SMauro Carvalho Chehab  * @brief Test if the circular buffer descriptor is full.
479d4fa1a1SMauro Carvalho Chehab  *
489d4fa1a1SMauro Carvalho Chehab  * @param cb_desc	The pointer to the circular buffer
499d4fa1a1SMauro Carvalho Chehab  *			descriptor.
509d4fa1a1SMauro Carvalho Chehab  *
519d4fa1a1SMauro Carvalho Chehab  * @return
529d4fa1a1SMauro Carvalho Chehab  *	- true when it is full.
539d4fa1a1SMauro Carvalho Chehab  *	- false when it is not full.
549d4fa1a1SMauro Carvalho Chehab  */
ia_css_circbuf_desc_is_full(ia_css_circbuf_desc_t * cb_desc)559d4fa1a1SMauro Carvalho Chehab static inline bool ia_css_circbuf_desc_is_full(
569d4fa1a1SMauro Carvalho Chehab     ia_css_circbuf_desc_t *cb_desc)
579d4fa1a1SMauro Carvalho Chehab {
589d4fa1a1SMauro Carvalho Chehab 	OP___assert(cb_desc);
599d4fa1a1SMauro Carvalho Chehab 	return (OP_std_modadd(cb_desc->end, 1, cb_desc->size) == cb_desc->start);
609d4fa1a1SMauro Carvalho Chehab }
619d4fa1a1SMauro Carvalho Chehab 
629d4fa1a1SMauro Carvalho Chehab /**
639d4fa1a1SMauro Carvalho Chehab  * @brief Initialize the circular buffer descriptor
649d4fa1a1SMauro Carvalho Chehab  *
659d4fa1a1SMauro Carvalho Chehab  * @param cb_desc	The pointer circular buffer descriptor
669d4fa1a1SMauro Carvalho Chehab  * @param size		The size of the circular buffer
679d4fa1a1SMauro Carvalho Chehab  */
ia_css_circbuf_desc_init(ia_css_circbuf_desc_t * cb_desc,int8_t size)689d4fa1a1SMauro Carvalho Chehab static inline void ia_css_circbuf_desc_init(
699d4fa1a1SMauro Carvalho Chehab     ia_css_circbuf_desc_t *cb_desc,
709d4fa1a1SMauro Carvalho Chehab     int8_t size)
719d4fa1a1SMauro Carvalho Chehab {
729d4fa1a1SMauro Carvalho Chehab 	OP___assert(cb_desc);
739d4fa1a1SMauro Carvalho Chehab 	cb_desc->size = size;
749d4fa1a1SMauro Carvalho Chehab }
759d4fa1a1SMauro Carvalho Chehab 
769d4fa1a1SMauro Carvalho Chehab /**
779d4fa1a1SMauro Carvalho Chehab  * @brief Get a position in the circular buffer descriptor.
789d4fa1a1SMauro Carvalho Chehab  *
799d4fa1a1SMauro Carvalho Chehab  * @param cb     The pointer to the circular buffer descriptor.
809d4fa1a1SMauro Carvalho Chehab  * @param base   The base position.
819d4fa1a1SMauro Carvalho Chehab  * @param offset The offset.
829d4fa1a1SMauro Carvalho Chehab  *
839d4fa1a1SMauro Carvalho Chehab  * @return the position in the circular buffer descriptor.
849d4fa1a1SMauro Carvalho Chehab  */
ia_css_circbuf_desc_get_pos_at_offset(ia_css_circbuf_desc_t * cb_desc,u32 base,int offset)859d4fa1a1SMauro Carvalho Chehab static inline uint8_t ia_css_circbuf_desc_get_pos_at_offset(
869d4fa1a1SMauro Carvalho Chehab     ia_css_circbuf_desc_t *cb_desc,
879d4fa1a1SMauro Carvalho Chehab     u32 base,
889d4fa1a1SMauro Carvalho Chehab     int offset)
899d4fa1a1SMauro Carvalho Chehab {
909d4fa1a1SMauro Carvalho Chehab 	u8 dest;
919d4fa1a1SMauro Carvalho Chehab 
929d4fa1a1SMauro Carvalho Chehab 	OP___assert(cb_desc);
939d4fa1a1SMauro Carvalho Chehab 	OP___assert(cb_desc->size > 0);
949d4fa1a1SMauro Carvalho Chehab 
959d4fa1a1SMauro Carvalho Chehab 	/* step 1: adjust the offset  */
969d4fa1a1SMauro Carvalho Chehab 	while (offset < 0) {
979d4fa1a1SMauro Carvalho Chehab 		offset += cb_desc->size;
989d4fa1a1SMauro Carvalho Chehab 	}
999d4fa1a1SMauro Carvalho Chehab 
1009d4fa1a1SMauro Carvalho Chehab 	/* step 2: shift and round by the upper limit */
1019d4fa1a1SMauro Carvalho Chehab 	dest = OP_std_modadd(base, offset, cb_desc->size);
1029d4fa1a1SMauro Carvalho Chehab 
1039d4fa1a1SMauro Carvalho Chehab 	return dest;
1049d4fa1a1SMauro Carvalho Chehab }
1059d4fa1a1SMauro Carvalho Chehab 
1069d4fa1a1SMauro Carvalho Chehab /**
1079d4fa1a1SMauro Carvalho Chehab  * @brief Get the offset between two positions in the circular buffer
1089d4fa1a1SMauro Carvalho Chehab  * descriptor.
1099d4fa1a1SMauro Carvalho Chehab  * Get the offset from the source position to the terminal position,
1109d4fa1a1SMauro Carvalho Chehab  * along the direction in which the new elements come in.
1119d4fa1a1SMauro Carvalho Chehab  *
1129d4fa1a1SMauro Carvalho Chehab  * @param cb_desc	The pointer to the circular buffer descriptor.
1139d4fa1a1SMauro Carvalho Chehab  * @param src_pos	The source position.
1149d4fa1a1SMauro Carvalho Chehab  * @param dest_pos	The terminal position.
1159d4fa1a1SMauro Carvalho Chehab  *
1169d4fa1a1SMauro Carvalho Chehab  * @return the offset.
1179d4fa1a1SMauro Carvalho Chehab  */
ia_css_circbuf_desc_get_offset(ia_css_circbuf_desc_t * cb_desc,u32 src_pos,uint32_t dest_pos)1189d4fa1a1SMauro Carvalho Chehab static inline int ia_css_circbuf_desc_get_offset(
1199d4fa1a1SMauro Carvalho Chehab     ia_css_circbuf_desc_t *cb_desc,
1209d4fa1a1SMauro Carvalho Chehab     u32 src_pos,
1219d4fa1a1SMauro Carvalho Chehab     uint32_t dest_pos)
1229d4fa1a1SMauro Carvalho Chehab {
1239d4fa1a1SMauro Carvalho Chehab 	int offset;
1249d4fa1a1SMauro Carvalho Chehab 
1259d4fa1a1SMauro Carvalho Chehab 	OP___assert(cb_desc);
1269d4fa1a1SMauro Carvalho Chehab 
1279d4fa1a1SMauro Carvalho Chehab 	offset = (int)(dest_pos - src_pos);
1289d4fa1a1SMauro Carvalho Chehab 	offset += (offset < 0) ? cb_desc->size : 0;
1299d4fa1a1SMauro Carvalho Chehab 
1309d4fa1a1SMauro Carvalho Chehab 	return offset;
1319d4fa1a1SMauro Carvalho Chehab }
1329d4fa1a1SMauro Carvalho Chehab 
1339d4fa1a1SMauro Carvalho Chehab /**
1349d4fa1a1SMauro Carvalho Chehab  * @brief Get the number of available elements.
1359d4fa1a1SMauro Carvalho Chehab  *
1369d4fa1a1SMauro Carvalho Chehab  * @param cb_desc The pointer to the circular buffer.
1379d4fa1a1SMauro Carvalho Chehab  *
1389d4fa1a1SMauro Carvalho Chehab  * @return The number of available elements.
1399d4fa1a1SMauro Carvalho Chehab  */
ia_css_circbuf_desc_get_num_elems(ia_css_circbuf_desc_t * cb_desc)1409d4fa1a1SMauro Carvalho Chehab static inline uint32_t ia_css_circbuf_desc_get_num_elems(
1419d4fa1a1SMauro Carvalho Chehab     ia_css_circbuf_desc_t *cb_desc)
1429d4fa1a1SMauro Carvalho Chehab {
1439d4fa1a1SMauro Carvalho Chehab 	int num;
1449d4fa1a1SMauro Carvalho Chehab 
1459d4fa1a1SMauro Carvalho Chehab 	OP___assert(cb_desc);
1469d4fa1a1SMauro Carvalho Chehab 
1479d4fa1a1SMauro Carvalho Chehab 	num = ia_css_circbuf_desc_get_offset(cb_desc,
1489d4fa1a1SMauro Carvalho Chehab 					     cb_desc->start,
1499d4fa1a1SMauro Carvalho Chehab 					     cb_desc->end);
1509d4fa1a1SMauro Carvalho Chehab 
1519d4fa1a1SMauro Carvalho Chehab 	return (uint32_t)num;
1529d4fa1a1SMauro Carvalho Chehab }
1539d4fa1a1SMauro Carvalho Chehab 
1549d4fa1a1SMauro Carvalho Chehab /**
1559d4fa1a1SMauro Carvalho Chehab  * @brief Get the number of free elements.
1569d4fa1a1SMauro Carvalho Chehab  *
1579d4fa1a1SMauro Carvalho Chehab  * @param cb_desc The pointer to the circular buffer descriptor.
1589d4fa1a1SMauro Carvalho Chehab  *
1599d4fa1a1SMauro Carvalho Chehab  * @return: The number of free elements.
1609d4fa1a1SMauro Carvalho Chehab  */
ia_css_circbuf_desc_get_free_elems(ia_css_circbuf_desc_t * cb_desc)1619d4fa1a1SMauro Carvalho Chehab static inline uint32_t ia_css_circbuf_desc_get_free_elems(
1629d4fa1a1SMauro Carvalho Chehab     ia_css_circbuf_desc_t *cb_desc)
1639d4fa1a1SMauro Carvalho Chehab {
1649d4fa1a1SMauro Carvalho Chehab 	u32 num;
1659d4fa1a1SMauro Carvalho Chehab 
1669d4fa1a1SMauro Carvalho Chehab 	OP___assert(cb_desc);
1679d4fa1a1SMauro Carvalho Chehab 
1689d4fa1a1SMauro Carvalho Chehab 	num = ia_css_circbuf_desc_get_offset(cb_desc,
1699d4fa1a1SMauro Carvalho Chehab 					     cb_desc->start,
1709d4fa1a1SMauro Carvalho Chehab 					     cb_desc->end);
1719d4fa1a1SMauro Carvalho Chehab 
1729d4fa1a1SMauro Carvalho Chehab 	return (cb_desc->size - num);
1739d4fa1a1SMauro Carvalho Chehab }
1749d4fa1a1SMauro Carvalho Chehab #endif /*_IA_CSS_CIRCBUF_DESC_H_ */
175