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)