#define __INLINE_INPUT_SYSTEM__
#include "input_system.h"
#include "assert_support.h"
#include "ia_css_isys.h"
#include "ia_css_irq.h"
#include "sh_css_internal.h"
#if !defined(ISP2401)
void ia_css_isys_rx_enable_all_interrupts(enum mipi_port_id port)
{
hrt_data bits = receiver_port_reg_load(RX0_ID,
port,
_HRT_CSS_RECEIVER_IRQ_ENABLE_REG_IDX);
bits |= (1U << _HRT_CSS_RECEIVER_IRQ_OVERRUN_BIT) |
(1U << _HRT_CSS_RECEIVER_IRQ_INIT_TIMEOUT_BIT) |
(1U << _HRT_CSS_RECEIVER_IRQ_SLEEP_MODE_ENTRY_BIT) |
(1U << _HRT_CSS_RECEIVER_IRQ_SLEEP_MODE_EXIT_BIT) |
(1U << _HRT_CSS_RECEIVER_IRQ_ERR_SOT_HS_BIT) |
(1U << _HRT_CSS_RECEIVER_IRQ_ERR_SOT_SYNC_HS_BIT) |
(1U << _HRT_CSS_RECEIVER_IRQ_ERR_CONTROL_BIT) |
(1U << _HRT_CSS_RECEIVER_IRQ_ERR_ECC_DOUBLE_BIT) |
(1U << _HRT_CSS_RECEIVER_IRQ_ERR_ECC_CORRECTED_BIT) |
(1U << _HRT_CSS_RECEIVER_IRQ_ERR_CRC_BIT) |
(1U << _HRT_CSS_RECEIVER_IRQ_ERR_ID_BIT) |
(1U << _HRT_CSS_RECEIVER_IRQ_ERR_FRAME_SYNC_BIT) |
(1U << _HRT_CSS_RECEIVER_IRQ_ERR_FRAME_DATA_BIT) |
(1U << _HRT_CSS_RECEIVER_IRQ_DATA_TIMEOUT_BIT) |
(1U << _HRT_CSS_RECEIVER_IRQ_ERR_ESCAPE_BIT);
receiver_port_reg_store(RX0_ID,
port,
_HRT_CSS_RECEIVER_IRQ_ENABLE_REG_IDX, bits);
ia_css_irq_enable(IA_CSS_IRQ_INFO_CSS_RECEIVER_ERROR, true);
return;
}
enum mipi_port_id ia_css_isys_port_to_mipi_port(enum mipi_port_id api_port)
{
enum mipi_port_id port = MIPI_PORT0_ID;
if (api_port == MIPI_PORT1_ID)
port = MIPI_PORT1_ID;
else if (api_port == MIPI_PORT2_ID)
port = MIPI_PORT2_ID;
return port;
}
unsigned int ia_css_isys_rx_get_interrupt_reg(enum mipi_port_id port)
{
return receiver_port_reg_load(RX0_ID,
port,
_HRT_CSS_RECEIVER_IRQ_STATUS_REG_IDX);
}
void ia_css_rx_get_irq_info(unsigned int *irq_infos)
{
ia_css_rx_port_get_irq_info(MIPI_PORT1_ID, irq_infos);
}
void ia_css_rx_port_get_irq_info(enum mipi_port_id api_port,
unsigned int *irq_infos)
{
enum mipi_port_id port = ia_css_isys_port_to_mipi_port(api_port);
ia_css_isys_rx_get_irq_info(port, irq_infos);
}
void ia_css_isys_rx_get_irq_info(enum mipi_port_id port,
unsigned int *irq_infos)
{
unsigned int bits;
assert(irq_infos);
bits = ia_css_isys_rx_get_interrupt_reg(port);
*irq_infos = ia_css_isys_rx_translate_irq_infos(bits);
}
unsigned int ia_css_isys_rx_translate_irq_infos(unsigned int bits)
{
unsigned int infos = 0;
if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_OVERRUN_BIT))
infos |= IA_CSS_RX_IRQ_INFO_BUFFER_OVERRUN;
if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_INIT_TIMEOUT_BIT))
infos |= IA_CSS_RX_IRQ_INFO_INIT_TIMEOUT;
if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_SLEEP_MODE_ENTRY_BIT))
infos |= IA_CSS_RX_IRQ_INFO_ENTER_SLEEP_MODE;
if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_SLEEP_MODE_EXIT_BIT))
infos |= IA_CSS_RX_IRQ_INFO_EXIT_SLEEP_MODE;
if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_ECC_CORRECTED_BIT))
infos |= IA_CSS_RX_IRQ_INFO_ECC_CORRECTED;
if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_SOT_HS_BIT))
infos |= IA_CSS_RX_IRQ_INFO_ERR_SOT;
if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_SOT_SYNC_HS_BIT))
infos |= IA_CSS_RX_IRQ_INFO_ERR_SOT_SYNC;
if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_CONTROL_BIT))
infos |= IA_CSS_RX_IRQ_INFO_ERR_CONTROL;
if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_ECC_DOUBLE_BIT))
infos |= IA_CSS_RX_IRQ_INFO_ERR_ECC_DOUBLE;
if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_CRC_BIT))
infos |= IA_CSS_RX_IRQ_INFO_ERR_CRC;
if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_ID_BIT))
infos |= IA_CSS_RX_IRQ_INFO_ERR_UNKNOWN_ID;
if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_FRAME_SYNC_BIT))
infos |= IA_CSS_RX_IRQ_INFO_ERR_FRAME_SYNC;
if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_FRAME_DATA_BIT))
infos |= IA_CSS_RX_IRQ_INFO_ERR_FRAME_DATA;
if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_DATA_TIMEOUT_BIT))
infos |= IA_CSS_RX_IRQ_INFO_ERR_DATA_TIMEOUT;
if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_ESCAPE_BIT))
infos |= IA_CSS_RX_IRQ_INFO_ERR_UNKNOWN_ESC;
if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_LINE_SYNC_BIT))
infos |= IA_CSS_RX_IRQ_INFO_ERR_LINE_SYNC;
return infos;
}
void ia_css_rx_clear_irq_info(unsigned int irq_infos)
{
ia_css_rx_port_clear_irq_info(MIPI_PORT1_ID, irq_infos);
}
void ia_css_rx_port_clear_irq_info(enum mipi_port_id api_port,
unsigned int irq_infos)
{
enum mipi_port_id port = ia_css_isys_port_to_mipi_port(api_port);
ia_css_isys_rx_clear_irq_info(port, irq_infos);
}
void ia_css_isys_rx_clear_irq_info(enum mipi_port_id port,
unsigned int irq_infos)
{
hrt_data bits = receiver_port_reg_load(RX0_ID,
port,
_HRT_CSS_RECEIVER_IRQ_ENABLE_REG_IDX);
if (irq_infos & IA_CSS_RX_IRQ_INFO_BUFFER_OVERRUN)
bits |= 1U << _HRT_CSS_RECEIVER_IRQ_OVERRUN_BIT;
if (irq_infos & IA_CSS_RX_IRQ_INFO_INIT_TIMEOUT)
bits |= 1U << _HRT_CSS_RECEIVER_IRQ_INIT_TIMEOUT_BIT;
if (irq_infos & IA_CSS_RX_IRQ_INFO_ENTER_SLEEP_MODE)
bits |= 1U << _HRT_CSS_RECEIVER_IRQ_SLEEP_MODE_ENTRY_BIT;
if (irq_infos & IA_CSS_RX_IRQ_INFO_EXIT_SLEEP_MODE)
bits |= 1U << _HRT_CSS_RECEIVER_IRQ_SLEEP_MODE_EXIT_BIT;
if (irq_infos & IA_CSS_RX_IRQ_INFO_ECC_CORRECTED)
bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_ECC_CORRECTED_BIT;
if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_SOT)
bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_SOT_HS_BIT;
if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_SOT_SYNC)
bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_SOT_SYNC_HS_BIT;
if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_CONTROL)
bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_CONTROL_BIT;
if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_ECC_DOUBLE)
bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_ECC_DOUBLE_BIT;
if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_CRC)
bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_CRC_BIT;
if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_UNKNOWN_ID)
bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_ID_BIT;
if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_FRAME_SYNC)
bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_FRAME_SYNC_BIT;
if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_FRAME_DATA)
bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_FRAME_DATA_BIT;
if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_DATA_TIMEOUT)
bits |= 1U << _HRT_CSS_RECEIVER_IRQ_DATA_TIMEOUT_BIT;
if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_UNKNOWN_ESC)
bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_ESCAPE_BIT;
if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_LINE_SYNC)
bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_LINE_SYNC_BIT;
receiver_port_reg_store(RX0_ID,
port,
_HRT_CSS_RECEIVER_IRQ_ENABLE_REG_IDX, bits);
return;
}
#endif /* #if !defined(ISP2401) */
int ia_css_isys_convert_stream_format_to_mipi_format(
enum atomisp_input_format input_format,
mipi_predictor_t compression,
unsigned int *fmt_type)
{
assert(fmt_type);
if (compression != MIPI_PREDICTOR_NONE) {
switch (input_format) {
case ATOMISP_INPUT_FORMAT_RAW_6:
*fmt_type = 6;
break;
case ATOMISP_INPUT_FORMAT_RAW_7:
*fmt_type = 7;
break;
case ATOMISP_INPUT_FORMAT_RAW_8:
*fmt_type = 8;
break;
case ATOMISP_INPUT_FORMAT_RAW_10:
*fmt_type = 10;
break;
case ATOMISP_INPUT_FORMAT_RAW_12:
*fmt_type = 12;
break;
case ATOMISP_INPUT_FORMAT_RAW_14:
*fmt_type = 14;
break;
case ATOMISP_INPUT_FORMAT_RAW_16:
*fmt_type = 16;
break;
default:
return -EINVAL;
}
return 0;
}
switch (input_format) {
case ATOMISP_INPUT_FORMAT_RGB_888:
*fmt_type = MIPI_FORMAT_RGB888;
break;
case ATOMISP_INPUT_FORMAT_RGB_555:
*fmt_type = MIPI_FORMAT_RGB555;
break;
case ATOMISP_INPUT_FORMAT_RGB_444:
*fmt_type = MIPI_FORMAT_RGB444;
break;
case ATOMISP_INPUT_FORMAT_RGB_565:
*fmt_type = MIPI_FORMAT_RGB565;
break;
case ATOMISP_INPUT_FORMAT_RGB_666:
*fmt_type = MIPI_FORMAT_RGB666;
break;
case ATOMISP_INPUT_FORMAT_RAW_8:
*fmt_type = MIPI_FORMAT_RAW8;
break;
case ATOMISP_INPUT_FORMAT_RAW_10:
*fmt_type = MIPI_FORMAT_RAW10;
break;
case ATOMISP_INPUT_FORMAT_RAW_6:
*fmt_type = MIPI_FORMAT_RAW6;
break;
case ATOMISP_INPUT_FORMAT_RAW_7:
*fmt_type = MIPI_FORMAT_RAW7;
break;
case ATOMISP_INPUT_FORMAT_RAW_12:
*fmt_type = MIPI_FORMAT_RAW12;
break;
case ATOMISP_INPUT_FORMAT_RAW_14:
*fmt_type = MIPI_FORMAT_RAW14;
break;
case ATOMISP_INPUT_FORMAT_YUV420_8:
*fmt_type = MIPI_FORMAT_YUV420_8;
break;
case ATOMISP_INPUT_FORMAT_YUV420_10:
*fmt_type = MIPI_FORMAT_YUV420_10;
break;
case ATOMISP_INPUT_FORMAT_YUV422_8:
*fmt_type = MIPI_FORMAT_YUV422_8;
break;
case ATOMISP_INPUT_FORMAT_YUV422_10:
*fmt_type = MIPI_FORMAT_YUV422_10;
break;
case ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY:
*fmt_type = MIPI_FORMAT_YUV420_8_LEGACY;
break;
case ATOMISP_INPUT_FORMAT_EMBEDDED:
*fmt_type = MIPI_FORMAT_EMBEDDED;
break;
#ifndef ISP2401
case ATOMISP_INPUT_FORMAT_RAW_16:
*fmt_type = MIPI_FORMAT_RAW16;
break;
case ATOMISP_INPUT_FORMAT_BINARY_8:
*fmt_type = MIPI_FORMAT_BINARY_8;
break;
#else
case ATOMISP_INPUT_FORMAT_USER_DEF1:
*fmt_type = MIPI_FORMAT_CUSTOM0;
break;
case ATOMISP_INPUT_FORMAT_USER_DEF2:
*fmt_type = MIPI_FORMAT_CUSTOM1;
break;
case ATOMISP_INPUT_FORMAT_USER_DEF3:
*fmt_type = MIPI_FORMAT_CUSTOM2;
break;
case ATOMISP_INPUT_FORMAT_USER_DEF4:
*fmt_type = MIPI_FORMAT_CUSTOM3;
break;
case ATOMISP_INPUT_FORMAT_USER_DEF5:
*fmt_type = MIPI_FORMAT_CUSTOM4;
break;
case ATOMISP_INPUT_FORMAT_USER_DEF6:
*fmt_type = MIPI_FORMAT_CUSTOM5;
break;
case ATOMISP_INPUT_FORMAT_USER_DEF7:
*fmt_type = MIPI_FORMAT_CUSTOM6;
break;
case ATOMISP_INPUT_FORMAT_USER_DEF8:
*fmt_type = MIPI_FORMAT_CUSTOM7;
break;
#endif
case ATOMISP_INPUT_FORMAT_YUV420_16:
case ATOMISP_INPUT_FORMAT_YUV422_16:
default:
return -EINVAL;
}
return 0;
}
#if defined(ISP2401)
static mipi_predictor_t sh_css_csi2_compression_type_2_mipi_predictor(
enum ia_css_csi2_compression_type type)
{
mipi_predictor_t predictor = MIPI_PREDICTOR_NONE;
switch (type) {
case IA_CSS_CSI2_COMPRESSION_TYPE_1:
predictor = MIPI_PREDICTOR_TYPE1 - 1;
break;
case IA_CSS_CSI2_COMPRESSION_TYPE_2:
predictor = MIPI_PREDICTOR_TYPE2 - 1;
break;
default:
break;
}
return predictor;
}
int ia_css_isys_convert_compressed_format(
struct ia_css_csi2_compression *comp,
struct isp2401_input_system_cfg_s *cfg)
{
int err = 0;
assert(comp);
assert(cfg);
if (comp->type != IA_CSS_CSI2_COMPRESSION_TYPE_NONE) {
if (comp->uncompressed_bits_per_pixel == UNCOMPRESSED_BITS_PER_PIXEL_10) {
switch (comp->compressed_bits_per_pixel) {
case COMPRESSED_BITS_PER_PIXEL_6:
cfg->csi_port_attr.comp_scheme = MIPI_COMPRESSOR_10_6_10;
break;
case COMPRESSED_BITS_PER_PIXEL_7:
cfg->csi_port_attr.comp_scheme = MIPI_COMPRESSOR_10_7_10;
break;
case COMPRESSED_BITS_PER_PIXEL_8:
cfg->csi_port_attr.comp_scheme = MIPI_COMPRESSOR_10_8_10;
break;
default:
err = -EINVAL;
}
} else if (comp->uncompressed_bits_per_pixel ==
UNCOMPRESSED_BITS_PER_PIXEL_12) {
switch (comp->compressed_bits_per_pixel) {
case COMPRESSED_BITS_PER_PIXEL_6:
cfg->csi_port_attr.comp_scheme = MIPI_COMPRESSOR_12_6_12;
break;
case COMPRESSED_BITS_PER_PIXEL_7:
cfg->csi_port_attr.comp_scheme = MIPI_COMPRESSOR_12_7_12;
break;
case COMPRESSED_BITS_PER_PIXEL_8:
cfg->csi_port_attr.comp_scheme = MIPI_COMPRESSOR_12_8_12;
break;
default:
err = -EINVAL;
}
} else
err = -EINVAL;
cfg->csi_port_attr.comp_predictor =
sh_css_csi2_compression_type_2_mipi_predictor(comp->type);
cfg->csi_port_attr.comp_enable = true;
} else
cfg->csi_port_attr.comp_enable = false;
return err;
}
unsigned int ia_css_csi2_calculate_input_system_alignment(
enum atomisp_input_format fmt_type)
{
unsigned int memory_alignment_in_bytes = HIVE_ISP_DDR_WORD_BYTES;
switch (fmt_type) {
case ATOMISP_INPUT_FORMAT_RAW_6:
case ATOMISP_INPUT_FORMAT_RAW_7:
case ATOMISP_INPUT_FORMAT_RAW_8:
case ATOMISP_INPUT_FORMAT_RAW_10:
case ATOMISP_INPUT_FORMAT_RAW_12:
case ATOMISP_INPUT_FORMAT_RAW_14:
memory_alignment_in_bytes = 2 * ISP_VEC_NELEMS;
break;
case ATOMISP_INPUT_FORMAT_YUV420_8:
case ATOMISP_INPUT_FORMAT_YUV422_8:
case ATOMISP_INPUT_FORMAT_USER_DEF1:
case ATOMISP_INPUT_FORMAT_USER_DEF2:
case ATOMISP_INPUT_FORMAT_USER_DEF3:
case ATOMISP_INPUT_FORMAT_USER_DEF4:
case ATOMISP_INPUT_FORMAT_USER_DEF5:
case ATOMISP_INPUT_FORMAT_USER_DEF6:
case ATOMISP_INPUT_FORMAT_USER_DEF7:
case ATOMISP_INPUT_FORMAT_USER_DEF8:
memory_alignment_in_bytes = 2 * HIVE_ISP_DDR_WORD_BYTES;
break;
case ATOMISP_INPUT_FORMAT_EMBEDDED:
default:
memory_alignment_in_bytes = HIVE_ISP_DDR_WORD_BYTES;
break;
}
return memory_alignment_in_bytes;
}
#endif
#if !defined(ISP2401)
static const mipi_lane_cfg_t MIPI_PORT_LANES[N_RX_MODE][N_MIPI_PORT_ID] = {
{MIPI_4LANE_CFG, MIPI_1LANE_CFG, MIPI_0LANE_CFG},
{MIPI_3LANE_CFG, MIPI_1LANE_CFG, MIPI_0LANE_CFG},
{MIPI_2LANE_CFG, MIPI_1LANE_CFG, MIPI_0LANE_CFG},
{MIPI_1LANE_CFG, MIPI_1LANE_CFG, MIPI_0LANE_CFG},
{MIPI_2LANE_CFG, MIPI_1LANE_CFG, MIPI_2LANE_CFG},
{MIPI_3LANE_CFG, MIPI_1LANE_CFG, MIPI_1LANE_CFG},
{MIPI_2LANE_CFG, MIPI_1LANE_CFG, MIPI_1LANE_CFG},
{MIPI_1LANE_CFG, MIPI_1LANE_CFG, MIPI_1LANE_CFG}
};
void ia_css_isys_rx_configure(const rx_cfg_t *config,
const enum ia_css_input_mode input_mode)
{
bool any_port_enabled = false;
enum mipi_port_id port;
if ((!config)
|| (config->mode >= N_RX_MODE)
|| (config->port >= N_MIPI_PORT_ID)) {
assert(0);
return;
}
for (port = (enum mipi_port_id)0; port < N_MIPI_PORT_ID; port++) {
if (is_receiver_port_enabled(RX0_ID, port))
any_port_enabled = true;
}
port = config->port;
receiver_port_enable(RX0_ID, port, false);
port = config->port;
if (MIPI_PORT_LANES[config->mode][port] != MIPI_0LANE_CFG) {
receiver_port_reg_store(RX0_ID, port,
_HRT_CSS_RECEIVER_FUNC_PROG_REG_IDX,
config->timeout);
receiver_port_reg_store(RX0_ID, port,
_HRT_CSS_RECEIVER_2400_INIT_COUNT_REG_IDX,
config->initcount);
receiver_port_reg_store(RX0_ID, port,
_HRT_CSS_RECEIVER_2400_SYNC_COUNT_REG_IDX,
config->synccount);
receiver_port_reg_store(RX0_ID, port,
_HRT_CSS_RECEIVER_2400_RX_COUNT_REG_IDX,
config->rxcount);
if (input_mode != IA_CSS_INPUT_MODE_BUFFERED_SENSOR) {
input_system_sub_system_reg_store(INPUT_SYSTEM0_ID,
GPREGS_UNIT0_ID,
HIVE_ISYS_GPREG_MULTICAST_A_IDX
+ (unsigned int)port,
INPUT_SYSTEM_CSI_BACKEND);
input_system_sub_system_reg_store(INPUT_SYSTEM0_ID,
GPREGS_UNIT0_ID,
HIVE_ISYS_GPREG_MUX_IDX,
(input_system_multiplex_t)port);
} else {
input_system_sub_system_reg_store(INPUT_SYSTEM0_ID,
GPREGS_UNIT0_ID,
HIVE_ISYS_GPREG_MULTICAST_A_IDX
+ (unsigned int)port,
INPUT_SYSTEM_INPUT_BUFFER);
input_system_sub_system_reg_store(INPUT_SYSTEM0_ID,
GPREGS_UNIT0_ID,
HIVE_ISYS_GPREG_MUX_IDX,
INPUT_SYSTEM_ACQUISITION_UNIT);
}
}
if (!any_port_enabled) {
receiver_reg_store(RX0_ID,
_HRT_CSS_RECEIVER_TWO_PIXEL_EN_REG_IDX,
config->is_two_ppc);
receiver_reg_store(RX0_ID, _HRT_CSS_RECEIVER_BE_TWO_PPC_REG_IDX,
config->is_two_ppc);
}
receiver_port_enable(RX0_ID, port, true);
input_system_reg_store(INPUT_SYSTEM0_ID, 0x207, 1);
return;
}
void ia_css_isys_rx_disable(void)
{
enum mipi_port_id port;
for (port = (enum mipi_port_id)0; port < N_MIPI_PORT_ID; port++) {
receiver_port_reg_store(RX0_ID, port,
_HRT_CSS_RECEIVER_DEVICE_READY_REG_IDX,
false);
}
return;
}
#endif /* if !defined(ISP2401) */