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_TPG:
430 		case INPUT_SYSTEM_SOURCE_PRBS:
431 		case INPUT_SYSTEM_SOURCE_FIFO:
432 		default:
433 			return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
434 		}
435 
436 		if (error != INPUT_SYSTEM_ERR_NO_ERROR) return error;
437 		// Input switch channel configurations must be combined in united config.
438 		config.input_switch_cfg.hsync_data_reg[channel.source_cfg.csi_cfg.csi_port * 2]
439 		    =
440 			channel.target_cfg.input_switch_channel_cfg.hsync_data_reg[0];
441 		config.input_switch_cfg.hsync_data_reg[channel.source_cfg.csi_cfg.csi_port * 2 +
442 											   1] =
443 							       channel.target_cfg.input_switch_channel_cfg.hsync_data_reg[1];
444 		config.input_switch_cfg.vsync_data_reg |=
445 		    (channel.target_cfg.input_switch_channel_cfg.vsync_data_reg & 0x7) <<
446 		    (channel.source_cfg.csi_cfg.csi_port * 3);
447 
448 		// Other targets are just copied and marked as set.
449 		config.target_isp[channel.source_cfg.csi_cfg.csi_port] =
450 		    channel.target_cfg.target_isp_cfg;
451 		config.target_sp[channel.source_cfg.csi_cfg.csi_port] =
452 		    channel.target_cfg.target_sp_cfg;
453 		config.target_strm2mem[channel.source_cfg.csi_cfg.csi_port] =
454 		    channel.target_cfg.target_strm2mem_cfg;
455 		config.target_isp_flags[channel.source_cfg.csi_cfg.csi_port] |=
456 		    INPUT_SYSTEM_CFG_FLAG_SET;
457 		config.target_sp_flags[channel.source_cfg.csi_cfg.csi_port] |=
458 		    INPUT_SYSTEM_CFG_FLAG_SET;
459 		config.target_strm2mem_flags[channel.source_cfg.csi_cfg.csi_port] |=
460 		    INPUT_SYSTEM_CFG_FLAG_SET;
461 
462 		config.ch_flags[channel.ch_id] = INPUT_SYSTEM_CFG_FLAG_SET;
463 	}
464 	return INPUT_SYSTEM_ERR_NO_ERROR;
465 }
466 
467 // Function that partitions input buffer space with determining addresses.
input_buffer_configuration(void)468 static input_system_err_t input_buffer_configuration(void)
469 {
470 	u32 current_address    = 0;
471 	u32 unallocated_memory = IB_CAPACITY_IN_WORDS;
472 
473 	isp2400_ib_buffer_t	candidate_buffer_acq  = IB_BUFFER_NULL;
474 	u32 size_requested;
475 	input_system_config_flags_t	acq_already_specified = INPUT_SYSTEM_CFG_FLAG_RESET;
476 	input_system_csi_port_t port;
477 
478 	for (port = INPUT_SYSTEM_PORT_A; port < N_INPUT_SYSTEM_PORTS; port++) {
479 		csi_cfg_t source = config.csi_value[port];//.csi_cfg;
480 
481 		if (config.csi_flags[port] & INPUT_SYSTEM_CFG_FLAG_SET) {
482 			// Check and set csi buffer in input buffer.
483 			switch (source.buffering_mode) {
484 			case INPUT_SYSTEM_FIFO_CAPTURE:
485 			case INPUT_SYSTEM_XMEM_ACQUIRE:
486 				config.csi_buffer_flags[port] =
487 				    INPUT_SYSTEM_CFG_FLAG_BLOCKED; // Well, not used.
488 				break;
489 
490 			case INPUT_SYSTEM_FIFO_CAPTURE_WITH_COUNTING:
491 			case INPUT_SYSTEM_SRAM_BUFFERING:
492 			case INPUT_SYSTEM_XMEM_BUFFERING:
493 			case INPUT_SYSTEM_XMEM_CAPTURE:
494 				size_requested = source.csi_buffer.mem_reg_size *
495 						 source.csi_buffer.nof_mem_regs;
496 				if (source.csi_buffer.mem_reg_size > 0
497 				    && source.csi_buffer.nof_mem_regs > 0
498 				    && size_requested <= unallocated_memory
499 				   ) {
500 					config.csi_buffer[port].mem_reg_addr = current_address;
501 					config.csi_buffer[port].mem_reg_size = source.csi_buffer.mem_reg_size;
502 					config.csi_buffer[port].nof_mem_regs = source.csi_buffer.nof_mem_regs;
503 					current_address		+= size_requested;
504 					unallocated_memory	-= size_requested;
505 					config.csi_buffer_flags[port] = INPUT_SYSTEM_CFG_FLAG_SET;
506 				} else {
507 					config.csi_buffer_flags[port] |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
508 					return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
509 				}
510 				break;
511 
512 			default:
513 				config.csi_buffer_flags[port] |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
514 				return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
515 			}
516 
517 			// Check acquisition buffer specified but set it later since it has to be unique.
518 			switch (source.buffering_mode) {
519 			case INPUT_SYSTEM_FIFO_CAPTURE:
520 			case INPUT_SYSTEM_SRAM_BUFFERING:
521 			case INPUT_SYSTEM_XMEM_CAPTURE:
522 				// Nothing to do.
523 				break;
524 
525 			case INPUT_SYSTEM_FIFO_CAPTURE_WITH_COUNTING:
526 			case INPUT_SYSTEM_XMEM_BUFFERING:
527 			case INPUT_SYSTEM_XMEM_ACQUIRE:
528 				if (acq_already_specified == INPUT_SYSTEM_CFG_FLAG_RESET) {
529 					size_requested = source.acquisition_buffer.mem_reg_size
530 							 * source.acquisition_buffer.nof_mem_regs;
531 					if (source.acquisition_buffer.mem_reg_size > 0
532 					    && source.acquisition_buffer.nof_mem_regs > 0
533 					    && size_requested <= unallocated_memory
534 					   ) {
535 						candidate_buffer_acq = source.acquisition_buffer;
536 						acq_already_specified = INPUT_SYSTEM_CFG_FLAG_SET;
537 					}
538 				} else {
539 					// Check if specified acquisition buffer is the same as specified before.
540 					if (source.acquisition_buffer.mem_reg_size != candidate_buffer_acq.mem_reg_size
541 					    || source.acquisition_buffer.nof_mem_regs !=  candidate_buffer_acq.nof_mem_regs
542 					   ) {
543 						config.acquisition_buffer_unique_flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
544 						return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
545 					}
546 				}
547 				break;
548 
549 			default:
550 				return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
551 			}
552 		} else {
553 			config.csi_buffer_flags[port] = INPUT_SYSTEM_CFG_FLAG_BLOCKED;
554 		}
555 	} // end of for ( port )
556 
557 	// Set the acquisition buffer at the end.
558 	size_requested = candidate_buffer_acq.mem_reg_size *
559 			 candidate_buffer_acq.nof_mem_regs;
560 	if (acq_already_specified == INPUT_SYSTEM_CFG_FLAG_SET
561 	    && size_requested <= unallocated_memory) {
562 		config.acquisition_buffer_unique.mem_reg_addr = current_address;
563 		config.acquisition_buffer_unique.mem_reg_size =
564 		    candidate_buffer_acq.mem_reg_size;
565 		config.acquisition_buffer_unique.nof_mem_regs =
566 		    candidate_buffer_acq.nof_mem_regs;
567 		current_address		+= size_requested;
568 		unallocated_memory	-= size_requested;
569 		config.acquisition_buffer_unique_flags = INPUT_SYSTEM_CFG_FLAG_SET;
570 
571 		assert(current_address <= IB_CAPACITY_IN_WORDS);
572 	}
573 
574 	return INPUT_SYSTEM_ERR_NO_ERROR;
575 }
576 
capture_unit_configure(const input_system_ID_t ID,const sub_system_ID_t sub_id,const isp2400_ib_buffer_t * const cfg)577 static void capture_unit_configure(
578     const input_system_ID_t			ID,
579     const sub_system_ID_t			sub_id,
580     const isp2400_ib_buffer_t *const cfg)
581 {
582 	assert(ID < N_INPUT_SYSTEM_ID);
583 	assert(/*(sub_id >= CAPTURE_UNIT0_ID) &&*/ (sub_id <=
584 		CAPTURE_UNIT2_ID)); // Commented part is always true.
585 	assert(cfg);
586 
587 	input_system_sub_system_reg_store(ID,
588 					  sub_id,
589 					  CAPT_START_ADDR_REG_ID,
590 					  cfg->mem_reg_addr);
591 	input_system_sub_system_reg_store(ID,
592 					  sub_id,
593 					  CAPT_MEM_REGION_SIZE_REG_ID,
594 					  cfg->mem_reg_size);
595 	input_system_sub_system_reg_store(ID,
596 					  sub_id,
597 					  CAPT_NUM_MEM_REGIONS_REG_ID,
598 					  cfg->nof_mem_regs);
599 }
600 
acquisition_unit_configure(const input_system_ID_t ID,const sub_system_ID_t sub_id,const isp2400_ib_buffer_t * const cfg)601 static void acquisition_unit_configure(
602     const input_system_ID_t			ID,
603     const sub_system_ID_t			sub_id,
604     const isp2400_ib_buffer_t *const cfg)
605 {
606 	assert(ID < N_INPUT_SYSTEM_ID);
607 	assert(sub_id == ACQUISITION_UNIT0_ID);
608 	assert(cfg);
609 
610 	input_system_sub_system_reg_store(ID,
611 					  sub_id,
612 					  ACQ_START_ADDR_REG_ID,
613 					  cfg->mem_reg_addr);
614 	input_system_sub_system_reg_store(ID,
615 					  sub_id,
616 					  ACQ_NUM_MEM_REGIONS_REG_ID,
617 					  cfg->nof_mem_regs);
618 	input_system_sub_system_reg_store(ID,
619 					  sub_id,
620 					  ACQ_MEM_REGION_SIZE_REG_ID,
621 					  cfg->mem_reg_size);
622 }
623 
ctrl_unit_configure(const input_system_ID_t ID,const sub_system_ID_t sub_id,const ctrl_unit_cfg_t * const cfg)624 static void ctrl_unit_configure(
625     const input_system_ID_t			ID,
626     const sub_system_ID_t			sub_id,
627     const ctrl_unit_cfg_t *const cfg)
628 {
629 	assert(ID < N_INPUT_SYSTEM_ID);
630 	assert(sub_id == CTRL_UNIT0_ID);
631 	assert(cfg);
632 
633 	input_system_sub_system_reg_store(ID,
634 					  sub_id,
635 					  ISYS_CTRL_CAPT_START_ADDR_A_REG_ID,
636 					  cfg->buffer_mipi[CAPTURE_UNIT0_ID].mem_reg_addr);
637 	input_system_sub_system_reg_store(ID,
638 					  sub_id,
639 					  ISYS_CTRL_CAPT_MEM_REGION_SIZE_A_REG_ID,
640 					  cfg->buffer_mipi[CAPTURE_UNIT0_ID].mem_reg_size);
641 	input_system_sub_system_reg_store(ID,
642 					  sub_id,
643 					  ISYS_CTRL_CAPT_NUM_MEM_REGIONS_A_REG_ID,
644 					  cfg->buffer_mipi[CAPTURE_UNIT0_ID].nof_mem_regs);
645 
646 	input_system_sub_system_reg_store(ID,
647 					  sub_id,
648 					  ISYS_CTRL_CAPT_START_ADDR_B_REG_ID,
649 					  cfg->buffer_mipi[CAPTURE_UNIT1_ID].mem_reg_addr);
650 	input_system_sub_system_reg_store(ID,
651 					  sub_id,
652 					  ISYS_CTRL_CAPT_MEM_REGION_SIZE_B_REG_ID,
653 					  cfg->buffer_mipi[CAPTURE_UNIT1_ID].mem_reg_size);
654 	input_system_sub_system_reg_store(ID,
655 					  sub_id,
656 					  ISYS_CTRL_CAPT_NUM_MEM_REGIONS_B_REG_ID,
657 					  cfg->buffer_mipi[CAPTURE_UNIT1_ID].nof_mem_regs);
658 
659 	input_system_sub_system_reg_store(ID,
660 					  sub_id,
661 					  ISYS_CTRL_CAPT_START_ADDR_C_REG_ID,
662 					  cfg->buffer_mipi[CAPTURE_UNIT2_ID].mem_reg_addr);
663 	input_system_sub_system_reg_store(ID,
664 					  sub_id,
665 					  ISYS_CTRL_CAPT_MEM_REGION_SIZE_C_REG_ID,
666 					  cfg->buffer_mipi[CAPTURE_UNIT2_ID].mem_reg_size);
667 	input_system_sub_system_reg_store(ID,
668 					  sub_id,
669 					  ISYS_CTRL_CAPT_NUM_MEM_REGIONS_C_REG_ID,
670 					  cfg->buffer_mipi[CAPTURE_UNIT2_ID].nof_mem_regs);
671 
672 	input_system_sub_system_reg_store(ID,
673 					  sub_id,
674 					  ISYS_CTRL_ACQ_START_ADDR_REG_ID,
675 					  cfg->buffer_acquire[ACQUISITION_UNIT0_ID - ACQUISITION_UNIT0_ID].mem_reg_addr);
676 	input_system_sub_system_reg_store(ID,
677 					  sub_id,
678 					  ISYS_CTRL_ACQ_MEM_REGION_SIZE_REG_ID,
679 					  cfg->buffer_acquire[ACQUISITION_UNIT0_ID - ACQUISITION_UNIT0_ID].mem_reg_size);
680 	input_system_sub_system_reg_store(ID,
681 					  sub_id,
682 					  ISYS_CTRL_ACQ_NUM_MEM_REGIONS_REG_ID,
683 					  cfg->buffer_acquire[ACQUISITION_UNIT0_ID - ACQUISITION_UNIT0_ID].nof_mem_regs);
684 	input_system_sub_system_reg_store(ID,
685 					  sub_id,
686 					  ISYS_CTRL_CAPT_RESERVE_ONE_MEM_REGION_REG_ID,
687 					  0);
688 }
689 
input_system_network_configure(const input_system_ID_t ID,const input_system_network_cfg_t * const cfg)690 static void input_system_network_configure(
691     const input_system_ID_t				ID,
692     const input_system_network_cfg_t *const cfg)
693 {
694 	u32 sub_id;
695 
696 	assert(ID < N_INPUT_SYSTEM_ID);
697 	assert(cfg);
698 
699 	// Set all 3 multicasts.
700 	input_system_sub_system_reg_store(ID,
701 					  GPREGS_UNIT0_ID,
702 					  HIVE_ISYS_GPREG_MULTICAST_A_IDX,
703 					  cfg->multicast_cfg[CAPTURE_UNIT0_ID]);
704 	input_system_sub_system_reg_store(ID,
705 					  GPREGS_UNIT0_ID,
706 					  HIVE_ISYS_GPREG_MULTICAST_B_IDX,
707 					  cfg->multicast_cfg[CAPTURE_UNIT1_ID]);
708 	input_system_sub_system_reg_store(ID,
709 					  GPREGS_UNIT0_ID,
710 					  HIVE_ISYS_GPREG_MULTICAST_C_IDX,
711 					  cfg->multicast_cfg[CAPTURE_UNIT2_ID]);
712 
713 	// Set stream mux.
714 	input_system_sub_system_reg_store(ID,
715 					  GPREGS_UNIT0_ID,
716 					  HIVE_ISYS_GPREG_MUX_IDX,
717 					  cfg->mux_cfg);
718 
719 	// Set capture units.
720 	for (sub_id = CAPTURE_UNIT0_ID; sub_id < CAPTURE_UNIT0_ID + N_CAPTURE_UNIT_ID;
721 	     sub_id++) {
722 		capture_unit_configure(ID,
723 				       sub_id,
724 				       &cfg->ctrl_unit_cfg[ID].buffer_mipi[sub_id - CAPTURE_UNIT0_ID]);
725 	}
726 
727 	// Set acquisition units.
728 	for (sub_id = ACQUISITION_UNIT0_ID;
729 	     sub_id < ACQUISITION_UNIT0_ID + N_ACQUISITION_UNIT_ID; sub_id++) {
730 		acquisition_unit_configure(ID,
731 					   sub_id,
732 					   &cfg->ctrl_unit_cfg[sub_id - ACQUISITION_UNIT0_ID].buffer_acquire[sub_id -
733 						   ACQUISITION_UNIT0_ID]);
734 	}
735 
736 	// No DMA configuration needed. Ctrl_unit will fully control it.
737 
738 	// Set controller units.
739 	for (sub_id = CTRL_UNIT0_ID; sub_id < CTRL_UNIT0_ID + N_CTRL_UNIT_ID;
740 	     sub_id++) {
741 		ctrl_unit_configure(ID,
742 				    sub_id,
743 				    &cfg->ctrl_unit_cfg[sub_id - CTRL_UNIT0_ID]);
744 	}
745 }
746 
configuration_to_registers(void)747 static input_system_err_t configuration_to_registers(void)
748 {
749 	input_system_network_cfg_t input_system_network_cfg;
750 	int i;
751 
752 	assert(config.source_type_flags & INPUT_SYSTEM_CFG_FLAG_SET);
753 
754 	switch (config.source_type) {
755 	case INPUT_SYSTEM_SOURCE_SENSOR:
756 
757 		// Determine stream multicasts setting based on the mode of csi_cfg_t.
758 		// AM: This should be moved towards earlier function call, e.g. in
759 		// the commit function.
760 		for (i = MIPI_PORT0_ID; i < N_MIPI_PORT_ID; i++) {
761 			if (config.csi_flags[i] & INPUT_SYSTEM_CFG_FLAG_SET) {
762 				switch (config.csi_value[i].buffering_mode) {
763 				case INPUT_SYSTEM_FIFO_CAPTURE:
764 					config.multicast[i] = INPUT_SYSTEM_CSI_BACKEND;
765 					break;
766 
767 				case INPUT_SYSTEM_XMEM_CAPTURE:
768 				case INPUT_SYSTEM_SRAM_BUFFERING:
769 				case INPUT_SYSTEM_XMEM_BUFFERING:
770 					config.multicast[i] = INPUT_SYSTEM_INPUT_BUFFER;
771 					break;
772 
773 				case INPUT_SYSTEM_FIFO_CAPTURE_WITH_COUNTING:
774 					config.multicast[i] = INPUT_SYSTEM_MULTICAST;
775 					break;
776 
777 				case INPUT_SYSTEM_XMEM_ACQUIRE:
778 					config.multicast[i] = INPUT_SYSTEM_DISCARD_ALL;
779 					break;
780 
781 				default:
782 					config.multicast[i] = INPUT_SYSTEM_DISCARD_ALL;
783 					return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
784 					//break;
785 				}
786 			} else {
787 				config.multicast[i] = INPUT_SYSTEM_DISCARD_ALL;
788 			}
789 
790 			input_system_network_cfg.multicast_cfg[i] = config.multicast[i];
791 
792 		} // for
793 
794 		input_system_network_cfg.mux_cfg = config.multiplexer;
795 
796 		input_system_network_cfg.ctrl_unit_cfg[CTRL_UNIT0_ID -
797 						       CTRL_UNIT0_ID].buffer_mipi[CAPTURE_UNIT0_ID] =
798 							       config.csi_buffer[MIPI_PORT0_ID];
799 		input_system_network_cfg.ctrl_unit_cfg[CTRL_UNIT0_ID -
800 						       CTRL_UNIT0_ID].buffer_mipi[CAPTURE_UNIT1_ID] =
801 							       config.csi_buffer[MIPI_PORT1_ID];
802 		input_system_network_cfg.ctrl_unit_cfg[CTRL_UNIT0_ID -
803 						       CTRL_UNIT0_ID].buffer_mipi[CAPTURE_UNIT2_ID] =
804 							       config.csi_buffer[MIPI_PORT2_ID];
805 		input_system_network_cfg.ctrl_unit_cfg[CTRL_UNIT0_ID -
806 						       CTRL_UNIT0_ID].buffer_acquire[ACQUISITION_UNIT0_ID -
807 							       ACQUISITION_UNIT0_ID] =
808 								       config.acquisition_buffer_unique;
809 
810 		// First set input network around CSI receiver.
811 		input_system_network_configure(INPUT_SYSTEM0_ID, &input_system_network_cfg);
812 
813 		// Set the CSI receiver.
814 		//...
815 		break;
816 
817 	case INPUT_SYSTEM_SOURCE_TPG:
818 	case INPUT_SYSTEM_SOURCE_PRBS:
819 	case INPUT_SYSTEM_SOURCE_FIFO:
820 		break;
821 
822 	default:
823 		return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
824 
825 	} // end of switch (source_type)
826 
827 	// Set input selector.
828 	input_selector_cfg_for_sensor(GP_DEVICE0_ID);
829 
830 	// Set input switch.
831 	input_switch_cfg(GP_DEVICE0_ID, &config.input_switch_cfg);
832 
833 	// Set input formatters.
834 	// AM: IF are set dynamically.
835 	return INPUT_SYSTEM_ERR_NO_ERROR;
836 }
837 
838 // Function that applies the whole configuration.
input_system_configuration_commit(void)839 input_system_err_t input_system_configuration_commit(void)
840 {
841 	// The last configuration step is to configure the input buffer.
842 	input_system_err_t error = input_buffer_configuration();
843 
844 	if (error != INPUT_SYSTEM_ERR_NO_ERROR) {
845 		return error;
846 	}
847 
848 	// Translate the whole configuration into registers.
849 	error = configuration_to_registers();
850 	if (error != INPUT_SYSTEM_ERR_NO_ERROR) {
851 		return error;
852 	}
853 
854 	// Translate the whole configuration into ctrl commands etc.
855 
856 	return INPUT_SYSTEM_ERR_NO_ERROR;
857 }
858 
859 // FIFO
860 
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)861 input_system_err_t	input_system_csi_fifo_channel_cfg(
862     u32		ch_id,
863     input_system_csi_port_t	port,
864     backend_channel_cfg_t	backend_ch,
865     target_cfg2400_t	target
866 )
867 {
868 	channel_cfg_t channel;
869 
870 	channel.ch_id	= ch_id;
871 	channel.backend_ch	= backend_ch;
872 	channel.source_type = INPUT_SYSTEM_SOURCE_SENSOR;
873 	//channel.source
874 	channel.source_cfg.csi_cfg.csi_port			= port;
875 	channel.source_cfg.csi_cfg.buffering_mode	= INPUT_SYSTEM_FIFO_CAPTURE;
876 	channel.source_cfg.csi_cfg.csi_buffer			= IB_BUFFER_NULL;
877 	channel.source_cfg.csi_cfg.acquisition_buffer	= IB_BUFFER_NULL;
878 	channel.source_cfg.csi_cfg.nof_xmem_buffers	= 0;
879 
880 	channel.target_cfg	= target;
881 	return input_system_configure_channel(channel);
882 }
883 
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)884 input_system_err_t	input_system_csi_fifo_channel_with_counting_cfg(
885     u32				ch_id,
886     u32				nof_frames,
887     input_system_csi_port_t			port,
888     backend_channel_cfg_t			backend_ch,
889     u32				csi_mem_reg_size,
890     u32				csi_nof_mem_regs,
891     target_cfg2400_t			target
892 )
893 {
894 	channel_cfg_t channel;
895 
896 	channel.ch_id	= ch_id;
897 	channel.backend_ch	= backend_ch;
898 	channel.source_type		= INPUT_SYSTEM_SOURCE_SENSOR;
899 	//channel.source
900 	channel.source_cfg.csi_cfg.csi_port			= port;
901 	channel.source_cfg.csi_cfg.buffering_mode	=
902 	    INPUT_SYSTEM_FIFO_CAPTURE_WITH_COUNTING;
903 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_size		= csi_mem_reg_size;
904 	channel.source_cfg.csi_cfg.csi_buffer.nof_mem_regs		= csi_nof_mem_regs;
905 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_addr		= 0;
906 	channel.source_cfg.csi_cfg.acquisition_buffer			= IB_BUFFER_NULL;
907 	channel.source_cfg.csi_cfg.nof_xmem_buffers	= nof_frames;
908 
909 	channel.target_cfg	= target;
910 	return input_system_configure_channel(channel);
911 }
912 
913 // SRAM
914 
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)915 input_system_err_t	input_system_csi_sram_channel_cfg(
916     u32				ch_id,
917     input_system_csi_port_t			port,
918     backend_channel_cfg_t			backend_ch,
919     u32				csi_mem_reg_size,
920     u32				csi_nof_mem_regs,
921     //	uint32_t				acq_mem_reg_size,
922     //	uint32_t				acq_nof_mem_regs,
923     target_cfg2400_t			target
924 )
925 {
926 	channel_cfg_t channel;
927 
928 	channel.ch_id	= ch_id;
929 	channel.backend_ch	= backend_ch;
930 	channel.source_type		= INPUT_SYSTEM_SOURCE_SENSOR;
931 	//channel.source
932 	channel.source_cfg.csi_cfg.csi_port			= port;
933 	channel.source_cfg.csi_cfg.buffering_mode	= INPUT_SYSTEM_SRAM_BUFFERING;
934 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_size		= csi_mem_reg_size;
935 	channel.source_cfg.csi_cfg.csi_buffer.nof_mem_regs		= csi_nof_mem_regs;
936 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_addr		= 0;
937 	channel.source_cfg.csi_cfg.acquisition_buffer			= IB_BUFFER_NULL;
938 	channel.source_cfg.csi_cfg.nof_xmem_buffers	= 0;
939 
940 	channel.target_cfg	= target;
941 	return input_system_configure_channel(channel);
942 }
943 
944 //XMEM
945 
946 // 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)947 input_system_err_t	input_system_csi_xmem_channel_cfg(
948     u32				ch_id,
949     input_system_csi_port_t			port,
950     backend_channel_cfg_t			backend_ch,
951     u32				csi_mem_reg_size,
952     u32				csi_nof_mem_regs,
953     u32				acq_mem_reg_size,
954     u32				acq_nof_mem_regs,
955     target_cfg2400_t			target,
956     uint32_t				nof_xmem_buffers
957 )
958 {
959 	channel_cfg_t channel;
960 
961 	channel.ch_id	= ch_id;
962 	channel.backend_ch	= backend_ch;
963 	channel.source_type		= INPUT_SYSTEM_SOURCE_SENSOR;
964 	//channel.source
965 	channel.source_cfg.csi_cfg.csi_port			= port;
966 	channel.source_cfg.csi_cfg.buffering_mode	= INPUT_SYSTEM_XMEM_BUFFERING;
967 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_size		= csi_mem_reg_size;
968 	channel.source_cfg.csi_cfg.csi_buffer.nof_mem_regs		= csi_nof_mem_regs;
969 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_addr		= 0;
970 	channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_size	= acq_mem_reg_size;
971 	channel.source_cfg.csi_cfg.acquisition_buffer.nof_mem_regs	= acq_nof_mem_regs;
972 	channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_addr	= 0;
973 	channel.source_cfg.csi_cfg.nof_xmem_buffers	= nof_xmem_buffers;
974 
975 	channel.target_cfg	= target;
976 	return input_system_configure_channel(channel);
977 }
978 
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)979 input_system_err_t	input_system_csi_xmem_acquire_only_channel_cfg(
980     u32				ch_id,
981     u32				nof_frames,
982     input_system_csi_port_t			port,
983     backend_channel_cfg_t			backend_ch,
984     u32				acq_mem_reg_size,
985     u32				acq_nof_mem_regs,
986     target_cfg2400_t			target)
987 {
988 	channel_cfg_t channel;
989 
990 	channel.ch_id	= ch_id;
991 	channel.backend_ch	= backend_ch;
992 	channel.source_type		= INPUT_SYSTEM_SOURCE_SENSOR;
993 	//channel.source
994 	channel.source_cfg.csi_cfg.csi_port			= port;
995 	channel.source_cfg.csi_cfg.buffering_mode	= INPUT_SYSTEM_XMEM_ACQUIRE;
996 	channel.source_cfg.csi_cfg.csi_buffer		= IB_BUFFER_NULL;
997 	channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_size	= acq_mem_reg_size;
998 	channel.source_cfg.csi_cfg.acquisition_buffer.nof_mem_regs	= acq_nof_mem_regs;
999 	channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_addr	= 0;
1000 	channel.source_cfg.csi_cfg.nof_xmem_buffers	= nof_frames;
1001 
1002 	channel.target_cfg	= target;
1003 	return input_system_configure_channel(channel);
1004 }
1005 
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)1006 input_system_err_t	input_system_csi_xmem_capture_only_channel_cfg(
1007     u32				ch_id,
1008     u32				nof_frames,
1009     input_system_csi_port_t			port,
1010     u32				csi_mem_reg_size,
1011     u32				csi_nof_mem_regs,
1012     u32				acq_mem_reg_size,
1013     u32				acq_nof_mem_regs,
1014     target_cfg2400_t			target)
1015 {
1016 	channel_cfg_t channel;
1017 
1018 	channel.ch_id	= ch_id;
1019 	//channel.backend_ch	= backend_ch;
1020 	channel.source_type		= INPUT_SYSTEM_SOURCE_SENSOR;
1021 	//channel.source
1022 	channel.source_cfg.csi_cfg.csi_port			= port;
1023 	//channel.source_cfg.csi_cfg.backend_ch		= backend_ch;
1024 	channel.source_cfg.csi_cfg.buffering_mode	= INPUT_SYSTEM_XMEM_CAPTURE;
1025 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_size		= csi_mem_reg_size;
1026 	channel.source_cfg.csi_cfg.csi_buffer.nof_mem_regs		= csi_nof_mem_regs;
1027 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_addr		= 0;
1028 	channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_size	= acq_mem_reg_size;
1029 	channel.source_cfg.csi_cfg.acquisition_buffer.nof_mem_regs	= acq_nof_mem_regs;
1030 	channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_addr	= 0;
1031 	channel.source_cfg.csi_cfg.nof_xmem_buffers	= nof_frames;
1032 
1033 	channel.target_cfg	= target;
1034 	return input_system_configure_channel(channel);
1035 }
1036 
1037 // Non - CSI
1038 
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)1039 input_system_err_t	input_system_prbs_channel_cfg(
1040     u32		ch_id,
1041     u32		nof_frames,//not used yet
1042     u32		seed,
1043     u32		sync_gen_width,
1044     u32		sync_gen_height,
1045     u32		sync_gen_hblank_cycles,
1046     u32		sync_gen_vblank_cycles,
1047     target_cfg2400_t	target
1048 )
1049 {
1050 	channel_cfg_t channel;
1051 
1052 	(void)nof_frames;
1053 
1054 	channel.ch_id	= ch_id;
1055 	channel.source_type = INPUT_SYSTEM_SOURCE_PRBS;
1056 
1057 	channel.source_cfg.prbs_cfg.seed = seed;
1058 	channel.source_cfg.prbs_cfg.sync_gen_cfg.width		= sync_gen_width;
1059 	channel.source_cfg.prbs_cfg.sync_gen_cfg.height		= sync_gen_height;
1060 	channel.source_cfg.prbs_cfg.sync_gen_cfg.hblank_cycles	= sync_gen_hblank_cycles;
1061 	channel.source_cfg.prbs_cfg.sync_gen_cfg.vblank_cycles	= sync_gen_vblank_cycles;
1062 
1063 	channel.target_cfg	= target;
1064 
1065 	return input_system_configure_channel(channel);
1066 }
1067 
input_system_tpg_channel_cfg(u32 ch_id,u32 nof_frames,u32 x_mask,u32 y_mask,u32 x_delta,u32 y_delta,u32 xy_mask,u32 sync_gen_width,u32 sync_gen_height,u32 sync_gen_hblank_cycles,u32 sync_gen_vblank_cycles,target_cfg2400_t target)1068 input_system_err_t	input_system_tpg_channel_cfg(
1069     u32		ch_id,
1070     u32		nof_frames,//not used yet
1071     u32		x_mask,
1072     u32		y_mask,
1073     u32		x_delta,
1074     u32		y_delta,
1075     u32		xy_mask,
1076     u32		sync_gen_width,
1077     u32		sync_gen_height,
1078     u32		sync_gen_hblank_cycles,
1079     u32		sync_gen_vblank_cycles,
1080     target_cfg2400_t	target
1081 )
1082 {
1083 	channel_cfg_t channel;
1084 
1085 	(void)nof_frames;
1086 
1087 	channel.ch_id	= ch_id;
1088 	channel.source_type		= INPUT_SYSTEM_SOURCE_TPG;
1089 
1090 	channel.source_cfg.tpg_cfg.x_mask	= x_mask;
1091 	channel.source_cfg.tpg_cfg.y_mask	= y_mask;
1092 	channel.source_cfg.tpg_cfg.x_delta	= x_delta;
1093 	channel.source_cfg.tpg_cfg.y_delta	= y_delta;
1094 	channel.source_cfg.tpg_cfg.xy_mask	= xy_mask;
1095 	channel.source_cfg.tpg_cfg.sync_gen_cfg.width		= sync_gen_width;
1096 	channel.source_cfg.tpg_cfg.sync_gen_cfg.height		= sync_gen_height;
1097 	channel.source_cfg.tpg_cfg.sync_gen_cfg.hblank_cycles	= sync_gen_hblank_cycles;
1098 	channel.source_cfg.tpg_cfg.sync_gen_cfg.vblank_cycles	= sync_gen_vblank_cycles;
1099 
1100 	channel.target_cfg	= target;
1101 	return input_system_configure_channel(channel);
1102 }
1103 
1104 // 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)1105 input_system_err_t	input_system_gpfifo_channel_cfg(
1106     u32		ch_id,
1107     u32		nof_frames, //not used yet
1108 
1109     target_cfg2400_t	target)
1110 {
1111 	channel_cfg_t channel;
1112 
1113 	(void)nof_frames;
1114 
1115 	channel.ch_id	= ch_id;
1116 	channel.source_type	= INPUT_SYSTEM_SOURCE_FIFO;
1117 
1118 	channel.target_cfg	= target;
1119 	return input_system_configure_channel(channel);
1120 }
1121 
1122 ///////////////////////////////////////////////////////////////////////////
1123 //
1124 // Private specialized functions for channel setting.
1125 //
1126 ///////////////////////////////////////////////////////////////////////////
1127 
1128 // Fills the parameters to config.csi_value[port]
input_system_configure_channel_sensor(const channel_cfg_t channel)1129 static input_system_err_t input_system_configure_channel_sensor(
1130     const channel_cfg_t channel)
1131 {
1132 	const u32 port = channel.source_cfg.csi_cfg.csi_port;
1133 	input_system_err_t status = INPUT_SYSTEM_ERR_NO_ERROR;
1134 
1135 	input_system_multiplex_t mux;
1136 
1137 	if (port >= N_INPUT_SYSTEM_PORTS)
1138 		return INPUT_SYSTEM_ERR_GENERIC;
1139 
1140 	//check if port > N_INPUT_SYSTEM_MULTIPLEX
1141 
1142 	status = set_source_type(&config.source_type, channel.source_type,
1143 				 &config.source_type_flags);
1144 	if (status != INPUT_SYSTEM_ERR_NO_ERROR) return status;
1145 
1146 	// Check for conflicts on source (implicitly on multicast, capture unit and input buffer).
1147 
1148 	status = set_csi_cfg(&config.csi_value[port], &channel.source_cfg.csi_cfg,
1149 			     &config.csi_flags[port]);
1150 	if (status != INPUT_SYSTEM_ERR_NO_ERROR) return status;
1151 
1152 	switch (channel.source_cfg.csi_cfg.buffering_mode) {
1153 	case INPUT_SYSTEM_FIFO_CAPTURE:
1154 
1155 		// Check for conflicts on mux.
1156 		mux = INPUT_SYSTEM_MIPI_PORT0 + port;
1157 		status = input_system_multiplexer_cfg(&config.multiplexer, mux,
1158 						      &config.multiplexer_flags);
1159 		if (status != INPUT_SYSTEM_ERR_NO_ERROR) return status;
1160 		config.multicast[port] = INPUT_SYSTEM_CSI_BACKEND;
1161 
1162 		// Shared resource, so it should be blocked.
1163 		//config.mux_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1164 		//config.csi_buffer_flags[port] |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1165 		//config.acquisition_buffer_unique_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1166 
1167 		break;
1168 	case INPUT_SYSTEM_SRAM_BUFFERING:
1169 
1170 		// Check for conflicts on mux.
1171 		mux = INPUT_SYSTEM_ACQUISITION_UNIT;
1172 		status = input_system_multiplexer_cfg(&config.multiplexer, mux,
1173 						      &config.multiplexer_flags);
1174 		if (status != INPUT_SYSTEM_ERR_NO_ERROR) return status;
1175 		config.multicast[port] = INPUT_SYSTEM_INPUT_BUFFER;
1176 
1177 		// Shared resource, so it should be blocked.
1178 		//config.mux_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1179 		//config.csi_buffer_flags[port] |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1180 		//config.acquisition_buffer_unique_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1181 
1182 		break;
1183 	case INPUT_SYSTEM_XMEM_BUFFERING:
1184 
1185 		// Check for conflicts on mux.
1186 		mux = INPUT_SYSTEM_ACQUISITION_UNIT;
1187 		status = input_system_multiplexer_cfg(&config.multiplexer, mux,
1188 						      &config.multiplexer_flags);
1189 		if (status != INPUT_SYSTEM_ERR_NO_ERROR) return status;
1190 		config.multicast[port] = INPUT_SYSTEM_INPUT_BUFFER;
1191 
1192 		// Shared resource, so it should be blocked.
1193 		//config.mux_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1194 		//config.csi_buffer_flags[port] |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1195 		//config.acquisition_buffer_unique_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1196 
1197 		break;
1198 	case INPUT_SYSTEM_FIFO_CAPTURE_WITH_COUNTING:
1199 	case INPUT_SYSTEM_XMEM_CAPTURE:
1200 	case INPUT_SYSTEM_XMEM_ACQUIRE:
1201 	default:
1202 		return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
1203 	}
1204 
1205 	return INPUT_SYSTEM_ERR_NO_ERROR;
1206 }
1207 
1208 // 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)1209 static input_system_err_t set_source_type(
1210     input_system_source_t *const lhs,
1211     const input_system_source_t			rhs,
1212     input_system_config_flags_t *const flags)
1213 {
1214 	// MW: Not enough asserts
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) == (rhs)) {
1226 			return INPUT_SYSTEM_ERR_NO_ERROR;
1227 		} else {
1228 			*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1229 			return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1230 		}
1231 	}
1232 	// Check the value (individually).
1233 	if (rhs >= N_INPUT_SYSTEM_SOURCE) {
1234 		*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1235 		return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1236 	}
1237 	// Set the value.
1238 	*lhs = rhs;
1239 
1240 	*flags |= INPUT_SYSTEM_CFG_FLAG_SET;
1241 	return INPUT_SYSTEM_ERR_NO_ERROR;
1242 }
1243 
1244 // 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)1245 static input_system_err_t set_csi_cfg(
1246     csi_cfg_t *const lhs,
1247     const csi_cfg_t *const rhs,
1248     input_system_config_flags_t *const flags)
1249 {
1250 	u32 memory_required;
1251 	u32 acq_memory_required;
1252 
1253 	assert(lhs);
1254 	assert(flags);
1255 
1256 	if ((*flags) & INPUT_SYSTEM_CFG_FLAG_BLOCKED) {
1257 		*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1258 		return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1259 	}
1260 
1261 	if (*flags & INPUT_SYSTEM_CFG_FLAG_SET) {
1262 		// check for consistency with already set value.
1263 		if (/*lhs->backend_ch == rhs.backend_ch
1264 			&&*/ lhs->buffering_mode == rhs->buffering_mode
1265 		    && lhs->csi_buffer.mem_reg_size == rhs->csi_buffer.mem_reg_size
1266 		    && lhs->csi_buffer.nof_mem_regs  == rhs->csi_buffer.nof_mem_regs
1267 		    && lhs->acquisition_buffer.mem_reg_size == rhs->acquisition_buffer.mem_reg_size
1268 		    && lhs->acquisition_buffer.nof_mem_regs  == rhs->acquisition_buffer.nof_mem_regs
1269 		    && lhs->nof_xmem_buffers  == rhs->nof_xmem_buffers
1270 		) {
1271 			return INPUT_SYSTEM_ERR_NO_ERROR;
1272 		} else {
1273 			*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1274 			return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1275 		}
1276 	}
1277 	// Check the value (individually).
1278 	// no check for backend_ch
1279 	// no check for nof_xmem_buffers
1280 	memory_required = rhs->csi_buffer.mem_reg_size * rhs->csi_buffer.nof_mem_regs;
1281 	acq_memory_required = rhs->acquisition_buffer.mem_reg_size *
1282 			      rhs->acquisition_buffer.nof_mem_regs;
1283 	if (rhs->buffering_mode >= N_INPUT_SYSTEM_BUFFERING_MODE
1284 	    ||
1285 	    // Check if required memory is available in input buffer (SRAM).
1286 	    (memory_required + acq_memory_required) > config.unallocated_ib_mem_words
1287 
1288 	   ) {
1289 		*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1290 		return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1291 	}
1292 	// Set the value.
1293 	//lhs[port]->backend_ch		= rhs.backend_ch;
1294 	lhs->buffering_mode	= rhs->buffering_mode;
1295 	lhs->nof_xmem_buffers = rhs->nof_xmem_buffers;
1296 
1297 	lhs->csi_buffer.mem_reg_size = rhs->csi_buffer.mem_reg_size;
1298 	lhs->csi_buffer.nof_mem_regs  = rhs->csi_buffer.nof_mem_regs;
1299 	lhs->acquisition_buffer.mem_reg_size = rhs->acquisition_buffer.mem_reg_size;
1300 	lhs->acquisition_buffer.nof_mem_regs  = rhs->acquisition_buffer.nof_mem_regs;
1301 	// ALX: NB: Here we just set buffer parameters, but still not allocate it
1302 	// (no addresses determined). That will be done during commit.
1303 
1304 	//  FIXIT:	acq_memory_required is not deducted, since it can be allocated multiple times.
1305 	config.unallocated_ib_mem_words -= memory_required;
1306 //assert(config.unallocated_ib_mem_words >=0);
1307 	*flags |= INPUT_SYSTEM_CFG_FLAG_SET;
1308 	return INPUT_SYSTEM_ERR_NO_ERROR;
1309 }
1310 
1311 // 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)1312 static input_system_err_t input_system_multiplexer_cfg(
1313     input_system_multiplex_t *const lhs,
1314     const input_system_multiplex_t		rhs,
1315     input_system_config_flags_t *const flags)
1316 {
1317 	assert(lhs);
1318 	assert(flags);
1319 
1320 	if ((*flags) & INPUT_SYSTEM_CFG_FLAG_BLOCKED) {
1321 		*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1322 		return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1323 	}
1324 
1325 	if ((*flags) & INPUT_SYSTEM_CFG_FLAG_SET) {
1326 		// Check for consistency with already set value.
1327 		if ((*lhs) == (rhs)) {
1328 			return INPUT_SYSTEM_ERR_NO_ERROR;
1329 		} else {
1330 			*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1331 			return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1332 		}
1333 	}
1334 	// Check the value (individually).
1335 	if (rhs >= N_INPUT_SYSTEM_MULTIPLEX) {
1336 		*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1337 		return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
1338 	}
1339 	// Set the value.
1340 	*lhs = rhs;
1341 
1342 	*flags |= INPUT_SYSTEM_CFG_FLAG_SET;
1343 	return INPUT_SYSTEM_ERR_NO_ERROR;
1344 }
1345