1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Support for Intel Camera Imaging ISP subsystem.
4 * Copyright (c) 2010 - 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 #define __INLINE_INPUT_SYSTEM__
17 #include "input_system.h"
18 #include "assert_support.h"
19 #include "ia_css_isys.h"
20 #include "ia_css_irq.h"
21 #include "sh_css_internal.h"
22
ia_css_isys_rx_enable_all_interrupts(enum mipi_port_id port)23 void ia_css_isys_rx_enable_all_interrupts(enum mipi_port_id port)
24 {
25 hrt_data bits = receiver_port_reg_load(RX0_ID,
26 port,
27 _HRT_CSS_RECEIVER_IRQ_ENABLE_REG_IDX);
28
29 bits |= (1U << _HRT_CSS_RECEIVER_IRQ_OVERRUN_BIT) |
30 (1U << _HRT_CSS_RECEIVER_IRQ_INIT_TIMEOUT_BIT) |
31 (1U << _HRT_CSS_RECEIVER_IRQ_SLEEP_MODE_ENTRY_BIT) |
32 (1U << _HRT_CSS_RECEIVER_IRQ_SLEEP_MODE_EXIT_BIT) |
33 (1U << _HRT_CSS_RECEIVER_IRQ_ERR_SOT_HS_BIT) |
34 (1U << _HRT_CSS_RECEIVER_IRQ_ERR_SOT_SYNC_HS_BIT) |
35 (1U << _HRT_CSS_RECEIVER_IRQ_ERR_CONTROL_BIT) |
36 (1U << _HRT_CSS_RECEIVER_IRQ_ERR_ECC_DOUBLE_BIT) |
37 (1U << _HRT_CSS_RECEIVER_IRQ_ERR_ECC_CORRECTED_BIT) |
38 /*(1U << _HRT_CSS_RECEIVER_IRQ_ERR_ECC_NO_CORRECTION_BIT) | */
39 (1U << _HRT_CSS_RECEIVER_IRQ_ERR_CRC_BIT) |
40 (1U << _HRT_CSS_RECEIVER_IRQ_ERR_ID_BIT) |
41 (1U << _HRT_CSS_RECEIVER_IRQ_ERR_FRAME_SYNC_BIT) |
42 (1U << _HRT_CSS_RECEIVER_IRQ_ERR_FRAME_DATA_BIT) |
43 (1U << _HRT_CSS_RECEIVER_IRQ_DATA_TIMEOUT_BIT) |
44 (1U << _HRT_CSS_RECEIVER_IRQ_ERR_ESCAPE_BIT);
45 /*(1U << _HRT_CSS_RECEIVER_IRQ_ERR_LINE_SYNC_BIT); */
46
47 receiver_port_reg_store(RX0_ID,
48 port,
49 _HRT_CSS_RECEIVER_IRQ_ENABLE_REG_IDX, bits);
50
51 /*
52 * The CSI is nested into the Iunit IRQ's
53 */
54 ia_css_irq_enable(IA_CSS_IRQ_INFO_CSS_RECEIVER_ERROR, true);
55
56 return;
57 }
58
59 /* This function converts between the enum used on the CSS API and the
60 * internal DLI enum type.
61 * We do not use an array for this since we cannot use named array
62 * initializers in Windows. Without that there is no easy way to guarantee
63 * that the array values would be in the correct order.
64 * */
ia_css_isys_port_to_mipi_port(enum mipi_port_id api_port)65 enum mipi_port_id ia_css_isys_port_to_mipi_port(enum mipi_port_id api_port)
66 {
67 /* In this module the validity of the inptu variable should
68 * have been checked already, so we do not check for erroneous
69 * values. */
70 enum mipi_port_id port = MIPI_PORT0_ID;
71
72 if (api_port == MIPI_PORT1_ID)
73 port = MIPI_PORT1_ID;
74 else if (api_port == MIPI_PORT2_ID)
75 port = MIPI_PORT2_ID;
76
77 return port;
78 }
79
ia_css_isys_rx_get_interrupt_reg(enum mipi_port_id port)80 unsigned int ia_css_isys_rx_get_interrupt_reg(enum mipi_port_id port)
81 {
82 return receiver_port_reg_load(RX0_ID,
83 port,
84 _HRT_CSS_RECEIVER_IRQ_STATUS_REG_IDX);
85 }
86
ia_css_rx_get_irq_info(unsigned int * irq_infos)87 void ia_css_rx_get_irq_info(unsigned int *irq_infos)
88 {
89 ia_css_rx_port_get_irq_info(MIPI_PORT1_ID, irq_infos);
90 }
91
ia_css_rx_port_get_irq_info(enum mipi_port_id api_port,unsigned int * irq_infos)92 void ia_css_rx_port_get_irq_info(enum mipi_port_id api_port,
93 unsigned int *irq_infos)
94 {
95 enum mipi_port_id port = ia_css_isys_port_to_mipi_port(api_port);
96
97 ia_css_isys_rx_get_irq_info(port, irq_infos);
98 }
99
ia_css_isys_rx_get_irq_info(enum mipi_port_id port,unsigned int * irq_infos)100 void ia_css_isys_rx_get_irq_info(enum mipi_port_id port,
101 unsigned int *irq_infos)
102 {
103 unsigned int bits;
104
105 assert(irq_infos);
106 bits = ia_css_isys_rx_get_interrupt_reg(port);
107 *irq_infos = ia_css_isys_rx_translate_irq_infos(bits);
108 }
109
110 /* Translate register bits to CSS API enum mask */
ia_css_isys_rx_translate_irq_infos(unsigned int bits)111 unsigned int ia_css_isys_rx_translate_irq_infos(unsigned int bits)
112 {
113 unsigned int infos = 0;
114
115 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_OVERRUN_BIT))
116 infos |= IA_CSS_RX_IRQ_INFO_BUFFER_OVERRUN;
117 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_INIT_TIMEOUT_BIT))
118 infos |= IA_CSS_RX_IRQ_INFO_INIT_TIMEOUT;
119 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_SLEEP_MODE_ENTRY_BIT))
120 infos |= IA_CSS_RX_IRQ_INFO_ENTER_SLEEP_MODE;
121 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_SLEEP_MODE_EXIT_BIT))
122 infos |= IA_CSS_RX_IRQ_INFO_EXIT_SLEEP_MODE;
123 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_ECC_CORRECTED_BIT))
124 infos |= IA_CSS_RX_IRQ_INFO_ECC_CORRECTED;
125 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_SOT_HS_BIT))
126 infos |= IA_CSS_RX_IRQ_INFO_ERR_SOT;
127 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_SOT_SYNC_HS_BIT))
128 infos |= IA_CSS_RX_IRQ_INFO_ERR_SOT_SYNC;
129 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_CONTROL_BIT))
130 infos |= IA_CSS_RX_IRQ_INFO_ERR_CONTROL;
131 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_ECC_DOUBLE_BIT))
132 infos |= IA_CSS_RX_IRQ_INFO_ERR_ECC_DOUBLE;
133 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_CRC_BIT))
134 infos |= IA_CSS_RX_IRQ_INFO_ERR_CRC;
135 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_ID_BIT))
136 infos |= IA_CSS_RX_IRQ_INFO_ERR_UNKNOWN_ID;
137 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_FRAME_SYNC_BIT))
138 infos |= IA_CSS_RX_IRQ_INFO_ERR_FRAME_SYNC;
139 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_FRAME_DATA_BIT))
140 infos |= IA_CSS_RX_IRQ_INFO_ERR_FRAME_DATA;
141 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_DATA_TIMEOUT_BIT))
142 infos |= IA_CSS_RX_IRQ_INFO_ERR_DATA_TIMEOUT;
143 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_ESCAPE_BIT))
144 infos |= IA_CSS_RX_IRQ_INFO_ERR_UNKNOWN_ESC;
145 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_LINE_SYNC_BIT))
146 infos |= IA_CSS_RX_IRQ_INFO_ERR_LINE_SYNC;
147
148 return infos;
149 }
150
ia_css_rx_clear_irq_info(unsigned int irq_infos)151 void ia_css_rx_clear_irq_info(unsigned int irq_infos)
152 {
153 ia_css_rx_port_clear_irq_info(MIPI_PORT1_ID, irq_infos);
154 }
155
ia_css_rx_port_clear_irq_info(enum mipi_port_id api_port,unsigned int irq_infos)156 void ia_css_rx_port_clear_irq_info(enum mipi_port_id api_port,
157 unsigned int irq_infos)
158 {
159 enum mipi_port_id port = ia_css_isys_port_to_mipi_port(api_port);
160
161 ia_css_isys_rx_clear_irq_info(port, irq_infos);
162 }
163
ia_css_isys_rx_clear_irq_info(enum mipi_port_id port,unsigned int irq_infos)164 void ia_css_isys_rx_clear_irq_info(enum mipi_port_id port,
165 unsigned int irq_infos)
166 {
167 hrt_data bits = receiver_port_reg_load(RX0_ID,
168 port,
169 _HRT_CSS_RECEIVER_IRQ_ENABLE_REG_IDX);
170
171 /* MW: Why do we remap the receiver bitmap */
172 if (irq_infos & IA_CSS_RX_IRQ_INFO_BUFFER_OVERRUN)
173 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_OVERRUN_BIT;
174 if (irq_infos & IA_CSS_RX_IRQ_INFO_INIT_TIMEOUT)
175 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_INIT_TIMEOUT_BIT;
176 if (irq_infos & IA_CSS_RX_IRQ_INFO_ENTER_SLEEP_MODE)
177 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_SLEEP_MODE_ENTRY_BIT;
178 if (irq_infos & IA_CSS_RX_IRQ_INFO_EXIT_SLEEP_MODE)
179 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_SLEEP_MODE_EXIT_BIT;
180 if (irq_infos & IA_CSS_RX_IRQ_INFO_ECC_CORRECTED)
181 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_ECC_CORRECTED_BIT;
182 if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_SOT)
183 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_SOT_HS_BIT;
184 if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_SOT_SYNC)
185 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_SOT_SYNC_HS_BIT;
186 if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_CONTROL)
187 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_CONTROL_BIT;
188 if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_ECC_DOUBLE)
189 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_ECC_DOUBLE_BIT;
190 if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_CRC)
191 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_CRC_BIT;
192 if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_UNKNOWN_ID)
193 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_ID_BIT;
194 if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_FRAME_SYNC)
195 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_FRAME_SYNC_BIT;
196 if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_FRAME_DATA)
197 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_FRAME_DATA_BIT;
198 if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_DATA_TIMEOUT)
199 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_DATA_TIMEOUT_BIT;
200 if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_UNKNOWN_ESC)
201 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_ESCAPE_BIT;
202 if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_LINE_SYNC)
203 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_LINE_SYNC_BIT;
204
205 receiver_port_reg_store(RX0_ID,
206 port,
207 _HRT_CSS_RECEIVER_IRQ_ENABLE_REG_IDX, bits);
208
209 return;
210 }
211
ia_css_isys_2400_set_fmt_type(enum atomisp_input_format input_format,unsigned int * fmt_type)212 static int ia_css_isys_2400_set_fmt_type(enum atomisp_input_format input_format,
213 unsigned int *fmt_type)
214 {
215 switch (input_format) {
216 case ATOMISP_INPUT_FORMAT_RGB_888:
217 *fmt_type = MIPI_FORMAT_2400_RGB888;
218 break;
219 case ATOMISP_INPUT_FORMAT_RGB_555:
220 *fmt_type = MIPI_FORMAT_2400_RGB555;
221 break;
222 case ATOMISP_INPUT_FORMAT_RGB_444:
223 *fmt_type = MIPI_FORMAT_2400_RGB444;
224 break;
225 case ATOMISP_INPUT_FORMAT_RGB_565:
226 *fmt_type = MIPI_FORMAT_2400_RGB565;
227 break;
228 case ATOMISP_INPUT_FORMAT_RGB_666:
229 *fmt_type = MIPI_FORMAT_2400_RGB666;
230 break;
231 case ATOMISP_INPUT_FORMAT_RAW_8:
232 *fmt_type = MIPI_FORMAT_2400_RAW8;
233 break;
234 case ATOMISP_INPUT_FORMAT_RAW_10:
235 *fmt_type = MIPI_FORMAT_2400_RAW10;
236 break;
237 case ATOMISP_INPUT_FORMAT_RAW_6:
238 *fmt_type = MIPI_FORMAT_2400_RAW6;
239 break;
240 case ATOMISP_INPUT_FORMAT_RAW_7:
241 *fmt_type = MIPI_FORMAT_2400_RAW7;
242 break;
243 case ATOMISP_INPUT_FORMAT_RAW_12:
244 *fmt_type = MIPI_FORMAT_2400_RAW12;
245 break;
246 case ATOMISP_INPUT_FORMAT_RAW_14:
247 *fmt_type = MIPI_FORMAT_2400_RAW14;
248 break;
249 case ATOMISP_INPUT_FORMAT_YUV420_8:
250 *fmt_type = MIPI_FORMAT_2400_YUV420_8;
251 break;
252 case ATOMISP_INPUT_FORMAT_YUV420_10:
253 *fmt_type = MIPI_FORMAT_2400_YUV420_10;
254 break;
255 case ATOMISP_INPUT_FORMAT_YUV422_8:
256 *fmt_type = MIPI_FORMAT_2400_YUV422_8;
257 break;
258 case ATOMISP_INPUT_FORMAT_YUV422_10:
259 *fmt_type = MIPI_FORMAT_2400_YUV422_10;
260 break;
261 case ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY:
262 *fmt_type = MIPI_FORMAT_2400_YUV420_8_LEGACY;
263 break;
264 case ATOMISP_INPUT_FORMAT_EMBEDDED:
265 *fmt_type = MIPI_FORMAT_2400_EMBEDDED;
266 break;
267 case ATOMISP_INPUT_FORMAT_RAW_16:
268 /* This is not specified by Arasan, so we use
269 * 17 for now.
270 */
271 *fmt_type = MIPI_FORMAT_2400_RAW16;
272 break;
273 case ATOMISP_INPUT_FORMAT_BINARY_8:
274 *fmt_type = MIPI_FORMAT_2400_CUSTOM0;
275 break;
276 case ATOMISP_INPUT_FORMAT_YUV420_16:
277 case ATOMISP_INPUT_FORMAT_YUV422_16:
278 default:
279 return -EINVAL;
280 }
281 return 0;
282 }
283
ia_css_isys_2401_set_fmt_type(enum atomisp_input_format input_format,unsigned int * fmt_type)284 static int ia_css_isys_2401_set_fmt_type(enum atomisp_input_format input_format,
285 unsigned int *fmt_type)
286 {
287 switch (input_format) {
288 case ATOMISP_INPUT_FORMAT_RGB_888:
289 *fmt_type = MIPI_FORMAT_2401_RGB888;
290 break;
291 case ATOMISP_INPUT_FORMAT_RGB_555:
292 *fmt_type = MIPI_FORMAT_2401_RGB555;
293 break;
294 case ATOMISP_INPUT_FORMAT_RGB_444:
295 *fmt_type = MIPI_FORMAT_2401_RGB444;
296 break;
297 case ATOMISP_INPUT_FORMAT_RGB_565:
298 *fmt_type = MIPI_FORMAT_2401_RGB565;
299 break;
300 case ATOMISP_INPUT_FORMAT_RGB_666:
301 *fmt_type = MIPI_FORMAT_2401_RGB666;
302 break;
303 case ATOMISP_INPUT_FORMAT_RAW_8:
304 *fmt_type = MIPI_FORMAT_2401_RAW8;
305 break;
306 case ATOMISP_INPUT_FORMAT_RAW_10:
307 *fmt_type = MIPI_FORMAT_2401_RAW10;
308 break;
309 case ATOMISP_INPUT_FORMAT_RAW_6:
310 *fmt_type = MIPI_FORMAT_2401_RAW6;
311 break;
312 case ATOMISP_INPUT_FORMAT_RAW_7:
313 *fmt_type = MIPI_FORMAT_2401_RAW7;
314 break;
315 case ATOMISP_INPUT_FORMAT_RAW_12:
316 *fmt_type = MIPI_FORMAT_2401_RAW12;
317 break;
318 case ATOMISP_INPUT_FORMAT_RAW_14:
319 *fmt_type = MIPI_FORMAT_2401_RAW14;
320 break;
321 case ATOMISP_INPUT_FORMAT_YUV420_8:
322 *fmt_type = MIPI_FORMAT_2401_YUV420_8;
323 break;
324 case ATOMISP_INPUT_FORMAT_YUV420_10:
325 *fmt_type = MIPI_FORMAT_2401_YUV420_10;
326 break;
327 case ATOMISP_INPUT_FORMAT_YUV422_8:
328 *fmt_type = MIPI_FORMAT_2401_YUV422_8;
329 break;
330 case ATOMISP_INPUT_FORMAT_YUV422_10:
331 *fmt_type = MIPI_FORMAT_2401_YUV422_10;
332 break;
333 case ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY:
334 *fmt_type = MIPI_FORMAT_2401_YUV420_8_LEGACY;
335 break;
336 case ATOMISP_INPUT_FORMAT_EMBEDDED:
337 *fmt_type = MIPI_FORMAT_2401_EMBEDDED;
338 break;
339 case ATOMISP_INPUT_FORMAT_USER_DEF1:
340 *fmt_type = MIPI_FORMAT_2401_CUSTOM0;
341 break;
342 case ATOMISP_INPUT_FORMAT_USER_DEF2:
343 *fmt_type = MIPI_FORMAT_2401_CUSTOM1;
344 break;
345 case ATOMISP_INPUT_FORMAT_USER_DEF3:
346 *fmt_type = MIPI_FORMAT_2401_CUSTOM2;
347 break;
348 case ATOMISP_INPUT_FORMAT_USER_DEF4:
349 *fmt_type = MIPI_FORMAT_2401_CUSTOM3;
350 break;
351 case ATOMISP_INPUT_FORMAT_USER_DEF5:
352 *fmt_type = MIPI_FORMAT_2401_CUSTOM4;
353 break;
354 case ATOMISP_INPUT_FORMAT_USER_DEF6:
355 *fmt_type = MIPI_FORMAT_2401_CUSTOM5;
356 break;
357 case ATOMISP_INPUT_FORMAT_USER_DEF7:
358 *fmt_type = MIPI_FORMAT_2401_CUSTOM6;
359 break;
360 case ATOMISP_INPUT_FORMAT_USER_DEF8:
361 *fmt_type = MIPI_FORMAT_2401_CUSTOM7;
362 break;
363
364 case ATOMISP_INPUT_FORMAT_YUV420_16:
365 case ATOMISP_INPUT_FORMAT_YUV422_16:
366 default:
367 return -EINVAL;
368 }
369 return 0;
370 }
371
ia_css_isys_convert_stream_format_to_mipi_format(enum atomisp_input_format input_format,mipi_predictor_t compression,unsigned int * fmt_type)372 int ia_css_isys_convert_stream_format_to_mipi_format(
373 enum atomisp_input_format input_format,
374 mipi_predictor_t compression,
375 unsigned int *fmt_type)
376 {
377 assert(fmt_type);
378 /*
379 * Custom (user defined) modes. Used for compressed
380 * MIPI transfers
381 *
382 * Checkpatch thinks the indent before "if" is suspect
383 * I think the only suspect part is the missing "else"
384 * because of the return.
385 */
386 if (compression != MIPI_PREDICTOR_NONE) {
387 switch (input_format) {
388 case ATOMISP_INPUT_FORMAT_RAW_6:
389 *fmt_type = 6;
390 break;
391 case ATOMISP_INPUT_FORMAT_RAW_7:
392 *fmt_type = 7;
393 break;
394 case ATOMISP_INPUT_FORMAT_RAW_8:
395 *fmt_type = 8;
396 break;
397 case ATOMISP_INPUT_FORMAT_RAW_10:
398 *fmt_type = 10;
399 break;
400 case ATOMISP_INPUT_FORMAT_RAW_12:
401 *fmt_type = 12;
402 break;
403 case ATOMISP_INPUT_FORMAT_RAW_14:
404 *fmt_type = 14;
405 break;
406 case ATOMISP_INPUT_FORMAT_RAW_16:
407 *fmt_type = 16;
408 break;
409 default:
410 return -EINVAL;
411 }
412 return 0;
413 }
414 /*
415 * This mapping comes from the Arasan CSS function spec
416 * (CSS_func_spec1.08_ahb_sep29_08.pdf).
417 *
418 * MW: For some reason the mapping is not 1-to-1
419 */
420 if (IS_ISP2401)
421 return ia_css_isys_2401_set_fmt_type(input_format, fmt_type);
422 else
423 return ia_css_isys_2400_set_fmt_type(input_format, fmt_type);
424 }
425
sh_css_csi2_compression_type_2_mipi_predictor(enum ia_css_csi2_compression_type type)426 static mipi_predictor_t sh_css_csi2_compression_type_2_mipi_predictor(
427 enum ia_css_csi2_compression_type type)
428 {
429 mipi_predictor_t predictor = MIPI_PREDICTOR_NONE;
430
431 switch (type) {
432 case IA_CSS_CSI2_COMPRESSION_TYPE_1:
433 predictor = MIPI_PREDICTOR_TYPE1 - 1;
434 break;
435 case IA_CSS_CSI2_COMPRESSION_TYPE_2:
436 predictor = MIPI_PREDICTOR_TYPE2 - 1;
437 break;
438 default:
439 break;
440 }
441 return predictor;
442 }
443
ia_css_isys_convert_compressed_format(struct ia_css_csi2_compression * comp,struct isp2401_input_system_cfg_s * cfg)444 int ia_css_isys_convert_compressed_format(
445 struct ia_css_csi2_compression *comp,
446 struct isp2401_input_system_cfg_s *cfg)
447 {
448 int err = 0;
449
450 assert(comp);
451 assert(cfg);
452
453 if (comp->type != IA_CSS_CSI2_COMPRESSION_TYPE_NONE) {
454 /* compression register bit slicing
455 4 bit for each user defined data type
456 3 bit indicate compression scheme
457 000 No compression
458 001 10-6-10
459 010 10-7-10
460 011 10-8-10
461 100 12-6-12
462 101 12-6-12
463 100 12-7-12
464 110 12-8-12
465 1 bit indicate predictor
466 */
467 if (comp->uncompressed_bits_per_pixel == UNCOMPRESSED_BITS_PER_PIXEL_10) {
468 switch (comp->compressed_bits_per_pixel) {
469 case COMPRESSED_BITS_PER_PIXEL_6:
470 cfg->csi_port_attr.comp_scheme = MIPI_COMPRESSOR_10_6_10;
471 break;
472 case COMPRESSED_BITS_PER_PIXEL_7:
473 cfg->csi_port_attr.comp_scheme = MIPI_COMPRESSOR_10_7_10;
474 break;
475 case COMPRESSED_BITS_PER_PIXEL_8:
476 cfg->csi_port_attr.comp_scheme = MIPI_COMPRESSOR_10_8_10;
477 break;
478 default:
479 err = -EINVAL;
480 }
481 } else if (comp->uncompressed_bits_per_pixel ==
482 UNCOMPRESSED_BITS_PER_PIXEL_12) {
483 switch (comp->compressed_bits_per_pixel) {
484 case COMPRESSED_BITS_PER_PIXEL_6:
485 cfg->csi_port_attr.comp_scheme = MIPI_COMPRESSOR_12_6_12;
486 break;
487 case COMPRESSED_BITS_PER_PIXEL_7:
488 cfg->csi_port_attr.comp_scheme = MIPI_COMPRESSOR_12_7_12;
489 break;
490 case COMPRESSED_BITS_PER_PIXEL_8:
491 cfg->csi_port_attr.comp_scheme = MIPI_COMPRESSOR_12_8_12;
492 break;
493 default:
494 err = -EINVAL;
495 }
496 } else
497 err = -EINVAL;
498 cfg->csi_port_attr.comp_predictor =
499 sh_css_csi2_compression_type_2_mipi_predictor(comp->type);
500 cfg->csi_port_attr.comp_enable = true;
501 } else /* No compression */
502 cfg->csi_port_attr.comp_enable = false;
503 return err;
504 }
505
ia_css_csi2_calculate_input_system_alignment(enum atomisp_input_format fmt_type)506 unsigned int ia_css_csi2_calculate_input_system_alignment(
507 enum atomisp_input_format fmt_type)
508 {
509 unsigned int memory_alignment_in_bytes = HIVE_ISP_DDR_WORD_BYTES;
510
511 switch (fmt_type) {
512 case ATOMISP_INPUT_FORMAT_RAW_6:
513 case ATOMISP_INPUT_FORMAT_RAW_7:
514 case ATOMISP_INPUT_FORMAT_RAW_8:
515 case ATOMISP_INPUT_FORMAT_RAW_10:
516 case ATOMISP_INPUT_FORMAT_RAW_12:
517 case ATOMISP_INPUT_FORMAT_RAW_14:
518 memory_alignment_in_bytes = 2 * ISP_VEC_NELEMS;
519 break;
520 case ATOMISP_INPUT_FORMAT_YUV420_8:
521 case ATOMISP_INPUT_FORMAT_YUV422_8:
522 case ATOMISP_INPUT_FORMAT_USER_DEF1:
523 case ATOMISP_INPUT_FORMAT_USER_DEF2:
524 case ATOMISP_INPUT_FORMAT_USER_DEF3:
525 case ATOMISP_INPUT_FORMAT_USER_DEF4:
526 case ATOMISP_INPUT_FORMAT_USER_DEF5:
527 case ATOMISP_INPUT_FORMAT_USER_DEF6:
528 case ATOMISP_INPUT_FORMAT_USER_DEF7:
529 case ATOMISP_INPUT_FORMAT_USER_DEF8:
530 /* Planar YUV formats need to have all planes aligned, this means
531 * double the alignment for the Y plane if the horizontal decimation is 2. */
532 memory_alignment_in_bytes = 2 * HIVE_ISP_DDR_WORD_BYTES;
533 break;
534 case ATOMISP_INPUT_FORMAT_EMBEDDED:
535 default:
536 memory_alignment_in_bytes = HIVE_ISP_DDR_WORD_BYTES;
537 break;
538 }
539 return memory_alignment_in_bytes;
540 }
541
542
543 static const mipi_lane_cfg_t MIPI_PORT_LANES[N_RX_MODE][N_MIPI_PORT_ID] = {
544 {MIPI_4LANE_CFG, MIPI_1LANE_CFG, MIPI_0LANE_CFG},
545 {MIPI_3LANE_CFG, MIPI_1LANE_CFG, MIPI_0LANE_CFG},
546 {MIPI_2LANE_CFG, MIPI_1LANE_CFG, MIPI_0LANE_CFG},
547 {MIPI_1LANE_CFG, MIPI_1LANE_CFG, MIPI_0LANE_CFG},
548 {MIPI_2LANE_CFG, MIPI_1LANE_CFG, MIPI_2LANE_CFG},
549 {MIPI_3LANE_CFG, MIPI_1LANE_CFG, MIPI_1LANE_CFG},
550 {MIPI_2LANE_CFG, MIPI_1LANE_CFG, MIPI_1LANE_CFG},
551 {MIPI_1LANE_CFG, MIPI_1LANE_CFG, MIPI_1LANE_CFG}
552 };
553
ia_css_isys_rx_configure(const rx_cfg_t * config,const enum ia_css_input_mode input_mode)554 void ia_css_isys_rx_configure(const rx_cfg_t *config,
555 const enum ia_css_input_mode input_mode)
556 {
557 bool any_port_enabled = false;
558 enum mipi_port_id port;
559
560 if ((!config)
561 || (config->mode >= N_RX_MODE)
562 || (config->port >= N_MIPI_PORT_ID)) {
563 assert(0);
564 return;
565 }
566 for (port = (enum mipi_port_id)0; port < N_MIPI_PORT_ID; port++) {
567 if (is_receiver_port_enabled(RX0_ID, port))
568 any_port_enabled = true;
569 }
570 /* AM: Check whether this is a problem with multiple
571 * streams. MS: This is the case. */
572
573 port = config->port;
574 receiver_port_enable(RX0_ID, port, false);
575
576 port = config->port;
577
578 /* AM: Check whether this is a problem with multiple streams. */
579 if (MIPI_PORT_LANES[config->mode][port] != MIPI_0LANE_CFG) {
580 receiver_port_reg_store(RX0_ID, port,
581 _HRT_CSS_RECEIVER_FUNC_PROG_REG_IDX,
582 config->timeout);
583 receiver_port_reg_store(RX0_ID, port,
584 _HRT_CSS_RECEIVER_2400_INIT_COUNT_REG_IDX,
585 config->initcount);
586 receiver_port_reg_store(RX0_ID, port,
587 _HRT_CSS_RECEIVER_2400_SYNC_COUNT_REG_IDX,
588 config->synccount);
589 receiver_port_reg_store(RX0_ID, port,
590 _HRT_CSS_RECEIVER_2400_RX_COUNT_REG_IDX,
591 config->rxcount);
592
593 if (input_mode != IA_CSS_INPUT_MODE_BUFFERED_SENSOR) {
594 /* MW: A bit of a hack, straight wiring of the capture
595 * units,assuming they are linearly enumerated. */
596 input_system_sub_system_reg_store(INPUT_SYSTEM0_ID,
597 GPREGS_UNIT0_ID,
598 HIVE_ISYS_GPREG_MULTICAST_A_IDX
599 + (unsigned int)port,
600 INPUT_SYSTEM_CSI_BACKEND);
601 /* MW: Like the integration test example we overwite,
602 * the GPREG_MUX register */
603 input_system_sub_system_reg_store(INPUT_SYSTEM0_ID,
604 GPREGS_UNIT0_ID,
605 HIVE_ISYS_GPREG_MUX_IDX,
606 (input_system_multiplex_t)port);
607 } else {
608 /*
609 * AM: A bit of a hack, wiring the input system.
610 */
611 input_system_sub_system_reg_store(INPUT_SYSTEM0_ID,
612 GPREGS_UNIT0_ID,
613 HIVE_ISYS_GPREG_MULTICAST_A_IDX
614 + (unsigned int)port,
615 INPUT_SYSTEM_INPUT_BUFFER);
616 input_system_sub_system_reg_store(INPUT_SYSTEM0_ID,
617 GPREGS_UNIT0_ID,
618 HIVE_ISYS_GPREG_MUX_IDX,
619 INPUT_SYSTEM_ACQUISITION_UNIT);
620 }
621 }
622 /*
623 * The 2ppc is shared for all ports, so we cannot
624 * disable->configure->enable individual ports
625 */
626 /* AM: Check whether this is a problem with multiple streams. */
627 /* MS: 2ppc should be a property per binary and should be
628 * enabled/disabled per binary.
629 * Currently it is implemented as a system wide setting due
630 * to effort and risks. */
631 if (!any_port_enabled) {
632 receiver_reg_store(RX0_ID,
633 _HRT_CSS_RECEIVER_TWO_PIXEL_EN_REG_IDX,
634 config->is_two_ppc);
635 receiver_reg_store(RX0_ID, _HRT_CSS_RECEIVER_BE_TWO_PPC_REG_IDX,
636 config->is_two_ppc);
637 }
638 receiver_port_enable(RX0_ID, port, true);
639 /* TODO: JB: need to add the beneath used define to mizuchi */
640 /* sh_css_sw_hive_isp_css_2400_system_20121224_0125\css
641 * \hrt\input_system_defs.h
642 * #define INPUT_SYSTEM_CSI_RECEIVER_SELECT_BACKENG 0X207
643 */
644 /* TODO: need better name for define
645 * input_system_reg_store(INPUT_SYSTEM0_ID,
646 * INPUT_SYSTEM_CSI_RECEIVER_SELECT_BACKENG, 1);
647 */
648 input_system_reg_store(INPUT_SYSTEM0_ID, 0x207, 1);
649
650 return;
651 }
652
ia_css_isys_rx_disable(void)653 void ia_css_isys_rx_disable(void)
654 {
655 enum mipi_port_id port;
656
657 for (port = (enum mipi_port_id)0; port < N_MIPI_PORT_ID; port++) {
658 receiver_port_reg_store(RX0_ID, port,
659 _HRT_CSS_RECEIVER_DEVICE_READY_REG_IDX,
660 false);
661 }
662 return;
663 }
664