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 "ia_css_pipe_binarydesc.h"
17 #include "ia_css_frame_format.h"
18 #include "ia_css_pipe.h"
19 #include "ia_css_pipe_util.h"
20 #include "ia_css_util.h"
21 #include "ia_css_debug.h"
22 #include "sh_css_params.h"
23 #include <assert_support.h>
24 /* HRT_GDC_N */
25 #include "gdc_device.h"
26 #include <linux/kernel.h>
27 
28 /* This module provides a binary descriptions to used to find a binary. Since,
29  * every stage is associated with a binary, it implicity helps stage
30  * description. Apart from providing a binary description, this module also
31  * populates the frame info's when required.*/
32 
33 /* Generic descriptor for offline binaries. Internal function. */
34 static void pipe_binarydesc_get_offline(
35     struct ia_css_pipe const *const pipe,
36     const int mode,
37     struct ia_css_binary_descr *descr,
38     struct ia_css_frame_info *in_info,
39     struct ia_css_frame_info *out_info[],
40     struct ia_css_frame_info *vf_info)
41 {
42 	unsigned int i;
43 	/* in_info, out_info, vf_info can be NULL */
44 	assert(pipe);
45 	assert(descr);
46 	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
47 			    "pipe_binarydesc_get_offline() enter:\n");
48 
49 	descr->mode = mode;
50 	descr->online = false;
51 	descr->continuous = pipe->stream->config.continuous;
52 	descr->striped = false;
53 	descr->two_ppc = false;
54 	descr->enable_yuv_ds = false;
55 	descr->enable_high_speed = false;
56 	descr->enable_dvs_6axis = false;
57 	descr->enable_reduced_pipe = false;
58 	descr->enable_dz = true;
59 	descr->enable_xnr = false;
60 	descr->enable_dpc = false;
61 	descr->enable_tnr = false;
62 	descr->enable_capture_pp_bli = false;
63 	descr->enable_fractional_ds = false;
64 	descr->dvs_env.width = 0;
65 	descr->dvs_env.height = 0;
66 	descr->stream_format = pipe->stream->config.input_config.format;
67 	descr->in_info = in_info;
68 	descr->bds_out_info = NULL;
69 	for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
70 		descr->out_info[i] = out_info[i];
71 	descr->vf_info = vf_info;
72 	descr->isp_pipe_version = pipe->config.isp_pipe_version;
73 	descr->required_bds_factor = SH_CSS_BDS_FACTOR_1_00;
74 	descr->stream_config_left_padding = -1;
75 }
76 
77 void ia_css_pipe_get_copy_binarydesc(
78     struct ia_css_pipe const *const pipe,
79     struct ia_css_binary_descr *copy_descr,
80     struct ia_css_frame_info *in_info,
81     struct ia_css_frame_info *out_info,
82     struct ia_css_frame_info *vf_info)
83 {
84 	struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
85 	unsigned int i;
86 	/* out_info can be NULL */
87 	assert(pipe);
88 	assert(in_info);
89 	IA_CSS_ENTER_PRIVATE("");
90 
91 	*in_info = *out_info;
92 	out_infos[0] = out_info;
93 	for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
94 		out_infos[i] = NULL;
95 	pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_COPY,
96 				    copy_descr, in_info, out_infos, vf_info);
97 	copy_descr->online = true;
98 	copy_descr->continuous = false;
99 	copy_descr->two_ppc = (pipe->stream->config.pixels_per_clock == 2);
100 	copy_descr->enable_dz = false;
101 	copy_descr->isp_pipe_version = IA_CSS_PIPE_VERSION_1;
102 	IA_CSS_LEAVE_PRIVATE("");
103 }
104 
105 void ia_css_pipe_get_vfpp_binarydesc(
106     struct ia_css_pipe const *const pipe,
107     struct ia_css_binary_descr *vf_pp_descr,
108     struct ia_css_frame_info *in_info,
109     struct ia_css_frame_info *out_info)
110 {
111 	struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
112 	unsigned int i;
113 	/* out_info can be NULL ??? */
114 	assert(pipe);
115 	assert(in_info);
116 	IA_CSS_ENTER_PRIVATE("");
117 
118 	in_info->raw_bit_depth = 0;
119 	out_infos[0] = out_info;
120 	for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
121 		out_infos[i] = NULL;
122 
123 	pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_VF_PP,
124 				    vf_pp_descr, in_info, out_infos, NULL);
125 	vf_pp_descr->enable_fractional_ds = true;
126 	IA_CSS_LEAVE_PRIVATE("");
127 }
128 
129 static struct sh_css_bds_factor bds_factors_list[] = {
130 	{1, 1, SH_CSS_BDS_FACTOR_1_00},
131 	{5, 4, SH_CSS_BDS_FACTOR_1_25},
132 	{3, 2, SH_CSS_BDS_FACTOR_1_50},
133 	{2, 1, SH_CSS_BDS_FACTOR_2_00},
134 	{9, 4, SH_CSS_BDS_FACTOR_2_25},
135 	{5, 2, SH_CSS_BDS_FACTOR_2_50},
136 	{3, 1, SH_CSS_BDS_FACTOR_3_00},
137 	{4, 1, SH_CSS_BDS_FACTOR_4_00},
138 	{9, 2, SH_CSS_BDS_FACTOR_4_50},
139 	{5, 1, SH_CSS_BDS_FACTOR_5_00},
140 	{6, 1, SH_CSS_BDS_FACTOR_6_00},
141 	{8, 1, SH_CSS_BDS_FACTOR_8_00}
142 };
143 
144 int sh_css_bds_factor_get_numerator_denominator(
145     unsigned int bds_factor,
146     unsigned int *bds_factor_numerator,
147     unsigned int *bds_factor_denominator)
148 {
149 	unsigned int i;
150 
151 	/* Loop over all bds factors until a match is found */
152 	for (i = 0; i < ARRAY_SIZE(bds_factors_list); i++) {
153 		if (bds_factors_list[i].bds_factor == bds_factor) {
154 			*bds_factor_numerator = bds_factors_list[i].numerator;
155 			*bds_factor_denominator = bds_factors_list[i].denominator;
156 			return 0;
157 		}
158 	}
159 
160 	/* Throw an error since bds_factor cannot be found
161 	in bds_factors_list */
162 	return -EINVAL;
163 }
164 
165 int binarydesc_calculate_bds_factor(
166     struct ia_css_resolution input_res,
167     struct ia_css_resolution output_res,
168     unsigned int *bds_factor)
169 {
170 	unsigned int i;
171 	unsigned int in_w = input_res.width,
172 		     in_h = input_res.height,
173 		     out_w = output_res.width, out_h = output_res.height;
174 
175 	unsigned int max_bds_factor = 8;
176 	unsigned int max_rounding_margin = 2;
177 	/* delta in pixels to account for rounding margin in the calculation */
178 	unsigned int delta = max_bds_factor * max_rounding_margin;
179 
180 	/* Assert if the resolutions are not set */
181 	assert(in_w != 0 && in_h != 0);
182 	assert(out_w != 0 && out_h != 0);
183 
184 	/* Loop over all bds factors until a match is found */
185 	for (i = 0; i < ARRAY_SIZE(bds_factors_list); i++) {
186 		unsigned int num = bds_factors_list[i].numerator;
187 		unsigned int den = bds_factors_list[i].denominator;
188 
189 		/* See width-wise and height-wise if this bds_factor
190 		 * satisfies the condition */
191 		bool cond = (out_w * num / den + delta > in_w) &&
192 			    (out_w * num / den <= in_w) &&
193 			    (out_h * num / den + delta > in_h) &&
194 			    (out_h * num / den <= in_h);
195 
196 		if (cond) {
197 			*bds_factor = bds_factors_list[i].bds_factor;
198 			return 0;
199 		}
200 	}
201 
202 	/* Throw an error since a suitable bds_factor cannot be found */
203 	return -EINVAL;
204 }
205 
206 int ia_css_pipe_get_preview_binarydesc(
207     struct ia_css_pipe *const pipe,
208     struct ia_css_binary_descr *preview_descr,
209     struct ia_css_frame_info *in_info,
210     struct ia_css_frame_info *bds_out_info,
211     struct ia_css_frame_info *out_info,
212     struct ia_css_frame_info *vf_info)
213 {
214 	int err;
215 	struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
216 	int mode = IA_CSS_BINARY_MODE_PREVIEW;
217 	unsigned int i;
218 
219 	assert(pipe);
220 	assert(in_info);
221 	assert(out_info);
222 	assert(vf_info);
223 	IA_CSS_ENTER_PRIVATE("");
224 
225 	/*
226 	 * Set up the info of the input frame with
227 	 * the ISP required resolution
228 	 */
229 	in_info->res = pipe->config.input_effective_res;
230 	in_info->padded_width = in_info->res.width;
231 	in_info->raw_bit_depth = ia_css_pipe_util_pipe_input_format_bpp(pipe);
232 
233 	if (ia_css_util_is_input_format_yuv(pipe->stream->config.input_config.format))
234 		mode = IA_CSS_BINARY_MODE_COPY;
235 	else
236 		in_info->format = IA_CSS_FRAME_FORMAT_RAW;
237 
238 	out_infos[0] = out_info;
239 	for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
240 		out_infos[i] = NULL;
241 
242 	pipe_binarydesc_get_offline(pipe, mode,
243 				    preview_descr, in_info, out_infos, vf_info);
244 	if (pipe->stream->config.online) {
245 		preview_descr->online = pipe->stream->config.online;
246 		preview_descr->two_ppc =
247 		    (pipe->stream->config.pixels_per_clock == 2);
248 	}
249 	preview_descr->stream_format = pipe->stream->config.input_config.format;
250 
251 	/* TODO: Remove this when bds_out_info is available! */
252 	*bds_out_info = *in_info;
253 
254 	if (pipe->extra_config.enable_raw_binning) {
255 		if (pipe->config.bayer_ds_out_res.width != 0 &&
256 		    pipe->config.bayer_ds_out_res.height != 0) {
257 			bds_out_info->res.width =
258 			    pipe->config.bayer_ds_out_res.width;
259 			bds_out_info->res.height =
260 			    pipe->config.bayer_ds_out_res.height;
261 			bds_out_info->padded_width =
262 			    pipe->config.bayer_ds_out_res.width;
263 			err =
264 			    binarydesc_calculate_bds_factor(in_info->res,
265 							    bds_out_info->res,
266 							    &preview_descr->required_bds_factor);
267 			if (err)
268 				return err;
269 		} else {
270 			bds_out_info->res.width = in_info->res.width / 2;
271 			bds_out_info->res.height = in_info->res.height / 2;
272 			bds_out_info->padded_width = in_info->padded_width / 2;
273 			preview_descr->required_bds_factor =
274 			    SH_CSS_BDS_FACTOR_2_00;
275 		}
276 	} else {
277 		/* TODO: Remove this when bds_out_info->is available! */
278 		bds_out_info->res.width = in_info->res.width;
279 		bds_out_info->res.height = in_info->res.height;
280 		bds_out_info->padded_width = in_info->padded_width;
281 		preview_descr->required_bds_factor = SH_CSS_BDS_FACTOR_1_00;
282 	}
283 	pipe->required_bds_factor = preview_descr->required_bds_factor;
284 
285 	/* bayer ds and fractional ds cannot be enabled at the same time,
286 	so we disable bds_out_info when fractional ds is used */
287 	if (!pipe->extra_config.enable_fractional_ds)
288 		preview_descr->bds_out_info = bds_out_info;
289 	else
290 		preview_descr->bds_out_info = NULL;
291 	/*
292 	   ----Preview binary-----
293 	   --in-->|--out->|vf_veceven|--|--->vf
294 	   -----------------------
295 	   * Preview binary normally doesn't have a vf_port but
296 	   * instead it has an output port. However, the output is
297 	   * generated by vf_veceven module in which we might have
298 	   * a downscaling (by 1x, 2x, or 4x). Because the resolution
299 	   * might change, we need two different info, namely out_info
300 	   * & vf_info. In fill_binary_info we use out&vf info to
301 	   * calculate vf decimation factor.
302 	 */
303 	*out_info = *vf_info;
304 
305 	/* In case of preview_ds binary, we can do any fractional amount
306 	 * of downscale, so there is no DS needed in vf_veceven. Therefore,
307 	 * out and vf infos will be the same. Otherwise, we set out resolution
308 	 * equal to in resolution. */
309 	if (!pipe->extra_config.enable_fractional_ds) {
310 		/* TODO: Change this when bds_out_info is available! */
311 		out_info->res.width = bds_out_info->res.width;
312 		out_info->res.height = bds_out_info->res.height;
313 		out_info->padded_width = bds_out_info->padded_width;
314 	}
315 	preview_descr->enable_fractional_ds =
316 	    pipe->extra_config.enable_fractional_ds;
317 
318 	preview_descr->enable_dpc = pipe->config.enable_dpc;
319 
320 	preview_descr->isp_pipe_version = pipe->config.isp_pipe_version;
321 	IA_CSS_LEAVE_ERR_PRIVATE(0);
322 	return 0;
323 }
324 
325 int ia_css_pipe_get_video_binarydesc(
326     struct ia_css_pipe *const pipe,
327     struct ia_css_binary_descr *video_descr,
328     struct ia_css_frame_info *in_info,
329     struct ia_css_frame_info *bds_out_info,
330     struct ia_css_frame_info *out_info,
331     struct ia_css_frame_info *vf_info,
332     int stream_config_left_padding)
333 {
334 	int mode = IA_CSS_BINARY_MODE_VIDEO;
335 	unsigned int i;
336 	struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
337 	int err = 0;
338 	bool stream_dz_config = false;
339 
340 	/* vf_info can be NULL */
341 	assert(pipe);
342 	assert(in_info);
343 	/* assert(vf_info != NULL); */
344 	IA_CSS_ENTER_PRIVATE("");
345 
346 	/* The solution below is not optimal; we should move to using ia_css_pipe_get_copy_binarydesc()
347 	 * But for now this fixes things; this code used to be there but was removed
348 	 * with gerrit 8908 as this was wrong for Skycam; however 240x still needs this
349 	 */
350 	if (ia_css_util_is_input_format_yuv(pipe->stream->config.input_config.format))
351 		mode = IA_CSS_BINARY_MODE_COPY;
352 
353 	in_info->res = pipe->config.input_effective_res;
354 	in_info->padded_width = in_info->res.width;
355 	in_info->format = IA_CSS_FRAME_FORMAT_RAW;
356 	in_info->raw_bit_depth = ia_css_pipe_util_pipe_input_format_bpp(pipe);
357 	out_infos[0] = out_info;
358 	for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
359 		out_infos[i] = NULL;
360 
361 	pipe_binarydesc_get_offline(pipe, mode,
362 				    video_descr, in_info, out_infos, vf_info);
363 
364 	if (pipe->stream->config.online) {
365 		video_descr->online = pipe->stream->config.online;
366 		video_descr->two_ppc =
367 		    (pipe->stream->config.pixels_per_clock == 2);
368 	}
369 
370 	if (mode == IA_CSS_BINARY_MODE_VIDEO) {
371 		stream_dz_config =
372 		    ((pipe->stream->isp_params_configs->dz_config.dx !=
373 		      HRT_GDC_N)
374 		     || (pipe->stream->isp_params_configs->dz_config.dy !=
375 			 HRT_GDC_N));
376 
377 		video_descr->enable_dz = pipe->config.enable_dz
378 					 || stream_dz_config;
379 		video_descr->dvs_env = pipe->config.dvs_envelope;
380 		video_descr->enable_yuv_ds = pipe->extra_config.enable_yuv_ds;
381 		video_descr->enable_high_speed =
382 		    pipe->extra_config.enable_high_speed;
383 		video_descr->enable_dvs_6axis =
384 		    pipe->extra_config.enable_dvs_6axis;
385 		video_descr->enable_reduced_pipe =
386 		    pipe->extra_config.enable_reduced_pipe;
387 		video_descr->isp_pipe_version = pipe->config.isp_pipe_version;
388 		video_descr->enable_fractional_ds =
389 		    pipe->extra_config.enable_fractional_ds;
390 		video_descr->enable_dpc =
391 		    pipe->config.enable_dpc;
392 		video_descr->enable_tnr =
393 		    pipe->config.enable_tnr;
394 
395 		if (pipe->extra_config.enable_raw_binning) {
396 			if (pipe->config.bayer_ds_out_res.width != 0 &&
397 			    pipe->config.bayer_ds_out_res.height != 0) {
398 				bds_out_info->res.width =
399 				    pipe->config.bayer_ds_out_res.width;
400 				bds_out_info->res.height =
401 				    pipe->config.bayer_ds_out_res.height;
402 				bds_out_info->padded_width =
403 				    pipe->config.bayer_ds_out_res.width;
404 				err =
405 				    binarydesc_calculate_bds_factor(
406 					in_info->res, bds_out_info->res,
407 					&video_descr->required_bds_factor);
408 				if (err)
409 					return err;
410 			} else {
411 				bds_out_info->res.width =
412 				    in_info->res.width / 2;
413 				bds_out_info->res.height =
414 				    in_info->res.height / 2;
415 				bds_out_info->padded_width =
416 				    in_info->padded_width / 2;
417 				video_descr->required_bds_factor =
418 				    SH_CSS_BDS_FACTOR_2_00;
419 			}
420 		} else {
421 			bds_out_info->res.width = in_info->res.width;
422 			bds_out_info->res.height = in_info->res.height;
423 			bds_out_info->padded_width = in_info->padded_width;
424 			video_descr->required_bds_factor =
425 			    SH_CSS_BDS_FACTOR_1_00;
426 		}
427 
428 		pipe->required_bds_factor = video_descr->required_bds_factor;
429 
430 		/* bayer ds and fractional ds cannot be enabled
431 		at the same time, so we disable bds_out_info when
432 		fractional ds is used */
433 		if (!pipe->extra_config.enable_fractional_ds)
434 			video_descr->bds_out_info = bds_out_info;
435 		else
436 			video_descr->bds_out_info = NULL;
437 
438 		video_descr->enable_fractional_ds =
439 		    pipe->extra_config.enable_fractional_ds;
440 		video_descr->stream_config_left_padding = stream_config_left_padding;
441 	}
442 	IA_CSS_LEAVE_ERR_PRIVATE(err);
443 	return err;
444 }
445 
446 void ia_css_pipe_get_yuvscaler_binarydesc(
447     struct ia_css_pipe const *const pipe,
448     struct ia_css_binary_descr *yuv_scaler_descr,
449     struct ia_css_frame_info *in_info,
450     struct ia_css_frame_info *out_info,
451     struct ia_css_frame_info *internal_out_info,
452     struct ia_css_frame_info *vf_info)
453 {
454 	struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
455 	struct ia_css_frame_info *this_vf_info = NULL;
456 
457 	assert(pipe);
458 	assert(in_info);
459 	/* Note: if the following assert fails, the number of ports has been
460 	 * changed; in that case an additional initializer must be added
461 	 * a few lines below after which this assert can be updated.
462 	 */
463 	assert(IA_CSS_BINARY_MAX_OUTPUT_PORTS == 2);
464 	IA_CSS_ENTER_PRIVATE("");
465 
466 	in_info->padded_width = in_info->res.width;
467 	in_info->raw_bit_depth = 0;
468 	ia_css_frame_info_set_width(in_info, in_info->res.width, 0);
469 	out_infos[0] = out_info;
470 	out_infos[1] = internal_out_info;
471 	/* add initializers here if
472 	 * assert(IA_CSS_BINARY_MAX_OUTPUT_PORTS == ...);
473 	 * fails
474 	 */
475 
476 	if (vf_info) {
477 		this_vf_info = (vf_info->res.width == 0 &&
478 				vf_info->res.height == 0) ? NULL : vf_info;
479 	}
480 
481 	pipe_binarydesc_get_offline(pipe,
482 				    IA_CSS_BINARY_MODE_CAPTURE_PP,
483 				    yuv_scaler_descr,
484 				    in_info, out_infos, this_vf_info);
485 
486 	yuv_scaler_descr->enable_fractional_ds = true;
487 	IA_CSS_LEAVE_PRIVATE("");
488 }
489 
490 void ia_css_pipe_get_capturepp_binarydesc(
491     struct ia_css_pipe *const pipe,
492     struct ia_css_binary_descr *capture_pp_descr,
493     struct ia_css_frame_info *in_info,
494     struct ia_css_frame_info *out_info,
495     struct ia_css_frame_info *vf_info)
496 {
497 	unsigned int i;
498 	struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
499 
500 	assert(pipe);
501 	assert(in_info);
502 	assert(vf_info);
503 	IA_CSS_ENTER_PRIVATE("");
504 
505 	/* the in_info is only used for resolution to enable
506 	   bayer down scaling. */
507 	if (pipe->out_yuv_ds_input_info.res.width)
508 		*in_info = pipe->out_yuv_ds_input_info;
509 	else
510 		*in_info = *out_info;
511 	in_info->format = IA_CSS_FRAME_FORMAT_YUV420;
512 	in_info->raw_bit_depth = 0;
513 	ia_css_frame_info_set_width(in_info, in_info->res.width, 0);
514 
515 	out_infos[0] = out_info;
516 	for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
517 		out_infos[i] = NULL;
518 
519 	pipe_binarydesc_get_offline(pipe,
520 				    IA_CSS_BINARY_MODE_CAPTURE_PP,
521 				    capture_pp_descr,
522 				    in_info, out_infos, vf_info);
523 
524 	capture_pp_descr->enable_capture_pp_bli =
525 	    pipe->config.default_capture_config.enable_capture_pp_bli;
526 	capture_pp_descr->enable_fractional_ds = true;
527 	capture_pp_descr->enable_xnr =
528 	    pipe->config.default_capture_config.enable_xnr != 0;
529 	IA_CSS_LEAVE_PRIVATE("");
530 }
531 
532 /* lookup table for high quality primary binaries */
533 static unsigned int primary_hq_binary_modes[NUM_PRIMARY_HQ_STAGES] = {
534 	IA_CSS_BINARY_MODE_PRIMARY_HQ_STAGE0,
535 	IA_CSS_BINARY_MODE_PRIMARY_HQ_STAGE1,
536 	IA_CSS_BINARY_MODE_PRIMARY_HQ_STAGE2,
537 	IA_CSS_BINARY_MODE_PRIMARY_HQ_STAGE3,
538 	IA_CSS_BINARY_MODE_PRIMARY_HQ_STAGE4,
539 	IA_CSS_BINARY_MODE_PRIMARY_HQ_STAGE5
540 };
541 
542 void ia_css_pipe_get_primary_binarydesc(
543     struct ia_css_pipe const *const pipe,
544     struct ia_css_binary_descr *prim_descr,
545     struct ia_css_frame_info *in_info,
546     struct ia_css_frame_info *out_info,
547     struct ia_css_frame_info *vf_info,
548     unsigned int stage_idx)
549 {
550 	enum ia_css_pipe_version pipe_version = pipe->config.isp_pipe_version;
551 	int mode;
552 	unsigned int i;
553 	struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
554 
555 	assert(pipe);
556 	assert(in_info);
557 	assert(out_info);
558 	assert(stage_idx < NUM_PRIMARY_HQ_STAGES);
559 	/* vf_info can be NULL - example video_binarydescr */
560 	/*assert(vf_info != NULL);*/
561 	IA_CSS_ENTER_PRIVATE("");
562 
563 	if (pipe_version == IA_CSS_PIPE_VERSION_2_6_1)
564 		mode = primary_hq_binary_modes[stage_idx];
565 	else
566 		mode = IA_CSS_BINARY_MODE_PRIMARY;
567 
568 	if (ia_css_util_is_input_format_yuv(pipe->stream->config.input_config.format))
569 		mode = IA_CSS_BINARY_MODE_COPY;
570 
571 	in_info->res = pipe->config.input_effective_res;
572 	in_info->padded_width = in_info->res.width;
573 
574 	if (pipe->stream->config.pack_raw_pixels)
575 		in_info->format = IA_CSS_FRAME_FORMAT_RAW_PACKED;
576 	else
577 		in_info->format = IA_CSS_FRAME_FORMAT_RAW;
578 
579 	in_info->raw_bit_depth = ia_css_pipe_util_pipe_input_format_bpp(pipe);
580 	out_infos[0] = out_info;
581 	for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
582 		out_infos[i] = NULL;
583 
584 	pipe_binarydesc_get_offline(pipe, mode,
585 				    prim_descr, in_info, out_infos, vf_info);
586 
587 	if (pipe->stream->config.online &&
588 	    pipe->stream->config.mode != IA_CSS_INPUT_MODE_MEMORY) {
589 		prim_descr->online = true;
590 		prim_descr->two_ppc =
591 		    (pipe->stream->config.pixels_per_clock == 2);
592 		prim_descr->stream_format = pipe->stream->config.input_config.format;
593 	}
594 	if (mode == IA_CSS_BINARY_MODE_PRIMARY) {
595 		prim_descr->isp_pipe_version = pipe->config.isp_pipe_version;
596 		prim_descr->enable_fractional_ds =
597 		    pipe->extra_config.enable_fractional_ds;
598 		/* We have both striped and non-striped primary binaries,
599 		 * if continuous viewfinder is required, then we must select
600 		 * a striped one. Otherwise we prefer to use a non-striped
601 		 * since it has better performance. */
602 		if (pipe_version == IA_CSS_PIPE_VERSION_2_6_1)
603 			prim_descr->striped = false;
604 		else
605 			prim_descr->striped = prim_descr->continuous &&
606 					      (!pipe->stream->stop_copy_preview || !pipe->stream->disable_cont_vf);
607 	}
608 	IA_CSS_LEAVE_PRIVATE("");
609 }
610 
611 void ia_css_pipe_get_pre_gdc_binarydesc(
612     struct ia_css_pipe const *const pipe,
613     struct ia_css_binary_descr *pre_gdc_descr,
614     struct ia_css_frame_info *in_info,
615     struct ia_css_frame_info *out_info)
616 {
617 	unsigned int i;
618 	struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
619 
620 	assert(pipe);
621 	assert(in_info);
622 	assert(out_info);
623 	IA_CSS_ENTER_PRIVATE("");
624 
625 	*in_info = *out_info;
626 	in_info->format = IA_CSS_FRAME_FORMAT_RAW;
627 	in_info->raw_bit_depth = ia_css_pipe_util_pipe_input_format_bpp(pipe);
628 	out_infos[0] = out_info;
629 	for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
630 		out_infos[i] = NULL;
631 
632 	pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_PRE_ISP,
633 				    pre_gdc_descr, in_info, out_infos, NULL);
634 	pre_gdc_descr->isp_pipe_version = pipe->config.isp_pipe_version;
635 	IA_CSS_LEAVE_PRIVATE("");
636 }
637 
638 void ia_css_pipe_get_gdc_binarydesc(
639     struct ia_css_pipe const *const pipe,
640     struct ia_css_binary_descr *gdc_descr,
641     struct ia_css_frame_info *in_info,
642     struct ia_css_frame_info *out_info)
643 {
644 	unsigned int i;
645 	struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
646 
647 	assert(pipe);
648 	assert(in_info);
649 	assert(out_info);
650 	IA_CSS_ENTER_PRIVATE("");
651 
652 	*in_info = *out_info;
653 	in_info->format = IA_CSS_FRAME_FORMAT_QPLANE6;
654 	out_infos[0] = out_info;
655 	for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
656 		out_infos[i] = NULL;
657 
658 	pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_GDC,
659 				    gdc_descr, in_info, out_infos, NULL);
660 	IA_CSS_LEAVE_PRIVATE("");
661 }
662 
663 void ia_css_pipe_get_post_gdc_binarydesc(
664     struct ia_css_pipe const *const pipe,
665     struct ia_css_binary_descr *post_gdc_descr,
666     struct ia_css_frame_info *in_info,
667     struct ia_css_frame_info *out_info,
668     struct ia_css_frame_info *vf_info)
669 {
670 	unsigned int i;
671 	struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
672 
673 	assert(pipe);
674 	assert(in_info);
675 	assert(out_info);
676 	assert(vf_info);
677 	IA_CSS_ENTER_PRIVATE("");
678 
679 	*in_info = *out_info;
680 	in_info->format = IA_CSS_FRAME_FORMAT_YUV420_16;
681 	in_info->raw_bit_depth = 16;
682 	out_infos[0] = out_info;
683 	for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
684 		out_infos[i] = NULL;
685 
686 	pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_POST_ISP,
687 				    post_gdc_descr, in_info, out_infos, vf_info);
688 
689 	post_gdc_descr->isp_pipe_version = pipe->config.isp_pipe_version;
690 	IA_CSS_LEAVE_PRIVATE("");
691 }
692 
693 void ia_css_pipe_get_pre_de_binarydesc(
694     struct ia_css_pipe const *const pipe,
695     struct ia_css_binary_descr *pre_de_descr,
696     struct ia_css_frame_info *in_info,
697     struct ia_css_frame_info *out_info)
698 {
699 	unsigned int i;
700 	struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
701 
702 	assert(pipe);
703 	assert(in_info);
704 	assert(out_info);
705 	IA_CSS_ENTER_PRIVATE("");
706 
707 	*in_info = *out_info;
708 	in_info->format = IA_CSS_FRAME_FORMAT_RAW;
709 	in_info->raw_bit_depth = ia_css_pipe_util_pipe_input_format_bpp(pipe);
710 	out_infos[0] = out_info;
711 	for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
712 		out_infos[i] = NULL;
713 
714 	if (pipe->config.isp_pipe_version == IA_CSS_PIPE_VERSION_1)
715 		pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_PRE_ISP,
716 					    pre_de_descr, in_info, out_infos, NULL);
717 	else if (pipe->config.isp_pipe_version == IA_CSS_PIPE_VERSION_2_2) {
718 		pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_PRE_DE,
719 					    pre_de_descr, in_info, out_infos, NULL);
720 	}
721 
722 	if (pipe->stream->config.online) {
723 		pre_de_descr->online = true;
724 		pre_de_descr->two_ppc =
725 		    (pipe->stream->config.pixels_per_clock == 2);
726 		pre_de_descr->stream_format = pipe->stream->config.input_config.format;
727 	}
728 	pre_de_descr->isp_pipe_version = pipe->config.isp_pipe_version;
729 	IA_CSS_LEAVE_PRIVATE("");
730 }
731 
732 void ia_css_pipe_get_pre_anr_binarydesc(
733     struct ia_css_pipe const *const pipe,
734     struct ia_css_binary_descr *pre_anr_descr,
735     struct ia_css_frame_info *in_info,
736     struct ia_css_frame_info *out_info)
737 {
738 	unsigned int i;
739 	struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
740 
741 	assert(pipe);
742 	assert(in_info);
743 	assert(out_info);
744 	IA_CSS_ENTER_PRIVATE("");
745 
746 	*in_info = *out_info;
747 	in_info->format = IA_CSS_FRAME_FORMAT_RAW;
748 	in_info->raw_bit_depth = ia_css_pipe_util_pipe_input_format_bpp(pipe);
749 	out_infos[0] = out_info;
750 	for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
751 		out_infos[i] = NULL;
752 
753 	pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_PRE_ISP,
754 				    pre_anr_descr, in_info, out_infos, NULL);
755 
756 	if (pipe->stream->config.online) {
757 		pre_anr_descr->online = true;
758 		pre_anr_descr->two_ppc =
759 		    (pipe->stream->config.pixels_per_clock == 2);
760 		pre_anr_descr->stream_format = pipe->stream->config.input_config.format;
761 	}
762 	pre_anr_descr->isp_pipe_version = pipe->config.isp_pipe_version;
763 	IA_CSS_LEAVE_PRIVATE("");
764 }
765 
766 void ia_css_pipe_get_anr_binarydesc(
767     struct ia_css_pipe const *const pipe,
768     struct ia_css_binary_descr *anr_descr,
769     struct ia_css_frame_info *in_info,
770     struct ia_css_frame_info *out_info)
771 {
772 	unsigned int i;
773 	struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
774 
775 	assert(pipe);
776 	assert(in_info);
777 	assert(out_info);
778 	IA_CSS_ENTER_PRIVATE("");
779 
780 	*in_info = *out_info;
781 	in_info->format = IA_CSS_FRAME_FORMAT_RAW;
782 	in_info->raw_bit_depth = ANR_ELEMENT_BITS;
783 	out_infos[0] = out_info;
784 	for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
785 		out_infos[i] = NULL;
786 
787 	pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_ANR,
788 				    anr_descr, in_info, out_infos, NULL);
789 
790 	anr_descr->isp_pipe_version = pipe->config.isp_pipe_version;
791 	IA_CSS_LEAVE_PRIVATE("");
792 }
793 
794 void ia_css_pipe_get_post_anr_binarydesc(
795     struct ia_css_pipe const *const pipe,
796     struct ia_css_binary_descr *post_anr_descr,
797     struct ia_css_frame_info *in_info,
798     struct ia_css_frame_info *out_info,
799     struct ia_css_frame_info *vf_info)
800 {
801 	unsigned int i;
802 	struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
803 
804 	assert(pipe);
805 	assert(in_info);
806 	assert(out_info);
807 	assert(vf_info);
808 	IA_CSS_ENTER_PRIVATE("");
809 
810 	*in_info = *out_info;
811 	in_info->format = IA_CSS_FRAME_FORMAT_RAW;
812 	in_info->raw_bit_depth = ANR_ELEMENT_BITS;
813 	out_infos[0] = out_info;
814 	for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
815 		out_infos[i] = NULL;
816 
817 	pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_POST_ISP,
818 				    post_anr_descr, in_info, out_infos, vf_info);
819 
820 	post_anr_descr->isp_pipe_version = pipe->config.isp_pipe_version;
821 	IA_CSS_LEAVE_PRIVATE("");
822 }
823 
824 void ia_css_pipe_get_ldc_binarydesc(
825     struct ia_css_pipe const *const pipe,
826     struct ia_css_binary_descr *ldc_descr,
827     struct ia_css_frame_info *in_info,
828     struct ia_css_frame_info *out_info)
829 {
830 	unsigned int i;
831 	struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
832 
833 	assert(pipe);
834 	assert(in_info);
835 	assert(out_info);
836 	IA_CSS_ENTER_PRIVATE("");
837 
838 	*in_info = *out_info;
839 
840 	in_info->format = IA_CSS_FRAME_FORMAT_YUV420;
841 	in_info->raw_bit_depth = 0;
842 	ia_css_frame_info_set_width(in_info, in_info->res.width, 0);
843 
844 	out_infos[0] = out_info;
845 	for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
846 		out_infos[i] = NULL;
847 
848 	pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_CAPTURE_PP,
849 				    ldc_descr, in_info, out_infos, NULL);
850 	ldc_descr->enable_dvs_6axis =
851 	    pipe->extra_config.enable_dvs_6axis;
852 	IA_CSS_LEAVE_PRIVATE("");
853 }
854