1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Support for Intel Camera Imaging ISP subsystem. 4 * Copyright (c) 2015, Intel Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms and conditions of the GNU General Public License, 8 * version 2, as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 * more details. 14 */ 15 16 #include <math_support.h> 17 #include <gdc_device.h> /* HR_GDC_N */ 18 19 #include "hmm.h" 20 21 #include "isp.h" /* ISP_VEC_NELEMS */ 22 23 #include "ia_css_binary.h" 24 #include "ia_css_debug.h" 25 #include "ia_css_util.h" 26 #include "ia_css_isp_param.h" 27 #include "sh_css_internal.h" 28 #include "sh_css_sp.h" 29 #include "sh_css_firmware.h" 30 #include "sh_css_defs.h" 31 #include "sh_css_legacy.h" 32 33 #include "atomisp_internal.h" 34 35 #include "vf/vf_1.0/ia_css_vf.host.h" 36 #include "sc/sc_1.0/ia_css_sc.host.h" 37 #include "sdis/sdis_1.0/ia_css_sdis.host.h" 38 #include "fixedbds/fixedbds_1.0/ia_css_fixedbds_param.h" /* FRAC_ACC */ 39 40 #include "camera/pipe/interface/ia_css_pipe_binarydesc.h" 41 42 #include "assert_support.h" 43 44 #define IMPLIES(a, b) (!(a) || (b)) /* A => B */ 45 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, }; 49 50 static void 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) 54 { 55 if (info->enable.dvs_envelope) { 56 assert(dvs_env); 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); 59 } 60 } 61 62 static void 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) 69 { 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; 74 75 binary_dvs_env.width = 0; 76 binary_dvs_env.height = 0; 77 ia_css_binary_dvs_env(info, dvs_env, &binary_dvs_env); 78 79 if (binary_supports_yuv_ds) { 80 if (in_info) { 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; 85 } 86 } else if ((bds_out_info) && (out_info) && 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; 92 } else { 93 if (out_info) { 94 isp_tmp_internal_width = out_info->padded_width; 95 isp_tmp_internal_height = out_info->res.height; 96 } 97 } 98 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); 109 } 110 111 /* ISP2400 */ 112 /* Computation results of the origin coordinate of bayer on the shading table. */ 113 struct sh_css_shading_table_bayer_origin_compute_results { 114 u32 bayer_scale_hor_ratio_in; /* Horizontal ratio (in) of bayer scaling. */ 115 u32 bayer_scale_hor_ratio_out; /* Horizontal ratio (out) of bayer scaling. */ 116 u32 bayer_scale_ver_ratio_in; /* Vertical ratio (in) of bayer scaling. */ 117 u32 bayer_scale_ver_ratio_out; /* Vertical ratio (out) of bayer scaling. */ 118 u32 sc_bayer_origin_x_bqs_on_shading_table; /* X coordinate (in bqs) of bayer origin on shading table. */ 119 u32 sc_bayer_origin_y_bqs_on_shading_table; /* Y coordinate (in bqs) of bayer origin on shading table. */ 120 }; 121 122 /* ISP2401 */ 123 /* Requirements for the shading correction. */ 124 struct sh_css_binary_sc_requirements { 125 /* Bayer scaling factor, for the scaling which is applied before shading correction. */ 126 u32 bayer_scale_hor_ratio_in; /* Horizontal ratio (in) of scaling applied BEFORE shading correction. */ 127 u32 bayer_scale_hor_ratio_out; /* Horizontal ratio (out) of scaling applied BEFORE shading correction. */ 128 u32 bayer_scale_ver_ratio_in; /* Vertical ratio (in) of scaling applied BEFORE shading correction. */ 129 u32 bayer_scale_ver_ratio_out; /* Vertical ratio (out) of scaling applied BEFORE shading correction. */ 130 131 /* ISP internal frame is composed of the real sensor data and the padding data. */ 132 u32 sensor_data_origin_x_bqs_on_internal; /* X origin (in bqs) of sensor data on internal frame 133 at shading correction. */ 134 u32 sensor_data_origin_y_bqs_on_internal; /* Y origin (in bqs) of sensor data on internal frame 135 at shading correction. */ 136 }; 137 138 /* ISP2400: Get the requirements for the shading correction. */ 139 static int 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] */ 145 { 146 int err; 147 148 /* Numerator and denominator of the fixed bayer downscaling factor. 149 (numerator >= denominator) */ 150 unsigned int bds_num, bds_den; 151 152 /* Horizontal/Vertical ratio of bayer scaling 153 between input area and output area. */ 154 unsigned int bs_hor_ratio_in; 155 unsigned int bs_hor_ratio_out; 156 unsigned int bs_ver_ratio_in; 157 unsigned int bs_ver_ratio_out; 158 159 /* Left padding set by InputFormatter. */ 160 unsigned int left_padding_bqs; /* in bqs */ 161 162 /* Flag for the NEED_BDS_FACTOR_2_00 macro defined in isp kernels. */ 163 unsigned int need_bds_factor_2_00; 164 165 /* Left padding adjusted inside the isp. */ 166 unsigned int left_padding_adjusted_bqs; /* in bqs */ 167 168 /* Bad pixels caused by filters. 169 NxN-filter (before/after bayer scaling) moves the image position 170 to right/bottom directions by a few pixels. 171 It causes bad pixels at left/top sides, 172 and effective bayer size decreases. */ 173 unsigned int bad_bqs_on_left_before_bs; /* in bqs */ 174 unsigned int bad_bqs_on_left_after_bs; /* in bqs */ 175 unsigned int bad_bqs_on_top_before_bs; /* in bqs */ 176 unsigned int bad_bqs_on_top_after_bs; /* in bqs */ 177 178 /* Get the numerator and denominator of bayer downscaling factor. */ 179 err = sh_css_bds_factor_get_numerator_denominator 180 (required_bds_factor, &bds_num, &bds_den); 181 if (err) 182 return err; 183 184 /* Set the horizontal/vertical ratio of bayer scaling 185 between input area and output area. */ 186 bs_hor_ratio_in = bds_num; 187 bs_hor_ratio_out = bds_den; 188 bs_ver_ratio_in = bds_num; 189 bs_ver_ratio_out = bds_den; 190 191 /* Set the left padding set by InputFormatter. (ifmtr.c) */ 192 if (stream_config->left_padding == -1) 193 left_padding_bqs = _ISP_BQS(binary->left_padding); 194 else 195 left_padding_bqs = (unsigned int)((int)ISP_VEC_NELEMS 196 - _ISP_BQS(stream_config->left_padding)); 197 198 /* Set the left padding adjusted inside the isp. 199 When bds_factor 2.00 is needed, some padding is added to left_padding 200 inside the isp, before bayer downscaling. (raw.isp.c) 201 (Hopefully, left_crop/left_padding/top_crop should be defined in css 202 appropriately, depending on bds_factor.) 203 */ 204 need_bds_factor_2_00 = ((binary->info->sp.bds.supported_bds_factors & 205 (PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_2_00) | 206 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_2_50) | 207 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_3_00) | 208 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_4_00) | 209 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_4_50) | 210 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_5_00) | 211 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_6_00) | 212 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_8_00))) != 0); 213 214 if (need_bds_factor_2_00 && binary->info->sp.pipeline.left_cropping > 0) 215 left_padding_adjusted_bqs = left_padding_bqs + ISP_VEC_NELEMS; 216 else 217 left_padding_adjusted_bqs = left_padding_bqs; 218 219 /* Currently, the bad pixel caused by filters before bayer scaling 220 is NOT considered, because the bad pixel is subtle. 221 When some large filter is used in the future, 222 we need to consider the bad pixel. 223 224 Currently, when bds_factor isn't 1.00, 3x3 anti-alias filter is applied 225 to each color plane(Gr/R/B/Gb) before bayer downscaling. 226 This filter moves each color plane to right/bottom directions 227 by 1 pixel at the most, depending on downscaling factor. 228 */ 229 bad_bqs_on_left_before_bs = 0; 230 bad_bqs_on_top_before_bs = 0; 231 232 /* Currently, the bad pixel caused by filters after bayer scaling 233 is NOT considered, because the bad pixel is subtle. 234 When some large filter is used in the future, 235 we need to consider the bad pixel. 236 237 Currently, when DPC&BNR is processed between bayer scaling and 238 shading correction, DPC&BNR moves each color plane to 239 right/bottom directions by 1 pixel. 240 */ 241 bad_bqs_on_left_after_bs = 0; 242 bad_bqs_on_top_after_bs = 0; 243 244 /* Calculate the origin of bayer (real sensor data area) 245 located on the shading table during the shading correction. */ 246 res->sc_bayer_origin_x_bqs_on_shading_table = 247 ((left_padding_adjusted_bqs + bad_bqs_on_left_before_bs) 248 * bs_hor_ratio_out + bs_hor_ratio_in / 2) / bs_hor_ratio_in 249 + bad_bqs_on_left_after_bs; 250 /* "+ bs_hor_ratio_in/2": rounding for division by bs_hor_ratio_in */ 251 res->sc_bayer_origin_y_bqs_on_shading_table = 252 (bad_bqs_on_top_before_bs * bs_ver_ratio_out + bs_ver_ratio_in / 2) / bs_ver_ratio_in 253 + bad_bqs_on_top_after_bs; 254 /* "+ bs_ver_ratio_in/2": rounding for division by bs_ver_ratio_in */ 255 256 res->bayer_scale_hor_ratio_in = (uint32_t)bs_hor_ratio_in; 257 res->bayer_scale_hor_ratio_out = (uint32_t)bs_hor_ratio_out; 258 res->bayer_scale_ver_ratio_in = (uint32_t)bs_ver_ratio_in; 259 res->bayer_scale_ver_ratio_out = (uint32_t)bs_ver_ratio_out; 260 261 return err; 262 } 263 264 /* ISP2401: Get the requirements for the shading correction. */ 265 static int 266 sh_css_binary_get_sc_requirements(const struct ia_css_binary *binary, /* [in] */ 267 unsigned int required_bds_factor, /* [in] */ 268 const struct ia_css_stream_config *stream_config, /* [in] */ 269 struct sh_css_binary_sc_requirements *scr) /* [out] */ 270 { 271 int err; 272 273 /* Numerator and denominator of the fixed bayer downscaling factor. (numerator >= denominator) */ 274 unsigned int bds_num, bds_den; 275 276 /* Horizontal/Vertical ratio of bayer scaling between input area and output area. */ 277 unsigned int bs_hor_ratio_in, bs_hor_ratio_out, bs_ver_ratio_in, bs_ver_ratio_out; 278 279 /* Left padding set by InputFormatter. */ 280 unsigned int left_padding_bqs; 281 282 /* Flags corresponding to NEED_BDS_FACTOR_2_00/NEED_BDS_FACTOR_1_50/NEED_BDS_FACTOR_1_25 macros 283 * defined in isp kernels. */ 284 unsigned int need_bds_factor_2_00, need_bds_factor_1_50, need_bds_factor_1_25; 285 286 /* Left padding adjusted inside the isp kernels. */ 287 unsigned int left_padding_adjusted_bqs; 288 289 /* Top padding padded inside the isp kernel for bayer downscaling binaries. */ 290 unsigned int top_padding_bqs; 291 292 /* Bayer downscaling factor 1.0 by fixed-point. */ 293 int bds_frac_acc = FRAC_ACC; /* FRAC_ACC is defined in ia_css_fixedbds_param.h. */ 294 295 /* Right/Down shift amount caused by filters applied BEFORE shading corrertion. */ 296 unsigned int right_shift_bqs_before_bs; /* right shift before bayer scaling */ 297 unsigned int right_shift_bqs_after_bs; /* right shift after bayer scaling */ 298 unsigned int down_shift_bqs_before_bs; /* down shift before bayer scaling */ 299 unsigned int down_shift_bqs_after_bs; /* down shift after bayer scaling */ 300 301 /* Origin of the real sensor data area on the internal frame at shading correction. */ 302 unsigned int sensor_data_origin_x_bqs_on_internal; 303 unsigned int sensor_data_origin_y_bqs_on_internal; 304 305 unsigned int bs_frac = bds_frac_acc; /* scaling factor 1.0 in fixed point */ 306 unsigned int bs_out, bs_in; /* scaling ratio in fixed point */ 307 308 IA_CSS_ENTER_PRIVATE("binary=%p, required_bds_factor=%d, stream_config=%p", 309 binary, required_bds_factor, stream_config); 310 311 /* Get the numerator and denominator of the required bayer downscaling factor. */ 312 err = sh_css_bds_factor_get_numerator_denominator(required_bds_factor, 313 &bds_num, &bds_den); 314 if (err) { 315 IA_CSS_LEAVE_ERR_PRIVATE(err); 316 return err; 317 } 318 319 IA_CSS_LOG("bds_num=%d, bds_den=%d", bds_num, bds_den); 320 321 /* Set the horizontal/vertical ratio of bayer scaling between input area and output area. */ 322 bs_hor_ratio_in = bds_num; 323 bs_hor_ratio_out = bds_den; 324 bs_ver_ratio_in = bds_num; 325 bs_ver_ratio_out = bds_den; 326 327 /* Set the left padding set by InputFormatter. (ia_css_ifmtr_configure() in ifmtr.c) */ 328 if (stream_config->left_padding == -1) 329 left_padding_bqs = _ISP_BQS(binary->left_padding); 330 else 331 left_padding_bqs = (unsigned int)((int)ISP_VEC_NELEMS - _ISP_BQS(stream_config->left_padding)); 332 333 IA_CSS_LOG("stream.left_padding=%d, binary.left_padding=%d, left_padding_bqs=%d", 334 stream_config->left_padding, binary->left_padding, 335 left_padding_bqs); 336 337 /* Set the left padding adjusted inside the isp kernels. 338 * When the bds_factor isn't 1.00, the left padding size is adjusted inside the isp, 339 * before bayer downscaling. (scaled_hor_plane_index(), raw_compute_hphase() in raw.isp.c) 340 */ 341 need_bds_factor_2_00 = ((binary->info->sp.bds.supported_bds_factors & 342 (PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_2_00) | 343 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_2_50) | 344 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_3_00) | 345 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_4_00) | 346 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_4_50) | 347 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_5_00) | 348 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_6_00) | 349 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_8_00))) != 0); 350 351 need_bds_factor_1_50 = ((binary->info->sp.bds.supported_bds_factors & 352 (PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_1_50) | 353 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_2_25) | 354 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_3_00) | 355 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_4_50) | 356 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_6_00))) != 0); 357 358 need_bds_factor_1_25 = ((binary->info->sp.bds.supported_bds_factors & 359 (PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_1_25) | 360 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_2_50) | 361 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_5_00))) != 0); 362 363 if (binary->info->sp.pipeline.left_cropping > 0 && 364 (need_bds_factor_2_00 || need_bds_factor_1_50 || need_bds_factor_1_25)) { 365 /* 366 * downscale 2.0 -> first_vec_adjusted_bqs = 128 367 * downscale 1.5 -> first_vec_adjusted_bqs = 96 368 * downscale 1.25 -> first_vec_adjusted_bqs = 80 369 */ 370 unsigned int first_vec_adjusted_bqs = ISP_VEC_NELEMS * bs_hor_ratio_in / bs_hor_ratio_out; 371 left_padding_adjusted_bqs = first_vec_adjusted_bqs 372 - _ISP_BQS(binary->info->sp.pipeline.left_cropping); 373 } else { 374 left_padding_adjusted_bqs = left_padding_bqs; 375 } 376 377 IA_CSS_LOG("supported_bds_factors=%d, need_bds_factor:2_00=%d, 1_50=%d, 1_25=%d", 378 binary->info->sp.bds.supported_bds_factors, 379 need_bds_factor_2_00, need_bds_factor_1_50, 380 need_bds_factor_1_25); 381 IA_CSS_LOG("left_cropping=%d, left_padding_adjusted_bqs=%d", 382 binary->info->sp.pipeline.left_cropping, 383 left_padding_adjusted_bqs); 384 385 /* Set the top padding padded inside the isp kernel for bayer downscaling binaries. 386 * When the bds_factor isn't 1.00, the top padding is padded inside the isp 387 * before bayer downscaling, because the top cropping size (input margin) is not enough. 388 * (calculate_input_line(), raw_compute_vphase(), dma_read_raw() in raw.isp.c) 389 * NOTE: In dma_read_raw(), the factor passed to raw_compute_vphase() is got by get_bds_factor_for_dma_read(). 390 * This factor is BDS_FPVAL_100/BDS_FPVAL_125/BDS_FPVAL_150/BDS_FPVAL_200. 391 */ 392 top_padding_bqs = 0; 393 if (binary->info->sp.pipeline.top_cropping > 0 && 394 (required_bds_factor == SH_CSS_BDS_FACTOR_1_25 || 395 required_bds_factor == SH_CSS_BDS_FACTOR_1_50 || 396 required_bds_factor == SH_CSS_BDS_FACTOR_2_00)) { 397 /* Calculation from calculate_input_line() and raw_compute_vphase() in raw.isp.c. */ 398 int top_cropping_bqs = _ISP_BQS(binary->info->sp.pipeline.top_cropping); 399 /* top cropping (in bqs) */ 400 int factor = bds_num * bds_frac_acc / 401 bds_den; /* downscaling factor by fixed-point */ 402 int top_padding_bqsxfrac_acc = (top_cropping_bqs * factor - top_cropping_bqs * 403 bds_frac_acc) 404 + (2 * bds_frac_acc - factor); /* top padding by fixed-point (in bqs) */ 405 406 top_padding_bqs = (unsigned int)((top_padding_bqsxfrac_acc + bds_frac_acc / 2 - 407 1) / bds_frac_acc); 408 } 409 410 IA_CSS_LOG("top_cropping=%d, top_padding_bqs=%d", 411 binary->info->sp.pipeline.top_cropping, top_padding_bqs); 412 413 /* Set the right/down shift amount caused by filters applied BEFORE bayer scaling, 414 * which scaling is applied BEFORE shading corrertion. 415 * 416 * When the bds_factor isn't 1.00, 3x3 anti-alias filter is applied to each color plane(Gr/R/B/Gb) 417 * before bayer downscaling. 418 * This filter shifts each color plane (Gr/R/B/Gb) to right/down directions by 1 pixel. 419 */ 420 right_shift_bqs_before_bs = 0; 421 down_shift_bqs_before_bs = 0; 422 423 if (need_bds_factor_2_00 || need_bds_factor_1_50 || need_bds_factor_1_25) { 424 right_shift_bqs_before_bs = 1; 425 down_shift_bqs_before_bs = 1; 426 } 427 428 IA_CSS_LOG("right_shift_bqs_before_bs=%d, down_shift_bqs_before_bs=%d", 429 right_shift_bqs_before_bs, down_shift_bqs_before_bs); 430 431 /* Set the right/down shift amount caused by filters applied AFTER bayer scaling, 432 * which scaling is applied BEFORE shading corrertion. 433 * 434 * When DPC&BNR is processed between bayer scaling and shading correction, 435 * DPC&BNR moves each color plane (Gr/R/B/Gb) to right/down directions by 1 pixel. 436 */ 437 right_shift_bqs_after_bs = 0; 438 down_shift_bqs_after_bs = 0; 439 440 /* if DPC&BNR is enabled in the binary */ 441 if (binary->info->mem_offsets.offsets.param->dmem.dp.size != 0) { 442 right_shift_bqs_after_bs = 1; 443 down_shift_bqs_after_bs = 1; 444 } 445 446 IA_CSS_LOG("right_shift_bqs_after_bs=%d, down_shift_bqs_after_bs=%d", 447 right_shift_bqs_after_bs, down_shift_bqs_after_bs); 448 449 bs_out = bs_hor_ratio_out * bs_frac; 450 bs_in = bs_hor_ratio_in * bs_frac; 451 sensor_data_origin_x_bqs_on_internal = 452 ((left_padding_adjusted_bqs + right_shift_bqs_before_bs) * bs_out + bs_in / 2) / bs_in 453 + right_shift_bqs_after_bs; /* "+ bs_in/2": rounding */ 454 455 bs_out = bs_ver_ratio_out * bs_frac; 456 bs_in = bs_ver_ratio_in * bs_frac; 457 sensor_data_origin_y_bqs_on_internal = 458 ((top_padding_bqs + down_shift_bqs_before_bs) * bs_out + bs_in / 2) / bs_in 459 + down_shift_bqs_after_bs; /* "+ bs_in/2": rounding */ 460 461 scr->bayer_scale_hor_ratio_in = (uint32_t)bs_hor_ratio_in; 462 scr->bayer_scale_hor_ratio_out = (uint32_t)bs_hor_ratio_out; 463 scr->bayer_scale_ver_ratio_in = (uint32_t)bs_ver_ratio_in; 464 scr->bayer_scale_ver_ratio_out = (uint32_t)bs_ver_ratio_out; 465 scr->sensor_data_origin_x_bqs_on_internal = (uint32_t)sensor_data_origin_x_bqs_on_internal; 466 scr->sensor_data_origin_y_bqs_on_internal = (uint32_t)sensor_data_origin_y_bqs_on_internal; 467 468 IA_CSS_LOG("sc_requirements: %d, %d, %d, %d, %d, %d", 469 scr->bayer_scale_hor_ratio_in, 470 scr->bayer_scale_hor_ratio_out, 471 scr->bayer_scale_ver_ratio_in, scr->bayer_scale_ver_ratio_out, 472 scr->sensor_data_origin_x_bqs_on_internal, 473 scr->sensor_data_origin_y_bqs_on_internal); 474 475 IA_CSS_LEAVE_ERR_PRIVATE(err); 476 return err; 477 } 478 479 /* Get the shading information of Shading Correction Type 1. */ 480 static int 481 isp2400_binary_get_shading_info_type_1(const struct ia_css_binary *binary, /* [in] */ 482 unsigned int required_bds_factor, /* [in] */ 483 const struct ia_css_stream_config *stream_config, /* [in] */ 484 struct ia_css_shading_info *info) /* [out] */ 485 { 486 int err; 487 struct sh_css_shading_table_bayer_origin_compute_results res; 488 489 assert(binary); 490 assert(info); 491 492 info->type = IA_CSS_SHADING_CORRECTION_TYPE_1; 493 494 info->info.type_1.enable = binary->info->sp.enable.sc; 495 info->info.type_1.num_hor_grids = binary->sctbl_width_per_color; 496 info->info.type_1.num_ver_grids = binary->sctbl_height; 497 info->info.type_1.bqs_per_grid_cell = (1 << binary->deci_factor_log2); 498 499 /* Initialize by default values. */ 500 info->info.type_1.bayer_scale_hor_ratio_in = 1; 501 info->info.type_1.bayer_scale_hor_ratio_out = 1; 502 info->info.type_1.bayer_scale_ver_ratio_in = 1; 503 info->info.type_1.bayer_scale_ver_ratio_out = 1; 504 info->info.type_1.sc_bayer_origin_x_bqs_on_shading_table = 0; 505 info->info.type_1.sc_bayer_origin_y_bqs_on_shading_table = 0; 506 507 err = ia_css_binary_compute_shading_table_bayer_origin( 508 binary, 509 required_bds_factor, 510 stream_config, 511 &res); 512 if (err) 513 return err; 514 515 info->info.type_1.bayer_scale_hor_ratio_in = res.bayer_scale_hor_ratio_in; 516 info->info.type_1.bayer_scale_hor_ratio_out = res.bayer_scale_hor_ratio_out; 517 info->info.type_1.bayer_scale_ver_ratio_in = res.bayer_scale_ver_ratio_in; 518 info->info.type_1.bayer_scale_ver_ratio_out = res.bayer_scale_ver_ratio_out; 519 info->info.type_1.sc_bayer_origin_x_bqs_on_shading_table = res.sc_bayer_origin_x_bqs_on_shading_table; 520 info->info.type_1.sc_bayer_origin_y_bqs_on_shading_table = res.sc_bayer_origin_y_bqs_on_shading_table; 521 522 return err; 523 } 524 525 /* Get the shading information of Shading Correction Type 1. */ 526 static int 527 isp2401_binary_get_shading_info_type_1(const struct ia_css_binary *binary, /* [in] */ 528 unsigned int required_bds_factor, /* [in] */ 529 const struct ia_css_stream_config *stream_config, /* [in] */ 530 struct ia_css_shading_info *shading_info, /* [out] */ 531 struct ia_css_pipe_config *pipe_config) /* [out] */ 532 { 533 int err; 534 struct sh_css_binary_sc_requirements scr; 535 536 u32 in_width_bqs, in_height_bqs, internal_width_bqs, internal_height_bqs; 537 u32 num_hor_grids, num_ver_grids, bqs_per_grid_cell, tbl_width_bqs, tbl_height_bqs; 538 u32 sensor_org_x_bqs_on_internal, sensor_org_y_bqs_on_internal, sensor_width_bqs, sensor_height_bqs; 539 u32 sensor_center_x_bqs_on_internal, sensor_center_y_bqs_on_internal; 540 u32 left, right, upper, lower; 541 u32 adjust_left, adjust_right, adjust_upper, adjust_lower, adjust_width_bqs, adjust_height_bqs; 542 u32 internal_org_x_bqs_on_tbl, internal_org_y_bqs_on_tbl; 543 u32 sensor_org_x_bqs_on_tbl, sensor_org_y_bqs_on_tbl; 544 545 assert(binary); 546 assert(stream_config); 547 assert(shading_info); 548 assert(pipe_config); 549 550 IA_CSS_ENTER_PRIVATE("binary=%p, required_bds_factor=%d, stream_config=%p", 551 binary, required_bds_factor, stream_config); 552 553 /* Initialize by default values. */ 554 *shading_info = DEFAULT_SHADING_INFO_TYPE_1; 555 556 err = sh_css_binary_get_sc_requirements(binary, required_bds_factor, stream_config, &scr); 557 if (err) { 558 IA_CSS_LEAVE_ERR_PRIVATE(err); 559 return err; 560 } 561 562 IA_CSS_LOG("binary: id=%d, sctbl=%dx%d, deci=%d", 563 binary->info->sp.id, binary->sctbl_width_per_color, binary->sctbl_height, binary->deci_factor_log2); 564 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", 565 binary->in_frame_info.res.width, binary->in_frame_info.res.height, binary->in_frame_info.padded_width, 566 binary->internal_frame_info.res.width, binary->internal_frame_info.res.height, 567 binary->internal_frame_info.padded_width, 568 binary->out_frame_info[0].res.width, binary->out_frame_info[0].res.height, 569 binary->out_frame_info[0].padded_width); 570 571 /* Set the input size from sensor, which includes left/top crop size. */ 572 in_width_bqs = _ISP_BQS(binary->in_frame_info.res.width); 573 in_height_bqs = _ISP_BQS(binary->in_frame_info.res.height); 574 575 /* 576 * Frame size internally used in ISP, including sensor data and padding. 577 * This is the frame size, to which the shading correction is applied. 578 */ 579 internal_width_bqs = _ISP_BQS(binary->internal_frame_info.res.width); 580 internal_height_bqs = _ISP_BQS(binary->internal_frame_info.res.height); 581 582 /* Shading table. */ 583 num_hor_grids = binary->sctbl_width_per_color; 584 num_ver_grids = binary->sctbl_height; 585 bqs_per_grid_cell = (1 << binary->deci_factor_log2); 586 tbl_width_bqs = (num_hor_grids - 1) * bqs_per_grid_cell; 587 tbl_height_bqs = (num_ver_grids - 1) * bqs_per_grid_cell; 588 589 IA_CSS_LOG("tbl_width_bqs=%d, tbl_height_bqs=%d", tbl_width_bqs, tbl_height_bqs); 590 591 /* 592 * Real sensor data area on the internal frame at shading correction. 593 * Filters and scaling are applied to the internal frame before 594 * shading correction, depending on the binary. 595 */ 596 sensor_org_x_bqs_on_internal = scr.sensor_data_origin_x_bqs_on_internal; 597 sensor_org_y_bqs_on_internal = scr.sensor_data_origin_y_bqs_on_internal; 598 { 599 unsigned int bs_frac = 8; /* scaling factor 1.0 in fixed point (8 == FRAC_ACC macro in ISP) */ 600 unsigned int bs_out, bs_in; /* scaling ratio in fixed point */ 601 602 bs_out = scr.bayer_scale_hor_ratio_out * bs_frac; 603 bs_in = scr.bayer_scale_hor_ratio_in * bs_frac; 604 sensor_width_bqs = (in_width_bqs * bs_out + bs_in / 2) / bs_in; /* "+ bs_in/2": rounding */ 605 606 bs_out = scr.bayer_scale_ver_ratio_out * bs_frac; 607 bs_in = scr.bayer_scale_ver_ratio_in * bs_frac; 608 sensor_height_bqs = (in_height_bqs * bs_out + bs_in / 2) / bs_in; /* "+ bs_in/2": rounding */ 609 } 610 611 /* Center of the sensor data on the internal frame at shading correction. */ 612 sensor_center_x_bqs_on_internal = sensor_org_x_bqs_on_internal + sensor_width_bqs / 2; 613 sensor_center_y_bqs_on_internal = sensor_org_y_bqs_on_internal + sensor_height_bqs / 2; 614 615 /* Size of left/right/upper/lower sides of the sensor center on the internal frame. */ 616 left = sensor_center_x_bqs_on_internal; 617 right = internal_width_bqs - sensor_center_x_bqs_on_internal; 618 upper = sensor_center_y_bqs_on_internal; 619 lower = internal_height_bqs - sensor_center_y_bqs_on_internal; 620 621 /* Align the size of left/right/upper/lower sides to a multiple of the grid cell size. */ 622 adjust_left = CEIL_MUL(left, bqs_per_grid_cell); 623 adjust_right = CEIL_MUL(right, bqs_per_grid_cell); 624 adjust_upper = CEIL_MUL(upper, bqs_per_grid_cell); 625 adjust_lower = CEIL_MUL(lower, bqs_per_grid_cell); 626 627 /* Shading table should cover the adjusted frame size. */ 628 adjust_width_bqs = adjust_left + adjust_right; 629 adjust_height_bqs = adjust_upper + adjust_lower; 630 631 IA_CSS_LOG("adjust_width_bqs=%d, adjust_height_bqs=%d", adjust_width_bqs, adjust_height_bqs); 632 633 if (adjust_width_bqs > tbl_width_bqs || adjust_height_bqs > tbl_height_bqs) { 634 IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL); 635 return -EINVAL; 636 } 637 638 /* Origin of the internal frame on the shading table. */ 639 internal_org_x_bqs_on_tbl = adjust_left - left; 640 internal_org_y_bqs_on_tbl = adjust_upper - upper; 641 642 /* Origin of the real sensor data area on the shading table. */ 643 sensor_org_x_bqs_on_tbl = internal_org_x_bqs_on_tbl + sensor_org_x_bqs_on_internal; 644 sensor_org_y_bqs_on_tbl = internal_org_y_bqs_on_tbl + sensor_org_y_bqs_on_internal; 645 646 /* The shading information necessary as API is stored in the shading_info. */ 647 shading_info->info.type_1.num_hor_grids = num_hor_grids; 648 shading_info->info.type_1.num_ver_grids = num_ver_grids; 649 shading_info->info.type_1.bqs_per_grid_cell = bqs_per_grid_cell; 650 651 shading_info->info.type_1.bayer_scale_hor_ratio_in = scr.bayer_scale_hor_ratio_in; 652 shading_info->info.type_1.bayer_scale_hor_ratio_out = scr.bayer_scale_hor_ratio_out; 653 shading_info->info.type_1.bayer_scale_ver_ratio_in = scr.bayer_scale_ver_ratio_in; 654 shading_info->info.type_1.bayer_scale_ver_ratio_out = scr.bayer_scale_ver_ratio_out; 655 656 shading_info->info.type_1.isp_input_sensor_data_res_bqs.width = in_width_bqs; 657 shading_info->info.type_1.isp_input_sensor_data_res_bqs.height = in_height_bqs; 658 659 shading_info->info.type_1.sensor_data_res_bqs.width = sensor_width_bqs; 660 shading_info->info.type_1.sensor_data_res_bqs.height = sensor_height_bqs; 661 662 shading_info->info.type_1.sensor_data_origin_bqs_on_sctbl.x = (int32_t)sensor_org_x_bqs_on_tbl; 663 shading_info->info.type_1.sensor_data_origin_bqs_on_sctbl.y = (int32_t)sensor_org_y_bqs_on_tbl; 664 665 /* The shading information related to ISP (but, not necessary as API) is stored in the pipe_config. */ 666 pipe_config->internal_frame_origin_bqs_on_sctbl.x = (int32_t)internal_org_x_bqs_on_tbl; 667 pipe_config->internal_frame_origin_bqs_on_sctbl.y = (int32_t)internal_org_y_bqs_on_tbl; 668 669 IA_CSS_LOG("shading_info: grids=%dx%d, cell=%d, scale=%d,%d,%d,%d, input=%dx%d, data=%dx%d, origin=(%d,%d)", 670 shading_info->info.type_1.num_hor_grids, 671 shading_info->info.type_1.num_ver_grids, 672 shading_info->info.type_1.bqs_per_grid_cell, 673 shading_info->info.type_1.bayer_scale_hor_ratio_in, 674 shading_info->info.type_1.bayer_scale_hor_ratio_out, 675 shading_info->info.type_1.bayer_scale_ver_ratio_in, 676 shading_info->info.type_1.bayer_scale_ver_ratio_out, 677 shading_info->info.type_1.isp_input_sensor_data_res_bqs.width, 678 shading_info->info.type_1.isp_input_sensor_data_res_bqs.height, 679 shading_info->info.type_1.sensor_data_res_bqs.width, 680 shading_info->info.type_1.sensor_data_res_bqs.height, 681 shading_info->info.type_1.sensor_data_origin_bqs_on_sctbl.x, 682 shading_info->info.type_1.sensor_data_origin_bqs_on_sctbl.y); 683 684 IA_CSS_LOG("pipe_config: origin=(%d,%d)", 685 pipe_config->internal_frame_origin_bqs_on_sctbl.x, 686 pipe_config->internal_frame_origin_bqs_on_sctbl.y); 687 688 IA_CSS_LEAVE_ERR_PRIVATE(err); 689 return err; 690 } 691 692 693 int 694 ia_css_binary_get_shading_info(const struct ia_css_binary *binary, /* [in] */ 695 enum ia_css_shading_correction_type type, /* [in] */ 696 unsigned int required_bds_factor, /* [in] */ 697 const struct ia_css_stream_config *stream_config, /* [in] */ 698 struct ia_css_shading_info *shading_info, /* [out] */ 699 struct ia_css_pipe_config *pipe_config) /* [out] */ 700 { 701 int err; 702 703 assert(binary); 704 assert(shading_info); 705 706 IA_CSS_ENTER_PRIVATE("binary=%p, type=%d, required_bds_factor=%d, stream_config=%p", 707 binary, type, required_bds_factor, stream_config); 708 709 if (type != IA_CSS_SHADING_CORRECTION_TYPE_1) { 710 err = -ENOTSUPP; 711 712 IA_CSS_LEAVE_ERR_PRIVATE(err); 713 return err; 714 } 715 716 if (!IS_ISP2401) 717 err = isp2400_binary_get_shading_info_type_1(binary, 718 required_bds_factor, 719 stream_config, 720 shading_info); 721 else 722 err = isp2401_binary_get_shading_info_type_1(binary, 723 required_bds_factor, 724 stream_config, 725 shading_info, 726 pipe_config); 727 728 IA_CSS_LEAVE_ERR_PRIVATE(err); 729 return err; 730 } 731 732 static void sh_css_binary_common_grid_info(const struct ia_css_binary *binary, 733 struct ia_css_grid_info *info) 734 { 735 assert(binary); 736 assert(info); 737 738 info->isp_in_width = binary->internal_frame_info.res.width; 739 info->isp_in_height = binary->internal_frame_info.res.height; 740 741 info->vamem_type = IA_CSS_VAMEM_TYPE_2; 742 } 743 744 void 745 ia_css_binary_dvs_grid_info(const struct ia_css_binary *binary, 746 struct ia_css_grid_info *info, 747 struct ia_css_pipe *pipe) 748 { 749 struct ia_css_dvs_grid_info *dvs_info; 750 751 (void)pipe; 752 assert(binary); 753 assert(info); 754 755 dvs_info = &info->dvs_grid.dvs_grid_info; 756 757 /* for DIS, we use a division instead of a ceil_div. If this is smaller 758 * than the 3a grid size, it indicates that the outer values are not 759 * valid for DIS. 760 */ 761 dvs_info->enable = binary->info->sp.enable.dis; 762 dvs_info->width = binary->dis.grid.dim.width; 763 dvs_info->height = binary->dis.grid.dim.height; 764 dvs_info->aligned_width = binary->dis.grid.pad.width; 765 dvs_info->aligned_height = binary->dis.grid.pad.height; 766 dvs_info->bqs_per_grid_cell = 1 << binary->dis.deci_factor_log2; 767 dvs_info->num_hor_coefs = binary->dis.coef.dim.width; 768 dvs_info->num_ver_coefs = binary->dis.coef.dim.height; 769 770 sh_css_binary_common_grid_info(binary, info); 771 } 772 773 void 774 ia_css_binary_dvs_stat_grid_info( 775 const struct ia_css_binary *binary, 776 struct ia_css_grid_info *info, 777 struct ia_css_pipe *pipe) 778 { 779 (void)pipe; 780 sh_css_binary_common_grid_info(binary, info); 781 return; 782 } 783 784 int 785 ia_css_binary_3a_grid_info(const struct ia_css_binary *binary, 786 struct ia_css_grid_info *info, 787 struct ia_css_pipe *pipe) { 788 struct ia_css_3a_grid_info *s3a_info; 789 int err = 0; 790 791 IA_CSS_ENTER_PRIVATE("binary=%p, info=%p, pipe=%p", 792 binary, info, pipe); 793 794 assert(binary); 795 assert(info); 796 s3a_info = &info->s3a_grid; 797 798 /* 3A statistics grid */ 799 s3a_info->enable = binary->info->sp.enable.s3a; 800 s3a_info->width = binary->s3atbl_width; 801 s3a_info->height = binary->s3atbl_height; 802 s3a_info->aligned_width = binary->s3atbl_isp_width; 803 s3a_info->aligned_height = binary->s3atbl_isp_height; 804 s3a_info->bqs_per_grid_cell = (1 << binary->deci_factor_log2); 805 s3a_info->deci_factor_log2 = binary->deci_factor_log2; 806 s3a_info->elem_bit_depth = SH_CSS_BAYER_BITS; 807 s3a_info->use_dmem = binary->info->sp.s3a.s3atbl_use_dmem; 808 #if defined(HAS_NO_HMEM) 809 s3a_info->has_histogram = 1; 810 #else 811 s3a_info->has_histogram = 0; 812 #endif 813 IA_CSS_LEAVE_ERR_PRIVATE(err); 814 return err; 815 } 816 817 static void 818 binary_init_pc_histogram(struct sh_css_pc_histogram *histo) 819 { 820 assert(histo); 821 822 histo->length = 0; 823 histo->run = NULL; 824 histo->stall = NULL; 825 } 826 827 static void 828 binary_init_metrics(struct sh_css_binary_metrics *metrics, 829 const struct ia_css_binary_info *info) 830 { 831 assert(metrics); 832 assert(info); 833 834 metrics->mode = info->pipeline.mode; 835 metrics->id = info->id; 836 metrics->next = NULL; 837 binary_init_pc_histogram(&metrics->isp_histogram); 838 binary_init_pc_histogram(&metrics->sp_histogram); 839 } 840 841 /* move to host part of output module */ 842 static bool 843 binary_supports_output_format(const struct ia_css_binary_xinfo *info, 844 enum ia_css_frame_format format) 845 { 846 int i; 847 848 assert(info); 849 850 for (i = 0; i < info->num_output_formats; i++) { 851 if (info->output_formats[i] == format) 852 return true; 853 } 854 return false; 855 } 856 857 static bool 858 binary_supports_vf_format(const struct ia_css_binary_xinfo *info, 859 enum ia_css_frame_format format) 860 { 861 int i; 862 863 assert(info); 864 865 for (i = 0; i < info->num_vf_formats; i++) { 866 if (info->vf_formats[i] == format) 867 return true; 868 } 869 return false; 870 } 871 872 /* move to host part of bds module */ 873 static bool 874 supports_bds_factor(u32 supported_factors, 875 uint32_t bds_factor) 876 { 877 return ((supported_factors & PACK_BDS_FACTOR(bds_factor)) != 0); 878 } 879 880 static int 881 binary_init_info(struct ia_css_binary_xinfo *info, unsigned int i, 882 bool *binary_found) { 883 const unsigned char *blob = sh_css_blob_info[i].blob; 884 unsigned int size = sh_css_blob_info[i].header.blob.size; 885 886 if ((!info) || (!binary_found)) 887 return -EINVAL; 888 889 *info = sh_css_blob_info[i].header.info.isp; 890 *binary_found = blob; 891 info->blob_index = i; 892 /* we don't have this binary, skip it */ 893 if (!size) 894 return 0; 895 896 info->xmem_addr = sh_css_load_blob(blob, size); 897 if (!info->xmem_addr) 898 return -ENOMEM; 899 return 0; 900 } 901 902 /* When binaries are put at the beginning, they will only 903 * be selected if no other primary matches. 904 */ 905 int 906 ia_css_binary_init_infos(void) { 907 unsigned int i; 908 unsigned int num_of_isp_binaries = sh_css_num_binaries - NUM_OF_SPS - NUM_OF_BLS; 909 910 if (num_of_isp_binaries == 0) 911 return 0; 912 913 all_binaries = kvmalloc(num_of_isp_binaries * sizeof(*all_binaries), 914 GFP_KERNEL); 915 if (!all_binaries) 916 return -ENOMEM; 917 918 for (i = 0; i < num_of_isp_binaries; i++) 919 { 920 int ret; 921 struct ia_css_binary_xinfo *binary = &all_binaries[i]; 922 bool binary_found; 923 924 ret = binary_init_info(binary, i, &binary_found); 925 if (ret) 926 return ret; 927 if (!binary_found) 928 continue; 929 /* Prepend new binary information */ 930 binary->next = binary_infos[binary->sp.pipeline.mode]; 931 binary_infos[binary->sp.pipeline.mode] = binary; 932 binary->blob = &sh_css_blob_info[i]; 933 binary->mem_offsets = sh_css_blob_info[i].mem_offsets; 934 } 935 return 0; 936 } 937 938 int 939 ia_css_binary_uninit(void) { 940 unsigned int i; 941 struct ia_css_binary_xinfo *b; 942 943 for (i = 0; i < IA_CSS_BINARY_NUM_MODES; i++) 944 { 945 for (b = binary_infos[i]; b; b = b->next) { 946 if (b->xmem_addr) 947 hmm_free(b->xmem_addr); 948 b->xmem_addr = mmgr_NULL; 949 } 950 binary_infos[i] = NULL; 951 } 952 kvfree(all_binaries); 953 return 0; 954 } 955 956 /* @brief Compute decimation factor for 3A statistics and shading correction. 957 * 958 * @param[in] width Frame width in pixels. 959 * @param[in] height Frame height in pixels. 960 * @return Log2 of decimation factor (= grid cell size) in bayer quads. 961 */ 962 static int 963 binary_grid_deci_factor_log2(int width, int height) 964 { 965 /* 3A/Shading decimation factor spcification (at August 2008) 966 * ------------------------------------------------------------------ 967 * [Image Width (BQ)] [Decimation Factor (BQ)] [Resulting grid cells] 968 #ifndef ISP2401 969 * 1280 ?c 32 40 ?c 970 * 640 ?c 1279 16 40 ?c 80 971 * ?c 639 8 ?c 80 972 #else 973 * from 1280 32 from 40 974 * from 640 to 1279 16 from 40 to 80 975 * to 639 8 to 80 976 #endif 977 * ------------------------------------------------------------------ 978 */ 979 /* Maximum and minimum decimation factor by the specification */ 980 #define MAX_SPEC_DECI_FACT_LOG2 5 981 #define MIN_SPEC_DECI_FACT_LOG2 3 982 /* the smallest frame width in bayer quads when decimation factor (log2) is 5 or 4, by the specification */ 983 #define DECI_FACT_LOG2_5_SMALLEST_FRAME_WIDTH_BQ 1280 984 #define DECI_FACT_LOG2_4_SMALLEST_FRAME_WIDTH_BQ 640 985 986 int smallest_factor; /* the smallest factor (log2) where the number of cells does not exceed the limitation */ 987 int spec_factor; /* the factor (log2) which satisfies the specification */ 988 989 /* Currently supported maximum width and height are 5120(=80*64) and 3840(=60*64). */ 990 assert(ISP_BQ_GRID_WIDTH(width, 991 MAX_SPEC_DECI_FACT_LOG2) <= SH_CSS_MAX_BQ_GRID_WIDTH); 992 assert(ISP_BQ_GRID_HEIGHT(height, 993 MAX_SPEC_DECI_FACT_LOG2) <= SH_CSS_MAX_BQ_GRID_HEIGHT); 994 995 /* Compute the smallest factor. */ 996 smallest_factor = MAX_SPEC_DECI_FACT_LOG2; 997 while (ISP_BQ_GRID_WIDTH(width, 998 smallest_factor - 1) <= SH_CSS_MAX_BQ_GRID_WIDTH && 999 ISP_BQ_GRID_HEIGHT(height, smallest_factor - 1) <= SH_CSS_MAX_BQ_GRID_HEIGHT 1000 && smallest_factor > MIN_SPEC_DECI_FACT_LOG2) 1001 smallest_factor--; 1002 1003 /* Get the factor by the specification. */ 1004 if (_ISP_BQS(width) >= DECI_FACT_LOG2_5_SMALLEST_FRAME_WIDTH_BQ) 1005 spec_factor = 5; 1006 else if (_ISP_BQS(width) >= DECI_FACT_LOG2_4_SMALLEST_FRAME_WIDTH_BQ) 1007 spec_factor = 4; 1008 else 1009 spec_factor = 3; 1010 1011 /* If smallest_factor is smaller than or equal to spec_factor, choose spec_factor to follow the specification. 1012 If smallest_factor is larger than spec_factor, choose smallest_factor. 1013 1014 ex. width=2560, height=1920 1015 smallest_factor=4, spec_factor=5 1016 smallest_factor < spec_factor -> return spec_factor 1017 1018 ex. width=300, height=3000 1019 smallest_factor=5, spec_factor=3 1020 smallest_factor > spec_factor -> return smallest_factor 1021 */ 1022 return max(smallest_factor, spec_factor); 1023 1024 #undef MAX_SPEC_DECI_FACT_LOG2 1025 #undef MIN_SPEC_DECI_FACT_LOG2 1026 #undef DECI_FACT_LOG2_5_SMALLEST_FRAME_WIDTH_BQ 1027 #undef DECI_FACT_LOG2_4_SMALLEST_FRAME_WIDTH_BQ 1028 } 1029 1030 static int 1031 binary_in_frame_padded_width(int in_frame_width, 1032 int isp_internal_width, 1033 int dvs_env_width, 1034 int stream_config_left_padding, 1035 int left_cropping, 1036 bool need_scaling) 1037 { 1038 int rval; 1039 int nr_of_left_paddings; /* number of paddings pixels on the left of an image line */ 1040 1041 #if defined(ISP2401) 1042 /* the output image line of Input System 2401 does not have the left paddings */ 1043 nr_of_left_paddings = 0; 1044 #else 1045 /* in other cases, the left padding pixels are always 128 */ 1046 nr_of_left_paddings = 2 * ISP_VEC_NELEMS; 1047 #endif 1048 if (need_scaling) { 1049 /* In SDV use-case, we need to match left-padding of 1050 * primary and the video binary. */ 1051 if (stream_config_left_padding != -1) { 1052 /* Different than before, we do left&right padding. */ 1053 rval = 1054 CEIL_MUL(in_frame_width + nr_of_left_paddings, 1055 2 * ISP_VEC_NELEMS); 1056 } else { 1057 /* Different than before, we do left&right padding. */ 1058 in_frame_width += dvs_env_width; 1059 rval = 1060 CEIL_MUL(in_frame_width + 1061 (left_cropping ? nr_of_left_paddings : 0), 1062 2 * ISP_VEC_NELEMS); 1063 } 1064 } else { 1065 rval = isp_internal_width; 1066 } 1067 1068 return rval; 1069 } 1070 1071 int 1072 ia_css_binary_fill_info(const struct ia_css_binary_xinfo *xinfo, 1073 bool online, 1074 bool two_ppc, 1075 enum atomisp_input_format stream_format, 1076 const struct ia_css_frame_info *in_info, /* can be NULL */ 1077 const struct ia_css_frame_info *bds_out_info, /* can be NULL */ 1078 const struct ia_css_frame_info *out_info[], /* can be NULL */ 1079 const struct ia_css_frame_info *vf_info, /* can be NULL */ 1080 struct ia_css_binary *binary, 1081 struct ia_css_resolution *dvs_env, 1082 int stream_config_left_padding, 1083 bool accelerator) { 1084 const struct ia_css_binary_info *info = &xinfo->sp; 1085 unsigned int dvs_env_width = 0, 1086 dvs_env_height = 0, 1087 vf_log_ds = 0, 1088 s3a_log_deci = 0, 1089 bits_per_pixel = 0, 1090 /* Resolution at SC/3A/DIS kernel. */ 1091 sc_3a_dis_width = 0, 1092 /* Resolution at SC/3A/DIS kernel. */ 1093 sc_3a_dis_padded_width = 0, 1094 /* Resolution at SC/3A/DIS kernel. */ 1095 sc_3a_dis_height = 0, 1096 isp_internal_width = 0, 1097 isp_internal_height = 0, 1098 s3a_isp_width = 0; 1099 1100 bool need_scaling = false; 1101 struct ia_css_resolution binary_dvs_env, internal_res; 1102 int err; 1103 unsigned int i; 1104 const struct ia_css_frame_info *bin_out_info = NULL; 1105 1106 assert(info); 1107 assert(binary); 1108 1109 binary->info = xinfo; 1110 if (!accelerator) 1111 { 1112 /* binary->css_params has been filled by accelerator itself. */ 1113 err = ia_css_isp_param_allocate_isp_parameters( 1114 &binary->mem_params, &binary->css_params, 1115 &info->mem_initializers); 1116 if (err) { 1117 return err; 1118 } 1119 } 1120 for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) 1121 { 1122 if (out_info[i] && (out_info[i]->res.width != 0)) { 1123 bin_out_info = out_info[i]; 1124 break; 1125 } 1126 } 1127 if (in_info && bin_out_info) 1128 { 1129 need_scaling = (in_info->res.width != bin_out_info->res.width) || 1130 (in_info->res.height != bin_out_info->res.height); 1131 } 1132 1133 /* binary_dvs_env has to be equal or larger than SH_CSS_MIN_DVS_ENVELOPE */ 1134 binary_dvs_env.width = 0; 1135 binary_dvs_env.height = 0; 1136 ia_css_binary_dvs_env(info, dvs_env, &binary_dvs_env); 1137 dvs_env_width = binary_dvs_env.width; 1138 dvs_env_height = binary_dvs_env.height; 1139 binary->dvs_envelope.width = dvs_env_width; 1140 binary->dvs_envelope.height = dvs_env_height; 1141 1142 /* internal resolution calculation */ 1143 internal_res.width = 0; 1144 internal_res.height = 0; 1145 ia_css_binary_internal_res(in_info, bds_out_info, bin_out_info, dvs_env, 1146 info, &internal_res); 1147 isp_internal_width = internal_res.width; 1148 isp_internal_height = internal_res.height; 1149 1150 /* internal frame info */ 1151 if (bin_out_info) /* { */ 1152 binary->internal_frame_info.format = bin_out_info->format; 1153 /* } */ 1154 binary->internal_frame_info.res.width = isp_internal_width; 1155 binary->internal_frame_info.padded_width = CEIL_MUL(isp_internal_width, 2 * ISP_VEC_NELEMS); 1156 binary->internal_frame_info.res.height = isp_internal_height; 1157 binary->internal_frame_info.raw_bit_depth = bits_per_pixel; 1158 1159 if (in_info) 1160 { 1161 binary->effective_in_frame_res.width = in_info->res.width; 1162 binary->effective_in_frame_res.height = in_info->res.height; 1163 1164 bits_per_pixel = in_info->raw_bit_depth; 1165 1166 /* input info */ 1167 binary->in_frame_info.res.width = in_info->res.width + 1168 info->pipeline.left_cropping; 1169 binary->in_frame_info.res.height = in_info->res.height + 1170 info->pipeline.top_cropping; 1171 1172 binary->in_frame_info.res.width += dvs_env_width; 1173 binary->in_frame_info.res.height += dvs_env_height; 1174 1175 binary->in_frame_info.padded_width = 1176 binary_in_frame_padded_width(in_info->res.width, 1177 isp_internal_width, 1178 dvs_env_width, 1179 stream_config_left_padding, 1180 info->pipeline.left_cropping, 1181 need_scaling); 1182 1183 binary->in_frame_info.format = in_info->format; 1184 binary->in_frame_info.raw_bayer_order = in_info->raw_bayer_order; 1185 binary->in_frame_info.crop_info = in_info->crop_info; 1186 } 1187 1188 if (online) 1189 { 1190 bits_per_pixel = ia_css_util_input_format_bpp( 1191 stream_format, two_ppc); 1192 } 1193 binary->in_frame_info.raw_bit_depth = bits_per_pixel; 1194 1195 for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) 1196 { 1197 if (out_info[i]) { 1198 binary->out_frame_info[i].res.width = out_info[i]->res.width; 1199 binary->out_frame_info[i].res.height = out_info[i]->res.height; 1200 binary->out_frame_info[i].padded_width = out_info[i]->padded_width; 1201 if (info->pipeline.mode == IA_CSS_BINARY_MODE_COPY) { 1202 binary->out_frame_info[i].raw_bit_depth = bits_per_pixel; 1203 } else { 1204 /* Only relevant for RAW format. 1205 * At the moment, all outputs are raw, 16 bit per pixel, except for copy. 1206 * To do this cleanly, the binary should specify in its info 1207 * the bit depth per output channel. 1208 */ 1209 binary->out_frame_info[i].raw_bit_depth = 16; 1210 } 1211 binary->out_frame_info[i].format = out_info[i]->format; 1212 } 1213 } 1214 1215 if (vf_info && (vf_info->res.width != 0)) 1216 { 1217 err = ia_css_vf_configure(binary, bin_out_info, 1218 (struct ia_css_frame_info *)vf_info, &vf_log_ds); 1219 if (err) { 1220 if (!accelerator) { 1221 ia_css_isp_param_destroy_isp_parameters( 1222 &binary->mem_params, 1223 &binary->css_params); 1224 } 1225 return err; 1226 } 1227 } 1228 binary->vf_downscale_log2 = vf_log_ds; 1229 1230 binary->online = online; 1231 binary->input_format = stream_format; 1232 1233 /* viewfinder output info */ 1234 if ((vf_info) && (vf_info->res.width != 0)) 1235 { 1236 unsigned int vf_out_vecs, vf_out_width, vf_out_height; 1237 1238 binary->vf_frame_info.format = vf_info->format; 1239 if (!bin_out_info) 1240 return -EINVAL; 1241 vf_out_vecs = __ISP_VF_OUTPUT_WIDTH_VECS(bin_out_info->padded_width, 1242 vf_log_ds); 1243 vf_out_width = _ISP_VF_OUTPUT_WIDTH(vf_out_vecs); 1244 vf_out_height = _ISP_VF_OUTPUT_HEIGHT(bin_out_info->res.height, 1245 vf_log_ds); 1246 1247 /* For preview mode, output pin is used instead of vf. */ 1248 if (info->pipeline.mode == IA_CSS_BINARY_MODE_PREVIEW) { 1249 binary->out_frame_info[0].res.width = 1250 (bin_out_info->res.width >> vf_log_ds); 1251 binary->out_frame_info[0].padded_width = vf_out_width; 1252 binary->out_frame_info[0].res.height = vf_out_height; 1253 1254 binary->vf_frame_info.res.width = 0; 1255 binary->vf_frame_info.padded_width = 0; 1256 binary->vf_frame_info.res.height = 0; 1257 } else { 1258 /* we also store the raw downscaled width. This is 1259 * used for digital zoom in preview to zoom only on 1260 * the width that we actually want to keep, not on 1261 * the aligned width. */ 1262 binary->vf_frame_info.res.width = 1263 (bin_out_info->res.width >> vf_log_ds); 1264 binary->vf_frame_info.padded_width = vf_out_width; 1265 binary->vf_frame_info.res.height = vf_out_height; 1266 } 1267 } else 1268 { 1269 binary->vf_frame_info.res.width = 0; 1270 binary->vf_frame_info.padded_width = 0; 1271 binary->vf_frame_info.res.height = 0; 1272 } 1273 1274 if (info->enable.ca_gdc) 1275 { 1276 binary->morph_tbl_width = 1277 _ISP_MORPH_TABLE_WIDTH(isp_internal_width); 1278 binary->morph_tbl_aligned_width = 1279 _ISP_MORPH_TABLE_ALIGNED_WIDTH(isp_internal_width); 1280 binary->morph_tbl_height = 1281 _ISP_MORPH_TABLE_HEIGHT(isp_internal_height); 1282 } else 1283 { 1284 binary->morph_tbl_width = 0; 1285 binary->morph_tbl_aligned_width = 0; 1286 binary->morph_tbl_height = 0; 1287 } 1288 1289 sc_3a_dis_width = binary->in_frame_info.res.width; 1290 sc_3a_dis_padded_width = binary->in_frame_info.padded_width; 1291 sc_3a_dis_height = binary->in_frame_info.res.height; 1292 if (bds_out_info && in_info && 1293 bds_out_info->res.width != in_info->res.width) 1294 { 1295 /* TODO: Next, "internal_frame_info" should be derived from 1296 * bds_out. So this part will change once it is in place! */ 1297 sc_3a_dis_width = bds_out_info->res.width + info->pipeline.left_cropping; 1298 sc_3a_dis_padded_width = isp_internal_width; 1299 sc_3a_dis_height = isp_internal_height; 1300 } 1301 1302 s3a_isp_width = _ISP_S3A_ELEMS_ISP_WIDTH(sc_3a_dis_padded_width, 1303 info->pipeline.left_cropping); 1304 if (info->s3a.fixed_s3a_deci_log) 1305 { 1306 s3a_log_deci = info->s3a.fixed_s3a_deci_log; 1307 } else 1308 { 1309 s3a_log_deci = binary_grid_deci_factor_log2(s3a_isp_width, 1310 sc_3a_dis_height); 1311 } 1312 binary->deci_factor_log2 = s3a_log_deci; 1313 1314 if (info->enable.s3a) 1315 { 1316 binary->s3atbl_width = 1317 _ISP_S3ATBL_WIDTH(sc_3a_dis_width, 1318 s3a_log_deci); 1319 binary->s3atbl_height = 1320 _ISP_S3ATBL_HEIGHT(sc_3a_dis_height, 1321 s3a_log_deci); 1322 binary->s3atbl_isp_width = 1323 _ISP_S3ATBL_ISP_WIDTH(s3a_isp_width, 1324 s3a_log_deci); 1325 binary->s3atbl_isp_height = 1326 _ISP_S3ATBL_ISP_HEIGHT(sc_3a_dis_height, 1327 s3a_log_deci); 1328 } else 1329 { 1330 binary->s3atbl_width = 0; 1331 binary->s3atbl_height = 0; 1332 binary->s3atbl_isp_width = 0; 1333 binary->s3atbl_isp_height = 0; 1334 } 1335 1336 if (info->enable.sc) 1337 { 1338 if (!IS_ISP2401) { 1339 binary->sctbl_width_per_color = _ISP2400_SCTBL_WIDTH_PER_COLOR(sc_3a_dis_padded_width, s3a_log_deci); 1340 binary->sctbl_aligned_width_per_color = ISP2400_SH_CSS_MAX_SCTBL_ALIGNED_WIDTH_PER_COLOR; 1341 binary->sctbl_height = _ISP2400_SCTBL_HEIGHT(sc_3a_dis_height, s3a_log_deci); 1342 } else { 1343 binary->sctbl_width_per_color = _ISP2401_SCTBL_WIDTH_PER_COLOR(isp_internal_width, s3a_log_deci); 1344 binary->sctbl_aligned_width_per_color = ISP2401_SH_CSS_MAX_SCTBL_ALIGNED_WIDTH_PER_COLOR; 1345 binary->sctbl_height = _ISP2401_SCTBL_HEIGHT(isp_internal_height, s3a_log_deci); 1346 binary->sctbl_legacy_width_per_color = _ISP_SCTBL_LEGACY_WIDTH_PER_COLOR(sc_3a_dis_padded_width, s3a_log_deci); 1347 binary->sctbl_legacy_height = _ISP_SCTBL_LEGACY_HEIGHT(sc_3a_dis_height, s3a_log_deci); 1348 } 1349 } else 1350 { 1351 binary->sctbl_width_per_color = 0; 1352 binary->sctbl_aligned_width_per_color = 0; 1353 binary->sctbl_height = 0; 1354 if (IS_ISP2401) { 1355 binary->sctbl_legacy_width_per_color = 0; 1356 binary->sctbl_legacy_height = 0; 1357 } 1358 } 1359 ia_css_sdis_init_info(&binary->dis, 1360 sc_3a_dis_width, 1361 sc_3a_dis_padded_width, 1362 sc_3a_dis_height, 1363 info->pipeline.isp_pipe_version, 1364 info->enable.dis); 1365 if (info->pipeline.left_cropping) 1366 binary->left_padding = 2 * ISP_VEC_NELEMS - info->pipeline.left_cropping; 1367 else 1368 binary->left_padding = 0; 1369 1370 return 0; 1371 } 1372 1373 static int __ia_css_binary_find(struct ia_css_binary_descr *descr, 1374 struct ia_css_binary *binary) { 1375 int mode; 1376 bool online; 1377 bool two_ppc; 1378 enum atomisp_input_format stream_format; 1379 const struct ia_css_frame_info *req_in_info, 1380 *req_bds_out_info, 1381 *req_out_info[IA_CSS_BINARY_MAX_OUTPUT_PORTS], 1382 *req_bin_out_info = NULL, 1383 *req_vf_info; 1384 1385 struct ia_css_binary_xinfo *xcandidate; 1386 #ifndef ISP2401 1387 bool need_ds, need_dz, need_dvs, need_xnr, need_dpc; 1388 #else 1389 bool need_ds, need_dz, need_dvs, need_xnr, need_dpc, need_tnr; 1390 #endif 1391 bool striped; 1392 bool enable_yuv_ds; 1393 bool enable_high_speed; 1394 bool enable_dvs_6axis; 1395 bool enable_reduced_pipe; 1396 bool enable_capture_pp_bli; 1397 #ifdef ISP2401 1398 bool enable_luma_only; 1399 #endif 1400 int err = -EINVAL; 1401 bool continuous; 1402 unsigned int isp_pipe_version; 1403 struct ia_css_resolution dvs_env, internal_res; 1404 unsigned int i; 1405 1406 assert(descr); 1407 /* MW: used after an error check, may accept NULL, but doubtfull */ 1408 assert(binary); 1409 1410 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1411 "ia_css_binary_find() enter: descr=%p, (mode=%d), binary=%p\n", 1412 descr, descr->mode, 1413 binary); 1414 1415 mode = descr->mode; 1416 online = descr->online; 1417 two_ppc = descr->two_ppc; 1418 stream_format = descr->stream_format; 1419 req_in_info = descr->in_info; 1420 req_bds_out_info = descr->bds_out_info; 1421 for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) 1422 { 1423 req_out_info[i] = descr->out_info[i]; 1424 if (req_out_info[i] && (req_out_info[i]->res.width != 0)) 1425 req_bin_out_info = req_out_info[i]; 1426 } 1427 if (!req_bin_out_info) 1428 return -EINVAL; 1429 #ifndef ISP2401 1430 req_vf_info = descr->vf_info; 1431 #else 1432 1433 if ((descr->vf_info) && (descr->vf_info->res.width == 0)) 1434 /* width==0 means that there is no vf pin (e.g. in SkyCam preview case) */ 1435 req_vf_info = NULL; 1436 else 1437 req_vf_info = descr->vf_info; 1438 #endif 1439 1440 need_xnr = descr->enable_xnr; 1441 need_ds = descr->enable_fractional_ds; 1442 need_dz = false; 1443 need_dvs = false; 1444 need_dpc = descr->enable_dpc; 1445 #ifdef ISP2401 1446 need_tnr = descr->enable_tnr; 1447 #endif 1448 enable_yuv_ds = descr->enable_yuv_ds; 1449 enable_high_speed = descr->enable_high_speed; 1450 enable_dvs_6axis = descr->enable_dvs_6axis; 1451 enable_reduced_pipe = descr->enable_reduced_pipe; 1452 enable_capture_pp_bli = descr->enable_capture_pp_bli; 1453 #ifdef ISP2401 1454 enable_luma_only = descr->enable_luma_only; 1455 #endif 1456 continuous = descr->continuous; 1457 striped = descr->striped; 1458 isp_pipe_version = descr->isp_pipe_version; 1459 1460 dvs_env.width = 0; 1461 dvs_env.height = 0; 1462 internal_res.width = 0; 1463 internal_res.height = 0; 1464 1465 if (mode == IA_CSS_BINARY_MODE_VIDEO) 1466 { 1467 dvs_env = descr->dvs_env; 1468 need_dz = descr->enable_dz; 1469 /* Video is the only mode that has a nodz variant. */ 1470 need_dvs = dvs_env.width || dvs_env.height; 1471 } 1472 1473 /* print a map of the binary file */ 1474 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "BINARY INFO:\n"); 1475 for (i = 0; i < IA_CSS_BINARY_NUM_MODES; i++) 1476 { 1477 xcandidate = binary_infos[i]; 1478 if (xcandidate) { 1479 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "%d:\n", i); 1480 while (xcandidate) { 1481 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, " Name:%s Type:%d Cont:%d\n", 1482 xcandidate->blob->name, xcandidate->type, 1483 xcandidate->sp.enable.continuous); 1484 xcandidate = xcandidate->next; 1485 } 1486 } 1487 } 1488 1489 /* printf("sh_css_binary_find: pipe version %d\n", isp_pipe_version); */ 1490 for (xcandidate = binary_infos[mode]; xcandidate; 1491 xcandidate = xcandidate->next) 1492 { 1493 struct ia_css_binary_info *candidate = &xcandidate->sp; 1494 /* printf("sh_css_binary_find: evaluating candidate: 1495 * %d\n",candidate->id); */ 1496 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1497 "ia_css_binary_find() candidate = %p, mode = %d ID = %d\n", 1498 candidate, candidate->pipeline.mode, candidate->id); 1499 1500 /* 1501 * MW: Only a limited set of jointly configured binaries can 1502 * be used in a continuous preview/video mode unless it is 1503 * the copy mode and runs on SP. 1504 */ 1505 if (!candidate->enable.continuous && 1506 continuous && (mode != IA_CSS_BINARY_MODE_COPY)) { 1507 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1508 "ia_css_binary_find() [%d] continue: !%d && %d && (%d != %d)\n", 1509 __LINE__, candidate->enable.continuous, 1510 continuous, mode, 1511 IA_CSS_BINARY_MODE_COPY); 1512 continue; 1513 } 1514 if (striped && candidate->iterator.num_stripes == 1) { 1515 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1516 "ia_css_binary_find() [%d] continue: binary is not striped\n", 1517 __LINE__); 1518 continue; 1519 } 1520 1521 if (candidate->pipeline.isp_pipe_version != isp_pipe_version && 1522 (mode != IA_CSS_BINARY_MODE_COPY) && 1523 (mode != IA_CSS_BINARY_MODE_CAPTURE_PP) && 1524 (mode != IA_CSS_BINARY_MODE_VF_PP)) { 1525 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1526 "ia_css_binary_find() [%d] continue: (%d != %d)\n", 1527 __LINE__, 1528 candidate->pipeline.isp_pipe_version, isp_pipe_version); 1529 continue; 1530 } 1531 if (!candidate->enable.reduced_pipe && enable_reduced_pipe) { 1532 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1533 "ia_css_binary_find() [%d] continue: !%d && %d\n", 1534 __LINE__, 1535 candidate->enable.reduced_pipe, 1536 enable_reduced_pipe); 1537 continue; 1538 } 1539 if (!candidate->enable.dvs_6axis && enable_dvs_6axis) { 1540 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1541 "ia_css_binary_find() [%d] continue: !%d && %d\n", 1542 __LINE__, 1543 candidate->enable.dvs_6axis, 1544 enable_dvs_6axis); 1545 continue; 1546 } 1547 if (candidate->enable.high_speed && !enable_high_speed) { 1548 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1549 "ia_css_binary_find() [%d] continue: %d && !%d\n", 1550 __LINE__, 1551 candidate->enable.high_speed, 1552 enable_high_speed); 1553 continue; 1554 } 1555 if (!candidate->enable.xnr && need_xnr) { 1556 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1557 "ia_css_binary_find() [%d] continue: %d && !%d\n", 1558 __LINE__, 1559 candidate->enable.xnr, 1560 need_xnr); 1561 continue; 1562 } 1563 if (!(candidate->enable.ds & 2) && enable_yuv_ds) { 1564 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1565 "ia_css_binary_find() [%d] continue: !%d && %d\n", 1566 __LINE__, 1567 ((candidate->enable.ds & 2) != 0), 1568 enable_yuv_ds); 1569 continue; 1570 } 1571 if ((candidate->enable.ds & 2) && !enable_yuv_ds) { 1572 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1573 "ia_css_binary_find() [%d] continue: %d && !%d\n", 1574 __LINE__, 1575 ((candidate->enable.ds & 2) != 0), 1576 enable_yuv_ds); 1577 continue; 1578 } 1579 1580 if (mode == IA_CSS_BINARY_MODE_VIDEO && 1581 candidate->enable.ds && need_ds) 1582 need_dz = false; 1583 1584 /* when we require vf output, we need to have vf_veceven */ 1585 if ((req_vf_info) && !(candidate->enable.vf_veceven || 1586 /* or variable vf vec even */ 1587 candidate->vf_dec.is_variable || 1588 /* or more than one output pin. */ 1589 xcandidate->num_output_pins > 1)) { 1590 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1591 "ia_css_binary_find() [%d] continue: (%p != NULL) && !(%d || %d || (%d >%d))\n", 1592 __LINE__, req_vf_info, 1593 candidate->enable.vf_veceven, 1594 candidate->vf_dec.is_variable, 1595 xcandidate->num_output_pins, 1); 1596 continue; 1597 } 1598 if (!candidate->enable.dvs_envelope && need_dvs) { 1599 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1600 "ia_css_binary_find() [%d] continue: !%d && %d\n", 1601 __LINE__, 1602 candidate->enable.dvs_envelope, (int)need_dvs); 1603 continue; 1604 } 1605 /* internal_res check considers input, output, and dvs envelope sizes */ 1606 ia_css_binary_internal_res(req_in_info, req_bds_out_info, 1607 req_bin_out_info, &dvs_env, candidate, &internal_res); 1608 if (internal_res.width > candidate->internal.max_width) { 1609 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1610 "ia_css_binary_find() [%d] continue: (%d > %d)\n", 1611 __LINE__, internal_res.width, 1612 candidate->internal.max_width); 1613 continue; 1614 } 1615 if (internal_res.height > candidate->internal.max_height) { 1616 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1617 "ia_css_binary_find() [%d] continue: (%d > %d)\n", 1618 __LINE__, internal_res.height, 1619 candidate->internal.max_height); 1620 continue; 1621 } 1622 if (!candidate->enable.ds && need_ds && !(xcandidate->num_output_pins > 1)) { 1623 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1624 "ia_css_binary_find() [%d] continue: !%d && %d\n", 1625 __LINE__, candidate->enable.ds, (int)need_ds); 1626 continue; 1627 } 1628 if (!candidate->enable.uds && !candidate->enable.dvs_6axis && need_dz) { 1629 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1630 "ia_css_binary_find() [%d] continue: !%d && !%d && %d\n", 1631 __LINE__, candidate->enable.uds, 1632 candidate->enable.dvs_6axis, (int)need_dz); 1633 continue; 1634 } 1635 if (online && candidate->input.source == IA_CSS_BINARY_INPUT_MEMORY) { 1636 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1637 "ia_css_binary_find() [%d] continue: %d && (%d == %d)\n", 1638 __LINE__, online, candidate->input.source, 1639 IA_CSS_BINARY_INPUT_MEMORY); 1640 continue; 1641 } 1642 if (!online && candidate->input.source == IA_CSS_BINARY_INPUT_SENSOR) { 1643 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1644 "ia_css_binary_find() [%d] continue: !%d && (%d == %d)\n", 1645 __LINE__, online, candidate->input.source, 1646 IA_CSS_BINARY_INPUT_SENSOR); 1647 continue; 1648 } 1649 if (req_bin_out_info->res.width < candidate->output.min_width || 1650 req_bin_out_info->res.width > candidate->output.max_width) { 1651 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1652 "ia_css_binary_find() [%d] continue: (%d > %d) || (%d < %d)\n", 1653 __LINE__, 1654 req_bin_out_info->padded_width, 1655 candidate->output.min_width, 1656 req_bin_out_info->padded_width, 1657 candidate->output.max_width); 1658 continue; 1659 } 1660 if (xcandidate->num_output_pins > 1 && 1661 /* in case we have a second output pin, */ 1662 req_vf_info) { /* and we need vf output. */ 1663 if (req_vf_info->res.width > candidate->output.max_width) { 1664 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1665 "ia_css_binary_find() [%d] continue: (%d < %d)\n", 1666 __LINE__, 1667 req_vf_info->res.width, 1668 candidate->output.max_width); 1669 continue; 1670 } 1671 } 1672 if (req_in_info->padded_width > candidate->input.max_width) { 1673 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1674 "ia_css_binary_find() [%d] continue: (%d > %d)\n", 1675 __LINE__, req_in_info->padded_width, 1676 candidate->input.max_width); 1677 continue; 1678 } 1679 if (!binary_supports_output_format(xcandidate, req_bin_out_info->format)) { 1680 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1681 "ia_css_binary_find() [%d] continue: !%d\n", 1682 __LINE__, 1683 binary_supports_output_format(xcandidate, req_bin_out_info->format)); 1684 continue; 1685 } 1686 if (xcandidate->num_output_pins > 1 && 1687 /* in case we have a second output pin, */ 1688 req_vf_info && /* and we need vf output. */ 1689 /* check if the required vf format 1690 is supported. */ 1691 !binary_supports_output_format(xcandidate, req_vf_info->format)) { 1692 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1693 "ia_css_binary_find() [%d] continue: (%d > %d) && (%p != NULL) && !%d\n", 1694 __LINE__, xcandidate->num_output_pins, 1, 1695 req_vf_info, 1696 binary_supports_output_format(xcandidate, req_vf_info->format)); 1697 continue; 1698 } 1699 1700 /* Check if vf_veceven supports the requested vf format */ 1701 if (xcandidate->num_output_pins == 1 && 1702 req_vf_info && candidate->enable.vf_veceven && 1703 !binary_supports_vf_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 && !%d\n", 1706 __LINE__, xcandidate->num_output_pins, 1, 1707 req_vf_info, candidate->enable.vf_veceven, 1708 binary_supports_vf_format(xcandidate, req_vf_info->format)); 1709 continue; 1710 } 1711 1712 /* Check if vf_veceven supports the requested vf width */ 1713 if (xcandidate->num_output_pins == 1 && 1714 req_vf_info && candidate->enable.vf_veceven) { /* and we need vf output. */ 1715 if (req_vf_info->res.width > candidate->output.max_width) { 1716 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1717 "ia_css_binary_find() [%d] continue: (%d < %d)\n", 1718 __LINE__, 1719 req_vf_info->res.width, 1720 candidate->output.max_width); 1721 continue; 1722 } 1723 } 1724 1725 if (!supports_bds_factor(candidate->bds.supported_bds_factors, 1726 descr->required_bds_factor)) { 1727 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1728 "ia_css_binary_find() [%d] continue: 0x%x & 0x%x)\n", 1729 __LINE__, candidate->bds.supported_bds_factors, 1730 descr->required_bds_factor); 1731 continue; 1732 } 1733 1734 if (!candidate->enable.dpc && need_dpc) { 1735 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1736 "ia_css_binary_find() [%d] continue: 0x%x & 0x%x)\n", 1737 __LINE__, candidate->enable.dpc, 1738 descr->enable_dpc); 1739 continue; 1740 } 1741 1742 if (candidate->uds.use_bci && enable_capture_pp_bli) { 1743 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1744 "ia_css_binary_find() [%d] continue: 0x%x & 0x%x)\n", 1745 __LINE__, candidate->uds.use_bci, 1746 descr->enable_capture_pp_bli); 1747 continue; 1748 } 1749 1750 #ifdef ISP2401 1751 if (candidate->enable.luma_only != enable_luma_only) { 1752 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1753 "ia_css_binary_find() [%d] continue: %d != %d\n", 1754 __LINE__, candidate->enable.luma_only, 1755 descr->enable_luma_only); 1756 continue; 1757 } 1758 1759 if (!candidate->enable.tnr && need_tnr) { 1760 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1761 "ia_css_binary_find() [%d] continue: !%d && %d\n", 1762 __LINE__, candidate->enable.tnr, 1763 descr->enable_tnr); 1764 continue; 1765 } 1766 1767 #endif 1768 /* reconfigure any variable properties of the binary */ 1769 err = ia_css_binary_fill_info(xcandidate, online, two_ppc, 1770 stream_format, req_in_info, 1771 req_bds_out_info, 1772 req_out_info, req_vf_info, 1773 binary, &dvs_env, 1774 descr->stream_config_left_padding, 1775 false); 1776 1777 if (err) 1778 break; 1779 binary_init_metrics(&binary->metrics, &binary->info->sp); 1780 break; 1781 } 1782 1783 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1784 "ia_css_binary_find() selected = %p, mode = %d ID = %d\n", 1785 xcandidate, xcandidate ? xcandidate->sp.pipeline.mode : 0, xcandidate ? xcandidate->sp.id : 0); 1786 1787 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1788 "ia_css_binary_find() leave: return_err=%d\n", err); 1789 1790 if (!err && xcandidate) 1791 dev_dbg(atomisp_dev, 1792 "Using binary %s (id %d), type %d, mode %d, continuous %s\n", 1793 xcandidate->blob->name, 1794 xcandidate->sp.id, 1795 xcandidate->type, 1796 xcandidate->sp.pipeline.mode, 1797 xcandidate->sp.enable.continuous ? "true" : "false"); 1798 1799 1800 return err; 1801 } 1802 1803 int ia_css_binary_find(struct ia_css_binary_descr *descr, 1804 struct ia_css_binary *binary) 1805 { 1806 int ret = __ia_css_binary_find(descr, binary); 1807 1808 if (unlikely(ret)) { 1809 dev_dbg(atomisp_dev, "Seeking for binary failed at:"); 1810 dump_stack(); 1811 } 1812 1813 return ret; 1814 } 1815 1816 unsigned 1817 ia_css_binary_max_vf_width(void) 1818 { 1819 /* This is (should be) true for IPU1 and IPU2 */ 1820 /* For IPU3 (SkyCam) this pointer is guaranteed to be NULL simply because such a binary does not exist */ 1821 if (binary_infos[IA_CSS_BINARY_MODE_VF_PP]) 1822 return binary_infos[IA_CSS_BINARY_MODE_VF_PP]->sp.output.max_width; 1823 return 0; 1824 } 1825 1826 void 1827 ia_css_binary_destroy_isp_parameters(struct ia_css_binary *binary) 1828 { 1829 if (binary) { 1830 ia_css_isp_param_destroy_isp_parameters(&binary->mem_params, 1831 &binary->css_params); 1832 } 1833 } 1834 1835 void 1836 ia_css_binary_get_isp_binaries(struct ia_css_binary_xinfo **binaries, 1837 uint32_t *num_isp_binaries) 1838 { 1839 assert(binaries); 1840 1841 if (num_isp_binaries) 1842 *num_isp_binaries = 0; 1843 1844 *binaries = all_binaries; 1845 if (all_binaries && num_isp_binaries) { 1846 /* -1 to account for sp binary which is not stored in all_binaries */ 1847 if (sh_css_num_binaries > 0) 1848 *num_isp_binaries = sh_css_num_binaries - 1; 1849 } 1850 } 1851