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 defined(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 #endif
614 if (need_scaling) {
615 /* In SDV use-case, we need to match left-padding of
616 * primary and the video binary. */
617 if (stream_config_left_padding != -1) {
618 /* Different than before, we do left&right padding. */
619 rval =
620 CEIL_MUL(in_frame_width + nr_of_left_paddings,
621 2 * ISP_VEC_NELEMS);
622 } else {
623 /* Different than before, we do left&right padding. */
624 in_frame_width += dvs_env_width;
625 rval =
626 CEIL_MUL(in_frame_width +
627 (left_cropping ? nr_of_left_paddings : 0),
628 2 * ISP_VEC_NELEMS);
629 }
630 } else {
631 rval = isp_internal_width;
632 }
633
634 return rval;
635 }
636
637 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)638 ia_css_binary_fill_info(const struct ia_css_binary_xinfo *xinfo,
639 bool online,
640 bool two_ppc,
641 enum atomisp_input_format stream_format,
642 const struct ia_css_frame_info *in_info, /* can be NULL */
643 const struct ia_css_frame_info *bds_out_info, /* can be NULL */
644 const struct ia_css_frame_info *out_info[], /* can be NULL */
645 const struct ia_css_frame_info *vf_info, /* can be NULL */
646 struct ia_css_binary *binary,
647 struct ia_css_resolution *dvs_env,
648 int stream_config_left_padding,
649 bool accelerator) {
650 const struct ia_css_binary_info *info = &xinfo->sp;
651 unsigned int dvs_env_width = 0,
652 dvs_env_height = 0,
653 vf_log_ds = 0,
654 s3a_log_deci = 0,
655 bits_per_pixel = 0,
656 /* Resolution at SC/3A/DIS kernel. */
657 sc_3a_dis_width = 0,
658 /* Resolution at SC/3A/DIS kernel. */
659 sc_3a_dis_padded_width = 0,
660 /* Resolution at SC/3A/DIS kernel. */
661 sc_3a_dis_height = 0,
662 isp_internal_width = 0,
663 isp_internal_height = 0,
664 s3a_isp_width = 0;
665
666 bool need_scaling = false;
667 struct ia_css_resolution binary_dvs_env, internal_res;
668 int err;
669 unsigned int i;
670 const struct ia_css_frame_info *bin_out_info = NULL;
671
672 assert(info);
673 assert(binary);
674
675 binary->info = xinfo;
676 if (!accelerator)
677 {
678 /* binary->css_params has been filled by accelerator itself. */
679 err = ia_css_isp_param_allocate_isp_parameters(
680 &binary->mem_params, &binary->css_params,
681 &info->mem_initializers);
682 if (err) {
683 return err;
684 }
685 }
686 for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
687 {
688 if (out_info[i] && (out_info[i]->res.width != 0)) {
689 bin_out_info = out_info[i];
690 break;
691 }
692 }
693 if (in_info && bin_out_info)
694 {
695 need_scaling = (in_info->res.width != bin_out_info->res.width) ||
696 (in_info->res.height != bin_out_info->res.height);
697 }
698
699 /* binary_dvs_env has to be equal or larger than SH_CSS_MIN_DVS_ENVELOPE */
700 binary_dvs_env.width = 0;
701 binary_dvs_env.height = 0;
702 ia_css_binary_dvs_env(info, dvs_env, &binary_dvs_env);
703 dvs_env_width = binary_dvs_env.width;
704 dvs_env_height = binary_dvs_env.height;
705 binary->dvs_envelope.width = dvs_env_width;
706 binary->dvs_envelope.height = dvs_env_height;
707
708 /* internal resolution calculation */
709 internal_res.width = 0;
710 internal_res.height = 0;
711 ia_css_binary_internal_res(in_info, bds_out_info, bin_out_info, dvs_env,
712 info, &internal_res);
713 isp_internal_width = internal_res.width;
714 isp_internal_height = internal_res.height;
715
716 /* internal frame info */
717 if (bin_out_info) /* { */
718 binary->internal_frame_info.format = bin_out_info->format;
719 /* } */
720 binary->internal_frame_info.res.width = isp_internal_width;
721 binary->internal_frame_info.padded_width = CEIL_MUL(isp_internal_width, 2 * ISP_VEC_NELEMS);
722 binary->internal_frame_info.res.height = isp_internal_height;
723 binary->internal_frame_info.raw_bit_depth = bits_per_pixel;
724
725 if (in_info)
726 {
727 binary->effective_in_frame_res.width = in_info->res.width;
728 binary->effective_in_frame_res.height = in_info->res.height;
729
730 bits_per_pixel = in_info->raw_bit_depth;
731
732 /* input info */
733 binary->in_frame_info.res.width = in_info->res.width +
734 info->pipeline.left_cropping;
735 binary->in_frame_info.res.height = in_info->res.height +
736 info->pipeline.top_cropping;
737
738 binary->in_frame_info.res.width += dvs_env_width;
739 binary->in_frame_info.res.height += dvs_env_height;
740
741 binary->in_frame_info.padded_width =
742 binary_in_frame_padded_width(in_info->res.width,
743 isp_internal_width,
744 dvs_env_width,
745 stream_config_left_padding,
746 info->pipeline.left_cropping,
747 need_scaling);
748
749 binary->in_frame_info.format = in_info->format;
750 binary->in_frame_info.raw_bayer_order = in_info->raw_bayer_order;
751 binary->in_frame_info.crop_info = in_info->crop_info;
752 }
753
754 if (online)
755 {
756 bits_per_pixel = ia_css_util_input_format_bpp(
757 stream_format, two_ppc);
758 }
759 binary->in_frame_info.raw_bit_depth = bits_per_pixel;
760
761 for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
762 {
763 if (out_info[i]) {
764 binary->out_frame_info[i].res.width = out_info[i]->res.width;
765 binary->out_frame_info[i].res.height = out_info[i]->res.height;
766 binary->out_frame_info[i].padded_width = out_info[i]->padded_width;
767 if (info->pipeline.mode == IA_CSS_BINARY_MODE_COPY) {
768 binary->out_frame_info[i].raw_bit_depth = bits_per_pixel;
769 } else {
770 /* Only relevant for RAW format.
771 * At the moment, all outputs are raw, 16 bit per pixel, except for copy.
772 * To do this cleanly, the binary should specify in its info
773 * the bit depth per output channel.
774 */
775 binary->out_frame_info[i].raw_bit_depth = 16;
776 }
777 binary->out_frame_info[i].format = out_info[i]->format;
778 }
779 }
780
781 if (vf_info && (vf_info->res.width != 0))
782 {
783 err = ia_css_vf_configure(binary, bin_out_info,
784 (struct ia_css_frame_info *)vf_info, &vf_log_ds);
785 if (err) {
786 if (!accelerator) {
787 ia_css_isp_param_destroy_isp_parameters(
788 &binary->mem_params,
789 &binary->css_params);
790 }
791 return err;
792 }
793 }
794 binary->vf_downscale_log2 = vf_log_ds;
795
796 binary->online = online;
797 binary->input_format = stream_format;
798
799 /* viewfinder output info */
800 if ((vf_info) && (vf_info->res.width != 0))
801 {
802 unsigned int vf_out_vecs, vf_out_width, vf_out_height;
803
804 binary->vf_frame_info.format = vf_info->format;
805 if (!bin_out_info)
806 return -EINVAL;
807 vf_out_vecs = __ISP_VF_OUTPUT_WIDTH_VECS(bin_out_info->padded_width,
808 vf_log_ds);
809 vf_out_width = _ISP_VF_OUTPUT_WIDTH(vf_out_vecs);
810 vf_out_height = _ISP_VF_OUTPUT_HEIGHT(bin_out_info->res.height,
811 vf_log_ds);
812
813 /* For preview mode, output pin is used instead of vf. */
814 if (info->pipeline.mode == IA_CSS_BINARY_MODE_PREVIEW) {
815 binary->out_frame_info[0].res.width =
816 (bin_out_info->res.width >> vf_log_ds);
817 binary->out_frame_info[0].padded_width = vf_out_width;
818 binary->out_frame_info[0].res.height = vf_out_height;
819
820 binary->vf_frame_info.res.width = 0;
821 binary->vf_frame_info.padded_width = 0;
822 binary->vf_frame_info.res.height = 0;
823 } else {
824 /* we also store the raw downscaled width. This is
825 * used for digital zoom in preview to zoom only on
826 * the width that we actually want to keep, not on
827 * the aligned width. */
828 binary->vf_frame_info.res.width =
829 (bin_out_info->res.width >> vf_log_ds);
830 binary->vf_frame_info.padded_width = vf_out_width;
831 binary->vf_frame_info.res.height = vf_out_height;
832 }
833 } else
834 {
835 binary->vf_frame_info.res.width = 0;
836 binary->vf_frame_info.padded_width = 0;
837 binary->vf_frame_info.res.height = 0;
838 }
839
840 if (info->enable.ca_gdc)
841 {
842 binary->morph_tbl_width =
843 _ISP_MORPH_TABLE_WIDTH(isp_internal_width);
844 binary->morph_tbl_aligned_width =
845 _ISP_MORPH_TABLE_ALIGNED_WIDTH(isp_internal_width);
846 binary->morph_tbl_height =
847 _ISP_MORPH_TABLE_HEIGHT(isp_internal_height);
848 } else
849 {
850 binary->morph_tbl_width = 0;
851 binary->morph_tbl_aligned_width = 0;
852 binary->morph_tbl_height = 0;
853 }
854
855 sc_3a_dis_width = binary->in_frame_info.res.width;
856 sc_3a_dis_padded_width = binary->in_frame_info.padded_width;
857 sc_3a_dis_height = binary->in_frame_info.res.height;
858 if (bds_out_info && in_info &&
859 bds_out_info->res.width != in_info->res.width)
860 {
861 /* TODO: Next, "internal_frame_info" should be derived from
862 * bds_out. So this part will change once it is in place! */
863 sc_3a_dis_width = bds_out_info->res.width + info->pipeline.left_cropping;
864 sc_3a_dis_padded_width = isp_internal_width;
865 sc_3a_dis_height = isp_internal_height;
866 }
867
868 s3a_isp_width = _ISP_S3A_ELEMS_ISP_WIDTH(sc_3a_dis_padded_width,
869 info->pipeline.left_cropping);
870 if (info->s3a.fixed_s3a_deci_log)
871 {
872 s3a_log_deci = info->s3a.fixed_s3a_deci_log;
873 } else
874 {
875 s3a_log_deci = binary_grid_deci_factor_log2(s3a_isp_width,
876 sc_3a_dis_height);
877 }
878 binary->deci_factor_log2 = s3a_log_deci;
879
880 if (info->enable.s3a)
881 {
882 binary->s3atbl_width =
883 _ISP_S3ATBL_WIDTH(sc_3a_dis_width,
884 s3a_log_deci);
885 binary->s3atbl_height =
886 _ISP_S3ATBL_HEIGHT(sc_3a_dis_height,
887 s3a_log_deci);
888 binary->s3atbl_isp_width =
889 _ISP_S3ATBL_ISP_WIDTH(s3a_isp_width,
890 s3a_log_deci);
891 binary->s3atbl_isp_height =
892 _ISP_S3ATBL_ISP_HEIGHT(sc_3a_dis_height,
893 s3a_log_deci);
894 } else
895 {
896 binary->s3atbl_width = 0;
897 binary->s3atbl_height = 0;
898 binary->s3atbl_isp_width = 0;
899 binary->s3atbl_isp_height = 0;
900 }
901
902 if (info->enable.sc)
903 {
904 binary->sctbl_width_per_color = _ISP_SCTBL_WIDTH_PER_COLOR(sc_3a_dis_padded_width, s3a_log_deci);
905 binary->sctbl_aligned_width_per_color = SH_CSS_MAX_SCTBL_ALIGNED_WIDTH_PER_COLOR;
906 binary->sctbl_height = _ISP_SCTBL_HEIGHT(sc_3a_dis_height, s3a_log_deci);
907 } else
908 {
909 binary->sctbl_width_per_color = 0;
910 binary->sctbl_aligned_width_per_color = 0;
911 binary->sctbl_height = 0;
912 }
913 ia_css_sdis_init_info(&binary->dis,
914 sc_3a_dis_width,
915 sc_3a_dis_padded_width,
916 sc_3a_dis_height,
917 info->pipeline.isp_pipe_version,
918 info->enable.dis);
919 if (info->pipeline.left_cropping)
920 binary->left_padding = 2 * ISP_VEC_NELEMS - info->pipeline.left_cropping;
921 else
922 binary->left_padding = 0;
923
924 return 0;
925 }
926
__ia_css_binary_find(struct ia_css_binary_descr * descr,struct ia_css_binary * binary)927 static int __ia_css_binary_find(struct ia_css_binary_descr *descr,
928 struct ia_css_binary *binary) {
929 int mode;
930 bool online;
931 bool two_ppc;
932 enum atomisp_input_format stream_format;
933 const struct ia_css_frame_info *req_in_info,
934 *req_bds_out_info,
935 *req_out_info[IA_CSS_BINARY_MAX_OUTPUT_PORTS],
936 *req_bin_out_info = NULL,
937 *req_vf_info;
938
939 struct ia_css_binary_xinfo *xcandidate;
940 bool need_ds, need_dz, need_dvs, need_xnr, need_dpc;
941 bool striped;
942 bool enable_yuv_ds;
943 bool enable_high_speed;
944 bool enable_dvs_6axis;
945 bool enable_reduced_pipe;
946 bool enable_capture_pp_bli;
947 int err = -EINVAL;
948 bool continuous;
949 unsigned int isp_pipe_version;
950 struct ia_css_resolution dvs_env, internal_res;
951 unsigned int i;
952
953 assert(descr);
954 /* MW: used after an error check, may accept NULL, but doubtfull */
955 assert(binary);
956
957 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
958 "ia_css_binary_find() enter: descr=%p, (mode=%d), binary=%p\n",
959 descr, descr->mode,
960 binary);
961
962 mode = descr->mode;
963 online = descr->online;
964 two_ppc = descr->two_ppc;
965 stream_format = descr->stream_format;
966 req_in_info = descr->in_info;
967 req_bds_out_info = descr->bds_out_info;
968 for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) {
969 req_out_info[i] = descr->out_info[i];
970 if (req_out_info[i] && (req_out_info[i]->res.width != 0))
971 req_bin_out_info = req_out_info[i];
972 }
973 if (!req_bin_out_info)
974 return -EINVAL;
975 req_vf_info = descr->vf_info;
976
977 need_xnr = descr->enable_xnr;
978 need_ds = descr->enable_fractional_ds;
979 need_dz = false;
980 need_dvs = false;
981 need_dpc = descr->enable_dpc;
982
983 enable_yuv_ds = descr->enable_yuv_ds;
984 enable_high_speed = descr->enable_high_speed;
985 enable_dvs_6axis = descr->enable_dvs_6axis;
986 enable_reduced_pipe = descr->enable_reduced_pipe;
987 enable_capture_pp_bli = descr->enable_capture_pp_bli;
988 continuous = descr->continuous;
989 striped = descr->striped;
990 isp_pipe_version = descr->isp_pipe_version;
991
992 dvs_env.width = 0;
993 dvs_env.height = 0;
994 internal_res.width = 0;
995 internal_res.height = 0;
996
997 if (mode == IA_CSS_BINARY_MODE_VIDEO) {
998 dvs_env = descr->dvs_env;
999 need_dz = descr->enable_dz;
1000 /* Video is the only mode that has a nodz variant. */
1001 need_dvs = dvs_env.width || dvs_env.height;
1002 }
1003
1004 /* print a map of the binary file */
1005 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "BINARY INFO:\n");
1006 for (i = 0; i < IA_CSS_BINARY_NUM_MODES; i++) {
1007 xcandidate = binary_infos[i];
1008 if (xcandidate) {
1009 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "%d:\n", i);
1010 while (xcandidate) {
1011 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, " Name:%s Type:%d Cont:%d\n",
1012 xcandidate->blob->name, xcandidate->type,
1013 xcandidate->sp.enable.continuous);
1014 xcandidate = xcandidate->next;
1015 }
1016 }
1017 }
1018
1019 /* printf("sh_css_binary_find: pipe version %d\n", isp_pipe_version); */
1020 for (xcandidate = binary_infos[mode]; xcandidate;
1021 xcandidate = xcandidate->next) {
1022 struct ia_css_binary_info *candidate = &xcandidate->sp;
1023 /* printf("sh_css_binary_find: evaluating candidate:
1024 * %d\n",candidate->id); */
1025 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1026 "ia_css_binary_find() candidate = %p, mode = %d ID = %d\n",
1027 candidate, candidate->pipeline.mode, candidate->id);
1028
1029 /*
1030 * MW: Only a limited set of jointly configured binaries can
1031 * be used in a continuous preview/video mode unless it is
1032 * the copy mode and runs on SP.
1033 */
1034 if (!candidate->enable.continuous &&
1035 continuous && (mode != IA_CSS_BINARY_MODE_COPY)) {
1036 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1037 "ia_css_binary_find() [%d] continue: !%d && %d && (%d != %d)\n",
1038 __LINE__, candidate->enable.continuous,
1039 continuous, mode,
1040 IA_CSS_BINARY_MODE_COPY);
1041 continue;
1042 }
1043 if (striped && candidate->iterator.num_stripes == 1) {
1044 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1045 "ia_css_binary_find() [%d] continue: binary is not striped\n",
1046 __LINE__);
1047 continue;
1048 }
1049
1050 if (candidate->pipeline.isp_pipe_version != isp_pipe_version &&
1051 (mode != IA_CSS_BINARY_MODE_COPY) &&
1052 (mode != IA_CSS_BINARY_MODE_CAPTURE_PP) &&
1053 (mode != IA_CSS_BINARY_MODE_VF_PP)) {
1054 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1055 "ia_css_binary_find() [%d] continue: (%d != %d)\n",
1056 __LINE__,
1057 candidate->pipeline.isp_pipe_version, isp_pipe_version);
1058 continue;
1059 }
1060 if (!candidate->enable.reduced_pipe && enable_reduced_pipe) {
1061 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1062 "ia_css_binary_find() [%d] continue: !%d && %d\n",
1063 __LINE__,
1064 candidate->enable.reduced_pipe,
1065 enable_reduced_pipe);
1066 continue;
1067 }
1068 if (!candidate->enable.dvs_6axis && enable_dvs_6axis) {
1069 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1070 "ia_css_binary_find() [%d] continue: !%d && %d\n",
1071 __LINE__,
1072 candidate->enable.dvs_6axis,
1073 enable_dvs_6axis);
1074 continue;
1075 }
1076 if (candidate->enable.high_speed && !enable_high_speed) {
1077 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1078 "ia_css_binary_find() [%d] continue: %d && !%d\n",
1079 __LINE__,
1080 candidate->enable.high_speed,
1081 enable_high_speed);
1082 continue;
1083 }
1084 if (!candidate->enable.xnr && need_xnr) {
1085 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1086 "ia_css_binary_find() [%d] continue: %d && !%d\n",
1087 __LINE__,
1088 candidate->enable.xnr,
1089 need_xnr);
1090 continue;
1091 }
1092 if (!(candidate->enable.ds & 2) && enable_yuv_ds) {
1093 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1094 "ia_css_binary_find() [%d] continue: !%d && %d\n",
1095 __LINE__,
1096 ((candidate->enable.ds & 2) != 0),
1097 enable_yuv_ds);
1098 continue;
1099 }
1100 if ((candidate->enable.ds & 2) && !enable_yuv_ds) {
1101 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1102 "ia_css_binary_find() [%d] continue: %d && !%d\n",
1103 __LINE__,
1104 ((candidate->enable.ds & 2) != 0),
1105 enable_yuv_ds);
1106 continue;
1107 }
1108
1109 if (mode == IA_CSS_BINARY_MODE_VIDEO &&
1110 candidate->enable.ds && need_ds)
1111 need_dz = false;
1112
1113 /* when we require vf output, we need to have vf_veceven */
1114 if ((req_vf_info) && !(candidate->enable.vf_veceven ||
1115 /* or variable vf vec even */
1116 candidate->vf_dec.is_variable ||
1117 /* or more than one output pin. */
1118 xcandidate->num_output_pins > 1)) {
1119 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1120 "ia_css_binary_find() [%d] continue: (%p != NULL) && !(%d || %d || (%d >%d))\n",
1121 __LINE__, req_vf_info,
1122 candidate->enable.vf_veceven,
1123 candidate->vf_dec.is_variable,
1124 xcandidate->num_output_pins, 1);
1125 continue;
1126 }
1127 if (!candidate->enable.dvs_envelope && need_dvs) {
1128 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1129 "ia_css_binary_find() [%d] continue: !%d && %d\n",
1130 __LINE__,
1131 candidate->enable.dvs_envelope, (int)need_dvs);
1132 continue;
1133 }
1134 /* internal_res check considers input, output, and dvs envelope sizes */
1135 ia_css_binary_internal_res(req_in_info, req_bds_out_info,
1136 req_bin_out_info, &dvs_env, candidate, &internal_res);
1137 if (internal_res.width > candidate->internal.max_width) {
1138 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1139 "ia_css_binary_find() [%d] continue: (%d > %d)\n",
1140 __LINE__, internal_res.width,
1141 candidate->internal.max_width);
1142 continue;
1143 }
1144 if (internal_res.height > candidate->internal.max_height) {
1145 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1146 "ia_css_binary_find() [%d] continue: (%d > %d)\n",
1147 __LINE__, internal_res.height,
1148 candidate->internal.max_height);
1149 continue;
1150 }
1151 if (!candidate->enable.ds && need_ds && !(xcandidate->num_output_pins > 1)) {
1152 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1153 "ia_css_binary_find() [%d] continue: !%d && %d\n",
1154 __LINE__, candidate->enable.ds, (int)need_ds);
1155 continue;
1156 }
1157 if (!candidate->enable.uds && !candidate->enable.dvs_6axis && need_dz) {
1158 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1159 "ia_css_binary_find() [%d] continue: !%d && !%d && %d\n",
1160 __LINE__, candidate->enable.uds,
1161 candidate->enable.dvs_6axis, (int)need_dz);
1162 continue;
1163 }
1164 if (online && candidate->input.source == IA_CSS_BINARY_INPUT_MEMORY) {
1165 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1166 "ia_css_binary_find() [%d] continue: %d && (%d == %d)\n",
1167 __LINE__, online, candidate->input.source,
1168 IA_CSS_BINARY_INPUT_MEMORY);
1169 continue;
1170 }
1171 if (!online && candidate->input.source == IA_CSS_BINARY_INPUT_SENSOR) {
1172 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1173 "ia_css_binary_find() [%d] continue: !%d && (%d == %d)\n",
1174 __LINE__, online, candidate->input.source,
1175 IA_CSS_BINARY_INPUT_SENSOR);
1176 continue;
1177 }
1178 if (req_bin_out_info->res.width < candidate->output.min_width ||
1179 req_bin_out_info->res.width > candidate->output.max_width) {
1180 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1181 "ia_css_binary_find() [%d] continue: (%d > %d) || (%d < %d)\n",
1182 __LINE__,
1183 req_bin_out_info->padded_width,
1184 candidate->output.min_width,
1185 req_bin_out_info->padded_width,
1186 candidate->output.max_width);
1187 continue;
1188 }
1189 if (xcandidate->num_output_pins > 1 &&
1190 /* in case we have a second output pin, */
1191 req_vf_info) { /* and we need vf output. */
1192 if (req_vf_info->res.width > candidate->output.max_width) {
1193 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1194 "ia_css_binary_find() [%d] continue: (%d < %d)\n",
1195 __LINE__,
1196 req_vf_info->res.width,
1197 candidate->output.max_width);
1198 continue;
1199 }
1200 }
1201 if (req_in_info->padded_width > candidate->input.max_width) {
1202 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1203 "ia_css_binary_find() [%d] continue: (%d > %d)\n",
1204 __LINE__, req_in_info->padded_width,
1205 candidate->input.max_width);
1206 continue;
1207 }
1208 if (!binary_supports_output_format(xcandidate, req_bin_out_info->format)) {
1209 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1210 "ia_css_binary_find() [%d] continue: !%d\n",
1211 __LINE__,
1212 binary_supports_output_format(xcandidate, req_bin_out_info->format));
1213 continue;
1214 }
1215 if (xcandidate->num_output_pins > 1 &&
1216 /* in case we have a second output pin, */
1217 req_vf_info && /* and we need vf output. */
1218 /* check if the required vf format
1219 is supported. */
1220 !binary_supports_output_format(xcandidate, req_vf_info->format)) {
1221 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1222 "ia_css_binary_find() [%d] continue: (%d > %d) && (%p != NULL) && !%d\n",
1223 __LINE__, xcandidate->num_output_pins, 1,
1224 req_vf_info,
1225 binary_supports_output_format(xcandidate, req_vf_info->format));
1226 continue;
1227 }
1228
1229 /* Check if vf_veceven supports the requested vf format */
1230 if (xcandidate->num_output_pins == 1 &&
1231 req_vf_info && candidate->enable.vf_veceven &&
1232 !binary_supports_vf_format(xcandidate, req_vf_info->format)) {
1233 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1234 "ia_css_binary_find() [%d] continue: (%d == %d) && (%p != NULL) && %d && !%d\n",
1235 __LINE__, xcandidate->num_output_pins, 1,
1236 req_vf_info, candidate->enable.vf_veceven,
1237 binary_supports_vf_format(xcandidate, req_vf_info->format));
1238 continue;
1239 }
1240
1241 /* Check if vf_veceven supports the requested vf width */
1242 if (xcandidate->num_output_pins == 1 &&
1243 req_vf_info && candidate->enable.vf_veceven) { /* and we need vf output. */
1244 if (req_vf_info->res.width > candidate->output.max_width) {
1245 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1246 "ia_css_binary_find() [%d] continue: (%d < %d)\n",
1247 __LINE__,
1248 req_vf_info->res.width,
1249 candidate->output.max_width);
1250 continue;
1251 }
1252 }
1253
1254 if (!supports_bds_factor(candidate->bds.supported_bds_factors,
1255 descr->required_bds_factor)) {
1256 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1257 "ia_css_binary_find() [%d] continue: 0x%x & 0x%x)\n",
1258 __LINE__, candidate->bds.supported_bds_factors,
1259 descr->required_bds_factor);
1260 continue;
1261 }
1262
1263 if (!candidate->enable.dpc && need_dpc) {
1264 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1265 "ia_css_binary_find() [%d] continue: 0x%x & 0x%x)\n",
1266 __LINE__, candidate->enable.dpc,
1267 descr->enable_dpc);
1268 continue;
1269 }
1270
1271 if (candidate->uds.use_bci && enable_capture_pp_bli) {
1272 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1273 "ia_css_binary_find() [%d] continue: 0x%x & 0x%x)\n",
1274 __LINE__, candidate->uds.use_bci,
1275 descr->enable_capture_pp_bli);
1276 continue;
1277 }
1278
1279 /* reconfigure any variable properties of the binary */
1280 err = ia_css_binary_fill_info(xcandidate, online, two_ppc,
1281 stream_format, req_in_info,
1282 req_bds_out_info,
1283 req_out_info, req_vf_info,
1284 binary, &dvs_env,
1285 descr->stream_config_left_padding,
1286 false);
1287
1288 if (err)
1289 break;
1290 binary_init_metrics(&binary->metrics, &binary->info->sp);
1291 break;
1292 }
1293
1294 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1295 "ia_css_binary_find() selected = %p, mode = %d ID = %d\n",
1296 xcandidate, xcandidate ? xcandidate->sp.pipeline.mode : 0, xcandidate ? xcandidate->sp.id : 0);
1297
1298 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1299 "ia_css_binary_find() leave: return_err=%d\n", err);
1300
1301 if (!err && xcandidate)
1302 dev_dbg(atomisp_dev,
1303 "Using binary %s (id %d), type %d, mode %d, continuous %s\n",
1304 xcandidate->blob->name,
1305 xcandidate->sp.id,
1306 xcandidate->type,
1307 xcandidate->sp.pipeline.mode,
1308 xcandidate->sp.enable.continuous ? "true" : "false");
1309
1310
1311 return err;
1312 }
1313
ia_css_binary_find(struct ia_css_binary_descr * descr,struct ia_css_binary * binary)1314 int ia_css_binary_find(struct ia_css_binary_descr *descr,
1315 struct ia_css_binary *binary)
1316 {
1317 int ret = __ia_css_binary_find(descr, binary);
1318
1319 if (unlikely(ret)) {
1320 dev_dbg(atomisp_dev, "Seeking for binary failed at:");
1321 dump_stack();
1322 }
1323
1324 return ret;
1325 }
1326
1327 unsigned
ia_css_binary_max_vf_width(void)1328 ia_css_binary_max_vf_width(void)
1329 {
1330 /* This is (should be) true for IPU1 and IPU2 */
1331 /* For IPU3 (SkyCam) this pointer is guaranteed to be NULL simply because such a binary does not exist */
1332 if (binary_infos[IA_CSS_BINARY_MODE_VF_PP])
1333 return binary_infos[IA_CSS_BINARY_MODE_VF_PP]->sp.output.max_width;
1334 return 0;
1335 }
1336
1337 void
ia_css_binary_destroy_isp_parameters(struct ia_css_binary * binary)1338 ia_css_binary_destroy_isp_parameters(struct ia_css_binary *binary)
1339 {
1340 if (binary) {
1341 ia_css_isp_param_destroy_isp_parameters(&binary->mem_params,
1342 &binary->css_params);
1343 }
1344 }
1345
1346 void
ia_css_binary_get_isp_binaries(struct ia_css_binary_xinfo ** binaries,uint32_t * num_isp_binaries)1347 ia_css_binary_get_isp_binaries(struct ia_css_binary_xinfo **binaries,
1348 uint32_t *num_isp_binaries)
1349 {
1350 assert(binaries);
1351
1352 if (num_isp_binaries)
1353 *num_isp_binaries = 0;
1354
1355 *binaries = all_binaries;
1356 if (all_binaries && num_isp_binaries) {
1357 /* -1 to account for sp binary which is not stored in all_binaries */
1358 if (sh_css_num_binaries > 0)
1359 *num_isp_binaries = sh_css_num_binaries - 1;
1360 }
1361 }
1362