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