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)
ia_css_isys_rx_enable_all_interrupts(enum mipi_port_id port)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  * */
ia_css_isys_port_to_mipi_port(enum mipi_port_id api_port)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 
ia_css_isys_rx_get_interrupt_reg(enum mipi_port_id port)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 
ia_css_rx_get_irq_info(unsigned int * irq_infos)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 
ia_css_rx_port_get_irq_info(enum mipi_port_id api_port,unsigned int * irq_infos)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 
ia_css_isys_rx_get_irq_info(enum mipi_port_id port,unsigned int * irq_infos)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 */
ia_css_isys_rx_translate_irq_infos(unsigned int bits)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 
ia_css_rx_clear_irq_info(unsigned int irq_infos)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 
ia_css_rx_port_clear_irq_info(enum mipi_port_id api_port,unsigned int irq_infos)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 
ia_css_isys_rx_clear_irq_info(enum mipi_port_id port,unsigned int irq_infos)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 
ia_css_isys_convert_stream_format_to_mipi_format(enum atomisp_input_format input_format,mipi_predictor_t compression,unsigned int * fmt_type)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)
sh_css_csi2_compression_type_2_mipi_predictor(enum ia_css_csi2_compression_type type)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 		break;
372 	default:
373 		break;
374 	}
375 	return predictor;
376 }
377 
ia_css_isys_convert_compressed_format(struct ia_css_csi2_compression * comp,struct isp2401_input_system_cfg_s * cfg)378 int ia_css_isys_convert_compressed_format(
379     struct ia_css_csi2_compression *comp,
380     struct isp2401_input_system_cfg_s *cfg)
381 {
382 	int err = 0;
383 
384 	assert(comp);
385 	assert(cfg);
386 
387 	if (comp->type != IA_CSS_CSI2_COMPRESSION_TYPE_NONE) {
388 		/* compression register bit slicing
389 		4 bit for each user defined data type
390 			3 bit indicate compression scheme
391 				000 No compression
392 				001 10-6-10
393 				010 10-7-10
394 				011 10-8-10
395 				100 12-6-12
396 				101 12-6-12
397 				100 12-7-12
398 				110 12-8-12
399 			1 bit indicate predictor
400 		*/
401 		if (comp->uncompressed_bits_per_pixel == UNCOMPRESSED_BITS_PER_PIXEL_10) {
402 			switch (comp->compressed_bits_per_pixel) {
403 			case COMPRESSED_BITS_PER_PIXEL_6:
404 				cfg->csi_port_attr.comp_scheme = MIPI_COMPRESSOR_10_6_10;
405 				break;
406 			case COMPRESSED_BITS_PER_PIXEL_7:
407 				cfg->csi_port_attr.comp_scheme = MIPI_COMPRESSOR_10_7_10;
408 				break;
409 			case COMPRESSED_BITS_PER_PIXEL_8:
410 				cfg->csi_port_attr.comp_scheme = MIPI_COMPRESSOR_10_8_10;
411 				break;
412 			default:
413 				err = -EINVAL;
414 			}
415 		} else if (comp->uncompressed_bits_per_pixel ==
416 			   UNCOMPRESSED_BITS_PER_PIXEL_12) {
417 			switch (comp->compressed_bits_per_pixel) {
418 			case COMPRESSED_BITS_PER_PIXEL_6:
419 				cfg->csi_port_attr.comp_scheme = MIPI_COMPRESSOR_12_6_12;
420 				break;
421 			case COMPRESSED_BITS_PER_PIXEL_7:
422 				cfg->csi_port_attr.comp_scheme = MIPI_COMPRESSOR_12_7_12;
423 				break;
424 			case COMPRESSED_BITS_PER_PIXEL_8:
425 				cfg->csi_port_attr.comp_scheme = MIPI_COMPRESSOR_12_8_12;
426 				break;
427 			default:
428 				err = -EINVAL;
429 			}
430 		} else
431 			err = -EINVAL;
432 		cfg->csi_port_attr.comp_predictor =
433 		    sh_css_csi2_compression_type_2_mipi_predictor(comp->type);
434 		cfg->csi_port_attr.comp_enable = true;
435 	} else /* No compression */
436 		cfg->csi_port_attr.comp_enable = false;
437 	return err;
438 }
439 
ia_css_csi2_calculate_input_system_alignment(enum atomisp_input_format fmt_type)440 unsigned int ia_css_csi2_calculate_input_system_alignment(
441     enum atomisp_input_format fmt_type)
442 {
443 	unsigned int memory_alignment_in_bytes = HIVE_ISP_DDR_WORD_BYTES;
444 
445 	switch (fmt_type) {
446 	case ATOMISP_INPUT_FORMAT_RAW_6:
447 	case ATOMISP_INPUT_FORMAT_RAW_7:
448 	case ATOMISP_INPUT_FORMAT_RAW_8:
449 	case ATOMISP_INPUT_FORMAT_RAW_10:
450 	case ATOMISP_INPUT_FORMAT_RAW_12:
451 	case ATOMISP_INPUT_FORMAT_RAW_14:
452 		memory_alignment_in_bytes = 2 * ISP_VEC_NELEMS;
453 		break;
454 	case ATOMISP_INPUT_FORMAT_YUV420_8:
455 	case ATOMISP_INPUT_FORMAT_YUV422_8:
456 	case ATOMISP_INPUT_FORMAT_USER_DEF1:
457 	case ATOMISP_INPUT_FORMAT_USER_DEF2:
458 	case ATOMISP_INPUT_FORMAT_USER_DEF3:
459 	case ATOMISP_INPUT_FORMAT_USER_DEF4:
460 	case ATOMISP_INPUT_FORMAT_USER_DEF5:
461 	case ATOMISP_INPUT_FORMAT_USER_DEF6:
462 	case ATOMISP_INPUT_FORMAT_USER_DEF7:
463 	case ATOMISP_INPUT_FORMAT_USER_DEF8:
464 		/* Planar YUV formats need to have all planes aligned, this means
465 		 * double the alignment for the Y plane if the horizontal decimation is 2. */
466 		memory_alignment_in_bytes = 2 * HIVE_ISP_DDR_WORD_BYTES;
467 		break;
468 	case ATOMISP_INPUT_FORMAT_EMBEDDED:
469 	default:
470 		memory_alignment_in_bytes = HIVE_ISP_DDR_WORD_BYTES;
471 		break;
472 	}
473 	return memory_alignment_in_bytes;
474 }
475 
476 #endif
477 
478 #if !defined(ISP2401)
479 static const mipi_lane_cfg_t MIPI_PORT_LANES[N_RX_MODE][N_MIPI_PORT_ID] = {
480 	{MIPI_4LANE_CFG, MIPI_1LANE_CFG, MIPI_0LANE_CFG},
481 	{MIPI_3LANE_CFG, MIPI_1LANE_CFG, MIPI_0LANE_CFG},
482 	{MIPI_2LANE_CFG, MIPI_1LANE_CFG, MIPI_0LANE_CFG},
483 	{MIPI_1LANE_CFG, MIPI_1LANE_CFG, MIPI_0LANE_CFG},
484 	{MIPI_2LANE_CFG, MIPI_1LANE_CFG, MIPI_2LANE_CFG},
485 	{MIPI_3LANE_CFG, MIPI_1LANE_CFG, MIPI_1LANE_CFG},
486 	{MIPI_2LANE_CFG, MIPI_1LANE_CFG, MIPI_1LANE_CFG},
487 	{MIPI_1LANE_CFG, MIPI_1LANE_CFG, MIPI_1LANE_CFG}
488 };
489 
ia_css_isys_rx_configure(const rx_cfg_t * config,const enum ia_css_input_mode input_mode)490 void ia_css_isys_rx_configure(const rx_cfg_t *config,
491 			      const enum ia_css_input_mode input_mode)
492 {
493 	bool any_port_enabled = false;
494 	enum mipi_port_id port;
495 
496 	if ((!config)
497 	    || (config->mode >= N_RX_MODE)
498 	    || (config->port >= N_MIPI_PORT_ID)) {
499 		assert(0);
500 		return;
501 	}
502 	for (port = (enum mipi_port_id)0; port < N_MIPI_PORT_ID; port++) {
503 		if (is_receiver_port_enabled(RX0_ID, port))
504 			any_port_enabled = true;
505 	}
506 	/* AM: Check whether this is a problem with multiple
507 	 * streams. MS: This is the case. */
508 
509 	port = config->port;
510 	receiver_port_enable(RX0_ID, port, false);
511 
512 	port = config->port;
513 
514 	/* AM: Check whether this is a problem with multiple streams. */
515 	if (MIPI_PORT_LANES[config->mode][port] != MIPI_0LANE_CFG) {
516 		receiver_port_reg_store(RX0_ID, port,
517 					_HRT_CSS_RECEIVER_FUNC_PROG_REG_IDX,
518 					config->timeout);
519 		receiver_port_reg_store(RX0_ID, port,
520 					_HRT_CSS_RECEIVER_2400_INIT_COUNT_REG_IDX,
521 					config->initcount);
522 		receiver_port_reg_store(RX0_ID, port,
523 					_HRT_CSS_RECEIVER_2400_SYNC_COUNT_REG_IDX,
524 					config->synccount);
525 		receiver_port_reg_store(RX0_ID, port,
526 					_HRT_CSS_RECEIVER_2400_RX_COUNT_REG_IDX,
527 					config->rxcount);
528 
529 		if (input_mode != IA_CSS_INPUT_MODE_BUFFERED_SENSOR) {
530 			/* MW: A bit of a hack, straight wiring of the capture
531 			 * units,assuming they are linearly enumerated. */
532 			input_system_sub_system_reg_store(INPUT_SYSTEM0_ID,
533 							  GPREGS_UNIT0_ID,
534 							  HIVE_ISYS_GPREG_MULTICAST_A_IDX
535 							  + (unsigned int)port,
536 							  INPUT_SYSTEM_CSI_BACKEND);
537 			/* MW: Like the integration test example we overwite,
538 			 * the GPREG_MUX register */
539 			input_system_sub_system_reg_store(INPUT_SYSTEM0_ID,
540 							  GPREGS_UNIT0_ID,
541 							  HIVE_ISYS_GPREG_MUX_IDX,
542 							  (input_system_multiplex_t)port);
543 		} else {
544 			/*
545 			 * AM: A bit of a hack, wiring the input system.
546 			 */
547 			input_system_sub_system_reg_store(INPUT_SYSTEM0_ID,
548 							  GPREGS_UNIT0_ID,
549 							  HIVE_ISYS_GPREG_MULTICAST_A_IDX
550 							  + (unsigned int)port,
551 							  INPUT_SYSTEM_INPUT_BUFFER);
552 			input_system_sub_system_reg_store(INPUT_SYSTEM0_ID,
553 							  GPREGS_UNIT0_ID,
554 							  HIVE_ISYS_GPREG_MUX_IDX,
555 							  INPUT_SYSTEM_ACQUISITION_UNIT);
556 		}
557 	}
558 	/*
559 	 * The 2ppc is shared for all ports, so we cannot
560 	 * disable->configure->enable individual ports
561 	 */
562 	/* AM: Check whether this is a problem with multiple streams. */
563 	/* MS: 2ppc should be a property per binary and should be
564 	 * enabled/disabled per binary.
565 	 * Currently it is implemented as a system wide setting due
566 	 * to effort and risks. */
567 	if (!any_port_enabled) {
568 		receiver_reg_store(RX0_ID,
569 				   _HRT_CSS_RECEIVER_TWO_PIXEL_EN_REG_IDX,
570 				   config->is_two_ppc);
571 		receiver_reg_store(RX0_ID, _HRT_CSS_RECEIVER_BE_TWO_PPC_REG_IDX,
572 				   config->is_two_ppc);
573 	}
574 	receiver_port_enable(RX0_ID, port, true);
575 	/* TODO: JB: need to add the beneath used define to mizuchi */
576 	/* sh_css_sw_hive_isp_css_2400_system_20121224_0125\css
577 	 *                      \hrt\input_system_defs.h
578 	 * #define INPUT_SYSTEM_CSI_RECEIVER_SELECT_BACKENG 0X207
579 	 */
580 	/* TODO: need better name for define
581 	 * input_system_reg_store(INPUT_SYSTEM0_ID,
582 	 *                INPUT_SYSTEM_CSI_RECEIVER_SELECT_BACKENG, 1);
583 	 */
584 	input_system_reg_store(INPUT_SYSTEM0_ID, 0x207, 1);
585 
586 	return;
587 }
588 
ia_css_isys_rx_disable(void)589 void ia_css_isys_rx_disable(void)
590 {
591 	enum mipi_port_id port;
592 
593 	for (port = (enum mipi_port_id)0; port < N_MIPI_PORT_ID; port++) {
594 		receiver_port_reg_store(RX0_ID, port,
595 					_HRT_CSS_RECEIVER_DEVICE_READY_REG_IDX,
596 					false);
597 	}
598 	return;
599 }
600 #endif /* if !defined(ISP2401) */
601