linux/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/input_system.c
<<
>>
Prefs
   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#ifndef ISP2401
  19
  20#include "input_system.h"
  21#include <type_support.h>
  22#include "gp_device.h"
  23
  24#include "assert_support.h"
  25
  26#ifndef __INLINE_INPUT_SYSTEM__
  27#include "input_system_private.h"
  28#endif /* __INLINE_INPUT_SYSTEM__ */
  29
  30#define ZERO (0x0)
  31#define ONE  (1U)
  32
  33static const isp2400_ib_buffer_t   IB_BUFFER_NULL = {0, 0, 0 };
  34
  35static input_system_err_t input_system_configure_channel(
  36    const channel_cfg_t         channel);
  37
  38static input_system_err_t input_system_configure_channel_sensor(
  39    const channel_cfg_t         channel);
  40
  41static input_system_err_t input_buffer_configuration(void);
  42
  43static input_system_err_t configuration_to_registers(void);
  44
  45static void receiver_rst(const rx_ID_t ID);
  46static void input_system_network_rst(const input_system_ID_t ID);
  47
  48static void capture_unit_configure(
  49    const input_system_ID_t                     ID,
  50    const sub_system_ID_t                       sub_id,
  51    const isp2400_ib_buffer_t *const cfg);
  52
  53static void acquisition_unit_configure(
  54    const input_system_ID_t                     ID,
  55    const sub_system_ID_t                       sub_id,
  56    const isp2400_ib_buffer_t *const cfg);
  57
  58static void ctrl_unit_configure(
  59    const input_system_ID_t                     ID,
  60    const sub_system_ID_t                       sub_id,
  61    const ctrl_unit_cfg_t *const cfg);
  62
  63static void input_system_network_configure(
  64    const input_system_ID_t                     ID,
  65    const input_system_network_cfg_t *const cfg);
  66
  67// MW: CSI is previously named as "rx" short for "receiver"
  68static input_system_err_t set_csi_cfg(
  69    csi_cfg_t *const lhs,
  70    const csi_cfg_t *const rhs,
  71    input_system_config_flags_t *const flags);
  72
  73static input_system_err_t set_source_type(
  74    input_system_source_t *const lhs,
  75    const input_system_source_t                         rhs,
  76    input_system_config_flags_t *const flags);
  77
  78static input_system_err_t input_system_multiplexer_cfg(
  79    input_system_multiplex_t *const lhs,
  80    const input_system_multiplex_t                      rhs,
  81    input_system_config_flags_t *const flags);
  82
  83static inline void capture_unit_get_state(
  84    const input_system_ID_t                     ID,
  85    const sub_system_ID_t                       sub_id,
  86    capture_unit_state_t                        *state);
  87
  88static inline void acquisition_unit_get_state(
  89    const input_system_ID_t                     ID,
  90    const sub_system_ID_t                       sub_id,
  91    acquisition_unit_state_t            *state);
  92
  93static inline void ctrl_unit_get_state(
  94    const input_system_ID_t                     ID,
  95    const sub_system_ID_t                       sub_id,
  96    ctrl_unit_state_t                           *state);
  97
  98static inline void mipi_port_get_state(
  99    const rx_ID_t                                       ID,
 100    const enum mipi_port_id                     port_ID,
 101    mipi_port_state_t                           *state);
 102
 103static inline void rx_channel_get_state(
 104    const rx_ID_t                                       ID,
 105    const unsigned int                          ch_id,
 106    rx_channel_state_t                          *state);
 107
 108static void gp_device_rst(const gp_device_ID_t          ID);
 109
 110static void input_selector_cfg_for_sensor(const gp_device_ID_t  ID);
 111
 112static void input_switch_rst(const gp_device_ID_t       ID);
 113
 114static void input_switch_cfg(
 115    const gp_device_ID_t                                ID,
 116    const input_switch_cfg_t *const cfg
 117);
 118
 119void input_system_get_state(
 120    const input_system_ID_t                     ID,
 121    input_system_state_t                        *state)
 122{
 123        sub_system_ID_t sub_id;
 124
 125        assert(ID < N_INPUT_SYSTEM_ID);
 126        assert(state);
 127
 128        state->str_multicastA_sel = input_system_sub_system_reg_load(ID,
 129                                    GPREGS_UNIT0_ID,
 130                                    HIVE_ISYS_GPREG_MULTICAST_A_IDX);
 131        state->str_multicastB_sel = input_system_sub_system_reg_load(ID,
 132                                    GPREGS_UNIT0_ID,
 133                                    HIVE_ISYS_GPREG_MULTICAST_B_IDX);
 134        state->str_multicastC_sel = input_system_sub_system_reg_load(ID,
 135                                    GPREGS_UNIT0_ID,
 136                                    HIVE_ISYS_GPREG_MULTICAST_C_IDX);
 137        state->str_mux_sel = input_system_sub_system_reg_load(ID,
 138                             GPREGS_UNIT0_ID,
 139                             HIVE_ISYS_GPREG_MUX_IDX);
 140        state->str_mon_status = input_system_sub_system_reg_load(ID,
 141                                GPREGS_UNIT0_ID,
 142                                HIVE_ISYS_GPREG_STRMON_STAT_IDX);
 143        state->str_mon_irq_cond = input_system_sub_system_reg_load(ID,
 144                                  GPREGS_UNIT0_ID,
 145                                  HIVE_ISYS_GPREG_STRMON_COND_IDX);
 146        state->str_mon_irq_en = input_system_sub_system_reg_load(ID,
 147                                GPREGS_UNIT0_ID,
 148                                HIVE_ISYS_GPREG_STRMON_IRQ_EN_IDX);
 149        state->isys_srst = input_system_sub_system_reg_load(ID,
 150                           GPREGS_UNIT0_ID,
 151                           HIVE_ISYS_GPREG_SRST_IDX);
 152        state->isys_slv_reg_srst = input_system_sub_system_reg_load(ID,
 153                                   GPREGS_UNIT0_ID,
 154                                   HIVE_ISYS_GPREG_SLV_REG_SRST_IDX);
 155        state->str_deint_portA_cnt = input_system_sub_system_reg_load(ID,
 156                                     GPREGS_UNIT0_ID,
 157                                     HIVE_ISYS_GPREG_REG_PORT_A_IDX);
 158        state->str_deint_portB_cnt = input_system_sub_system_reg_load(ID,
 159                                     GPREGS_UNIT0_ID,
 160                                     HIVE_ISYS_GPREG_REG_PORT_B_IDX);
 161
 162        for (sub_id = CAPTURE_UNIT0_ID; sub_id < CAPTURE_UNIT0_ID + N_CAPTURE_UNIT_ID;
 163             sub_id++) {
 164                capture_unit_get_state(ID, sub_id,
 165                                       &state->capture_unit[sub_id - CAPTURE_UNIT0_ID]);
 166        }
 167        for (sub_id = ACQUISITION_UNIT0_ID;
 168             sub_id < ACQUISITION_UNIT0_ID + N_ACQUISITION_UNIT_ID; sub_id++) {
 169                acquisition_unit_get_state(ID, sub_id,
 170                                           &state->acquisition_unit[sub_id - ACQUISITION_UNIT0_ID]);
 171        }
 172        for (sub_id = CTRL_UNIT0_ID; sub_id < CTRL_UNIT0_ID + N_CTRL_UNIT_ID;
 173             sub_id++) {
 174                ctrl_unit_get_state(ID, sub_id,
 175                                    &state->ctrl_unit_state[sub_id - CTRL_UNIT0_ID]);
 176        }
 177}
 178
 179void receiver_get_state(
 180    const rx_ID_t                               ID,
 181    receiver_state_t                    *state)
 182{
 183        enum mipi_port_id       port_id;
 184        unsigned int    ch_id;
 185
 186        assert(ID < N_RX_ID);
 187        assert(state);
 188
 189        state->fs_to_ls_delay = (uint8_t)receiver_reg_load(ID,
 190                                _HRT_CSS_RECEIVER_FS_TO_LS_DELAY_REG_IDX);
 191        state->ls_to_data_delay = (uint8_t)receiver_reg_load(ID,
 192                                  _HRT_CSS_RECEIVER_LS_TO_DATA_DELAY_REG_IDX);
 193        state->data_to_le_delay = (uint8_t)receiver_reg_load(ID,
 194                                  _HRT_CSS_RECEIVER_DATA_TO_LE_DELAY_REG_IDX);
 195        state->le_to_fe_delay = (uint8_t)receiver_reg_load(ID,
 196                                _HRT_CSS_RECEIVER_LE_TO_FE_DELAY_REG_IDX);
 197        state->fe_to_fs_delay = (uint8_t)receiver_reg_load(ID,
 198                                _HRT_CSS_RECEIVER_FE_TO_FS_DELAY_REG_IDX);
 199        state->le_to_fs_delay = (uint8_t)receiver_reg_load(ID,
 200                                _HRT_CSS_RECEIVER_LE_TO_LS_DELAY_REG_IDX);
 201        state->is_two_ppc = (bool)receiver_reg_load(ID,
 202                            _HRT_CSS_RECEIVER_TWO_PIXEL_EN_REG_IDX);
 203        state->backend_rst = receiver_reg_load(ID,
 204                                               _HRT_CSS_RECEIVER_BACKEND_RST_REG_IDX);
 205        state->raw18 = (uint16_t)receiver_reg_load(ID,
 206                       _HRT_CSS_RECEIVER_RAW18_REG_IDX);
 207        state->force_raw8 = (bool)receiver_reg_load(ID,
 208                            _HRT_CSS_RECEIVER_FORCE_RAW8_REG_IDX);
 209        state->raw16 = (uint16_t)receiver_reg_load(ID,
 210                       _HRT_CSS_RECEIVER_RAW16_REG_IDX);
 211
 212        for (port_id = (enum mipi_port_id)0; port_id < N_MIPI_PORT_ID; port_id++) {
 213                mipi_port_get_state(ID, port_id,
 214                                    &state->mipi_port_state[port_id]);
 215        }
 216        for (ch_id = 0U; ch_id < N_RX_CHANNEL_ID; ch_id++) {
 217                rx_channel_get_state(ID, ch_id,
 218                                     &state->rx_channel_state[ch_id]);
 219        }
 220
 221        state->be_gsp_acc_ovl = receiver_reg_load(ID,
 222                                _HRT_CSS_RECEIVER_BE_GSP_ACC_OVL_REG_IDX);
 223        state->be_srst = receiver_reg_load(ID,
 224                                           _HRT_CSS_RECEIVER_BE_SRST_REG_IDX);
 225        state->be_is_two_ppc = receiver_reg_load(ID,
 226                               _HRT_CSS_RECEIVER_BE_TWO_PPC_REG_IDX);
 227        state->be_comp_format0 = receiver_reg_load(ID,
 228                                 _HRT_CSS_RECEIVER_BE_COMP_FORMAT_REG0_IDX);
 229        state->be_comp_format1 = receiver_reg_load(ID,
 230                                 _HRT_CSS_RECEIVER_BE_COMP_FORMAT_REG1_IDX);
 231        state->be_comp_format2 = receiver_reg_load(ID,
 232                                 _HRT_CSS_RECEIVER_BE_COMP_FORMAT_REG2_IDX);
 233        state->be_comp_format3 = receiver_reg_load(ID,
 234                                 _HRT_CSS_RECEIVER_BE_COMP_FORMAT_REG3_IDX);
 235        state->be_sel = receiver_reg_load(ID,
 236                                          _HRT_CSS_RECEIVER_BE_SEL_REG_IDX);
 237        state->be_raw16_config = receiver_reg_load(ID,
 238                                 _HRT_CSS_RECEIVER_BE_RAW16_CONFIG_REG_IDX);
 239        state->be_raw18_config = receiver_reg_load(ID,
 240                                 _HRT_CSS_RECEIVER_BE_RAW18_CONFIG_REG_IDX);
 241        state->be_force_raw8 = receiver_reg_load(ID,
 242                               _HRT_CSS_RECEIVER_BE_FORCE_RAW8_REG_IDX);
 243        state->be_irq_status = receiver_reg_load(ID,
 244                               _HRT_CSS_RECEIVER_BE_IRQ_STATUS_REG_IDX);
 245        state->be_irq_clear = receiver_reg_load(ID,
 246                                                _HRT_CSS_RECEIVER_BE_IRQ_CLEAR_REG_IDX);
 247}
 248
 249bool is_mipi_format_yuv420(
 250    const mipi_format_t                 mipi_format)
 251{
 252        bool    is_yuv420 = (
 253                                (mipi_format == MIPI_FORMAT_YUV420_8) ||
 254                                (mipi_format == MIPI_FORMAT_YUV420_10) ||
 255                                (mipi_format == MIPI_FORMAT_YUV420_8_SHIFT) ||
 256                                (mipi_format == MIPI_FORMAT_YUV420_10_SHIFT));
 257        /* MIPI_FORMAT_YUV420_8_LEGACY is not YUV420 */
 258
 259        return is_yuv420;
 260}
 261
 262void receiver_set_compression(
 263    const rx_ID_t                       ID,
 264    const unsigned int          cfg_ID,
 265    const mipi_compressor_t             comp,
 266    const mipi_predictor_t              pred)
 267{
 268        const unsigned int              field_id = cfg_ID % N_MIPI_FORMAT_CUSTOM;
 269        const unsigned int              ch_id = cfg_ID / N_MIPI_FORMAT_CUSTOM;
 270        hrt_data                        val;
 271        hrt_address                     addr = 0;
 272        hrt_data                        reg;
 273
 274        assert(ID < N_RX_ID);
 275        assert(cfg_ID < N_MIPI_COMPRESSOR_CONTEXT);
 276        assert(field_id < N_MIPI_FORMAT_CUSTOM);
 277        assert(ch_id < N_RX_CHANNEL_ID);
 278        assert(comp < N_MIPI_COMPRESSOR_METHODS);
 279        assert(pred < N_MIPI_PREDICTOR_TYPES);
 280
 281        val = (((uint8_t)pred) << 3) | comp;
 282
 283        switch (ch_id) {
 284        case 0:
 285                addr = ((field_id < 6) ? _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC0_REG0_IDX :
 286                        _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC0_REG1_IDX);
 287                break;
 288        case 1:
 289                addr = ((field_id < 6) ? _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC1_REG0_IDX :
 290                        _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC1_REG1_IDX);
 291                break;
 292        case 2:
 293                addr = ((field_id < 6) ? _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC2_REG0_IDX :
 294                        _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC2_REG1_IDX);
 295                break;
 296        case 3:
 297                addr = ((field_id < 6) ? _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC3_REG0_IDX :
 298                        _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC3_REG1_IDX);
 299                break;
 300        default:
 301                /* should not happen */
 302                assert(false);
 303                return;
 304        }
 305
 306        reg = ((field_id < 6) ? (val << (field_id * 5)) : (val << ((
 307                    field_id - 6) * 5)));
 308        receiver_reg_store(ID, addr, reg);
 309}
 310
 311void receiver_port_enable(
 312    const rx_ID_t                       ID,
 313    const enum mipi_port_id             port_ID,
 314    const bool                  cnd)
 315{
 316        hrt_data        reg = receiver_port_reg_load(ID, port_ID,
 317                          _HRT_CSS_RECEIVER_DEVICE_READY_REG_IDX);
 318
 319        if (cnd) {
 320                reg |= 0x01;
 321        } else {
 322                reg &= ~0x01;
 323        }
 324
 325        receiver_port_reg_store(ID, port_ID,
 326                                _HRT_CSS_RECEIVER_DEVICE_READY_REG_IDX, reg);
 327}
 328
 329bool is_receiver_port_enabled(
 330    const rx_ID_t                       ID,
 331    const enum mipi_port_id             port_ID)
 332{
 333        hrt_data        reg = receiver_port_reg_load(ID, port_ID,
 334                          _HRT_CSS_RECEIVER_DEVICE_READY_REG_IDX);
 335        return ((reg & 0x01) != 0);
 336}
 337
 338void receiver_irq_enable(
 339    const rx_ID_t                       ID,
 340    const enum mipi_port_id             port_ID,
 341    const rx_irq_info_t         irq_info)
 342{
 343        receiver_port_reg_store(ID,
 344                                port_ID, _HRT_CSS_RECEIVER_IRQ_ENABLE_REG_IDX, irq_info);
 345}
 346
 347rx_irq_info_t receiver_get_irq_info(
 348    const rx_ID_t                       ID,
 349    const enum mipi_port_id             port_ID)
 350{
 351        return receiver_port_reg_load(ID,
 352                                      port_ID, _HRT_CSS_RECEIVER_IRQ_STATUS_REG_IDX);
 353}
 354
 355void receiver_irq_clear(
 356    const rx_ID_t                       ID,
 357    const enum mipi_port_id             port_ID,
 358    const rx_irq_info_t         irq_info)
 359{
 360        receiver_port_reg_store(ID,
 361                                port_ID, _HRT_CSS_RECEIVER_IRQ_STATUS_REG_IDX, irq_info);
 362}
 363
 364static inline void capture_unit_get_state(
 365    const input_system_ID_t                     ID,
 366    const sub_system_ID_t                       sub_id,
 367    capture_unit_state_t                        *state)
 368{
 369        assert(/*(sub_id >= CAPTURE_UNIT0_ID) &&*/ (sub_id <= CAPTURE_UNIT2_ID));
 370        assert(state);
 371
 372        state->StartMode = input_system_sub_system_reg_load(ID,
 373                           sub_id,
 374                           CAPT_START_MODE_REG_ID);
 375        state->Start_Addr = input_system_sub_system_reg_load(ID,
 376                            sub_id,
 377                            CAPT_START_ADDR_REG_ID);
 378        state->Mem_Region_Size = input_system_sub_system_reg_load(ID,
 379                                 sub_id,
 380                                 CAPT_MEM_REGION_SIZE_REG_ID);
 381        state->Num_Mem_Regions = input_system_sub_system_reg_load(ID,
 382                                 sub_id,
 383                                 CAPT_NUM_MEM_REGIONS_REG_ID);
 384//      AM: Illegal read from following registers.
 385        /*      state->Init = input_system_sub_system_reg_load(ID,
 386                        sub_id,
 387                        CAPT_INIT_REG_ID);
 388                state->Start = input_system_sub_system_reg_load(ID,
 389                        sub_id,
 390                        CAPT_START_REG_ID);
 391                state->Stop = input_system_sub_system_reg_load(ID,
 392                        sub_id,
 393                        CAPT_STOP_REG_ID);
 394        */
 395        state->Packet_Length = input_system_sub_system_reg_load(ID,
 396                               sub_id,
 397                               CAPT_PACKET_LENGTH_REG_ID);
 398        state->Received_Length = input_system_sub_system_reg_load(ID,
 399                                 sub_id,
 400                                 CAPT_RECEIVED_LENGTH_REG_ID);
 401        state->Received_Short_Packets = input_system_sub_system_reg_load(ID,
 402                                        sub_id,
 403                                        CAPT_RECEIVED_SHORT_PACKETS_REG_ID);
 404        state->Received_Long_Packets = input_system_sub_system_reg_load(ID,
 405                                       sub_id,
 406                                       CAPT_RECEIVED_LONG_PACKETS_REG_ID);
 407        state->Last_Command = input_system_sub_system_reg_load(ID,
 408                              sub_id,
 409                              CAPT_LAST_COMMAND_REG_ID);
 410        state->Next_Command = input_system_sub_system_reg_load(ID,
 411                              sub_id,
 412                              CAPT_NEXT_COMMAND_REG_ID);
 413        state->Last_Acknowledge = input_system_sub_system_reg_load(ID,
 414                                  sub_id,
 415                                  CAPT_LAST_ACKNOWLEDGE_REG_ID);
 416        state->Next_Acknowledge = input_system_sub_system_reg_load(ID,
 417                                  sub_id,
 418                                  CAPT_NEXT_ACKNOWLEDGE_REG_ID);
 419        state->FSM_State_Info = input_system_sub_system_reg_load(ID,
 420                                sub_id,
 421                                CAPT_FSM_STATE_INFO_REG_ID);
 422}
 423
 424static inline void acquisition_unit_get_state(
 425    const input_system_ID_t                     ID,
 426    const sub_system_ID_t                       sub_id,
 427    acquisition_unit_state_t            *state)
 428{
 429        assert(sub_id == ACQUISITION_UNIT0_ID);
 430        assert(state);
 431
 432        state->Start_Addr = input_system_sub_system_reg_load(ID,
 433                            sub_id,
 434                            ACQ_START_ADDR_REG_ID);
 435        state->Mem_Region_Size = input_system_sub_system_reg_load(ID,
 436                                 sub_id,
 437                                 ACQ_MEM_REGION_SIZE_REG_ID);
 438        state->Num_Mem_Regions = input_system_sub_system_reg_load(ID,
 439                                 sub_id,
 440                                 ACQ_NUM_MEM_REGIONS_REG_ID);
 441//      AM: Illegal read from following registers.
 442        /*      state->Init = input_system_sub_system_reg_load(ID,
 443                        sub_id,
 444                        ACQ_INIT_REG_ID);
 445        */
 446        state->Received_Short_Packets = input_system_sub_system_reg_load(ID,
 447                                        sub_id,
 448                                        ACQ_RECEIVED_SHORT_PACKETS_REG_ID);
 449        state->Received_Long_Packets = input_system_sub_system_reg_load(ID,
 450                                       sub_id,
 451                                       ACQ_RECEIVED_LONG_PACKETS_REG_ID);
 452        state->Last_Command = input_system_sub_system_reg_load(ID,
 453                              sub_id,
 454                              ACQ_LAST_COMMAND_REG_ID);
 455        state->Next_Command = input_system_sub_system_reg_load(ID,
 456                              sub_id,
 457                              ACQ_NEXT_COMMAND_REG_ID);
 458        state->Last_Acknowledge = input_system_sub_system_reg_load(ID,
 459                                  sub_id,
 460                                  ACQ_LAST_ACKNOWLEDGE_REG_ID);
 461        state->Next_Acknowledge = input_system_sub_system_reg_load(ID,
 462                                  sub_id,
 463                                  ACQ_NEXT_ACKNOWLEDGE_REG_ID);
 464        state->FSM_State_Info = input_system_sub_system_reg_load(ID,
 465                                sub_id,
 466                                ACQ_FSM_STATE_INFO_REG_ID);
 467        state->Int_Cntr_Info = input_system_sub_system_reg_load(ID,
 468                               sub_id,
 469                               ACQ_INT_CNTR_INFO_REG_ID);
 470}
 471
 472static inline void ctrl_unit_get_state(
 473    const input_system_ID_t                     ID,
 474    const sub_system_ID_t                       sub_id,
 475    ctrl_unit_state_t                   *state)
 476{
 477        assert(sub_id == CTRL_UNIT0_ID);
 478        assert(state);
 479
 480        state->captA_start_addr = input_system_sub_system_reg_load(ID,
 481                                  sub_id,
 482                                  ISYS_CTRL_CAPT_START_ADDR_A_REG_ID);
 483        state->captB_start_addr = input_system_sub_system_reg_load(ID,
 484                                  sub_id,
 485                                  ISYS_CTRL_CAPT_START_ADDR_B_REG_ID);
 486        state->captC_start_addr = input_system_sub_system_reg_load(ID,
 487                                  sub_id,
 488                                  ISYS_CTRL_CAPT_START_ADDR_C_REG_ID);
 489        state->captA_mem_region_size = input_system_sub_system_reg_load(ID,
 490                                       sub_id,
 491                                       ISYS_CTRL_CAPT_MEM_REGION_SIZE_A_REG_ID);
 492        state->captB_mem_region_size = input_system_sub_system_reg_load(ID,
 493                                       sub_id,
 494                                       ISYS_CTRL_CAPT_MEM_REGION_SIZE_B_REG_ID);
 495        state->captC_mem_region_size = input_system_sub_system_reg_load(ID,
 496                                       sub_id,
 497                                       ISYS_CTRL_CAPT_MEM_REGION_SIZE_C_REG_ID);
 498        state->captA_num_mem_regions = input_system_sub_system_reg_load(ID,
 499                                       sub_id,
 500                                       ISYS_CTRL_CAPT_NUM_MEM_REGIONS_A_REG_ID);
 501        state->captB_num_mem_regions = input_system_sub_system_reg_load(ID,
 502                                       sub_id,
 503                                       ISYS_CTRL_CAPT_NUM_MEM_REGIONS_B_REG_ID);
 504        state->captC_num_mem_regions = input_system_sub_system_reg_load(ID,
 505                                       sub_id,
 506                                       ISYS_CTRL_CAPT_NUM_MEM_REGIONS_C_REG_ID);
 507        state->acq_start_addr = input_system_sub_system_reg_load(ID,
 508                                sub_id,
 509                                ISYS_CTRL_ACQ_START_ADDR_REG_ID);
 510        state->acq_mem_region_size = input_system_sub_system_reg_load(ID,
 511                                     sub_id,
 512                                     ISYS_CTRL_ACQ_MEM_REGION_SIZE_REG_ID);
 513        state->acq_num_mem_regions = input_system_sub_system_reg_load(ID,
 514                                     sub_id,
 515                                     ISYS_CTRL_ACQ_NUM_MEM_REGIONS_REG_ID);
 516//      AM: Illegal read from following registers.
 517        /*      state->ctrl_init = input_system_sub_system_reg_load(ID,
 518                        sub_id,
 519                        ISYS_CTRL_INIT_REG_ID);
 520        */
 521        state->last_cmd = input_system_sub_system_reg_load(ID,
 522                          sub_id,
 523                          ISYS_CTRL_LAST_COMMAND_REG_ID);
 524        state->next_cmd = input_system_sub_system_reg_load(ID,
 525                          sub_id,
 526                          ISYS_CTRL_NEXT_COMMAND_REG_ID);
 527        state->last_ack = input_system_sub_system_reg_load(ID,
 528                          sub_id,
 529                          ISYS_CTRL_LAST_ACKNOWLEDGE_REG_ID);
 530        state->next_ack = input_system_sub_system_reg_load(ID,
 531                          sub_id,
 532                          ISYS_CTRL_NEXT_ACKNOWLEDGE_REG_ID);
 533        state->top_fsm_state = input_system_sub_system_reg_load(ID,
 534                               sub_id,
 535                               ISYS_CTRL_FSM_STATE_INFO_REG_ID);
 536        state->captA_fsm_state = input_system_sub_system_reg_load(ID,
 537                                 sub_id,
 538                                 ISYS_CTRL_CAPT_A_FSM_STATE_INFO_REG_ID);
 539        state->captB_fsm_state = input_system_sub_system_reg_load(ID,
 540                                 sub_id,
 541                                 ISYS_CTRL_CAPT_B_FSM_STATE_INFO_REG_ID);
 542        state->captC_fsm_state = input_system_sub_system_reg_load(ID,
 543                                 sub_id,
 544                                 ISYS_CTRL_CAPT_C_FSM_STATE_INFO_REG_ID);
 545        state->acq_fsm_state = input_system_sub_system_reg_load(ID,
 546                               sub_id,
 547                               ISYS_CTRL_ACQ_FSM_STATE_INFO_REG_ID);
 548        state->capt_reserve_one_mem_region = input_system_sub_system_reg_load(ID,
 549                                             sub_id,
 550                                             ISYS_CTRL_CAPT_RESERVE_ONE_MEM_REGION_REG_ID);
 551}
 552
 553static inline void mipi_port_get_state(
 554    const rx_ID_t                               ID,
 555    const enum mipi_port_id                     port_ID,
 556    mipi_port_state_t                   *state)
 557{
 558        int     i;
 559
 560        assert(ID < N_RX_ID);
 561        assert(port_ID < N_MIPI_PORT_ID);
 562        assert(state);
 563
 564        state->device_ready = receiver_port_reg_load(ID,
 565                              port_ID, _HRT_CSS_RECEIVER_DEVICE_READY_REG_IDX);
 566        state->irq_status = receiver_port_reg_load(ID,
 567                            port_ID, _HRT_CSS_RECEIVER_IRQ_STATUS_REG_IDX);
 568        state->irq_enable = receiver_port_reg_load(ID,
 569                            port_ID, _HRT_CSS_RECEIVER_IRQ_ENABLE_REG_IDX);
 570        state->timeout_count = receiver_port_reg_load(ID,
 571                               port_ID, _HRT_CSS_RECEIVER_TIMEOUT_COUNT_REG_IDX);
 572        state->init_count = (uint16_t)receiver_port_reg_load(ID,
 573                            port_ID, _HRT_CSS_RECEIVER_INIT_COUNT_REG_IDX);
 574        state->raw16_18 = (uint16_t)receiver_port_reg_load(ID,
 575                          port_ID, _HRT_CSS_RECEIVER_RAW16_18_DATAID_REG_IDX);
 576        state->sync_count = receiver_port_reg_load(ID,
 577                            port_ID, _HRT_CSS_RECEIVER_SYNC_COUNT_REG_IDX);
 578        state->rx_count = receiver_port_reg_load(ID,
 579                          port_ID, _HRT_CSS_RECEIVER_RX_COUNT_REG_IDX);
 580
 581        for (i = 0; i < MIPI_4LANE_CFG ; i++) {
 582                state->lane_sync_count[i] = (uint8_t)((state->sync_count) >> (i * 8));
 583                state->lane_rx_count[i] = (uint8_t)((state->rx_count) >> (i * 8));
 584        }
 585}
 586
 587static inline void rx_channel_get_state(
 588    const rx_ID_t                                       ID,
 589    const unsigned int                          ch_id,
 590    rx_channel_state_t                          *state)
 591{
 592        int     i;
 593
 594        assert(ID < N_RX_ID);
 595        assert(ch_id < N_RX_CHANNEL_ID);
 596        assert(state);
 597
 598        switch (ch_id) {
 599        case 0:
 600                state->comp_scheme0 = receiver_reg_load(ID,
 601                                                        _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC0_REG0_IDX);
 602                state->comp_scheme1 = receiver_reg_load(ID,
 603                                                        _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC0_REG1_IDX);
 604                break;
 605        case 1:
 606                state->comp_scheme0 = receiver_reg_load(ID,
 607                                                        _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC1_REG0_IDX);
 608                state->comp_scheme1 = receiver_reg_load(ID,
 609                                                        _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC1_REG1_IDX);
 610                break;
 611        case 2:
 612                state->comp_scheme0 = receiver_reg_load(ID,
 613                                                        _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC2_REG0_IDX);
 614                state->comp_scheme1 = receiver_reg_load(ID,
 615                                                        _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC2_REG1_IDX);
 616                break;
 617        case 3:
 618                state->comp_scheme0 = receiver_reg_load(ID,
 619                                                        _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC3_REG0_IDX);
 620                state->comp_scheme1 = receiver_reg_load(ID,
 621                                                        _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC3_REG1_IDX);
 622                break;
 623        }
 624
 625        /* See Table 7.1.17,..., 7.1.24 */
 626        for (i = 0; i < 6; i++) {
 627                u8      val = (uint8_t)((state->comp_scheme0) >> (i * 5)) & 0x1f;
 628
 629                state->comp[i] = (mipi_compressor_t)(val & 0x07);
 630                state->pred[i] = (mipi_predictor_t)((val & 0x18) >> 3);
 631        }
 632        for (i = 6; i < N_MIPI_FORMAT_CUSTOM; i++) {
 633                u8      val = (uint8_t)((state->comp_scheme0) >> ((i - 6) * 5)) & 0x1f;
 634
 635                state->comp[i] = (mipi_compressor_t)(val & 0x07);
 636                state->pred[i] = (mipi_predictor_t)((val & 0x18) >> 3);
 637        }
 638}
 639
 640// MW: "2400" in the name is not good, but this is to avoid a naming conflict
 641static input_system_cfg2400_t config;
 642
 643static void receiver_rst(
 644    const rx_ID_t                               ID)
 645{
 646        enum mipi_port_id               port_id;
 647
 648        assert(ID < N_RX_ID);
 649
 650// Disable all ports.
 651        for (port_id = MIPI_PORT0_ID; port_id < N_MIPI_PORT_ID; port_id++) {
 652                receiver_port_enable(ID, port_id, false);
 653        }
 654
 655        // AM: Additional actions for stopping receiver?
 656}
 657
 658//Single function to reset all the devices mapped via GP_DEVICE.
 659static void gp_device_rst(const gp_device_ID_t          ID)
 660{
 661        assert(ID < N_GP_DEVICE_ID);
 662
 663        gp_device_reg_store(ID, _REG_GP_SYNCGEN_ENABLE_ADDR, ZERO);
 664        // gp_device_reg_store(ID, _REG_GP_SYNCGEN_FREE_RUNNING_ADDR, ZERO);
 665        // gp_device_reg_store(ID, _REG_GP_SYNCGEN_PAUSE_ADDR, ONE);
 666        // gp_device_reg_store(ID, _REG_GP_NR_FRAMES_ADDR, ZERO);
 667        // gp_device_reg_store(ID, _REG_GP_SYNGEN_NR_PIX_ADDR, ZERO);
 668        // gp_device_reg_store(ID, _REG_GP_SYNGEN_NR_PIX_ADDR, ZERO);
 669        // gp_device_reg_store(ID, _REG_GP_SYNGEN_NR_LINES_ADDR, ZERO);
 670        // gp_device_reg_store(ID, _REG_GP_SYNGEN_HBLANK_CYCLES_ADDR, ZERO);
 671        // gp_device_reg_store(ID, _REG_GP_SYNGEN_VBLANK_CYCLES_ADDR, ZERO);
 672// AM: Following calls cause strange warnings. Probably they should not be initialized.
 673//      gp_device_reg_store(ID, _REG_GP_ISEL_SOF_ADDR, ZERO);
 674//      gp_device_reg_store(ID, _REG_GP_ISEL_EOF_ADDR, ZERO);
 675//      gp_device_reg_store(ID, _REG_GP_ISEL_SOL_ADDR, ZERO);
 676//      gp_device_reg_store(ID, _REG_GP_ISEL_EOL_ADDR, ZERO);
 677        gp_device_reg_store(ID, _REG_GP_ISEL_LFSR_ENABLE_ADDR, ZERO);
 678        gp_device_reg_store(ID, _REG_GP_ISEL_LFSR_ENABLE_B_ADDR, ZERO);
 679        gp_device_reg_store(ID, _REG_GP_ISEL_LFSR_RESET_VALUE_ADDR, ZERO);
 680        gp_device_reg_store(ID, _REG_GP_ISEL_TPG_ENABLE_ADDR, ZERO);
 681        gp_device_reg_store(ID, _REG_GP_ISEL_TPG_ENABLE_B_ADDR, ZERO);
 682        gp_device_reg_store(ID, _REG_GP_ISEL_HOR_CNT_MASK_ADDR, ZERO);
 683        gp_device_reg_store(ID, _REG_GP_ISEL_VER_CNT_MASK_ADDR, ZERO);
 684        gp_device_reg_store(ID, _REG_GP_ISEL_XY_CNT_MASK_ADDR, ZERO);
 685        gp_device_reg_store(ID, _REG_GP_ISEL_HOR_CNT_DELTA_ADDR, ZERO);
 686        gp_device_reg_store(ID, _REG_GP_ISEL_VER_CNT_DELTA_ADDR, ZERO);
 687        gp_device_reg_store(ID, _REG_GP_ISEL_TPG_MODE_ADDR, ZERO);
 688        gp_device_reg_store(ID, _REG_GP_ISEL_TPG_RED1_ADDR, ZERO);
 689        gp_device_reg_store(ID, _REG_GP_ISEL_TPG_GREEN1_ADDR, ZERO);
 690        gp_device_reg_store(ID, _REG_GP_ISEL_TPG_BLUE1_ADDR, ZERO);
 691        gp_device_reg_store(ID, _REG_GP_ISEL_TPG_RED2_ADDR, ZERO);
 692        gp_device_reg_store(ID, _REG_GP_ISEL_TPG_GREEN2_ADDR, ZERO);
 693        gp_device_reg_store(ID, _REG_GP_ISEL_TPG_BLUE2_ADDR, ZERO);
 694        //gp_device_reg_store(ID, _REG_GP_ISEL_CH_ID_ADDR, ZERO);
 695        //gp_device_reg_store(ID, _REG_GP_ISEL_FMT_TYPE_ADDR, ZERO);
 696        gp_device_reg_store(ID, _REG_GP_ISEL_DATA_SEL_ADDR, ZERO);
 697        gp_device_reg_store(ID, _REG_GP_ISEL_SBAND_SEL_ADDR, ZERO);
 698        gp_device_reg_store(ID, _REG_GP_ISEL_SYNC_SEL_ADDR, ZERO);
 699        //      gp_device_reg_store(ID, _REG_GP_SYNCGEN_HOR_CNT_ADDR, ZERO);
 700        //      gp_device_reg_store(ID, _REG_GP_SYNCGEN_VER_CNT_ADDR, ZERO);
 701        //      gp_device_reg_store(ID, _REG_GP_SYNCGEN_FRAME_CNT_ADDR, ZERO);
 702        gp_device_reg_store(ID, _REG_GP_SOFT_RESET_ADDR,
 703                            ZERO); // AM: Maybe this soft reset is not safe.
 704}
 705
 706static void input_selector_cfg_for_sensor(const gp_device_ID_t ID)
 707{
 708        assert(ID < N_GP_DEVICE_ID);
 709
 710        gp_device_reg_store(ID, _REG_GP_ISEL_SOF_ADDR, ONE);
 711        gp_device_reg_store(ID, _REG_GP_ISEL_EOF_ADDR, ONE);
 712        gp_device_reg_store(ID, _REG_GP_ISEL_SOL_ADDR, ONE);
 713        gp_device_reg_store(ID, _REG_GP_ISEL_EOL_ADDR, ONE);
 714        gp_device_reg_store(ID, _REG_GP_ISEL_CH_ID_ADDR, ZERO);
 715        gp_device_reg_store(ID, _REG_GP_ISEL_FMT_TYPE_ADDR, ZERO);
 716        gp_device_reg_store(ID, _REG_GP_ISEL_DATA_SEL_ADDR, ZERO);
 717        gp_device_reg_store(ID, _REG_GP_ISEL_SBAND_SEL_ADDR, ZERO);
 718        gp_device_reg_store(ID, _REG_GP_ISEL_SYNC_SEL_ADDR, ZERO);
 719        gp_device_reg_store(ID, _REG_GP_SOFT_RESET_ADDR, ZERO);
 720}
 721
 722static void input_switch_rst(const gp_device_ID_t ID)
 723{
 724        int addr;
 725
 726        assert(ID < N_GP_DEVICE_ID);
 727
 728        // Initialize the data&hsync LUT.
 729        for (addr = _REG_GP_IFMT_input_switch_lut_reg0;
 730             addr <= _REG_GP_IFMT_input_switch_lut_reg7; addr += SIZEOF_HRT_REG) {
 731                gp_device_reg_store(ID, addr, ZERO);
 732        }
 733
 734        // Initialize the vsync LUT.
 735        gp_device_reg_store(ID,
 736                            _REG_GP_IFMT_input_switch_fsync_lut,
 737                            ZERO);
 738}
 739
 740static void input_switch_cfg(
 741    const gp_device_ID_t                        ID,
 742    const input_switch_cfg_t *const cfg)
 743{
 744        int addr_offset;
 745
 746        assert(ID < N_GP_DEVICE_ID);
 747        assert(cfg);
 748
 749        // Initialize the data&hsync LUT.
 750        for (addr_offset = 0; addr_offset < N_RX_CHANNEL_ID * 2; addr_offset++) {
 751                assert(addr_offset * SIZEOF_HRT_REG + _REG_GP_IFMT_input_switch_lut_reg0 <=
 752                       _REG_GP_IFMT_input_switch_lut_reg7);
 753                gp_device_reg_store(ID,
 754                                    _REG_GP_IFMT_input_switch_lut_reg0 + addr_offset * SIZEOF_HRT_REG,
 755                                    cfg->hsync_data_reg[addr_offset]);
 756        }
 757
 758        // Initialize the vsync LUT.
 759        gp_device_reg_store(ID,
 760                            _REG_GP_IFMT_input_switch_fsync_lut,
 761                            cfg->vsync_data_reg);
 762}
 763
 764static void input_system_network_rst(const input_system_ID_t ID)
 765{
 766        unsigned int sub_id;
 767
 768        // Reset all 3 multicasts.
 769        input_system_sub_system_reg_store(ID,
 770                                          GPREGS_UNIT0_ID,
 771                                          HIVE_ISYS_GPREG_MULTICAST_A_IDX,
 772                                          INPUT_SYSTEM_DISCARD_ALL);
 773        input_system_sub_system_reg_store(ID,
 774                                          GPREGS_UNIT0_ID,
 775                                          HIVE_ISYS_GPREG_MULTICAST_B_IDX,
 776                                          INPUT_SYSTEM_DISCARD_ALL);
 777        input_system_sub_system_reg_store(ID,
 778                                          GPREGS_UNIT0_ID,
 779                                          HIVE_ISYS_GPREG_MULTICAST_C_IDX,
 780                                          INPUT_SYSTEM_DISCARD_ALL);
 781
 782        // Reset stream mux.
 783        input_system_sub_system_reg_store(ID,
 784                                          GPREGS_UNIT0_ID,
 785                                          HIVE_ISYS_GPREG_MUX_IDX,
 786                                          N_INPUT_SYSTEM_MULTIPLEX);
 787
 788        // Reset 3 capture units.
 789        for (sub_id = CAPTURE_UNIT0_ID; sub_id < CAPTURE_UNIT0_ID + N_CAPTURE_UNIT_ID;
 790             sub_id++) {
 791                input_system_sub_system_reg_store(ID,
 792                                                  sub_id,
 793                                                  CAPT_INIT_REG_ID,
 794                                                  1U << CAPT_INIT_RST_REG_BIT);
 795        }
 796
 797        // Reset acquisition unit.
 798        for (sub_id = ACQUISITION_UNIT0_ID;
 799             sub_id < ACQUISITION_UNIT0_ID + N_ACQUISITION_UNIT_ID; sub_id++) {
 800                input_system_sub_system_reg_store(ID,
 801                                                  sub_id,
 802                                                  ACQ_INIT_REG_ID,
 803                                                  1U << ACQ_INIT_RST_REG_BIT);
 804        }
 805
 806        // DMA unit reset is not needed.
 807
 808        // Reset controller units.
 809        // NB: In future we need to keep part of ctrl_state for split capture and
 810        for (sub_id = CTRL_UNIT0_ID; sub_id < CTRL_UNIT0_ID + N_CTRL_UNIT_ID;
 811             sub_id++) {
 812                input_system_sub_system_reg_store(ID,
 813                                                  sub_id,
 814                                                  ISYS_CTRL_INIT_REG_ID,
 815                                                  1U); //AM: Is there any named constant?
 816        }
 817}
 818
 819// Function that resets current configuration.
 820input_system_err_t input_system_configuration_reset(void)
 821{
 822        unsigned int i;
 823
 824        receiver_rst(RX0_ID);
 825
 826        input_system_network_rst(INPUT_SYSTEM0_ID);
 827
 828        gp_device_rst(GP_DEVICE0_ID);
 829
 830        input_switch_rst(GP_DEVICE0_ID);
 831
 832        //target_rst();
 833
 834        // Reset IRQ_CTRLs.
 835
 836        // Reset configuration data structures.
 837        for (i = 0; i < N_CHANNELS; i++) {
 838                config.ch_flags[i] = INPUT_SYSTEM_CFG_FLAG_RESET;
 839                config.target_isp_flags[i] = INPUT_SYSTEM_CFG_FLAG_RESET;
 840                config.target_sp_flags[i] = INPUT_SYSTEM_CFG_FLAG_RESET;
 841                config.target_strm2mem_flags[i] = INPUT_SYSTEM_CFG_FLAG_RESET;
 842        }
 843
 844        for (i = 0; i < N_CSI_PORTS; i++) {
 845                config.csi_buffer_flags[i]       = INPUT_SYSTEM_CFG_FLAG_RESET;
 846                config.multicast[i]              = INPUT_SYSTEM_DISCARD_ALL;
 847        }
 848
 849        config.source_type_flags                                 = INPUT_SYSTEM_CFG_FLAG_RESET;
 850        config.acquisition_buffer_unique_flags   = INPUT_SYSTEM_CFG_FLAG_RESET;
 851        config.unallocated_ib_mem_words                  = IB_CAPACITY_IN_WORDS;
 852        //config.acq_allocated_ib_mem_words              = 0;
 853
 854        // Set the start of the session cofiguration.
 855        config.session_flags = INPUT_SYSTEM_CFG_FLAG_REQUIRED;
 856
 857        return INPUT_SYSTEM_ERR_NO_ERROR;
 858}
 859
 860// MW: Comments are good, but doxygen is required, place it at the declaration
 861// Function that appends the channel to current configuration.
 862static input_system_err_t input_system_configure_channel(
 863    const channel_cfg_t         channel)
 864{
 865        input_system_err_t error = INPUT_SYSTEM_ERR_NO_ERROR;
 866        // Check if channel is not already configured.
 867        if (config.ch_flags[channel.ch_id] & INPUT_SYSTEM_CFG_FLAG_SET) {
 868                return INPUT_SYSTEM_ERR_CHANNEL_ALREADY_SET;
 869        } else {
 870                switch (channel.source_type) {
 871                case INPUT_SYSTEM_SOURCE_SENSOR:
 872                        error = input_system_configure_channel_sensor(channel);
 873                        break;
 874                case INPUT_SYSTEM_SOURCE_TPG:
 875                case INPUT_SYSTEM_SOURCE_PRBS:
 876                case INPUT_SYSTEM_SOURCE_FIFO:
 877                default:
 878                        return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
 879                }
 880
 881                if (error != INPUT_SYSTEM_ERR_NO_ERROR) return error;
 882                // Input switch channel configurations must be combined in united config.
 883                config.input_switch_cfg.hsync_data_reg[channel.source_cfg.csi_cfg.csi_port * 2]
 884                    =
 885                        channel.target_cfg.input_switch_channel_cfg.hsync_data_reg[0];
 886                config.input_switch_cfg.hsync_data_reg[channel.source_cfg.csi_cfg.csi_port * 2 +
 887                                                                                           1] =
 888                                                               channel.target_cfg.input_switch_channel_cfg.hsync_data_reg[1];
 889                config.input_switch_cfg.vsync_data_reg |=
 890                    (channel.target_cfg.input_switch_channel_cfg.vsync_data_reg & 0x7) <<
 891                    (channel.source_cfg.csi_cfg.csi_port * 3);
 892
 893                // Other targets are just copied and marked as set.
 894                config.target_isp[channel.source_cfg.csi_cfg.csi_port] =
 895                    channel.target_cfg.target_isp_cfg;
 896                config.target_sp[channel.source_cfg.csi_cfg.csi_port] =
 897                    channel.target_cfg.target_sp_cfg;
 898                config.target_strm2mem[channel.source_cfg.csi_cfg.csi_port] =
 899                    channel.target_cfg.target_strm2mem_cfg;
 900                config.target_isp_flags[channel.source_cfg.csi_cfg.csi_port] |=
 901                    INPUT_SYSTEM_CFG_FLAG_SET;
 902                config.target_sp_flags[channel.source_cfg.csi_cfg.csi_port] |=
 903                    INPUT_SYSTEM_CFG_FLAG_SET;
 904                config.target_strm2mem_flags[channel.source_cfg.csi_cfg.csi_port] |=
 905                    INPUT_SYSTEM_CFG_FLAG_SET;
 906
 907                config.ch_flags[channel.ch_id] = INPUT_SYSTEM_CFG_FLAG_SET;
 908        }
 909        return INPUT_SYSTEM_ERR_NO_ERROR;
 910}
 911
 912// Function that partitions input buffer space with determining addresses.
 913static input_system_err_t input_buffer_configuration(void)
 914{
 915        u32 current_address    = 0;
 916        u32 unallocated_memory = IB_CAPACITY_IN_WORDS;
 917
 918        isp2400_ib_buffer_t     candidate_buffer_acq  = IB_BUFFER_NULL;
 919        u32 size_requested;
 920        input_system_config_flags_t     acq_already_specified = INPUT_SYSTEM_CFG_FLAG_RESET;
 921        input_system_csi_port_t port;
 922
 923        for (port = INPUT_SYSTEM_PORT_A; port < N_INPUT_SYSTEM_PORTS; port++) {
 924                csi_cfg_t source = config.csi_value[port];//.csi_cfg;
 925
 926                if (config.csi_flags[port] & INPUT_SYSTEM_CFG_FLAG_SET) {
 927                        // Check and set csi buffer in input buffer.
 928                        switch (source.buffering_mode) {
 929                        case INPUT_SYSTEM_FIFO_CAPTURE:
 930                        case INPUT_SYSTEM_XMEM_ACQUIRE:
 931                                config.csi_buffer_flags[port] =
 932                                    INPUT_SYSTEM_CFG_FLAG_BLOCKED; // Well, not used.
 933                                break;
 934
 935                        case INPUT_SYSTEM_FIFO_CAPTURE_WITH_COUNTING:
 936                        case INPUT_SYSTEM_SRAM_BUFFERING:
 937                        case INPUT_SYSTEM_XMEM_BUFFERING:
 938                        case INPUT_SYSTEM_XMEM_CAPTURE:
 939                                size_requested = source.csi_buffer.mem_reg_size *
 940                                                 source.csi_buffer.nof_mem_regs;
 941                                if (source.csi_buffer.mem_reg_size > 0
 942                                    && source.csi_buffer.nof_mem_regs > 0
 943                                    && size_requested <= unallocated_memory
 944                                   ) {
 945                                        config.csi_buffer[port].mem_reg_addr = current_address;
 946                                        config.csi_buffer[port].mem_reg_size = source.csi_buffer.mem_reg_size;
 947                                        config.csi_buffer[port].nof_mem_regs = source.csi_buffer.nof_mem_regs;
 948                                        current_address         += size_requested;
 949                                        unallocated_memory      -= size_requested;
 950                                        config.csi_buffer_flags[port] = INPUT_SYSTEM_CFG_FLAG_SET;
 951                                } else {
 952                                        config.csi_buffer_flags[port] |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
 953                                        return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
 954                                }
 955                                break;
 956
 957                        default:
 958                                config.csi_buffer_flags[port] |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
 959                                return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
 960                        }
 961
 962                        // Check acquisition buffer specified but set it later since it has to be unique.
 963                        switch (source.buffering_mode) {
 964                        case INPUT_SYSTEM_FIFO_CAPTURE:
 965                        case INPUT_SYSTEM_SRAM_BUFFERING:
 966                        case INPUT_SYSTEM_XMEM_CAPTURE:
 967                                // Nothing to do.
 968                                break;
 969
 970                        case INPUT_SYSTEM_FIFO_CAPTURE_WITH_COUNTING:
 971                        case INPUT_SYSTEM_XMEM_BUFFERING:
 972                        case INPUT_SYSTEM_XMEM_ACQUIRE:
 973                                if (acq_already_specified == INPUT_SYSTEM_CFG_FLAG_RESET) {
 974                                        size_requested = source.acquisition_buffer.mem_reg_size
 975                                                         * source.acquisition_buffer.nof_mem_regs;
 976                                        if (source.acquisition_buffer.mem_reg_size > 0
 977                                            && source.acquisition_buffer.nof_mem_regs > 0
 978                                            && size_requested <= unallocated_memory
 979                                           ) {
 980                                                candidate_buffer_acq = source.acquisition_buffer;
 981                                                acq_already_specified = INPUT_SYSTEM_CFG_FLAG_SET;
 982                                        }
 983                                } else {
 984                                        // Check if specified acquisition buffer is the same as specified before.
 985                                        if (source.acquisition_buffer.mem_reg_size != candidate_buffer_acq.mem_reg_size
 986                                            || source.acquisition_buffer.nof_mem_regs !=  candidate_buffer_acq.nof_mem_regs
 987                                           ) {
 988                                                config.acquisition_buffer_unique_flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
 989                                                return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
 990                                        }
 991                                }
 992                                break;
 993
 994                        default:
 995                                return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
 996                        }
 997                } else {
 998                        config.csi_buffer_flags[port] = INPUT_SYSTEM_CFG_FLAG_BLOCKED;
 999                }
1000        } // end of for ( port )
1001
1002        // Set the acquisition buffer at the end.
1003        size_requested = candidate_buffer_acq.mem_reg_size *
1004                         candidate_buffer_acq.nof_mem_regs;
1005        if (acq_already_specified == INPUT_SYSTEM_CFG_FLAG_SET
1006            && size_requested <= unallocated_memory) {
1007                config.acquisition_buffer_unique.mem_reg_addr = current_address;
1008                config.acquisition_buffer_unique.mem_reg_size =
1009                    candidate_buffer_acq.mem_reg_size;
1010                config.acquisition_buffer_unique.nof_mem_regs =
1011                    candidate_buffer_acq.nof_mem_regs;
1012                current_address         += size_requested;
1013                unallocated_memory      -= size_requested;
1014                config.acquisition_buffer_unique_flags = INPUT_SYSTEM_CFG_FLAG_SET;
1015
1016                assert(current_address <= IB_CAPACITY_IN_WORDS);
1017        }
1018
1019        return INPUT_SYSTEM_ERR_NO_ERROR;
1020}
1021
1022static void capture_unit_configure(
1023    const input_system_ID_t                     ID,
1024    const sub_system_ID_t                       sub_id,
1025    const isp2400_ib_buffer_t *const cfg)
1026{
1027        assert(ID < N_INPUT_SYSTEM_ID);
1028        assert(/*(sub_id >= CAPTURE_UNIT0_ID) &&*/ (sub_id <=
1029                CAPTURE_UNIT2_ID)); // Commented part is always true.
1030        assert(cfg);
1031
1032        input_system_sub_system_reg_store(ID,
1033                                          sub_id,
1034                                          CAPT_START_ADDR_REG_ID,
1035                                          cfg->mem_reg_addr);
1036        input_system_sub_system_reg_store(ID,
1037                                          sub_id,
1038                                          CAPT_MEM_REGION_SIZE_REG_ID,
1039                                          cfg->mem_reg_size);
1040        input_system_sub_system_reg_store(ID,
1041                                          sub_id,
1042                                          CAPT_NUM_MEM_REGIONS_REG_ID,
1043                                          cfg->nof_mem_regs);
1044}
1045
1046static void acquisition_unit_configure(
1047    const input_system_ID_t                     ID,
1048    const sub_system_ID_t                       sub_id,
1049    const isp2400_ib_buffer_t *const cfg)
1050{
1051        assert(ID < N_INPUT_SYSTEM_ID);
1052        assert(sub_id == ACQUISITION_UNIT0_ID);
1053        assert(cfg);
1054
1055        input_system_sub_system_reg_store(ID,
1056                                          sub_id,
1057                                          ACQ_START_ADDR_REG_ID,
1058                                          cfg->mem_reg_addr);
1059        input_system_sub_system_reg_store(ID,
1060                                          sub_id,
1061                                          ACQ_NUM_MEM_REGIONS_REG_ID,
1062                                          cfg->nof_mem_regs);
1063        input_system_sub_system_reg_store(ID,
1064                                          sub_id,
1065                                          ACQ_MEM_REGION_SIZE_REG_ID,
1066                                          cfg->mem_reg_size);
1067}
1068
1069static void ctrl_unit_configure(
1070    const input_system_ID_t                     ID,
1071    const sub_system_ID_t                       sub_id,
1072    const ctrl_unit_cfg_t *const cfg)
1073{
1074        assert(ID < N_INPUT_SYSTEM_ID);
1075        assert(sub_id == CTRL_UNIT0_ID);
1076        assert(cfg);
1077
1078        input_system_sub_system_reg_store(ID,
1079                                          sub_id,
1080                                          ISYS_CTRL_CAPT_START_ADDR_A_REG_ID,
1081                                          cfg->buffer_mipi[CAPTURE_UNIT0_ID].mem_reg_addr);
1082        input_system_sub_system_reg_store(ID,
1083                                          sub_id,
1084                                          ISYS_CTRL_CAPT_MEM_REGION_SIZE_A_REG_ID,
1085                                          cfg->buffer_mipi[CAPTURE_UNIT0_ID].mem_reg_size);
1086        input_system_sub_system_reg_store(ID,
1087                                          sub_id,
1088                                          ISYS_CTRL_CAPT_NUM_MEM_REGIONS_A_REG_ID,
1089                                          cfg->buffer_mipi[CAPTURE_UNIT0_ID].nof_mem_regs);
1090
1091        input_system_sub_system_reg_store(ID,
1092                                          sub_id,
1093                                          ISYS_CTRL_CAPT_START_ADDR_B_REG_ID,
1094                                          cfg->buffer_mipi[CAPTURE_UNIT1_ID].mem_reg_addr);
1095        input_system_sub_system_reg_store(ID,
1096                                          sub_id,
1097                                          ISYS_CTRL_CAPT_MEM_REGION_SIZE_B_REG_ID,
1098                                          cfg->buffer_mipi[CAPTURE_UNIT1_ID].mem_reg_size);
1099        input_system_sub_system_reg_store(ID,
1100                                          sub_id,
1101                                          ISYS_CTRL_CAPT_NUM_MEM_REGIONS_B_REG_ID,
1102                                          cfg->buffer_mipi[CAPTURE_UNIT1_ID].nof_mem_regs);
1103
1104        input_system_sub_system_reg_store(ID,
1105                                          sub_id,
1106                                          ISYS_CTRL_CAPT_START_ADDR_C_REG_ID,
1107                                          cfg->buffer_mipi[CAPTURE_UNIT2_ID].mem_reg_addr);
1108        input_system_sub_system_reg_store(ID,
1109                                          sub_id,
1110                                          ISYS_CTRL_CAPT_MEM_REGION_SIZE_C_REG_ID,
1111                                          cfg->buffer_mipi[CAPTURE_UNIT2_ID].mem_reg_size);
1112        input_system_sub_system_reg_store(ID,
1113                                          sub_id,
1114                                          ISYS_CTRL_CAPT_NUM_MEM_REGIONS_C_REG_ID,
1115                                          cfg->buffer_mipi[CAPTURE_UNIT2_ID].nof_mem_regs);
1116
1117        input_system_sub_system_reg_store(ID,
1118                                          sub_id,
1119                                          ISYS_CTRL_ACQ_START_ADDR_REG_ID,
1120                                          cfg->buffer_acquire[ACQUISITION_UNIT0_ID - ACQUISITION_UNIT0_ID].mem_reg_addr);
1121        input_system_sub_system_reg_store(ID,
1122                                          sub_id,
1123                                          ISYS_CTRL_ACQ_MEM_REGION_SIZE_REG_ID,
1124                                          cfg->buffer_acquire[ACQUISITION_UNIT0_ID - ACQUISITION_UNIT0_ID].mem_reg_size);
1125        input_system_sub_system_reg_store(ID,
1126                                          sub_id,
1127                                          ISYS_CTRL_ACQ_NUM_MEM_REGIONS_REG_ID,
1128                                          cfg->buffer_acquire[ACQUISITION_UNIT0_ID - ACQUISITION_UNIT0_ID].nof_mem_regs);
1129        input_system_sub_system_reg_store(ID,
1130                                          sub_id,
1131                                          ISYS_CTRL_CAPT_RESERVE_ONE_MEM_REGION_REG_ID,
1132                                          0);
1133}
1134
1135static void input_system_network_configure(
1136    const input_system_ID_t                             ID,
1137    const input_system_network_cfg_t *const cfg)
1138{
1139        u32 sub_id;
1140
1141        assert(ID < N_INPUT_SYSTEM_ID);
1142        assert(cfg);
1143
1144        // Set all 3 multicasts.
1145        input_system_sub_system_reg_store(ID,
1146                                          GPREGS_UNIT0_ID,
1147                                          HIVE_ISYS_GPREG_MULTICAST_A_IDX,
1148                                          cfg->multicast_cfg[CAPTURE_UNIT0_ID]);
1149        input_system_sub_system_reg_store(ID,
1150                                          GPREGS_UNIT0_ID,
1151                                          HIVE_ISYS_GPREG_MULTICAST_B_IDX,
1152                                          cfg->multicast_cfg[CAPTURE_UNIT1_ID]);
1153        input_system_sub_system_reg_store(ID,
1154                                          GPREGS_UNIT0_ID,
1155                                          HIVE_ISYS_GPREG_MULTICAST_C_IDX,
1156                                          cfg->multicast_cfg[CAPTURE_UNIT2_ID]);
1157
1158        // Set stream mux.
1159        input_system_sub_system_reg_store(ID,
1160                                          GPREGS_UNIT0_ID,
1161                                          HIVE_ISYS_GPREG_MUX_IDX,
1162                                          cfg->mux_cfg);
1163
1164        // Set capture units.
1165        for (sub_id = CAPTURE_UNIT0_ID; sub_id < CAPTURE_UNIT0_ID + N_CAPTURE_UNIT_ID;
1166             sub_id++) {
1167                capture_unit_configure(ID,
1168                                       sub_id,
1169                                       &cfg->ctrl_unit_cfg[ID].buffer_mipi[sub_id - CAPTURE_UNIT0_ID]);
1170        }
1171
1172        // Set acquisition units.
1173        for (sub_id = ACQUISITION_UNIT0_ID;
1174             sub_id < ACQUISITION_UNIT0_ID + N_ACQUISITION_UNIT_ID; sub_id++) {
1175                acquisition_unit_configure(ID,
1176                                           sub_id,
1177                                           &cfg->ctrl_unit_cfg[sub_id - ACQUISITION_UNIT0_ID].buffer_acquire[sub_id -
1178                                                   ACQUISITION_UNIT0_ID]);
1179        }
1180
1181        // No DMA configuration needed. Ctrl_unit will fully control it.
1182
1183        // Set controller units.
1184        for (sub_id = CTRL_UNIT0_ID; sub_id < CTRL_UNIT0_ID + N_CTRL_UNIT_ID;
1185             sub_id++) {
1186                ctrl_unit_configure(ID,
1187                                    sub_id,
1188                                    &cfg->ctrl_unit_cfg[sub_id - CTRL_UNIT0_ID]);
1189        }
1190}
1191
1192static input_system_err_t configuration_to_registers(void)
1193{
1194        input_system_network_cfg_t input_system_network_cfg;
1195        int i;
1196
1197        assert(config.source_type_flags & INPUT_SYSTEM_CFG_FLAG_SET);
1198
1199        switch (config.source_type) {
1200        case INPUT_SYSTEM_SOURCE_SENSOR:
1201
1202                // Determine stream multicasts setting based on the mode of csi_cfg_t.
1203                // AM: This should be moved towards earlier function call, e.g. in
1204                // the commit function.
1205                for (i = MIPI_PORT0_ID; i < N_MIPI_PORT_ID; i++) {
1206                        if (config.csi_flags[i] & INPUT_SYSTEM_CFG_FLAG_SET) {
1207                                switch (config.csi_value[i].buffering_mode) {
1208                                case INPUT_SYSTEM_FIFO_CAPTURE:
1209                                        config.multicast[i] = INPUT_SYSTEM_CSI_BACKEND;
1210                                        break;
1211
1212                                case INPUT_SYSTEM_XMEM_CAPTURE:
1213                                case INPUT_SYSTEM_SRAM_BUFFERING:
1214                                case INPUT_SYSTEM_XMEM_BUFFERING:
1215                                        config.multicast[i] = INPUT_SYSTEM_INPUT_BUFFER;
1216                                        break;
1217
1218                                case INPUT_SYSTEM_FIFO_CAPTURE_WITH_COUNTING:
1219                                        config.multicast[i] = INPUT_SYSTEM_MULTICAST;
1220                                        break;
1221
1222                                case INPUT_SYSTEM_XMEM_ACQUIRE:
1223                                        config.multicast[i] = INPUT_SYSTEM_DISCARD_ALL;
1224                                        break;
1225
1226                                default:
1227                                        config.multicast[i] = INPUT_SYSTEM_DISCARD_ALL;
1228                                        return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
1229                                        //break;
1230                                }
1231                        } else {
1232                                config.multicast[i] = INPUT_SYSTEM_DISCARD_ALL;
1233                        }
1234
1235                        input_system_network_cfg.multicast_cfg[i] = config.multicast[i];
1236
1237                } // for
1238
1239                input_system_network_cfg.mux_cfg = config.multiplexer;
1240
1241                input_system_network_cfg.ctrl_unit_cfg[CTRL_UNIT0_ID -
1242                                                       CTRL_UNIT0_ID].buffer_mipi[CAPTURE_UNIT0_ID] =
1243                                                               config.csi_buffer[MIPI_PORT0_ID];
1244                input_system_network_cfg.ctrl_unit_cfg[CTRL_UNIT0_ID -
1245                                                       CTRL_UNIT0_ID].buffer_mipi[CAPTURE_UNIT1_ID] =
1246                                                               config.csi_buffer[MIPI_PORT1_ID];
1247                input_system_network_cfg.ctrl_unit_cfg[CTRL_UNIT0_ID -
1248                                                       CTRL_UNIT0_ID].buffer_mipi[CAPTURE_UNIT2_ID] =
1249                                                               config.csi_buffer[MIPI_PORT2_ID];
1250                input_system_network_cfg.ctrl_unit_cfg[CTRL_UNIT0_ID -
1251                                                       CTRL_UNIT0_ID].buffer_acquire[ACQUISITION_UNIT0_ID -
1252                                                               ACQUISITION_UNIT0_ID] =
1253                                                                       config.acquisition_buffer_unique;
1254
1255                // First set input network around CSI receiver.
1256                input_system_network_configure(INPUT_SYSTEM0_ID, &input_system_network_cfg);
1257
1258                // Set the CSI receiver.
1259                //...
1260                break;
1261
1262        case INPUT_SYSTEM_SOURCE_TPG:
1263        case INPUT_SYSTEM_SOURCE_PRBS:
1264        case INPUT_SYSTEM_SOURCE_FIFO:
1265                break;
1266
1267        default:
1268                return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
1269
1270        } // end of switch (source_type)
1271
1272        // Set input selector.
1273        input_selector_cfg_for_sensor(GP_DEVICE0_ID);
1274
1275        // Set input switch.
1276        input_switch_cfg(GP_DEVICE0_ID, &config.input_switch_cfg);
1277
1278        // Set input formatters.
1279        // AM: IF are set dynamically.
1280        return INPUT_SYSTEM_ERR_NO_ERROR;
1281}
1282
1283// Function that applies the whole configuration.
1284input_system_err_t input_system_configuration_commit(void)
1285{
1286        // The last configuration step is to configure the input buffer.
1287        input_system_err_t error = input_buffer_configuration();
1288
1289        if (error != INPUT_SYSTEM_ERR_NO_ERROR) {
1290                return error;
1291        }
1292
1293        // Translate the whole configuration into registers.
1294        error = configuration_to_registers();
1295        if (error != INPUT_SYSTEM_ERR_NO_ERROR) {
1296                return error;
1297        }
1298
1299        // Translate the whole configuration into ctrl commands etc.
1300
1301        return INPUT_SYSTEM_ERR_NO_ERROR;
1302}
1303
1304// FIFO
1305
1306input_system_err_t      input_system_csi_fifo_channel_cfg(
1307    u32         ch_id,
1308    input_system_csi_port_t     port,
1309    backend_channel_cfg_t       backend_ch,
1310    target_cfg2400_t    target
1311)
1312{
1313        channel_cfg_t channel;
1314
1315        channel.ch_id   = ch_id;
1316        channel.backend_ch      = backend_ch;
1317        channel.source_type = INPUT_SYSTEM_SOURCE_SENSOR;
1318        //channel.source
1319        channel.source_cfg.csi_cfg.csi_port                     = port;
1320        channel.source_cfg.csi_cfg.buffering_mode       = INPUT_SYSTEM_FIFO_CAPTURE;
1321        channel.source_cfg.csi_cfg.csi_buffer                   = IB_BUFFER_NULL;
1322        channel.source_cfg.csi_cfg.acquisition_buffer   = IB_BUFFER_NULL;
1323        channel.source_cfg.csi_cfg.nof_xmem_buffers     = 0;
1324
1325        channel.target_cfg      = target;
1326        return input_system_configure_channel(channel);
1327}
1328
1329input_system_err_t      input_system_csi_fifo_channel_with_counting_cfg(
1330    u32                         ch_id,
1331    u32                         nof_frames,
1332    input_system_csi_port_t                     port,
1333    backend_channel_cfg_t                       backend_ch,
1334    u32                         csi_mem_reg_size,
1335    u32                         csi_nof_mem_regs,
1336    target_cfg2400_t                    target
1337)
1338{
1339        channel_cfg_t channel;
1340
1341        channel.ch_id   = ch_id;
1342        channel.backend_ch      = backend_ch;
1343        channel.source_type             = INPUT_SYSTEM_SOURCE_SENSOR;
1344        //channel.source
1345        channel.source_cfg.csi_cfg.csi_port                     = port;
1346        channel.source_cfg.csi_cfg.buffering_mode       =
1347            INPUT_SYSTEM_FIFO_CAPTURE_WITH_COUNTING;
1348        channel.source_cfg.csi_cfg.csi_buffer.mem_reg_size              = csi_mem_reg_size;
1349        channel.source_cfg.csi_cfg.csi_buffer.nof_mem_regs              = csi_nof_mem_regs;
1350        channel.source_cfg.csi_cfg.csi_buffer.mem_reg_addr              = 0;
1351        channel.source_cfg.csi_cfg.acquisition_buffer                   = IB_BUFFER_NULL;
1352        channel.source_cfg.csi_cfg.nof_xmem_buffers     = nof_frames;
1353
1354        channel.target_cfg      = target;
1355        return input_system_configure_channel(channel);
1356}
1357
1358// SRAM
1359
1360input_system_err_t      input_system_csi_sram_channel_cfg(
1361    u32                         ch_id,
1362    input_system_csi_port_t                     port,
1363    backend_channel_cfg_t                       backend_ch,
1364    u32                         csi_mem_reg_size,
1365    u32                         csi_nof_mem_regs,
1366    //  uint32_t                                acq_mem_reg_size,
1367    //  uint32_t                                acq_nof_mem_regs,
1368    target_cfg2400_t                    target
1369)
1370{
1371        channel_cfg_t channel;
1372
1373        channel.ch_id   = ch_id;
1374        channel.backend_ch      = backend_ch;
1375        channel.source_type             = INPUT_SYSTEM_SOURCE_SENSOR;
1376        //channel.source
1377        channel.source_cfg.csi_cfg.csi_port                     = port;
1378        channel.source_cfg.csi_cfg.buffering_mode       = INPUT_SYSTEM_SRAM_BUFFERING;
1379        channel.source_cfg.csi_cfg.csi_buffer.mem_reg_size              = csi_mem_reg_size;
1380        channel.source_cfg.csi_cfg.csi_buffer.nof_mem_regs              = csi_nof_mem_regs;
1381        channel.source_cfg.csi_cfg.csi_buffer.mem_reg_addr              = 0;
1382        channel.source_cfg.csi_cfg.acquisition_buffer                   = IB_BUFFER_NULL;
1383        channel.source_cfg.csi_cfg.nof_xmem_buffers     = 0;
1384
1385        channel.target_cfg      = target;
1386        return input_system_configure_channel(channel);
1387}
1388
1389//XMEM
1390
1391// Collects all parameters and puts them in channel_cfg_t.
1392input_system_err_t      input_system_csi_xmem_channel_cfg(
1393    u32                         ch_id,
1394    input_system_csi_port_t                     port,
1395    backend_channel_cfg_t                       backend_ch,
1396    u32                         csi_mem_reg_size,
1397    u32                         csi_nof_mem_regs,
1398    u32                         acq_mem_reg_size,
1399    u32                         acq_nof_mem_regs,
1400    target_cfg2400_t                    target,
1401    uint32_t                            nof_xmem_buffers
1402)
1403{
1404        channel_cfg_t channel;
1405
1406        channel.ch_id   = ch_id;
1407        channel.backend_ch      = backend_ch;
1408        channel.source_type             = INPUT_SYSTEM_SOURCE_SENSOR;
1409        //channel.source
1410        channel.source_cfg.csi_cfg.csi_port                     = port;
1411        channel.source_cfg.csi_cfg.buffering_mode       = INPUT_SYSTEM_XMEM_BUFFERING;
1412        channel.source_cfg.csi_cfg.csi_buffer.mem_reg_size              = csi_mem_reg_size;
1413        channel.source_cfg.csi_cfg.csi_buffer.nof_mem_regs              = csi_nof_mem_regs;
1414        channel.source_cfg.csi_cfg.csi_buffer.mem_reg_addr              = 0;
1415        channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_size      = acq_mem_reg_size;
1416        channel.source_cfg.csi_cfg.acquisition_buffer.nof_mem_regs      = acq_nof_mem_regs;
1417        channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_addr      = 0;
1418        channel.source_cfg.csi_cfg.nof_xmem_buffers     = nof_xmem_buffers;
1419
1420        channel.target_cfg      = target;
1421        return input_system_configure_channel(channel);
1422}
1423
1424input_system_err_t      input_system_csi_xmem_acquire_only_channel_cfg(
1425    u32                         ch_id,
1426    u32                         nof_frames,
1427    input_system_csi_port_t                     port,
1428    backend_channel_cfg_t                       backend_ch,
1429    u32                         acq_mem_reg_size,
1430    u32                         acq_nof_mem_regs,
1431    target_cfg2400_t                    target)
1432{
1433        channel_cfg_t channel;
1434
1435        channel.ch_id   = ch_id;
1436        channel.backend_ch      = backend_ch;
1437        channel.source_type             = INPUT_SYSTEM_SOURCE_SENSOR;
1438        //channel.source
1439        channel.source_cfg.csi_cfg.csi_port                     = port;
1440        channel.source_cfg.csi_cfg.buffering_mode       = INPUT_SYSTEM_XMEM_ACQUIRE;
1441        channel.source_cfg.csi_cfg.csi_buffer           = IB_BUFFER_NULL;
1442        channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_size      = acq_mem_reg_size;
1443        channel.source_cfg.csi_cfg.acquisition_buffer.nof_mem_regs      = acq_nof_mem_regs;
1444        channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_addr      = 0;
1445        channel.source_cfg.csi_cfg.nof_xmem_buffers     = nof_frames;
1446
1447        channel.target_cfg      = target;
1448        return input_system_configure_channel(channel);
1449}
1450
1451input_system_err_t      input_system_csi_xmem_capture_only_channel_cfg(
1452    u32                         ch_id,
1453    u32                         nof_frames,
1454    input_system_csi_port_t                     port,
1455    u32                         csi_mem_reg_size,
1456    u32                         csi_nof_mem_regs,
1457    u32                         acq_mem_reg_size,
1458    u32                         acq_nof_mem_regs,
1459    target_cfg2400_t                    target)
1460{
1461        channel_cfg_t channel;
1462
1463        channel.ch_id   = ch_id;
1464        //channel.backend_ch    = backend_ch;
1465        channel.source_type             = INPUT_SYSTEM_SOURCE_SENSOR;
1466        //channel.source
1467        channel.source_cfg.csi_cfg.csi_port                     = port;
1468        //channel.source_cfg.csi_cfg.backend_ch         = backend_ch;
1469        channel.source_cfg.csi_cfg.buffering_mode       = INPUT_SYSTEM_XMEM_CAPTURE;
1470        channel.source_cfg.csi_cfg.csi_buffer.mem_reg_size              = csi_mem_reg_size;
1471        channel.source_cfg.csi_cfg.csi_buffer.nof_mem_regs              = csi_nof_mem_regs;
1472        channel.source_cfg.csi_cfg.csi_buffer.mem_reg_addr              = 0;
1473        channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_size      = acq_mem_reg_size;
1474        channel.source_cfg.csi_cfg.acquisition_buffer.nof_mem_regs      = acq_nof_mem_regs;
1475        channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_addr      = 0;
1476        channel.source_cfg.csi_cfg.nof_xmem_buffers     = nof_frames;
1477
1478        channel.target_cfg      = target;
1479        return input_system_configure_channel(channel);
1480}
1481
1482// Non - CSI
1483
1484input_system_err_t      input_system_prbs_channel_cfg(
1485    u32         ch_id,
1486    u32         nof_frames,//not used yet
1487    u32         seed,
1488    u32         sync_gen_width,
1489    u32         sync_gen_height,
1490    u32         sync_gen_hblank_cycles,
1491    u32         sync_gen_vblank_cycles,
1492    target_cfg2400_t    target
1493)
1494{
1495        channel_cfg_t channel;
1496
1497        (void)nof_frames;
1498
1499        channel.ch_id   = ch_id;
1500        channel.source_type = INPUT_SYSTEM_SOURCE_PRBS;
1501
1502        channel.source_cfg.prbs_cfg.seed = seed;
1503        channel.source_cfg.prbs_cfg.sync_gen_cfg.width          = sync_gen_width;
1504        channel.source_cfg.prbs_cfg.sync_gen_cfg.height         = sync_gen_height;
1505        channel.source_cfg.prbs_cfg.sync_gen_cfg.hblank_cycles  = sync_gen_hblank_cycles;
1506        channel.source_cfg.prbs_cfg.sync_gen_cfg.vblank_cycles  = sync_gen_vblank_cycles;
1507
1508        channel.target_cfg      = target;
1509
1510        return input_system_configure_channel(channel);
1511}
1512
1513input_system_err_t      input_system_tpg_channel_cfg(
1514    u32         ch_id,
1515    u32         nof_frames,//not used yet
1516    u32         x_mask,
1517    u32         y_mask,
1518    u32         x_delta,
1519    u32         y_delta,
1520    u32         xy_mask,
1521    u32         sync_gen_width,
1522    u32         sync_gen_height,
1523    u32         sync_gen_hblank_cycles,
1524    u32         sync_gen_vblank_cycles,
1525    target_cfg2400_t    target
1526)
1527{
1528        channel_cfg_t channel;
1529
1530        (void)nof_frames;
1531
1532        channel.ch_id   = ch_id;
1533        channel.source_type             = INPUT_SYSTEM_SOURCE_TPG;
1534
1535        channel.source_cfg.tpg_cfg.x_mask       = x_mask;
1536        channel.source_cfg.tpg_cfg.y_mask       = y_mask;
1537        channel.source_cfg.tpg_cfg.x_delta      = x_delta;
1538        channel.source_cfg.tpg_cfg.y_delta      = y_delta;
1539        channel.source_cfg.tpg_cfg.xy_mask      = xy_mask;
1540        channel.source_cfg.tpg_cfg.sync_gen_cfg.width           = sync_gen_width;
1541        channel.source_cfg.tpg_cfg.sync_gen_cfg.height          = sync_gen_height;
1542        channel.source_cfg.tpg_cfg.sync_gen_cfg.hblank_cycles   = sync_gen_hblank_cycles;
1543        channel.source_cfg.tpg_cfg.sync_gen_cfg.vblank_cycles   = sync_gen_vblank_cycles;
1544
1545        channel.target_cfg      = target;
1546        return input_system_configure_channel(channel);
1547}
1548
1549// MW: Don't use system specific names, (even in system specific files) "cfg2400" -> cfg
1550input_system_err_t      input_system_gpfifo_channel_cfg(
1551    u32         ch_id,
1552    u32         nof_frames, //not used yet
1553
1554    target_cfg2400_t    target)
1555{
1556        channel_cfg_t channel;
1557
1558        (void)nof_frames;
1559
1560        channel.ch_id   = ch_id;
1561        channel.source_type     = INPUT_SYSTEM_SOURCE_FIFO;
1562
1563        channel.target_cfg      = target;
1564        return input_system_configure_channel(channel);
1565}
1566
1567///////////////////////////////////////////////////////////////////////////
1568//
1569// Private specialized functions for channel setting.
1570//
1571///////////////////////////////////////////////////////////////////////////
1572
1573// Fills the parameters to config.csi_value[port]
1574static input_system_err_t input_system_configure_channel_sensor(
1575    const channel_cfg_t channel)
1576{
1577        const u32 port = channel.source_cfg.csi_cfg.csi_port;
1578        input_system_err_t status = INPUT_SYSTEM_ERR_NO_ERROR;
1579
1580        input_system_multiplex_t mux;
1581
1582        if (port >= N_INPUT_SYSTEM_PORTS)
1583                return INPUT_SYSTEM_ERR_GENERIC;
1584
1585        //check if port > N_INPUT_SYSTEM_MULTIPLEX
1586
1587        status = set_source_type(&config.source_type, channel.source_type,
1588                                 &config.source_type_flags);
1589        if (status != INPUT_SYSTEM_ERR_NO_ERROR) return status;
1590
1591        // Check for conflicts on source (implicitly on multicast, capture unit and input buffer).
1592
1593        status = set_csi_cfg(&config.csi_value[port], &channel.source_cfg.csi_cfg,
1594                             &config.csi_flags[port]);
1595        if (status != INPUT_SYSTEM_ERR_NO_ERROR) return status;
1596
1597        switch (channel.source_cfg.csi_cfg.buffering_mode) {
1598        case INPUT_SYSTEM_FIFO_CAPTURE:
1599
1600                // Check for conflicts on mux.
1601                mux = INPUT_SYSTEM_MIPI_PORT0 + port;
1602                status = input_system_multiplexer_cfg(&config.multiplexer, mux,
1603                                                      &config.multiplexer_flags);
1604                if (status != INPUT_SYSTEM_ERR_NO_ERROR) return status;
1605                config.multicast[port] = INPUT_SYSTEM_CSI_BACKEND;
1606
1607                // Shared resource, so it should be blocked.
1608                //config.mux_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1609                //config.csi_buffer_flags[port] |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1610                //config.acquisition_buffer_unique_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1611
1612                break;
1613        case INPUT_SYSTEM_SRAM_BUFFERING:
1614
1615                // Check for conflicts on mux.
1616                mux = INPUT_SYSTEM_ACQUISITION_UNIT;
1617                status = input_system_multiplexer_cfg(&config.multiplexer, mux,
1618                                                      &config.multiplexer_flags);
1619                if (status != INPUT_SYSTEM_ERR_NO_ERROR) return status;
1620                config.multicast[port] = INPUT_SYSTEM_INPUT_BUFFER;
1621
1622                // Shared resource, so it should be blocked.
1623                //config.mux_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1624                //config.csi_buffer_flags[port] |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1625                //config.acquisition_buffer_unique_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1626
1627                break;
1628        case INPUT_SYSTEM_XMEM_BUFFERING:
1629
1630                // Check for conflicts on mux.
1631                mux = INPUT_SYSTEM_ACQUISITION_UNIT;
1632                status = input_system_multiplexer_cfg(&config.multiplexer, mux,
1633                                                      &config.multiplexer_flags);
1634                if (status != INPUT_SYSTEM_ERR_NO_ERROR) return status;
1635                config.multicast[port] = INPUT_SYSTEM_INPUT_BUFFER;
1636
1637                // Shared resource, so it should be blocked.
1638                //config.mux_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1639                //config.csi_buffer_flags[port] |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1640                //config.acquisition_buffer_unique_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1641
1642                break;
1643        case INPUT_SYSTEM_FIFO_CAPTURE_WITH_COUNTING:
1644        case INPUT_SYSTEM_XMEM_CAPTURE:
1645        case INPUT_SYSTEM_XMEM_ACQUIRE:
1646        default:
1647                return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
1648        }
1649
1650        return INPUT_SYSTEM_ERR_NO_ERROR;
1651}
1652
1653// Test flags and set structure.
1654static input_system_err_t set_source_type(
1655    input_system_source_t *const lhs,
1656    const input_system_source_t                 rhs,
1657    input_system_config_flags_t *const flags)
1658{
1659        // MW: Not enough asserts
1660        assert(lhs);
1661        assert(flags);
1662
1663        if ((*flags) & INPUT_SYSTEM_CFG_FLAG_BLOCKED) {
1664                *flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1665                return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1666        }
1667
1668        if ((*flags) & INPUT_SYSTEM_CFG_FLAG_SET) {
1669                // Check for consistency with already set value.
1670                if ((*lhs) == (rhs)) {
1671                        return INPUT_SYSTEM_ERR_NO_ERROR;
1672                } else {
1673                        *flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1674                        return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1675                }
1676        }
1677        // Check the value (individually).
1678        if (rhs >= N_INPUT_SYSTEM_SOURCE) {
1679                *flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1680                return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1681        }
1682        // Set the value.
1683        *lhs = rhs;
1684
1685        *flags |= INPUT_SYSTEM_CFG_FLAG_SET;
1686        return INPUT_SYSTEM_ERR_NO_ERROR;
1687}
1688
1689// Test flags and set structure.
1690static input_system_err_t set_csi_cfg(
1691    csi_cfg_t *const lhs,
1692    const csi_cfg_t *const rhs,
1693    input_system_config_flags_t *const flags)
1694{
1695        u32 memory_required;
1696        u32 acq_memory_required;
1697
1698        assert(lhs);
1699        assert(flags);
1700
1701        if ((*flags) & INPUT_SYSTEM_CFG_FLAG_BLOCKED) {
1702                *flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1703                return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1704        }
1705
1706        if (*flags & INPUT_SYSTEM_CFG_FLAG_SET) {
1707                // check for consistency with already set value.
1708                if (/*lhs->backend_ch == rhs.backend_ch
1709                        &&*/ lhs->buffering_mode == rhs->buffering_mode
1710                    && lhs->csi_buffer.mem_reg_size == rhs->csi_buffer.mem_reg_size
1711                    && lhs->csi_buffer.nof_mem_regs  == rhs->csi_buffer.nof_mem_regs
1712                    && lhs->acquisition_buffer.mem_reg_size == rhs->acquisition_buffer.mem_reg_size
1713                    && lhs->acquisition_buffer.nof_mem_regs  == rhs->acquisition_buffer.nof_mem_regs
1714                    && lhs->nof_xmem_buffers  == rhs->nof_xmem_buffers
1715                ) {
1716                        return INPUT_SYSTEM_ERR_NO_ERROR;
1717                } else {
1718                        *flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1719                        return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1720                }
1721        }
1722        // Check the value (individually).
1723        // no check for backend_ch
1724        // no check for nof_xmem_buffers
1725        memory_required = rhs->csi_buffer.mem_reg_size * rhs->csi_buffer.nof_mem_regs;
1726        acq_memory_required = rhs->acquisition_buffer.mem_reg_size *
1727                              rhs->acquisition_buffer.nof_mem_regs;
1728        if (rhs->buffering_mode >= N_INPUT_SYSTEM_BUFFERING_MODE
1729            ||
1730            // Check if required memory is available in input buffer (SRAM).
1731            (memory_required + acq_memory_required) > config.unallocated_ib_mem_words
1732
1733           ) {
1734                *flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1735                return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1736        }
1737        // Set the value.
1738        //lhs[port]->backend_ch         = rhs.backend_ch;
1739        lhs->buffering_mode     = rhs->buffering_mode;
1740        lhs->nof_xmem_buffers = rhs->nof_xmem_buffers;
1741
1742        lhs->csi_buffer.mem_reg_size = rhs->csi_buffer.mem_reg_size;
1743        lhs->csi_buffer.nof_mem_regs  = rhs->csi_buffer.nof_mem_regs;
1744        lhs->acquisition_buffer.mem_reg_size = rhs->acquisition_buffer.mem_reg_size;
1745        lhs->acquisition_buffer.nof_mem_regs  = rhs->acquisition_buffer.nof_mem_regs;
1746        // ALX: NB: Here we just set buffer parameters, but still not allocate it
1747        // (no addresses determined). That will be done during commit.
1748
1749        //  FIXIT:      acq_memory_required is not deducted, since it can be allocated multiple times.
1750        config.unallocated_ib_mem_words -= memory_required;
1751//assert(config.unallocated_ib_mem_words >=0);
1752        *flags |= INPUT_SYSTEM_CFG_FLAG_SET;
1753        return INPUT_SYSTEM_ERR_NO_ERROR;
1754}
1755
1756// Test flags and set structure.
1757static input_system_err_t input_system_multiplexer_cfg(
1758    input_system_multiplex_t *const lhs,
1759    const input_system_multiplex_t              rhs,
1760    input_system_config_flags_t *const flags)
1761{
1762        assert(lhs);
1763        assert(flags);
1764
1765        if ((*flags) & INPUT_SYSTEM_CFG_FLAG_BLOCKED) {
1766                *flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1767                return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1768        }
1769
1770        if ((*flags) & INPUT_SYSTEM_CFG_FLAG_SET) {
1771                // Check for consistency with already set value.
1772                if ((*lhs) == (rhs)) {
1773                        return INPUT_SYSTEM_ERR_NO_ERROR;
1774                } else {
1775                        *flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1776                        return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1777                }
1778        }
1779        // Check the value (individually).
1780        if (rhs >= N_INPUT_SYSTEM_MULTIPLEX) {
1781                *flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1782                return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
1783        }
1784        // Set the value.
1785        *lhs = rhs;
1786
1787        *flags |= INPUT_SYSTEM_CFG_FLAG_SET;
1788        return INPUT_SYSTEM_ERR_NO_ERROR;
1789}
1790#endif
1791