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