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 #include "hmm.h"
8
9 #include <assert_support.h>
10 #include "ia_css_debug.h"
11 #include "ia_css_sdis2.host.h"
12
13 const struct ia_css_dvs2_coefficients default_sdis2_config = {
14 .grid = { 0, 0, 0, 0, 0, 0, 0, 0 },
15 .hor_coefs = { NULL, NULL, NULL, NULL },
16 .ver_coefs = { NULL, NULL, NULL, NULL },
17 };
18
19 static void
fill_row(short * private,const short * public,unsigned int width,unsigned int padding)20 fill_row(short *private, const short *public, unsigned int width,
21 unsigned int padding)
22 {
23 memcpy(private, public, width * sizeof(short));
24 memset(&private[width], 0, padding * sizeof(short));
25 }
26
ia_css_sdis2_horicoef_vmem_encode(struct sh_css_isp_sdis_hori_coef_tbl * to,const struct ia_css_dvs2_coefficients * from,unsigned int size)27 void ia_css_sdis2_horicoef_vmem_encode(
28 struct sh_css_isp_sdis_hori_coef_tbl *to,
29 const struct ia_css_dvs2_coefficients *from,
30 unsigned int size)
31 {
32 unsigned int aligned_width = from->grid.aligned_width *
33 from->grid.bqs_per_grid_cell;
34 unsigned int width = from->grid.num_hor_coefs;
35 int padding = aligned_width - width;
36 unsigned int stride = size / IA_CSS_DVS2_NUM_COEF_TYPES / sizeof(short);
37 unsigned int total_bytes = aligned_width * IA_CSS_DVS2_NUM_COEF_TYPES *
38 sizeof(short);
39 short *private = (short *)to;
40
41 /* Copy the table, add padding */
42 assert(padding >= 0);
43 assert(total_bytes <= size);
44 assert(size % (IA_CSS_DVS2_NUM_COEF_TYPES * ISP_VEC_NELEMS * sizeof(
45 short)) == 0);
46 fill_row(&private[0 * stride], from->hor_coefs.odd_real, width, padding);
47 fill_row(&private[1 * stride], from->hor_coefs.odd_imag, width, padding);
48 fill_row(&private[2 * stride], from->hor_coefs.even_real, width, padding);
49 fill_row(&private[3 * stride], from->hor_coefs.even_imag, width, padding);
50 }
51
ia_css_sdis2_vertcoef_vmem_encode(struct sh_css_isp_sdis_vert_coef_tbl * to,const struct ia_css_dvs2_coefficients * from,unsigned int size)52 void ia_css_sdis2_vertcoef_vmem_encode(
53 struct sh_css_isp_sdis_vert_coef_tbl *to,
54 const struct ia_css_dvs2_coefficients *from,
55 unsigned int size)
56 {
57 unsigned int aligned_height = from->grid.aligned_height *
58 from->grid.bqs_per_grid_cell;
59 unsigned int height = from->grid.num_ver_coefs;
60 int padding = aligned_height - height;
61 unsigned int stride = size / IA_CSS_DVS2_NUM_COEF_TYPES / sizeof(short);
62 unsigned int total_bytes = aligned_height * IA_CSS_DVS2_NUM_COEF_TYPES *
63 sizeof(short);
64 short *private = (short *)to;
65
66 /* Copy the table, add padding */
67 assert(padding >= 0);
68 assert(total_bytes <= size);
69 assert(size % (IA_CSS_DVS2_NUM_COEF_TYPES * ISP_VEC_NELEMS * sizeof(
70 short)) == 0);
71 fill_row(&private[0 * stride], from->ver_coefs.odd_real, height, padding);
72 fill_row(&private[1 * stride], from->ver_coefs.odd_imag, height, padding);
73 fill_row(&private[2 * stride], from->ver_coefs.even_real, height, padding);
74 fill_row(&private[3 * stride], from->ver_coefs.even_imag, height, padding);
75 }
76
ia_css_sdis2_horiproj_encode(struct sh_css_isp_sdis_hori_proj_tbl * to,const struct ia_css_dvs2_coefficients * from,unsigned int size)77 void ia_css_sdis2_horiproj_encode(
78 struct sh_css_isp_sdis_hori_proj_tbl *to,
79 const struct ia_css_dvs2_coefficients *from,
80 unsigned int size)
81 {
82 (void)to;
83 (void)from;
84 (void)size;
85 }
86
ia_css_sdis2_vertproj_encode(struct sh_css_isp_sdis_vert_proj_tbl * to,const struct ia_css_dvs2_coefficients * from,unsigned int size)87 void ia_css_sdis2_vertproj_encode(
88 struct sh_css_isp_sdis_vert_proj_tbl *to,
89 const struct ia_css_dvs2_coefficients *from,
90 unsigned int size)
91 {
92 (void)to;
93 (void)from;
94 (void)size;
95 }
96
ia_css_get_isp_dvs2_coefficients(struct ia_css_stream * stream,short * hor_coefs_odd_real,short * hor_coefs_odd_imag,short * hor_coefs_even_real,short * hor_coefs_even_imag,short * ver_coefs_odd_real,short * ver_coefs_odd_imag,short * ver_coefs_even_real,short * ver_coefs_even_imag)97 void ia_css_get_isp_dvs2_coefficients(
98 struct ia_css_stream *stream,
99 short *hor_coefs_odd_real,
100 short *hor_coefs_odd_imag,
101 short *hor_coefs_even_real,
102 short *hor_coefs_even_imag,
103 short *ver_coefs_odd_real,
104 short *ver_coefs_odd_imag,
105 short *ver_coefs_even_real,
106 short *ver_coefs_even_imag)
107 {
108 struct ia_css_isp_parameters *params;
109 unsigned int hor_num_3a, ver_num_3a;
110 struct ia_css_binary *dvs_binary;
111
112 IA_CSS_ENTER("void");
113
114 assert(stream);
115 assert(hor_coefs_odd_real);
116 assert(hor_coefs_odd_imag);
117 assert(hor_coefs_even_real);
118 assert(hor_coefs_even_imag);
119 assert(ver_coefs_odd_real);
120 assert(ver_coefs_odd_imag);
121 assert(ver_coefs_even_real);
122 assert(ver_coefs_even_imag);
123
124 params = stream->isp_params_configs;
125
126 /* Only video pipe supports DVS */
127 dvs_binary = ia_css_stream_get_dvs_binary(stream);
128 if (!dvs_binary)
129 return;
130
131 hor_num_3a = dvs_binary->dis.coef.dim.width;
132 ver_num_3a = dvs_binary->dis.coef.dim.height;
133
134 memcpy(hor_coefs_odd_real, params->dvs2_coefs.hor_coefs.odd_real,
135 hor_num_3a * sizeof(short));
136 memcpy(hor_coefs_odd_imag, params->dvs2_coefs.hor_coefs.odd_imag,
137 hor_num_3a * sizeof(short));
138 memcpy(hor_coefs_even_real, params->dvs2_coefs.hor_coefs.even_real,
139 hor_num_3a * sizeof(short));
140 memcpy(hor_coefs_even_imag, params->dvs2_coefs.hor_coefs.even_imag,
141 hor_num_3a * sizeof(short));
142 memcpy(ver_coefs_odd_real, params->dvs2_coefs.ver_coefs.odd_real,
143 ver_num_3a * sizeof(short));
144 memcpy(ver_coefs_odd_imag, params->dvs2_coefs.ver_coefs.odd_imag,
145 ver_num_3a * sizeof(short));
146 memcpy(ver_coefs_even_real, params->dvs2_coefs.ver_coefs.even_real,
147 ver_num_3a * sizeof(short));
148 memcpy(ver_coefs_even_imag, params->dvs2_coefs.ver_coefs.even_imag,
149 ver_num_3a * sizeof(short));
150
151 IA_CSS_LEAVE("void");
152 }
153
ia_css_sdis2_clear_coefficients(struct ia_css_dvs2_coefficients * dvs2_coefs)154 void ia_css_sdis2_clear_coefficients(
155 struct ia_css_dvs2_coefficients *dvs2_coefs)
156 {
157 dvs2_coefs->hor_coefs.odd_real = NULL;
158 dvs2_coefs->hor_coefs.odd_imag = NULL;
159 dvs2_coefs->hor_coefs.even_real = NULL;
160 dvs2_coefs->hor_coefs.even_imag = NULL;
161 dvs2_coefs->ver_coefs.odd_real = NULL;
162 dvs2_coefs->ver_coefs.odd_imag = NULL;
163 dvs2_coefs->ver_coefs.even_real = NULL;
164 dvs2_coefs->ver_coefs.even_imag = NULL;
165 }
166
167 int
ia_css_get_dvs2_statistics(struct ia_css_dvs2_statistics * host_stats,const struct ia_css_isp_dvs_statistics * isp_stats)168 ia_css_get_dvs2_statistics(
169 struct ia_css_dvs2_statistics *host_stats,
170 const struct ia_css_isp_dvs_statistics *isp_stats) {
171 struct ia_css_isp_dvs_statistics_map *map;
172 int ret = 0;
173
174 IA_CSS_ENTER("host_stats=%p, isp_stats=%p", host_stats, isp_stats);
175
176 assert(host_stats);
177 assert(isp_stats);
178
179 map = ia_css_isp_dvs_statistics_map_allocate(isp_stats, NULL);
180 if (map)
181 {
182 hmm_load(isp_stats->data_ptr, map->data_ptr, isp_stats->size);
183 ia_css_translate_dvs2_statistics(host_stats, map);
184 ia_css_isp_dvs_statistics_map_free(map);
185 } else
186 {
187 IA_CSS_ERROR("out of memory");
188 ret = -ENOMEM;
189 }
190
191 IA_CSS_LEAVE_ERR(ret);
192 return ret;
193 }
194
195 void
ia_css_translate_dvs2_statistics(struct ia_css_dvs2_statistics * host_stats,const struct ia_css_isp_dvs_statistics_map * isp_stats)196 ia_css_translate_dvs2_statistics(
197 struct ia_css_dvs2_statistics *host_stats,
198 const struct ia_css_isp_dvs_statistics_map *isp_stats)
199 {
200 unsigned int size_bytes, table_width, table_size, height;
201 unsigned int src_offset = 0, dst_offset = 0;
202 s32 *htemp_ptr, *vtemp_ptr;
203
204 assert(host_stats);
205 assert(host_stats->hor_prod.odd_real);
206 assert(host_stats->hor_prod.odd_imag);
207 assert(host_stats->hor_prod.even_real);
208 assert(host_stats->hor_prod.even_imag);
209 assert(host_stats->ver_prod.odd_real);
210 assert(host_stats->ver_prod.odd_imag);
211 assert(host_stats->ver_prod.even_real);
212 assert(host_stats->ver_prod.even_imag);
213 assert(isp_stats);
214 assert(isp_stats->hor_proj);
215 assert(isp_stats->ver_proj);
216
217 IA_CSS_ENTER("hor_coefs.odd_real=%p, hor_coefs.odd_imag=%p, hor_coefs.even_real=%p, hor_coefs.even_imag=%p, ver_coefs.odd_real=%p, ver_coefs.odd_imag=%p, ver_coefs.even_real=%p, ver_coefs.even_imag=%p, haddr=%p, vaddr=%p",
218 host_stats->hor_prod.odd_real, host_stats->hor_prod.odd_imag,
219 host_stats->hor_prod.even_real, host_stats->hor_prod.even_imag,
220 host_stats->ver_prod.odd_real, host_stats->ver_prod.odd_imag,
221 host_stats->ver_prod.even_real, host_stats->ver_prod.even_imag,
222 isp_stats->hor_proj, isp_stats->ver_proj);
223
224 /* Host side: reflecting the true width in bytes */
225 size_bytes = host_stats->grid.aligned_width * sizeof(*htemp_ptr);
226
227 /* DDR side: need to be aligned to the system bus width */
228 /* statistics table width in terms of 32-bit words*/
229 table_width = CEIL_MUL(size_bytes,
230 HIVE_ISP_DDR_WORD_BYTES) / sizeof(*htemp_ptr);
231 table_size = table_width * host_stats->grid.aligned_height;
232
233 htemp_ptr = isp_stats->hor_proj; /* horizontal stats */
234 vtemp_ptr = isp_stats->ver_proj; /* vertical stats */
235 for (height = 0; height < host_stats->grid.aligned_height; height++) {
236 /* hor stats */
237 memcpy(host_stats->hor_prod.odd_real + dst_offset,
238 &htemp_ptr[0 * table_size + src_offset], size_bytes);
239 memcpy(host_stats->hor_prod.odd_imag + dst_offset,
240 &htemp_ptr[1 * table_size + src_offset], size_bytes);
241 memcpy(host_stats->hor_prod.even_real + dst_offset,
242 &htemp_ptr[2 * table_size + src_offset], size_bytes);
243 memcpy(host_stats->hor_prod.even_imag + dst_offset,
244 &htemp_ptr[3 * table_size + src_offset], size_bytes);
245
246 /* ver stats */
247 memcpy(host_stats->ver_prod.odd_real + dst_offset,
248 &vtemp_ptr[0 * table_size + src_offset], size_bytes);
249 memcpy(host_stats->ver_prod.odd_imag + dst_offset,
250 &vtemp_ptr[1 * table_size + src_offset], size_bytes);
251 memcpy(host_stats->ver_prod.even_real + dst_offset,
252 &vtemp_ptr[2 * table_size + src_offset], size_bytes);
253 memcpy(host_stats->ver_prod.even_imag + dst_offset,
254 &vtemp_ptr[3 * table_size + src_offset], size_bytes);
255
256 src_offset += table_width; /* aligned table width */
257 dst_offset += host_stats->grid.aligned_width;
258 }
259
260 IA_CSS_LEAVE("void");
261 }
262
263 struct ia_css_isp_dvs_statistics *
ia_css_isp_dvs2_statistics_allocate(const struct ia_css_dvs_grid_info * grid)264 ia_css_isp_dvs2_statistics_allocate(
265 const struct ia_css_dvs_grid_info *grid)
266 {
267 struct ia_css_isp_dvs_statistics *me;
268 int size;
269
270 assert(grid);
271
272 IA_CSS_ENTER("grid=%p", grid);
273
274 if (!grid->enable)
275 return NULL;
276
277 me = kvcalloc(1, sizeof(*me), GFP_KERNEL);
278 if (!me)
279 goto err;
280
281 /* on ISP 2 SDIS DMA model, every row of projection table width must be
282 aligned to HIVE_ISP_DDR_WORD_BYTES
283 */
284 size = CEIL_MUL(sizeof(int) * grid->aligned_width, HIVE_ISP_DDR_WORD_BYTES)
285 * grid->aligned_height * IA_CSS_DVS2_NUM_COEF_TYPES;
286
287 me->size = 2 * size;
288 me->data_ptr = hmm_alloc(me->size);
289 if (me->data_ptr == mmgr_NULL)
290 goto err;
291 me->hor_proj = me->data_ptr;
292 me->hor_size = size;
293 me->ver_proj = me->data_ptr + size;
294 me->ver_size = size;
295
296 IA_CSS_LEAVE("return=%p", me);
297 return me;
298 err:
299 ia_css_isp_dvs2_statistics_free(me);
300 IA_CSS_LEAVE("return=%p", NULL);
301
302 return NULL;
303 }
304
305 void
ia_css_isp_dvs2_statistics_free(struct ia_css_isp_dvs_statistics * me)306 ia_css_isp_dvs2_statistics_free(struct ia_css_isp_dvs_statistics *me)
307 {
308 if (me) {
309 hmm_free(me->data_ptr);
310 kvfree(me);
311 }
312 }
313
ia_css_sdis2_horicoef_debug_dtrace(const struct ia_css_dvs2_coefficients * config,unsigned int level)314 void ia_css_sdis2_horicoef_debug_dtrace(
315 const struct ia_css_dvs2_coefficients *config, unsigned int level)
316 {
317 (void)config;
318 (void)level;
319 }
320
ia_css_sdis2_vertcoef_debug_dtrace(const struct ia_css_dvs2_coefficients * config,unsigned int level)321 void ia_css_sdis2_vertcoef_debug_dtrace(
322 const struct ia_css_dvs2_coefficients *config, unsigned int level)
323 {
324 (void)config;
325 (void)level;
326 }
327
ia_css_sdis2_horiproj_debug_dtrace(const struct ia_css_dvs2_coefficients * config,unsigned int level)328 void ia_css_sdis2_horiproj_debug_dtrace(
329 const struct ia_css_dvs2_coefficients *config, unsigned int level)
330 {
331 (void)config;
332 (void)level;
333 }
334
ia_css_sdis2_vertproj_debug_dtrace(const struct ia_css_dvs2_coefficients * config,unsigned int level)335 void ia_css_sdis2_vertproj_debug_dtrace(
336 const struct ia_css_dvs2_coefficients *config, unsigned int level)
337 {
338 (void)config;
339 (void)level;
340 }
341