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