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