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