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 <math_support.h>
16 #include <gdc_device.h> /* HR_GDC_N */
17 #include "isp.h" /* ISP_VEC_NELEMS */
19 #include "ia_css_binary.h"
20 #include "ia_css_debug.h"
21 #include "ia_css_util.h"
22 #include "ia_css_isp_param.h"
23 #include "sh_css_internal.h"
24 #include "sh_css_sp.h"
25 #include "sh_css_firmware.h"
26 #include "sh_css_defs.h"
27 #include "sh_css_legacy.h"
29 #include "vf/vf_1.0/ia_css_vf.host.h"
31 #include "sc/sc_1.0/ia_css_sc.host.h"
33 #include "sdis/sdis_1.0/ia_css_sdis.host.h"
35 #include "fixedbds/fixedbds_1.0/ia_css_fixedbds_param.h" /* FRAC_ACC */
38 #include "camera/pipe/interface/ia_css_pipe_binarydesc.h"
40 #include "memory_access.h"
42 #include "assert_support.h"
44 #define IMPLIES(a, b) (!(a) || (b)) /* A => B */
46 static struct ia_css_binary_xinfo *all_binaries; /* ISP binaries only (no SP) */
47 static struct ia_css_binary_xinfo
48 *binary_infos[IA_CSS_BINARY_NUM_MODES] = { NULL, };
51 ia_css_binary_dvs_env(const struct ia_css_binary_info *info,
52 const struct ia_css_resolution *dvs_env,
53 struct ia_css_resolution *binary_dvs_env)
55 if (info->enable.dvs_envelope) {
56 assert(dvs_env != NULL);
57 binary_dvs_env->width = max(dvs_env->width, SH_CSS_MIN_DVS_ENVELOPE);
58 binary_dvs_env->height = max(dvs_env->height, SH_CSS_MIN_DVS_ENVELOPE);
63 ia_css_binary_internal_res(const struct ia_css_frame_info *in_info,
64 const struct ia_css_frame_info *bds_out_info,
65 const struct ia_css_frame_info *out_info,
66 const struct ia_css_resolution *dvs_env,
67 const struct ia_css_binary_info *info,
68 struct ia_css_resolution *internal_res)
70 unsigned int isp_tmp_internal_width = 0,
71 isp_tmp_internal_height = 0;
72 bool binary_supports_yuv_ds = info->enable.ds & 2;
73 struct ia_css_resolution binary_dvs_env;
75 binary_dvs_env.width = 0;
76 binary_dvs_env.height = 0;
77 ia_css_binary_dvs_env(info, dvs_env, &binary_dvs_env);
79 if (binary_supports_yuv_ds) {
80 if (in_info != NULL) {
81 isp_tmp_internal_width = in_info->res.width
82 + info->pipeline.left_cropping + binary_dvs_env.width;
83 isp_tmp_internal_height = in_info->res.height
84 + info->pipeline.top_cropping + binary_dvs_env.height;
86 } else if ((bds_out_info != NULL) && (out_info != NULL) &&
87 /* TODO: hack to make video_us case work. this should be reverted after
88 a nice solution in ISP */
89 (bds_out_info->res.width >= out_info->res.width)) {
90 isp_tmp_internal_width = bds_out_info->padded_width;
91 isp_tmp_internal_height = bds_out_info->res.height;
93 if (out_info != NULL) {
94 isp_tmp_internal_width = out_info->padded_width;
95 isp_tmp_internal_height = out_info->res.height;
99 /* We first calculate the resolutions used by the ISP. After that,
100 * we use those resolutions to compute sizes for tables etc. */
101 internal_res->width = __ISP_INTERNAL_WIDTH(isp_tmp_internal_width,
102 (int)binary_dvs_env.width,
103 info->pipeline.left_cropping, info->pipeline.mode,
104 info->pipeline.c_subsampling,
105 info->output.num_chunks, info->pipeline.pipelining);
106 internal_res->height = __ISP_INTERNAL_HEIGHT(isp_tmp_internal_height,
107 info->pipeline.top_cropping,
108 binary_dvs_env.height);
112 /* Computation results of the origin coordinate of bayer on the shading table. */
113 struct sh_css_shading_table_bayer_origin_compute_results {
114 uint32_t bayer_scale_hor_ratio_in; /* Horizontal ratio (in) of bayer scaling. */
115 uint32_t bayer_scale_hor_ratio_out; /* Horizontal ratio (out) of bayer scaling. */
116 uint32_t bayer_scale_ver_ratio_in; /* Vertical ratio (in) of bayer scaling. */
117 uint32_t bayer_scale_ver_ratio_out; /* Vertical ratio (out) of bayer scaling. */
118 uint32_t sc_bayer_origin_x_bqs_on_shading_table; /* X coordinate (in bqs) of bayer origin on shading table. */
119 uint32_t sc_bayer_origin_y_bqs_on_shading_table; /* Y coordinate (in bqs) of bayer origin on shading table. */
121 /* Requirements for the shading correction. */
122 struct sh_css_binary_sc_requirements {
123 /* Bayer scaling factor, for the scaling which is applied before shading correction. */
124 uint32_t bayer_scale_hor_ratio_in; /* Horizontal ratio (in) of scaling applied BEFORE shading correction. */
125 uint32_t bayer_scale_hor_ratio_out; /* Horizontal ratio (out) of scaling applied BEFORE shading correction. */
126 uint32_t bayer_scale_ver_ratio_in; /* Vertical ratio (in) of scaling applied BEFORE shading correction. */
127 uint32_t bayer_scale_ver_ratio_out; /* Vertical ratio (out) of scaling applied BEFORE shading correction. */
129 /* ISP internal frame is composed of the real sensor data and the padding data. */
130 uint32_t sensor_data_origin_x_bqs_on_internal; /* X origin (in bqs) of sensor data on internal frame
131 at shading correction. */
132 uint32_t sensor_data_origin_y_bqs_on_internal; /* Y origin (in bqs) of sensor data on internal frame
133 at shading correction. */
137 /* Get the requirements for the shading correction. */
138 static enum ia_css_err
140 ia_css_binary_compute_shading_table_bayer_origin(
141 const struct ia_css_binary *binary, /* [in] */
142 unsigned int required_bds_factor, /* [in] */
143 const struct ia_css_stream_config *stream_config, /* [in] */
144 struct sh_css_shading_table_bayer_origin_compute_results *res) /* [out] */
146 sh_css_binary_get_sc_requirements(
147 const struct ia_css_binary *binary, /* [in] */
148 unsigned int required_bds_factor, /* [in] */
149 const struct ia_css_stream_config *stream_config, /* [in] */
150 struct sh_css_binary_sc_requirements *scr) /* [out] */
156 /* Numerator and denominator of the fixed bayer downscaling factor.
157 (numerator >= denominator) */
159 /* Numerator and denominator of the fixed bayer downscaling factor. (numerator >= denominator) */
161 unsigned int bds_num, bds_den;
164 /* Horizontal/Vertical ratio of bayer scaling
165 between input area and output area. */
166 unsigned int bs_hor_ratio_in;
167 unsigned int bs_hor_ratio_out;
168 unsigned int bs_ver_ratio_in;
169 unsigned int bs_ver_ratio_out;
171 /* Horizontal/Vertical ratio of bayer scaling between input area and output area. */
172 unsigned int bs_hor_ratio_in, bs_hor_ratio_out, bs_ver_ratio_in, bs_ver_ratio_out;
175 /* Left padding set by InputFormatter. */
177 unsigned int left_padding_bqs; /* in bqs */
179 unsigned int left_padding_bqs;
183 /* Flag for the NEED_BDS_FACTOR_2_00 macro defined in isp kernels. */
184 unsigned int need_bds_factor_2_00;
186 /* Left padding adjusted inside the isp. */
187 unsigned int left_padding_adjusted_bqs; /* in bqs */
189 /* Bad pixels caused by filters.
190 NxN-filter (before/after bayer scaling) moves the image position
191 to right/bottom directions by a few pixels.
192 It causes bad pixels at left/top sides,
193 and effective bayer size decreases. */
194 unsigned int bad_bqs_on_left_before_bs; /* in bqs */
195 unsigned int bad_bqs_on_left_after_bs; /* in bqs */
196 unsigned int bad_bqs_on_top_before_bs; /* in bqs */
197 unsigned int bad_bqs_on_top_after_bs; /* in bqs */
199 /* Get the numerator and denominator of bayer downscaling factor. */
200 err = sh_css_bds_factor_get_numerator_denominator
201 (required_bds_factor, &bds_num, &bds_den);
202 if (err != IA_CSS_SUCCESS)
204 /* Flags corresponding to NEED_BDS_FACTOR_2_00/NEED_BDS_FACTOR_1_50/NEED_BDS_FACTOR_1_25 macros
205 * defined in isp kernels. */
206 unsigned int need_bds_factor_2_00, need_bds_factor_1_50, need_bds_factor_1_25;
208 /* Left padding adjusted inside the isp kernels. */
209 unsigned int left_padding_adjusted_bqs;
211 /* Top padding padded inside the isp kernel for bayer downscaling binaries. */
212 unsigned int top_padding_bqs;
214 /* Bayer downscaling factor 1.0 by fixed-point. */
215 int bds_frac_acc = FRAC_ACC; /* FRAC_ACC is defined in ia_css_fixedbds_param.h. */
217 /* Right/Down shift amount caused by filters applied BEFORE shading corrertion. */
218 unsigned int right_shift_bqs_before_bs; /* right shift before bayer scaling */
219 unsigned int right_shift_bqs_after_bs; /* right shift after bayer scaling */
220 unsigned int down_shift_bqs_before_bs; /* down shift before bayer scaling */
221 unsigned int down_shift_bqs_after_bs; /* down shift after bayer scaling */
223 /* Origin of the real sensor data area on the internal frame at shading correction. */
224 unsigned int sensor_data_origin_x_bqs_on_internal;
225 unsigned int sensor_data_origin_y_bqs_on_internal;
227 IA_CSS_ENTER_PRIVATE("binary=%p, required_bds_factor=%d, stream_config=%p",
228 binary, required_bds_factor, stream_config);
230 /* Get the numerator and denominator of the required bayer downscaling factor. */
231 err = sh_css_bds_factor_get_numerator_denominator(required_bds_factor, &bds_num, &bds_den);
232 if (err != IA_CSS_SUCCESS) {
233 IA_CSS_LEAVE_ERR_PRIVATE(err);
241 /* Set the horizontal/vertical ratio of bayer scaling
242 between input area and output area. */
244 IA_CSS_LOG("bds_num=%d, bds_den=%d", bds_num, bds_den);
246 /* Set the horizontal/vertical ratio of bayer scaling between input area and output area. */
248 bs_hor_ratio_in = bds_num;
249 bs_hor_ratio_out = bds_den;
250 bs_ver_ratio_in = bds_num;
251 bs_ver_ratio_out = bds_den;
254 /* Set the left padding set by InputFormatter. (ifmtr.c) */
256 /* Set the left padding set by InputFormatter. (ia_css_ifmtr_configure() in ifmtr.c) */
258 if (stream_config->left_padding == -1)
259 left_padding_bqs = _ISP_BQS(binary->left_padding);
262 left_padding_bqs = (unsigned int)((int)ISP_VEC_NELEMS
263 - _ISP_BQS(stream_config->left_padding));
265 left_padding_bqs = (unsigned int)((int)ISP_VEC_NELEMS - _ISP_BQS(stream_config->left_padding));
269 /* Set the left padding adjusted inside the isp.
270 When bds_factor 2.00 is needed, some padding is added to left_padding
271 inside the isp, before bayer downscaling. (raw.isp.c)
272 (Hopefully, left_crop/left_padding/top_crop should be defined in css
273 appropriately, depending on bds_factor.)
276 IA_CSS_LOG("stream.left_padding=%d, binary.left_padding=%d, left_padding_bqs=%d",
277 stream_config->left_padding, binary->left_padding, left_padding_bqs);
279 /* Set the left padding adjusted inside the isp kernels.
280 * When the bds_factor isn't 1.00, the left padding size is adjusted inside the isp,
281 * before bayer downscaling. (scaled_hor_plane_index(), raw_compute_hphase() in raw.isp.c)
284 need_bds_factor_2_00 = ((binary->info->sp.bds.supported_bds_factors &
285 (PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_2_00) |
286 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_2_50) |
287 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_3_00) |
288 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_4_00) |
289 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_4_50) |
290 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_5_00) |
291 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_6_00) |
292 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_8_00))) != 0);
295 if (need_bds_factor_2_00 && binary->info->sp.pipeline.left_cropping > 0)
296 left_padding_adjusted_bqs = left_padding_bqs + ISP_VEC_NELEMS;
299 need_bds_factor_1_50 = ((binary->info->sp.bds.supported_bds_factors &
300 (PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_1_50) |
301 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_2_25) |
302 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_3_00) |
303 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_4_50) |
304 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_6_00))) != 0);
306 need_bds_factor_1_25 = ((binary->info->sp.bds.supported_bds_factors &
307 (PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_1_25) |
308 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_2_50) |
309 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_5_00))) != 0);
311 if (binary->info->sp.pipeline.left_cropping > 0 &&
312 (need_bds_factor_2_00 || need_bds_factor_1_50 || need_bds_factor_1_25)) {
314 * downscale 2.0 -> first_vec_adjusted_bqs = 128
315 * downscale 1.5 -> first_vec_adjusted_bqs = 96
316 * downscale 1.25 -> first_vec_adjusted_bqs = 80
318 unsigned int first_vec_adjusted_bqs
319 = ISP_VEC_NELEMS * bs_hor_ratio_in / bs_hor_ratio_out;
320 left_padding_adjusted_bqs = first_vec_adjusted_bqs
321 - _ISP_BQS(binary->info->sp.pipeline.left_cropping);
324 left_padding_adjusted_bqs = left_padding_bqs;
327 /* Currently, the bad pixel caused by filters before bayer scaling
328 is NOT considered, because the bad pixel is subtle.
329 When some large filter is used in the future,
330 we need to consider the bad pixel.
332 Currently, when bds_factor isn't 1.00, 3x3 anti-alias filter is applied
333 to each color plane(Gr/R/B/Gb) before bayer downscaling.
334 This filter moves each color plane to right/bottom directions
335 by 1 pixel at the most, depending on downscaling factor.
337 bad_bqs_on_left_before_bs = 0;
338 bad_bqs_on_top_before_bs = 0;
340 IA_CSS_LOG("supported_bds_factors=%d, need_bds_factor:2_00=%d, 1_50=%d, 1_25=%d",
341 binary->info->sp.bds.supported_bds_factors,
342 need_bds_factor_2_00, need_bds_factor_1_50, need_bds_factor_1_25);
343 IA_CSS_LOG("left_cropping=%d, left_padding_adjusted_bqs=%d",
344 binary->info->sp.pipeline.left_cropping, left_padding_adjusted_bqs);
346 /* Set the top padding padded inside the isp kernel for bayer downscaling binaries.
347 * When the bds_factor isn't 1.00, the top padding is padded inside the isp
348 * before bayer downscaling, because the top cropping size (input margin) is not enough.
349 * (calculate_input_line(), raw_compute_vphase(), dma_read_raw() in raw.isp.c)
350 * NOTE: In dma_read_raw(), the factor passed to raw_compute_vphase() is got by get_bds_factor_for_dma_read().
351 * This factor is BDS_FPVAL_100/BDS_FPVAL_125/BDS_FPVAL_150/BDS_FPVAL_200.
354 if (binary->info->sp.pipeline.top_cropping > 0 &&
355 (required_bds_factor == SH_CSS_BDS_FACTOR_1_25 ||
356 required_bds_factor == SH_CSS_BDS_FACTOR_1_50 ||
357 required_bds_factor == SH_CSS_BDS_FACTOR_2_00)) {
358 /* Calculation from calculate_input_line() and raw_compute_vphase() in raw.isp.c. */
359 int top_cropping_bqs = _ISP_BQS(binary->info->sp.pipeline.top_cropping);
360 /* top cropping (in bqs) */
361 int factor = bds_num * bds_frac_acc / bds_den; /* downscaling factor by fixed-point */
362 int top_padding_bqsxfrac_acc = (top_cropping_bqs * factor - top_cropping_bqs * bds_frac_acc)
363 + (2 * bds_frac_acc - factor); /* top padding by fixed-point (in bqs) */
365 top_padding_bqs = (unsigned int)((top_padding_bqsxfrac_acc + bds_frac_acc/2 - 1) / bds_frac_acc);
368 IA_CSS_LOG("top_cropping=%d, top_padding_bqs=%d", binary->info->sp.pipeline.top_cropping, top_padding_bqs);
370 /* Set the right/down shift amount caused by filters applied BEFORE bayer scaling,
371 * which scaling is applied BEFORE shading corrertion.
373 * When the bds_factor isn't 1.00, 3x3 anti-alias filter is applied to each color plane(Gr/R/B/Gb)
374 * before bayer downscaling.
375 * This filter shifts each color plane (Gr/R/B/Gb) to right/down directions by 1 pixel.
377 right_shift_bqs_before_bs = 0;
378 down_shift_bqs_before_bs = 0;
382 /* Currently, the bad pixel caused by filters after bayer scaling
383 is NOT considered, because the bad pixel is subtle.
384 When some large filter is used in the future,
385 we need to consider the bad pixel.
387 Currently, when DPC&BNR is processed between bayer scaling and
388 shading correction, DPC&BNR moves each color plane to
389 right/bottom directions by 1 pixel.
391 bad_bqs_on_left_after_bs = 0;
392 bad_bqs_on_top_after_bs = 0;
394 if (need_bds_factor_2_00 || need_bds_factor_1_50 || need_bds_factor_1_25) {
395 right_shift_bqs_before_bs = 1;
396 down_shift_bqs_before_bs = 1;
399 IA_CSS_LOG("right_shift_bqs_before_bs=%d, down_shift_bqs_before_bs=%d",
400 right_shift_bqs_before_bs, down_shift_bqs_before_bs);
402 /* Set the right/down shift amount caused by filters applied AFTER bayer scaling,
403 * which scaling is applied BEFORE shading corrertion.
405 * When DPC&BNR is processed between bayer scaling and shading correction,
406 * DPC&BNR moves each color plane (Gr/R/B/Gb) to right/down directions by 1 pixel.
408 right_shift_bqs_after_bs = 0;
409 down_shift_bqs_after_bs = 0;
413 /* Calculate the origin of bayer (real sensor data area)
414 located on the shading table during the shading correction. */
415 res->sc_bayer_origin_x_bqs_on_shading_table
416 = ((left_padding_adjusted_bqs + bad_bqs_on_left_before_bs)
417 * bs_hor_ratio_out + bs_hor_ratio_in/2) / bs_hor_ratio_in
418 + bad_bqs_on_left_after_bs;
419 /* "+ bs_hor_ratio_in/2": rounding for division by bs_hor_ratio_in */
420 res->sc_bayer_origin_y_bqs_on_shading_table
421 = (bad_bqs_on_top_before_bs
422 * bs_ver_ratio_out + bs_ver_ratio_in/2) / bs_ver_ratio_in
423 + bad_bqs_on_top_after_bs;
424 /* "+ bs_ver_ratio_in/2": rounding for division by bs_ver_ratio_in */
426 res->bayer_scale_hor_ratio_in = (uint32_t)bs_hor_ratio_in;
427 res->bayer_scale_hor_ratio_out = (uint32_t)bs_hor_ratio_out;
428 res->bayer_scale_ver_ratio_in = (uint32_t)bs_ver_ratio_in;
429 res->bayer_scale_ver_ratio_out = (uint32_t)bs_ver_ratio_out;
431 if (binary->info->mem_offsets.offsets.param->dmem.dp.size != 0) { /* if DPC&BNR is enabled in the binary */
432 right_shift_bqs_after_bs = 1;
433 down_shift_bqs_after_bs = 1;
436 IA_CSS_LOG("right_shift_bqs_after_bs=%d, down_shift_bqs_after_bs=%d",
437 right_shift_bqs_after_bs, down_shift_bqs_after_bs);
439 /* Set the origin of the sensor data area on the internal frame at shading correction. */
441 unsigned int bs_frac = bds_frac_acc; /* scaling factor 1.0 in fixed point */
442 unsigned int bs_out, bs_in; /* scaling ratio in fixed point */
444 bs_out = bs_hor_ratio_out * bs_frac;
445 bs_in = bs_hor_ratio_in * bs_frac;
446 sensor_data_origin_x_bqs_on_internal
447 = ((left_padding_adjusted_bqs + right_shift_bqs_before_bs) * bs_out + bs_in/2) / bs_in
448 + right_shift_bqs_after_bs; /* "+ bs_in/2": rounding */
450 bs_out = bs_ver_ratio_out * bs_frac;
451 bs_in = bs_ver_ratio_in * bs_frac;
452 sensor_data_origin_y_bqs_on_internal
453 = ((top_padding_bqs + down_shift_bqs_before_bs) * bs_out + bs_in/2) / bs_in
454 + down_shift_bqs_after_bs; /* "+ bs_in/2": rounding */
457 scr->bayer_scale_hor_ratio_in = (uint32_t)bs_hor_ratio_in;
458 scr->bayer_scale_hor_ratio_out = (uint32_t)bs_hor_ratio_out;
459 scr->bayer_scale_ver_ratio_in = (uint32_t)bs_ver_ratio_in;
460 scr->bayer_scale_ver_ratio_out = (uint32_t)bs_ver_ratio_out;
461 scr->sensor_data_origin_x_bqs_on_internal = (uint32_t)sensor_data_origin_x_bqs_on_internal;
462 scr->sensor_data_origin_y_bqs_on_internal = (uint32_t)sensor_data_origin_y_bqs_on_internal;
464 IA_CSS_LOG("sc_requirements: %d, %d, %d, %d, %d, %d",
465 scr->bayer_scale_hor_ratio_in, scr->bayer_scale_hor_ratio_out,
466 scr->bayer_scale_ver_ratio_in, scr->bayer_scale_ver_ratio_out,
467 scr->sensor_data_origin_x_bqs_on_internal, scr->sensor_data_origin_y_bqs_on_internal);
471 IA_CSS_LEAVE_ERR_PRIVATE(err);
476 /* Get the shading information of Shading Correction Type 1. */
477 static enum ia_css_err
478 ia_css_binary_get_shading_info_type_1(const struct ia_css_binary *binary, /* [in] */
479 unsigned int required_bds_factor, /* [in] */
480 const struct ia_css_stream_config *stream_config, /* [in] */
482 struct ia_css_shading_info *info) /* [out] */
484 struct ia_css_shading_info *shading_info, /* [out] */
485 struct ia_css_pipe_config *pipe_config) /* [out] */
490 struct sh_css_shading_table_bayer_origin_compute_results res;
492 struct sh_css_binary_sc_requirements scr;
493 struct ia_css_shading_info default_shading_info_type_1 = DEFAULT_SHADING_INFO_TYPE_1;
497 assert(binary != NULL);
498 assert(info != NULL);
500 uint32_t in_width_bqs, in_height_bqs, internal_width_bqs, internal_height_bqs;
501 uint32_t num_hor_grids, num_ver_grids, bqs_per_grid_cell, tbl_width_bqs, tbl_height_bqs;
502 uint32_t sensor_org_x_bqs_on_internal, sensor_org_y_bqs_on_internal, sensor_width_bqs, sensor_height_bqs;
503 uint32_t sensor_center_x_bqs_on_internal, sensor_center_y_bqs_on_internal;
504 uint32_t left, right, upper, lower;
505 uint32_t adjust_left, adjust_right, adjust_upper, adjust_lower, adjust_width_bqs, adjust_height_bqs;
506 uint32_t internal_org_x_bqs_on_tbl, internal_org_y_bqs_on_tbl;
507 uint32_t sensor_org_x_bqs_on_tbl, sensor_org_y_bqs_on_tbl;
511 info->type = IA_CSS_SHADING_CORRECTION_TYPE_1;
513 assert(binary != NULL);
514 assert(stream_config != NULL);
515 assert(shading_info != NULL);
516 assert(pipe_config != NULL);
520 info->info.type_1.enable = binary->info->sp.enable.sc;
521 info->info.type_1.num_hor_grids = binary->sctbl_width_per_color;
522 info->info.type_1.num_ver_grids = binary->sctbl_height;
523 info->info.type_1.bqs_per_grid_cell = (1 << binary->deci_factor_log2);
525 IA_CSS_ENTER_PRIVATE("binary=%p, required_bds_factor=%d, stream_config=%p",
526 binary, required_bds_factor, stream_config);
529 /* Initialize by default values. */
531 info->info.type_1.bayer_scale_hor_ratio_in = 1;
532 info->info.type_1.bayer_scale_hor_ratio_out = 1;
533 info->info.type_1.bayer_scale_ver_ratio_in = 1;
534 info->info.type_1.bayer_scale_ver_ratio_out = 1;
535 info->info.type_1.sc_bayer_origin_x_bqs_on_shading_table = 0;
536 info->info.type_1.sc_bayer_origin_y_bqs_on_shading_table = 0;
538 err = ia_css_binary_compute_shading_table_bayer_origin(
543 if (err != IA_CSS_SUCCESS)
545 *shading_info = default_shading_info_type_1;
547 err = sh_css_binary_get_sc_requirements(binary, required_bds_factor, stream_config, &scr);
548 if (err != IA_CSS_SUCCESS) {
549 IA_CSS_LEAVE_ERR_PRIVATE(err);
555 IA_CSS_LOG("binary: id=%d, sctbl=%dx%d, deci=%d",
556 binary->info->sp.id, binary->sctbl_width_per_color, binary->sctbl_height, binary->deci_factor_log2);
557 IA_CSS_LOG("binary: in=%dx%d, in_padded_w=%d, int=%dx%d, int_padded_w=%d, out=%dx%d, out_padded_w=%d",
558 binary->in_frame_info.res.width, binary->in_frame_info.res.height, binary->in_frame_info.padded_width,
559 binary->internal_frame_info.res.width, binary->internal_frame_info.res.height,
560 binary->internal_frame_info.padded_width,
561 binary->out_frame_info[0].res.width, binary->out_frame_info[0].res.height,
562 binary->out_frame_info[0].padded_width);
564 /* Set the input size from sensor, which includes left/top crop size. */
565 in_width_bqs = _ISP_BQS(binary->in_frame_info.res.width);
566 in_height_bqs = _ISP_BQS(binary->in_frame_info.res.height);
568 /* Frame size internally used in ISP, including sensor data and padding.
569 * This is the frame size, to which the shading correction is applied.
571 internal_width_bqs = _ISP_BQS(binary->internal_frame_info.res.width);
572 internal_height_bqs = _ISP_BQS(binary->internal_frame_info.res.height);
575 num_hor_grids = binary->sctbl_width_per_color;
576 num_ver_grids = binary->sctbl_height;
577 bqs_per_grid_cell = (1 << binary->deci_factor_log2);
578 tbl_width_bqs = (num_hor_grids - 1) * bqs_per_grid_cell;
579 tbl_height_bqs = (num_ver_grids - 1) * bqs_per_grid_cell;
583 info->info.type_1.bayer_scale_hor_ratio_in = res.bayer_scale_hor_ratio_in;
584 info->info.type_1.bayer_scale_hor_ratio_out = res.bayer_scale_hor_ratio_out;
585 info->info.type_1.bayer_scale_ver_ratio_in = res.bayer_scale_ver_ratio_in;
586 info->info.type_1.bayer_scale_ver_ratio_out = res.bayer_scale_ver_ratio_out;
587 info->info.type_1.sc_bayer_origin_x_bqs_on_shading_table = res.sc_bayer_origin_x_bqs_on_shading_table;
588 info->info.type_1.sc_bayer_origin_y_bqs_on_shading_table = res.sc_bayer_origin_y_bqs_on_shading_table;
590 IA_CSS_LOG("tbl_width_bqs=%d, tbl_height_bqs=%d", tbl_width_bqs, tbl_height_bqs);
594 /* Real sensor data area on the internal frame at shading correction.
595 * Filters and scaling are applied to the internal frame before shading correction, depending on the binary.
597 sensor_org_x_bqs_on_internal = scr.sensor_data_origin_x_bqs_on_internal;
598 sensor_org_y_bqs_on_internal = scr.sensor_data_origin_y_bqs_on_internal;
600 unsigned int bs_frac = 8; /* scaling factor 1.0 in fixed point (8 == FRAC_ACC macro in ISP) */
601 unsigned int bs_out, bs_in; /* scaling ratio in fixed point */
603 bs_out = scr.bayer_scale_hor_ratio_out * bs_frac;
604 bs_in = scr.bayer_scale_hor_ratio_in * bs_frac;
605 sensor_width_bqs = (in_width_bqs * bs_out + bs_in/2) / bs_in; /* "+ bs_in/2": rounding */
607 bs_out = scr.bayer_scale_ver_ratio_out * bs_frac;
608 bs_in = scr.bayer_scale_ver_ratio_in * bs_frac;
609 sensor_height_bqs = (in_height_bqs * bs_out + bs_in/2) / bs_in; /* "+ bs_in/2": rounding */
612 /* Center of the sensor data on the internal frame at shading correction. */
613 sensor_center_x_bqs_on_internal = sensor_org_x_bqs_on_internal + sensor_width_bqs / 2;
614 sensor_center_y_bqs_on_internal = sensor_org_y_bqs_on_internal + sensor_height_bqs / 2;
616 /* Size of left/right/upper/lower sides of the sensor center on the internal frame. */
617 left = sensor_center_x_bqs_on_internal;
618 right = internal_width_bqs - sensor_center_x_bqs_on_internal;
619 upper = sensor_center_y_bqs_on_internal;
620 lower = internal_height_bqs - sensor_center_y_bqs_on_internal;
622 /* Align the size of left/right/upper/lower sides to a multiple of the grid cell size. */
623 adjust_left = CEIL_MUL(left, bqs_per_grid_cell);
624 adjust_right = CEIL_MUL(right, bqs_per_grid_cell);
625 adjust_upper = CEIL_MUL(upper, bqs_per_grid_cell);
626 adjust_lower = CEIL_MUL(lower, bqs_per_grid_cell);
628 /* Shading table should cover the adjusted frame size. */
629 adjust_width_bqs = adjust_left + adjust_right;
630 adjust_height_bqs = adjust_upper + adjust_lower;
632 IA_CSS_LOG("adjust_width_bqs=%d, adjust_height_bqs=%d", adjust_width_bqs, adjust_height_bqs);
634 if (adjust_width_bqs > tbl_width_bqs || adjust_height_bqs > tbl_height_bqs) {
635 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INTERNAL_ERROR);
636 return IA_CSS_ERR_INTERNAL_ERROR;
639 /* Origin of the internal frame on the shading table. */
640 internal_org_x_bqs_on_tbl = adjust_left - left;
641 internal_org_y_bqs_on_tbl = adjust_upper - upper;
643 /* Origin of the real sensor data area on the shading table. */
644 sensor_org_x_bqs_on_tbl = internal_org_x_bqs_on_tbl + sensor_org_x_bqs_on_internal;
645 sensor_org_y_bqs_on_tbl = internal_org_y_bqs_on_tbl + sensor_org_y_bqs_on_internal;
647 /* The shading information necessary as API is stored in the shading_info. */
648 shading_info->info.type_1.num_hor_grids = num_hor_grids;
649 shading_info->info.type_1.num_ver_grids = num_ver_grids;
650 shading_info->info.type_1.bqs_per_grid_cell = bqs_per_grid_cell;
652 shading_info->info.type_1.bayer_scale_hor_ratio_in = scr.bayer_scale_hor_ratio_in;
653 shading_info->info.type_1.bayer_scale_hor_ratio_out = scr.bayer_scale_hor_ratio_out;
654 shading_info->info.type_1.bayer_scale_ver_ratio_in = scr.bayer_scale_ver_ratio_in;
655 shading_info->info.type_1.bayer_scale_ver_ratio_out = scr.bayer_scale_ver_ratio_out;
657 shading_info->info.type_1.isp_input_sensor_data_res_bqs.width = in_width_bqs;
658 shading_info->info.type_1.isp_input_sensor_data_res_bqs.height = in_height_bqs;
660 shading_info->info.type_1.sensor_data_res_bqs.width = sensor_width_bqs;
661 shading_info->info.type_1.sensor_data_res_bqs.height = sensor_height_bqs;
663 shading_info->info.type_1.sensor_data_origin_bqs_on_sctbl.x = (int32_t)sensor_org_x_bqs_on_tbl;
664 shading_info->info.type_1.sensor_data_origin_bqs_on_sctbl.y = (int32_t)sensor_org_y_bqs_on_tbl;
666 /* The shading information related to ISP (but, not necessary as API) is stored in the pipe_config. */
667 pipe_config->internal_frame_origin_bqs_on_sctbl.x = (int32_t)internal_org_x_bqs_on_tbl;
668 pipe_config->internal_frame_origin_bqs_on_sctbl.y = (int32_t)internal_org_y_bqs_on_tbl;
670 IA_CSS_LOG("shading_info: grids=%dx%d, cell=%d, scale=%d,%d,%d,%d, input=%dx%d, data=%dx%d, origin=(%d,%d)",
671 shading_info->info.type_1.num_hor_grids,
672 shading_info->info.type_1.num_ver_grids,
673 shading_info->info.type_1.bqs_per_grid_cell,
674 shading_info->info.type_1.bayer_scale_hor_ratio_in,
675 shading_info->info.type_1.bayer_scale_hor_ratio_out,
676 shading_info->info.type_1.bayer_scale_ver_ratio_in,
677 shading_info->info.type_1.bayer_scale_ver_ratio_out,
678 shading_info->info.type_1.isp_input_sensor_data_res_bqs.width,
679 shading_info->info.type_1.isp_input_sensor_data_res_bqs.height,
680 shading_info->info.type_1.sensor_data_res_bqs.width,
681 shading_info->info.type_1.sensor_data_res_bqs.height,
682 shading_info->info.type_1.sensor_data_origin_bqs_on_sctbl.x,
683 shading_info->info.type_1.sensor_data_origin_bqs_on_sctbl.y);
685 IA_CSS_LOG("pipe_config: origin=(%d,%d)",
686 pipe_config->internal_frame_origin_bqs_on_sctbl.x,
687 pipe_config->internal_frame_origin_bqs_on_sctbl.y);
689 IA_CSS_LEAVE_ERR_PRIVATE(err);
695 ia_css_binary_get_shading_info(const struct ia_css_binary *binary, /* [in] */
696 enum ia_css_shading_correction_type type, /* [in] */
697 unsigned int required_bds_factor, /* [in] */
698 const struct ia_css_stream_config *stream_config, /* [in] */
700 struct ia_css_shading_info *info) /* [out] */
702 struct ia_css_shading_info *shading_info, /* [out] */
703 struct ia_css_pipe_config *pipe_config) /* [out] */
708 assert(binary != NULL);
710 assert(info != NULL);
712 assert(shading_info != NULL);
714 IA_CSS_ENTER_PRIVATE("binary=%p, type=%d, required_bds_factor=%d, stream_config=%p",
715 binary, type, required_bds_factor, stream_config);
718 if (type == IA_CSS_SHADING_CORRECTION_TYPE_1)
720 err = ia_css_binary_get_shading_info_type_1(binary, required_bds_factor, stream_config, info);
722 err = ia_css_binary_get_shading_info_type_1(binary, required_bds_factor, stream_config,
723 shading_info, pipe_config);
726 /* Other function calls can be added here when other shading correction types will be added in the future. */
729 err = IA_CSS_ERR_NOT_SUPPORTED;
731 IA_CSS_LEAVE_ERR_PRIVATE(err);
735 static void sh_css_binary_common_grid_info(const struct ia_css_binary *binary,
736 struct ia_css_grid_info *info)
738 assert(binary != NULL);
739 assert(info != NULL);
741 info->isp_in_width = binary->internal_frame_info.res.width;
742 info->isp_in_height = binary->internal_frame_info.res.height;
744 info->vamem_type = IA_CSS_VAMEM_TYPE_2;
748 ia_css_binary_dvs_grid_info(const struct ia_css_binary *binary,
749 struct ia_css_grid_info *info,
750 struct ia_css_pipe *pipe)
752 struct ia_css_dvs_grid_info *dvs_info;
755 assert(binary != NULL);
756 assert(info != NULL);
758 dvs_info = &info->dvs_grid.dvs_grid_info;
760 /* for DIS, we use a division instead of a ceil_div. If this is smaller
761 * than the 3a grid size, it indicates that the outer values are not
764 dvs_info->enable = binary->info->sp.enable.dis;
765 dvs_info->width = binary->dis.grid.dim.width;
766 dvs_info->height = binary->dis.grid.dim.height;
767 dvs_info->aligned_width = binary->dis.grid.pad.width;
768 dvs_info->aligned_height = binary->dis.grid.pad.height;
769 dvs_info->bqs_per_grid_cell = 1 << binary->dis.deci_factor_log2;
770 dvs_info->num_hor_coefs = binary->dis.coef.dim.width;
771 dvs_info->num_ver_coefs = binary->dis.coef.dim.height;
773 sh_css_binary_common_grid_info(binary, info);
777 ia_css_binary_dvs_stat_grid_info(
778 const struct ia_css_binary *binary,
779 struct ia_css_grid_info *info,
780 struct ia_css_pipe *pipe)
783 sh_css_binary_common_grid_info(binary, info);
788 ia_css_binary_3a_grid_info(const struct ia_css_binary *binary,
789 struct ia_css_grid_info *info,
790 struct ia_css_pipe *pipe)
792 struct ia_css_3a_grid_info *s3a_info;
793 enum ia_css_err err = IA_CSS_SUCCESS;
795 IA_CSS_ENTER_PRIVATE("binary=%p, info=%p, pipe=%p",
798 assert(binary != NULL);
799 assert(info != NULL);
800 s3a_info = &info->s3a_grid;
803 /* 3A statistics grid */
804 s3a_info->enable = binary->info->sp.enable.s3a;
805 s3a_info->width = binary->s3atbl_width;
806 s3a_info->height = binary->s3atbl_height;
807 s3a_info->aligned_width = binary->s3atbl_isp_width;
808 s3a_info->aligned_height = binary->s3atbl_isp_height;
809 s3a_info->bqs_per_grid_cell = (1 << binary->deci_factor_log2);
810 s3a_info->deci_factor_log2 = binary->deci_factor_log2;
811 s3a_info->elem_bit_depth = SH_CSS_BAYER_BITS;
812 s3a_info->use_dmem = binary->info->sp.s3a.s3atbl_use_dmem;
813 #if defined(HAS_NO_HMEM)
814 s3a_info->has_histogram = 1;
816 s3a_info->has_histogram = 0;
818 IA_CSS_LEAVE_ERR_PRIVATE(err);
823 binary_init_pc_histogram(struct sh_css_pc_histogram *histo)
825 assert(histo != NULL);
833 binary_init_metrics(struct sh_css_binary_metrics *metrics,
834 const struct ia_css_binary_info *info)
836 assert(metrics != NULL);
837 assert(info != NULL);
839 metrics->mode = info->pipeline.mode;
840 metrics->id = info->id;
841 metrics->next = NULL;
842 binary_init_pc_histogram(&metrics->isp_histogram);
843 binary_init_pc_histogram(&metrics->sp_histogram);
846 /* move to host part of output module */
848 binary_supports_output_format(const struct ia_css_binary_xinfo *info,
849 enum ia_css_frame_format format)
853 assert(info != NULL);
855 for (i = 0; i < info->num_output_formats; i++) {
856 if (info->output_formats[i] == format)
864 binary_supports_input_format(const struct ia_css_binary_xinfo *info,
865 enum ia_css_stream_format format)
868 assert(info != NULL);
876 binary_supports_vf_format(const struct ia_css_binary_xinfo *info,
877 enum ia_css_frame_format format)
881 assert(info != NULL);
883 for (i = 0; i < info->num_vf_formats; i++) {
884 if (info->vf_formats[i] == format)
890 /* move to host part of bds module */
892 supports_bds_factor(uint32_t supported_factors,
895 return ((supported_factors & PACK_BDS_FACTOR(bds_factor)) != 0);
898 static enum ia_css_err
899 binary_init_info(struct ia_css_binary_xinfo *info, unsigned int i,
902 const unsigned char *blob = sh_css_blob_info[i].blob;
903 unsigned size = sh_css_blob_info[i].header.blob.size;
905 if ((info == NULL) || (binary_found == NULL))
906 return IA_CSS_ERR_INVALID_ARGUMENTS;
908 *info = sh_css_blob_info[i].header.info.isp;
909 *binary_found = blob != NULL;
910 info->blob_index = i;
911 /* we don't have this binary, skip it */
913 return IA_CSS_SUCCESS;
915 info->xmem_addr = sh_css_load_blob(blob, size);
916 if (!info->xmem_addr)
917 return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
918 return IA_CSS_SUCCESS;
921 /* When binaries are put at the beginning, they will only
922 * be selected if no other primary matches.
925 ia_css_binary_init_infos(void)
928 unsigned int num_of_isp_binaries = sh_css_num_binaries - NUM_OF_SPS - NUM_OF_BLS;
930 if (num_of_isp_binaries == 0)
931 return IA_CSS_SUCCESS;
933 all_binaries = sh_css_malloc(num_of_isp_binaries *
934 sizeof(*all_binaries));
935 if (all_binaries == NULL)
936 return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
938 for (i = 0; i < num_of_isp_binaries; i++) {
940 struct ia_css_binary_xinfo *binary = &all_binaries[i];
943 ret = binary_init_info(binary, i, &binary_found);
944 if (ret != IA_CSS_SUCCESS)
948 /* Prepend new binary information */
949 binary->next = binary_infos[binary->sp.pipeline.mode];
950 binary_infos[binary->sp.pipeline.mode] = binary;
951 binary->blob = &sh_css_blob_info[i];
952 binary->mem_offsets = sh_css_blob_info[i].mem_offsets;
954 return IA_CSS_SUCCESS;
958 ia_css_binary_uninit(void)
961 struct ia_css_binary_xinfo *b;
963 for (i = 0; i < IA_CSS_BINARY_NUM_MODES; i++) {
964 for (b = binary_infos[i]; b; b = b->next) {
966 hmm_free(b->xmem_addr);
967 b->xmem_addr = mmgr_NULL;
969 binary_infos[i] = NULL;
971 sh_css_free(all_binaries);
972 return IA_CSS_SUCCESS;
975 /** @brief Compute decimation factor for 3A statistics and shading correction.
977 * @param[in] width Frame width in pixels.
978 * @param[in] height Frame height in pixels.
979 * @return Log2 of decimation factor (= grid cell size) in bayer quads.
982 binary_grid_deci_factor_log2(int width, int height)
984 /* 3A/Shading decimation factor spcification (at August 2008)
985 * ------------------------------------------------------------------
986 * [Image Width (BQ)] [Decimation Factor (BQ)] [Resulting grid cells]
989 * 640 ?c 1279 16 40 ?c 80
992 * from 1280 32 from 40
993 * from 640 to 1279 16 from 40 to 80
996 * ------------------------------------------------------------------
998 /* Maximum and minimum decimation factor by the specification */
999 #define MAX_SPEC_DECI_FACT_LOG2 5
1000 #define MIN_SPEC_DECI_FACT_LOG2 3
1001 /* the smallest frame width in bayer quads when decimation factor (log2) is 5 or 4, by the specification */
1002 #define DECI_FACT_LOG2_5_SMALLEST_FRAME_WIDTH_BQ 1280
1003 #define DECI_FACT_LOG2_4_SMALLEST_FRAME_WIDTH_BQ 640
1005 int smallest_factor; /* the smallest factor (log2) where the number of cells does not exceed the limitation */
1006 int spec_factor; /* the factor (log2) which satisfies the specification */
1008 /* Currently supported maximum width and height are 5120(=80*64) and 3840(=60*64). */
1009 assert(ISP_BQ_GRID_WIDTH(width, MAX_SPEC_DECI_FACT_LOG2) <= SH_CSS_MAX_BQ_GRID_WIDTH);
1010 assert(ISP_BQ_GRID_HEIGHT(height, MAX_SPEC_DECI_FACT_LOG2) <= SH_CSS_MAX_BQ_GRID_HEIGHT);
1012 /* Compute the smallest factor. */
1013 smallest_factor = MAX_SPEC_DECI_FACT_LOG2;
1014 while (ISP_BQ_GRID_WIDTH(width, smallest_factor - 1) <= SH_CSS_MAX_BQ_GRID_WIDTH &&
1015 ISP_BQ_GRID_HEIGHT(height, smallest_factor - 1) <= SH_CSS_MAX_BQ_GRID_HEIGHT
1016 && smallest_factor > MIN_SPEC_DECI_FACT_LOG2)
1019 /* Get the factor by the specification. */
1020 if (_ISP_BQS(width) >= DECI_FACT_LOG2_5_SMALLEST_FRAME_WIDTH_BQ)
1022 else if (_ISP_BQS(width) >= DECI_FACT_LOG2_4_SMALLEST_FRAME_WIDTH_BQ)
1027 /* If smallest_factor is smaller than or equal to spec_factor, choose spec_factor to follow the specification.
1028 If smallest_factor is larger than spec_factor, choose smallest_factor.
1030 ex. width=2560, height=1920
1031 smallest_factor=4, spec_factor=5
1032 smallest_factor < spec_factor -> return spec_factor
1034 ex. width=300, height=3000
1035 smallest_factor=5, spec_factor=3
1036 smallest_factor > spec_factor -> return smallest_factor
1038 return max(smallest_factor, spec_factor);
1040 #undef MAX_SPEC_DECI_FACT_LOG2
1041 #undef MIN_SPEC_DECI_FACT_LOG2
1042 #undef DECI_FACT_LOG2_5_SMALLEST_FRAME_WIDTH_BQ
1043 #undef DECI_FACT_LOG2_4_SMALLEST_FRAME_WIDTH_BQ
1047 binary_in_frame_padded_width(int in_frame_width,
1048 int isp_internal_width,
1050 int stream_config_left_padding,
1055 int nr_of_left_paddings; /* number of paddings pixels on the left of an image line */
1057 #if defined(USE_INPUT_SYSTEM_VERSION_2401)
1058 /* the output image line of Input System 2401 does not have the left paddings */
1059 nr_of_left_paddings = 0;
1061 /* in other cases, the left padding pixels are always 128 */
1062 nr_of_left_paddings = 2*ISP_VEC_NELEMS;
1065 /* In SDV use-case, we need to match left-padding of
1066 * primary and the video binary. */
1067 if (stream_config_left_padding != -1) {
1068 /* Different than before, we do left&right padding. */
1070 CEIL_MUL(in_frame_width + nr_of_left_paddings,
1073 /* Different than before, we do left&right padding. */
1074 in_frame_width += dvs_env_width;
1076 CEIL_MUL(in_frame_width +
1077 (left_cropping ? nr_of_left_paddings : 0),
1081 rval = isp_internal_width;
1089 ia_css_binary_fill_info(const struct ia_css_binary_xinfo *xinfo,
1092 enum ia_css_stream_format stream_format,
1093 const struct ia_css_frame_info *in_info, /* can be NULL */
1094 const struct ia_css_frame_info *bds_out_info, /* can be NULL */
1095 const struct ia_css_frame_info *out_info[], /* can be NULL */
1096 const struct ia_css_frame_info *vf_info, /* can be NULL */
1097 struct ia_css_binary *binary,
1098 struct ia_css_resolution *dvs_env,
1099 int stream_config_left_padding,
1102 const struct ia_css_binary_info *info = &xinfo->sp;
1103 unsigned int dvs_env_width = 0,
1108 /* Resolution at SC/3A/DIS kernel. */
1109 sc_3a_dis_width = 0,
1110 /* Resolution at SC/3A/DIS kernel. */
1111 sc_3a_dis_padded_width = 0,
1112 /* Resolution at SC/3A/DIS kernel. */
1113 sc_3a_dis_height = 0,
1114 isp_internal_width = 0,
1115 isp_internal_height = 0,
1118 bool need_scaling = false;
1119 struct ia_css_resolution binary_dvs_env, internal_res;
1120 enum ia_css_err err;
1122 const struct ia_css_frame_info *bin_out_info = NULL;
1124 assert(info != NULL);
1125 assert(binary != NULL);
1127 binary->info = xinfo;
1129 /* binary->css_params has been filled by accelerator itself. */
1130 err = ia_css_isp_param_allocate_isp_parameters(
1131 &binary->mem_params, &binary->css_params,
1132 &info->mem_initializers);
1133 if (err != IA_CSS_SUCCESS) {
1137 for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) {
1138 if (out_info[i] && (out_info[i]->res.width != 0)) {
1139 bin_out_info = out_info[i];
1143 if (in_info != NULL && bin_out_info != NULL) {
1144 need_scaling = (in_info->res.width != bin_out_info->res.width) ||
1145 (in_info->res.height != bin_out_info->res.height);
1149 /* binary_dvs_env has to be equal or larger than SH_CSS_MIN_DVS_ENVELOPE */
1150 binary_dvs_env.width = 0;
1151 binary_dvs_env.height = 0;
1152 ia_css_binary_dvs_env(info, dvs_env, &binary_dvs_env);
1153 dvs_env_width = binary_dvs_env.width;
1154 dvs_env_height = binary_dvs_env.height;
1155 binary->dvs_envelope.width = dvs_env_width;
1156 binary->dvs_envelope.height = dvs_env_height;
1158 /* internal resolution calculation */
1159 internal_res.width = 0;
1160 internal_res.height = 0;
1161 ia_css_binary_internal_res(in_info, bds_out_info, bin_out_info, dvs_env,
1162 info, &internal_res);
1163 isp_internal_width = internal_res.width;
1164 isp_internal_height = internal_res.height;
1166 /* internal frame info */
1167 if (bin_out_info != NULL) /* { */
1168 binary->internal_frame_info.format = bin_out_info->format;
1170 binary->internal_frame_info.res.width = isp_internal_width;
1171 binary->internal_frame_info.padded_width = CEIL_MUL(isp_internal_width, 2*ISP_VEC_NELEMS);
1172 binary->internal_frame_info.res.height = isp_internal_height;
1173 binary->internal_frame_info.raw_bit_depth = bits_per_pixel;
1175 if (in_info != NULL) {
1176 binary->effective_in_frame_res.width = in_info->res.width;
1177 binary->effective_in_frame_res.height = in_info->res.height;
1179 bits_per_pixel = in_info->raw_bit_depth;
1182 binary->in_frame_info.res.width = in_info->res.width + info->pipeline.left_cropping;
1183 binary->in_frame_info.res.height = in_info->res.height + info->pipeline.top_cropping;
1185 binary->in_frame_info.res.width += dvs_env_width;
1186 binary->in_frame_info.res.height += dvs_env_height;
1188 binary->in_frame_info.padded_width =
1189 binary_in_frame_padded_width(in_info->res.width,
1192 stream_config_left_padding,
1193 info->pipeline.left_cropping,
1196 binary->in_frame_info.format = in_info->format;
1197 binary->in_frame_info.raw_bayer_order = in_info->raw_bayer_order;
1198 binary->in_frame_info.crop_info = in_info->crop_info;
1202 bits_per_pixel = ia_css_util_input_format_bpp(
1203 stream_format, two_ppc);
1205 binary->in_frame_info.raw_bit_depth = bits_per_pixel;
1207 for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) {
1208 if (out_info[i] != NULL) {
1209 binary->out_frame_info[i].res.width = out_info[i]->res.width;
1210 binary->out_frame_info[i].res.height = out_info[i]->res.height;
1211 binary->out_frame_info[i].padded_width = out_info[i]->padded_width;
1212 if (info->pipeline.mode == IA_CSS_BINARY_MODE_COPY) {
1213 binary->out_frame_info[i].raw_bit_depth = bits_per_pixel;
1215 /* Only relevant for RAW format.
1216 * At the moment, all outputs are raw, 16 bit per pixel, except for copy.
1217 * To do this cleanly, the binary should specify in its info
1218 * the bit depth per output channel.
1220 binary->out_frame_info[i].raw_bit_depth = 16;
1222 binary->out_frame_info[i].format = out_info[i]->format;
1226 if (vf_info && (vf_info->res.width != 0)) {
1227 err = ia_css_vf_configure(binary, bin_out_info, (struct ia_css_frame_info *)vf_info, &vf_log_ds);
1228 if (err != IA_CSS_SUCCESS) {
1230 ia_css_isp_param_destroy_isp_parameters(
1231 &binary->mem_params,
1232 &binary->css_params);
1237 binary->vf_downscale_log2 = vf_log_ds;
1239 binary->online = online;
1240 binary->input_format = stream_format;
1242 /* viewfinder output info */
1243 if ((vf_info != NULL) && (vf_info->res.width != 0)) {
1244 unsigned int vf_out_vecs, vf_out_width, vf_out_height;
1245 binary->vf_frame_info.format = vf_info->format;
1246 if (bin_out_info == NULL)
1247 return IA_CSS_ERR_INTERNAL_ERROR;
1248 vf_out_vecs = __ISP_VF_OUTPUT_WIDTH_VECS(bin_out_info->padded_width,
1250 vf_out_width = _ISP_VF_OUTPUT_WIDTH(vf_out_vecs);
1251 vf_out_height = _ISP_VF_OUTPUT_HEIGHT(bin_out_info->res.height,
1254 /* For preview mode, output pin is used instead of vf. */
1255 if (info->pipeline.mode == IA_CSS_BINARY_MODE_PREVIEW) {
1256 binary->out_frame_info[0].res.width =
1257 (bin_out_info->res.width >> vf_log_ds);
1258 binary->out_frame_info[0].padded_width = vf_out_width;
1259 binary->out_frame_info[0].res.height = vf_out_height;
1261 binary->vf_frame_info.res.width = 0;
1262 binary->vf_frame_info.padded_width = 0;
1263 binary->vf_frame_info.res.height = 0;
1265 /* we also store the raw downscaled width. This is
1266 * used for digital zoom in preview to zoom only on
1267 * the width that we actually want to keep, not on
1268 * the aligned width. */
1269 binary->vf_frame_info.res.width =
1270 (bin_out_info->res.width >> vf_log_ds);
1271 binary->vf_frame_info.padded_width = vf_out_width;
1272 binary->vf_frame_info.res.height = vf_out_height;
1275 binary->vf_frame_info.res.width = 0;
1276 binary->vf_frame_info.padded_width = 0;
1277 binary->vf_frame_info.res.height = 0;
1280 if (info->enable.ca_gdc) {
1281 binary->morph_tbl_width =
1282 _ISP_MORPH_TABLE_WIDTH(isp_internal_width);
1283 binary->morph_tbl_aligned_width =
1284 _ISP_MORPH_TABLE_ALIGNED_WIDTH(isp_internal_width);
1285 binary->morph_tbl_height =
1286 _ISP_MORPH_TABLE_HEIGHT(isp_internal_height);
1288 binary->morph_tbl_width = 0;
1289 binary->morph_tbl_aligned_width = 0;
1290 binary->morph_tbl_height = 0;
1293 sc_3a_dis_width = binary->in_frame_info.res.width;
1294 sc_3a_dis_padded_width = binary->in_frame_info.padded_width;
1295 sc_3a_dis_height = binary->in_frame_info.res.height;
1296 if (bds_out_info != NULL && in_info != NULL &&
1297 bds_out_info->res.width != in_info->res.width) {
1298 /* TODO: Next, "internal_frame_info" should be derived from
1299 * bds_out. So this part will change once it is in place! */
1300 sc_3a_dis_width = bds_out_info->res.width + info->pipeline.left_cropping;
1301 sc_3a_dis_padded_width = isp_internal_width;
1302 sc_3a_dis_height = isp_internal_height;
1306 s3a_isp_width = _ISP_S3A_ELEMS_ISP_WIDTH(sc_3a_dis_padded_width,
1307 info->pipeline.left_cropping);
1308 if (info->s3a.fixed_s3a_deci_log) {
1309 s3a_log_deci = info->s3a.fixed_s3a_deci_log;
1311 s3a_log_deci = binary_grid_deci_factor_log2(s3a_isp_width,
1314 binary->deci_factor_log2 = s3a_log_deci;
1316 if (info->enable.s3a) {
1317 binary->s3atbl_width =
1318 _ISP_S3ATBL_WIDTH(sc_3a_dis_width,
1320 binary->s3atbl_height =
1321 _ISP_S3ATBL_HEIGHT(sc_3a_dis_height,
1323 binary->s3atbl_isp_width =
1324 _ISP_S3ATBL_ISP_WIDTH(s3a_isp_width,
1326 binary->s3atbl_isp_height =
1327 _ISP_S3ATBL_ISP_HEIGHT(sc_3a_dis_height,
1330 binary->s3atbl_width = 0;
1331 binary->s3atbl_height = 0;
1332 binary->s3atbl_isp_width = 0;
1333 binary->s3atbl_isp_height = 0;
1336 if (info->enable.sc) {
1337 binary->sctbl_width_per_color =
1339 _ISP_SCTBL_WIDTH_PER_COLOR(sc_3a_dis_padded_width,
1342 _ISP_SCTBL_WIDTH_PER_COLOR(isp_internal_width, s3a_log_deci);
1344 binary->sctbl_aligned_width_per_color =
1345 SH_CSS_MAX_SCTBL_ALIGNED_WIDTH_PER_COLOR;
1346 binary->sctbl_height =
1348 _ISP_SCTBL_HEIGHT(sc_3a_dis_height, s3a_log_deci);
1350 _ISP_SCTBL_HEIGHT(isp_internal_height, s3a_log_deci);
1351 binary->sctbl_legacy_width_per_color =
1352 _ISP_SCTBL_LEGACY_WIDTH_PER_COLOR(sc_3a_dis_padded_width, s3a_log_deci);
1353 binary->sctbl_legacy_height =
1354 _ISP_SCTBL_LEGACY_HEIGHT(sc_3a_dis_height, s3a_log_deci);
1357 binary->sctbl_width_per_color = 0;
1358 binary->sctbl_aligned_width_per_color = 0;
1359 binary->sctbl_height = 0;
1361 binary->sctbl_legacy_width_per_color = 0;
1362 binary->sctbl_legacy_height = 0;
1365 ia_css_sdis_init_info(&binary->dis,
1367 sc_3a_dis_padded_width,
1369 info->pipeline.isp_pipe_version,
1371 if (info->pipeline.left_cropping)
1372 binary->left_padding = 2 * ISP_VEC_NELEMS - info->pipeline.left_cropping;
1374 binary->left_padding = 0;
1376 return IA_CSS_SUCCESS;
1380 ia_css_binary_find(struct ia_css_binary_descr *descr,
1381 struct ia_css_binary *binary)
1386 enum ia_css_stream_format stream_format;
1387 const struct ia_css_frame_info *req_in_info,
1389 *req_out_info[IA_CSS_BINARY_MAX_OUTPUT_PORTS],
1390 *req_bin_out_info = NULL,
1393 struct ia_css_binary_xinfo *xcandidate;
1395 bool need_ds, need_dz, need_dvs, need_xnr, need_dpc;
1397 bool need_ds, need_dz, need_dvs, need_xnr, need_dpc, need_tnr;
1401 bool enable_high_speed;
1402 bool enable_dvs_6axis;
1403 bool enable_reduced_pipe;
1404 bool enable_capture_pp_bli;
1406 bool enable_luma_only;
1408 enum ia_css_err err = IA_CSS_ERR_INTERNAL_ERROR;
1410 unsigned int isp_pipe_version;
1411 struct ia_css_resolution dvs_env, internal_res;
1414 assert(descr != NULL);
1415 /* MW: used after an error check, may accept NULL, but doubtfull */
1416 assert(binary != NULL);
1418 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1419 "ia_css_binary_find() enter: descr=%p, (mode=%d), binary=%p\n",
1424 online = descr->online;
1425 two_ppc = descr->two_ppc;
1426 stream_format = descr->stream_format;
1427 req_in_info = descr->in_info;
1428 req_bds_out_info = descr->bds_out_info;
1429 for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) {
1430 req_out_info[i] = descr->out_info[i];
1431 if (req_out_info[i] && (req_out_info[i]->res.width != 0))
1432 req_bin_out_info = req_out_info[i];
1434 if (req_bin_out_info == NULL)
1435 return IA_CSS_ERR_INTERNAL_ERROR;
1437 req_vf_info = descr->vf_info;
1440 if ((descr->vf_info != NULL) && (descr->vf_info->res.width == 0))
1441 /* width==0 means that there is no vf pin (e.g. in SkyCam preview case) */
1444 req_vf_info = descr->vf_info;
1447 need_xnr = descr->enable_xnr;
1448 need_ds = descr->enable_fractional_ds;
1451 need_dpc = descr->enable_dpc;
1453 need_tnr = descr->enable_tnr;
1455 enable_yuv_ds = descr->enable_yuv_ds;
1456 enable_high_speed = descr->enable_high_speed;
1457 enable_dvs_6axis = descr->enable_dvs_6axis;
1458 enable_reduced_pipe = descr->enable_reduced_pipe;
1459 enable_capture_pp_bli = descr->enable_capture_pp_bli;
1461 enable_luma_only = descr->enable_luma_only;
1463 continuous = descr->continuous;
1464 striped = descr->striped;
1465 isp_pipe_version = descr->isp_pipe_version;
1469 internal_res.width = 0;
1470 internal_res.height = 0;
1473 if (mode == IA_CSS_BINARY_MODE_VIDEO) {
1474 dvs_env = descr->dvs_env;
1475 need_dz = descr->enable_dz;
1476 /* Video is the only mode that has a nodz variant. */
1477 need_dvs = dvs_env.width || dvs_env.height;
1480 /* print a map of the binary file */
1481 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "BINARY INFO:\n");
1482 for (i = 0; i < IA_CSS_BINARY_NUM_MODES; i++) {
1483 xcandidate = binary_infos[i];
1485 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "%d:\n", i);
1486 while (xcandidate) {
1487 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, " Name:%s Type:%d Cont:%d\n",
1488 xcandidate->blob->name, xcandidate->type,
1489 xcandidate->sp.enable.continuous);
1490 xcandidate = xcandidate->next;
1495 /* printf("sh_css_binary_find: pipe version %d\n", isp_pipe_version); */
1496 for (xcandidate = binary_infos[mode]; xcandidate;
1497 xcandidate = xcandidate->next) {
1498 struct ia_css_binary_info *candidate = &xcandidate->sp;
1499 /* printf("sh_css_binary_find: evaluating candidate:
1500 * %d\n",candidate->id); */
1501 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1502 "ia_css_binary_find() candidate = %p, mode = %d ID = %d\n",
1503 candidate, candidate->pipeline.mode, candidate->id);
1506 * MW: Only a limited set of jointly configured binaries can
1507 * be used in a continuous preview/video mode unless it is
1508 * the copy mode and runs on SP.
1510 if (!candidate->enable.continuous &&
1511 continuous && (mode != IA_CSS_BINARY_MODE_COPY)) {
1512 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1513 "ia_css_binary_find() [%d] continue: !%d && %d && (%d != %d)\n",
1514 __LINE__, candidate->enable.continuous,
1516 IA_CSS_BINARY_MODE_COPY);
1519 if (striped && candidate->iterator.num_stripes == 1) {
1520 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1521 "ia_css_binary_find() [%d] continue: binary is not striped\n",
1526 if (candidate->pipeline.isp_pipe_version != isp_pipe_version &&
1527 (mode != IA_CSS_BINARY_MODE_COPY) &&
1528 (mode != IA_CSS_BINARY_MODE_CAPTURE_PP) &&
1529 (mode != IA_CSS_BINARY_MODE_VF_PP)) {
1530 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1531 "ia_css_binary_find() [%d] continue: (%d != %d)\n",
1533 candidate->pipeline.isp_pipe_version, isp_pipe_version);
1536 if (!candidate->enable.reduced_pipe && enable_reduced_pipe) {
1537 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1538 "ia_css_binary_find() [%d] continue: !%d && %d\n",
1540 candidate->enable.reduced_pipe,
1541 enable_reduced_pipe);
1544 if (!candidate->enable.dvs_6axis && enable_dvs_6axis) {
1545 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1546 "ia_css_binary_find() [%d] continue: !%d && %d\n",
1548 candidate->enable.dvs_6axis,
1552 if (candidate->enable.high_speed && !enable_high_speed) {
1553 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1554 "ia_css_binary_find() [%d] continue: %d && !%d\n",
1556 candidate->enable.high_speed,
1560 if (!candidate->enable.xnr && need_xnr) {
1561 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1562 "ia_css_binary_find() [%d] continue: %d && !%d\n",
1564 candidate->enable.xnr,
1568 if (!(candidate->enable.ds & 2) && enable_yuv_ds) {
1569 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1570 "ia_css_binary_find() [%d] continue: !%d && %d\n",
1572 ((candidate->enable.ds & 2) != 0),
1576 if ((candidate->enable.ds & 2) && !enable_yuv_ds) {
1577 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1578 "ia_css_binary_find() [%d] continue: %d && !%d\n",
1580 ((candidate->enable.ds & 2) != 0),
1585 if (mode == IA_CSS_BINARY_MODE_VIDEO &&
1586 candidate->enable.ds && need_ds)
1589 /* when we require vf output, we need to have vf_veceven */
1590 if ((req_vf_info != NULL) && !(candidate->enable.vf_veceven ||
1591 /* or variable vf vec even */
1592 candidate->vf_dec.is_variable ||
1593 /* or more than one output pin. */
1594 xcandidate->num_output_pins > 1)) {
1595 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1596 "ia_css_binary_find() [%d] continue: (%p != NULL) && !(%d || %d || (%d >%d))\n",
1597 __LINE__, req_vf_info,
1598 candidate->enable.vf_veceven,
1599 candidate->vf_dec.is_variable,
1600 xcandidate->num_output_pins, 1);
1603 if (!candidate->enable.dvs_envelope && need_dvs) {
1604 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1605 "ia_css_binary_find() [%d] continue: !%d && %d\n",
1607 candidate->enable.dvs_envelope, (int)need_dvs);
1610 /* internal_res check considers input, output, and dvs envelope sizes */
1611 ia_css_binary_internal_res(req_in_info, req_bds_out_info,
1612 req_bin_out_info, &dvs_env, candidate, &internal_res);
1613 if (internal_res.width > candidate->internal.max_width) {
1614 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1615 "ia_css_binary_find() [%d] continue: (%d > %d)\n",
1616 __LINE__, internal_res.width,
1617 candidate->internal.max_width);
1620 if (internal_res.height > candidate->internal.max_height) {
1621 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1622 "ia_css_binary_find() [%d] continue: (%d > %d)\n",
1623 __LINE__, internal_res.height,
1624 candidate->internal.max_height);
1627 if (!candidate->enable.ds && need_ds && !(xcandidate->num_output_pins > 1)) {
1628 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1629 "ia_css_binary_find() [%d] continue: !%d && %d\n",
1630 __LINE__, candidate->enable.ds, (int)need_ds);
1633 if (!candidate->enable.uds && !candidate->enable.dvs_6axis && need_dz) {
1634 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1635 "ia_css_binary_find() [%d] continue: !%d && !%d && %d\n",
1636 __LINE__, candidate->enable.uds,
1637 candidate->enable.dvs_6axis, (int)need_dz);
1640 if (online && candidate->input.source == IA_CSS_BINARY_INPUT_MEMORY) {
1641 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1642 "ia_css_binary_find() [%d] continue: %d && (%d == %d)\n",
1643 __LINE__, online, candidate->input.source,
1644 IA_CSS_BINARY_INPUT_MEMORY);
1647 if (!online && candidate->input.source == IA_CSS_BINARY_INPUT_SENSOR) {
1648 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1649 "ia_css_binary_find() [%d] continue: !%d && (%d == %d)\n",
1650 __LINE__, online, candidate->input.source,
1651 IA_CSS_BINARY_INPUT_SENSOR);
1654 if (req_bin_out_info->res.width < candidate->output.min_width ||
1655 req_bin_out_info->res.width > candidate->output.max_width) {
1656 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1657 "ia_css_binary_find() [%d] continue: (%d > %d) || (%d < %d)\n",
1659 req_bin_out_info->padded_width,
1660 candidate->output.min_width,
1661 req_bin_out_info->padded_width,
1662 candidate->output.max_width);
1665 if (xcandidate->num_output_pins > 1 && /* in case we have a second output pin, */
1666 req_vf_info) { /* and we need vf output. */
1667 if (req_vf_info->res.width > candidate->output.max_width) {
1668 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1669 "ia_css_binary_find() [%d] continue: (%d < %d)\n",
1671 req_vf_info->res.width,
1672 candidate->output.max_width);
1676 if (req_in_info->padded_width > candidate->input.max_width) {
1677 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1678 "ia_css_binary_find() [%d] continue: (%d > %d)\n",
1679 __LINE__, req_in_info->padded_width,
1680 candidate->input.max_width);
1683 if (!binary_supports_output_format(xcandidate, req_bin_out_info->format)) {
1684 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1685 "ia_css_binary_find() [%d] continue: !%d\n",
1687 binary_supports_output_format(xcandidate, req_bin_out_info->format));
1691 if (!binary_supports_input_format(xcandidate, descr->stream_format)) {
1692 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1693 "ia_css_binary_find() [%d] continue: !%d\n",
1695 binary_supports_input_format(xcandidate, req_in_info->format));
1699 if (xcandidate->num_output_pins > 1 && /* in case we have a second output pin, */
1700 req_vf_info && /* and we need vf output. */
1701 /* check if the required vf format
1703 !binary_supports_output_format(xcandidate, req_vf_info->format)) {
1704 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1705 "ia_css_binary_find() [%d] continue: (%d > %d) && (%p != NULL) && !%d\n",
1706 __LINE__, xcandidate->num_output_pins, 1,
1708 binary_supports_output_format(xcandidate, req_vf_info->format));
1712 /* Check if vf_veceven supports the requested vf format */
1713 if (xcandidate->num_output_pins == 1 &&
1714 req_vf_info && candidate->enable.vf_veceven &&
1715 !binary_supports_vf_format(xcandidate, req_vf_info->format)) {
1716 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1717 "ia_css_binary_find() [%d] continue: (%d == %d) && (%p != NULL) && %d && !%d\n",
1718 __LINE__, xcandidate->num_output_pins, 1,
1719 req_vf_info, candidate->enable.vf_veceven,
1720 binary_supports_vf_format(xcandidate, req_vf_info->format));
1724 /* Check if vf_veceven supports the requested vf width */
1725 if (xcandidate->num_output_pins == 1 &&
1726 req_vf_info && candidate->enable.vf_veceven) { /* and we need vf output. */
1727 if (req_vf_info->res.width > candidate->output.max_width) {
1728 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1729 "ia_css_binary_find() [%d] continue: (%d < %d)\n",
1731 req_vf_info->res.width,
1732 candidate->output.max_width);
1737 if (!supports_bds_factor(candidate->bds.supported_bds_factors,
1738 descr->required_bds_factor)) {
1739 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1740 "ia_css_binary_find() [%d] continue: 0x%x & 0x%x)\n",
1741 __LINE__, candidate->bds.supported_bds_factors,
1742 descr->required_bds_factor);
1746 if (!candidate->enable.dpc && need_dpc) {
1747 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1748 "ia_css_binary_find() [%d] continue: 0x%x & 0x%x)\n",
1749 __LINE__, candidate->enable.dpc,
1754 if (candidate->uds.use_bci && enable_capture_pp_bli) {
1755 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1756 "ia_css_binary_find() [%d] continue: 0x%x & 0x%x)\n",
1757 __LINE__, candidate->uds.use_bci,
1758 descr->enable_capture_pp_bli);
1763 if (candidate->enable.luma_only != enable_luma_only) {
1764 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1765 "ia_css_binary_find() [%d] continue: %d != %d\n",
1766 __LINE__, candidate->enable.luma_only,
1767 descr->enable_luma_only);
1771 if(!candidate->enable.tnr && need_tnr) {
1772 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1773 "ia_css_binary_find() [%d] continue: !%d && %d\n",
1774 __LINE__, candidate->enable.tnr,
1780 /* reconfigure any variable properties of the binary */
1781 err = ia_css_binary_fill_info(xcandidate, online, two_ppc,
1782 stream_format, req_in_info,
1784 req_out_info, req_vf_info,
1786 descr->stream_config_left_padding,
1789 if (err != IA_CSS_SUCCESS)
1791 binary_init_metrics(&binary->metrics, &binary->info->sp);
1795 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1796 "ia_css_binary_find() selected = %p, mode = %d ID = %d\n",
1797 xcandidate, xcandidate ? xcandidate->sp.pipeline.mode : 0, xcandidate ? xcandidate->sp.id : 0);
1799 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1800 "ia_css_binary_find() leave: return_err=%d\n", err);
1806 ia_css_binary_max_vf_width(void)
1808 /* This is (should be) true for IPU1 and IPU2 */
1809 /* For IPU3 (SkyCam) this pointer is guarenteed to be NULL simply because such a binary does not exist */
1810 if (binary_infos[IA_CSS_BINARY_MODE_VF_PP])
1811 return binary_infos[IA_CSS_BINARY_MODE_VF_PP]->sp.output.max_width;
1816 ia_css_binary_destroy_isp_parameters(struct ia_css_binary *binary)
1819 ia_css_isp_param_destroy_isp_parameters(&binary->mem_params,
1820 &binary->css_params);
1825 ia_css_binary_get_isp_binaries(struct ia_css_binary_xinfo **binaries,
1826 uint32_t *num_isp_binaries)
1828 assert(binaries != NULL);
1830 if (num_isp_binaries)
1831 *num_isp_binaries = 0;
1833 *binaries = all_binaries;
1834 if (all_binaries && num_isp_binaries) {
1835 /* -1 to account for sp binary which is not stored in all_binaries */
1836 if (sh_css_num_binaries > 0)
1837 *num_isp_binaries = sh_css_num_binaries - 1;