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