xref: /linux/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/input_system.c (revision 6fd600d742744dc7ef7fc65ca26daa2b1163158a)
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 
19 #include "input_system.h"
20 #include <type_support.h>
21 #include "gp_device.h"
22 
23 #include "assert_support.h"
24 
25 #ifndef __INLINE_INPUT_SYSTEM__
26 #include "input_system_private.h"
27 #endif /* __INLINE_INPUT_SYSTEM__ */
28 
29 #define ZERO (0x0)
30 #define ONE  (1U)
31 
32 static const isp2400_ib_buffer_t   IB_BUFFER_NULL = {0, 0, 0 };
33 
34 static input_system_err_t input_system_configure_channel(
35     const channel_cfg_t		channel);
36 
37 static input_system_err_t input_system_configure_channel_sensor(
38     const channel_cfg_t		channel);
39 
40 static input_system_err_t input_buffer_configuration(void);
41 
42 static input_system_err_t configuration_to_registers(void);
43 
44 static void receiver_rst(const rx_ID_t ID);
45 static void input_system_network_rst(const input_system_ID_t ID);
46 
47 static void capture_unit_configure(
48     const input_system_ID_t			ID,
49     const sub_system_ID_t			sub_id,
50     const isp2400_ib_buffer_t *const cfg);
51 
52 static void acquisition_unit_configure(
53     const input_system_ID_t			ID,
54     const sub_system_ID_t			sub_id,
55     const isp2400_ib_buffer_t *const cfg);
56 
57 static void ctrl_unit_configure(
58     const input_system_ID_t			ID,
59     const sub_system_ID_t			sub_id,
60     const ctrl_unit_cfg_t *const cfg);
61 
62 static void input_system_network_configure(
63     const input_system_ID_t			ID,
64     const input_system_network_cfg_t *const cfg);
65 
66 // MW: CSI is previously named as "rx" short for "receiver"
67 static input_system_err_t set_csi_cfg(
68     csi_cfg_t *const lhs,
69     const csi_cfg_t *const rhs,
70     input_system_config_flags_t *const flags);
71 
72 static input_system_err_t set_source_type(
73     input_system_source_t *const lhs,
74     const input_system_source_t				rhs,
75     input_system_config_flags_t *const flags);
76 
77 static input_system_err_t input_system_multiplexer_cfg(
78     input_system_multiplex_t *const lhs,
79     const input_system_multiplex_t			rhs,
80     input_system_config_flags_t *const flags);
81 
82 static void gp_device_rst(const gp_device_ID_t		ID);
83 
84 static void input_selector_cfg_for_sensor(const gp_device_ID_t	ID);
85 
86 static void input_switch_rst(const gp_device_ID_t	ID);
87 
88 static void input_switch_cfg(
89     const gp_device_ID_t				ID,
90     const input_switch_cfg_t *const cfg
91 );
92 
receiver_set_compression(const rx_ID_t ID,const unsigned int cfg_ID,const mipi_compressor_t comp,const mipi_predictor_t pred)93 void receiver_set_compression(
94     const rx_ID_t			ID,
95     const unsigned int		cfg_ID,
96     const mipi_compressor_t		comp,
97     const mipi_predictor_t		pred)
98 {
99 	const unsigned int		field_id = cfg_ID % N_MIPI_FORMAT_CUSTOM;
100 	const unsigned int		ch_id = cfg_ID / N_MIPI_FORMAT_CUSTOM;
101 	hrt_data			val;
102 	hrt_address			addr = 0;
103 	hrt_data			reg;
104 
105 	assert(ID < N_RX_ID);
106 	assert(cfg_ID < N_MIPI_COMPRESSOR_CONTEXT);
107 	assert(field_id < N_MIPI_FORMAT_CUSTOM);
108 	assert(ch_id < N_RX_CHANNEL_ID);
109 	assert(comp < N_MIPI_COMPRESSOR_METHODS);
110 	assert(pred < N_MIPI_PREDICTOR_TYPES);
111 
112 	val = (((uint8_t)pred) << 3) | comp;
113 
114 	switch (ch_id) {
115 	case 0:
116 		addr = ((field_id < 6) ? _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC0_REG0_IDX :
117 			_HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC0_REG1_IDX);
118 		break;
119 	case 1:
120 		addr = ((field_id < 6) ? _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC1_REG0_IDX :
121 			_HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC1_REG1_IDX);
122 		break;
123 	case 2:
124 		addr = ((field_id < 6) ? _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC2_REG0_IDX :
125 			_HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC2_REG1_IDX);
126 		break;
127 	case 3:
128 		addr = ((field_id < 6) ? _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC3_REG0_IDX :
129 			_HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC3_REG1_IDX);
130 		break;
131 	default:
132 		/* should not happen */
133 		assert(false);
134 		return;
135 	}
136 
137 	reg = ((field_id < 6) ? (val << (field_id * 5)) : (val << ((
138 		    field_id - 6) * 5)));
139 	receiver_reg_store(ID, addr, reg);
140 }
141 
receiver_port_enable(const rx_ID_t ID,const enum mipi_port_id port_ID,const bool cnd)142 void receiver_port_enable(
143     const rx_ID_t			ID,
144     const enum mipi_port_id		port_ID,
145     const bool			cnd)
146 {
147 	hrt_data	reg = receiver_port_reg_load(ID, port_ID,
148 			  _HRT_CSS_RECEIVER_DEVICE_READY_REG_IDX);
149 
150 	if (cnd) {
151 		reg |= 0x01;
152 	} else {
153 		reg &= ~0x01;
154 	}
155 
156 	receiver_port_reg_store(ID, port_ID,
157 				_HRT_CSS_RECEIVER_DEVICE_READY_REG_IDX, reg);
158 }
159 
is_receiver_port_enabled(const rx_ID_t ID,const enum mipi_port_id port_ID)160 bool is_receiver_port_enabled(
161     const rx_ID_t			ID,
162     const enum mipi_port_id		port_ID)
163 {
164 	hrt_data	reg = receiver_port_reg_load(ID, port_ID,
165 			  _HRT_CSS_RECEIVER_DEVICE_READY_REG_IDX);
166 	return ((reg & 0x01) != 0);
167 }
168 
receiver_irq_enable(const rx_ID_t ID,const enum mipi_port_id port_ID,const rx_irq_info_t irq_info)169 void receiver_irq_enable(
170     const rx_ID_t			ID,
171     const enum mipi_port_id		port_ID,
172     const rx_irq_info_t		irq_info)
173 {
174 	receiver_port_reg_store(ID,
175 				port_ID, _HRT_CSS_RECEIVER_IRQ_ENABLE_REG_IDX, irq_info);
176 }
177 
receiver_get_irq_info(const rx_ID_t ID,const enum mipi_port_id port_ID)178 rx_irq_info_t receiver_get_irq_info(
179     const rx_ID_t			ID,
180     const enum mipi_port_id		port_ID)
181 {
182 	return receiver_port_reg_load(ID,
183 				      port_ID, _HRT_CSS_RECEIVER_IRQ_STATUS_REG_IDX);
184 }
185 
receiver_irq_clear(const rx_ID_t ID,const enum mipi_port_id port_ID,const rx_irq_info_t irq_info)186 void receiver_irq_clear(
187     const rx_ID_t			ID,
188     const enum mipi_port_id		port_ID,
189     const rx_irq_info_t		irq_info)
190 {
191 	receiver_port_reg_store(ID,
192 				port_ID, _HRT_CSS_RECEIVER_IRQ_STATUS_REG_IDX, irq_info);
193 }
194 
195 // MW: "2400" in the name is not good, but this is to avoid a naming conflict
196 static input_system_cfg2400_t config;
197 
receiver_rst(const rx_ID_t ID)198 static void receiver_rst(
199     const rx_ID_t				ID)
200 {
201 	enum mipi_port_id		port_id;
202 
203 	assert(ID < N_RX_ID);
204 
205 // Disable all ports.
206 	for (port_id = MIPI_PORT0_ID; port_id < N_MIPI_PORT_ID; port_id++) {
207 		receiver_port_enable(ID, port_id, false);
208 	}
209 
210 	// AM: Additional actions for stopping receiver?
211 }
212 
213 //Single function to reset all the devices mapped via GP_DEVICE.
gp_device_rst(const gp_device_ID_t ID)214 static void gp_device_rst(const gp_device_ID_t		ID)
215 {
216 	assert(ID < N_GP_DEVICE_ID);
217 
218 	gp_device_reg_store(ID, _REG_GP_SYNCGEN_ENABLE_ADDR, ZERO);
219 	// gp_device_reg_store(ID, _REG_GP_SYNCGEN_FREE_RUNNING_ADDR, ZERO);
220 	// gp_device_reg_store(ID, _REG_GP_SYNCGEN_PAUSE_ADDR, ONE);
221 	// gp_device_reg_store(ID, _REG_GP_NR_FRAMES_ADDR, ZERO);
222 	// gp_device_reg_store(ID, _REG_GP_SYNGEN_NR_PIX_ADDR, ZERO);
223 	// gp_device_reg_store(ID, _REG_GP_SYNGEN_NR_PIX_ADDR, ZERO);
224 	// gp_device_reg_store(ID, _REG_GP_SYNGEN_NR_LINES_ADDR, ZERO);
225 	// gp_device_reg_store(ID, _REG_GP_SYNGEN_HBLANK_CYCLES_ADDR, ZERO);
226 	// gp_device_reg_store(ID, _REG_GP_SYNGEN_VBLANK_CYCLES_ADDR, ZERO);
227 // AM: Following calls cause strange warnings. Probably they should not be initialized.
228 //	gp_device_reg_store(ID, _REG_GP_ISEL_SOF_ADDR, ZERO);
229 //	gp_device_reg_store(ID, _REG_GP_ISEL_EOF_ADDR, ZERO);
230 //	gp_device_reg_store(ID, _REG_GP_ISEL_SOL_ADDR, ZERO);
231 //	gp_device_reg_store(ID, _REG_GP_ISEL_EOL_ADDR, ZERO);
232 	gp_device_reg_store(ID, _REG_GP_ISEL_LFSR_ENABLE_ADDR, ZERO);
233 	gp_device_reg_store(ID, _REG_GP_ISEL_LFSR_ENABLE_B_ADDR, ZERO);
234 	gp_device_reg_store(ID, _REG_GP_ISEL_LFSR_RESET_VALUE_ADDR, ZERO);
235 	gp_device_reg_store(ID, _REG_GP_ISEL_TPG_ENABLE_ADDR, ZERO);
236 	gp_device_reg_store(ID, _REG_GP_ISEL_TPG_ENABLE_B_ADDR, ZERO);
237 	gp_device_reg_store(ID, _REG_GP_ISEL_HOR_CNT_MASK_ADDR, ZERO);
238 	gp_device_reg_store(ID, _REG_GP_ISEL_VER_CNT_MASK_ADDR, ZERO);
239 	gp_device_reg_store(ID, _REG_GP_ISEL_XY_CNT_MASK_ADDR, ZERO);
240 	gp_device_reg_store(ID, _REG_GP_ISEL_HOR_CNT_DELTA_ADDR, ZERO);
241 	gp_device_reg_store(ID, _REG_GP_ISEL_VER_CNT_DELTA_ADDR, ZERO);
242 	gp_device_reg_store(ID, _REG_GP_ISEL_TPG_MODE_ADDR, ZERO);
243 	gp_device_reg_store(ID, _REG_GP_ISEL_TPG_RED1_ADDR, ZERO);
244 	gp_device_reg_store(ID, _REG_GP_ISEL_TPG_GREEN1_ADDR, ZERO);
245 	gp_device_reg_store(ID, _REG_GP_ISEL_TPG_BLUE1_ADDR, ZERO);
246 	gp_device_reg_store(ID, _REG_GP_ISEL_TPG_RED2_ADDR, ZERO);
247 	gp_device_reg_store(ID, _REG_GP_ISEL_TPG_GREEN2_ADDR, ZERO);
248 	gp_device_reg_store(ID, _REG_GP_ISEL_TPG_BLUE2_ADDR, ZERO);
249 	//gp_device_reg_store(ID, _REG_GP_ISEL_CH_ID_ADDR, ZERO);
250 	//gp_device_reg_store(ID, _REG_GP_ISEL_FMT_TYPE_ADDR, ZERO);
251 	gp_device_reg_store(ID, _REG_GP_ISEL_DATA_SEL_ADDR, ZERO);
252 	gp_device_reg_store(ID, _REG_GP_ISEL_SBAND_SEL_ADDR, ZERO);
253 	gp_device_reg_store(ID, _REG_GP_ISEL_SYNC_SEL_ADDR, ZERO);
254 	//	gp_device_reg_store(ID, _REG_GP_SYNCGEN_HOR_CNT_ADDR, ZERO);
255 	//	gp_device_reg_store(ID, _REG_GP_SYNCGEN_VER_CNT_ADDR, ZERO);
256 	//	gp_device_reg_store(ID, _REG_GP_SYNCGEN_FRAME_CNT_ADDR, ZERO);
257 	gp_device_reg_store(ID, _REG_GP_SOFT_RESET_ADDR,
258 			    ZERO); // AM: Maybe this soft reset is not safe.
259 }
260 
input_selector_cfg_for_sensor(const gp_device_ID_t ID)261 static void input_selector_cfg_for_sensor(const gp_device_ID_t ID)
262 {
263 	assert(ID < N_GP_DEVICE_ID);
264 
265 	gp_device_reg_store(ID, _REG_GP_ISEL_SOF_ADDR, ONE);
266 	gp_device_reg_store(ID, _REG_GP_ISEL_EOF_ADDR, ONE);
267 	gp_device_reg_store(ID, _REG_GP_ISEL_SOL_ADDR, ONE);
268 	gp_device_reg_store(ID, _REG_GP_ISEL_EOL_ADDR, ONE);
269 	gp_device_reg_store(ID, _REG_GP_ISEL_CH_ID_ADDR, ZERO);
270 	gp_device_reg_store(ID, _REG_GP_ISEL_FMT_TYPE_ADDR, ZERO);
271 	gp_device_reg_store(ID, _REG_GP_ISEL_DATA_SEL_ADDR, ZERO);
272 	gp_device_reg_store(ID, _REG_GP_ISEL_SBAND_SEL_ADDR, ZERO);
273 	gp_device_reg_store(ID, _REG_GP_ISEL_SYNC_SEL_ADDR, ZERO);
274 	gp_device_reg_store(ID, _REG_GP_SOFT_RESET_ADDR, ZERO);
275 }
276 
input_switch_rst(const gp_device_ID_t ID)277 static void input_switch_rst(const gp_device_ID_t ID)
278 {
279 	int addr;
280 
281 	assert(ID < N_GP_DEVICE_ID);
282 
283 	// Initialize the data&hsync LUT.
284 	for (addr = _REG_GP_IFMT_input_switch_lut_reg0;
285 	     addr <= _REG_GP_IFMT_input_switch_lut_reg7; addr += SIZEOF_HRT_REG) {
286 		gp_device_reg_store(ID, addr, ZERO);
287 	}
288 
289 	// Initialize the vsync LUT.
290 	gp_device_reg_store(ID,
291 			    _REG_GP_IFMT_input_switch_fsync_lut,
292 			    ZERO);
293 }
294 
input_switch_cfg(const gp_device_ID_t ID,const input_switch_cfg_t * const cfg)295 static void input_switch_cfg(
296     const gp_device_ID_t			ID,
297     const input_switch_cfg_t *const cfg)
298 {
299 	int addr_offset;
300 
301 	assert(ID < N_GP_DEVICE_ID);
302 	assert(cfg);
303 
304 	// Initialize the data&hsync LUT.
305 	for (addr_offset = 0; addr_offset < N_RX_CHANNEL_ID * 2; addr_offset++) {
306 		assert(addr_offset * SIZEOF_HRT_REG + _REG_GP_IFMT_input_switch_lut_reg0 <=
307 		       _REG_GP_IFMT_input_switch_lut_reg7);
308 		gp_device_reg_store(ID,
309 				    _REG_GP_IFMT_input_switch_lut_reg0 + addr_offset * SIZEOF_HRT_REG,
310 				    cfg->hsync_data_reg[addr_offset]);
311 	}
312 
313 	// Initialize the vsync LUT.
314 	gp_device_reg_store(ID,
315 			    _REG_GP_IFMT_input_switch_fsync_lut,
316 			    cfg->vsync_data_reg);
317 }
318 
input_system_network_rst(const input_system_ID_t ID)319 static void input_system_network_rst(const input_system_ID_t ID)
320 {
321 	unsigned int sub_id;
322 
323 	// Reset all 3 multicasts.
324 	input_system_sub_system_reg_store(ID,
325 					  GPREGS_UNIT0_ID,
326 					  HIVE_ISYS_GPREG_MULTICAST_A_IDX,
327 					  INPUT_SYSTEM_DISCARD_ALL);
328 	input_system_sub_system_reg_store(ID,
329 					  GPREGS_UNIT0_ID,
330 					  HIVE_ISYS_GPREG_MULTICAST_B_IDX,
331 					  INPUT_SYSTEM_DISCARD_ALL);
332 	input_system_sub_system_reg_store(ID,
333 					  GPREGS_UNIT0_ID,
334 					  HIVE_ISYS_GPREG_MULTICAST_C_IDX,
335 					  INPUT_SYSTEM_DISCARD_ALL);
336 
337 	// Reset stream mux.
338 	input_system_sub_system_reg_store(ID,
339 					  GPREGS_UNIT0_ID,
340 					  HIVE_ISYS_GPREG_MUX_IDX,
341 					  N_INPUT_SYSTEM_MULTIPLEX);
342 
343 	// Reset 3 capture units.
344 	for (sub_id = CAPTURE_UNIT0_ID; sub_id < CAPTURE_UNIT0_ID + N_CAPTURE_UNIT_ID;
345 	     sub_id++) {
346 		input_system_sub_system_reg_store(ID,
347 						  sub_id,
348 						  CAPT_INIT_REG_ID,
349 						  1U << CAPT_INIT_RST_REG_BIT);
350 	}
351 
352 	// Reset acquisition unit.
353 	for (sub_id = ACQUISITION_UNIT0_ID;
354 	     sub_id < ACQUISITION_UNIT0_ID + N_ACQUISITION_UNIT_ID; sub_id++) {
355 		input_system_sub_system_reg_store(ID,
356 						  sub_id,
357 						  ACQ_INIT_REG_ID,
358 						  1U << ACQ_INIT_RST_REG_BIT);
359 	}
360 
361 	// DMA unit reset is not needed.
362 
363 	// Reset controller units.
364 	// NB: In future we need to keep part of ctrl_state for split capture and
365 	for (sub_id = CTRL_UNIT0_ID; sub_id < CTRL_UNIT0_ID + N_CTRL_UNIT_ID;
366 	     sub_id++) {
367 		input_system_sub_system_reg_store(ID,
368 						  sub_id,
369 						  ISYS_CTRL_INIT_REG_ID,
370 						  1U); //AM: Is there any named constant?
371 	}
372 }
373 
374 // Function that resets current configuration.
input_system_configuration_reset(void)375 input_system_err_t input_system_configuration_reset(void)
376 {
377 	unsigned int i;
378 
379 	receiver_rst(RX0_ID);
380 
381 	input_system_network_rst(INPUT_SYSTEM0_ID);
382 
383 	gp_device_rst(GP_DEVICE0_ID);
384 
385 	input_switch_rst(GP_DEVICE0_ID);
386 
387 	//target_rst();
388 
389 	// Reset IRQ_CTRLs.
390 
391 	// Reset configuration data structures.
392 	for (i = 0; i < N_CHANNELS; i++) {
393 		config.ch_flags[i] = INPUT_SYSTEM_CFG_FLAG_RESET;
394 		config.target_isp_flags[i] = INPUT_SYSTEM_CFG_FLAG_RESET;
395 		config.target_sp_flags[i] = INPUT_SYSTEM_CFG_FLAG_RESET;
396 		config.target_strm2mem_flags[i] = INPUT_SYSTEM_CFG_FLAG_RESET;
397 	}
398 
399 	for (i = 0; i < N_CSI_PORTS; i++) {
400 		config.csi_buffer_flags[i]	 = INPUT_SYSTEM_CFG_FLAG_RESET;
401 		config.multicast[i]		 = INPUT_SYSTEM_DISCARD_ALL;
402 	}
403 
404 	config.source_type_flags				 = INPUT_SYSTEM_CFG_FLAG_RESET;
405 	config.acquisition_buffer_unique_flags	 = INPUT_SYSTEM_CFG_FLAG_RESET;
406 	config.unallocated_ib_mem_words			 = IB_CAPACITY_IN_WORDS;
407 	//config.acq_allocated_ib_mem_words		 = 0;
408 
409 	// Set the start of the session cofiguration.
410 	config.session_flags = INPUT_SYSTEM_CFG_FLAG_REQUIRED;
411 
412 	return INPUT_SYSTEM_ERR_NO_ERROR;
413 }
414 
415 // MW: Comments are good, but doxygen is required, place it at the declaration
416 // Function that appends the channel to current configuration.
input_system_configure_channel(const channel_cfg_t channel)417 static input_system_err_t input_system_configure_channel(
418     const channel_cfg_t		channel)
419 {
420 	input_system_err_t error = INPUT_SYSTEM_ERR_NO_ERROR;
421 	// Check if channel is not already configured.
422 	if (config.ch_flags[channel.ch_id] & INPUT_SYSTEM_CFG_FLAG_SET) {
423 		return INPUT_SYSTEM_ERR_CHANNEL_ALREADY_SET;
424 	} else {
425 		switch (channel.source_type) {
426 		case INPUT_SYSTEM_SOURCE_SENSOR:
427 			error = input_system_configure_channel_sensor(channel);
428 			break;
429 		case INPUT_SYSTEM_SOURCE_PRBS:
430 		case INPUT_SYSTEM_SOURCE_FIFO:
431 		default:
432 			return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
433 		}
434 
435 		if (error != INPUT_SYSTEM_ERR_NO_ERROR) return error;
436 		// Input switch channel configurations must be combined in united config.
437 		config.input_switch_cfg.hsync_data_reg[channel.source_cfg.csi_cfg.csi_port * 2]
438 		    =
439 			channel.target_cfg.input_switch_channel_cfg.hsync_data_reg[0];
440 		config.input_switch_cfg.hsync_data_reg[channel.source_cfg.csi_cfg.csi_port * 2 +
441 											   1] =
442 							       channel.target_cfg.input_switch_channel_cfg.hsync_data_reg[1];
443 		config.input_switch_cfg.vsync_data_reg |=
444 		    (channel.target_cfg.input_switch_channel_cfg.vsync_data_reg & 0x7) <<
445 		    (channel.source_cfg.csi_cfg.csi_port * 3);
446 
447 		// Other targets are just copied and marked as set.
448 		config.target_isp[channel.source_cfg.csi_cfg.csi_port] =
449 		    channel.target_cfg.target_isp_cfg;
450 		config.target_sp[channel.source_cfg.csi_cfg.csi_port] =
451 		    channel.target_cfg.target_sp_cfg;
452 		config.target_strm2mem[channel.source_cfg.csi_cfg.csi_port] =
453 		    channel.target_cfg.target_strm2mem_cfg;
454 		config.target_isp_flags[channel.source_cfg.csi_cfg.csi_port] |=
455 		    INPUT_SYSTEM_CFG_FLAG_SET;
456 		config.target_sp_flags[channel.source_cfg.csi_cfg.csi_port] |=
457 		    INPUT_SYSTEM_CFG_FLAG_SET;
458 		config.target_strm2mem_flags[channel.source_cfg.csi_cfg.csi_port] |=
459 		    INPUT_SYSTEM_CFG_FLAG_SET;
460 
461 		config.ch_flags[channel.ch_id] = INPUT_SYSTEM_CFG_FLAG_SET;
462 	}
463 	return INPUT_SYSTEM_ERR_NO_ERROR;
464 }
465 
466 // Function that partitions input buffer space with determining addresses.
input_buffer_configuration(void)467 static input_system_err_t input_buffer_configuration(void)
468 {
469 	u32 current_address    = 0;
470 	u32 unallocated_memory = IB_CAPACITY_IN_WORDS;
471 
472 	isp2400_ib_buffer_t	candidate_buffer_acq  = IB_BUFFER_NULL;
473 	u32 size_requested;
474 	input_system_config_flags_t	acq_already_specified = INPUT_SYSTEM_CFG_FLAG_RESET;
475 	input_system_csi_port_t port;
476 
477 	for (port = INPUT_SYSTEM_PORT_A; port < N_INPUT_SYSTEM_PORTS; port++) {
478 		csi_cfg_t source = config.csi_value[port];//.csi_cfg;
479 
480 		if (config.csi_flags[port] & INPUT_SYSTEM_CFG_FLAG_SET) {
481 			// Check and set csi buffer in input buffer.
482 			switch (source.buffering_mode) {
483 			case INPUT_SYSTEM_FIFO_CAPTURE:
484 			case INPUT_SYSTEM_XMEM_ACQUIRE:
485 				config.csi_buffer_flags[port] =
486 				    INPUT_SYSTEM_CFG_FLAG_BLOCKED; // Well, not used.
487 				break;
488 
489 			case INPUT_SYSTEM_FIFO_CAPTURE_WITH_COUNTING:
490 			case INPUT_SYSTEM_SRAM_BUFFERING:
491 			case INPUT_SYSTEM_XMEM_BUFFERING:
492 			case INPUT_SYSTEM_XMEM_CAPTURE:
493 				size_requested = source.csi_buffer.mem_reg_size *
494 						 source.csi_buffer.nof_mem_regs;
495 				if (source.csi_buffer.mem_reg_size > 0
496 				    && source.csi_buffer.nof_mem_regs > 0
497 				    && size_requested <= unallocated_memory
498 				   ) {
499 					config.csi_buffer[port].mem_reg_addr = current_address;
500 					config.csi_buffer[port].mem_reg_size = source.csi_buffer.mem_reg_size;
501 					config.csi_buffer[port].nof_mem_regs = source.csi_buffer.nof_mem_regs;
502 					current_address		+= size_requested;
503 					unallocated_memory	-= size_requested;
504 					config.csi_buffer_flags[port] = INPUT_SYSTEM_CFG_FLAG_SET;
505 				} else {
506 					config.csi_buffer_flags[port] |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
507 					return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
508 				}
509 				break;
510 
511 			default:
512 				config.csi_buffer_flags[port] |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
513 				return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
514 			}
515 
516 			// Check acquisition buffer specified but set it later since it has to be unique.
517 			switch (source.buffering_mode) {
518 			case INPUT_SYSTEM_FIFO_CAPTURE:
519 			case INPUT_SYSTEM_SRAM_BUFFERING:
520 			case INPUT_SYSTEM_XMEM_CAPTURE:
521 				// Nothing to do.
522 				break;
523 
524 			case INPUT_SYSTEM_FIFO_CAPTURE_WITH_COUNTING:
525 			case INPUT_SYSTEM_XMEM_BUFFERING:
526 			case INPUT_SYSTEM_XMEM_ACQUIRE:
527 				if (acq_already_specified == INPUT_SYSTEM_CFG_FLAG_RESET) {
528 					size_requested = source.acquisition_buffer.mem_reg_size
529 							 * source.acquisition_buffer.nof_mem_regs;
530 					if (source.acquisition_buffer.mem_reg_size > 0
531 					    && source.acquisition_buffer.nof_mem_regs > 0
532 					    && size_requested <= unallocated_memory
533 					   ) {
534 						candidate_buffer_acq = source.acquisition_buffer;
535 						acq_already_specified = INPUT_SYSTEM_CFG_FLAG_SET;
536 					}
537 				} else {
538 					// Check if specified acquisition buffer is the same as specified before.
539 					if (source.acquisition_buffer.mem_reg_size != candidate_buffer_acq.mem_reg_size
540 					    || source.acquisition_buffer.nof_mem_regs !=  candidate_buffer_acq.nof_mem_regs
541 					   ) {
542 						config.acquisition_buffer_unique_flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
543 						return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
544 					}
545 				}
546 				break;
547 
548 			default:
549 				return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
550 			}
551 		} else {
552 			config.csi_buffer_flags[port] = INPUT_SYSTEM_CFG_FLAG_BLOCKED;
553 		}
554 	} // end of for ( port )
555 
556 	// Set the acquisition buffer at the end.
557 	size_requested = candidate_buffer_acq.mem_reg_size *
558 			 candidate_buffer_acq.nof_mem_regs;
559 	if (acq_already_specified == INPUT_SYSTEM_CFG_FLAG_SET
560 	    && size_requested <= unallocated_memory) {
561 		config.acquisition_buffer_unique.mem_reg_addr = current_address;
562 		config.acquisition_buffer_unique.mem_reg_size =
563 		    candidate_buffer_acq.mem_reg_size;
564 		config.acquisition_buffer_unique.nof_mem_regs =
565 		    candidate_buffer_acq.nof_mem_regs;
566 		current_address		+= size_requested;
567 		unallocated_memory	-= size_requested;
568 		config.acquisition_buffer_unique_flags = INPUT_SYSTEM_CFG_FLAG_SET;
569 
570 		assert(current_address <= IB_CAPACITY_IN_WORDS);
571 	}
572 
573 	return INPUT_SYSTEM_ERR_NO_ERROR;
574 }
575 
capture_unit_configure(const input_system_ID_t ID,const sub_system_ID_t sub_id,const isp2400_ib_buffer_t * const cfg)576 static void capture_unit_configure(
577     const input_system_ID_t			ID,
578     const sub_system_ID_t			sub_id,
579     const isp2400_ib_buffer_t *const cfg)
580 {
581 	assert(ID < N_INPUT_SYSTEM_ID);
582 	assert(/*(sub_id >= CAPTURE_UNIT0_ID) &&*/ (sub_id <=
583 		CAPTURE_UNIT2_ID)); // Commented part is always true.
584 	assert(cfg);
585 
586 	input_system_sub_system_reg_store(ID,
587 					  sub_id,
588 					  CAPT_START_ADDR_REG_ID,
589 					  cfg->mem_reg_addr);
590 	input_system_sub_system_reg_store(ID,
591 					  sub_id,
592 					  CAPT_MEM_REGION_SIZE_REG_ID,
593 					  cfg->mem_reg_size);
594 	input_system_sub_system_reg_store(ID,
595 					  sub_id,
596 					  CAPT_NUM_MEM_REGIONS_REG_ID,
597 					  cfg->nof_mem_regs);
598 }
599 
acquisition_unit_configure(const input_system_ID_t ID,const sub_system_ID_t sub_id,const isp2400_ib_buffer_t * const cfg)600 static void acquisition_unit_configure(
601     const input_system_ID_t			ID,
602     const sub_system_ID_t			sub_id,
603     const isp2400_ib_buffer_t *const cfg)
604 {
605 	assert(ID < N_INPUT_SYSTEM_ID);
606 	assert(sub_id == ACQUISITION_UNIT0_ID);
607 	assert(cfg);
608 
609 	input_system_sub_system_reg_store(ID,
610 					  sub_id,
611 					  ACQ_START_ADDR_REG_ID,
612 					  cfg->mem_reg_addr);
613 	input_system_sub_system_reg_store(ID,
614 					  sub_id,
615 					  ACQ_NUM_MEM_REGIONS_REG_ID,
616 					  cfg->nof_mem_regs);
617 	input_system_sub_system_reg_store(ID,
618 					  sub_id,
619 					  ACQ_MEM_REGION_SIZE_REG_ID,
620 					  cfg->mem_reg_size);
621 }
622 
ctrl_unit_configure(const input_system_ID_t ID,const sub_system_ID_t sub_id,const ctrl_unit_cfg_t * const cfg)623 static void ctrl_unit_configure(
624     const input_system_ID_t			ID,
625     const sub_system_ID_t			sub_id,
626     const ctrl_unit_cfg_t *const cfg)
627 {
628 	assert(ID < N_INPUT_SYSTEM_ID);
629 	assert(sub_id == CTRL_UNIT0_ID);
630 	assert(cfg);
631 
632 	input_system_sub_system_reg_store(ID,
633 					  sub_id,
634 					  ISYS_CTRL_CAPT_START_ADDR_A_REG_ID,
635 					  cfg->buffer_mipi[CAPTURE_UNIT0_ID].mem_reg_addr);
636 	input_system_sub_system_reg_store(ID,
637 					  sub_id,
638 					  ISYS_CTRL_CAPT_MEM_REGION_SIZE_A_REG_ID,
639 					  cfg->buffer_mipi[CAPTURE_UNIT0_ID].mem_reg_size);
640 	input_system_sub_system_reg_store(ID,
641 					  sub_id,
642 					  ISYS_CTRL_CAPT_NUM_MEM_REGIONS_A_REG_ID,
643 					  cfg->buffer_mipi[CAPTURE_UNIT0_ID].nof_mem_regs);
644 
645 	input_system_sub_system_reg_store(ID,
646 					  sub_id,
647 					  ISYS_CTRL_CAPT_START_ADDR_B_REG_ID,
648 					  cfg->buffer_mipi[CAPTURE_UNIT1_ID].mem_reg_addr);
649 	input_system_sub_system_reg_store(ID,
650 					  sub_id,
651 					  ISYS_CTRL_CAPT_MEM_REGION_SIZE_B_REG_ID,
652 					  cfg->buffer_mipi[CAPTURE_UNIT1_ID].mem_reg_size);
653 	input_system_sub_system_reg_store(ID,
654 					  sub_id,
655 					  ISYS_CTRL_CAPT_NUM_MEM_REGIONS_B_REG_ID,
656 					  cfg->buffer_mipi[CAPTURE_UNIT1_ID].nof_mem_regs);
657 
658 	input_system_sub_system_reg_store(ID,
659 					  sub_id,
660 					  ISYS_CTRL_CAPT_START_ADDR_C_REG_ID,
661 					  cfg->buffer_mipi[CAPTURE_UNIT2_ID].mem_reg_addr);
662 	input_system_sub_system_reg_store(ID,
663 					  sub_id,
664 					  ISYS_CTRL_CAPT_MEM_REGION_SIZE_C_REG_ID,
665 					  cfg->buffer_mipi[CAPTURE_UNIT2_ID].mem_reg_size);
666 	input_system_sub_system_reg_store(ID,
667 					  sub_id,
668 					  ISYS_CTRL_CAPT_NUM_MEM_REGIONS_C_REG_ID,
669 					  cfg->buffer_mipi[CAPTURE_UNIT2_ID].nof_mem_regs);
670 
671 	input_system_sub_system_reg_store(ID,
672 					  sub_id,
673 					  ISYS_CTRL_ACQ_START_ADDR_REG_ID,
674 					  cfg->buffer_acquire[ACQUISITION_UNIT0_ID - ACQUISITION_UNIT0_ID].mem_reg_addr);
675 	input_system_sub_system_reg_store(ID,
676 					  sub_id,
677 					  ISYS_CTRL_ACQ_MEM_REGION_SIZE_REG_ID,
678 					  cfg->buffer_acquire[ACQUISITION_UNIT0_ID - ACQUISITION_UNIT0_ID].mem_reg_size);
679 	input_system_sub_system_reg_store(ID,
680 					  sub_id,
681 					  ISYS_CTRL_ACQ_NUM_MEM_REGIONS_REG_ID,
682 					  cfg->buffer_acquire[ACQUISITION_UNIT0_ID - ACQUISITION_UNIT0_ID].nof_mem_regs);
683 	input_system_sub_system_reg_store(ID,
684 					  sub_id,
685 					  ISYS_CTRL_CAPT_RESERVE_ONE_MEM_REGION_REG_ID,
686 					  0);
687 }
688 
input_system_network_configure(const input_system_ID_t ID,const input_system_network_cfg_t * const cfg)689 static void input_system_network_configure(
690     const input_system_ID_t				ID,
691     const input_system_network_cfg_t *const cfg)
692 {
693 	u32 sub_id;
694 
695 	assert(ID < N_INPUT_SYSTEM_ID);
696 	assert(cfg);
697 
698 	// Set all 3 multicasts.
699 	input_system_sub_system_reg_store(ID,
700 					  GPREGS_UNIT0_ID,
701 					  HIVE_ISYS_GPREG_MULTICAST_A_IDX,
702 					  cfg->multicast_cfg[CAPTURE_UNIT0_ID]);
703 	input_system_sub_system_reg_store(ID,
704 					  GPREGS_UNIT0_ID,
705 					  HIVE_ISYS_GPREG_MULTICAST_B_IDX,
706 					  cfg->multicast_cfg[CAPTURE_UNIT1_ID]);
707 	input_system_sub_system_reg_store(ID,
708 					  GPREGS_UNIT0_ID,
709 					  HIVE_ISYS_GPREG_MULTICAST_C_IDX,
710 					  cfg->multicast_cfg[CAPTURE_UNIT2_ID]);
711 
712 	// Set stream mux.
713 	input_system_sub_system_reg_store(ID,
714 					  GPREGS_UNIT0_ID,
715 					  HIVE_ISYS_GPREG_MUX_IDX,
716 					  cfg->mux_cfg);
717 
718 	// Set capture units.
719 	for (sub_id = CAPTURE_UNIT0_ID; sub_id < CAPTURE_UNIT0_ID + N_CAPTURE_UNIT_ID;
720 	     sub_id++) {
721 		capture_unit_configure(ID,
722 				       sub_id,
723 				       &cfg->ctrl_unit_cfg[ID].buffer_mipi[sub_id - CAPTURE_UNIT0_ID]);
724 	}
725 
726 	// Set acquisition units.
727 	for (sub_id = ACQUISITION_UNIT0_ID;
728 	     sub_id < ACQUISITION_UNIT0_ID + N_ACQUISITION_UNIT_ID; sub_id++) {
729 		acquisition_unit_configure(ID,
730 					   sub_id,
731 					   &cfg->ctrl_unit_cfg[sub_id - ACQUISITION_UNIT0_ID].buffer_acquire[sub_id -
732 						   ACQUISITION_UNIT0_ID]);
733 	}
734 
735 	// No DMA configuration needed. Ctrl_unit will fully control it.
736 
737 	// Set controller units.
738 	for (sub_id = CTRL_UNIT0_ID; sub_id < CTRL_UNIT0_ID + N_CTRL_UNIT_ID;
739 	     sub_id++) {
740 		ctrl_unit_configure(ID,
741 				    sub_id,
742 				    &cfg->ctrl_unit_cfg[sub_id - CTRL_UNIT0_ID]);
743 	}
744 }
745 
configuration_to_registers(void)746 static input_system_err_t configuration_to_registers(void)
747 {
748 	input_system_network_cfg_t input_system_network_cfg;
749 	int i;
750 
751 	assert(config.source_type_flags & INPUT_SYSTEM_CFG_FLAG_SET);
752 
753 	switch (config.source_type) {
754 	case INPUT_SYSTEM_SOURCE_SENSOR:
755 
756 		// Determine stream multicasts setting based on the mode of csi_cfg_t.
757 		// AM: This should be moved towards earlier function call, e.g. in
758 		// the commit function.
759 		for (i = MIPI_PORT0_ID; i < N_MIPI_PORT_ID; i++) {
760 			if (config.csi_flags[i] & INPUT_SYSTEM_CFG_FLAG_SET) {
761 				switch (config.csi_value[i].buffering_mode) {
762 				case INPUT_SYSTEM_FIFO_CAPTURE:
763 					config.multicast[i] = INPUT_SYSTEM_CSI_BACKEND;
764 					break;
765 
766 				case INPUT_SYSTEM_XMEM_CAPTURE:
767 				case INPUT_SYSTEM_SRAM_BUFFERING:
768 				case INPUT_SYSTEM_XMEM_BUFFERING:
769 					config.multicast[i] = INPUT_SYSTEM_INPUT_BUFFER;
770 					break;
771 
772 				case INPUT_SYSTEM_FIFO_CAPTURE_WITH_COUNTING:
773 					config.multicast[i] = INPUT_SYSTEM_MULTICAST;
774 					break;
775 
776 				case INPUT_SYSTEM_XMEM_ACQUIRE:
777 					config.multicast[i] = INPUT_SYSTEM_DISCARD_ALL;
778 					break;
779 
780 				default:
781 					config.multicast[i] = INPUT_SYSTEM_DISCARD_ALL;
782 					return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
783 					//break;
784 				}
785 			} else {
786 				config.multicast[i] = INPUT_SYSTEM_DISCARD_ALL;
787 			}
788 
789 			input_system_network_cfg.multicast_cfg[i] = config.multicast[i];
790 
791 		} // for
792 
793 		input_system_network_cfg.mux_cfg = config.multiplexer;
794 
795 		input_system_network_cfg.ctrl_unit_cfg[CTRL_UNIT0_ID -
796 						       CTRL_UNIT0_ID].buffer_mipi[CAPTURE_UNIT0_ID] =
797 							       config.csi_buffer[MIPI_PORT0_ID];
798 		input_system_network_cfg.ctrl_unit_cfg[CTRL_UNIT0_ID -
799 						       CTRL_UNIT0_ID].buffer_mipi[CAPTURE_UNIT1_ID] =
800 							       config.csi_buffer[MIPI_PORT1_ID];
801 		input_system_network_cfg.ctrl_unit_cfg[CTRL_UNIT0_ID -
802 						       CTRL_UNIT0_ID].buffer_mipi[CAPTURE_UNIT2_ID] =
803 							       config.csi_buffer[MIPI_PORT2_ID];
804 		input_system_network_cfg.ctrl_unit_cfg[CTRL_UNIT0_ID -
805 						       CTRL_UNIT0_ID].buffer_acquire[ACQUISITION_UNIT0_ID -
806 							       ACQUISITION_UNIT0_ID] =
807 								       config.acquisition_buffer_unique;
808 
809 		// First set input network around CSI receiver.
810 		input_system_network_configure(INPUT_SYSTEM0_ID, &input_system_network_cfg);
811 
812 		// Set the CSI receiver.
813 		//...
814 		break;
815 
816 	case INPUT_SYSTEM_SOURCE_PRBS:
817 	case INPUT_SYSTEM_SOURCE_FIFO:
818 		break;
819 
820 	default:
821 		return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
822 
823 	} // end of switch (source_type)
824 
825 	// Set input selector.
826 	input_selector_cfg_for_sensor(GP_DEVICE0_ID);
827 
828 	// Set input switch.
829 	input_switch_cfg(GP_DEVICE0_ID, &config.input_switch_cfg);
830 
831 	// Set input formatters.
832 	// AM: IF are set dynamically.
833 	return INPUT_SYSTEM_ERR_NO_ERROR;
834 }
835 
836 // Function that applies the whole configuration.
input_system_configuration_commit(void)837 input_system_err_t input_system_configuration_commit(void)
838 {
839 	// The last configuration step is to configure the input buffer.
840 	input_system_err_t error = input_buffer_configuration();
841 
842 	if (error != INPUT_SYSTEM_ERR_NO_ERROR) {
843 		return error;
844 	}
845 
846 	// Translate the whole configuration into registers.
847 	error = configuration_to_registers();
848 	if (error != INPUT_SYSTEM_ERR_NO_ERROR) {
849 		return error;
850 	}
851 
852 	// Translate the whole configuration into ctrl commands etc.
853 
854 	return INPUT_SYSTEM_ERR_NO_ERROR;
855 }
856 
857 // FIFO
858 
input_system_csi_fifo_channel_cfg(u32 ch_id,input_system_csi_port_t port,backend_channel_cfg_t backend_ch,target_cfg2400_t target)859 input_system_err_t	input_system_csi_fifo_channel_cfg(
860     u32		ch_id,
861     input_system_csi_port_t	port,
862     backend_channel_cfg_t	backend_ch,
863     target_cfg2400_t	target
864 )
865 {
866 	channel_cfg_t channel;
867 
868 	channel.ch_id	= ch_id;
869 	channel.backend_ch	= backend_ch;
870 	channel.source_type = INPUT_SYSTEM_SOURCE_SENSOR;
871 	//channel.source
872 	channel.source_cfg.csi_cfg.csi_port			= port;
873 	channel.source_cfg.csi_cfg.buffering_mode	= INPUT_SYSTEM_FIFO_CAPTURE;
874 	channel.source_cfg.csi_cfg.csi_buffer			= IB_BUFFER_NULL;
875 	channel.source_cfg.csi_cfg.acquisition_buffer	= IB_BUFFER_NULL;
876 	channel.source_cfg.csi_cfg.nof_xmem_buffers	= 0;
877 
878 	channel.target_cfg	= target;
879 	return input_system_configure_channel(channel);
880 }
881 
input_system_csi_fifo_channel_with_counting_cfg(u32 ch_id,u32 nof_frames,input_system_csi_port_t port,backend_channel_cfg_t backend_ch,u32 csi_mem_reg_size,u32 csi_nof_mem_regs,target_cfg2400_t target)882 input_system_err_t	input_system_csi_fifo_channel_with_counting_cfg(
883     u32				ch_id,
884     u32				nof_frames,
885     input_system_csi_port_t			port,
886     backend_channel_cfg_t			backend_ch,
887     u32				csi_mem_reg_size,
888     u32				csi_nof_mem_regs,
889     target_cfg2400_t			target
890 )
891 {
892 	channel_cfg_t channel;
893 
894 	channel.ch_id	= ch_id;
895 	channel.backend_ch	= backend_ch;
896 	channel.source_type		= INPUT_SYSTEM_SOURCE_SENSOR;
897 	//channel.source
898 	channel.source_cfg.csi_cfg.csi_port			= port;
899 	channel.source_cfg.csi_cfg.buffering_mode	=
900 	    INPUT_SYSTEM_FIFO_CAPTURE_WITH_COUNTING;
901 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_size		= csi_mem_reg_size;
902 	channel.source_cfg.csi_cfg.csi_buffer.nof_mem_regs		= csi_nof_mem_regs;
903 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_addr		= 0;
904 	channel.source_cfg.csi_cfg.acquisition_buffer			= IB_BUFFER_NULL;
905 	channel.source_cfg.csi_cfg.nof_xmem_buffers	= nof_frames;
906 
907 	channel.target_cfg	= target;
908 	return input_system_configure_channel(channel);
909 }
910 
911 // SRAM
912 
input_system_csi_sram_channel_cfg(u32 ch_id,input_system_csi_port_t port,backend_channel_cfg_t backend_ch,u32 csi_mem_reg_size,u32 csi_nof_mem_regs,target_cfg2400_t target)913 input_system_err_t	input_system_csi_sram_channel_cfg(
914     u32				ch_id,
915     input_system_csi_port_t			port,
916     backend_channel_cfg_t			backend_ch,
917     u32				csi_mem_reg_size,
918     u32				csi_nof_mem_regs,
919     //	uint32_t				acq_mem_reg_size,
920     //	uint32_t				acq_nof_mem_regs,
921     target_cfg2400_t			target
922 )
923 {
924 	channel_cfg_t channel;
925 
926 	channel.ch_id	= ch_id;
927 	channel.backend_ch	= backend_ch;
928 	channel.source_type		= INPUT_SYSTEM_SOURCE_SENSOR;
929 	//channel.source
930 	channel.source_cfg.csi_cfg.csi_port			= port;
931 	channel.source_cfg.csi_cfg.buffering_mode	= INPUT_SYSTEM_SRAM_BUFFERING;
932 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_size		= csi_mem_reg_size;
933 	channel.source_cfg.csi_cfg.csi_buffer.nof_mem_regs		= csi_nof_mem_regs;
934 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_addr		= 0;
935 	channel.source_cfg.csi_cfg.acquisition_buffer			= IB_BUFFER_NULL;
936 	channel.source_cfg.csi_cfg.nof_xmem_buffers	= 0;
937 
938 	channel.target_cfg	= target;
939 	return input_system_configure_channel(channel);
940 }
941 
942 //XMEM
943 
944 // Collects all parameters and puts them in channel_cfg_t.
input_system_csi_xmem_channel_cfg(u32 ch_id,input_system_csi_port_t port,backend_channel_cfg_t backend_ch,u32 csi_mem_reg_size,u32 csi_nof_mem_regs,u32 acq_mem_reg_size,u32 acq_nof_mem_regs,target_cfg2400_t target,uint32_t nof_xmem_buffers)945 input_system_err_t	input_system_csi_xmem_channel_cfg(
946     u32				ch_id,
947     input_system_csi_port_t			port,
948     backend_channel_cfg_t			backend_ch,
949     u32				csi_mem_reg_size,
950     u32				csi_nof_mem_regs,
951     u32				acq_mem_reg_size,
952     u32				acq_nof_mem_regs,
953     target_cfg2400_t			target,
954     uint32_t				nof_xmem_buffers
955 )
956 {
957 	channel_cfg_t channel;
958 
959 	channel.ch_id	= ch_id;
960 	channel.backend_ch	= backend_ch;
961 	channel.source_type		= INPUT_SYSTEM_SOURCE_SENSOR;
962 	//channel.source
963 	channel.source_cfg.csi_cfg.csi_port			= port;
964 	channel.source_cfg.csi_cfg.buffering_mode	= INPUT_SYSTEM_XMEM_BUFFERING;
965 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_size		= csi_mem_reg_size;
966 	channel.source_cfg.csi_cfg.csi_buffer.nof_mem_regs		= csi_nof_mem_regs;
967 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_addr		= 0;
968 	channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_size	= acq_mem_reg_size;
969 	channel.source_cfg.csi_cfg.acquisition_buffer.nof_mem_regs	= acq_nof_mem_regs;
970 	channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_addr	= 0;
971 	channel.source_cfg.csi_cfg.nof_xmem_buffers	= nof_xmem_buffers;
972 
973 	channel.target_cfg	= target;
974 	return input_system_configure_channel(channel);
975 }
976 
input_system_csi_xmem_acquire_only_channel_cfg(u32 ch_id,u32 nof_frames,input_system_csi_port_t port,backend_channel_cfg_t backend_ch,u32 acq_mem_reg_size,u32 acq_nof_mem_regs,target_cfg2400_t target)977 input_system_err_t	input_system_csi_xmem_acquire_only_channel_cfg(
978     u32				ch_id,
979     u32				nof_frames,
980     input_system_csi_port_t			port,
981     backend_channel_cfg_t			backend_ch,
982     u32				acq_mem_reg_size,
983     u32				acq_nof_mem_regs,
984     target_cfg2400_t			target)
985 {
986 	channel_cfg_t channel;
987 
988 	channel.ch_id	= ch_id;
989 	channel.backend_ch	= backend_ch;
990 	channel.source_type		= INPUT_SYSTEM_SOURCE_SENSOR;
991 	//channel.source
992 	channel.source_cfg.csi_cfg.csi_port			= port;
993 	channel.source_cfg.csi_cfg.buffering_mode	= INPUT_SYSTEM_XMEM_ACQUIRE;
994 	channel.source_cfg.csi_cfg.csi_buffer		= IB_BUFFER_NULL;
995 	channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_size	= acq_mem_reg_size;
996 	channel.source_cfg.csi_cfg.acquisition_buffer.nof_mem_regs	= acq_nof_mem_regs;
997 	channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_addr	= 0;
998 	channel.source_cfg.csi_cfg.nof_xmem_buffers	= nof_frames;
999 
1000 	channel.target_cfg	= target;
1001 	return input_system_configure_channel(channel);
1002 }
1003 
input_system_csi_xmem_capture_only_channel_cfg(u32 ch_id,u32 nof_frames,input_system_csi_port_t port,u32 csi_mem_reg_size,u32 csi_nof_mem_regs,u32 acq_mem_reg_size,u32 acq_nof_mem_regs,target_cfg2400_t target)1004 input_system_err_t	input_system_csi_xmem_capture_only_channel_cfg(
1005     u32				ch_id,
1006     u32				nof_frames,
1007     input_system_csi_port_t			port,
1008     u32				csi_mem_reg_size,
1009     u32				csi_nof_mem_regs,
1010     u32				acq_mem_reg_size,
1011     u32				acq_nof_mem_regs,
1012     target_cfg2400_t			target)
1013 {
1014 	channel_cfg_t channel;
1015 
1016 	channel.ch_id	= ch_id;
1017 	//channel.backend_ch	= backend_ch;
1018 	channel.source_type		= INPUT_SYSTEM_SOURCE_SENSOR;
1019 	//channel.source
1020 	channel.source_cfg.csi_cfg.csi_port			= port;
1021 	//channel.source_cfg.csi_cfg.backend_ch		= backend_ch;
1022 	channel.source_cfg.csi_cfg.buffering_mode	= INPUT_SYSTEM_XMEM_CAPTURE;
1023 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_size		= csi_mem_reg_size;
1024 	channel.source_cfg.csi_cfg.csi_buffer.nof_mem_regs		= csi_nof_mem_regs;
1025 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_addr		= 0;
1026 	channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_size	= acq_mem_reg_size;
1027 	channel.source_cfg.csi_cfg.acquisition_buffer.nof_mem_regs	= acq_nof_mem_regs;
1028 	channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_addr	= 0;
1029 	channel.source_cfg.csi_cfg.nof_xmem_buffers	= nof_frames;
1030 
1031 	channel.target_cfg	= target;
1032 	return input_system_configure_channel(channel);
1033 }
1034 
1035 // Non - CSI
1036 
input_system_prbs_channel_cfg(u32 ch_id,u32 nof_frames,u32 seed,u32 sync_gen_width,u32 sync_gen_height,u32 sync_gen_hblank_cycles,u32 sync_gen_vblank_cycles,target_cfg2400_t target)1037 input_system_err_t	input_system_prbs_channel_cfg(
1038     u32		ch_id,
1039     u32		nof_frames,//not used yet
1040     u32		seed,
1041     u32		sync_gen_width,
1042     u32		sync_gen_height,
1043     u32		sync_gen_hblank_cycles,
1044     u32		sync_gen_vblank_cycles,
1045     target_cfg2400_t	target
1046 )
1047 {
1048 	channel_cfg_t channel;
1049 
1050 	(void)nof_frames;
1051 
1052 	channel.ch_id	= ch_id;
1053 	channel.source_type = INPUT_SYSTEM_SOURCE_PRBS;
1054 
1055 	channel.source_cfg.prbs_cfg.seed = seed;
1056 	channel.source_cfg.prbs_cfg.sync_gen_cfg.width		= sync_gen_width;
1057 	channel.source_cfg.prbs_cfg.sync_gen_cfg.height		= sync_gen_height;
1058 	channel.source_cfg.prbs_cfg.sync_gen_cfg.hblank_cycles	= sync_gen_hblank_cycles;
1059 	channel.source_cfg.prbs_cfg.sync_gen_cfg.vblank_cycles	= sync_gen_vblank_cycles;
1060 
1061 	channel.target_cfg	= target;
1062 
1063 	return input_system_configure_channel(channel);
1064 }
1065 
1066 // MW: Don't use system specific names, (even in system specific files) "cfg2400" -> cfg
input_system_gpfifo_channel_cfg(u32 ch_id,u32 nof_frames,target_cfg2400_t target)1067 input_system_err_t	input_system_gpfifo_channel_cfg(
1068     u32		ch_id,
1069     u32		nof_frames, //not used yet
1070 
1071     target_cfg2400_t	target)
1072 {
1073 	channel_cfg_t channel;
1074 
1075 	(void)nof_frames;
1076 
1077 	channel.ch_id	= ch_id;
1078 	channel.source_type	= INPUT_SYSTEM_SOURCE_FIFO;
1079 
1080 	channel.target_cfg	= target;
1081 	return input_system_configure_channel(channel);
1082 }
1083 
1084 ///////////////////////////////////////////////////////////////////////////
1085 //
1086 // Private specialized functions for channel setting.
1087 //
1088 ///////////////////////////////////////////////////////////////////////////
1089 
1090 // Fills the parameters to config.csi_value[port]
input_system_configure_channel_sensor(const channel_cfg_t channel)1091 static input_system_err_t input_system_configure_channel_sensor(
1092     const channel_cfg_t channel)
1093 {
1094 	const u32 port = channel.source_cfg.csi_cfg.csi_port;
1095 	input_system_err_t status = INPUT_SYSTEM_ERR_NO_ERROR;
1096 
1097 	input_system_multiplex_t mux;
1098 
1099 	if (port >= N_INPUT_SYSTEM_PORTS)
1100 		return INPUT_SYSTEM_ERR_GENERIC;
1101 
1102 	//check if port > N_INPUT_SYSTEM_MULTIPLEX
1103 
1104 	status = set_source_type(&config.source_type, channel.source_type,
1105 				 &config.source_type_flags);
1106 	if (status != INPUT_SYSTEM_ERR_NO_ERROR) return status;
1107 
1108 	// Check for conflicts on source (implicitly on multicast, capture unit and input buffer).
1109 
1110 	status = set_csi_cfg(&config.csi_value[port], &channel.source_cfg.csi_cfg,
1111 			     &config.csi_flags[port]);
1112 	if (status != INPUT_SYSTEM_ERR_NO_ERROR) return status;
1113 
1114 	switch (channel.source_cfg.csi_cfg.buffering_mode) {
1115 	case INPUT_SYSTEM_FIFO_CAPTURE:
1116 
1117 		// Check for conflicts on mux.
1118 		mux = INPUT_SYSTEM_MIPI_PORT0 + port;
1119 		status = input_system_multiplexer_cfg(&config.multiplexer, mux,
1120 						      &config.multiplexer_flags);
1121 		if (status != INPUT_SYSTEM_ERR_NO_ERROR) return status;
1122 		config.multicast[port] = INPUT_SYSTEM_CSI_BACKEND;
1123 
1124 		// Shared resource, so it should be blocked.
1125 		//config.mux_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1126 		//config.csi_buffer_flags[port] |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1127 		//config.acquisition_buffer_unique_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1128 
1129 		break;
1130 	case INPUT_SYSTEM_SRAM_BUFFERING:
1131 
1132 		// Check for conflicts on mux.
1133 		mux = INPUT_SYSTEM_ACQUISITION_UNIT;
1134 		status = input_system_multiplexer_cfg(&config.multiplexer, mux,
1135 						      &config.multiplexer_flags);
1136 		if (status != INPUT_SYSTEM_ERR_NO_ERROR) return status;
1137 		config.multicast[port] = INPUT_SYSTEM_INPUT_BUFFER;
1138 
1139 		// Shared resource, so it should be blocked.
1140 		//config.mux_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1141 		//config.csi_buffer_flags[port] |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1142 		//config.acquisition_buffer_unique_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1143 
1144 		break;
1145 	case INPUT_SYSTEM_XMEM_BUFFERING:
1146 
1147 		// Check for conflicts on mux.
1148 		mux = INPUT_SYSTEM_ACQUISITION_UNIT;
1149 		status = input_system_multiplexer_cfg(&config.multiplexer, mux,
1150 						      &config.multiplexer_flags);
1151 		if (status != INPUT_SYSTEM_ERR_NO_ERROR) return status;
1152 		config.multicast[port] = INPUT_SYSTEM_INPUT_BUFFER;
1153 
1154 		// Shared resource, so it should be blocked.
1155 		//config.mux_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1156 		//config.csi_buffer_flags[port] |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1157 		//config.acquisition_buffer_unique_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1158 
1159 		break;
1160 	case INPUT_SYSTEM_FIFO_CAPTURE_WITH_COUNTING:
1161 	case INPUT_SYSTEM_XMEM_CAPTURE:
1162 	case INPUT_SYSTEM_XMEM_ACQUIRE:
1163 	default:
1164 		return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
1165 	}
1166 
1167 	return INPUT_SYSTEM_ERR_NO_ERROR;
1168 }
1169 
1170 // Test flags and set structure.
set_source_type(input_system_source_t * const lhs,const input_system_source_t rhs,input_system_config_flags_t * const flags)1171 static input_system_err_t set_source_type(
1172     input_system_source_t *const lhs,
1173     const input_system_source_t			rhs,
1174     input_system_config_flags_t *const flags)
1175 {
1176 	// MW: Not enough asserts
1177 	assert(lhs);
1178 	assert(flags);
1179 
1180 	if ((*flags) & INPUT_SYSTEM_CFG_FLAG_BLOCKED) {
1181 		*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1182 		return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1183 	}
1184 
1185 	if ((*flags) & INPUT_SYSTEM_CFG_FLAG_SET) {
1186 		// Check for consistency with already set value.
1187 		if ((*lhs) == (rhs)) {
1188 			return INPUT_SYSTEM_ERR_NO_ERROR;
1189 		} else {
1190 			*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1191 			return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1192 		}
1193 	}
1194 	// Check the value (individually).
1195 	if (rhs >= N_INPUT_SYSTEM_SOURCE) {
1196 		*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1197 		return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1198 	}
1199 	// Set the value.
1200 	*lhs = rhs;
1201 
1202 	*flags |= INPUT_SYSTEM_CFG_FLAG_SET;
1203 	return INPUT_SYSTEM_ERR_NO_ERROR;
1204 }
1205 
1206 // Test flags and set structure.
set_csi_cfg(csi_cfg_t * const lhs,const csi_cfg_t * const rhs,input_system_config_flags_t * const flags)1207 static input_system_err_t set_csi_cfg(
1208     csi_cfg_t *const lhs,
1209     const csi_cfg_t *const rhs,
1210     input_system_config_flags_t *const flags)
1211 {
1212 	u32 memory_required;
1213 	u32 acq_memory_required;
1214 
1215 	assert(lhs);
1216 	assert(flags);
1217 
1218 	if ((*flags) & INPUT_SYSTEM_CFG_FLAG_BLOCKED) {
1219 		*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1220 		return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1221 	}
1222 
1223 	if (*flags & INPUT_SYSTEM_CFG_FLAG_SET) {
1224 		// check for consistency with already set value.
1225 		if (/*lhs->backend_ch == rhs.backend_ch
1226 			&&*/ lhs->buffering_mode == rhs->buffering_mode
1227 		    && lhs->csi_buffer.mem_reg_size == rhs->csi_buffer.mem_reg_size
1228 		    && lhs->csi_buffer.nof_mem_regs  == rhs->csi_buffer.nof_mem_regs
1229 		    && lhs->acquisition_buffer.mem_reg_size == rhs->acquisition_buffer.mem_reg_size
1230 		    && lhs->acquisition_buffer.nof_mem_regs  == rhs->acquisition_buffer.nof_mem_regs
1231 		    && lhs->nof_xmem_buffers  == rhs->nof_xmem_buffers
1232 		) {
1233 			return INPUT_SYSTEM_ERR_NO_ERROR;
1234 		} else {
1235 			*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1236 			return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1237 		}
1238 	}
1239 	// Check the value (individually).
1240 	// no check for backend_ch
1241 	// no check for nof_xmem_buffers
1242 	memory_required = rhs->csi_buffer.mem_reg_size * rhs->csi_buffer.nof_mem_regs;
1243 	acq_memory_required = rhs->acquisition_buffer.mem_reg_size *
1244 			      rhs->acquisition_buffer.nof_mem_regs;
1245 	if (rhs->buffering_mode >= N_INPUT_SYSTEM_BUFFERING_MODE
1246 	    ||
1247 	    // Check if required memory is available in input buffer (SRAM).
1248 	    (memory_required + acq_memory_required) > config.unallocated_ib_mem_words
1249 
1250 	   ) {
1251 		*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1252 		return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1253 	}
1254 	// Set the value.
1255 	//lhs[port]->backend_ch		= rhs.backend_ch;
1256 	lhs->buffering_mode	= rhs->buffering_mode;
1257 	lhs->nof_xmem_buffers = rhs->nof_xmem_buffers;
1258 
1259 	lhs->csi_buffer.mem_reg_size = rhs->csi_buffer.mem_reg_size;
1260 	lhs->csi_buffer.nof_mem_regs  = rhs->csi_buffer.nof_mem_regs;
1261 	lhs->acquisition_buffer.mem_reg_size = rhs->acquisition_buffer.mem_reg_size;
1262 	lhs->acquisition_buffer.nof_mem_regs  = rhs->acquisition_buffer.nof_mem_regs;
1263 	// ALX: NB: Here we just set buffer parameters, but still not allocate it
1264 	// (no addresses determined). That will be done during commit.
1265 
1266 	//  FIXIT:	acq_memory_required is not deducted, since it can be allocated multiple times.
1267 	config.unallocated_ib_mem_words -= memory_required;
1268 //assert(config.unallocated_ib_mem_words >=0);
1269 	*flags |= INPUT_SYSTEM_CFG_FLAG_SET;
1270 	return INPUT_SYSTEM_ERR_NO_ERROR;
1271 }
1272 
1273 // Test flags and set structure.
input_system_multiplexer_cfg(input_system_multiplex_t * const lhs,const input_system_multiplex_t rhs,input_system_config_flags_t * const flags)1274 static input_system_err_t input_system_multiplexer_cfg(
1275     input_system_multiplex_t *const lhs,
1276     const input_system_multiplex_t		rhs,
1277     input_system_config_flags_t *const flags)
1278 {
1279 	assert(lhs);
1280 	assert(flags);
1281 
1282 	if ((*flags) & INPUT_SYSTEM_CFG_FLAG_BLOCKED) {
1283 		*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1284 		return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1285 	}
1286 
1287 	if ((*flags) & INPUT_SYSTEM_CFG_FLAG_SET) {
1288 		// Check for consistency with already set value.
1289 		if ((*lhs) == (rhs)) {
1290 			return INPUT_SYSTEM_ERR_NO_ERROR;
1291 		} else {
1292 			*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1293 			return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1294 		}
1295 	}
1296 	// Check the value (individually).
1297 	if (rhs >= N_INPUT_SYSTEM_MULTIPLEX) {
1298 		*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1299 		return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
1300 	}
1301 	// Set the value.
1302 	*lhs = rhs;
1303 
1304 	*flags |= INPUT_SYSTEM_CFG_FLAG_SET;
1305 	return INPUT_SYSTEM_ERR_NO_ERROR;
1306 }
1307