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