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