1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Support for Intel Camera Imaging ISP subsystem.
4  * Copyright (c) 2010-015, 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 #include "system_global.h"
17 
18 #ifndef ISP2401
19 
20 #include "input_system.h"
21 #include <type_support.h>
22 #include "gp_device.h"
23 
24 #include "assert_support.h"
25 
26 #ifndef __INLINE_INPUT_SYSTEM__
27 #include "input_system_private.h"
28 #endif /* __INLINE_INPUT_SYSTEM__ */
29 
30 #define ZERO (0x0)
31 #define ONE  (1U)
32 
33 static const isp2400_ib_buffer_t   IB_BUFFER_NULL = {0, 0, 0 };
34 
35 static input_system_err_t input_system_configure_channel(
36     const channel_cfg_t		channel);
37 
38 static input_system_err_t input_system_configure_channel_sensor(
39     const channel_cfg_t		channel);
40 
41 static input_system_err_t input_buffer_configuration(void);
42 
43 static input_system_err_t configuration_to_registers(void);
44 
45 static void receiver_rst(const rx_ID_t ID);
46 static void input_system_network_rst(const input_system_ID_t ID);
47 
48 static void capture_unit_configure(
49     const input_system_ID_t			ID,
50     const sub_system_ID_t			sub_id,
51     const isp2400_ib_buffer_t *const cfg);
52 
53 static void acquisition_unit_configure(
54     const input_system_ID_t			ID,
55     const sub_system_ID_t			sub_id,
56     const isp2400_ib_buffer_t *const cfg);
57 
58 static void ctrl_unit_configure(
59     const input_system_ID_t			ID,
60     const sub_system_ID_t			sub_id,
61     const ctrl_unit_cfg_t *const cfg);
62 
63 static void input_system_network_configure(
64     const input_system_ID_t			ID,
65     const input_system_network_cfg_t *const cfg);
66 
67 // MW: CSI is previously named as "rx" short for "receiver"
68 static input_system_err_t set_csi_cfg(
69     csi_cfg_t *const lhs,
70     const csi_cfg_t *const rhs,
71     input_system_config_flags_t *const flags);
72 
73 static input_system_err_t set_source_type(
74     input_system_source_t *const lhs,
75     const input_system_source_t				rhs,
76     input_system_config_flags_t *const flags);
77 
78 static input_system_err_t input_system_multiplexer_cfg(
79     input_system_multiplex_t *const lhs,
80     const input_system_multiplex_t			rhs,
81     input_system_config_flags_t *const flags);
82 
83 static inline void capture_unit_get_state(
84     const input_system_ID_t			ID,
85     const sub_system_ID_t			sub_id,
86     capture_unit_state_t			*state);
87 
88 static inline void acquisition_unit_get_state(
89     const input_system_ID_t			ID,
90     const sub_system_ID_t			sub_id,
91     acquisition_unit_state_t		*state);
92 
93 static inline void ctrl_unit_get_state(
94     const input_system_ID_t			ID,
95     const sub_system_ID_t			sub_id,
96     ctrl_unit_state_t				*state);
97 
98 static inline void mipi_port_get_state(
99     const rx_ID_t					ID,
100     const enum mipi_port_id			port_ID,
101     mipi_port_state_t				*state);
102 
103 static inline void rx_channel_get_state(
104     const rx_ID_t					ID,
105     const unsigned int				ch_id,
106     rx_channel_state_t				*state);
107 
108 static void gp_device_rst(const gp_device_ID_t		ID);
109 
110 static void input_selector_cfg_for_sensor(const gp_device_ID_t	ID);
111 
112 static void input_switch_rst(const gp_device_ID_t	ID);
113 
114 static void input_switch_cfg(
115     const gp_device_ID_t				ID,
116     const input_switch_cfg_t *const cfg
117 );
118 
119 void input_system_get_state(
120     const input_system_ID_t			ID,
121     input_system_state_t			*state)
122 {
123 	sub_system_ID_t	sub_id;
124 
125 	assert(ID < N_INPUT_SYSTEM_ID);
126 	assert(state);
127 
128 	state->str_multicastA_sel = input_system_sub_system_reg_load(ID,
129 				    GPREGS_UNIT0_ID,
130 				    HIVE_ISYS_GPREG_MULTICAST_A_IDX);
131 	state->str_multicastB_sel = input_system_sub_system_reg_load(ID,
132 				    GPREGS_UNIT0_ID,
133 				    HIVE_ISYS_GPREG_MULTICAST_B_IDX);
134 	state->str_multicastC_sel = input_system_sub_system_reg_load(ID,
135 				    GPREGS_UNIT0_ID,
136 				    HIVE_ISYS_GPREG_MULTICAST_C_IDX);
137 	state->str_mux_sel = input_system_sub_system_reg_load(ID,
138 			     GPREGS_UNIT0_ID,
139 			     HIVE_ISYS_GPREG_MUX_IDX);
140 	state->str_mon_status = input_system_sub_system_reg_load(ID,
141 				GPREGS_UNIT0_ID,
142 				HIVE_ISYS_GPREG_STRMON_STAT_IDX);
143 	state->str_mon_irq_cond = input_system_sub_system_reg_load(ID,
144 				  GPREGS_UNIT0_ID,
145 				  HIVE_ISYS_GPREG_STRMON_COND_IDX);
146 	state->str_mon_irq_en = input_system_sub_system_reg_load(ID,
147 				GPREGS_UNIT0_ID,
148 				HIVE_ISYS_GPREG_STRMON_IRQ_EN_IDX);
149 	state->isys_srst = input_system_sub_system_reg_load(ID,
150 			   GPREGS_UNIT0_ID,
151 			   HIVE_ISYS_GPREG_SRST_IDX);
152 	state->isys_slv_reg_srst = input_system_sub_system_reg_load(ID,
153 				   GPREGS_UNIT0_ID,
154 				   HIVE_ISYS_GPREG_SLV_REG_SRST_IDX);
155 	state->str_deint_portA_cnt = input_system_sub_system_reg_load(ID,
156 				     GPREGS_UNIT0_ID,
157 				     HIVE_ISYS_GPREG_REG_PORT_A_IDX);
158 	state->str_deint_portB_cnt = input_system_sub_system_reg_load(ID,
159 				     GPREGS_UNIT0_ID,
160 				     HIVE_ISYS_GPREG_REG_PORT_B_IDX);
161 
162 	for (sub_id = CAPTURE_UNIT0_ID; sub_id < CAPTURE_UNIT0_ID + N_CAPTURE_UNIT_ID;
163 	     sub_id++) {
164 		capture_unit_get_state(ID, sub_id,
165 				       &state->capture_unit[sub_id - CAPTURE_UNIT0_ID]);
166 	}
167 	for (sub_id = ACQUISITION_UNIT0_ID;
168 	     sub_id < ACQUISITION_UNIT0_ID + N_ACQUISITION_UNIT_ID; sub_id++) {
169 		acquisition_unit_get_state(ID, sub_id,
170 					   &state->acquisition_unit[sub_id - ACQUISITION_UNIT0_ID]);
171 	}
172 	for (sub_id = CTRL_UNIT0_ID; sub_id < CTRL_UNIT0_ID + N_CTRL_UNIT_ID;
173 	     sub_id++) {
174 		ctrl_unit_get_state(ID, sub_id,
175 				    &state->ctrl_unit_state[sub_id - CTRL_UNIT0_ID]);
176 	}
177 }
178 
179 void receiver_get_state(
180     const rx_ID_t				ID,
181     receiver_state_t			*state)
182 {
183 	enum mipi_port_id	port_id;
184 	unsigned int	ch_id;
185 
186 	assert(ID < N_RX_ID);
187 	assert(state);
188 
189 	state->fs_to_ls_delay = (uint8_t)receiver_reg_load(ID,
190 				_HRT_CSS_RECEIVER_FS_TO_LS_DELAY_REG_IDX);
191 	state->ls_to_data_delay = (uint8_t)receiver_reg_load(ID,
192 				  _HRT_CSS_RECEIVER_LS_TO_DATA_DELAY_REG_IDX);
193 	state->data_to_le_delay = (uint8_t)receiver_reg_load(ID,
194 				  _HRT_CSS_RECEIVER_DATA_TO_LE_DELAY_REG_IDX);
195 	state->le_to_fe_delay = (uint8_t)receiver_reg_load(ID,
196 				_HRT_CSS_RECEIVER_LE_TO_FE_DELAY_REG_IDX);
197 	state->fe_to_fs_delay = (uint8_t)receiver_reg_load(ID,
198 				_HRT_CSS_RECEIVER_FE_TO_FS_DELAY_REG_IDX);
199 	state->le_to_fs_delay = (uint8_t)receiver_reg_load(ID,
200 				_HRT_CSS_RECEIVER_LE_TO_LS_DELAY_REG_IDX);
201 	state->is_two_ppc = (bool)receiver_reg_load(ID,
202 			    _HRT_CSS_RECEIVER_TWO_PIXEL_EN_REG_IDX);
203 	state->backend_rst = receiver_reg_load(ID,
204 					       _HRT_CSS_RECEIVER_BACKEND_RST_REG_IDX);
205 	state->raw18 = (uint16_t)receiver_reg_load(ID,
206 		       _HRT_CSS_RECEIVER_RAW18_REG_IDX);
207 	state->force_raw8 = (bool)receiver_reg_load(ID,
208 			    _HRT_CSS_RECEIVER_FORCE_RAW8_REG_IDX);
209 	state->raw16 = (uint16_t)receiver_reg_load(ID,
210 		       _HRT_CSS_RECEIVER_RAW16_REG_IDX);
211 
212 	for (port_id = (enum mipi_port_id)0; port_id < N_MIPI_PORT_ID; port_id++) {
213 		mipi_port_get_state(ID, port_id,
214 				    &state->mipi_port_state[port_id]);
215 	}
216 	for (ch_id = 0U; ch_id < N_RX_CHANNEL_ID; ch_id++) {
217 		rx_channel_get_state(ID, ch_id,
218 				     &state->rx_channel_state[ch_id]);
219 	}
220 
221 	state->be_gsp_acc_ovl = receiver_reg_load(ID,
222 				_HRT_CSS_RECEIVER_BE_GSP_ACC_OVL_REG_IDX);
223 	state->be_srst = receiver_reg_load(ID,
224 					   _HRT_CSS_RECEIVER_BE_SRST_REG_IDX);
225 	state->be_is_two_ppc = receiver_reg_load(ID,
226 			       _HRT_CSS_RECEIVER_BE_TWO_PPC_REG_IDX);
227 	state->be_comp_format0 = receiver_reg_load(ID,
228 				 _HRT_CSS_RECEIVER_BE_COMP_FORMAT_REG0_IDX);
229 	state->be_comp_format1 = receiver_reg_load(ID,
230 				 _HRT_CSS_RECEIVER_BE_COMP_FORMAT_REG1_IDX);
231 	state->be_comp_format2 = receiver_reg_load(ID,
232 				 _HRT_CSS_RECEIVER_BE_COMP_FORMAT_REG2_IDX);
233 	state->be_comp_format3 = receiver_reg_load(ID,
234 				 _HRT_CSS_RECEIVER_BE_COMP_FORMAT_REG3_IDX);
235 	state->be_sel = receiver_reg_load(ID,
236 					  _HRT_CSS_RECEIVER_BE_SEL_REG_IDX);
237 	state->be_raw16_config = receiver_reg_load(ID,
238 				 _HRT_CSS_RECEIVER_BE_RAW16_CONFIG_REG_IDX);
239 	state->be_raw18_config = receiver_reg_load(ID,
240 				 _HRT_CSS_RECEIVER_BE_RAW18_CONFIG_REG_IDX);
241 	state->be_force_raw8 = receiver_reg_load(ID,
242 			       _HRT_CSS_RECEIVER_BE_FORCE_RAW8_REG_IDX);
243 	state->be_irq_status = receiver_reg_load(ID,
244 			       _HRT_CSS_RECEIVER_BE_IRQ_STATUS_REG_IDX);
245 	state->be_irq_clear = receiver_reg_load(ID,
246 						_HRT_CSS_RECEIVER_BE_IRQ_CLEAR_REG_IDX);
247 }
248 
249 bool is_mipi_format_yuv420(
250     const mipi_format_t			mipi_format)
251 {
252 	bool	is_yuv420 = (
253 				(mipi_format == MIPI_FORMAT_YUV420_8) ||
254 				(mipi_format == MIPI_FORMAT_YUV420_10) ||
255 				(mipi_format == MIPI_FORMAT_YUV420_8_SHIFT) ||
256 				(mipi_format == MIPI_FORMAT_YUV420_10_SHIFT));
257 	/* MIPI_FORMAT_YUV420_8_LEGACY is not YUV420 */
258 
259 	return is_yuv420;
260 }
261 
262 void receiver_set_compression(
263     const rx_ID_t			ID,
264     const unsigned int		cfg_ID,
265     const mipi_compressor_t		comp,
266     const mipi_predictor_t		pred)
267 {
268 	const unsigned int		field_id = cfg_ID % N_MIPI_FORMAT_CUSTOM;
269 	const unsigned int		ch_id = cfg_ID / N_MIPI_FORMAT_CUSTOM;
270 	hrt_data			val;
271 	hrt_address			addr = 0;
272 	hrt_data			reg;
273 
274 	assert(ID < N_RX_ID);
275 	assert(cfg_ID < N_MIPI_COMPRESSOR_CONTEXT);
276 	assert(field_id < N_MIPI_FORMAT_CUSTOM);
277 	assert(ch_id < N_RX_CHANNEL_ID);
278 	assert(comp < N_MIPI_COMPRESSOR_METHODS);
279 	assert(pred < N_MIPI_PREDICTOR_TYPES);
280 
281 	val = (((uint8_t)pred) << 3) | comp;
282 
283 	switch (ch_id) {
284 	case 0:
285 		addr = ((field_id < 6) ? _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC0_REG0_IDX :
286 			_HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC0_REG1_IDX);
287 		break;
288 	case 1:
289 		addr = ((field_id < 6) ? _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC1_REG0_IDX :
290 			_HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC1_REG1_IDX);
291 		break;
292 	case 2:
293 		addr = ((field_id < 6) ? _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC2_REG0_IDX :
294 			_HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC2_REG1_IDX);
295 		break;
296 	case 3:
297 		addr = ((field_id < 6) ? _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC3_REG0_IDX :
298 			_HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC3_REG1_IDX);
299 		break;
300 	default:
301 		/* should not happen */
302 		assert(false);
303 		return;
304 	}
305 
306 	reg = ((field_id < 6) ? (val << (field_id * 5)) : (val << ((
307 		    field_id - 6) * 5)));
308 	receiver_reg_store(ID, addr, reg);
309 }
310 
311 void receiver_port_enable(
312     const rx_ID_t			ID,
313     const enum mipi_port_id		port_ID,
314     const bool			cnd)
315 {
316 	hrt_data	reg = receiver_port_reg_load(ID, port_ID,
317 			  _HRT_CSS_RECEIVER_DEVICE_READY_REG_IDX);
318 
319 	if (cnd) {
320 		reg |= 0x01;
321 	} else {
322 		reg &= ~0x01;
323 	}
324 
325 	receiver_port_reg_store(ID, port_ID,
326 				_HRT_CSS_RECEIVER_DEVICE_READY_REG_IDX, reg);
327 }
328 
329 bool is_receiver_port_enabled(
330     const rx_ID_t			ID,
331     const enum mipi_port_id		port_ID)
332 {
333 	hrt_data	reg = receiver_port_reg_load(ID, port_ID,
334 			  _HRT_CSS_RECEIVER_DEVICE_READY_REG_IDX);
335 	return ((reg & 0x01) != 0);
336 }
337 
338 void receiver_irq_enable(
339     const rx_ID_t			ID,
340     const enum mipi_port_id		port_ID,
341     const rx_irq_info_t		irq_info)
342 {
343 	receiver_port_reg_store(ID,
344 				port_ID, _HRT_CSS_RECEIVER_IRQ_ENABLE_REG_IDX, irq_info);
345 }
346 
347 rx_irq_info_t receiver_get_irq_info(
348     const rx_ID_t			ID,
349     const enum mipi_port_id		port_ID)
350 {
351 	return receiver_port_reg_load(ID,
352 				      port_ID, _HRT_CSS_RECEIVER_IRQ_STATUS_REG_IDX);
353 }
354 
355 void receiver_irq_clear(
356     const rx_ID_t			ID,
357     const enum mipi_port_id		port_ID,
358     const rx_irq_info_t		irq_info)
359 {
360 	receiver_port_reg_store(ID,
361 				port_ID, _HRT_CSS_RECEIVER_IRQ_STATUS_REG_IDX, irq_info);
362 }
363 
364 static inline void capture_unit_get_state(
365     const input_system_ID_t			ID,
366     const sub_system_ID_t			sub_id,
367     capture_unit_state_t			*state)
368 {
369 	assert(/*(sub_id >= CAPTURE_UNIT0_ID) &&*/ (sub_id <= CAPTURE_UNIT2_ID));
370 	assert(state);
371 
372 	state->StartMode = input_system_sub_system_reg_load(ID,
373 			   sub_id,
374 			   CAPT_START_MODE_REG_ID);
375 	state->Start_Addr = input_system_sub_system_reg_load(ID,
376 			    sub_id,
377 			    CAPT_START_ADDR_REG_ID);
378 	state->Mem_Region_Size = input_system_sub_system_reg_load(ID,
379 				 sub_id,
380 				 CAPT_MEM_REGION_SIZE_REG_ID);
381 	state->Num_Mem_Regions = input_system_sub_system_reg_load(ID,
382 				 sub_id,
383 				 CAPT_NUM_MEM_REGIONS_REG_ID);
384 //	AM: Illegal read from following registers.
385 	/*	state->Init = input_system_sub_system_reg_load(ID,
386 			sub_id,
387 			CAPT_INIT_REG_ID);
388 		state->Start = input_system_sub_system_reg_load(ID,
389 			sub_id,
390 			CAPT_START_REG_ID);
391 		state->Stop = input_system_sub_system_reg_load(ID,
392 			sub_id,
393 			CAPT_STOP_REG_ID);
394 	*/
395 	state->Packet_Length = input_system_sub_system_reg_load(ID,
396 			       sub_id,
397 			       CAPT_PACKET_LENGTH_REG_ID);
398 	state->Received_Length = input_system_sub_system_reg_load(ID,
399 				 sub_id,
400 				 CAPT_RECEIVED_LENGTH_REG_ID);
401 	state->Received_Short_Packets = input_system_sub_system_reg_load(ID,
402 					sub_id,
403 					CAPT_RECEIVED_SHORT_PACKETS_REG_ID);
404 	state->Received_Long_Packets = input_system_sub_system_reg_load(ID,
405 				       sub_id,
406 				       CAPT_RECEIVED_LONG_PACKETS_REG_ID);
407 	state->Last_Command = input_system_sub_system_reg_load(ID,
408 			      sub_id,
409 			      CAPT_LAST_COMMAND_REG_ID);
410 	state->Next_Command = input_system_sub_system_reg_load(ID,
411 			      sub_id,
412 			      CAPT_NEXT_COMMAND_REG_ID);
413 	state->Last_Acknowledge = input_system_sub_system_reg_load(ID,
414 				  sub_id,
415 				  CAPT_LAST_ACKNOWLEDGE_REG_ID);
416 	state->Next_Acknowledge = input_system_sub_system_reg_load(ID,
417 				  sub_id,
418 				  CAPT_NEXT_ACKNOWLEDGE_REG_ID);
419 	state->FSM_State_Info = input_system_sub_system_reg_load(ID,
420 				sub_id,
421 				CAPT_FSM_STATE_INFO_REG_ID);
422 }
423 
424 static inline void acquisition_unit_get_state(
425     const input_system_ID_t			ID,
426     const sub_system_ID_t			sub_id,
427     acquisition_unit_state_t		*state)
428 {
429 	assert(sub_id == ACQUISITION_UNIT0_ID);
430 	assert(state);
431 
432 	state->Start_Addr = input_system_sub_system_reg_load(ID,
433 			    sub_id,
434 			    ACQ_START_ADDR_REG_ID);
435 	state->Mem_Region_Size = input_system_sub_system_reg_load(ID,
436 				 sub_id,
437 				 ACQ_MEM_REGION_SIZE_REG_ID);
438 	state->Num_Mem_Regions = input_system_sub_system_reg_load(ID,
439 				 sub_id,
440 				 ACQ_NUM_MEM_REGIONS_REG_ID);
441 //	AM: Illegal read from following registers.
442 	/*	state->Init = input_system_sub_system_reg_load(ID,
443 			sub_id,
444 			ACQ_INIT_REG_ID);
445 	*/
446 	state->Received_Short_Packets = input_system_sub_system_reg_load(ID,
447 					sub_id,
448 					ACQ_RECEIVED_SHORT_PACKETS_REG_ID);
449 	state->Received_Long_Packets = input_system_sub_system_reg_load(ID,
450 				       sub_id,
451 				       ACQ_RECEIVED_LONG_PACKETS_REG_ID);
452 	state->Last_Command = input_system_sub_system_reg_load(ID,
453 			      sub_id,
454 			      ACQ_LAST_COMMAND_REG_ID);
455 	state->Next_Command = input_system_sub_system_reg_load(ID,
456 			      sub_id,
457 			      ACQ_NEXT_COMMAND_REG_ID);
458 	state->Last_Acknowledge = input_system_sub_system_reg_load(ID,
459 				  sub_id,
460 				  ACQ_LAST_ACKNOWLEDGE_REG_ID);
461 	state->Next_Acknowledge = input_system_sub_system_reg_load(ID,
462 				  sub_id,
463 				  ACQ_NEXT_ACKNOWLEDGE_REG_ID);
464 	state->FSM_State_Info = input_system_sub_system_reg_load(ID,
465 				sub_id,
466 				ACQ_FSM_STATE_INFO_REG_ID);
467 	state->Int_Cntr_Info = input_system_sub_system_reg_load(ID,
468 			       sub_id,
469 			       ACQ_INT_CNTR_INFO_REG_ID);
470 }
471 
472 static inline void ctrl_unit_get_state(
473     const input_system_ID_t			ID,
474     const sub_system_ID_t			sub_id,
475     ctrl_unit_state_t			*state)
476 {
477 	assert(sub_id == CTRL_UNIT0_ID);
478 	assert(state);
479 
480 	state->captA_start_addr = input_system_sub_system_reg_load(ID,
481 				  sub_id,
482 				  ISYS_CTRL_CAPT_START_ADDR_A_REG_ID);
483 	state->captB_start_addr = input_system_sub_system_reg_load(ID,
484 				  sub_id,
485 				  ISYS_CTRL_CAPT_START_ADDR_B_REG_ID);
486 	state->captC_start_addr = input_system_sub_system_reg_load(ID,
487 				  sub_id,
488 				  ISYS_CTRL_CAPT_START_ADDR_C_REG_ID);
489 	state->captA_mem_region_size = input_system_sub_system_reg_load(ID,
490 				       sub_id,
491 				       ISYS_CTRL_CAPT_MEM_REGION_SIZE_A_REG_ID);
492 	state->captB_mem_region_size = input_system_sub_system_reg_load(ID,
493 				       sub_id,
494 				       ISYS_CTRL_CAPT_MEM_REGION_SIZE_B_REG_ID);
495 	state->captC_mem_region_size = input_system_sub_system_reg_load(ID,
496 				       sub_id,
497 				       ISYS_CTRL_CAPT_MEM_REGION_SIZE_C_REG_ID);
498 	state->captA_num_mem_regions = input_system_sub_system_reg_load(ID,
499 				       sub_id,
500 				       ISYS_CTRL_CAPT_NUM_MEM_REGIONS_A_REG_ID);
501 	state->captB_num_mem_regions = input_system_sub_system_reg_load(ID,
502 				       sub_id,
503 				       ISYS_CTRL_CAPT_NUM_MEM_REGIONS_B_REG_ID);
504 	state->captC_num_mem_regions = input_system_sub_system_reg_load(ID,
505 				       sub_id,
506 				       ISYS_CTRL_CAPT_NUM_MEM_REGIONS_C_REG_ID);
507 	state->acq_start_addr = input_system_sub_system_reg_load(ID,
508 				sub_id,
509 				ISYS_CTRL_ACQ_START_ADDR_REG_ID);
510 	state->acq_mem_region_size = input_system_sub_system_reg_load(ID,
511 				     sub_id,
512 				     ISYS_CTRL_ACQ_MEM_REGION_SIZE_REG_ID);
513 	state->acq_num_mem_regions = input_system_sub_system_reg_load(ID,
514 				     sub_id,
515 				     ISYS_CTRL_ACQ_NUM_MEM_REGIONS_REG_ID);
516 //	AM: Illegal read from following registers.
517 	/*	state->ctrl_init = input_system_sub_system_reg_load(ID,
518 			sub_id,
519 			ISYS_CTRL_INIT_REG_ID);
520 	*/
521 	state->last_cmd = input_system_sub_system_reg_load(ID,
522 			  sub_id,
523 			  ISYS_CTRL_LAST_COMMAND_REG_ID);
524 	state->next_cmd = input_system_sub_system_reg_load(ID,
525 			  sub_id,
526 			  ISYS_CTRL_NEXT_COMMAND_REG_ID);
527 	state->last_ack = input_system_sub_system_reg_load(ID,
528 			  sub_id,
529 			  ISYS_CTRL_LAST_ACKNOWLEDGE_REG_ID);
530 	state->next_ack = input_system_sub_system_reg_load(ID,
531 			  sub_id,
532 			  ISYS_CTRL_NEXT_ACKNOWLEDGE_REG_ID);
533 	state->top_fsm_state = input_system_sub_system_reg_load(ID,
534 			       sub_id,
535 			       ISYS_CTRL_FSM_STATE_INFO_REG_ID);
536 	state->captA_fsm_state = input_system_sub_system_reg_load(ID,
537 				 sub_id,
538 				 ISYS_CTRL_CAPT_A_FSM_STATE_INFO_REG_ID);
539 	state->captB_fsm_state = input_system_sub_system_reg_load(ID,
540 				 sub_id,
541 				 ISYS_CTRL_CAPT_B_FSM_STATE_INFO_REG_ID);
542 	state->captC_fsm_state = input_system_sub_system_reg_load(ID,
543 				 sub_id,
544 				 ISYS_CTRL_CAPT_C_FSM_STATE_INFO_REG_ID);
545 	state->acq_fsm_state = input_system_sub_system_reg_load(ID,
546 			       sub_id,
547 			       ISYS_CTRL_ACQ_FSM_STATE_INFO_REG_ID);
548 	state->capt_reserve_one_mem_region = input_system_sub_system_reg_load(ID,
549 					     sub_id,
550 					     ISYS_CTRL_CAPT_RESERVE_ONE_MEM_REGION_REG_ID);
551 }
552 
553 static inline void mipi_port_get_state(
554     const rx_ID_t				ID,
555     const enum mipi_port_id			port_ID,
556     mipi_port_state_t			*state)
557 {
558 	int	i;
559 
560 	assert(ID < N_RX_ID);
561 	assert(port_ID < N_MIPI_PORT_ID);
562 	assert(state);
563 
564 	state->device_ready = receiver_port_reg_load(ID,
565 			      port_ID, _HRT_CSS_RECEIVER_DEVICE_READY_REG_IDX);
566 	state->irq_status = receiver_port_reg_load(ID,
567 			    port_ID, _HRT_CSS_RECEIVER_IRQ_STATUS_REG_IDX);
568 	state->irq_enable = receiver_port_reg_load(ID,
569 			    port_ID, _HRT_CSS_RECEIVER_IRQ_ENABLE_REG_IDX);
570 	state->timeout_count = receiver_port_reg_load(ID,
571 			       port_ID, _HRT_CSS_RECEIVER_TIMEOUT_COUNT_REG_IDX);
572 	state->init_count = (uint16_t)receiver_port_reg_load(ID,
573 			    port_ID, _HRT_CSS_RECEIVER_INIT_COUNT_REG_IDX);
574 	state->raw16_18 = (uint16_t)receiver_port_reg_load(ID,
575 			  port_ID, _HRT_CSS_RECEIVER_RAW16_18_DATAID_REG_IDX);
576 	state->sync_count = receiver_port_reg_load(ID,
577 			    port_ID, _HRT_CSS_RECEIVER_SYNC_COUNT_REG_IDX);
578 	state->rx_count = receiver_port_reg_load(ID,
579 			  port_ID, _HRT_CSS_RECEIVER_RX_COUNT_REG_IDX);
580 
581 	for (i = 0; i < MIPI_4LANE_CFG ; i++) {
582 		state->lane_sync_count[i] = (uint8_t)((state->sync_count) >> (i * 8));
583 		state->lane_rx_count[i] = (uint8_t)((state->rx_count) >> (i * 8));
584 	}
585 }
586 
587 static inline void rx_channel_get_state(
588     const rx_ID_t					ID,
589     const unsigned int				ch_id,
590     rx_channel_state_t				*state)
591 {
592 	int	i;
593 
594 	assert(ID < N_RX_ID);
595 	assert(ch_id < N_RX_CHANNEL_ID);
596 	assert(state);
597 
598 	switch (ch_id) {
599 	case 0:
600 		state->comp_scheme0 = receiver_reg_load(ID,
601 							_HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC0_REG0_IDX);
602 		state->comp_scheme1 = receiver_reg_load(ID,
603 							_HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC0_REG1_IDX);
604 		break;
605 	case 1:
606 		state->comp_scheme0 = receiver_reg_load(ID,
607 							_HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC1_REG0_IDX);
608 		state->comp_scheme1 = receiver_reg_load(ID,
609 							_HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC1_REG1_IDX);
610 		break;
611 	case 2:
612 		state->comp_scheme0 = receiver_reg_load(ID,
613 							_HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC2_REG0_IDX);
614 		state->comp_scheme1 = receiver_reg_load(ID,
615 							_HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC2_REG1_IDX);
616 		break;
617 	case 3:
618 		state->comp_scheme0 = receiver_reg_load(ID,
619 							_HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC3_REG0_IDX);
620 		state->comp_scheme1 = receiver_reg_load(ID,
621 							_HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC3_REG1_IDX);
622 		break;
623 	}
624 
625 	/* See Table 7.1.17,..., 7.1.24 */
626 	for (i = 0; i < 6; i++) {
627 		u8	val = (uint8_t)((state->comp_scheme0) >> (i * 5)) & 0x1f;
628 
629 		state->comp[i] = (mipi_compressor_t)(val & 0x07);
630 		state->pred[i] = (mipi_predictor_t)((val & 0x18) >> 3);
631 	}
632 	for (i = 6; i < N_MIPI_FORMAT_CUSTOM; i++) {
633 		u8	val = (uint8_t)((state->comp_scheme0) >> ((i - 6) * 5)) & 0x1f;
634 
635 		state->comp[i] = (mipi_compressor_t)(val & 0x07);
636 		state->pred[i] = (mipi_predictor_t)((val & 0x18) >> 3);
637 	}
638 }
639 
640 // MW: "2400" in the name is not good, but this is to avoid a naming conflict
641 static input_system_cfg2400_t config;
642 
643 static void receiver_rst(
644     const rx_ID_t				ID)
645 {
646 	enum mipi_port_id		port_id;
647 
648 	assert(ID < N_RX_ID);
649 
650 // Disable all ports.
651 	for (port_id = MIPI_PORT0_ID; port_id < N_MIPI_PORT_ID; port_id++) {
652 		receiver_port_enable(ID, port_id, false);
653 	}
654 
655 	// AM: Additional actions for stopping receiver?
656 }
657 
658 //Single function to reset all the devices mapped via GP_DEVICE.
659 static void gp_device_rst(const gp_device_ID_t		ID)
660 {
661 	assert(ID < N_GP_DEVICE_ID);
662 
663 	gp_device_reg_store(ID, _REG_GP_SYNCGEN_ENABLE_ADDR, ZERO);
664 	// gp_device_reg_store(ID, _REG_GP_SYNCGEN_FREE_RUNNING_ADDR, ZERO);
665 	// gp_device_reg_store(ID, _REG_GP_SYNCGEN_PAUSE_ADDR, ONE);
666 	// gp_device_reg_store(ID, _REG_GP_NR_FRAMES_ADDR, ZERO);
667 	// gp_device_reg_store(ID, _REG_GP_SYNGEN_NR_PIX_ADDR, ZERO);
668 	// gp_device_reg_store(ID, _REG_GP_SYNGEN_NR_PIX_ADDR, ZERO);
669 	// gp_device_reg_store(ID, _REG_GP_SYNGEN_NR_LINES_ADDR, ZERO);
670 	// gp_device_reg_store(ID, _REG_GP_SYNGEN_HBLANK_CYCLES_ADDR, ZERO);
671 	// gp_device_reg_store(ID, _REG_GP_SYNGEN_VBLANK_CYCLES_ADDR, ZERO);
672 // AM: Following calls cause strange warnings. Probably they should not be initialized.
673 //	gp_device_reg_store(ID, _REG_GP_ISEL_SOF_ADDR, ZERO);
674 //	gp_device_reg_store(ID, _REG_GP_ISEL_EOF_ADDR, ZERO);
675 //	gp_device_reg_store(ID, _REG_GP_ISEL_SOL_ADDR, ZERO);
676 //	gp_device_reg_store(ID, _REG_GP_ISEL_EOL_ADDR, ZERO);
677 	gp_device_reg_store(ID, _REG_GP_ISEL_LFSR_ENABLE_ADDR, ZERO);
678 	gp_device_reg_store(ID, _REG_GP_ISEL_LFSR_ENABLE_B_ADDR, ZERO);
679 	gp_device_reg_store(ID, _REG_GP_ISEL_LFSR_RESET_VALUE_ADDR, ZERO);
680 	gp_device_reg_store(ID, _REG_GP_ISEL_TPG_ENABLE_ADDR, ZERO);
681 	gp_device_reg_store(ID, _REG_GP_ISEL_TPG_ENABLE_B_ADDR, ZERO);
682 	gp_device_reg_store(ID, _REG_GP_ISEL_HOR_CNT_MASK_ADDR, ZERO);
683 	gp_device_reg_store(ID, _REG_GP_ISEL_VER_CNT_MASK_ADDR, ZERO);
684 	gp_device_reg_store(ID, _REG_GP_ISEL_XY_CNT_MASK_ADDR, ZERO);
685 	gp_device_reg_store(ID, _REG_GP_ISEL_HOR_CNT_DELTA_ADDR, ZERO);
686 	gp_device_reg_store(ID, _REG_GP_ISEL_VER_CNT_DELTA_ADDR, ZERO);
687 	gp_device_reg_store(ID, _REG_GP_ISEL_TPG_MODE_ADDR, ZERO);
688 	gp_device_reg_store(ID, _REG_GP_ISEL_TPG_RED1_ADDR, ZERO);
689 	gp_device_reg_store(ID, _REG_GP_ISEL_TPG_GREEN1_ADDR, ZERO);
690 	gp_device_reg_store(ID, _REG_GP_ISEL_TPG_BLUE1_ADDR, ZERO);
691 	gp_device_reg_store(ID, _REG_GP_ISEL_TPG_RED2_ADDR, ZERO);
692 	gp_device_reg_store(ID, _REG_GP_ISEL_TPG_GREEN2_ADDR, ZERO);
693 	gp_device_reg_store(ID, _REG_GP_ISEL_TPG_BLUE2_ADDR, ZERO);
694 	//gp_device_reg_store(ID, _REG_GP_ISEL_CH_ID_ADDR, ZERO);
695 	//gp_device_reg_store(ID, _REG_GP_ISEL_FMT_TYPE_ADDR, ZERO);
696 	gp_device_reg_store(ID, _REG_GP_ISEL_DATA_SEL_ADDR, ZERO);
697 	gp_device_reg_store(ID, _REG_GP_ISEL_SBAND_SEL_ADDR, ZERO);
698 	gp_device_reg_store(ID, _REG_GP_ISEL_SYNC_SEL_ADDR, ZERO);
699 	//	gp_device_reg_store(ID, _REG_GP_SYNCGEN_HOR_CNT_ADDR, ZERO);
700 	//	gp_device_reg_store(ID, _REG_GP_SYNCGEN_VER_CNT_ADDR, ZERO);
701 	//	gp_device_reg_store(ID, _REG_GP_SYNCGEN_FRAME_CNT_ADDR, ZERO);
702 	gp_device_reg_store(ID, _REG_GP_SOFT_RESET_ADDR,
703 			    ZERO); // AM: Maybe this soft reset is not safe.
704 }
705 
706 static void input_selector_cfg_for_sensor(const gp_device_ID_t ID)
707 {
708 	assert(ID < N_GP_DEVICE_ID);
709 
710 	gp_device_reg_store(ID, _REG_GP_ISEL_SOF_ADDR, ONE);
711 	gp_device_reg_store(ID, _REG_GP_ISEL_EOF_ADDR, ONE);
712 	gp_device_reg_store(ID, _REG_GP_ISEL_SOL_ADDR, ONE);
713 	gp_device_reg_store(ID, _REG_GP_ISEL_EOL_ADDR, ONE);
714 	gp_device_reg_store(ID, _REG_GP_ISEL_CH_ID_ADDR, ZERO);
715 	gp_device_reg_store(ID, _REG_GP_ISEL_FMT_TYPE_ADDR, ZERO);
716 	gp_device_reg_store(ID, _REG_GP_ISEL_DATA_SEL_ADDR, ZERO);
717 	gp_device_reg_store(ID, _REG_GP_ISEL_SBAND_SEL_ADDR, ZERO);
718 	gp_device_reg_store(ID, _REG_GP_ISEL_SYNC_SEL_ADDR, ZERO);
719 	gp_device_reg_store(ID, _REG_GP_SOFT_RESET_ADDR, ZERO);
720 }
721 
722 static void input_switch_rst(const gp_device_ID_t ID)
723 {
724 	int addr;
725 
726 	assert(ID < N_GP_DEVICE_ID);
727 
728 	// Initialize the data&hsync LUT.
729 	for (addr = _REG_GP_IFMT_input_switch_lut_reg0;
730 	     addr <= _REG_GP_IFMT_input_switch_lut_reg7; addr += SIZEOF_HRT_REG) {
731 		gp_device_reg_store(ID, addr, ZERO);
732 	}
733 
734 	// Initialize the vsync LUT.
735 	gp_device_reg_store(ID,
736 			    _REG_GP_IFMT_input_switch_fsync_lut,
737 			    ZERO);
738 }
739 
740 static void input_switch_cfg(
741     const gp_device_ID_t			ID,
742     const input_switch_cfg_t *const cfg)
743 {
744 	int addr_offset;
745 
746 	assert(ID < N_GP_DEVICE_ID);
747 	assert(cfg);
748 
749 	// Initialize the data&hsync LUT.
750 	for (addr_offset = 0; addr_offset < N_RX_CHANNEL_ID * 2; addr_offset++) {
751 		assert(addr_offset * SIZEOF_HRT_REG + _REG_GP_IFMT_input_switch_lut_reg0 <=
752 		       _REG_GP_IFMT_input_switch_lut_reg7);
753 		gp_device_reg_store(ID,
754 				    _REG_GP_IFMT_input_switch_lut_reg0 + addr_offset * SIZEOF_HRT_REG,
755 				    cfg->hsync_data_reg[addr_offset]);
756 	}
757 
758 	// Initialize the vsync LUT.
759 	gp_device_reg_store(ID,
760 			    _REG_GP_IFMT_input_switch_fsync_lut,
761 			    cfg->vsync_data_reg);
762 }
763 
764 static void input_system_network_rst(const input_system_ID_t ID)
765 {
766 	unsigned int sub_id;
767 
768 	// Reset all 3 multicasts.
769 	input_system_sub_system_reg_store(ID,
770 					  GPREGS_UNIT0_ID,
771 					  HIVE_ISYS_GPREG_MULTICAST_A_IDX,
772 					  INPUT_SYSTEM_DISCARD_ALL);
773 	input_system_sub_system_reg_store(ID,
774 					  GPREGS_UNIT0_ID,
775 					  HIVE_ISYS_GPREG_MULTICAST_B_IDX,
776 					  INPUT_SYSTEM_DISCARD_ALL);
777 	input_system_sub_system_reg_store(ID,
778 					  GPREGS_UNIT0_ID,
779 					  HIVE_ISYS_GPREG_MULTICAST_C_IDX,
780 					  INPUT_SYSTEM_DISCARD_ALL);
781 
782 	// Reset stream mux.
783 	input_system_sub_system_reg_store(ID,
784 					  GPREGS_UNIT0_ID,
785 					  HIVE_ISYS_GPREG_MUX_IDX,
786 					  N_INPUT_SYSTEM_MULTIPLEX);
787 
788 	// Reset 3 capture units.
789 	for (sub_id = CAPTURE_UNIT0_ID; sub_id < CAPTURE_UNIT0_ID + N_CAPTURE_UNIT_ID;
790 	     sub_id++) {
791 		input_system_sub_system_reg_store(ID,
792 						  sub_id,
793 						  CAPT_INIT_REG_ID,
794 						  1U << CAPT_INIT_RST_REG_BIT);
795 	}
796 
797 	// Reset acquisition unit.
798 	for (sub_id = ACQUISITION_UNIT0_ID;
799 	     sub_id < ACQUISITION_UNIT0_ID + N_ACQUISITION_UNIT_ID; sub_id++) {
800 		input_system_sub_system_reg_store(ID,
801 						  sub_id,
802 						  ACQ_INIT_REG_ID,
803 						  1U << ACQ_INIT_RST_REG_BIT);
804 	}
805 
806 	// DMA unit reset is not needed.
807 
808 	// Reset controller units.
809 	// NB: In future we need to keep part of ctrl_state for split capture and
810 	for (sub_id = CTRL_UNIT0_ID; sub_id < CTRL_UNIT0_ID + N_CTRL_UNIT_ID;
811 	     sub_id++) {
812 		input_system_sub_system_reg_store(ID,
813 						  sub_id,
814 						  ISYS_CTRL_INIT_REG_ID,
815 						  1U); //AM: Is there any named constant?
816 	}
817 }
818 
819 // Function that resets current configuration.
820 input_system_err_t input_system_configuration_reset(void)
821 {
822 	unsigned int i;
823 
824 	receiver_rst(RX0_ID);
825 
826 	input_system_network_rst(INPUT_SYSTEM0_ID);
827 
828 	gp_device_rst(GP_DEVICE0_ID);
829 
830 	input_switch_rst(GP_DEVICE0_ID);
831 
832 	//target_rst();
833 
834 	// Reset IRQ_CTRLs.
835 
836 	// Reset configuration data structures.
837 	for (i = 0; i < N_CHANNELS; i++) {
838 		config.ch_flags[i] = INPUT_SYSTEM_CFG_FLAG_RESET;
839 		config.target_isp_flags[i] = INPUT_SYSTEM_CFG_FLAG_RESET;
840 		config.target_sp_flags[i] = INPUT_SYSTEM_CFG_FLAG_RESET;
841 		config.target_strm2mem_flags[i] = INPUT_SYSTEM_CFG_FLAG_RESET;
842 	}
843 
844 	for (i = 0; i < N_CSI_PORTS; i++) {
845 		config.csi_buffer_flags[i]	 = INPUT_SYSTEM_CFG_FLAG_RESET;
846 		config.multicast[i]		 = INPUT_SYSTEM_DISCARD_ALL;
847 	}
848 
849 	config.source_type_flags				 = INPUT_SYSTEM_CFG_FLAG_RESET;
850 	config.acquisition_buffer_unique_flags	 = INPUT_SYSTEM_CFG_FLAG_RESET;
851 	config.unallocated_ib_mem_words			 = IB_CAPACITY_IN_WORDS;
852 	//config.acq_allocated_ib_mem_words		 = 0;
853 
854 	// Set the start of the session cofiguration.
855 	config.session_flags = INPUT_SYSTEM_CFG_FLAG_REQUIRED;
856 
857 	return INPUT_SYSTEM_ERR_NO_ERROR;
858 }
859 
860 // MW: Comments are good, but doxygen is required, place it at the declaration
861 // Function that appends the channel to current configuration.
862 static input_system_err_t input_system_configure_channel(
863     const channel_cfg_t		channel)
864 {
865 	input_system_err_t error = INPUT_SYSTEM_ERR_NO_ERROR;
866 	// Check if channel is not already configured.
867 	if (config.ch_flags[channel.ch_id] & INPUT_SYSTEM_CFG_FLAG_SET) {
868 		return INPUT_SYSTEM_ERR_CHANNEL_ALREADY_SET;
869 	} else {
870 		switch (channel.source_type) {
871 		case INPUT_SYSTEM_SOURCE_SENSOR:
872 			error = input_system_configure_channel_sensor(channel);
873 			break;
874 		case INPUT_SYSTEM_SOURCE_TPG:
875 		case INPUT_SYSTEM_SOURCE_PRBS:
876 		case INPUT_SYSTEM_SOURCE_FIFO:
877 		default:
878 			return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
879 		}
880 
881 		if (error != INPUT_SYSTEM_ERR_NO_ERROR) return error;
882 		// Input switch channel configurations must be combined in united config.
883 		config.input_switch_cfg.hsync_data_reg[channel.source_cfg.csi_cfg.csi_port * 2]
884 		    =
885 			channel.target_cfg.input_switch_channel_cfg.hsync_data_reg[0];
886 		config.input_switch_cfg.hsync_data_reg[channel.source_cfg.csi_cfg.csi_port * 2 +
887 											   1] =
888 							       channel.target_cfg.input_switch_channel_cfg.hsync_data_reg[1];
889 		config.input_switch_cfg.vsync_data_reg |=
890 		    (channel.target_cfg.input_switch_channel_cfg.vsync_data_reg & 0x7) <<
891 		    (channel.source_cfg.csi_cfg.csi_port * 3);
892 
893 		// Other targets are just copied and marked as set.
894 		config.target_isp[channel.source_cfg.csi_cfg.csi_port] =
895 		    channel.target_cfg.target_isp_cfg;
896 		config.target_sp[channel.source_cfg.csi_cfg.csi_port] =
897 		    channel.target_cfg.target_sp_cfg;
898 		config.target_strm2mem[channel.source_cfg.csi_cfg.csi_port] =
899 		    channel.target_cfg.target_strm2mem_cfg;
900 		config.target_isp_flags[channel.source_cfg.csi_cfg.csi_port] |=
901 		    INPUT_SYSTEM_CFG_FLAG_SET;
902 		config.target_sp_flags[channel.source_cfg.csi_cfg.csi_port] |=
903 		    INPUT_SYSTEM_CFG_FLAG_SET;
904 		config.target_strm2mem_flags[channel.source_cfg.csi_cfg.csi_port] |=
905 		    INPUT_SYSTEM_CFG_FLAG_SET;
906 
907 		config.ch_flags[channel.ch_id] = INPUT_SYSTEM_CFG_FLAG_SET;
908 	}
909 	return INPUT_SYSTEM_ERR_NO_ERROR;
910 }
911 
912 // Function that partitions input buffer space with determining addresses.
913 static input_system_err_t input_buffer_configuration(void)
914 {
915 	u32 current_address    = 0;
916 	u32 unallocated_memory = IB_CAPACITY_IN_WORDS;
917 
918 	isp2400_ib_buffer_t	candidate_buffer_acq  = IB_BUFFER_NULL;
919 	u32 size_requested;
920 	input_system_config_flags_t	acq_already_specified = INPUT_SYSTEM_CFG_FLAG_RESET;
921 	input_system_csi_port_t port;
922 
923 	for (port = INPUT_SYSTEM_PORT_A; port < N_INPUT_SYSTEM_PORTS; port++) {
924 		csi_cfg_t source = config.csi_value[port];//.csi_cfg;
925 
926 		if (config.csi_flags[port] & INPUT_SYSTEM_CFG_FLAG_SET) {
927 			// Check and set csi buffer in input buffer.
928 			switch (source.buffering_mode) {
929 			case INPUT_SYSTEM_FIFO_CAPTURE:
930 			case INPUT_SYSTEM_XMEM_ACQUIRE:
931 				config.csi_buffer_flags[port] =
932 				    INPUT_SYSTEM_CFG_FLAG_BLOCKED; // Well, not used.
933 				break;
934 
935 			case INPUT_SYSTEM_FIFO_CAPTURE_WITH_COUNTING:
936 			case INPUT_SYSTEM_SRAM_BUFFERING:
937 			case INPUT_SYSTEM_XMEM_BUFFERING:
938 			case INPUT_SYSTEM_XMEM_CAPTURE:
939 				size_requested = source.csi_buffer.mem_reg_size *
940 						 source.csi_buffer.nof_mem_regs;
941 				if (source.csi_buffer.mem_reg_size > 0
942 				    && source.csi_buffer.nof_mem_regs > 0
943 				    && size_requested <= unallocated_memory
944 				   ) {
945 					config.csi_buffer[port].mem_reg_addr = current_address;
946 					config.csi_buffer[port].mem_reg_size = source.csi_buffer.mem_reg_size;
947 					config.csi_buffer[port].nof_mem_regs = source.csi_buffer.nof_mem_regs;
948 					current_address		+= size_requested;
949 					unallocated_memory	-= size_requested;
950 					config.csi_buffer_flags[port] = INPUT_SYSTEM_CFG_FLAG_SET;
951 				} else {
952 					config.csi_buffer_flags[port] |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
953 					return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
954 				}
955 				break;
956 
957 			default:
958 				config.csi_buffer_flags[port] |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
959 				return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
960 			}
961 
962 			// Check acquisition buffer specified but set it later since it has to be unique.
963 			switch (source.buffering_mode) {
964 			case INPUT_SYSTEM_FIFO_CAPTURE:
965 			case INPUT_SYSTEM_SRAM_BUFFERING:
966 			case INPUT_SYSTEM_XMEM_CAPTURE:
967 				// Nothing to do.
968 				break;
969 
970 			case INPUT_SYSTEM_FIFO_CAPTURE_WITH_COUNTING:
971 			case INPUT_SYSTEM_XMEM_BUFFERING:
972 			case INPUT_SYSTEM_XMEM_ACQUIRE:
973 				if (acq_already_specified == INPUT_SYSTEM_CFG_FLAG_RESET) {
974 					size_requested = source.acquisition_buffer.mem_reg_size
975 							 * source.acquisition_buffer.nof_mem_regs;
976 					if (source.acquisition_buffer.mem_reg_size > 0
977 					    && source.acquisition_buffer.nof_mem_regs > 0
978 					    && size_requested <= unallocated_memory
979 					   ) {
980 						candidate_buffer_acq = source.acquisition_buffer;
981 						acq_already_specified = INPUT_SYSTEM_CFG_FLAG_SET;
982 					}
983 				} else {
984 					// Check if specified acquisition buffer is the same as specified before.
985 					if (source.acquisition_buffer.mem_reg_size != candidate_buffer_acq.mem_reg_size
986 					    || source.acquisition_buffer.nof_mem_regs !=  candidate_buffer_acq.nof_mem_regs
987 					   ) {
988 						config.acquisition_buffer_unique_flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
989 						return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
990 					}
991 				}
992 				break;
993 
994 			default:
995 				return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
996 			}
997 		} else {
998 			config.csi_buffer_flags[port] = INPUT_SYSTEM_CFG_FLAG_BLOCKED;
999 		}
1000 	} // end of for ( port )
1001 
1002 	// Set the acquisition buffer at the end.
1003 	size_requested = candidate_buffer_acq.mem_reg_size *
1004 			 candidate_buffer_acq.nof_mem_regs;
1005 	if (acq_already_specified == INPUT_SYSTEM_CFG_FLAG_SET
1006 	    && size_requested <= unallocated_memory) {
1007 		config.acquisition_buffer_unique.mem_reg_addr = current_address;
1008 		config.acquisition_buffer_unique.mem_reg_size =
1009 		    candidate_buffer_acq.mem_reg_size;
1010 		config.acquisition_buffer_unique.nof_mem_regs =
1011 		    candidate_buffer_acq.nof_mem_regs;
1012 		current_address		+= size_requested;
1013 		unallocated_memory	-= size_requested;
1014 		config.acquisition_buffer_unique_flags = INPUT_SYSTEM_CFG_FLAG_SET;
1015 
1016 		assert(current_address <= IB_CAPACITY_IN_WORDS);
1017 	}
1018 
1019 	return INPUT_SYSTEM_ERR_NO_ERROR;
1020 }
1021 
1022 static void capture_unit_configure(
1023     const input_system_ID_t			ID,
1024     const sub_system_ID_t			sub_id,
1025     const isp2400_ib_buffer_t *const cfg)
1026 {
1027 	assert(ID < N_INPUT_SYSTEM_ID);
1028 	assert(/*(sub_id >= CAPTURE_UNIT0_ID) &&*/ (sub_id <=
1029 		CAPTURE_UNIT2_ID)); // Commented part is always true.
1030 	assert(cfg);
1031 
1032 	input_system_sub_system_reg_store(ID,
1033 					  sub_id,
1034 					  CAPT_START_ADDR_REG_ID,
1035 					  cfg->mem_reg_addr);
1036 	input_system_sub_system_reg_store(ID,
1037 					  sub_id,
1038 					  CAPT_MEM_REGION_SIZE_REG_ID,
1039 					  cfg->mem_reg_size);
1040 	input_system_sub_system_reg_store(ID,
1041 					  sub_id,
1042 					  CAPT_NUM_MEM_REGIONS_REG_ID,
1043 					  cfg->nof_mem_regs);
1044 }
1045 
1046 static void acquisition_unit_configure(
1047     const input_system_ID_t			ID,
1048     const sub_system_ID_t			sub_id,
1049     const isp2400_ib_buffer_t *const cfg)
1050 {
1051 	assert(ID < N_INPUT_SYSTEM_ID);
1052 	assert(sub_id == ACQUISITION_UNIT0_ID);
1053 	assert(cfg);
1054 
1055 	input_system_sub_system_reg_store(ID,
1056 					  sub_id,
1057 					  ACQ_START_ADDR_REG_ID,
1058 					  cfg->mem_reg_addr);
1059 	input_system_sub_system_reg_store(ID,
1060 					  sub_id,
1061 					  ACQ_NUM_MEM_REGIONS_REG_ID,
1062 					  cfg->nof_mem_regs);
1063 	input_system_sub_system_reg_store(ID,
1064 					  sub_id,
1065 					  ACQ_MEM_REGION_SIZE_REG_ID,
1066 					  cfg->mem_reg_size);
1067 }
1068 
1069 static void ctrl_unit_configure(
1070     const input_system_ID_t			ID,
1071     const sub_system_ID_t			sub_id,
1072     const ctrl_unit_cfg_t *const cfg)
1073 {
1074 	assert(ID < N_INPUT_SYSTEM_ID);
1075 	assert(sub_id == CTRL_UNIT0_ID);
1076 	assert(cfg);
1077 
1078 	input_system_sub_system_reg_store(ID,
1079 					  sub_id,
1080 					  ISYS_CTRL_CAPT_START_ADDR_A_REG_ID,
1081 					  cfg->buffer_mipi[CAPTURE_UNIT0_ID].mem_reg_addr);
1082 	input_system_sub_system_reg_store(ID,
1083 					  sub_id,
1084 					  ISYS_CTRL_CAPT_MEM_REGION_SIZE_A_REG_ID,
1085 					  cfg->buffer_mipi[CAPTURE_UNIT0_ID].mem_reg_size);
1086 	input_system_sub_system_reg_store(ID,
1087 					  sub_id,
1088 					  ISYS_CTRL_CAPT_NUM_MEM_REGIONS_A_REG_ID,
1089 					  cfg->buffer_mipi[CAPTURE_UNIT0_ID].nof_mem_regs);
1090 
1091 	input_system_sub_system_reg_store(ID,
1092 					  sub_id,
1093 					  ISYS_CTRL_CAPT_START_ADDR_B_REG_ID,
1094 					  cfg->buffer_mipi[CAPTURE_UNIT1_ID].mem_reg_addr);
1095 	input_system_sub_system_reg_store(ID,
1096 					  sub_id,
1097 					  ISYS_CTRL_CAPT_MEM_REGION_SIZE_B_REG_ID,
1098 					  cfg->buffer_mipi[CAPTURE_UNIT1_ID].mem_reg_size);
1099 	input_system_sub_system_reg_store(ID,
1100 					  sub_id,
1101 					  ISYS_CTRL_CAPT_NUM_MEM_REGIONS_B_REG_ID,
1102 					  cfg->buffer_mipi[CAPTURE_UNIT1_ID].nof_mem_regs);
1103 
1104 	input_system_sub_system_reg_store(ID,
1105 					  sub_id,
1106 					  ISYS_CTRL_CAPT_START_ADDR_C_REG_ID,
1107 					  cfg->buffer_mipi[CAPTURE_UNIT2_ID].mem_reg_addr);
1108 	input_system_sub_system_reg_store(ID,
1109 					  sub_id,
1110 					  ISYS_CTRL_CAPT_MEM_REGION_SIZE_C_REG_ID,
1111 					  cfg->buffer_mipi[CAPTURE_UNIT2_ID].mem_reg_size);
1112 	input_system_sub_system_reg_store(ID,
1113 					  sub_id,
1114 					  ISYS_CTRL_CAPT_NUM_MEM_REGIONS_C_REG_ID,
1115 					  cfg->buffer_mipi[CAPTURE_UNIT2_ID].nof_mem_regs);
1116 
1117 	input_system_sub_system_reg_store(ID,
1118 					  sub_id,
1119 					  ISYS_CTRL_ACQ_START_ADDR_REG_ID,
1120 					  cfg->buffer_acquire[ACQUISITION_UNIT0_ID - ACQUISITION_UNIT0_ID].mem_reg_addr);
1121 	input_system_sub_system_reg_store(ID,
1122 					  sub_id,
1123 					  ISYS_CTRL_ACQ_MEM_REGION_SIZE_REG_ID,
1124 					  cfg->buffer_acquire[ACQUISITION_UNIT0_ID - ACQUISITION_UNIT0_ID].mem_reg_size);
1125 	input_system_sub_system_reg_store(ID,
1126 					  sub_id,
1127 					  ISYS_CTRL_ACQ_NUM_MEM_REGIONS_REG_ID,
1128 					  cfg->buffer_acquire[ACQUISITION_UNIT0_ID - ACQUISITION_UNIT0_ID].nof_mem_regs);
1129 	input_system_sub_system_reg_store(ID,
1130 					  sub_id,
1131 					  ISYS_CTRL_CAPT_RESERVE_ONE_MEM_REGION_REG_ID,
1132 					  0);
1133 }
1134 
1135 static void input_system_network_configure(
1136     const input_system_ID_t				ID,
1137     const input_system_network_cfg_t *const cfg)
1138 {
1139 	u32 sub_id;
1140 
1141 	assert(ID < N_INPUT_SYSTEM_ID);
1142 	assert(cfg);
1143 
1144 	// Set all 3 multicasts.
1145 	input_system_sub_system_reg_store(ID,
1146 					  GPREGS_UNIT0_ID,
1147 					  HIVE_ISYS_GPREG_MULTICAST_A_IDX,
1148 					  cfg->multicast_cfg[CAPTURE_UNIT0_ID]);
1149 	input_system_sub_system_reg_store(ID,
1150 					  GPREGS_UNIT0_ID,
1151 					  HIVE_ISYS_GPREG_MULTICAST_B_IDX,
1152 					  cfg->multicast_cfg[CAPTURE_UNIT1_ID]);
1153 	input_system_sub_system_reg_store(ID,
1154 					  GPREGS_UNIT0_ID,
1155 					  HIVE_ISYS_GPREG_MULTICAST_C_IDX,
1156 					  cfg->multicast_cfg[CAPTURE_UNIT2_ID]);
1157 
1158 	// Set stream mux.
1159 	input_system_sub_system_reg_store(ID,
1160 					  GPREGS_UNIT0_ID,
1161 					  HIVE_ISYS_GPREG_MUX_IDX,
1162 					  cfg->mux_cfg);
1163 
1164 	// Set capture units.
1165 	for (sub_id = CAPTURE_UNIT0_ID; sub_id < CAPTURE_UNIT0_ID + N_CAPTURE_UNIT_ID;
1166 	     sub_id++) {
1167 		capture_unit_configure(ID,
1168 				       sub_id,
1169 				       &cfg->ctrl_unit_cfg[ID].buffer_mipi[sub_id - CAPTURE_UNIT0_ID]);
1170 	}
1171 
1172 	// Set acquisition units.
1173 	for (sub_id = ACQUISITION_UNIT0_ID;
1174 	     sub_id < ACQUISITION_UNIT0_ID + N_ACQUISITION_UNIT_ID; sub_id++) {
1175 		acquisition_unit_configure(ID,
1176 					   sub_id,
1177 					   &cfg->ctrl_unit_cfg[sub_id - ACQUISITION_UNIT0_ID].buffer_acquire[sub_id -
1178 						   ACQUISITION_UNIT0_ID]);
1179 	}
1180 
1181 	// No DMA configuration needed. Ctrl_unit will fully control it.
1182 
1183 	// Set controller units.
1184 	for (sub_id = CTRL_UNIT0_ID; sub_id < CTRL_UNIT0_ID + N_CTRL_UNIT_ID;
1185 	     sub_id++) {
1186 		ctrl_unit_configure(ID,
1187 				    sub_id,
1188 				    &cfg->ctrl_unit_cfg[sub_id - CTRL_UNIT0_ID]);
1189 	}
1190 }
1191 
1192 static input_system_err_t configuration_to_registers(void)
1193 {
1194 	input_system_network_cfg_t input_system_network_cfg;
1195 	int i;
1196 
1197 	assert(config.source_type_flags & INPUT_SYSTEM_CFG_FLAG_SET);
1198 
1199 	switch (config.source_type) {
1200 	case INPUT_SYSTEM_SOURCE_SENSOR:
1201 
1202 		// Determine stream multicasts setting based on the mode of csi_cfg_t.
1203 		// AM: This should be moved towards earlier function call, e.g. in
1204 		// the commit function.
1205 		for (i = MIPI_PORT0_ID; i < N_MIPI_PORT_ID; i++) {
1206 			if (config.csi_flags[i] & INPUT_SYSTEM_CFG_FLAG_SET) {
1207 				switch (config.csi_value[i].buffering_mode) {
1208 				case INPUT_SYSTEM_FIFO_CAPTURE:
1209 					config.multicast[i] = INPUT_SYSTEM_CSI_BACKEND;
1210 					break;
1211 
1212 				case INPUT_SYSTEM_XMEM_CAPTURE:
1213 				case INPUT_SYSTEM_SRAM_BUFFERING:
1214 				case INPUT_SYSTEM_XMEM_BUFFERING:
1215 					config.multicast[i] = INPUT_SYSTEM_INPUT_BUFFER;
1216 					break;
1217 
1218 				case INPUT_SYSTEM_FIFO_CAPTURE_WITH_COUNTING:
1219 					config.multicast[i] = INPUT_SYSTEM_MULTICAST;
1220 					break;
1221 
1222 				case INPUT_SYSTEM_XMEM_ACQUIRE:
1223 					config.multicast[i] = INPUT_SYSTEM_DISCARD_ALL;
1224 					break;
1225 
1226 				default:
1227 					config.multicast[i] = INPUT_SYSTEM_DISCARD_ALL;
1228 					return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
1229 					//break;
1230 				}
1231 			} else {
1232 				config.multicast[i] = INPUT_SYSTEM_DISCARD_ALL;
1233 			}
1234 
1235 			input_system_network_cfg.multicast_cfg[i] = config.multicast[i];
1236 
1237 		} // for
1238 
1239 		input_system_network_cfg.mux_cfg = config.multiplexer;
1240 
1241 		input_system_network_cfg.ctrl_unit_cfg[CTRL_UNIT0_ID -
1242 						       CTRL_UNIT0_ID].buffer_mipi[CAPTURE_UNIT0_ID] =
1243 							       config.csi_buffer[MIPI_PORT0_ID];
1244 		input_system_network_cfg.ctrl_unit_cfg[CTRL_UNIT0_ID -
1245 						       CTRL_UNIT0_ID].buffer_mipi[CAPTURE_UNIT1_ID] =
1246 							       config.csi_buffer[MIPI_PORT1_ID];
1247 		input_system_network_cfg.ctrl_unit_cfg[CTRL_UNIT0_ID -
1248 						       CTRL_UNIT0_ID].buffer_mipi[CAPTURE_UNIT2_ID] =
1249 							       config.csi_buffer[MIPI_PORT2_ID];
1250 		input_system_network_cfg.ctrl_unit_cfg[CTRL_UNIT0_ID -
1251 						       CTRL_UNIT0_ID].buffer_acquire[ACQUISITION_UNIT0_ID -
1252 							       ACQUISITION_UNIT0_ID] =
1253 								       config.acquisition_buffer_unique;
1254 
1255 		// First set input network around CSI receiver.
1256 		input_system_network_configure(INPUT_SYSTEM0_ID, &input_system_network_cfg);
1257 
1258 		// Set the CSI receiver.
1259 		//...
1260 		break;
1261 
1262 	case INPUT_SYSTEM_SOURCE_TPG:
1263 	case INPUT_SYSTEM_SOURCE_PRBS:
1264 	case INPUT_SYSTEM_SOURCE_FIFO:
1265 		break;
1266 
1267 	default:
1268 		return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
1269 
1270 	} // end of switch (source_type)
1271 
1272 	// Set input selector.
1273 	input_selector_cfg_for_sensor(GP_DEVICE0_ID);
1274 
1275 	// Set input switch.
1276 	input_switch_cfg(GP_DEVICE0_ID, &config.input_switch_cfg);
1277 
1278 	// Set input formatters.
1279 	// AM: IF are set dynamically.
1280 	return INPUT_SYSTEM_ERR_NO_ERROR;
1281 }
1282 
1283 // Function that applies the whole configuration.
1284 input_system_err_t input_system_configuration_commit(void)
1285 {
1286 	// The last configuration step is to configure the input buffer.
1287 	input_system_err_t error = input_buffer_configuration();
1288 
1289 	if (error != INPUT_SYSTEM_ERR_NO_ERROR) {
1290 		return error;
1291 	}
1292 
1293 	// Translate the whole configuration into registers.
1294 	error = configuration_to_registers();
1295 	if (error != INPUT_SYSTEM_ERR_NO_ERROR) {
1296 		return error;
1297 	}
1298 
1299 	// Translate the whole configuration into ctrl commands etc.
1300 
1301 	return INPUT_SYSTEM_ERR_NO_ERROR;
1302 }
1303 
1304 // FIFO
1305 
1306 input_system_err_t	input_system_csi_fifo_channel_cfg(
1307     u32		ch_id,
1308     input_system_csi_port_t	port,
1309     backend_channel_cfg_t	backend_ch,
1310     target_cfg2400_t	target
1311 )
1312 {
1313 	channel_cfg_t channel;
1314 
1315 	channel.ch_id	= ch_id;
1316 	channel.backend_ch	= backend_ch;
1317 	channel.source_type = INPUT_SYSTEM_SOURCE_SENSOR;
1318 	//channel.source
1319 	channel.source_cfg.csi_cfg.csi_port			= port;
1320 	channel.source_cfg.csi_cfg.buffering_mode	= INPUT_SYSTEM_FIFO_CAPTURE;
1321 	channel.source_cfg.csi_cfg.csi_buffer			= IB_BUFFER_NULL;
1322 	channel.source_cfg.csi_cfg.acquisition_buffer	= IB_BUFFER_NULL;
1323 	channel.source_cfg.csi_cfg.nof_xmem_buffers	= 0;
1324 
1325 	channel.target_cfg	= target;
1326 	return input_system_configure_channel(channel);
1327 }
1328 
1329 input_system_err_t	input_system_csi_fifo_channel_with_counting_cfg(
1330     u32				ch_id,
1331     u32				nof_frames,
1332     input_system_csi_port_t			port,
1333     backend_channel_cfg_t			backend_ch,
1334     u32				csi_mem_reg_size,
1335     u32				csi_nof_mem_regs,
1336     target_cfg2400_t			target
1337 )
1338 {
1339 	channel_cfg_t channel;
1340 
1341 	channel.ch_id	= ch_id;
1342 	channel.backend_ch	= backend_ch;
1343 	channel.source_type		= INPUT_SYSTEM_SOURCE_SENSOR;
1344 	//channel.source
1345 	channel.source_cfg.csi_cfg.csi_port			= port;
1346 	channel.source_cfg.csi_cfg.buffering_mode	=
1347 	    INPUT_SYSTEM_FIFO_CAPTURE_WITH_COUNTING;
1348 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_size		= csi_mem_reg_size;
1349 	channel.source_cfg.csi_cfg.csi_buffer.nof_mem_regs		= csi_nof_mem_regs;
1350 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_addr		= 0;
1351 	channel.source_cfg.csi_cfg.acquisition_buffer			= IB_BUFFER_NULL;
1352 	channel.source_cfg.csi_cfg.nof_xmem_buffers	= nof_frames;
1353 
1354 	channel.target_cfg	= target;
1355 	return input_system_configure_channel(channel);
1356 }
1357 
1358 // SRAM
1359 
1360 input_system_err_t	input_system_csi_sram_channel_cfg(
1361     u32				ch_id,
1362     input_system_csi_port_t			port,
1363     backend_channel_cfg_t			backend_ch,
1364     u32				csi_mem_reg_size,
1365     u32				csi_nof_mem_regs,
1366     //	uint32_t				acq_mem_reg_size,
1367     //	uint32_t				acq_nof_mem_regs,
1368     target_cfg2400_t			target
1369 )
1370 {
1371 	channel_cfg_t channel;
1372 
1373 	channel.ch_id	= ch_id;
1374 	channel.backend_ch	= backend_ch;
1375 	channel.source_type		= INPUT_SYSTEM_SOURCE_SENSOR;
1376 	//channel.source
1377 	channel.source_cfg.csi_cfg.csi_port			= port;
1378 	channel.source_cfg.csi_cfg.buffering_mode	= INPUT_SYSTEM_SRAM_BUFFERING;
1379 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_size		= csi_mem_reg_size;
1380 	channel.source_cfg.csi_cfg.csi_buffer.nof_mem_regs		= csi_nof_mem_regs;
1381 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_addr		= 0;
1382 	channel.source_cfg.csi_cfg.acquisition_buffer			= IB_BUFFER_NULL;
1383 	channel.source_cfg.csi_cfg.nof_xmem_buffers	= 0;
1384 
1385 	channel.target_cfg	= target;
1386 	return input_system_configure_channel(channel);
1387 }
1388 
1389 //XMEM
1390 
1391 // Collects all parameters and puts them in channel_cfg_t.
1392 input_system_err_t	input_system_csi_xmem_channel_cfg(
1393     u32				ch_id,
1394     input_system_csi_port_t			port,
1395     backend_channel_cfg_t			backend_ch,
1396     u32				csi_mem_reg_size,
1397     u32				csi_nof_mem_regs,
1398     u32				acq_mem_reg_size,
1399     u32				acq_nof_mem_regs,
1400     target_cfg2400_t			target,
1401     uint32_t				nof_xmem_buffers
1402 )
1403 {
1404 	channel_cfg_t channel;
1405 
1406 	channel.ch_id	= ch_id;
1407 	channel.backend_ch	= backend_ch;
1408 	channel.source_type		= INPUT_SYSTEM_SOURCE_SENSOR;
1409 	//channel.source
1410 	channel.source_cfg.csi_cfg.csi_port			= port;
1411 	channel.source_cfg.csi_cfg.buffering_mode	= INPUT_SYSTEM_XMEM_BUFFERING;
1412 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_size		= csi_mem_reg_size;
1413 	channel.source_cfg.csi_cfg.csi_buffer.nof_mem_regs		= csi_nof_mem_regs;
1414 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_addr		= 0;
1415 	channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_size	= acq_mem_reg_size;
1416 	channel.source_cfg.csi_cfg.acquisition_buffer.nof_mem_regs	= acq_nof_mem_regs;
1417 	channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_addr	= 0;
1418 	channel.source_cfg.csi_cfg.nof_xmem_buffers	= nof_xmem_buffers;
1419 
1420 	channel.target_cfg	= target;
1421 	return input_system_configure_channel(channel);
1422 }
1423 
1424 input_system_err_t	input_system_csi_xmem_acquire_only_channel_cfg(
1425     u32				ch_id,
1426     u32				nof_frames,
1427     input_system_csi_port_t			port,
1428     backend_channel_cfg_t			backend_ch,
1429     u32				acq_mem_reg_size,
1430     u32				acq_nof_mem_regs,
1431     target_cfg2400_t			target)
1432 {
1433 	channel_cfg_t channel;
1434 
1435 	channel.ch_id	= ch_id;
1436 	channel.backend_ch	= backend_ch;
1437 	channel.source_type		= INPUT_SYSTEM_SOURCE_SENSOR;
1438 	//channel.source
1439 	channel.source_cfg.csi_cfg.csi_port			= port;
1440 	channel.source_cfg.csi_cfg.buffering_mode	= INPUT_SYSTEM_XMEM_ACQUIRE;
1441 	channel.source_cfg.csi_cfg.csi_buffer		= IB_BUFFER_NULL;
1442 	channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_size	= acq_mem_reg_size;
1443 	channel.source_cfg.csi_cfg.acquisition_buffer.nof_mem_regs	= acq_nof_mem_regs;
1444 	channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_addr	= 0;
1445 	channel.source_cfg.csi_cfg.nof_xmem_buffers	= nof_frames;
1446 
1447 	channel.target_cfg	= target;
1448 	return input_system_configure_channel(channel);
1449 }
1450 
1451 input_system_err_t	input_system_csi_xmem_capture_only_channel_cfg(
1452     u32				ch_id,
1453     u32				nof_frames,
1454     input_system_csi_port_t			port,
1455     u32				csi_mem_reg_size,
1456     u32				csi_nof_mem_regs,
1457     u32				acq_mem_reg_size,
1458     u32				acq_nof_mem_regs,
1459     target_cfg2400_t			target)
1460 {
1461 	channel_cfg_t channel;
1462 
1463 	channel.ch_id	= ch_id;
1464 	//channel.backend_ch	= backend_ch;
1465 	channel.source_type		= INPUT_SYSTEM_SOURCE_SENSOR;
1466 	//channel.source
1467 	channel.source_cfg.csi_cfg.csi_port			= port;
1468 	//channel.source_cfg.csi_cfg.backend_ch		= backend_ch;
1469 	channel.source_cfg.csi_cfg.buffering_mode	= INPUT_SYSTEM_XMEM_CAPTURE;
1470 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_size		= csi_mem_reg_size;
1471 	channel.source_cfg.csi_cfg.csi_buffer.nof_mem_regs		= csi_nof_mem_regs;
1472 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_addr		= 0;
1473 	channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_size	= acq_mem_reg_size;
1474 	channel.source_cfg.csi_cfg.acquisition_buffer.nof_mem_regs	= acq_nof_mem_regs;
1475 	channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_addr	= 0;
1476 	channel.source_cfg.csi_cfg.nof_xmem_buffers	= nof_frames;
1477 
1478 	channel.target_cfg	= target;
1479 	return input_system_configure_channel(channel);
1480 }
1481 
1482 // Non - CSI
1483 
1484 input_system_err_t	input_system_prbs_channel_cfg(
1485     u32		ch_id,
1486     u32		nof_frames,//not used yet
1487     u32		seed,
1488     u32		sync_gen_width,
1489     u32		sync_gen_height,
1490     u32		sync_gen_hblank_cycles,
1491     u32		sync_gen_vblank_cycles,
1492     target_cfg2400_t	target
1493 )
1494 {
1495 	channel_cfg_t channel;
1496 
1497 	(void)nof_frames;
1498 
1499 	channel.ch_id	= ch_id;
1500 	channel.source_type = INPUT_SYSTEM_SOURCE_PRBS;
1501 
1502 	channel.source_cfg.prbs_cfg.seed = seed;
1503 	channel.source_cfg.prbs_cfg.sync_gen_cfg.width		= sync_gen_width;
1504 	channel.source_cfg.prbs_cfg.sync_gen_cfg.height		= sync_gen_height;
1505 	channel.source_cfg.prbs_cfg.sync_gen_cfg.hblank_cycles	= sync_gen_hblank_cycles;
1506 	channel.source_cfg.prbs_cfg.sync_gen_cfg.vblank_cycles	= sync_gen_vblank_cycles;
1507 
1508 	channel.target_cfg	= target;
1509 
1510 	return input_system_configure_channel(channel);
1511 }
1512 
1513 input_system_err_t	input_system_tpg_channel_cfg(
1514     u32		ch_id,
1515     u32		nof_frames,//not used yet
1516     u32		x_mask,
1517     u32		y_mask,
1518     u32		x_delta,
1519     u32		y_delta,
1520     u32		xy_mask,
1521     u32		sync_gen_width,
1522     u32		sync_gen_height,
1523     u32		sync_gen_hblank_cycles,
1524     u32		sync_gen_vblank_cycles,
1525     target_cfg2400_t	target
1526 )
1527 {
1528 	channel_cfg_t channel;
1529 
1530 	(void)nof_frames;
1531 
1532 	channel.ch_id	= ch_id;
1533 	channel.source_type		= INPUT_SYSTEM_SOURCE_TPG;
1534 
1535 	channel.source_cfg.tpg_cfg.x_mask	= x_mask;
1536 	channel.source_cfg.tpg_cfg.y_mask	= y_mask;
1537 	channel.source_cfg.tpg_cfg.x_delta	= x_delta;
1538 	channel.source_cfg.tpg_cfg.y_delta	= y_delta;
1539 	channel.source_cfg.tpg_cfg.xy_mask	= xy_mask;
1540 	channel.source_cfg.tpg_cfg.sync_gen_cfg.width		= sync_gen_width;
1541 	channel.source_cfg.tpg_cfg.sync_gen_cfg.height		= sync_gen_height;
1542 	channel.source_cfg.tpg_cfg.sync_gen_cfg.hblank_cycles	= sync_gen_hblank_cycles;
1543 	channel.source_cfg.tpg_cfg.sync_gen_cfg.vblank_cycles	= sync_gen_vblank_cycles;
1544 
1545 	channel.target_cfg	= target;
1546 	return input_system_configure_channel(channel);
1547 }
1548 
1549 // MW: Don't use system specific names, (even in system specific files) "cfg2400" -> cfg
1550 input_system_err_t	input_system_gpfifo_channel_cfg(
1551     u32		ch_id,
1552     u32		nof_frames, //not used yet
1553 
1554     target_cfg2400_t	target)
1555 {
1556 	channel_cfg_t channel;
1557 
1558 	(void)nof_frames;
1559 
1560 	channel.ch_id	= ch_id;
1561 	channel.source_type	= INPUT_SYSTEM_SOURCE_FIFO;
1562 
1563 	channel.target_cfg	= target;
1564 	return input_system_configure_channel(channel);
1565 }
1566 
1567 ///////////////////////////////////////////////////////////////////////////
1568 //
1569 // Private specialized functions for channel setting.
1570 //
1571 ///////////////////////////////////////////////////////////////////////////
1572 
1573 // Fills the parameters to config.csi_value[port]
1574 static input_system_err_t input_system_configure_channel_sensor(
1575     const channel_cfg_t channel)
1576 {
1577 	const u32 port = channel.source_cfg.csi_cfg.csi_port;
1578 	input_system_err_t status = INPUT_SYSTEM_ERR_NO_ERROR;
1579 
1580 	input_system_multiplex_t mux;
1581 
1582 	if (port >= N_INPUT_SYSTEM_PORTS)
1583 		return INPUT_SYSTEM_ERR_GENERIC;
1584 
1585 	//check if port > N_INPUT_SYSTEM_MULTIPLEX
1586 
1587 	status = set_source_type(&config.source_type, channel.source_type,
1588 				 &config.source_type_flags);
1589 	if (status != INPUT_SYSTEM_ERR_NO_ERROR) return status;
1590 
1591 	// Check for conflicts on source (implicitly on multicast, capture unit and input buffer).
1592 
1593 	status = set_csi_cfg(&config.csi_value[port], &channel.source_cfg.csi_cfg,
1594 			     &config.csi_flags[port]);
1595 	if (status != INPUT_SYSTEM_ERR_NO_ERROR) return status;
1596 
1597 	switch (channel.source_cfg.csi_cfg.buffering_mode) {
1598 	case INPUT_SYSTEM_FIFO_CAPTURE:
1599 
1600 		// Check for conflicts on mux.
1601 		mux = INPUT_SYSTEM_MIPI_PORT0 + port;
1602 		status = input_system_multiplexer_cfg(&config.multiplexer, mux,
1603 						      &config.multiplexer_flags);
1604 		if (status != INPUT_SYSTEM_ERR_NO_ERROR) return status;
1605 		config.multicast[port] = INPUT_SYSTEM_CSI_BACKEND;
1606 
1607 		// Shared resource, so it should be blocked.
1608 		//config.mux_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1609 		//config.csi_buffer_flags[port] |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1610 		//config.acquisition_buffer_unique_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1611 
1612 		break;
1613 	case INPUT_SYSTEM_SRAM_BUFFERING:
1614 
1615 		// Check for conflicts on mux.
1616 		mux = INPUT_SYSTEM_ACQUISITION_UNIT;
1617 		status = input_system_multiplexer_cfg(&config.multiplexer, mux,
1618 						      &config.multiplexer_flags);
1619 		if (status != INPUT_SYSTEM_ERR_NO_ERROR) return status;
1620 		config.multicast[port] = INPUT_SYSTEM_INPUT_BUFFER;
1621 
1622 		// Shared resource, so it should be blocked.
1623 		//config.mux_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1624 		//config.csi_buffer_flags[port] |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1625 		//config.acquisition_buffer_unique_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1626 
1627 		break;
1628 	case INPUT_SYSTEM_XMEM_BUFFERING:
1629 
1630 		// Check for conflicts on mux.
1631 		mux = INPUT_SYSTEM_ACQUISITION_UNIT;
1632 		status = input_system_multiplexer_cfg(&config.multiplexer, mux,
1633 						      &config.multiplexer_flags);
1634 		if (status != INPUT_SYSTEM_ERR_NO_ERROR) return status;
1635 		config.multicast[port] = INPUT_SYSTEM_INPUT_BUFFER;
1636 
1637 		// Shared resource, so it should be blocked.
1638 		//config.mux_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1639 		//config.csi_buffer_flags[port] |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1640 		//config.acquisition_buffer_unique_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1641 
1642 		break;
1643 	case INPUT_SYSTEM_FIFO_CAPTURE_WITH_COUNTING:
1644 	case INPUT_SYSTEM_XMEM_CAPTURE:
1645 	case INPUT_SYSTEM_XMEM_ACQUIRE:
1646 	default:
1647 		return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
1648 	}
1649 
1650 	return INPUT_SYSTEM_ERR_NO_ERROR;
1651 }
1652 
1653 // Test flags and set structure.
1654 static input_system_err_t set_source_type(
1655     input_system_source_t *const lhs,
1656     const input_system_source_t			rhs,
1657     input_system_config_flags_t *const flags)
1658 {
1659 	// MW: Not enough asserts
1660 	assert(lhs);
1661 	assert(flags);
1662 
1663 	if ((*flags) & INPUT_SYSTEM_CFG_FLAG_BLOCKED) {
1664 		*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1665 		return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1666 	}
1667 
1668 	if ((*flags) & INPUT_SYSTEM_CFG_FLAG_SET) {
1669 		// Check for consistency with already set value.
1670 		if ((*lhs) == (rhs)) {
1671 			return INPUT_SYSTEM_ERR_NO_ERROR;
1672 		} else {
1673 			*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1674 			return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1675 		}
1676 	}
1677 	// Check the value (individually).
1678 	if (rhs >= N_INPUT_SYSTEM_SOURCE) {
1679 		*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1680 		return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1681 	}
1682 	// Set the value.
1683 	*lhs = rhs;
1684 
1685 	*flags |= INPUT_SYSTEM_CFG_FLAG_SET;
1686 	return INPUT_SYSTEM_ERR_NO_ERROR;
1687 }
1688 
1689 // Test flags and set structure.
1690 static input_system_err_t set_csi_cfg(
1691     csi_cfg_t *const lhs,
1692     const csi_cfg_t *const rhs,
1693     input_system_config_flags_t *const flags)
1694 {
1695 	u32 memory_required;
1696 	u32 acq_memory_required;
1697 
1698 	assert(lhs);
1699 	assert(flags);
1700 
1701 	if ((*flags) & INPUT_SYSTEM_CFG_FLAG_BLOCKED) {
1702 		*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1703 		return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1704 	}
1705 
1706 	if (*flags & INPUT_SYSTEM_CFG_FLAG_SET) {
1707 		// check for consistency with already set value.
1708 		if (/*lhs->backend_ch == rhs.backend_ch
1709 			&&*/ lhs->buffering_mode == rhs->buffering_mode
1710 		    && lhs->csi_buffer.mem_reg_size == rhs->csi_buffer.mem_reg_size
1711 		    && lhs->csi_buffer.nof_mem_regs  == rhs->csi_buffer.nof_mem_regs
1712 		    && lhs->acquisition_buffer.mem_reg_size == rhs->acquisition_buffer.mem_reg_size
1713 		    && lhs->acquisition_buffer.nof_mem_regs  == rhs->acquisition_buffer.nof_mem_regs
1714 		    && lhs->nof_xmem_buffers  == rhs->nof_xmem_buffers
1715 		) {
1716 			return INPUT_SYSTEM_ERR_NO_ERROR;
1717 		} else {
1718 			*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1719 			return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1720 		}
1721 	}
1722 	// Check the value (individually).
1723 	// no check for backend_ch
1724 	// no check for nof_xmem_buffers
1725 	memory_required = rhs->csi_buffer.mem_reg_size * rhs->csi_buffer.nof_mem_regs;
1726 	acq_memory_required = rhs->acquisition_buffer.mem_reg_size *
1727 			      rhs->acquisition_buffer.nof_mem_regs;
1728 	if (rhs->buffering_mode >= N_INPUT_SYSTEM_BUFFERING_MODE
1729 	    ||
1730 	    // Check if required memory is available in input buffer (SRAM).
1731 	    (memory_required + acq_memory_required) > config.unallocated_ib_mem_words
1732 
1733 	   ) {
1734 		*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1735 		return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1736 	}
1737 	// Set the value.
1738 	//lhs[port]->backend_ch		= rhs.backend_ch;
1739 	lhs->buffering_mode	= rhs->buffering_mode;
1740 	lhs->nof_xmem_buffers = rhs->nof_xmem_buffers;
1741 
1742 	lhs->csi_buffer.mem_reg_size = rhs->csi_buffer.mem_reg_size;
1743 	lhs->csi_buffer.nof_mem_regs  = rhs->csi_buffer.nof_mem_regs;
1744 	lhs->acquisition_buffer.mem_reg_size = rhs->acquisition_buffer.mem_reg_size;
1745 	lhs->acquisition_buffer.nof_mem_regs  = rhs->acquisition_buffer.nof_mem_regs;
1746 	// ALX: NB: Here we just set buffer parameters, but still not allocate it
1747 	// (no addresses determined). That will be done during commit.
1748 
1749 	//  FIXIT:	acq_memory_required is not deducted, since it can be allocated multiple times.
1750 	config.unallocated_ib_mem_words -= memory_required;
1751 //assert(config.unallocated_ib_mem_words >=0);
1752 	*flags |= INPUT_SYSTEM_CFG_FLAG_SET;
1753 	return INPUT_SYSTEM_ERR_NO_ERROR;
1754 }
1755 
1756 // Test flags and set structure.
1757 static input_system_err_t input_system_multiplexer_cfg(
1758     input_system_multiplex_t *const lhs,
1759     const input_system_multiplex_t		rhs,
1760     input_system_config_flags_t *const flags)
1761 {
1762 	assert(lhs);
1763 	assert(flags);
1764 
1765 	if ((*flags) & INPUT_SYSTEM_CFG_FLAG_BLOCKED) {
1766 		*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1767 		return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1768 	}
1769 
1770 	if ((*flags) & INPUT_SYSTEM_CFG_FLAG_SET) {
1771 		// Check for consistency with already set value.
1772 		if ((*lhs) == (rhs)) {
1773 			return INPUT_SYSTEM_ERR_NO_ERROR;
1774 		} else {
1775 			*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1776 			return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1777 		}
1778 	}
1779 	// Check the value (individually).
1780 	if (rhs >= N_INPUT_SYSTEM_MULTIPLEX) {
1781 		*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1782 		return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
1783 	}
1784 	// Set the value.
1785 	*lhs = rhs;
1786 
1787 	*flags |= INPUT_SYSTEM_CFG_FLAG_SET;
1788 	return INPUT_SYSTEM_ERR_NO_ERROR;
1789 }
1790 #endif
1791