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