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