// SPDX-License-Identifier: GPL-2.0 /* * Support for Intel Camera Imaging ISP subsystem. * Copyright (c) 2015, Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. */ #include /* for memcpy() */ #include "system_global.h" #ifdef ISP2401 #include "ia_css_isys.h" #include "ia_css_debug.h" #include "math_support.h" #include "virtual_isys.h" #include "isp.h" #include "sh_css_defs.h" /************************************************* * * Forwarded Declaration * *************************************************/ static bool create_input_system_channel( isp2401_input_system_cfg_t *cfg, bool metadata, input_system_channel_t *channel); static void destroy_input_system_channel( input_system_channel_t *channel); static bool create_input_system_input_port( isp2401_input_system_cfg_t *cfg, input_system_input_port_t *input_port); static void destroy_input_system_input_port( input_system_input_port_t *input_port); static bool calculate_input_system_channel_cfg( input_system_channel_t *channel, input_system_input_port_t *input_port, isp2401_input_system_cfg_t *isys_cfg, input_system_channel_cfg_t *channel_cfg, bool metadata); static bool calculate_input_system_input_port_cfg( input_system_channel_t *channel, input_system_input_port_t *input_port, isp2401_input_system_cfg_t *isys_cfg, input_system_input_port_cfg_t *input_port_cfg); static bool acquire_sid( stream2mmio_ID_t stream2mmio, stream2mmio_sid_ID_t *sid); static void release_sid( stream2mmio_ID_t stream2mmio, stream2mmio_sid_ID_t *sid); static bool acquire_ib_buffer( s32 bits_per_pixel, s32 pixels_per_line, s32 lines_per_frame, s32 align_in_bytes, bool online, isp2401_ib_buffer_t *buf); static void release_ib_buffer( isp2401_ib_buffer_t *buf); static bool acquire_dma_channel( isys2401_dma_ID_t dma_id, isys2401_dma_channel *channel); static void release_dma_channel( isys2401_dma_ID_t dma_id, isys2401_dma_channel *channel); static bool acquire_be_lut_entry( csi_rx_backend_ID_t backend, csi_mipi_packet_type_t packet_type, csi_rx_backend_lut_entry_t *entry); static void release_be_lut_entry( csi_rx_backend_ID_t backend, csi_mipi_packet_type_t packet_type, csi_rx_backend_lut_entry_t *entry); static bool calculate_tpg_cfg( input_system_channel_t *channel, input_system_input_port_t *input_port, isp2401_input_system_cfg_t *isys_cfg, pixelgen_tpg_cfg_t *cfg); static bool calculate_prbs_cfg( input_system_channel_t *channel, input_system_input_port_t *input_port, isp2401_input_system_cfg_t *isys_cfg, pixelgen_prbs_cfg_t *cfg); static bool calculate_fe_cfg( const isp2401_input_system_cfg_t *isys_cfg, csi_rx_frontend_cfg_t *cfg); static bool calculate_be_cfg( const input_system_input_port_t *input_port, const isp2401_input_system_cfg_t *isys_cfg, bool metadata, csi_rx_backend_cfg_t *cfg); static bool calculate_stream2mmio_cfg( const isp2401_input_system_cfg_t *isys_cfg, bool metadata, stream2mmio_cfg_t *cfg); static bool calculate_ibuf_ctrl_cfg( const input_system_channel_t *channel, const input_system_input_port_t *input_port, const isp2401_input_system_cfg_t *isys_cfg, ibuf_ctrl_cfg_t *cfg); static bool calculate_isys2401_dma_cfg( const input_system_channel_t *channel, const isp2401_input_system_cfg_t *isys_cfg, isys2401_dma_cfg_t *cfg); static bool calculate_isys2401_dma_port_cfg( const isp2401_input_system_cfg_t *isys_cfg, bool raw_packed, bool metadata, isys2401_dma_port_cfg_t *cfg); static csi_mipi_packet_type_t get_csi_mipi_packet_type( int32_t data_type); static int32_t calculate_stride( s32 bits_per_pixel, s32 pixels_per_line, bool raw_packed, int32_t align_in_bytes); /* end of Forwarded Declaration */ /************************************************** * * Public Methods * **************************************************/ ia_css_isys_error_t ia_css_isys_stream_create( ia_css_isys_descr_t *isys_stream_descr, ia_css_isys_stream_h isys_stream, uint32_t isys_stream_id) { ia_css_isys_error_t rc; if (!isys_stream_descr || !isys_stream || isys_stream_id >= SH_CSS_MAX_ISYS_CHANNEL_NODES) return false; ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_isys_stream_create() enter:\n"); /*Reset isys_stream to 0*/ memset(isys_stream, 0, sizeof(*isys_stream)); isys_stream->enable_metadata = isys_stream_descr->metadata.enable; isys_stream->id = isys_stream_id; isys_stream->linked_isys_stream_id = isys_stream_descr->linked_isys_stream_id; rc = create_input_system_input_port(isys_stream_descr, &isys_stream->input_port); if (!rc) return false; rc = create_input_system_channel(isys_stream_descr, false, &isys_stream->channel); if (!rc) { destroy_input_system_input_port(&isys_stream->input_port); return false; } /* create metadata channel */ if (isys_stream_descr->metadata.enable) { rc = create_input_system_channel(isys_stream_descr, true, &isys_stream->md_channel); if (!rc) { destroy_input_system_input_port(&isys_stream->input_port); destroy_input_system_channel(&isys_stream->channel); return false; } } ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_isys_stream_create() leave:\n"); return true; } void ia_css_isys_stream_destroy( ia_css_isys_stream_h isys_stream) { destroy_input_system_input_port(&isys_stream->input_port); destroy_input_system_channel(&isys_stream->channel); if (isys_stream->enable_metadata) { /* Destroy metadata channel only if its allocated*/ destroy_input_system_channel(&isys_stream->md_channel); } } ia_css_isys_error_t ia_css_isys_stream_calculate_cfg( ia_css_isys_stream_h isys_stream, ia_css_isys_descr_t *isys_stream_descr, ia_css_isys_stream_cfg_t *isys_stream_cfg) { ia_css_isys_error_t rc; if (!isys_stream_cfg || !isys_stream_descr || !isys_stream) return false; ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_isys_stream_calculate_cfg() enter:\n"); rc = calculate_input_system_channel_cfg( &isys_stream->channel, &isys_stream->input_port, isys_stream_descr, &isys_stream_cfg->channel_cfg, false); if (!rc) return false; /* configure metadata channel */ if (isys_stream_descr->metadata.enable) { isys_stream_cfg->enable_metadata = true; rc = calculate_input_system_channel_cfg( &isys_stream->md_channel, &isys_stream->input_port, isys_stream_descr, &isys_stream_cfg->md_channel_cfg, true); if (!rc) return false; } rc = calculate_input_system_input_port_cfg( &isys_stream->channel, &isys_stream->input_port, isys_stream_descr, &isys_stream_cfg->input_port_cfg); if (!rc) return false; isys_stream->valid = 1; isys_stream_cfg->valid = 1; ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_isys_stream_calculate_cfg() leave:\n"); return rc; } /* end of Public Methods */ /************************************************** * * Private Methods * **************************************************/ static bool create_input_system_channel( isp2401_input_system_cfg_t *cfg, bool metadata, input_system_channel_t *me) { bool rc = true; me->dma_id = ISYS2401_DMA0_ID; switch (cfg->input_port_id) { case INPUT_SYSTEM_CSI_PORT0_ID: case INPUT_SYSTEM_PIXELGEN_PORT0_ID: me->stream2mmio_id = STREAM2MMIO0_ID; me->ibuf_ctrl_id = IBUF_CTRL0_ID; break; case INPUT_SYSTEM_CSI_PORT1_ID: case INPUT_SYSTEM_PIXELGEN_PORT1_ID: me->stream2mmio_id = STREAM2MMIO1_ID; me->ibuf_ctrl_id = IBUF_CTRL1_ID; break; case INPUT_SYSTEM_CSI_PORT2_ID: case INPUT_SYSTEM_PIXELGEN_PORT2_ID: me->stream2mmio_id = STREAM2MMIO2_ID; me->ibuf_ctrl_id = IBUF_CTRL2_ID; break; default: rc = false; break; } if (!rc) return false; if (!acquire_sid(me->stream2mmio_id, &me->stream2mmio_sid_id)) { return false; } if (!acquire_ib_buffer( metadata ? cfg->metadata.bits_per_pixel : cfg->input_port_resolution.bits_per_pixel, metadata ? cfg->metadata.pixels_per_line : cfg->input_port_resolution.pixels_per_line, metadata ? cfg->metadata.lines_per_frame : cfg->input_port_resolution.lines_per_frame, metadata ? cfg->metadata.align_req_in_bytes : cfg->input_port_resolution.align_req_in_bytes, cfg->online, &me->ib_buffer)) { release_sid(me->stream2mmio_id, &me->stream2mmio_sid_id); return false; } if (!acquire_dma_channel(me->dma_id, &me->dma_channel)) { release_sid(me->stream2mmio_id, &me->stream2mmio_sid_id); release_ib_buffer(&me->ib_buffer); return false; } return true; } static void destroy_input_system_channel( input_system_channel_t *me) { release_sid(me->stream2mmio_id, &me->stream2mmio_sid_id); release_ib_buffer(&me->ib_buffer); release_dma_channel(me->dma_id, &me->dma_channel); } static bool create_input_system_input_port( isp2401_input_system_cfg_t *cfg, input_system_input_port_t *me) { csi_mipi_packet_type_t packet_type; bool rc = true; switch (cfg->input_port_id) { case INPUT_SYSTEM_CSI_PORT0_ID: me->csi_rx.frontend_id = CSI_RX_FRONTEND0_ID; me->csi_rx.backend_id = CSI_RX_BACKEND0_ID; packet_type = get_csi_mipi_packet_type(cfg->csi_port_attr.fmt_type); me->csi_rx.packet_type = packet_type; rc = acquire_be_lut_entry( me->csi_rx.backend_id, packet_type, &me->csi_rx.backend_lut_entry); break; case INPUT_SYSTEM_PIXELGEN_PORT0_ID: me->pixelgen.pixelgen_id = PIXELGEN0_ID; break; case INPUT_SYSTEM_CSI_PORT1_ID: me->csi_rx.frontend_id = CSI_RX_FRONTEND1_ID; me->csi_rx.backend_id = CSI_RX_BACKEND1_ID; packet_type = get_csi_mipi_packet_type(cfg->csi_port_attr.fmt_type); me->csi_rx.packet_type = packet_type; rc = acquire_be_lut_entry( me->csi_rx.backend_id, packet_type, &me->csi_rx.backend_lut_entry); break; case INPUT_SYSTEM_PIXELGEN_PORT1_ID: me->pixelgen.pixelgen_id = PIXELGEN1_ID; break; case INPUT_SYSTEM_CSI_PORT2_ID: me->csi_rx.frontend_id = CSI_RX_FRONTEND2_ID; me->csi_rx.backend_id = CSI_RX_BACKEND2_ID; packet_type = get_csi_mipi_packet_type(cfg->csi_port_attr.fmt_type); me->csi_rx.packet_type = packet_type; rc = acquire_be_lut_entry( me->csi_rx.backend_id, packet_type, &me->csi_rx.backend_lut_entry); break; case INPUT_SYSTEM_PIXELGEN_PORT2_ID: me->pixelgen.pixelgen_id = PIXELGEN2_ID; break; default: rc = false; break; } me->source_type = cfg->mode; /* for metadata */ me->metadata.packet_type = CSI_MIPI_PACKET_TYPE_UNDEFINED; if (rc && cfg->metadata.enable) { me->metadata.packet_type = get_csi_mipi_packet_type( cfg->metadata.fmt_type); rc = acquire_be_lut_entry( me->csi_rx.backend_id, me->metadata.packet_type, &me->metadata.backend_lut_entry); } return rc; } static void destroy_input_system_input_port( input_system_input_port_t *me) { if (me->source_type == INPUT_SYSTEM_SOURCE_TYPE_SENSOR) { release_be_lut_entry( me->csi_rx.backend_id, me->csi_rx.packet_type, &me->csi_rx.backend_lut_entry); } if (me->metadata.packet_type != CSI_MIPI_PACKET_TYPE_UNDEFINED) { /*Free the backend lut allocated for metadata*/ release_be_lut_entry( me->csi_rx.backend_id, me->metadata.packet_type, &me->metadata.backend_lut_entry); } } static bool calculate_input_system_channel_cfg( input_system_channel_t *channel, input_system_input_port_t *input_port, isp2401_input_system_cfg_t *isys_cfg, input_system_channel_cfg_t *channel_cfg, bool metadata) { bool rc; rc = calculate_stream2mmio_cfg(isys_cfg, metadata, &channel_cfg->stream2mmio_cfg); if (!rc) return false; rc = calculate_ibuf_ctrl_cfg( channel, input_port, isys_cfg, &channel_cfg->ibuf_ctrl_cfg); if (!rc) return false; if (metadata) channel_cfg->ibuf_ctrl_cfg.stores_per_frame = isys_cfg->metadata.lines_per_frame; rc = calculate_isys2401_dma_cfg( channel, isys_cfg, &channel_cfg->dma_cfg); if (!rc) return false; rc = calculate_isys2401_dma_port_cfg( isys_cfg, false, metadata, &channel_cfg->dma_src_port_cfg); if (!rc) return false; rc = calculate_isys2401_dma_port_cfg( isys_cfg, isys_cfg->raw_packed, metadata, &channel_cfg->dma_dest_port_cfg); if (!rc) return false; return true; } static bool calculate_input_system_input_port_cfg( input_system_channel_t *channel, input_system_input_port_t *input_port, isp2401_input_system_cfg_t *isys_cfg, input_system_input_port_cfg_t *input_port_cfg) { bool rc; switch (input_port->source_type) { case INPUT_SYSTEM_SOURCE_TYPE_SENSOR: rc = calculate_fe_cfg( isys_cfg, &input_port_cfg->csi_rx_cfg.frontend_cfg); rc &= calculate_be_cfg( input_port, isys_cfg, false, &input_port_cfg->csi_rx_cfg.backend_cfg); if (rc && isys_cfg->metadata.enable) rc &= calculate_be_cfg(input_port, isys_cfg, true, &input_port_cfg->csi_rx_cfg.md_backend_cfg); break; case INPUT_SYSTEM_SOURCE_TYPE_TPG: rc = calculate_tpg_cfg( channel, input_port, isys_cfg, &input_port_cfg->pixelgen_cfg.tpg_cfg); break; case INPUT_SYSTEM_SOURCE_TYPE_PRBS: rc = calculate_prbs_cfg( channel, input_port, isys_cfg, &input_port_cfg->pixelgen_cfg.prbs_cfg); break; default: rc = false; break; } return rc; } static bool acquire_sid( stream2mmio_ID_t stream2mmio, stream2mmio_sid_ID_t *sid) { return ia_css_isys_stream2mmio_sid_rmgr_acquire(stream2mmio, sid); } static void release_sid( stream2mmio_ID_t stream2mmio, stream2mmio_sid_ID_t *sid) { ia_css_isys_stream2mmio_sid_rmgr_release(stream2mmio, sid); } /* See also: ia_css_dma_configure_from_info() */ static int32_t calculate_stride( s32 bits_per_pixel, s32 pixels_per_line, bool raw_packed, int32_t align_in_bytes) { s32 bytes_per_line; s32 pixels_per_word; s32 words_per_line; s32 pixels_per_line_padded; pixels_per_line_padded = CEIL_MUL(pixels_per_line, align_in_bytes); if (!raw_packed) bits_per_pixel = CEIL_MUL(bits_per_pixel, 8); pixels_per_word = HIVE_ISP_DDR_WORD_BITS / bits_per_pixel; words_per_line = ceil_div(pixels_per_line_padded, pixels_per_word); bytes_per_line = HIVE_ISP_DDR_WORD_BYTES * words_per_line; return bytes_per_line; } static bool acquire_ib_buffer( s32 bits_per_pixel, s32 pixels_per_line, s32 lines_per_frame, s32 align_in_bytes, bool online, isp2401_ib_buffer_t *buf) { buf->stride = calculate_stride(bits_per_pixel, pixels_per_line, false, align_in_bytes); if (online) buf->lines = 4; /* use double buffering for online usecases */ else buf->lines = 2; (void)(lines_per_frame); return ia_css_isys_ibuf_rmgr_acquire(buf->stride * buf->lines, &buf->start_addr); } static void release_ib_buffer( isp2401_ib_buffer_t *buf) { ia_css_isys_ibuf_rmgr_release(&buf->start_addr); } static bool acquire_dma_channel( isys2401_dma_ID_t dma_id, isys2401_dma_channel *channel) { return ia_css_isys_dma_channel_rmgr_acquire(dma_id, channel); } static void release_dma_channel( isys2401_dma_ID_t dma_id, isys2401_dma_channel *channel) { ia_css_isys_dma_channel_rmgr_release(dma_id, channel); } static bool acquire_be_lut_entry( csi_rx_backend_ID_t backend, csi_mipi_packet_type_t packet_type, csi_rx_backend_lut_entry_t *entry) { return ia_css_isys_csi_rx_lut_rmgr_acquire(backend, packet_type, entry); } static void release_be_lut_entry( csi_rx_backend_ID_t backend, csi_mipi_packet_type_t packet_type, csi_rx_backend_lut_entry_t *entry) { ia_css_isys_csi_rx_lut_rmgr_release(backend, packet_type, entry); } static bool calculate_tpg_cfg( input_system_channel_t *channel, input_system_input_port_t *input_port, isp2401_input_system_cfg_t *isys_cfg, pixelgen_tpg_cfg_t *cfg) { memcpy(cfg, &isys_cfg->tpg_port_attr, sizeof(pixelgen_tpg_cfg_t)); return true; } static bool calculate_prbs_cfg( input_system_channel_t *channel, input_system_input_port_t *input_port, isp2401_input_system_cfg_t *isys_cfg, pixelgen_prbs_cfg_t *cfg) { memcpy(cfg, &isys_cfg->prbs_port_attr, sizeof(pixelgen_prbs_cfg_t)); return true; } static bool calculate_fe_cfg( const isp2401_input_system_cfg_t *isys_cfg, csi_rx_frontend_cfg_t *cfg) { cfg->active_lanes = isys_cfg->csi_port_attr.active_lanes; return true; } static bool calculate_be_cfg( const input_system_input_port_t *input_port, const isp2401_input_system_cfg_t *isys_cfg, bool metadata, csi_rx_backend_cfg_t *cfg) { memcpy(&cfg->lut_entry, metadata ? &input_port->metadata.backend_lut_entry : &input_port->csi_rx.backend_lut_entry, sizeof(csi_rx_backend_lut_entry_t)); cfg->csi_mipi_cfg.virtual_channel = isys_cfg->csi_port_attr.ch_id; if (metadata) { cfg->csi_mipi_packet_type = get_csi_mipi_packet_type( isys_cfg->metadata.fmt_type); cfg->csi_mipi_cfg.comp_enable = false; cfg->csi_mipi_cfg.data_type = isys_cfg->metadata.fmt_type; } else { cfg->csi_mipi_packet_type = get_csi_mipi_packet_type( isys_cfg->csi_port_attr.fmt_type); cfg->csi_mipi_cfg.data_type = isys_cfg->csi_port_attr.fmt_type; cfg->csi_mipi_cfg.comp_enable = isys_cfg->csi_port_attr.comp_enable; cfg->csi_mipi_cfg.comp_scheme = isys_cfg->csi_port_attr.comp_scheme; cfg->csi_mipi_cfg.comp_predictor = isys_cfg->csi_port_attr.comp_predictor; cfg->csi_mipi_cfg.comp_bit_idx = cfg->csi_mipi_cfg.data_type - MIPI_FORMAT_CUSTOM0; } return true; } static bool calculate_stream2mmio_cfg( const isp2401_input_system_cfg_t *isys_cfg, bool metadata, stream2mmio_cfg_t *cfg ) { cfg->bits_per_pixel = metadata ? isys_cfg->metadata.bits_per_pixel : isys_cfg->input_port_resolution.bits_per_pixel; cfg->enable_blocking = ((isys_cfg->mode == INPUT_SYSTEM_SOURCE_TYPE_TPG) || (isys_cfg->mode == INPUT_SYSTEM_SOURCE_TYPE_PRBS)); return true; } static bool calculate_ibuf_ctrl_cfg( const input_system_channel_t *channel, const input_system_input_port_t *input_port, const isp2401_input_system_cfg_t *isys_cfg, ibuf_ctrl_cfg_t *cfg) { const s32 bits_per_byte = 8; s32 bits_per_pixel; s32 bytes_per_pixel; s32 left_padding; (void)input_port; bits_per_pixel = isys_cfg->input_port_resolution.bits_per_pixel; bytes_per_pixel = ceil_div(bits_per_pixel, bits_per_byte); left_padding = CEIL_MUL(isys_cfg->output_port_attr.left_padding, ISP_VEC_NELEMS) * bytes_per_pixel; cfg->online = isys_cfg->online; cfg->dma_cfg.channel = channel->dma_channel; cfg->dma_cfg.cmd = _DMA_V2_MOVE_A2B_NO_SYNC_CHK_COMMAND; cfg->dma_cfg.shift_returned_items = 0; cfg->dma_cfg.elems_per_word_in_ibuf = 0; cfg->dma_cfg.elems_per_word_in_dest = 0; cfg->ib_buffer.start_addr = channel->ib_buffer.start_addr; cfg->ib_buffer.stride = channel->ib_buffer.stride; cfg->ib_buffer.lines = channel->ib_buffer.lines; /* #ifndef ISP2401 * zhengjie.lu@intel.com: #endif * "dest_buf_cfg" should be part of the input system output * port configuration. * * TODO: move "dest_buf_cfg" to the input system output * port configuration. */ /* input_buf addr only available in sched mode; this buffer is allocated in isp, crun mode addr can be passed by after ISP allocation */ if (cfg->online) { cfg->dest_buf_cfg.start_addr = ISP_INPUT_BUF_START_ADDR + left_padding; cfg->dest_buf_cfg.stride = bytes_per_pixel * isys_cfg->output_port_attr.max_isp_input_width; cfg->dest_buf_cfg.lines = LINES_OF_ISP_INPUT_BUF; } else if (isys_cfg->raw_packed) { cfg->dest_buf_cfg.stride = calculate_stride(bits_per_pixel, isys_cfg->input_port_resolution.pixels_per_line, isys_cfg->raw_packed, isys_cfg->input_port_resolution.align_req_in_bytes); } else { cfg->dest_buf_cfg.stride = channel->ib_buffer.stride; } /* #ifndef ISP2401 * zhengjie.lu@intel.com: #endif * "items_per_store" is hard coded as "1", which is ONLY valid * when the CSI-MIPI long packet is transferred. * * TODO: After the 1st stage of MERR+, make the proper solution to * configure "items_per_store" so that it can also handle the CSI-MIPI * short packet. */ cfg->items_per_store = 1; cfg->stores_per_frame = isys_cfg->input_port_resolution.lines_per_frame; cfg->stream2mmio_cfg.sync_cmd = _STREAM2MMIO_CMD_TOKEN_SYNC_FRAME; /* TODO: Define conditions as when to use store words vs store packets */ cfg->stream2mmio_cfg.store_cmd = _STREAM2MMIO_CMD_TOKEN_STORE_PACKETS; return true; } static bool calculate_isys2401_dma_cfg( const input_system_channel_t *channel, const isp2401_input_system_cfg_t *isys_cfg, isys2401_dma_cfg_t *cfg) { cfg->channel = channel->dma_channel; /* only online/sensor mode goto vmem offline/buffered_sensor, tpg and prbs will go to ddr */ if (isys_cfg->online) cfg->connection = isys2401_dma_ibuf_to_vmem_connection; else cfg->connection = isys2401_dma_ibuf_to_ddr_connection; cfg->extension = isys2401_dma_zero_extension; cfg->height = 1; return true; } /* See also: ia_css_dma_configure_from_info() */ static bool calculate_isys2401_dma_port_cfg( const isp2401_input_system_cfg_t *isys_cfg, bool raw_packed, bool metadata, isys2401_dma_port_cfg_t *cfg) { s32 bits_per_pixel; s32 pixels_per_line; s32 align_req_in_bytes; /* TODO: Move metadata away from isys_cfg to application layer */ if (metadata) { bits_per_pixel = isys_cfg->metadata.bits_per_pixel; pixels_per_line = isys_cfg->metadata.pixels_per_line; align_req_in_bytes = isys_cfg->metadata.align_req_in_bytes; } else { bits_per_pixel = isys_cfg->input_port_resolution.bits_per_pixel; pixels_per_line = isys_cfg->input_port_resolution.pixels_per_line; align_req_in_bytes = isys_cfg->input_port_resolution.align_req_in_bytes; } cfg->stride = calculate_stride(bits_per_pixel, pixels_per_line, raw_packed, align_req_in_bytes); if (!raw_packed) bits_per_pixel = CEIL_MUL(bits_per_pixel, 8); cfg->elements = HIVE_ISP_DDR_WORD_BITS / bits_per_pixel; cfg->cropping = 0; cfg->width = CEIL_DIV(cfg->stride, HIVE_ISP_DDR_WORD_BYTES); return true; } static csi_mipi_packet_type_t get_csi_mipi_packet_type( int32_t data_type) { csi_mipi_packet_type_t packet_type; packet_type = CSI_MIPI_PACKET_TYPE_RESERVED; if (data_type >= 0 && data_type <= MIPI_FORMAT_SHORT8) packet_type = CSI_MIPI_PACKET_TYPE_SHORT; if (data_type > MIPI_FORMAT_SHORT8 && data_type <= N_MIPI_FORMAT) packet_type = CSI_MIPI_PACKET_TYPE_LONG; return packet_type; } /* end of Private Methods */ #endif