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