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_3A_H
8 #define __IA_CSS_3A_H
9 
10 /* @file
11  * This file contains types used for 3A statistics
12  */
13 
14 #include <linux/build_bug.h>
15 
16 #include <math_support.h>
17 #include <type_support.h>
18 #include "ia_css_types.h"
19 #include "ia_css_err.h"
20 #include "system_global.h"
21 
22 enum ia_css_3a_tables {
23 	IA_CSS_S3A_TBL_HI,
24 	IA_CSS_S3A_TBL_LO,
25 	IA_CSS_RGBY_TBL,
26 	IA_CSS_NUM_3A_TABLES
27 };
28 
29 /* Structure that holds 3A statistics in the ISP internal
30  * format. Use ia_css_get_3a_statistics() to translate
31  * this to the format used on the host (3A library).
32  * */
33 struct ia_css_isp_3a_statistics {
34 	union {
35 		struct {
36 			ia_css_ptr s3a_tbl;
37 		} dmem;
38 		struct {
39 			ia_css_ptr s3a_tbl_hi;
40 			ia_css_ptr s3a_tbl_lo;
41 		} vmem;
42 	} data;
43 	struct {
44 		ia_css_ptr rgby_tbl;
45 	} data_hmem;
46 	u32 exp_id;     /** exposure id, to match statistics to a frame,
47 				  see ia_css_event_public.h for more detail. */
48 	u32 isp_config_id;/** Unique ID to track which config was actually applied to a particular frame */
49 	ia_css_ptr data_ptr; /** pointer to base of all data */
50 	u32   size;     /** total size of all data */
51 	u32   dmem_size;
52 	u32   vmem_size; /** both lo and hi have this size */
53 	u32   hmem_size;
54 };
55 
56 #define SIZE_OF_DMEM_STRUCT						\
57 	(SIZE_OF_IA_CSS_PTR)
58 
59 #define SIZE_OF_VMEM_STRUCT						\
60 	(2 * SIZE_OF_IA_CSS_PTR)
61 
62 #define SIZE_OF_DATA_UNION						\
63 	(MAX(SIZE_OF_DMEM_STRUCT, SIZE_OF_VMEM_STRUCT))
64 
65 #define SIZE_OF_DATA_HMEM_STRUCT					\
66 	(SIZE_OF_IA_CSS_PTR)
67 
68 #define SIZE_OF_IA_CSS_ISP_3A_STATISTICS_STRUCT				\
69 	(SIZE_OF_DATA_UNION +						\
70 	 SIZE_OF_DATA_HMEM_STRUCT +					\
71 	 sizeof(uint32_t) +						\
72 	 sizeof(uint32_t) +						\
73 	 SIZE_OF_IA_CSS_PTR +						\
74 	 4 * sizeof(uint32_t))
75 
76 static_assert(sizeof(struct ia_css_isp_3a_statistics) == SIZE_OF_IA_CSS_ISP_3A_STATISTICS_STRUCT);
77 
78 /* Map with host-side pointers to ISP-format statistics.
79  * These pointers can either be copies of ISP data or memory mapped
80  * ISP pointers.
81  * All of the data behind these pointers is allocated contiguously, the
82  * allocated pointer is stored in the data_ptr field. The other fields
83  * point into this one block of data.
84  */
85 struct ia_css_isp_3a_statistics_map {
86 	void                    *data_ptr; /** Pointer to start of memory */
87 	struct ia_css_3a_output *dmem_stats;
88 	u16                *vmem_stats_hi;
89 	u16                *vmem_stats_lo;
90 	struct ia_css_bh_table  *hmem_stats;
91 	u32                 size; /** total size in bytes of data_ptr */
92 	u32                 data_allocated; /** indicate whether data_ptr
93 						    was allocated or not. */
94 };
95 
96 /* @brief Copy and translate 3A statistics from an ISP buffer to a host buffer
97  * @param[out]	host_stats Host buffer.
98  * @param[in]	isp_stats ISP buffer.
99  * @return	error value if temporary memory cannot be allocated
100  *
101  * This copies 3a statistics from an ISP pointer to a host pointer and then
102  * translates some of the statistics, details depend on which ISP binary is
103  * used.
104  * Always use this function, never copy the buffer directly.
105  */
106 int
107 ia_css_get_3a_statistics(struct ia_css_3a_statistics           *host_stats,
108 			 const struct ia_css_isp_3a_statistics *isp_stats);
109 
110 /* @brief Translate 3A statistics from ISP format to host format.
111  * @param[out]	host_stats host-format statistics
112  * @param[in]	isp_stats  ISP-format statistics
113  * @return	None
114  *
115  * This function translates statistics from the internal ISP-format to
116  * the host-format. This function does not include an additional copy
117  * step.
118  * */
119 void
120 ia_css_translate_3a_statistics(
121     struct ia_css_3a_statistics               *host_stats,
122     const struct ia_css_isp_3a_statistics_map *isp_stats);
123 
124 /* Convenience functions for alloc/free of certain datatypes */
125 
126 /* @brief Allocate memory for the 3a statistics on the ISP
127  * @param[in]	grid The grid.
128  * @return		Pointer to the allocated 3a statistics buffer on the ISP
129 */
130 struct ia_css_isp_3a_statistics *
131 ia_css_isp_3a_statistics_allocate(const struct ia_css_3a_grid_info *grid);
132 
133 /* @brief Free the 3a statistics memory on the isp
134  * @param[in]	me Pointer to the 3a statistics buffer on the ISP.
135  * @return		None
136 */
137 void
138 ia_css_isp_3a_statistics_free(struct ia_css_isp_3a_statistics *me);
139 
140 /* @brief Allocate memory for the 3a statistics on the host
141  * @param[in]	grid The grid.
142  * @return		Pointer to the allocated 3a statistics buffer on the host
143 */
144 struct ia_css_3a_statistics *
145 ia_css_3a_statistics_allocate(const struct ia_css_3a_grid_info *grid);
146 
147 /* @brief Free the 3a statistics memory on the host
148  * @param[in]	me Pointer to the 3a statistics buffer on the host.
149  * @return		None
150  */
151 void
152 ia_css_3a_statistics_free(struct ia_css_3a_statistics *me);
153 
154 /* @brief Allocate a 3a statistics map structure
155  * @param[in]	isp_stats pointer to ISP 3a statistis struct
156  * @param[in]	data_ptr  host-side pointer to ISP 3a statistics.
157  * @return		Pointer to the allocated 3a statistics map
158  *
159  * This function allocates the ISP 3a statistics map structure
160  * and uses the data_ptr as base pointer to set the appropriate
161  * pointers to all relevant subsets of the 3a statistics (dmem,
162  * vmem, hmem).
163  * If the data_ptr is NULL, this function will allocate the host-side
164  * memory. This information is stored in the struct and used in the
165  * ia_css_isp_3a_statistics_map_free() function to determine whether
166  * the memory should be freed or not.
167  * Note that this function does not allocate or map any ISP
168  * memory.
169 */
170 struct ia_css_isp_3a_statistics_map *
171 ia_css_isp_3a_statistics_map_allocate(
172     const struct ia_css_isp_3a_statistics *isp_stats,
173     void *data_ptr);
174 
175 /* @brief Free the 3a statistics map
176  * @param[in]	me Pointer to the 3a statistics map
177  * @return		None
178  *
179  * This function frees the map struct. If the data_ptr inside it
180  * was allocated inside ia_css_isp_3a_statistics_map_allocate(), it
181  * will be freed in this function. Otherwise it will not be freed.
182  */
183 void
184 ia_css_isp_3a_statistics_map_free(struct ia_css_isp_3a_statistics_map *me);
185 
186 #endif /* __IA_CSS_3A_H */
187