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 /* Computation results of the origin coordinate of bayer on the shading table. */ 112 struct sh_css_shading_table_bayer_origin_compute_results { 113 u32 bayer_scale_hor_ratio_in; /* Horizontal ratio (in) of bayer scaling. */ 114 u32 bayer_scale_hor_ratio_out; /* Horizontal ratio (out) of bayer scaling. */ 115 u32 bayer_scale_ver_ratio_in; /* Vertical ratio (in) of bayer scaling. */ 116 u32 bayer_scale_ver_ratio_out; /* Vertical ratio (out) of bayer scaling. */ 117 u32 sc_bayer_origin_x_bqs_on_shading_table; /* X coordinate (in bqs) of bayer origin on shading table. */ 118 u32 sc_bayer_origin_y_bqs_on_shading_table; /* Y coordinate (in bqs) of bayer origin on shading table. */ 119 }; 120 121 /* Get the requirements for the shading correction. */ 122 static int 123 ia_css_binary_compute_shading_table_bayer_origin( 124 const struct ia_css_binary *binary, /* [in] */ 125 unsigned int required_bds_factor, /* [in] */ 126 const struct ia_css_stream_config *stream_config, /* [in] */ 127 struct sh_css_shading_table_bayer_origin_compute_results *res) /* [out] */ 128 { 129 int err; 130 131 /* Numerator and denominator of the fixed bayer downscaling factor. 132 (numerator >= denominator) */ 133 unsigned int bds_num, bds_den; 134 135 /* Horizontal/Vertical ratio of bayer scaling 136 between input area and output area. */ 137 unsigned int bs_hor_ratio_in; 138 unsigned int bs_hor_ratio_out; 139 unsigned int bs_ver_ratio_in; 140 unsigned int bs_ver_ratio_out; 141 142 /* Left padding set by InputFormatter. */ 143 unsigned int left_padding_bqs; /* in bqs */ 144 145 /* Flag for the NEED_BDS_FACTOR_2_00 macro defined in isp kernels. */ 146 unsigned int need_bds_factor_2_00; 147 148 /* Left padding adjusted inside the isp. */ 149 unsigned int left_padding_adjusted_bqs; /* in bqs */ 150 151 /* Bad pixels caused by filters. 152 NxN-filter (before/after bayer scaling) moves the image position 153 to right/bottom directions by a few pixels. 154 It causes bad pixels at left/top sides, 155 and effective bayer size decreases. */ 156 unsigned int bad_bqs_on_left_before_bs; /* in bqs */ 157 unsigned int bad_bqs_on_left_after_bs; /* in bqs */ 158 unsigned int bad_bqs_on_top_before_bs; /* in bqs */ 159 unsigned int bad_bqs_on_top_after_bs; /* in bqs */ 160 161 /* Get the numerator and denominator of bayer downscaling factor. */ 162 err = sh_css_bds_factor_get_numerator_denominator 163 (required_bds_factor, &bds_num, &bds_den); 164 if (err) 165 return err; 166 167 /* Set the horizontal/vertical ratio of bayer scaling 168 between input area and output area. */ 169 bs_hor_ratio_in = bds_num; 170 bs_hor_ratio_out = bds_den; 171 bs_ver_ratio_in = bds_num; 172 bs_ver_ratio_out = bds_den; 173 174 /* Set the left padding set by InputFormatter. (ifmtr.c) */ 175 if (stream_config->left_padding == -1) 176 left_padding_bqs = _ISP_BQS(binary->left_padding); 177 else 178 left_padding_bqs = (unsigned int)((int)ISP_VEC_NELEMS 179 - _ISP_BQS(stream_config->left_padding)); 180 181 /* Set the left padding adjusted inside the isp. 182 When bds_factor 2.00 is needed, some padding is added to left_padding 183 inside the isp, before bayer downscaling. (raw.isp.c) 184 (Hopefully, left_crop/left_padding/top_crop should be defined in css 185 appropriately, depending on bds_factor.) 186 */ 187 need_bds_factor_2_00 = ((binary->info->sp.bds.supported_bds_factors & 188 (PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_2_00) | 189 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_2_50) | 190 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_3_00) | 191 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_4_00) | 192 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_4_50) | 193 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_5_00) | 194 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_6_00) | 195 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_8_00))) != 0); 196 197 if (need_bds_factor_2_00 && binary->info->sp.pipeline.left_cropping > 0) 198 left_padding_adjusted_bqs = left_padding_bqs + ISP_VEC_NELEMS; 199 else 200 left_padding_adjusted_bqs = left_padding_bqs; 201 202 /* Currently, the bad pixel caused by filters before bayer scaling 203 is NOT considered, because the bad pixel is subtle. 204 When some large filter is used in the future, 205 we need to consider the bad pixel. 206 207 Currently, when bds_factor isn't 1.00, 3x3 anti-alias filter is applied 208 to each color plane(Gr/R/B/Gb) before bayer downscaling. 209 This filter moves each color plane to right/bottom directions 210 by 1 pixel at the most, depending on downscaling factor. 211 */ 212 bad_bqs_on_left_before_bs = 0; 213 bad_bqs_on_top_before_bs = 0; 214 215 /* Currently, the bad pixel caused by filters after bayer scaling 216 is NOT considered, because the bad pixel is subtle. 217 When some large filter is used in the future, 218 we need to consider the bad pixel. 219 220 Currently, when DPC&BNR is processed between bayer scaling and 221 shading correction, DPC&BNR moves each color plane to 222 right/bottom directions by 1 pixel. 223 */ 224 bad_bqs_on_left_after_bs = 0; 225 bad_bqs_on_top_after_bs = 0; 226 227 /* Calculate the origin of bayer (real sensor data area) 228 located on the shading table during the shading correction. */ 229 res->sc_bayer_origin_x_bqs_on_shading_table = 230 ((left_padding_adjusted_bqs + bad_bqs_on_left_before_bs) 231 * bs_hor_ratio_out + bs_hor_ratio_in / 2) / bs_hor_ratio_in 232 + bad_bqs_on_left_after_bs; 233 /* "+ bs_hor_ratio_in/2": rounding for division by bs_hor_ratio_in */ 234 res->sc_bayer_origin_y_bqs_on_shading_table = 235 (bad_bqs_on_top_before_bs * bs_ver_ratio_out + bs_ver_ratio_in / 2) / bs_ver_ratio_in 236 + bad_bqs_on_top_after_bs; 237 /* "+ bs_ver_ratio_in/2": rounding for division by bs_ver_ratio_in */ 238 239 res->bayer_scale_hor_ratio_in = (uint32_t)bs_hor_ratio_in; 240 res->bayer_scale_hor_ratio_out = (uint32_t)bs_hor_ratio_out; 241 res->bayer_scale_ver_ratio_in = (uint32_t)bs_ver_ratio_in; 242 res->bayer_scale_ver_ratio_out = (uint32_t)bs_ver_ratio_out; 243 244 return err; 245 } 246 247 /* Get the shading information of Shading Correction Type 1. */ 248 static int 249 binary_get_shading_info_type_1(const struct ia_css_binary *binary, /* [in] */ 250 unsigned int required_bds_factor, /* [in] */ 251 const struct ia_css_stream_config *stream_config, /* [in] */ 252 struct ia_css_shading_info *info) /* [out] */ 253 { 254 int err; 255 struct sh_css_shading_table_bayer_origin_compute_results res; 256 257 assert(binary); 258 assert(info); 259 260 info->type = IA_CSS_SHADING_CORRECTION_TYPE_1; 261 262 info->info.type_1.enable = binary->info->sp.enable.sc; 263 info->info.type_1.num_hor_grids = binary->sctbl_width_per_color; 264 info->info.type_1.num_ver_grids = binary->sctbl_height; 265 info->info.type_1.bqs_per_grid_cell = (1 << binary->deci_factor_log2); 266 267 /* Initialize by default values. */ 268 info->info.type_1.bayer_scale_hor_ratio_in = 1; 269 info->info.type_1.bayer_scale_hor_ratio_out = 1; 270 info->info.type_1.bayer_scale_ver_ratio_in = 1; 271 info->info.type_1.bayer_scale_ver_ratio_out = 1; 272 info->info.type_1.sc_bayer_origin_x_bqs_on_shading_table = 0; 273 info->info.type_1.sc_bayer_origin_y_bqs_on_shading_table = 0; 274 275 err = ia_css_binary_compute_shading_table_bayer_origin( 276 binary, 277 required_bds_factor, 278 stream_config, 279 &res); 280 if (err) 281 return err; 282 283 info->info.type_1.bayer_scale_hor_ratio_in = res.bayer_scale_hor_ratio_in; 284 info->info.type_1.bayer_scale_hor_ratio_out = res.bayer_scale_hor_ratio_out; 285 info->info.type_1.bayer_scale_ver_ratio_in = res.bayer_scale_ver_ratio_in; 286 info->info.type_1.bayer_scale_ver_ratio_out = res.bayer_scale_ver_ratio_out; 287 info->info.type_1.sc_bayer_origin_x_bqs_on_shading_table = res.sc_bayer_origin_x_bqs_on_shading_table; 288 info->info.type_1.sc_bayer_origin_y_bqs_on_shading_table = res.sc_bayer_origin_y_bqs_on_shading_table; 289 290 return err; 291 } 292 293 294 int 295 ia_css_binary_get_shading_info(const struct ia_css_binary *binary, /* [in] */ 296 enum ia_css_shading_correction_type type, /* [in] */ 297 unsigned int required_bds_factor, /* [in] */ 298 const struct ia_css_stream_config *stream_config, /* [in] */ 299 struct ia_css_shading_info *shading_info, /* [out] */ 300 struct ia_css_pipe_config *pipe_config) /* [out] */ 301 { 302 int err; 303 304 assert(binary); 305 assert(shading_info); 306 307 IA_CSS_ENTER_PRIVATE("binary=%p, type=%d, required_bds_factor=%d, stream_config=%p", 308 binary, type, required_bds_factor, stream_config); 309 310 if (type == IA_CSS_SHADING_CORRECTION_TYPE_1) 311 err = binary_get_shading_info_type_1(binary, 312 required_bds_factor, 313 stream_config, 314 shading_info); 315 else 316 err = -ENOTSUPP; 317 318 IA_CSS_LEAVE_ERR_PRIVATE(err); 319 return err; 320 } 321 322 static void sh_css_binary_common_grid_info(const struct ia_css_binary *binary, 323 struct ia_css_grid_info *info) 324 { 325 assert(binary); 326 assert(info); 327 328 info->isp_in_width = binary->internal_frame_info.res.width; 329 info->isp_in_height = binary->internal_frame_info.res.height; 330 331 info->vamem_type = IA_CSS_VAMEM_TYPE_2; 332 } 333 334 void 335 ia_css_binary_dvs_grid_info(const struct ia_css_binary *binary, 336 struct ia_css_grid_info *info, 337 struct ia_css_pipe *pipe) 338 { 339 struct ia_css_dvs_grid_info *dvs_info; 340 341 (void)pipe; 342 assert(binary); 343 assert(info); 344 345 dvs_info = &info->dvs_grid.dvs_grid_info; 346 347 /* for DIS, we use a division instead of a ceil_div. If this is smaller 348 * than the 3a grid size, it indicates that the outer values are not 349 * valid for DIS. 350 */ 351 dvs_info->enable = binary->info->sp.enable.dis; 352 dvs_info->width = binary->dis.grid.dim.width; 353 dvs_info->height = binary->dis.grid.dim.height; 354 dvs_info->aligned_width = binary->dis.grid.pad.width; 355 dvs_info->aligned_height = binary->dis.grid.pad.height; 356 dvs_info->bqs_per_grid_cell = 1 << binary->dis.deci_factor_log2; 357 dvs_info->num_hor_coefs = binary->dis.coef.dim.width; 358 dvs_info->num_ver_coefs = binary->dis.coef.dim.height; 359 360 sh_css_binary_common_grid_info(binary, info); 361 } 362 363 void 364 ia_css_binary_dvs_stat_grid_info( 365 const struct ia_css_binary *binary, 366 struct ia_css_grid_info *info, 367 struct ia_css_pipe *pipe) 368 { 369 (void)pipe; 370 sh_css_binary_common_grid_info(binary, info); 371 return; 372 } 373 374 int 375 ia_css_binary_3a_grid_info(const struct ia_css_binary *binary, 376 struct ia_css_grid_info *info, 377 struct ia_css_pipe *pipe) { 378 struct ia_css_3a_grid_info *s3a_info; 379 int err = 0; 380 381 IA_CSS_ENTER_PRIVATE("binary=%p, info=%p, pipe=%p", 382 binary, info, pipe); 383 384 assert(binary); 385 assert(info); 386 s3a_info = &info->s3a_grid; 387 388 /* 3A statistics grid */ 389 s3a_info->enable = binary->info->sp.enable.s3a; 390 s3a_info->width = binary->s3atbl_width; 391 s3a_info->height = binary->s3atbl_height; 392 s3a_info->aligned_width = binary->s3atbl_isp_width; 393 s3a_info->aligned_height = binary->s3atbl_isp_height; 394 s3a_info->bqs_per_grid_cell = (1 << binary->deci_factor_log2); 395 s3a_info->deci_factor_log2 = binary->deci_factor_log2; 396 s3a_info->elem_bit_depth = SH_CSS_BAYER_BITS; 397 s3a_info->use_dmem = binary->info->sp.s3a.s3atbl_use_dmem; 398 s3a_info->has_histogram = 0; 399 IA_CSS_LEAVE_ERR_PRIVATE(err); 400 return err; 401 } 402 403 static void 404 binary_init_pc_histogram(struct sh_css_pc_histogram *histo) 405 { 406 assert(histo); 407 408 histo->length = 0; 409 histo->run = NULL; 410 histo->stall = NULL; 411 } 412 413 static void 414 binary_init_metrics(struct sh_css_binary_metrics *metrics, 415 const struct ia_css_binary_info *info) 416 { 417 assert(metrics); 418 assert(info); 419 420 metrics->mode = info->pipeline.mode; 421 metrics->id = info->id; 422 metrics->next = NULL; 423 binary_init_pc_histogram(&metrics->isp_histogram); 424 binary_init_pc_histogram(&metrics->sp_histogram); 425 } 426 427 /* move to host part of output module */ 428 static bool 429 binary_supports_output_format(const struct ia_css_binary_xinfo *info, 430 enum ia_css_frame_format format) 431 { 432 int i; 433 434 assert(info); 435 436 for (i = 0; i < info->num_output_formats; i++) { 437 if (info->output_formats[i] == format) 438 return true; 439 } 440 return false; 441 } 442 443 static bool 444 binary_supports_vf_format(const struct ia_css_binary_xinfo *info, 445 enum ia_css_frame_format format) 446 { 447 int i; 448 449 assert(info); 450 451 for (i = 0; i < info->num_vf_formats; i++) { 452 if (info->vf_formats[i] == format) 453 return true; 454 } 455 return false; 456 } 457 458 /* move to host part of bds module */ 459 static bool 460 supports_bds_factor(u32 supported_factors, 461 uint32_t bds_factor) 462 { 463 return ((supported_factors & PACK_BDS_FACTOR(bds_factor)) != 0); 464 } 465 466 static int 467 binary_init_info(struct ia_css_binary_xinfo *info, unsigned int i, 468 bool *binary_found) { 469 const unsigned char *blob = sh_css_blob_info[i].blob; 470 unsigned int size = sh_css_blob_info[i].header.blob.size; 471 472 if ((!info) || (!binary_found)) 473 return -EINVAL; 474 475 *info = sh_css_blob_info[i].header.info.isp; 476 *binary_found = blob; 477 info->blob_index = i; 478 /* we don't have this binary, skip it */ 479 if (!size) 480 return 0; 481 482 info->xmem_addr = sh_css_load_blob(blob, size); 483 if (!info->xmem_addr) 484 return -ENOMEM; 485 return 0; 486 } 487 488 /* When binaries are put at the beginning, they will only 489 * be selected if no other primary matches. 490 */ 491 int 492 ia_css_binary_init_infos(void) { 493 unsigned int i; 494 unsigned int num_of_isp_binaries = sh_css_num_binaries - NUM_OF_SPS - NUM_OF_BLS; 495 496 if (num_of_isp_binaries == 0) 497 return 0; 498 499 all_binaries = kvmalloc(num_of_isp_binaries * sizeof(*all_binaries), 500 GFP_KERNEL); 501 if (!all_binaries) 502 return -ENOMEM; 503 504 for (i = 0; i < num_of_isp_binaries; i++) 505 { 506 int ret; 507 struct ia_css_binary_xinfo *binary = &all_binaries[i]; 508 bool binary_found; 509 510 ret = binary_init_info(binary, i, &binary_found); 511 if (ret) 512 return ret; 513 if (!binary_found) 514 continue; 515 /* Prepend new binary information */ 516 binary->next = binary_infos[binary->sp.pipeline.mode]; 517 binary_infos[binary->sp.pipeline.mode] = binary; 518 binary->blob = &sh_css_blob_info[i]; 519 binary->mem_offsets = sh_css_blob_info[i].mem_offsets; 520 } 521 return 0; 522 } 523 524 int 525 ia_css_binary_uninit(void) { 526 unsigned int i; 527 struct ia_css_binary_xinfo *b; 528 529 for (i = 0; i < IA_CSS_BINARY_NUM_MODES; i++) 530 { 531 for (b = binary_infos[i]; b; b = b->next) { 532 if (b->xmem_addr) 533 hmm_free(b->xmem_addr); 534 b->xmem_addr = mmgr_NULL; 535 } 536 binary_infos[i] = NULL; 537 } 538 kvfree(all_binaries); 539 return 0; 540 } 541 542 /* @brief Compute decimation factor for 3A statistics and shading correction. 543 * 544 * @param[in] width Frame width in pixels. 545 * @param[in] height Frame height in pixels. 546 * @return Log2 of decimation factor (= grid cell size) in bayer quads. 547 */ 548 static int 549 binary_grid_deci_factor_log2(int width, int height) 550 { 551 /* 3A/Shading decimation factor spcification (at August 2008) 552 * ------------------------------------------------------------------ 553 * [Image Width (BQ)] [Decimation Factor (BQ)] [Resulting grid cells] 554 * 1280 ?c 32 40 ?c 555 * 640 ?c 1279 16 40 ?c 80 556 * ?c 639 8 ?c 80 557 * ------------------------------------------------------------------ 558 */ 559 /* Maximum and minimum decimation factor by the specification */ 560 #define MAX_SPEC_DECI_FACT_LOG2 5 561 #define MIN_SPEC_DECI_FACT_LOG2 3 562 /* the smallest frame width in bayer quads when decimation factor (log2) is 5 or 4, by the specification */ 563 #define DECI_FACT_LOG2_5_SMALLEST_FRAME_WIDTH_BQ 1280 564 #define DECI_FACT_LOG2_4_SMALLEST_FRAME_WIDTH_BQ 640 565 566 int smallest_factor; /* the smallest factor (log2) where the number of cells does not exceed the limitation */ 567 int spec_factor; /* the factor (log2) which satisfies the specification */ 568 569 /* Currently supported maximum width and height are 5120(=80*64) and 3840(=60*64). */ 570 assert(ISP_BQ_GRID_WIDTH(width, 571 MAX_SPEC_DECI_FACT_LOG2) <= SH_CSS_MAX_BQ_GRID_WIDTH); 572 assert(ISP_BQ_GRID_HEIGHT(height, 573 MAX_SPEC_DECI_FACT_LOG2) <= SH_CSS_MAX_BQ_GRID_HEIGHT); 574 575 /* Compute the smallest factor. */ 576 smallest_factor = MAX_SPEC_DECI_FACT_LOG2; 577 while (ISP_BQ_GRID_WIDTH(width, 578 smallest_factor - 1) <= SH_CSS_MAX_BQ_GRID_WIDTH && 579 ISP_BQ_GRID_HEIGHT(height, smallest_factor - 1) <= SH_CSS_MAX_BQ_GRID_HEIGHT 580 && smallest_factor > MIN_SPEC_DECI_FACT_LOG2) 581 smallest_factor--; 582 583 /* Get the factor by the specification. */ 584 if (_ISP_BQS(width) >= DECI_FACT_LOG2_5_SMALLEST_FRAME_WIDTH_BQ) 585 spec_factor = 5; 586 else if (_ISP_BQS(width) >= DECI_FACT_LOG2_4_SMALLEST_FRAME_WIDTH_BQ) 587 spec_factor = 4; 588 else 589 spec_factor = 3; 590 591 /* If smallest_factor is smaller than or equal to spec_factor, choose spec_factor to follow the specification. 592 If smallest_factor is larger than spec_factor, choose smallest_factor. 593 594 ex. width=2560, height=1920 595 smallest_factor=4, spec_factor=5 596 smallest_factor < spec_factor -> return spec_factor 597 598 ex. width=300, height=3000 599 smallest_factor=5, spec_factor=3 600 smallest_factor > spec_factor -> return smallest_factor 601 */ 602 return max(smallest_factor, spec_factor); 603 604 #undef MAX_SPEC_DECI_FACT_LOG2 605 #undef MIN_SPEC_DECI_FACT_LOG2 606 #undef DECI_FACT_LOG2_5_SMALLEST_FRAME_WIDTH_BQ 607 #undef DECI_FACT_LOG2_4_SMALLEST_FRAME_WIDTH_BQ 608 } 609 610 static int 611 binary_in_frame_padded_width(int in_frame_width, 612 int isp_internal_width, 613 int dvs_env_width, 614 int stream_config_left_padding, 615 int left_cropping, 616 bool need_scaling) 617 { 618 int rval; 619 int nr_of_left_paddings; /* number of paddings pixels on the left of an image line */ 620 621 #if defined(ISP2401) 622 /* the output image line of Input System 2401 does not have the left paddings */ 623 nr_of_left_paddings = 0; 624 #else 625 /* in other cases, the left padding pixels are always 128 */ 626 nr_of_left_paddings = 2 * ISP_VEC_NELEMS; 627 #endif 628 if (need_scaling) { 629 /* In SDV use-case, we need to match left-padding of 630 * primary and the video binary. */ 631 if (stream_config_left_padding != -1) { 632 /* Different than before, we do left&right padding. */ 633 rval = 634 CEIL_MUL(in_frame_width + nr_of_left_paddings, 635 2 * ISP_VEC_NELEMS); 636 } else { 637 /* Different than before, we do left&right padding. */ 638 in_frame_width += dvs_env_width; 639 rval = 640 CEIL_MUL(in_frame_width + 641 (left_cropping ? nr_of_left_paddings : 0), 642 2 * ISP_VEC_NELEMS); 643 } 644 } else { 645 rval = isp_internal_width; 646 } 647 648 return rval; 649 } 650 651 int 652 ia_css_binary_fill_info(const struct ia_css_binary_xinfo *xinfo, 653 bool online, 654 bool two_ppc, 655 enum atomisp_input_format stream_format, 656 const struct ia_css_frame_info *in_info, /* can be NULL */ 657 const struct ia_css_frame_info *bds_out_info, /* can be NULL */ 658 const struct ia_css_frame_info *out_info[], /* can be NULL */ 659 const struct ia_css_frame_info *vf_info, /* can be NULL */ 660 struct ia_css_binary *binary, 661 struct ia_css_resolution *dvs_env, 662 int stream_config_left_padding, 663 bool accelerator) { 664 const struct ia_css_binary_info *info = &xinfo->sp; 665 unsigned int dvs_env_width = 0, 666 dvs_env_height = 0, 667 vf_log_ds = 0, 668 s3a_log_deci = 0, 669 bits_per_pixel = 0, 670 /* Resolution at SC/3A/DIS kernel. */ 671 sc_3a_dis_width = 0, 672 /* Resolution at SC/3A/DIS kernel. */ 673 sc_3a_dis_padded_width = 0, 674 /* Resolution at SC/3A/DIS kernel. */ 675 sc_3a_dis_height = 0, 676 isp_internal_width = 0, 677 isp_internal_height = 0, 678 s3a_isp_width = 0; 679 680 bool need_scaling = false; 681 struct ia_css_resolution binary_dvs_env, internal_res; 682 int err; 683 unsigned int i; 684 const struct ia_css_frame_info *bin_out_info = NULL; 685 686 assert(info); 687 assert(binary); 688 689 binary->info = xinfo; 690 if (!accelerator) 691 { 692 /* binary->css_params has been filled by accelerator itself. */ 693 err = ia_css_isp_param_allocate_isp_parameters( 694 &binary->mem_params, &binary->css_params, 695 &info->mem_initializers); 696 if (err) { 697 return err; 698 } 699 } 700 for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) 701 { 702 if (out_info[i] && (out_info[i]->res.width != 0)) { 703 bin_out_info = out_info[i]; 704 break; 705 } 706 } 707 if (in_info && bin_out_info) 708 { 709 need_scaling = (in_info->res.width != bin_out_info->res.width) || 710 (in_info->res.height != bin_out_info->res.height); 711 } 712 713 /* binary_dvs_env has to be equal or larger than SH_CSS_MIN_DVS_ENVELOPE */ 714 binary_dvs_env.width = 0; 715 binary_dvs_env.height = 0; 716 ia_css_binary_dvs_env(info, dvs_env, &binary_dvs_env); 717 dvs_env_width = binary_dvs_env.width; 718 dvs_env_height = binary_dvs_env.height; 719 binary->dvs_envelope.width = dvs_env_width; 720 binary->dvs_envelope.height = dvs_env_height; 721 722 /* internal resolution calculation */ 723 internal_res.width = 0; 724 internal_res.height = 0; 725 ia_css_binary_internal_res(in_info, bds_out_info, bin_out_info, dvs_env, 726 info, &internal_res); 727 isp_internal_width = internal_res.width; 728 isp_internal_height = internal_res.height; 729 730 /* internal frame info */ 731 if (bin_out_info) /* { */ 732 binary->internal_frame_info.format = bin_out_info->format; 733 /* } */ 734 binary->internal_frame_info.res.width = isp_internal_width; 735 binary->internal_frame_info.padded_width = CEIL_MUL(isp_internal_width, 2 * ISP_VEC_NELEMS); 736 binary->internal_frame_info.res.height = isp_internal_height; 737 binary->internal_frame_info.raw_bit_depth = bits_per_pixel; 738 739 if (in_info) 740 { 741 binary->effective_in_frame_res.width = in_info->res.width; 742 binary->effective_in_frame_res.height = in_info->res.height; 743 744 bits_per_pixel = in_info->raw_bit_depth; 745 746 /* input info */ 747 binary->in_frame_info.res.width = in_info->res.width + 748 info->pipeline.left_cropping; 749 binary->in_frame_info.res.height = in_info->res.height + 750 info->pipeline.top_cropping; 751 752 binary->in_frame_info.res.width += dvs_env_width; 753 binary->in_frame_info.res.height += dvs_env_height; 754 755 binary->in_frame_info.padded_width = 756 binary_in_frame_padded_width(in_info->res.width, 757 isp_internal_width, 758 dvs_env_width, 759 stream_config_left_padding, 760 info->pipeline.left_cropping, 761 need_scaling); 762 763 binary->in_frame_info.format = in_info->format; 764 binary->in_frame_info.raw_bayer_order = in_info->raw_bayer_order; 765 binary->in_frame_info.crop_info = in_info->crop_info; 766 } 767 768 if (online) 769 { 770 bits_per_pixel = ia_css_util_input_format_bpp( 771 stream_format, two_ppc); 772 } 773 binary->in_frame_info.raw_bit_depth = bits_per_pixel; 774 775 for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) 776 { 777 if (out_info[i]) { 778 binary->out_frame_info[i].res.width = out_info[i]->res.width; 779 binary->out_frame_info[i].res.height = out_info[i]->res.height; 780 binary->out_frame_info[i].padded_width = out_info[i]->padded_width; 781 if (info->pipeline.mode == IA_CSS_BINARY_MODE_COPY) { 782 binary->out_frame_info[i].raw_bit_depth = bits_per_pixel; 783 } else { 784 /* Only relevant for RAW format. 785 * At the moment, all outputs are raw, 16 bit per pixel, except for copy. 786 * To do this cleanly, the binary should specify in its info 787 * the bit depth per output channel. 788 */ 789 binary->out_frame_info[i].raw_bit_depth = 16; 790 } 791 binary->out_frame_info[i].format = out_info[i]->format; 792 } 793 } 794 795 if (vf_info && (vf_info->res.width != 0)) 796 { 797 err = ia_css_vf_configure(binary, bin_out_info, 798 (struct ia_css_frame_info *)vf_info, &vf_log_ds); 799 if (err) { 800 if (!accelerator) { 801 ia_css_isp_param_destroy_isp_parameters( 802 &binary->mem_params, 803 &binary->css_params); 804 } 805 return err; 806 } 807 } 808 binary->vf_downscale_log2 = vf_log_ds; 809 810 binary->online = online; 811 binary->input_format = stream_format; 812 813 /* viewfinder output info */ 814 if ((vf_info) && (vf_info->res.width != 0)) 815 { 816 unsigned int vf_out_vecs, vf_out_width, vf_out_height; 817 818 binary->vf_frame_info.format = vf_info->format; 819 if (!bin_out_info) 820 return -EINVAL; 821 vf_out_vecs = __ISP_VF_OUTPUT_WIDTH_VECS(bin_out_info->padded_width, 822 vf_log_ds); 823 vf_out_width = _ISP_VF_OUTPUT_WIDTH(vf_out_vecs); 824 vf_out_height = _ISP_VF_OUTPUT_HEIGHT(bin_out_info->res.height, 825 vf_log_ds); 826 827 /* For preview mode, output pin is used instead of vf. */ 828 if (info->pipeline.mode == IA_CSS_BINARY_MODE_PREVIEW) { 829 binary->out_frame_info[0].res.width = 830 (bin_out_info->res.width >> vf_log_ds); 831 binary->out_frame_info[0].padded_width = vf_out_width; 832 binary->out_frame_info[0].res.height = vf_out_height; 833 834 binary->vf_frame_info.res.width = 0; 835 binary->vf_frame_info.padded_width = 0; 836 binary->vf_frame_info.res.height = 0; 837 } else { 838 /* we also store the raw downscaled width. This is 839 * used for digital zoom in preview to zoom only on 840 * the width that we actually want to keep, not on 841 * the aligned width. */ 842 binary->vf_frame_info.res.width = 843 (bin_out_info->res.width >> vf_log_ds); 844 binary->vf_frame_info.padded_width = vf_out_width; 845 binary->vf_frame_info.res.height = vf_out_height; 846 } 847 } else 848 { 849 binary->vf_frame_info.res.width = 0; 850 binary->vf_frame_info.padded_width = 0; 851 binary->vf_frame_info.res.height = 0; 852 } 853 854 if (info->enable.ca_gdc) 855 { 856 binary->morph_tbl_width = 857 _ISP_MORPH_TABLE_WIDTH(isp_internal_width); 858 binary->morph_tbl_aligned_width = 859 _ISP_MORPH_TABLE_ALIGNED_WIDTH(isp_internal_width); 860 binary->morph_tbl_height = 861 _ISP_MORPH_TABLE_HEIGHT(isp_internal_height); 862 } else 863 { 864 binary->morph_tbl_width = 0; 865 binary->morph_tbl_aligned_width = 0; 866 binary->morph_tbl_height = 0; 867 } 868 869 sc_3a_dis_width = binary->in_frame_info.res.width; 870 sc_3a_dis_padded_width = binary->in_frame_info.padded_width; 871 sc_3a_dis_height = binary->in_frame_info.res.height; 872 if (bds_out_info && in_info && 873 bds_out_info->res.width != in_info->res.width) 874 { 875 /* TODO: Next, "internal_frame_info" should be derived from 876 * bds_out. So this part will change once it is in place! */ 877 sc_3a_dis_width = bds_out_info->res.width + info->pipeline.left_cropping; 878 sc_3a_dis_padded_width = isp_internal_width; 879 sc_3a_dis_height = isp_internal_height; 880 } 881 882 s3a_isp_width = _ISP_S3A_ELEMS_ISP_WIDTH(sc_3a_dis_padded_width, 883 info->pipeline.left_cropping); 884 if (info->s3a.fixed_s3a_deci_log) 885 { 886 s3a_log_deci = info->s3a.fixed_s3a_deci_log; 887 } else 888 { 889 s3a_log_deci = binary_grid_deci_factor_log2(s3a_isp_width, 890 sc_3a_dis_height); 891 } 892 binary->deci_factor_log2 = s3a_log_deci; 893 894 if (info->enable.s3a) 895 { 896 binary->s3atbl_width = 897 _ISP_S3ATBL_WIDTH(sc_3a_dis_width, 898 s3a_log_deci); 899 binary->s3atbl_height = 900 _ISP_S3ATBL_HEIGHT(sc_3a_dis_height, 901 s3a_log_deci); 902 binary->s3atbl_isp_width = 903 _ISP_S3ATBL_ISP_WIDTH(s3a_isp_width, 904 s3a_log_deci); 905 binary->s3atbl_isp_height = 906 _ISP_S3ATBL_ISP_HEIGHT(sc_3a_dis_height, 907 s3a_log_deci); 908 } else 909 { 910 binary->s3atbl_width = 0; 911 binary->s3atbl_height = 0; 912 binary->s3atbl_isp_width = 0; 913 binary->s3atbl_isp_height = 0; 914 } 915 916 if (info->enable.sc) 917 { 918 binary->sctbl_width_per_color = _ISP_SCTBL_WIDTH_PER_COLOR(sc_3a_dis_padded_width, s3a_log_deci); 919 binary->sctbl_aligned_width_per_color = SH_CSS_MAX_SCTBL_ALIGNED_WIDTH_PER_COLOR; 920 binary->sctbl_height = _ISP_SCTBL_HEIGHT(sc_3a_dis_height, s3a_log_deci); 921 } else 922 { 923 binary->sctbl_width_per_color = 0; 924 binary->sctbl_aligned_width_per_color = 0; 925 binary->sctbl_height = 0; 926 } 927 ia_css_sdis_init_info(&binary->dis, 928 sc_3a_dis_width, 929 sc_3a_dis_padded_width, 930 sc_3a_dis_height, 931 info->pipeline.isp_pipe_version, 932 info->enable.dis); 933 if (info->pipeline.left_cropping) 934 binary->left_padding = 2 * ISP_VEC_NELEMS - info->pipeline.left_cropping; 935 else 936 binary->left_padding = 0; 937 938 return 0; 939 } 940 941 static int __ia_css_binary_find(struct ia_css_binary_descr *descr, 942 struct ia_css_binary *binary) { 943 int mode; 944 bool online; 945 bool two_ppc; 946 enum atomisp_input_format stream_format; 947 const struct ia_css_frame_info *req_in_info, 948 *req_bds_out_info, 949 *req_out_info[IA_CSS_BINARY_MAX_OUTPUT_PORTS], 950 *req_bin_out_info = NULL, 951 *req_vf_info; 952 953 struct ia_css_binary_xinfo *xcandidate; 954 bool need_ds, need_dz, need_dvs, need_xnr, need_dpc; 955 bool striped; 956 bool enable_yuv_ds; 957 bool enable_high_speed; 958 bool enable_dvs_6axis; 959 bool enable_reduced_pipe; 960 bool enable_capture_pp_bli; 961 int err = -EINVAL; 962 bool continuous; 963 unsigned int isp_pipe_version; 964 struct ia_css_resolution dvs_env, internal_res; 965 unsigned int i; 966 967 assert(descr); 968 /* MW: used after an error check, may accept NULL, but doubtfull */ 969 assert(binary); 970 971 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 972 "ia_css_binary_find() enter: descr=%p, (mode=%d), binary=%p\n", 973 descr, descr->mode, 974 binary); 975 976 mode = descr->mode; 977 online = descr->online; 978 two_ppc = descr->two_ppc; 979 stream_format = descr->stream_format; 980 req_in_info = descr->in_info; 981 req_bds_out_info = descr->bds_out_info; 982 for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) { 983 req_out_info[i] = descr->out_info[i]; 984 if (req_out_info[i] && (req_out_info[i]->res.width != 0)) 985 req_bin_out_info = req_out_info[i]; 986 } 987 if (!req_bin_out_info) 988 return -EINVAL; 989 req_vf_info = descr->vf_info; 990 991 need_xnr = descr->enable_xnr; 992 need_ds = descr->enable_fractional_ds; 993 need_dz = false; 994 need_dvs = false; 995 need_dpc = descr->enable_dpc; 996 997 enable_yuv_ds = descr->enable_yuv_ds; 998 enable_high_speed = descr->enable_high_speed; 999 enable_dvs_6axis = descr->enable_dvs_6axis; 1000 enable_reduced_pipe = descr->enable_reduced_pipe; 1001 enable_capture_pp_bli = descr->enable_capture_pp_bli; 1002 continuous = descr->continuous; 1003 striped = descr->striped; 1004 isp_pipe_version = descr->isp_pipe_version; 1005 1006 dvs_env.width = 0; 1007 dvs_env.height = 0; 1008 internal_res.width = 0; 1009 internal_res.height = 0; 1010 1011 if (mode == IA_CSS_BINARY_MODE_VIDEO) { 1012 dvs_env = descr->dvs_env; 1013 need_dz = descr->enable_dz; 1014 /* Video is the only mode that has a nodz variant. */ 1015 need_dvs = dvs_env.width || dvs_env.height; 1016 } 1017 1018 /* print a map of the binary file */ 1019 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "BINARY INFO:\n"); 1020 for (i = 0; i < IA_CSS_BINARY_NUM_MODES; i++) { 1021 xcandidate = binary_infos[i]; 1022 if (xcandidate) { 1023 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "%d:\n", i); 1024 while (xcandidate) { 1025 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, " Name:%s Type:%d Cont:%d\n", 1026 xcandidate->blob->name, xcandidate->type, 1027 xcandidate->sp.enable.continuous); 1028 xcandidate = xcandidate->next; 1029 } 1030 } 1031 } 1032 1033 /* printf("sh_css_binary_find: pipe version %d\n", isp_pipe_version); */ 1034 for (xcandidate = binary_infos[mode]; xcandidate; 1035 xcandidate = xcandidate->next) { 1036 struct ia_css_binary_info *candidate = &xcandidate->sp; 1037 /* printf("sh_css_binary_find: evaluating candidate: 1038 * %d\n",candidate->id); */ 1039 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1040 "ia_css_binary_find() candidate = %p, mode = %d ID = %d\n", 1041 candidate, candidate->pipeline.mode, candidate->id); 1042 1043 /* 1044 * MW: Only a limited set of jointly configured binaries can 1045 * be used in a continuous preview/video mode unless it is 1046 * the copy mode and runs on SP. 1047 */ 1048 if (!candidate->enable.continuous && 1049 continuous && (mode != IA_CSS_BINARY_MODE_COPY)) { 1050 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1051 "ia_css_binary_find() [%d] continue: !%d && %d && (%d != %d)\n", 1052 __LINE__, candidate->enable.continuous, 1053 continuous, mode, 1054 IA_CSS_BINARY_MODE_COPY); 1055 continue; 1056 } 1057 if (striped && candidate->iterator.num_stripes == 1) { 1058 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1059 "ia_css_binary_find() [%d] continue: binary is not striped\n", 1060 __LINE__); 1061 continue; 1062 } 1063 1064 if (candidate->pipeline.isp_pipe_version != isp_pipe_version && 1065 (mode != IA_CSS_BINARY_MODE_COPY) && 1066 (mode != IA_CSS_BINARY_MODE_CAPTURE_PP) && 1067 (mode != IA_CSS_BINARY_MODE_VF_PP)) { 1068 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1069 "ia_css_binary_find() [%d] continue: (%d != %d)\n", 1070 __LINE__, 1071 candidate->pipeline.isp_pipe_version, isp_pipe_version); 1072 continue; 1073 } 1074 if (!candidate->enable.reduced_pipe && enable_reduced_pipe) { 1075 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1076 "ia_css_binary_find() [%d] continue: !%d && %d\n", 1077 __LINE__, 1078 candidate->enable.reduced_pipe, 1079 enable_reduced_pipe); 1080 continue; 1081 } 1082 if (!candidate->enable.dvs_6axis && enable_dvs_6axis) { 1083 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1084 "ia_css_binary_find() [%d] continue: !%d && %d\n", 1085 __LINE__, 1086 candidate->enable.dvs_6axis, 1087 enable_dvs_6axis); 1088 continue; 1089 } 1090 if (candidate->enable.high_speed && !enable_high_speed) { 1091 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1092 "ia_css_binary_find() [%d] continue: %d && !%d\n", 1093 __LINE__, 1094 candidate->enable.high_speed, 1095 enable_high_speed); 1096 continue; 1097 } 1098 if (!candidate->enable.xnr && need_xnr) { 1099 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1100 "ia_css_binary_find() [%d] continue: %d && !%d\n", 1101 __LINE__, 1102 candidate->enable.xnr, 1103 need_xnr); 1104 continue; 1105 } 1106 if (!(candidate->enable.ds & 2) && enable_yuv_ds) { 1107 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1108 "ia_css_binary_find() [%d] continue: !%d && %d\n", 1109 __LINE__, 1110 ((candidate->enable.ds & 2) != 0), 1111 enable_yuv_ds); 1112 continue; 1113 } 1114 if ((candidate->enable.ds & 2) && !enable_yuv_ds) { 1115 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1116 "ia_css_binary_find() [%d] continue: %d && !%d\n", 1117 __LINE__, 1118 ((candidate->enable.ds & 2) != 0), 1119 enable_yuv_ds); 1120 continue; 1121 } 1122 1123 if (mode == IA_CSS_BINARY_MODE_VIDEO && 1124 candidate->enable.ds && need_ds) 1125 need_dz = false; 1126 1127 /* when we require vf output, we need to have vf_veceven */ 1128 if ((req_vf_info) && !(candidate->enable.vf_veceven || 1129 /* or variable vf vec even */ 1130 candidate->vf_dec.is_variable || 1131 /* or more than one output pin. */ 1132 xcandidate->num_output_pins > 1)) { 1133 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1134 "ia_css_binary_find() [%d] continue: (%p != NULL) && !(%d || %d || (%d >%d))\n", 1135 __LINE__, req_vf_info, 1136 candidate->enable.vf_veceven, 1137 candidate->vf_dec.is_variable, 1138 xcandidate->num_output_pins, 1); 1139 continue; 1140 } 1141 if (!candidate->enable.dvs_envelope && need_dvs) { 1142 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1143 "ia_css_binary_find() [%d] continue: !%d && %d\n", 1144 __LINE__, 1145 candidate->enable.dvs_envelope, (int)need_dvs); 1146 continue; 1147 } 1148 /* internal_res check considers input, output, and dvs envelope sizes */ 1149 ia_css_binary_internal_res(req_in_info, req_bds_out_info, 1150 req_bin_out_info, &dvs_env, candidate, &internal_res); 1151 if (internal_res.width > candidate->internal.max_width) { 1152 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1153 "ia_css_binary_find() [%d] continue: (%d > %d)\n", 1154 __LINE__, internal_res.width, 1155 candidate->internal.max_width); 1156 continue; 1157 } 1158 if (internal_res.height > candidate->internal.max_height) { 1159 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1160 "ia_css_binary_find() [%d] continue: (%d > %d)\n", 1161 __LINE__, internal_res.height, 1162 candidate->internal.max_height); 1163 continue; 1164 } 1165 if (!candidate->enable.ds && need_ds && !(xcandidate->num_output_pins > 1)) { 1166 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1167 "ia_css_binary_find() [%d] continue: !%d && %d\n", 1168 __LINE__, candidate->enable.ds, (int)need_ds); 1169 continue; 1170 } 1171 if (!candidate->enable.uds && !candidate->enable.dvs_6axis && need_dz) { 1172 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1173 "ia_css_binary_find() [%d] continue: !%d && !%d && %d\n", 1174 __LINE__, candidate->enable.uds, 1175 candidate->enable.dvs_6axis, (int)need_dz); 1176 continue; 1177 } 1178 if (online && candidate->input.source == IA_CSS_BINARY_INPUT_MEMORY) { 1179 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1180 "ia_css_binary_find() [%d] continue: %d && (%d == %d)\n", 1181 __LINE__, online, candidate->input.source, 1182 IA_CSS_BINARY_INPUT_MEMORY); 1183 continue; 1184 } 1185 if (!online && candidate->input.source == IA_CSS_BINARY_INPUT_SENSOR) { 1186 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1187 "ia_css_binary_find() [%d] continue: !%d && (%d == %d)\n", 1188 __LINE__, online, candidate->input.source, 1189 IA_CSS_BINARY_INPUT_SENSOR); 1190 continue; 1191 } 1192 if (req_bin_out_info->res.width < candidate->output.min_width || 1193 req_bin_out_info->res.width > candidate->output.max_width) { 1194 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1195 "ia_css_binary_find() [%d] continue: (%d > %d) || (%d < %d)\n", 1196 __LINE__, 1197 req_bin_out_info->padded_width, 1198 candidate->output.min_width, 1199 req_bin_out_info->padded_width, 1200 candidate->output.max_width); 1201 continue; 1202 } 1203 if (xcandidate->num_output_pins > 1 && 1204 /* in case we have a second output pin, */ 1205 req_vf_info) { /* and we need vf output. */ 1206 if (req_vf_info->res.width > candidate->output.max_width) { 1207 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1208 "ia_css_binary_find() [%d] continue: (%d < %d)\n", 1209 __LINE__, 1210 req_vf_info->res.width, 1211 candidate->output.max_width); 1212 continue; 1213 } 1214 } 1215 if (req_in_info->padded_width > candidate->input.max_width) { 1216 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1217 "ia_css_binary_find() [%d] continue: (%d > %d)\n", 1218 __LINE__, req_in_info->padded_width, 1219 candidate->input.max_width); 1220 continue; 1221 } 1222 if (!binary_supports_output_format(xcandidate, req_bin_out_info->format)) { 1223 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1224 "ia_css_binary_find() [%d] continue: !%d\n", 1225 __LINE__, 1226 binary_supports_output_format(xcandidate, req_bin_out_info->format)); 1227 continue; 1228 } 1229 if (xcandidate->num_output_pins > 1 && 1230 /* in case we have a second output pin, */ 1231 req_vf_info && /* and we need vf output. */ 1232 /* check if the required vf format 1233 is supported. */ 1234 !binary_supports_output_format(xcandidate, req_vf_info->format)) { 1235 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1236 "ia_css_binary_find() [%d] continue: (%d > %d) && (%p != NULL) && !%d\n", 1237 __LINE__, xcandidate->num_output_pins, 1, 1238 req_vf_info, 1239 binary_supports_output_format(xcandidate, req_vf_info->format)); 1240 continue; 1241 } 1242 1243 /* Check if vf_veceven supports the requested vf format */ 1244 if (xcandidate->num_output_pins == 1 && 1245 req_vf_info && candidate->enable.vf_veceven && 1246 !binary_supports_vf_format(xcandidate, req_vf_info->format)) { 1247 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1248 "ia_css_binary_find() [%d] continue: (%d == %d) && (%p != NULL) && %d && !%d\n", 1249 __LINE__, xcandidate->num_output_pins, 1, 1250 req_vf_info, candidate->enable.vf_veceven, 1251 binary_supports_vf_format(xcandidate, req_vf_info->format)); 1252 continue; 1253 } 1254 1255 /* Check if vf_veceven supports the requested vf width */ 1256 if (xcandidate->num_output_pins == 1 && 1257 req_vf_info && candidate->enable.vf_veceven) { /* and we need vf output. */ 1258 if (req_vf_info->res.width > candidate->output.max_width) { 1259 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1260 "ia_css_binary_find() [%d] continue: (%d < %d)\n", 1261 __LINE__, 1262 req_vf_info->res.width, 1263 candidate->output.max_width); 1264 continue; 1265 } 1266 } 1267 1268 if (!supports_bds_factor(candidate->bds.supported_bds_factors, 1269 descr->required_bds_factor)) { 1270 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1271 "ia_css_binary_find() [%d] continue: 0x%x & 0x%x)\n", 1272 __LINE__, candidate->bds.supported_bds_factors, 1273 descr->required_bds_factor); 1274 continue; 1275 } 1276 1277 if (!candidate->enable.dpc && need_dpc) { 1278 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1279 "ia_css_binary_find() [%d] continue: 0x%x & 0x%x)\n", 1280 __LINE__, candidate->enable.dpc, 1281 descr->enable_dpc); 1282 continue; 1283 } 1284 1285 if (candidate->uds.use_bci && enable_capture_pp_bli) { 1286 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1287 "ia_css_binary_find() [%d] continue: 0x%x & 0x%x)\n", 1288 __LINE__, candidate->uds.use_bci, 1289 descr->enable_capture_pp_bli); 1290 continue; 1291 } 1292 1293 /* reconfigure any variable properties of the binary */ 1294 err = ia_css_binary_fill_info(xcandidate, online, two_ppc, 1295 stream_format, req_in_info, 1296 req_bds_out_info, 1297 req_out_info, req_vf_info, 1298 binary, &dvs_env, 1299 descr->stream_config_left_padding, 1300 false); 1301 1302 if (err) 1303 break; 1304 binary_init_metrics(&binary->metrics, &binary->info->sp); 1305 break; 1306 } 1307 1308 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1309 "ia_css_binary_find() selected = %p, mode = %d ID = %d\n", 1310 xcandidate, xcandidate ? xcandidate->sp.pipeline.mode : 0, xcandidate ? xcandidate->sp.id : 0); 1311 1312 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1313 "ia_css_binary_find() leave: return_err=%d\n", err); 1314 1315 if (!err && xcandidate) 1316 dev_dbg(atomisp_dev, 1317 "Using binary %s (id %d), type %d, mode %d, continuous %s\n", 1318 xcandidate->blob->name, 1319 xcandidate->sp.id, 1320 xcandidate->type, 1321 xcandidate->sp.pipeline.mode, 1322 xcandidate->sp.enable.continuous ? "true" : "false"); 1323 1324 1325 return err; 1326 } 1327 1328 int ia_css_binary_find(struct ia_css_binary_descr *descr, 1329 struct ia_css_binary *binary) 1330 { 1331 int ret = __ia_css_binary_find(descr, binary); 1332 1333 if (unlikely(ret)) { 1334 dev_dbg(atomisp_dev, "Seeking for binary failed at:"); 1335 dump_stack(); 1336 } 1337 1338 return ret; 1339 } 1340 1341 unsigned 1342 ia_css_binary_max_vf_width(void) 1343 { 1344 /* This is (should be) true for IPU1 and IPU2 */ 1345 /* For IPU3 (SkyCam) this pointer is guaranteed to be NULL simply because such a binary does not exist */ 1346 if (binary_infos[IA_CSS_BINARY_MODE_VF_PP]) 1347 return binary_infos[IA_CSS_BINARY_MODE_VF_PP]->sp.output.max_width; 1348 return 0; 1349 } 1350 1351 void 1352 ia_css_binary_destroy_isp_parameters(struct ia_css_binary *binary) 1353 { 1354 if (binary) { 1355 ia_css_isp_param_destroy_isp_parameters(&binary->mem_params, 1356 &binary->css_params); 1357 } 1358 } 1359 1360 void 1361 ia_css_binary_get_isp_binaries(struct ia_css_binary_xinfo **binaries, 1362 uint32_t *num_isp_binaries) 1363 { 1364 assert(binaries); 1365 1366 if (num_isp_binaries) 1367 *num_isp_binaries = 0; 1368 1369 *binaries = all_binaries; 1370 if (all_binaries && num_isp_binaries) { 1371 /* -1 to account for sp binary which is not stored in all_binaries */ 1372 if (sh_css_num_binaries > 0) 1373 *num_isp_binaries = sh_css_num_binaries - 1; 1374 } 1375 } 1376