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