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