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