// 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 <linux/string.h> /* 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;
	}

#ifdef ISP2401
	/*
	 * Early polling is required for timestamp accuracy in certain cause.
	 * The ISYS HW polling is started on
	 * ia_css_isys_stream_capture_indication() instead of
	 * ia_css_pipeline_sp_wait_for_isys_stream_N() as isp processing of
	 * capture takes longer than getting an ISYS frame
	 */
	isys_stream->polling_mode = isys_stream_descr->polling_mode;

#endif
	/* 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
