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