2 * Support for Intel Camera Imaging ISP subsystem.
3 * Copyright (c) 2015, Intel Corporation.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 #include "memory_access.h"
16 #include "assert_support.h"
17 #include "ia_css_debug.h"
18 #include "ia_css_sdis_types.h"
19 #include "sdis/common/ia_css_sdis_common.host.h"
20 #include "ia_css_sdis.host.h"
22 const struct ia_css_dvs_coefficients default_sdis_config
= {
23 .grid
= { 0, 0, 0, 0, 0, 0, 0, 0 },
29 fill_row(short *private, const short *public, unsigned width
, unsigned padding
)
31 assert((int)width
>= 0);
32 assert((int)padding
>= 0);
33 memcpy (private, public, width
*sizeof(short));
34 memset (&private[width
], 0, padding
*sizeof(short));
37 void ia_css_sdis_horicoef_vmem_encode (
38 struct sh_css_isp_sdis_hori_coef_tbl
*to
,
39 const struct ia_css_dvs_coefficients
*from
,
42 unsigned aligned_width
= from
->grid
.aligned_width
* from
->grid
.bqs_per_grid_cell
;
43 unsigned width
= from
->grid
.num_hor_coefs
;
44 int padding
= aligned_width
-width
;
45 unsigned stride
= size
/IA_CSS_DVS_NUM_COEF_TYPES
/sizeof(short);
46 unsigned total_bytes
= aligned_width
*IA_CSS_DVS_NUM_COEF_TYPES
*sizeof(short);
47 short *public = from
->hor_coefs
;
48 short *private = (short*)to
;
51 /* Copy the table, add padding */
53 assert(total_bytes
<= size
);
54 assert(size
% (IA_CSS_DVS_NUM_COEF_TYPES
*ISP_VEC_NELEMS
*sizeof(short)) == 0);
56 for (type
= 0; type
< IA_CSS_DVS_NUM_COEF_TYPES
; type
++) {
57 fill_row(&private[type
*stride
], &public[type
*width
], width
, padding
);
61 void ia_css_sdis_vertcoef_vmem_encode (
62 struct sh_css_isp_sdis_vert_coef_tbl
*to
,
63 const struct ia_css_dvs_coefficients
*from
,
66 unsigned aligned_height
= from
->grid
.aligned_height
* from
->grid
.bqs_per_grid_cell
;
67 unsigned height
= from
->grid
.num_ver_coefs
;
68 int padding
= aligned_height
-height
;
69 unsigned stride
= size
/IA_CSS_DVS_NUM_COEF_TYPES
/sizeof(short);
70 unsigned total_bytes
= aligned_height
*IA_CSS_DVS_NUM_COEF_TYPES
*sizeof(short);
71 short *public = from
->ver_coefs
;
72 short *private = (short*)to
;
75 /* Copy the table, add padding */
77 assert(total_bytes
<= size
);
78 assert(size
% (IA_CSS_DVS_NUM_COEF_TYPES
*ISP_VEC_NELEMS
*sizeof(short)) == 0);
80 for (type
= 0; type
< IA_CSS_DVS_NUM_COEF_TYPES
; type
++) {
81 fill_row(&private[type
*stride
], &public[type
*height
], height
, padding
);
85 void ia_css_sdis_horiproj_encode (
86 struct sh_css_isp_sdis_hori_proj_tbl
*to
,
87 const struct ia_css_dvs_coefficients
*from
,
95 void ia_css_sdis_vertproj_encode (
96 struct sh_css_isp_sdis_vert_proj_tbl
*to
,
97 const struct ia_css_dvs_coefficients
*from
,
105 void ia_css_get_isp_dis_coefficients(
106 struct ia_css_stream
*stream
,
107 short *horizontal_coefficients
,
108 short *vertical_coefficients
)
110 struct ia_css_isp_parameters
*params
;
111 unsigned int hor_num_isp
, ver_num_isp
;
112 unsigned int hor_num_3a
, ver_num_3a
;
114 struct ia_css_binary
*dvs_binary
;
116 IA_CSS_ENTER("void");
118 assert(horizontal_coefficients
!= NULL
);
119 assert(vertical_coefficients
!= NULL
);
121 params
= stream
->isp_params_configs
;
123 /* Only video pipe supports DVS */
124 dvs_binary
= ia_css_stream_get_dvs_binary(stream
);
128 hor_num_isp
= dvs_binary
->dis
.coef
.pad
.width
;
129 ver_num_isp
= dvs_binary
->dis
.coef
.pad
.height
;
130 hor_num_3a
= dvs_binary
->dis
.coef
.dim
.width
;
131 ver_num_3a
= dvs_binary
->dis
.coef
.dim
.height
;
133 for (i
= 0; i
< IA_CSS_DVS_NUM_COEF_TYPES
; i
++) {
134 fill_row(&horizontal_coefficients
[i
*hor_num_isp
],
135 ¶ms
->dvs_coefs
.hor_coefs
[i
*hor_num_3a
], hor_num_3a
, hor_num_isp
-hor_num_3a
);
137 for (i
= 0; i
< SH_CSS_DIS_VER_NUM_COEF_TYPES(dvs_binary
); i
++) {
138 fill_row(&vertical_coefficients
[i
*ver_num_isp
],
139 ¶ms
->dvs_coefs
.ver_coefs
[i
*ver_num_3a
], ver_num_3a
, ver_num_isp
-ver_num_3a
);
142 IA_CSS_LEAVE("void");
146 ia_css_sdis_hor_coef_tbl_bytes(
147 const struct ia_css_binary
*binary
)
149 if (binary
->info
->sp
.pipeline
.isp_pipe_version
== 1)
150 return sizeof(short) * IA_CSS_DVS_NUM_COEF_TYPES
* binary
->dis
.coef
.pad
.width
;
152 return sizeof(short) * IA_CSS_DVS2_NUM_COEF_TYPES
* binary
->dis
.coef
.pad
.width
;
156 ia_css_sdis_ver_coef_tbl_bytes(
157 const struct ia_css_binary
*binary
)
159 return sizeof(short) * SH_CSS_DIS_VER_NUM_COEF_TYPES(binary
) * binary
->dis
.coef
.pad
.height
;
163 ia_css_sdis_init_info(
164 struct ia_css_sdis_info
*dis
,
165 unsigned sc_3a_dis_width
,
166 unsigned sc_3a_dis_padded_width
,
167 unsigned sc_3a_dis_height
,
168 unsigned isp_pipe_version
,
172 struct ia_css_sdis_info default_dis
= IA_CSS_DEFAULT_SDIS_INFO
;
177 dis
->deci_factor_log2
= SH_CSS_DIS_DECI_FACTOR_LOG2
;
179 dis
->grid
.dim
.width
=
180 _ISP_BQS(sc_3a_dis_width
) >> SH_CSS_DIS_DECI_FACTOR_LOG2
;
181 dis
->grid
.dim
.height
=
182 _ISP_BQS(sc_3a_dis_height
) >> SH_CSS_DIS_DECI_FACTOR_LOG2
;
183 dis
->grid
.pad
.width
=
184 CEIL_SHIFT(_ISP_BQS(sc_3a_dis_padded_width
), SH_CSS_DIS_DECI_FACTOR_LOG2
);
185 dis
->grid
.pad
.height
=
186 CEIL_SHIFT(_ISP_BQS(sc_3a_dis_height
), SH_CSS_DIS_DECI_FACTOR_LOG2
);
188 dis
->coef
.dim
.width
=
189 (_ISP_BQS(sc_3a_dis_width
) >> SH_CSS_DIS_DECI_FACTOR_LOG2
) << SH_CSS_DIS_DECI_FACTOR_LOG2
;
190 dis
->coef
.dim
.height
=
191 (_ISP_BQS(sc_3a_dis_height
) >> SH_CSS_DIS_DECI_FACTOR_LOG2
) << SH_CSS_DIS_DECI_FACTOR_LOG2
;
192 dis
->coef
.pad
.width
=
193 __ISP_SDIS_HOR_COEF_NUM_VECS(sc_3a_dis_padded_width
) * ISP_VEC_NELEMS
;
194 dis
->coef
.pad
.height
=
195 __ISP_SDIS_VER_COEF_NUM_VECS(sc_3a_dis_height
) * ISP_VEC_NELEMS
;
196 if (isp_pipe_version
== 1) {
197 dis
->proj
.dim
.width
=
198 _ISP_BQS(sc_3a_dis_height
) >> SH_CSS_DIS_DECI_FACTOR_LOG2
;
199 dis
->proj
.dim
.height
=
200 _ISP_BQS(sc_3a_dis_width
) >> SH_CSS_DIS_DECI_FACTOR_LOG2
;
202 dis
->proj
.dim
.width
=
203 (_ISP_BQS(sc_3a_dis_width
) >> SH_CSS_DIS_DECI_FACTOR_LOG2
) *
204 (_ISP_BQS(sc_3a_dis_height
) >> SH_CSS_DIS_DECI_FACTOR_LOG2
);
205 dis
->proj
.dim
.height
=
206 (_ISP_BQS(sc_3a_dis_width
) >> SH_CSS_DIS_DECI_FACTOR_LOG2
) *
207 (_ISP_BQS(sc_3a_dis_height
) >> SH_CSS_DIS_DECI_FACTOR_LOG2
);
209 dis
->proj
.pad
.width
=
210 __ISP_SDIS_HOR_PROJ_NUM_ISP(sc_3a_dis_padded_width
,
212 SH_CSS_DIS_DECI_FACTOR_LOG2
,
214 dis
->proj
.pad
.height
=
215 __ISP_SDIS_VER_PROJ_NUM_ISP(sc_3a_dis_padded_width
,
216 SH_CSS_DIS_DECI_FACTOR_LOG2
);
219 void ia_css_sdis_clear_coefficients(
220 struct ia_css_dvs_coefficients
*dvs_coefs
)
222 dvs_coefs
->hor_coefs
= NULL
;
223 dvs_coefs
->ver_coefs
= NULL
;
227 ia_css_get_dvs_statistics(
228 struct ia_css_dvs_statistics
*host_stats
,
229 const struct ia_css_isp_dvs_statistics
*isp_stats
)
231 struct ia_css_isp_dvs_statistics_map
*map
;
232 enum ia_css_err ret
= IA_CSS_SUCCESS
;
234 IA_CSS_ENTER("host_stats=%p, isp_stats=%p", host_stats
, isp_stats
);
236 assert(host_stats
!= NULL
);
237 assert(isp_stats
!= NULL
);
239 map
= ia_css_isp_dvs_statistics_map_allocate(isp_stats
, NULL
);
241 mmgr_load(isp_stats
->data_ptr
, map
->data_ptr
, isp_stats
->size
);
242 ia_css_translate_dvs_statistics(host_stats
, map
);
243 ia_css_isp_dvs_statistics_map_free(map
);
245 IA_CSS_ERROR("out of memory");
246 ret
= IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY
;
249 IA_CSS_LEAVE_ERR(ret
);
254 ia_css_translate_dvs_statistics(
255 struct ia_css_dvs_statistics
*host_stats
,
256 const struct ia_css_isp_dvs_statistics_map
*isp_stats
)
258 unsigned int hor_num_isp
, ver_num_isp
, hor_num_dvs
, ver_num_dvs
, i
;
259 int32_t *hor_ptr_dvs
, *ver_ptr_dvs
, *hor_ptr_isp
, *ver_ptr_isp
;
261 assert(host_stats
!= NULL
);
262 assert(host_stats
->hor_proj
!= NULL
);
263 assert(host_stats
->ver_proj
!= NULL
);
264 assert(isp_stats
!= NULL
);
265 assert(isp_stats
->hor_proj
!= NULL
);
266 assert(isp_stats
->ver_proj
!= NULL
);
268 IA_CSS_ENTER("hproj=%p, vproj=%p, haddr=%p, vaddr=%p",
269 host_stats
->hor_proj
, host_stats
->ver_proj
,
270 isp_stats
->hor_proj
, isp_stats
->ver_proj
);
272 hor_num_isp
= host_stats
->grid
.aligned_height
;
273 ver_num_isp
= host_stats
->grid
.aligned_width
;
274 hor_ptr_isp
= isp_stats
->hor_proj
;
275 ver_ptr_isp
= isp_stats
->ver_proj
;
276 hor_num_dvs
= host_stats
->grid
.height
;
277 ver_num_dvs
= host_stats
->grid
.width
;
278 hor_ptr_dvs
= host_stats
->hor_proj
;
279 ver_ptr_dvs
= host_stats
->ver_proj
;
281 for (i
= 0; i
< IA_CSS_DVS_NUM_COEF_TYPES
; i
++) {
282 memcpy(hor_ptr_dvs
, hor_ptr_isp
, hor_num_dvs
* sizeof(int32_t));
283 hor_ptr_isp
+= hor_num_isp
;
284 hor_ptr_dvs
+= hor_num_dvs
;
286 memcpy(ver_ptr_dvs
, ver_ptr_isp
, ver_num_dvs
* sizeof(int32_t));
287 ver_ptr_isp
+= ver_num_isp
;
288 ver_ptr_dvs
+= ver_num_dvs
;
291 IA_CSS_LEAVE("void");
294 struct ia_css_isp_dvs_statistics
*
295 ia_css_isp_dvs_statistics_allocate(
296 const struct ia_css_dvs_grid_info
*grid
)
298 struct ia_css_isp_dvs_statistics
*me
;
299 int hor_size
, ver_size
;
301 assert(grid
!= NULL
);
303 IA_CSS_ENTER("grid=%p", grid
);
308 me
= sh_css_calloc(1,sizeof(*me
));
312 hor_size
= CEIL_MUL(sizeof(int) * IA_CSS_DVS_NUM_COEF_TYPES
* grid
->aligned_height
,
313 HIVE_ISP_DDR_WORD_BYTES
);
314 ver_size
= CEIL_MUL(sizeof(int) * IA_CSS_DVS_NUM_COEF_TYPES
* grid
->aligned_width
,
315 HIVE_ISP_DDR_WORD_BYTES
);
318 me
->size
= hor_size
+ ver_size
;
319 me
->data_ptr
= mmgr_malloc(me
->size
);
320 if (me
->data_ptr
== mmgr_NULL
)
322 me
->hor_size
= hor_size
;
323 me
->hor_proj
= me
->data_ptr
;
324 me
->ver_size
= ver_size
;
325 me
->ver_proj
= me
->data_ptr
+ hor_size
;
327 IA_CSS_LEAVE("return=%p", me
);
331 ia_css_isp_dvs_statistics_free(me
);
333 IA_CSS_LEAVE("return=%p", NULL
);
338 struct ia_css_isp_dvs_statistics_map
*
339 ia_css_isp_dvs_statistics_map_allocate(
340 const struct ia_css_isp_dvs_statistics
*isp_stats
,
343 struct ia_css_isp_dvs_statistics_map
*me
;
344 /* Windows compiler does not like adding sizes to a void *
345 * so we use a local char * instead. */
348 me
= sh_css_malloc(sizeof(*me
));
350 IA_CSS_LOG("cannot allocate memory");
354 me
->data_ptr
= data_ptr
;
355 me
->data_allocated
= data_ptr
== NULL
;
358 me
->data_ptr
= sh_css_malloc(isp_stats
->size
);
360 IA_CSS_LOG("cannot allocate memory");
364 base_ptr
= me
->data_ptr
;
366 me
->size
= isp_stats
->size
;
367 /* GCC complains when we assign a char * to a void *, so these
368 * casts are necessary unfortunately. */
369 me
->hor_proj
= (void*)base_ptr
;
370 me
->ver_proj
= (void*)(base_ptr
+ isp_stats
->hor_size
);
380 ia_css_isp_dvs_statistics_map_free(struct ia_css_isp_dvs_statistics_map
*me
)
383 if (me
->data_allocated
)
384 sh_css_free(me
->data_ptr
);
390 ia_css_isp_dvs_statistics_free(struct ia_css_isp_dvs_statistics
*me
)
393 hmm_free(me
->data_ptr
);
398 void ia_css_sdis_horicoef_debug_dtrace(
399 const struct ia_css_dvs_coefficients
*config
, unsigned level
)
405 void ia_css_sdis_vertcoef_debug_dtrace(
406 const struct ia_css_dvs_coefficients
*config
, unsigned level
)
412 void ia_css_sdis_horiproj_debug_dtrace(
413 const struct ia_css_dvs_coefficients
*config
, unsigned level
)
419 void ia_css_sdis_vertproj_debug_dtrace(
420 const struct ia_css_dvs_coefficients
*config
, unsigned level
)