]>
Commit | Line | Data |
---|---|---|
a49d2536 AC |
1 | #ifndef ISP2401 |
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 | #else | |
d929fb4e | 16 | /* |
a49d2536 AC |
17 | Support for Intel Camera Imaging ISP subsystem. |
18 | Copyright (c) 2010 - 2015, Intel Corporation. | |
19 | ||
20 | This program is free software; you can redistribute it and/or modify it | |
21 | under the terms and conditions of the GNU General Public License, | |
22 | version 2, as published by the Free Software Foundation. | |
23 | ||
24 | This program is distributed in the hope it will be useful, but WITHOUT | |
25 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
26 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
27 | more details. | |
28 | */ | |
29 | #endif | |
30 | ||
31 | #include "system_global.h" | |
7e8e8091 | 32 | #include <linux/kernel.h> |
a49d2536 AC |
33 | |
34 | #ifdef USE_INPUT_SYSTEM_VERSION_2 | |
35 | ||
36 | #include "ia_css_ifmtr.h" | |
37 | #include <math_support.h> | |
38 | #include "sh_css_internal.h" | |
39 | #include "input_formatter.h" | |
40 | #include "assert_support.h" | |
41 | #include "sh_css_sp.h" | |
42 | #include "isp/modes/interface/input_buf.isp.h" | |
43 | ||
44 | /************************************************************ | |
45 | * Static functions declarations | |
46 | ************************************************************/ | |
47 | static enum ia_css_err ifmtr_start_column( | |
48 | const struct ia_css_stream_config *config, | |
49 | unsigned int bin_in, | |
50 | unsigned int *start_column); | |
51 | ||
52 | static enum ia_css_err ifmtr_input_start_line( | |
53 | const struct ia_css_stream_config *config, | |
54 | unsigned int bin_in, | |
55 | unsigned int *start_line); | |
56 | ||
57 | static void ifmtr_set_if_blocking_mode( | |
58 | const input_formatter_cfg_t * const config_a, | |
59 | const input_formatter_cfg_t * const config_b); | |
60 | ||
61 | /************************************************************ | |
62 | * Public functions | |
63 | ************************************************************/ | |
64 | ||
65 | /* ISP expects GRBG bayer order, we skip one line and/or one row | |
66 | * to correct in case the input bayer order is different. | |
67 | */ | |
68 | unsigned int ia_css_ifmtr_lines_needed_for_bayer_order( | |
69 | const struct ia_css_stream_config *config) | |
70 | { | |
71 | assert(config != NULL); | |
72 | if ((IA_CSS_BAYER_ORDER_BGGR == config->input_config.bayer_order) | |
73 | || (IA_CSS_BAYER_ORDER_GBRG == config->input_config.bayer_order)) | |
74 | return 1; | |
75 | ||
76 | return 0; | |
77 | } | |
78 | ||
79 | unsigned int ia_css_ifmtr_columns_needed_for_bayer_order( | |
80 | const struct ia_css_stream_config *config) | |
81 | { | |
82 | assert(config != NULL); | |
83 | if ((IA_CSS_BAYER_ORDER_RGGB == config->input_config.bayer_order) | |
84 | || (IA_CSS_BAYER_ORDER_GBRG == config->input_config.bayer_order)) | |
85 | return 1; | |
86 | ||
87 | return 0; | |
88 | } | |
89 | ||
90 | enum ia_css_err ia_css_ifmtr_configure(struct ia_css_stream_config *config, | |
91 | struct ia_css_binary *binary) | |
92 | { | |
93 | unsigned int start_line, start_column = 0, | |
94 | cropped_height, | |
95 | cropped_width, | |
96 | num_vectors, | |
97 | buffer_height = 2, | |
98 | buffer_width, | |
99 | two_ppc, | |
100 | vmem_increment = 0, | |
101 | deinterleaving = 0, | |
102 | deinterleaving_b = 0, | |
103 | width_a = 0, | |
104 | width_b = 0, | |
105 | bits_per_pixel, | |
106 | vectors_per_buffer, | |
107 | vectors_per_line = 0, | |
108 | buffers_per_line = 0, | |
109 | buf_offset_a = 0, | |
110 | buf_offset_b = 0, | |
111 | line_width = 0, | |
112 | width_b_factor = 1, start_column_b, | |
113 | left_padding = 0; | |
114 | input_formatter_cfg_t if_a_config, if_b_config; | |
115 | enum ia_css_stream_format input_format; | |
116 | enum ia_css_err err = IA_CSS_SUCCESS; | |
117 | uint8_t if_config_index; | |
118 | ||
119 | /* Determine which input formatter config set is targeted. */ | |
120 | /* Index is equal to the CSI-2 port used. */ | |
121 | enum ia_css_csi2_port port; | |
122 | ||
123 | if (binary) { | |
124 | cropped_height = binary->in_frame_info.res.height; | |
125 | cropped_width = binary->in_frame_info.res.width; | |
126 | /* This should correspond to the input buffer definition for | |
127 | ISP binaries in input_buf.isp.h */ | |
128 | if (binary->info->sp.enable.continuous && binary->info->sp.pipeline.mode != IA_CSS_BINARY_MODE_COPY) | |
129 | buffer_width = MAX_VECTORS_PER_INPUT_LINE_CONT * ISP_VEC_NELEMS; | |
130 | else | |
131 | buffer_width = binary->info->sp.input.max_width; | |
132 | input_format = binary->input_format; | |
133 | } else { | |
134 | /* sp raw copy pipe (IA_CSS_PIPE_MODE_COPY): binary is NULL */ | |
135 | cropped_height = config->input_config.input_res.height; | |
136 | cropped_width = config->input_config.input_res.width; | |
137 | buffer_width = MAX_VECTORS_PER_INPUT_LINE_CONT * ISP_VEC_NELEMS; | |
138 | input_format = config->input_config.format; | |
139 | } | |
140 | two_ppc = config->pixels_per_clock == 2; | |
141 | if (config->mode == IA_CSS_INPUT_MODE_SENSOR | |
142 | || config->mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR) { | |
143 | port = config->source.port.port; | |
144 | if_config_index = (uint8_t) (port - IA_CSS_CSI2_PORT0); | |
145 | } else if (config->mode == IA_CSS_INPUT_MODE_MEMORY) { | |
146 | if_config_index = SH_CSS_IF_CONFIG_NOT_NEEDED; | |
147 | } else { | |
148 | if_config_index = 0; | |
149 | } | |
150 | ||
151 | assert(if_config_index <= SH_CSS_MAX_IF_CONFIGS | |
152 | || if_config_index == SH_CSS_IF_CONFIG_NOT_NEEDED); | |
153 | ||
154 | /* TODO: check to see if input is RAW and if current mode interprets | |
155 | * RAW data in any particular bayer order. copy binary with output | |
156 | * format other than raw should not result in dropping lines and/or | |
157 | * columns. | |
158 | */ | |
159 | err = ifmtr_input_start_line(config, cropped_height, &start_line); | |
160 | if (err != IA_CSS_SUCCESS) | |
161 | return err; | |
162 | err = ifmtr_start_column(config, cropped_width, &start_column); | |
163 | if (err != IA_CSS_SUCCESS) | |
164 | return err; | |
165 | ||
166 | if (config->left_padding == -1) | |
167 | if (!binary) | |
168 | /* sp raw copy pipe: set left_padding value */ | |
169 | left_padding = 0; | |
170 | else | |
171 | left_padding = binary->left_padding; | |
172 | else | |
173 | left_padding = 2*ISP_VEC_NELEMS - config->left_padding; | |
174 | ||
175 | ||
176 | if (left_padding) { | |
177 | num_vectors = CEIL_DIV(cropped_width + left_padding, | |
178 | ISP_VEC_NELEMS); | |
179 | } else { | |
180 | num_vectors = CEIL_DIV(cropped_width, ISP_VEC_NELEMS); | |
181 | num_vectors *= buffer_height; | |
182 | /* todo: in case of left padding, | |
183 | num_vectors is vectors per line, | |
184 | otherwise vectors per line * buffer_height. */ | |
185 | } | |
186 | ||
187 | start_column_b = start_column; | |
188 | ||
189 | bits_per_pixel = input_formatter_get_alignment(INPUT_FORMATTER0_ID) | |
190 | * 8 / ISP_VEC_NELEMS; | |
191 | switch (input_format) { | |
192 | case IA_CSS_STREAM_FORMAT_YUV420_8_LEGACY: | |
193 | if (two_ppc) { | |
194 | vmem_increment = 1; | |
195 | deinterleaving = 1; | |
196 | deinterleaving_b = 1; | |
197 | /* half lines */ | |
198 | width_a = cropped_width * deinterleaving / 2; | |
199 | width_b_factor = 2; | |
200 | /* full lines */ | |
201 | width_b = width_a * width_b_factor; | |
202 | buffer_width *= deinterleaving * 2; | |
203 | /* Patch from bayer to yuv */ | |
204 | num_vectors *= deinterleaving; | |
205 | buf_offset_b = buffer_width / 2 / ISP_VEC_NELEMS; | |
206 | vectors_per_line = num_vectors / buffer_height; | |
207 | /* Even lines are half size */ | |
208 | line_width = vectors_per_line * | |
209 | input_formatter_get_alignment(INPUT_FORMATTER0_ID) / | |
210 | 2; | |
211 | start_column /= 2; | |
212 | } else { | |
213 | vmem_increment = 1; | |
214 | deinterleaving = 3; | |
215 | width_a = cropped_width * deinterleaving / 2; | |
216 | buffer_width = buffer_width * deinterleaving / 2; | |
217 | /* Patch from bayer to yuv */ | |
218 | num_vectors = num_vectors / 2 * deinterleaving; | |
219 | start_column = start_column * deinterleaving / 2; | |
220 | } | |
221 | break; | |
222 | case IA_CSS_STREAM_FORMAT_YUV420_8: | |
223 | case IA_CSS_STREAM_FORMAT_YUV420_10: | |
224 | case IA_CSS_STREAM_FORMAT_YUV420_16: | |
225 | if (two_ppc) { | |
226 | vmem_increment = 1; | |
227 | deinterleaving = 1; | |
228 | width_a = width_b = cropped_width * deinterleaving / 2; | |
229 | buffer_width *= deinterleaving * 2; | |
230 | num_vectors *= deinterleaving; | |
231 | buf_offset_b = buffer_width / 2 / ISP_VEC_NELEMS; | |
232 | vectors_per_line = num_vectors / buffer_height; | |
233 | /* Even lines are half size */ | |
234 | line_width = vectors_per_line * | |
235 | input_formatter_get_alignment(INPUT_FORMATTER0_ID) / | |
236 | 2; | |
237 | start_column *= deinterleaving; | |
238 | start_column /= 2; | |
239 | start_column_b = start_column; | |
240 | } else { | |
241 | vmem_increment = 1; | |
242 | deinterleaving = 1; | |
243 | width_a = cropped_width * deinterleaving; | |
244 | buffer_width *= deinterleaving * 2; | |
245 | num_vectors *= deinterleaving; | |
246 | start_column *= deinterleaving; | |
247 | } | |
248 | break; | |
249 | case IA_CSS_STREAM_FORMAT_YUV422_8: | |
250 | case IA_CSS_STREAM_FORMAT_YUV422_10: | |
251 | case IA_CSS_STREAM_FORMAT_YUV422_16: | |
252 | if (two_ppc) { | |
253 | vmem_increment = 1; | |
254 | deinterleaving = 1; | |
255 | width_a = width_b = cropped_width * deinterleaving; | |
256 | buffer_width *= deinterleaving * 2; | |
257 | num_vectors *= deinterleaving; | |
258 | start_column *= deinterleaving; | |
259 | buf_offset_b = buffer_width / 2 / ISP_VEC_NELEMS; | |
260 | start_column_b = start_column; | |
261 | } else { | |
262 | vmem_increment = 1; | |
263 | deinterleaving = 2; | |
264 | width_a = cropped_width * deinterleaving; | |
265 | buffer_width *= deinterleaving; | |
266 | num_vectors *= deinterleaving; | |
267 | start_column *= deinterleaving; | |
268 | } | |
269 | break; | |
270 | case IA_CSS_STREAM_FORMAT_RGB_444: | |
271 | case IA_CSS_STREAM_FORMAT_RGB_555: | |
272 | case IA_CSS_STREAM_FORMAT_RGB_565: | |
273 | case IA_CSS_STREAM_FORMAT_RGB_666: | |
274 | case IA_CSS_STREAM_FORMAT_RGB_888: | |
275 | num_vectors *= 2; | |
276 | if (two_ppc) { | |
277 | deinterleaving = 2; /* BR in if_a, G in if_b */ | |
278 | deinterleaving_b = 1; /* BR in if_a, G in if_b */ | |
279 | buffers_per_line = 4; | |
280 | start_column_b = start_column; | |
281 | start_column *= deinterleaving; | |
282 | start_column_b *= deinterleaving_b; | |
283 | } else { | |
284 | deinterleaving = 3; /* BGR */ | |
285 | buffers_per_line = 3; | |
286 | start_column *= deinterleaving; | |
287 | } | |
288 | vmem_increment = 1; | |
289 | width_a = cropped_width * deinterleaving; | |
290 | width_b = cropped_width * deinterleaving_b; | |
291 | buffer_width *= buffers_per_line; | |
292 | /* Patch from bayer to rgb */ | |
293 | num_vectors = num_vectors / 2 * deinterleaving; | |
294 | buf_offset_b = buffer_width / 2 / ISP_VEC_NELEMS; | |
295 | break; | |
296 | case IA_CSS_STREAM_FORMAT_RAW_6: | |
297 | case IA_CSS_STREAM_FORMAT_RAW_7: | |
298 | case IA_CSS_STREAM_FORMAT_RAW_8: | |
299 | case IA_CSS_STREAM_FORMAT_RAW_10: | |
300 | case IA_CSS_STREAM_FORMAT_RAW_12: | |
301 | if (two_ppc) { | |
302 | int crop_col = (start_column % 2) == 1; | |
303 | vmem_increment = 2; | |
304 | deinterleaving = 1; | |
305 | width_a = width_b = cropped_width / 2; | |
306 | ||
307 | /* When two_ppc is enabled AND we need to crop one extra | |
308 | * column, if_a crops by one extra and we swap the | |
309 | * output offsets to interleave the bayer pattern in | |
310 | * the correct order. | |
311 | */ | |
312 | buf_offset_a = crop_col ? 1 : 0; | |
313 | buf_offset_b = crop_col ? 0 : 1; | |
314 | start_column_b = start_column / 2; | |
315 | start_column = start_column / 2 + crop_col; | |
316 | } else { | |
317 | vmem_increment = 1; | |
318 | deinterleaving = 2; | |
319 | if ((!binary) || (config->continuous && binary | |
320 | && binary->info->sp.pipeline.mode == IA_CSS_BINARY_MODE_COPY)) { | |
321 | /* !binary -> sp raw copy pipe, no deinterleaving */ | |
322 | deinterleaving = 1; | |
323 | } | |
324 | width_a = cropped_width; | |
325 | /* Must be multiple of deinterleaving */ | |
326 | num_vectors = CEIL_MUL(num_vectors, deinterleaving); | |
327 | } | |
328 | buffer_height *= 2; | |
329 | if ((!binary) || config->continuous) | |
330 | /* !binary -> sp raw copy pipe */ | |
331 | buffer_height *= 2; | |
332 | vectors_per_line = CEIL_DIV(cropped_width, ISP_VEC_NELEMS); | |
333 | vectors_per_line = CEIL_MUL(vectors_per_line, deinterleaving); | |
334 | break; | |
335 | case IA_CSS_STREAM_FORMAT_RAW_14: | |
336 | case IA_CSS_STREAM_FORMAT_RAW_16: | |
337 | if (two_ppc) { | |
338 | num_vectors *= 2; | |
339 | vmem_increment = 1; | |
340 | deinterleaving = 2; | |
341 | width_a = width_b = cropped_width; | |
342 | /* B buffer is one line further */ | |
343 | buf_offset_b = buffer_width / ISP_VEC_NELEMS; | |
344 | bits_per_pixel *= 2; | |
345 | } else { | |
346 | vmem_increment = 1; | |
347 | deinterleaving = 2; | |
348 | width_a = cropped_width; | |
349 | start_column /= deinterleaving; | |
350 | } | |
351 | buffer_height *= 2; | |
352 | break; | |
353 | case IA_CSS_STREAM_FORMAT_BINARY_8: | |
354 | case IA_CSS_STREAM_FORMAT_GENERIC_SHORT1: | |
355 | case IA_CSS_STREAM_FORMAT_GENERIC_SHORT2: | |
356 | case IA_CSS_STREAM_FORMAT_GENERIC_SHORT3: | |
357 | case IA_CSS_STREAM_FORMAT_GENERIC_SHORT4: | |
358 | case IA_CSS_STREAM_FORMAT_GENERIC_SHORT5: | |
359 | case IA_CSS_STREAM_FORMAT_GENERIC_SHORT6: | |
360 | case IA_CSS_STREAM_FORMAT_GENERIC_SHORT7: | |
361 | case IA_CSS_STREAM_FORMAT_GENERIC_SHORT8: | |
362 | case IA_CSS_STREAM_FORMAT_YUV420_8_SHIFT: | |
363 | case IA_CSS_STREAM_FORMAT_YUV420_10_SHIFT: | |
364 | case IA_CSS_STREAM_FORMAT_EMBEDDED: | |
365 | case IA_CSS_STREAM_FORMAT_USER_DEF1: | |
366 | case IA_CSS_STREAM_FORMAT_USER_DEF2: | |
367 | case IA_CSS_STREAM_FORMAT_USER_DEF3: | |
368 | case IA_CSS_STREAM_FORMAT_USER_DEF4: | |
369 | case IA_CSS_STREAM_FORMAT_USER_DEF5: | |
370 | case IA_CSS_STREAM_FORMAT_USER_DEF6: | |
371 | case IA_CSS_STREAM_FORMAT_USER_DEF7: | |
372 | case IA_CSS_STREAM_FORMAT_USER_DEF8: | |
373 | break; | |
374 | } | |
375 | if (width_a == 0) | |
376 | return IA_CSS_ERR_INVALID_ARGUMENTS; | |
377 | ||
378 | if (two_ppc) | |
379 | left_padding /= 2; | |
380 | ||
381 | /* Default values */ | |
382 | if (left_padding) | |
383 | vectors_per_line = num_vectors; | |
384 | if (!vectors_per_line) { | |
385 | vectors_per_line = CEIL_MUL(num_vectors / buffer_height, | |
386 | deinterleaving); | |
387 | line_width = 0; | |
388 | } | |
389 | if (!line_width) | |
390 | line_width = vectors_per_line * | |
391 | input_formatter_get_alignment(INPUT_FORMATTER0_ID); | |
392 | if (!buffers_per_line) | |
393 | buffers_per_line = deinterleaving; | |
394 | line_width = CEIL_MUL(line_width, | |
395 | input_formatter_get_alignment(INPUT_FORMATTER0_ID) | |
396 | * vmem_increment); | |
397 | ||
398 | vectors_per_buffer = buffer_height * buffer_width / ISP_VEC_NELEMS; | |
399 | ||
400 | if (config->mode == IA_CSS_INPUT_MODE_TPG && | |
401 | ((binary && binary->info->sp.pipeline.mode == IA_CSS_BINARY_MODE_VIDEO) || | |
402 | (!binary))) { | |
403 | /* !binary -> sp raw copy pipe */ | |
404 | /* workaround for TPG in video mode */ | |
405 | start_line = 0; | |
406 | start_column = 0; | |
407 | cropped_height -= start_line; | |
408 | width_a -= start_column; | |
409 | } | |
410 | ||
411 | if_a_config.start_line = start_line; | |
412 | if_a_config.start_column = start_column; | |
413 | if_a_config.left_padding = left_padding / deinterleaving; | |
414 | if_a_config.cropped_height = cropped_height; | |
415 | if_a_config.cropped_width = width_a; | |
416 | if_a_config.deinterleaving = deinterleaving; | |
417 | if_a_config.buf_vecs = vectors_per_buffer; | |
418 | if_a_config.buf_start_index = buf_offset_a; | |
419 | if_a_config.buf_increment = vmem_increment; | |
420 | if_a_config.buf_eol_offset = | |
421 | buffer_width * bits_per_pixel / 8 - line_width; | |
422 | if_a_config.is_yuv420_format = | |
423 | (input_format == IA_CSS_STREAM_FORMAT_YUV420_8) | |
424 | || (input_format == IA_CSS_STREAM_FORMAT_YUV420_10) | |
425 | || (input_format == IA_CSS_STREAM_FORMAT_YUV420_16); | |
426 | if_a_config.block_no_reqs = (config->mode != IA_CSS_INPUT_MODE_SENSOR); | |
427 | ||
428 | if (two_ppc) { | |
429 | if (deinterleaving_b) { | |
430 | deinterleaving = deinterleaving_b; | |
431 | width_b = cropped_width * deinterleaving; | |
432 | buffer_width *= deinterleaving; | |
433 | /* Patch from bayer to rgb */ | |
434 | num_vectors = num_vectors / 2 * | |
435 | deinterleaving * width_b_factor; | |
436 | vectors_per_line = num_vectors / buffer_height; | |
437 | line_width = vectors_per_line * | |
438 | input_formatter_get_alignment(INPUT_FORMATTER0_ID); | |
439 | } | |
440 | if_b_config.start_line = start_line; | |
441 | if_b_config.start_column = start_column_b; | |
442 | if_b_config.left_padding = left_padding / deinterleaving; | |
443 | if_b_config.cropped_height = cropped_height; | |
444 | if_b_config.cropped_width = width_b; | |
445 | if_b_config.deinterleaving = deinterleaving; | |
446 | if_b_config.buf_vecs = vectors_per_buffer; | |
447 | if_b_config.buf_start_index = buf_offset_b; | |
448 | if_b_config.buf_increment = vmem_increment; | |
449 | if_b_config.buf_eol_offset = | |
450 | buffer_width * bits_per_pixel / 8 - line_width; | |
451 | if_b_config.is_yuv420_format = | |
452 | input_format == IA_CSS_STREAM_FORMAT_YUV420_8 | |
453 | || input_format == IA_CSS_STREAM_FORMAT_YUV420_10 | |
454 | || input_format == IA_CSS_STREAM_FORMAT_YUV420_16; | |
455 | if_b_config.block_no_reqs = | |
456 | (config->mode != IA_CSS_INPUT_MODE_SENSOR); | |
457 | ||
458 | if (SH_CSS_IF_CONFIG_NOT_NEEDED != if_config_index) { | |
459 | assert(if_config_index <= SH_CSS_MAX_IF_CONFIGS); | |
460 | ||
461 | ifmtr_set_if_blocking_mode(&if_a_config, &if_b_config); | |
462 | /* Set the ifconfigs to SP group */ | |
463 | sh_css_sp_set_if_configs(&if_a_config, &if_b_config, | |
464 | if_config_index); | |
465 | } | |
466 | } else { | |
467 | if (SH_CSS_IF_CONFIG_NOT_NEEDED != if_config_index) { | |
468 | assert(if_config_index <= SH_CSS_MAX_IF_CONFIGS); | |
469 | ||
470 | ifmtr_set_if_blocking_mode(&if_a_config, NULL); | |
471 | /* Set the ifconfigs to SP group */ | |
472 | sh_css_sp_set_if_configs(&if_a_config, NULL, | |
473 | if_config_index); | |
474 | } | |
475 | } | |
476 | ||
477 | return IA_CSS_SUCCESS; | |
478 | } | |
479 | ||
480 | bool ifmtr_set_if_blocking_mode_reset = true; | |
481 | ||
482 | /************************************************************ | |
483 | * Static functions | |
484 | ************************************************************/ | |
485 | static void ifmtr_set_if_blocking_mode( | |
486 | const input_formatter_cfg_t * const config_a, | |
487 | const input_formatter_cfg_t * const config_b) | |
488 | { | |
489 | int i; | |
490 | bool block[] = { false, false, false, false }; | |
7e8e8091 | 491 | assert(N_INPUT_FORMATTER_ID <= (ARRAY_SIZE(block))); |
a49d2536 AC |
492 | |
493 | #if !defined(IS_ISP_2400_SYSTEM) | |
494 | #error "ifmtr_set_if_blocking_mode: ISP_SYSTEM must be one of {IS_ISP_2400_SYSTEM}" | |
495 | #endif | |
496 | ||
497 | block[INPUT_FORMATTER0_ID] = (bool)config_a->block_no_reqs; | |
498 | if (NULL != config_b) | |
499 | block[INPUT_FORMATTER1_ID] = (bool)config_b->block_no_reqs; | |
500 | ||
501 | /* TODO: next could cause issues when streams are started after | |
502 | * eachother. */ | |
503 | /*IF should not be reconfigured/reset from host */ | |
504 | if (ifmtr_set_if_blocking_mode_reset) { | |
505 | ifmtr_set_if_blocking_mode_reset = false; | |
506 | for (i = 0; i < N_INPUT_FORMATTER_ID; i++) { | |
507 | input_formatter_ID_t id = (input_formatter_ID_t) i; | |
508 | input_formatter_rst(id); | |
509 | input_formatter_set_fifo_blocking_mode(id, block[id]); | |
510 | } | |
511 | } | |
512 | ||
513 | return; | |
514 | } | |
515 | ||
516 | static enum ia_css_err ifmtr_start_column( | |
517 | const struct ia_css_stream_config *config, | |
518 | unsigned int bin_in, | |
519 | unsigned int *start_column) | |
520 | { | |
521 | unsigned int in = config->input_config.input_res.width, start, | |
522 | for_bayer = ia_css_ifmtr_columns_needed_for_bayer_order(config); | |
523 | ||
524 | if (bin_in + 2 * for_bayer > in) | |
525 | return IA_CSS_ERR_INVALID_ARGUMENTS; | |
526 | ||
527 | /* On the hardware, we want to use the middle of the input, so we | |
528 | * divide the start column by 2. */ | |
529 | start = (in - bin_in) / 2; | |
530 | /* in case the number of extra columns is 2 or odd, we round the start | |
531 | * column down */ | |
532 | start &= ~0x1; | |
533 | ||
534 | /* now we add the one column (if needed) to correct for the bayer | |
535 | * order). | |
536 | */ | |
537 | start += for_bayer; | |
538 | *start_column = start; | |
539 | return IA_CSS_SUCCESS; | |
540 | } | |
541 | ||
542 | static enum ia_css_err ifmtr_input_start_line( | |
543 | const struct ia_css_stream_config *config, | |
544 | unsigned int bin_in, | |
545 | unsigned int *start_line) | |
546 | { | |
547 | unsigned int in = config->input_config.input_res.height, start, | |
548 | for_bayer = ia_css_ifmtr_lines_needed_for_bayer_order(config); | |
549 | ||
550 | if (bin_in + 2 * for_bayer > in) | |
551 | return IA_CSS_ERR_INVALID_ARGUMENTS; | |
552 | ||
553 | /* On the hardware, we want to use the middle of the input, so we | |
554 | * divide the start line by 2. On the simulator, we cannot handle extra | |
555 | * lines at the end of the frame. | |
556 | */ | |
557 | start = (in - bin_in) / 2; | |
558 | /* in case the number of extra lines is 2 or odd, we round the start | |
559 | * line down. | |
560 | */ | |
561 | start &= ~0x1; | |
562 | ||
563 | /* now we add the one line (if needed) to correct for the bayer order */ | |
564 | start += for_bayer; | |
565 | *start_line = start; | |
566 | return IA_CSS_SUCCESS; | |
567 | } | |
568 | ||
569 | #endif |