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