1 /*
2  * Support for Intel Camera Imaging ISP subsystem.
3  * Copyright (c) 2015, Intel Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms and conditions of the GNU General Public License,
7  * version 2, as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  */
14 
15 #include "ia_css_pipe_binarydesc.h"
16 #include "ia_css_frame_format.h"
17 #include "ia_css_pipe.h"
18 #include "ia_css_pipe_util.h"
19 #include "ia_css_util.h"
20 #include "ia_css_debug.h"
21 #include "sh_css_params.h"
22 #include <assert_support.h>
23 /* HRT_GDC_N */
24 #include "gdc_device.h"
25 #include <linux/kernel.h>
26 
27 /* This module provides a binary descriptions to used to find a binary. Since,
28  * every stage is associated with a binary, it implicity helps stage
29  * description. Apart from providing a binary description, this module also
30  * populates the frame info's when required.*/
31 
32 /* Generic descriptor for offline binaries. Internal function. */
33 static void pipe_binarydesc_get_offline(
34     struct ia_css_pipe const *const pipe,
35     const int mode,
36     struct ia_css_binary_descr *descr,
37     struct ia_css_frame_info *in_info,
38     struct ia_css_frame_info *out_info[],
39     struct ia_css_frame_info *vf_info)
40 {
41 	unsigned int i;
42 	/* in_info, out_info, vf_info can be NULL */
43 	assert(pipe);
44 	assert(descr);
45 	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
46 			    "pipe_binarydesc_get_offline() enter:\n");
47 
48 	descr->mode = mode;
49 	descr->online = false;
50 	descr->continuous = pipe->stream->config.continuous;
51 	descr->striped = false;
52 	descr->two_ppc = false;
53 	descr->enable_yuv_ds = false;
54 	descr->enable_high_speed = false;
55 	descr->enable_dvs_6axis = false;
56 	descr->enable_reduced_pipe = false;
57 	descr->enable_dz = true;
58 	descr->enable_xnr = false;
59 	descr->enable_dpc = false;
60 	descr->enable_luma_only = 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_luma_only =
393 		    pipe->config.enable_luma_only;
394 		video_descr->enable_tnr =
395 		    pipe->config.enable_tnr;
396 
397 		if (pipe->extra_config.enable_raw_binning) {
398 			if (pipe->config.bayer_ds_out_res.width != 0 &&
399 			    pipe->config.bayer_ds_out_res.height != 0) {
400 				bds_out_info->res.width =
401 				    pipe->config.bayer_ds_out_res.width;
402 				bds_out_info->res.height =
403 				    pipe->config.bayer_ds_out_res.height;
404 				bds_out_info->padded_width =
405 				    pipe->config.bayer_ds_out_res.width;
406 				err =
407 				    binarydesc_calculate_bds_factor(
408 					in_info->res, bds_out_info->res,
409 					&video_descr->required_bds_factor);
410 				if (err)
411 					return err;
412 			} else {
413 				bds_out_info->res.width =
414 				    in_info->res.width / 2;
415 				bds_out_info->res.height =
416 				    in_info->res.height / 2;
417 				bds_out_info->padded_width =
418 				    in_info->padded_width / 2;
419 				video_descr->required_bds_factor =
420 				    SH_CSS_BDS_FACTOR_2_00;
421 			}
422 		} else {
423 			bds_out_info->res.width = in_info->res.width;
424 			bds_out_info->res.height = in_info->res.height;
425 			bds_out_info->padded_width = in_info->padded_width;
426 			video_descr->required_bds_factor =
427 			    SH_CSS_BDS_FACTOR_1_00;
428 		}
429 
430 		pipe->required_bds_factor = video_descr->required_bds_factor;
431 
432 		/* bayer ds and fractional ds cannot be enabled
433 		at the same time, so we disable bds_out_info when
434 		fractional ds is used */
435 		if (!pipe->extra_config.enable_fractional_ds)
436 			video_descr->bds_out_info = bds_out_info;
437 		else
438 			video_descr->bds_out_info = NULL;
439 
440 		video_descr->enable_fractional_ds =
441 		    pipe->extra_config.enable_fractional_ds;
442 		video_descr->stream_config_left_padding = stream_config_left_padding;
443 	}
444 	IA_CSS_LEAVE_ERR_PRIVATE(err);
445 	return err;
446 }
447 
448 void ia_css_pipe_get_yuvscaler_binarydesc(
449     struct ia_css_pipe const *const pipe,
450     struct ia_css_binary_descr *yuv_scaler_descr,
451     struct ia_css_frame_info *in_info,
452     struct ia_css_frame_info *out_info,
453     struct ia_css_frame_info *internal_out_info,
454     struct ia_css_frame_info *vf_info)
455 {
456 	struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
457 	struct ia_css_frame_info *this_vf_info = NULL;
458 
459 	assert(pipe);
460 	assert(in_info);
461 	/* Note: if the following assert fails, the number of ports has been
462 	 * changed; in that case an additional initializer must be added
463 	 * a few lines below after which this assert can be updated.
464 	 */
465 	assert(IA_CSS_BINARY_MAX_OUTPUT_PORTS == 2);
466 	IA_CSS_ENTER_PRIVATE("");
467 
468 	in_info->padded_width = in_info->res.width;
469 	in_info->raw_bit_depth = 0;
470 	ia_css_frame_info_set_width(in_info, in_info->res.width, 0);
471 	out_infos[0] = out_info;
472 	out_infos[1] = internal_out_info;
473 	/* add initializers here if
474 	 * assert(IA_CSS_BINARY_MAX_OUTPUT_PORTS == ...);
475 	 * fails
476 	 */
477 
478 	if (vf_info) {
479 		this_vf_info = (vf_info->res.width == 0 &&
480 				vf_info->res.height == 0) ? NULL : vf_info;
481 	}
482 
483 	pipe_binarydesc_get_offline(pipe,
484 				    IA_CSS_BINARY_MODE_CAPTURE_PP,
485 				    yuv_scaler_descr,
486 				    in_info, out_infos, this_vf_info);
487 
488 	yuv_scaler_descr->enable_fractional_ds = true;
489 	IA_CSS_LEAVE_PRIVATE("");
490 }
491 
492 void ia_css_pipe_get_capturepp_binarydesc(
493     struct ia_css_pipe *const pipe,
494     struct ia_css_binary_descr *capture_pp_descr,
495     struct ia_css_frame_info *in_info,
496     struct ia_css_frame_info *out_info,
497     struct ia_css_frame_info *vf_info)
498 {
499 	unsigned int i;
500 	struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
501 
502 	assert(pipe);
503 	assert(in_info);
504 	assert(vf_info);
505 	IA_CSS_ENTER_PRIVATE("");
506 
507 	/* the in_info is only used for resolution to enable
508 	   bayer down scaling. */
509 	if (pipe->out_yuv_ds_input_info.res.width)
510 		*in_info = pipe->out_yuv_ds_input_info;
511 	else
512 		*in_info = *out_info;
513 	in_info->format = IA_CSS_FRAME_FORMAT_YUV420;
514 	in_info->raw_bit_depth = 0;
515 	ia_css_frame_info_set_width(in_info, in_info->res.width, 0);
516 
517 	out_infos[0] = out_info;
518 	for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
519 		out_infos[i] = NULL;
520 
521 	pipe_binarydesc_get_offline(pipe,
522 				    IA_CSS_BINARY_MODE_CAPTURE_PP,
523 				    capture_pp_descr,
524 				    in_info, out_infos, vf_info);
525 
526 	capture_pp_descr->enable_capture_pp_bli =
527 	    pipe->config.default_capture_config.enable_capture_pp_bli;
528 	capture_pp_descr->enable_fractional_ds = true;
529 	capture_pp_descr->enable_xnr =
530 	    pipe->config.default_capture_config.enable_xnr != 0;
531 	IA_CSS_LEAVE_PRIVATE("");
532 }
533 
534 /* lookup table for high quality primary binaries */
535 static unsigned int primary_hq_binary_modes[NUM_PRIMARY_HQ_STAGES] = {
536 	IA_CSS_BINARY_MODE_PRIMARY_HQ_STAGE0,
537 	IA_CSS_BINARY_MODE_PRIMARY_HQ_STAGE1,
538 	IA_CSS_BINARY_MODE_PRIMARY_HQ_STAGE2,
539 	IA_CSS_BINARY_MODE_PRIMARY_HQ_STAGE3,
540 	IA_CSS_BINARY_MODE_PRIMARY_HQ_STAGE4,
541 	IA_CSS_BINARY_MODE_PRIMARY_HQ_STAGE5
542 };
543 
544 void ia_css_pipe_get_primary_binarydesc(
545     struct ia_css_pipe const *const pipe,
546     struct ia_css_binary_descr *prim_descr,
547     struct ia_css_frame_info *in_info,
548     struct ia_css_frame_info *out_info,
549     struct ia_css_frame_info *vf_info,
550     unsigned int stage_idx)
551 {
552 	enum ia_css_pipe_version pipe_version = pipe->config.isp_pipe_version;
553 	int mode;
554 	unsigned int i;
555 	struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
556 
557 	assert(pipe);
558 	assert(in_info);
559 	assert(out_info);
560 	assert(stage_idx < NUM_PRIMARY_HQ_STAGES);
561 	/* vf_info can be NULL - example video_binarydescr */
562 	/*assert(vf_info != NULL);*/
563 	IA_CSS_ENTER_PRIVATE("");
564 
565 	if (pipe_version == IA_CSS_PIPE_VERSION_2_6_1)
566 		mode = primary_hq_binary_modes[stage_idx];
567 	else
568 		mode = IA_CSS_BINARY_MODE_PRIMARY;
569 
570 	if (ia_css_util_is_input_format_yuv(pipe->stream->config.input_config.format))
571 		mode = IA_CSS_BINARY_MODE_COPY;
572 
573 	in_info->res = pipe->config.input_effective_res;
574 	in_info->padded_width = in_info->res.width;
575 
576 #if !defined(HAS_NO_PACKED_RAW_PIXELS)
577 	if (pipe->stream->config.pack_raw_pixels)
578 		in_info->format = IA_CSS_FRAME_FORMAT_RAW_PACKED;
579 	else
580 #endif
581 		in_info->format = IA_CSS_FRAME_FORMAT_RAW;
582 
583 	in_info->raw_bit_depth = ia_css_pipe_util_pipe_input_format_bpp(pipe);
584 	out_infos[0] = out_info;
585 	for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
586 		out_infos[i] = NULL;
587 
588 	pipe_binarydesc_get_offline(pipe, mode,
589 				    prim_descr, in_info, out_infos, vf_info);
590 
591 	if (pipe->stream->config.online &&
592 	    pipe->stream->config.mode != IA_CSS_INPUT_MODE_MEMORY) {
593 		prim_descr->online = true;
594 		prim_descr->two_ppc =
595 		    (pipe->stream->config.pixels_per_clock == 2);
596 		prim_descr->stream_format = pipe->stream->config.input_config.format;
597 	}
598 	if (mode == IA_CSS_BINARY_MODE_PRIMARY) {
599 		prim_descr->isp_pipe_version = pipe->config.isp_pipe_version;
600 		prim_descr->enable_fractional_ds =
601 		    pipe->extra_config.enable_fractional_ds;
602 		prim_descr->enable_luma_only =
603 		    pipe->config.enable_luma_only;
604 		/* We have both striped and non-striped primary binaries,
605 		 * if continuous viewfinder is required, then we must select
606 		 * a striped one. Otherwise we prefer to use a non-striped
607 		 * since it has better performance. */
608 		if (pipe_version == IA_CSS_PIPE_VERSION_2_6_1)
609 			prim_descr->striped = false;
610 		else if (!atomisp_hw_is_isp2401) {
611 			prim_descr->striped = prim_descr->continuous &&
612 					      (!pipe->stream->stop_copy_preview || !pipe->stream->disable_cont_vf);
613 		} else {
614 			prim_descr->striped = prim_descr->continuous && !pipe->stream->disable_cont_vf;
615 
616 			if ((pipe->config.default_capture_config.enable_xnr != 0) &&
617 			    (pipe->extra_config.enable_dvs_6axis == true))
618 				prim_descr->enable_xnr = true;
619 		}
620 	}
621 	IA_CSS_LEAVE_PRIVATE("");
622 }
623 
624 void ia_css_pipe_get_pre_gdc_binarydesc(
625     struct ia_css_pipe const *const pipe,
626     struct ia_css_binary_descr *pre_gdc_descr,
627     struct ia_css_frame_info *in_info,
628     struct ia_css_frame_info *out_info)
629 {
630 	unsigned int i;
631 	struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
632 
633 	assert(pipe);
634 	assert(in_info);
635 	assert(out_info);
636 	IA_CSS_ENTER_PRIVATE("");
637 
638 	*in_info = *out_info;
639 	in_info->format = IA_CSS_FRAME_FORMAT_RAW;
640 	in_info->raw_bit_depth = ia_css_pipe_util_pipe_input_format_bpp(pipe);
641 	out_infos[0] = out_info;
642 	for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
643 		out_infos[i] = NULL;
644 
645 	pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_PRE_ISP,
646 				    pre_gdc_descr, in_info, out_infos, NULL);
647 	pre_gdc_descr->isp_pipe_version = pipe->config.isp_pipe_version;
648 	IA_CSS_LEAVE_PRIVATE("");
649 }
650 
651 void ia_css_pipe_get_gdc_binarydesc(
652     struct ia_css_pipe const *const pipe,
653     struct ia_css_binary_descr *gdc_descr,
654     struct ia_css_frame_info *in_info,
655     struct ia_css_frame_info *out_info)
656 {
657 	unsigned int i;
658 	struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
659 
660 	assert(pipe);
661 	assert(in_info);
662 	assert(out_info);
663 	IA_CSS_ENTER_PRIVATE("");
664 
665 	*in_info = *out_info;
666 	in_info->format = IA_CSS_FRAME_FORMAT_QPLANE6;
667 	out_infos[0] = out_info;
668 	for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
669 		out_infos[i] = NULL;
670 
671 	pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_GDC,
672 				    gdc_descr, in_info, out_infos, NULL);
673 	IA_CSS_LEAVE_PRIVATE("");
674 }
675 
676 void ia_css_pipe_get_post_gdc_binarydesc(
677     struct ia_css_pipe const *const pipe,
678     struct ia_css_binary_descr *post_gdc_descr,
679     struct ia_css_frame_info *in_info,
680     struct ia_css_frame_info *out_info,
681     struct ia_css_frame_info *vf_info)
682 {
683 	unsigned int i;
684 	struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
685 
686 	assert(pipe);
687 	assert(in_info);
688 	assert(out_info);
689 	assert(vf_info);
690 	IA_CSS_ENTER_PRIVATE("");
691 
692 	*in_info = *out_info;
693 	in_info->format = IA_CSS_FRAME_FORMAT_YUV420_16;
694 	in_info->raw_bit_depth = 16;
695 	out_infos[0] = out_info;
696 	for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
697 		out_infos[i] = NULL;
698 
699 	pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_POST_ISP,
700 				    post_gdc_descr, in_info, out_infos, vf_info);
701 
702 	post_gdc_descr->isp_pipe_version = pipe->config.isp_pipe_version;
703 	IA_CSS_LEAVE_PRIVATE("");
704 }
705 
706 void ia_css_pipe_get_pre_de_binarydesc(
707     struct ia_css_pipe const *const pipe,
708     struct ia_css_binary_descr *pre_de_descr,
709     struct ia_css_frame_info *in_info,
710     struct ia_css_frame_info *out_info)
711 {
712 	unsigned int i;
713 	struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
714 
715 	assert(pipe);
716 	assert(in_info);
717 	assert(out_info);
718 	IA_CSS_ENTER_PRIVATE("");
719 
720 	*in_info = *out_info;
721 	in_info->format = IA_CSS_FRAME_FORMAT_RAW;
722 	in_info->raw_bit_depth = ia_css_pipe_util_pipe_input_format_bpp(pipe);
723 	out_infos[0] = out_info;
724 	for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
725 		out_infos[i] = NULL;
726 
727 	if (pipe->config.isp_pipe_version == IA_CSS_PIPE_VERSION_1)
728 		pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_PRE_ISP,
729 					    pre_de_descr, in_info, out_infos, NULL);
730 	else if (pipe->config.isp_pipe_version == IA_CSS_PIPE_VERSION_2_2) {
731 		pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_PRE_DE,
732 					    pre_de_descr, in_info, out_infos, NULL);
733 	}
734 
735 	if (pipe->stream->config.online) {
736 		pre_de_descr->online = true;
737 		pre_de_descr->two_ppc =
738 		    (pipe->stream->config.pixels_per_clock == 2);
739 		pre_de_descr->stream_format = pipe->stream->config.input_config.format;
740 	}
741 	pre_de_descr->isp_pipe_version = pipe->config.isp_pipe_version;
742 	IA_CSS_LEAVE_PRIVATE("");
743 }
744 
745 void ia_css_pipe_get_pre_anr_binarydesc(
746     struct ia_css_pipe const *const pipe,
747     struct ia_css_binary_descr *pre_anr_descr,
748     struct ia_css_frame_info *in_info,
749     struct ia_css_frame_info *out_info)
750 {
751 	unsigned int i;
752 	struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
753 
754 	assert(pipe);
755 	assert(in_info);
756 	assert(out_info);
757 	IA_CSS_ENTER_PRIVATE("");
758 
759 	*in_info = *out_info;
760 	in_info->format = IA_CSS_FRAME_FORMAT_RAW;
761 	in_info->raw_bit_depth = ia_css_pipe_util_pipe_input_format_bpp(pipe);
762 	out_infos[0] = out_info;
763 	for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
764 		out_infos[i] = NULL;
765 
766 	pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_PRE_ISP,
767 				    pre_anr_descr, in_info, out_infos, NULL);
768 
769 	if (pipe->stream->config.online) {
770 		pre_anr_descr->online = true;
771 		pre_anr_descr->two_ppc =
772 		    (pipe->stream->config.pixels_per_clock == 2);
773 		pre_anr_descr->stream_format = pipe->stream->config.input_config.format;
774 	}
775 	pre_anr_descr->isp_pipe_version = pipe->config.isp_pipe_version;
776 	IA_CSS_LEAVE_PRIVATE("");
777 }
778 
779 void ia_css_pipe_get_anr_binarydesc(
780     struct ia_css_pipe const *const pipe,
781     struct ia_css_binary_descr *anr_descr,
782     struct ia_css_frame_info *in_info,
783     struct ia_css_frame_info *out_info)
784 {
785 	unsigned int i;
786 	struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
787 
788 	assert(pipe);
789 	assert(in_info);
790 	assert(out_info);
791 	IA_CSS_ENTER_PRIVATE("");
792 
793 	*in_info = *out_info;
794 	in_info->format = IA_CSS_FRAME_FORMAT_RAW;
795 	in_info->raw_bit_depth = ANR_ELEMENT_BITS;
796 	out_infos[0] = out_info;
797 	for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
798 		out_infos[i] = NULL;
799 
800 	pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_ANR,
801 				    anr_descr, in_info, out_infos, NULL);
802 
803 	anr_descr->isp_pipe_version = pipe->config.isp_pipe_version;
804 	IA_CSS_LEAVE_PRIVATE("");
805 }
806 
807 void ia_css_pipe_get_post_anr_binarydesc(
808     struct ia_css_pipe const *const pipe,
809     struct ia_css_binary_descr *post_anr_descr,
810     struct ia_css_frame_info *in_info,
811     struct ia_css_frame_info *out_info,
812     struct ia_css_frame_info *vf_info)
813 {
814 	unsigned int i;
815 	struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
816 
817 	assert(pipe);
818 	assert(in_info);
819 	assert(out_info);
820 	assert(vf_info);
821 	IA_CSS_ENTER_PRIVATE("");
822 
823 	*in_info = *out_info;
824 	in_info->format = IA_CSS_FRAME_FORMAT_RAW;
825 	in_info->raw_bit_depth = ANR_ELEMENT_BITS;
826 	out_infos[0] = out_info;
827 	for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
828 		out_infos[i] = NULL;
829 
830 	pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_POST_ISP,
831 				    post_anr_descr, in_info, out_infos, vf_info);
832 
833 	post_anr_descr->isp_pipe_version = pipe->config.isp_pipe_version;
834 	IA_CSS_LEAVE_PRIVATE("");
835 }
836 
837 void ia_css_pipe_get_ldc_binarydesc(
838     struct ia_css_pipe const *const pipe,
839     struct ia_css_binary_descr *ldc_descr,
840     struct ia_css_frame_info *in_info,
841     struct ia_css_frame_info *out_info)
842 {
843 	unsigned int i;
844 	struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
845 
846 	assert(pipe);
847 	assert(in_info);
848 	assert(out_info);
849 	IA_CSS_ENTER_PRIVATE("");
850 
851 	if (!atomisp_hw_is_isp2401) {
852 		*in_info = *out_info;
853 	} else {
854 		if (pipe->out_yuv_ds_input_info.res.width)
855 			*in_info = pipe->out_yuv_ds_input_info;
856 		else
857 			*in_info = *out_info;
858 	}
859 
860 	in_info->format = IA_CSS_FRAME_FORMAT_YUV420;
861 	in_info->raw_bit_depth = 0;
862 	ia_css_frame_info_set_width(in_info, in_info->res.width, 0);
863 
864 	out_infos[0] = out_info;
865 	for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
866 		out_infos[i] = NULL;
867 
868 	pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_CAPTURE_PP,
869 				    ldc_descr, in_info, out_infos, NULL);
870 	ldc_descr->enable_dvs_6axis =
871 	    pipe->extra_config.enable_dvs_6axis;
872 	IA_CSS_LEAVE_PRIVATE("");
873 }
874