// 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 "ia_css_mipi.h"
#include "sh_css_mipi.h"
#include <type_support.h>
#include "system_global.h"
#include "ia_css_err.h"
#include "ia_css_pipe.h"
#include "ia_css_stream_format.h"
#include "sh_css_stream_format.h"
#include "ia_css_stream_public.h"
#include "ia_css_frame_public.h"
#include "ia_css_input_port.h"
#include "ia_css_debug.h"
#include "sh_css_struct.h"
#include "sh_css_defs.h"
#include "sh_css_sp.h" /* sh_css_update_host2sp_mipi_frame sh_css_update_host2sp_num_mipi_frames ... */
#include "sw_event_global.h" /* IA_CSS_PSYS_SW_EVENT_MIPI_BUFFERS_READY */

static u32
ref_count_mipi_allocation[N_CSI_PORTS]; /* Initialized in mipi_init */

/*
 * Check if a source port or TPG/PRBS ID is valid
 */
static bool ia_css_mipi_is_source_port_valid(struct ia_css_pipe *pipe,
	unsigned int *pport)
{
	bool ret = true;
	unsigned int port = 0;
	unsigned int max_ports = 0;

	switch (pipe->stream->config.mode) {
	case IA_CSS_INPUT_MODE_BUFFERED_SENSOR:
		port = (unsigned int)pipe->stream->config.source.port.port;
		max_ports = N_CSI_PORTS;
		break;
	case IA_CSS_INPUT_MODE_TPG:
		port = (unsigned int)pipe->stream->config.source.tpg.id;
		max_ports = N_CSS_TPG_IDS;
		break;
	case IA_CSS_INPUT_MODE_PRBS:
		port = (unsigned int)pipe->stream->config.source.prbs.id;
		max_ports = N_CSS_PRBS_IDS;
		break;
	default:
		assert(false);
		ret = false;
		break;
	}

	if (ret) {
		assert(port < max_ports);

		if (port >= max_ports)
			ret = false;
	}

	*pport = port;

	return ret;
}

/* Assumptions:
 *	- A line is multiple of 4 bytes = 1 word.
 *	- Each frame has SOF and EOF (each 1 word).
 *	- Each line has format header and optionally SOL and EOL (each 1 word).
 *	- Odd and even lines of YUV420 format are different in bites per pixel size.
 *	- Custom size of embedded data.
 *  -- Interleaved frames are not taken into account.
 *  -- Lines are multiples of 8B, and not necessary of (custom 3B, or 7B
 *  etc.).
 * Result is given in DDR mem words, 32B or 256 bits
 */
int
ia_css_mipi_frame_calculate_size(const unsigned int width,
				 const unsigned int height,
				 const enum atomisp_input_format format,
				 const bool hasSOLandEOL,
				 const unsigned int embedded_data_size_words,
				 unsigned int *size_mem_words)
{
	int err = 0;

	unsigned int bits_per_pixel = 0;
	unsigned int even_line_bytes = 0;
	unsigned int odd_line_bytes = 0;
	unsigned int words_per_odd_line = 0;
	unsigned int words_for_first_line = 0;
	unsigned int words_per_even_line = 0;
	unsigned int mem_words_per_even_line = 0;
	unsigned int mem_words_per_odd_line = 0;
	unsigned int mem_words_for_first_line = 0;
	unsigned int mem_words_for_EOF = 0;
	unsigned int mem_words = 0;
	unsigned int width_padded = width;

#if defined(ISP2401)
	/* The changes will be reverted as soon as RAW
	 * Buffers are deployed by the 2401 Input System
	 * in the non-continuous use scenario.
	 */
	width_padded += (2 * ISP_VEC_NELEMS);
#endif

	IA_CSS_ENTER("padded_width=%d, height=%d, format=%d, hasSOLandEOL=%d, embedded_data_size_words=%d\n",
		     width_padded, height, format, hasSOLandEOL, embedded_data_size_words);

	switch (format) {
	case ATOMISP_INPUT_FORMAT_RAW_6:		/* 4p, 3B, 24bits */
		bits_per_pixel = 6;
		break;
	case ATOMISP_INPUT_FORMAT_RAW_7:		/* 8p, 7B, 56bits */
		bits_per_pixel = 7;
		break;
	case ATOMISP_INPUT_FORMAT_RAW_8:		/* 1p, 1B, 8bits */
	case ATOMISP_INPUT_FORMAT_BINARY_8:		/*  8bits, TODO: check. */
	case ATOMISP_INPUT_FORMAT_YUV420_8:		/* odd 2p, 2B, 16bits, even 2p, 4B, 32bits */
		bits_per_pixel = 8;
		break;
	case ATOMISP_INPUT_FORMAT_YUV420_10:		/* odd 4p, 5B, 40bits, even 4p, 10B, 80bits */
	case ATOMISP_INPUT_FORMAT_RAW_10:		/* 4p, 5B, 40bits */
#if !defined(HAS_NO_PACKED_RAW_PIXELS)
		/* The changes will be reverted as soon as RAW
		 * Buffers are deployed by the 2401 Input System
		 * in the non-continuous use scenario.
		 */
		bits_per_pixel = 10;
#else
		bits_per_pixel = 16;
#endif
		break;
	case ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY:	/* 2p, 3B, 24bits */
	case ATOMISP_INPUT_FORMAT_RAW_12:		/* 2p, 3B, 24bits */
		bits_per_pixel = 12;
		break;
	case ATOMISP_INPUT_FORMAT_RAW_14:		/* 4p, 7B, 56bits */
		bits_per_pixel = 14;
		break;
	case ATOMISP_INPUT_FORMAT_RGB_444:		/* 1p, 2B, 16bits */
	case ATOMISP_INPUT_FORMAT_RGB_555:		/* 1p, 2B, 16bits */
	case ATOMISP_INPUT_FORMAT_RGB_565:		/* 1p, 2B, 16bits */
	case ATOMISP_INPUT_FORMAT_YUV422_8:		/* 2p, 4B, 32bits */
		bits_per_pixel = 16;
		break;
	case ATOMISP_INPUT_FORMAT_RGB_666:		/* 4p, 9B, 72bits */
		bits_per_pixel = 18;
		break;
	case ATOMISP_INPUT_FORMAT_YUV422_10:		/* 2p, 5B, 40bits */
		bits_per_pixel = 20;
		break;
	case ATOMISP_INPUT_FORMAT_RGB_888:		/* 1p, 3B, 24bits */
		bits_per_pixel = 24;
		break;

	case ATOMISP_INPUT_FORMAT_YUV420_16:		/* Not supported */
	case ATOMISP_INPUT_FORMAT_YUV422_16:		/* Not supported */
	case ATOMISP_INPUT_FORMAT_RAW_16:		/* TODO: not specified in MIPI SPEC, check */
	default:
		return -EINVAL;
	}

	odd_line_bytes = (width_padded * bits_per_pixel + 7) >> 3; /* ceil ( bits per line / 8) */

	/* Even lines for YUV420 formats are double in bits_per_pixel. */
	if (format == ATOMISP_INPUT_FORMAT_YUV420_8
	    || format == ATOMISP_INPUT_FORMAT_YUV420_10
	    || format == ATOMISP_INPUT_FORMAT_YUV420_16) {
		even_line_bytes = (width_padded * 2 * bits_per_pixel + 7) >>
			3; /* ceil ( bits per line / 8) */
	} else {
		even_line_bytes = odd_line_bytes;
	}

	/*  a frame represented in memory:  ()- optional; data - payload words.
	*  addr		0	1	2	3	4	5	6	7:
	*  first	SOF	(SOL)	PACK_H	data	data	data	data	data
	*		data	data	data	data	data	data	data	data
	*		...
	*		data	data	0	0	0	0	0	0
	*  second	(EOL)	(SOL)	PACK_H	data	data	data	data	data
	*		data	data	data	data	data	data	data	data
	*		...
	*		data	data	0	0	0	0	0	0
	*  ...
	*  last		(EOL)	EOF	0	0	0	0	0	0
	*
	*  Embedded lines are regular lines stored before the first and after
	*  payload lines.
	*/

	words_per_odd_line = (odd_line_bytes + 3) >> 2;
	/* ceil(odd_line_bytes/4); word = 4 bytes */
	words_per_even_line  = (even_line_bytes  + 3) >> 2;
	words_for_first_line = words_per_odd_line + 2 + (hasSOLandEOL ? 1 : 0);
	/* + SOF +packet header + optionally (SOL), but (EOL) is not in the first line */
	words_per_odd_line	+= (1 + (hasSOLandEOL ? 2 : 0));
	/* each non-first line has format header, and optionally (SOL) and (EOL). */
	words_per_even_line += (1 + (hasSOLandEOL ? 2 : 0));

	mem_words_per_odd_line	 = (words_per_odd_line + 7) >> 3;
	/* ceil(words_per_odd_line/8); mem_word = 32 bytes, 8 words */
	mem_words_for_first_line = (words_for_first_line + 7) >> 3;
	mem_words_per_even_line  = (words_per_even_line + 7) >> 3;
	mem_words_for_EOF        = 1; /* last line consisit of the optional (EOL) and EOF */

	mem_words = ((embedded_data_size_words + 7) >> 3) +
	mem_words_for_first_line +
	(((height + 1) >> 1) - 1) * mem_words_per_odd_line +
	/* ceil (height/2) - 1 (first line is calculated separatelly) */
	(height      >> 1) * mem_words_per_even_line + /* floor(height/2) */
	mem_words_for_EOF;

	*size_mem_words = mem_words; /* ceil(words/8); mem word is 32B = 8words. */
	/* Check if the above is still needed. */

	IA_CSS_LEAVE_ERR(err);
	return err;
}

#if !defined(ISP2401)
int
ia_css_mipi_frame_enable_check_on_size(const enum mipi_port_id port,
				       const unsigned int	size_mem_words)
{
	u32 idx;

	int err = -EBUSY;

	OP___assert(port < N_CSI_PORTS);
	OP___assert(size_mem_words != 0);

	for (idx = 0; idx < IA_CSS_MIPI_SIZE_CHECK_MAX_NOF_ENTRIES_PER_PORT &&
	     my_css.mipi_sizes_for_check[port][idx] != 0;
	     idx++) { /* do nothing */
	}
	if (idx < IA_CSS_MIPI_SIZE_CHECK_MAX_NOF_ENTRIES_PER_PORT) {
		my_css.mipi_sizes_for_check[port][idx] = size_mem_words;
		err = 0;
	}

	return err;
}
#endif

void
mipi_init(void)
{
	unsigned int i;

	for (i = 0; i < N_CSI_PORTS; i++)
		ref_count_mipi_allocation[i] = 0;
}

int
calculate_mipi_buff_size(
    struct ia_css_stream_config *stream_cfg,
    unsigned int *size_mem_words)
{
#if !defined(ISP2401)
	int err = -EINVAL;
	(void)stream_cfg;
	(void)size_mem_words;
#else
	unsigned int width;
	unsigned int height;
	enum atomisp_input_format format;
	bool pack_raw_pixels;

	unsigned int width_padded;
	unsigned int bits_per_pixel = 0;

	unsigned int even_line_bytes = 0;
	unsigned int odd_line_bytes = 0;

	unsigned int words_per_odd_line = 0;
	unsigned int words_per_even_line = 0;

	unsigned int mem_words_per_even_line = 0;
	unsigned int mem_words_per_odd_line = 0;

	unsigned int mem_words_per_buff_line = 0;
	unsigned int mem_words_per_buff = 0;
	int err = 0;

	/**
	 * zhengjie.lu@intel.com
	 *
	 * NOTE
	 * - In the struct "ia_css_stream_config", there
	 *   are two members: "input_config" and "isys_config".
	 *   Both of them provide the same information, e.g.
	 *   input_res and format.
	 *
	 *   Question here is that: which one shall be used?
	 */
	width = stream_cfg->input_config.input_res.width;
	height = stream_cfg->input_config.input_res.height;
	format = stream_cfg->input_config.format;
	pack_raw_pixels = stream_cfg->pack_raw_pixels;
	/* end of NOTE */

	/**
	 * zhengjie.lu@intel.com
	 *
	 * NOTE
	 * - The following code is derived from the
	 *   existing code "ia_css_mipi_frame_calculate_size()".
	 *
	 *   Question here is: why adding "2 * ISP_VEC_NELEMS"
	 *   to "width_padded", but not making "width_padded"
	 *   aligned with "2 * ISP_VEC_NELEMS"?
	 */
	/* The changes will be reverted as soon as RAW
	 * Buffers are deployed by the 2401 Input System
	 * in the non-continuous use scenario.
	 */
	width_padded = width + (2 * ISP_VEC_NELEMS);
	/* end of NOTE */

	IA_CSS_ENTER("padded_width=%d, height=%d, format=%d\n",
		     width_padded, height, format);

	bits_per_pixel = sh_css_stream_format_2_bits_per_subpixel(format);
	bits_per_pixel =
	(format == ATOMISP_INPUT_FORMAT_RAW_10 && pack_raw_pixels) ? bits_per_pixel : 16;
	if (bits_per_pixel == 0)
		return -EINVAL;

	odd_line_bytes = (width_padded * bits_per_pixel + 7) >> 3; /* ceil ( bits per line / 8) */

	/* Even lines for YUV420 formats are double in bits_per_pixel. */
	if (format == ATOMISP_INPUT_FORMAT_YUV420_8
	    || format == ATOMISP_INPUT_FORMAT_YUV420_10) {
		even_line_bytes = (width_padded * 2 * bits_per_pixel + 7) >>
			3; /* ceil ( bits per line / 8) */
	} else {
		even_line_bytes = odd_line_bytes;
	}

	words_per_odd_line	 = (odd_line_bytes   + 3) >> 2;
	/* ceil(odd_line_bytes/4); word = 4 bytes */
	words_per_even_line  = (even_line_bytes  + 3) >> 2;

	mem_words_per_odd_line	 = (words_per_odd_line + 7) >> 3;
	/* ceil(words_per_odd_line/8); mem_word = 32 bytes, 8 words */
	mem_words_per_even_line  = (words_per_even_line + 7) >> 3;

	mem_words_per_buff_line =
	(mem_words_per_odd_line > mem_words_per_even_line) ? mem_words_per_odd_line : mem_words_per_even_line;
	mem_words_per_buff = mem_words_per_buff_line * height;

	*size_mem_words = mem_words_per_buff;

	IA_CSS_LEAVE_ERR(err);
#endif
	return err;
}

static bool buffers_needed(struct ia_css_pipe *pipe)
{
	if (!IS_ISP2401) {
		if (pipe->stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR)
			return false;
		else
			return true;
	}

	if (pipe->stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR ||
	    pipe->stream->config.mode == IA_CSS_INPUT_MODE_TPG ||
	    pipe->stream->config.mode == IA_CSS_INPUT_MODE_PRBS)
		return false;

	return true;
}

int
allocate_mipi_frames(struct ia_css_pipe *pipe,
		     struct ia_css_stream_info *info)
{
	int err = -EINVAL;
	unsigned int port;

	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
			    "allocate_mipi_frames(%p) enter:\n", pipe);

	assert(pipe);
	assert(pipe->stream);
	if ((!pipe) || (!pipe->stream)) {
		ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
				    "allocate_mipi_frames(%p) exit: pipe or stream is null.\n",
				    pipe);
		return -EINVAL;
	}

#ifdef ISP2401
	if (pipe->stream->config.online) {
		ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
				    "allocate_mipi_frames(%p) exit: no buffers needed for 2401 pipe mode.\n",
				    pipe);
		return 0;
	}

#endif

	if (!buffers_needed(pipe)) {
		ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
				    "allocate_mipi_frames(%p) exit: no buffers needed for pipe mode.\n",
				    pipe);
		return 0; /* AM TODO: Check  */
	}

	if (!IS_ISP2401)
		port = (unsigned int)pipe->stream->config.source.port.port;
	else
		err = ia_css_mipi_is_source_port_valid(pipe, &port);

	assert(port < N_CSI_PORTS);

	if (port >= N_CSI_PORTS || err) {
		ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
				    "allocate_mipi_frames(%p) exit: error: port is not correct (port=%d).\n",
				    pipe, port);
		return -EINVAL;
	}

#ifdef ISP2401
	err = calculate_mipi_buff_size(
	    &pipe->stream->config,
	    &my_css.mipi_frame_size[port]);
#endif

#if !defined(ISP2401)
	if (ref_count_mipi_allocation[port] != 0) {
		ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
				    "allocate_mipi_frames(%p) exit: already allocated for this port (port=%d).\n",
				    pipe, port);
		return 0;
	}
#else
	/* 2401 system allows multiple streams to use same physical port. This is not
	 * true for 2400 system. Currently 2401 uses MIPI buffers as a temporary solution.
	 * TODO AM: Once that is changed (removed) this code should be removed as well.
	 * In that case only 2400 related code should remain.
	 */
	if (ref_count_mipi_allocation[port] != 0) {
		ref_count_mipi_allocation[port]++;
		ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
				    "allocate_mipi_frames(%p) leave: nothing to do, already allocated for this port (port=%d).\n",
				    pipe, port);
		return 0;
	}
#endif

	ref_count_mipi_allocation[port]++;

	/* AM TODO: mipi frames number should come from stream struct. */
	my_css.num_mipi_frames[port] = NUM_MIPI_FRAMES_PER_STREAM;

	/* Incremental allocation (per stream), not for all streams at once. */
	{ /* limit the scope of i,j */
		unsigned int i, j;

		for (i = 0; i < my_css.num_mipi_frames[port]; i++) {
			/* free previous frame */
			if (my_css.mipi_frames[port][i]) {
				ia_css_frame_free(my_css.mipi_frames[port][i]);
				my_css.mipi_frames[port][i] = NULL;
			}
			/* check if new frame is needed */
			if (i < my_css.num_mipi_frames[port]) {
				/* allocate new frame */
				err = ia_css_frame_allocate_with_buffer_size(
					  &my_css.mipi_frames[port][i],
					  my_css.mipi_frame_size[port] * HIVE_ISP_DDR_WORD_BYTES,
					  false);
				if (err) {
					for (j = 0; j < i; j++) {
						if (my_css.mipi_frames[port][j]) {
							ia_css_frame_free(my_css.mipi_frames[port][j]);
							my_css.mipi_frames[port][j] = NULL;
						}
					}
					ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
							    "allocate_mipi_frames(%p, %d) exit: error: allocation failed.\n",
							    pipe, port);
					return err;
				}
			}
			if (info->metadata_info.size > 0) {
				/* free previous metadata buffer */
				if (my_css.mipi_metadata[port][i]) {
					ia_css_metadata_free(my_css.mipi_metadata[port][i]);
					my_css.mipi_metadata[port][i] = NULL;
				}
				/* check if need to allocate a new metadata buffer */
				if (i < my_css.num_mipi_frames[port]) {
					/* allocate new metadata buffer */
					my_css.mipi_metadata[port][i] = ia_css_metadata_allocate(&info->metadata_info);
					if (!my_css.mipi_metadata[port][i]) {
						ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
								    "allocate_mipi_metadata(%p, %d) failed.\n",
								    pipe, port);
						return err;
					}
				}
			}
		}
	}
	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
			    "allocate_mipi_frames(%p) exit:\n", pipe);

	return err;
}

int
free_mipi_frames(struct ia_css_pipe *pipe)
{
	int err = -EINVAL;
	unsigned int port;

	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
			    "free_mipi_frames(%p) enter:\n", pipe);

	/* assert(pipe != NULL); TEMP: TODO: Should be assert only. */
	if (pipe) {
		assert(pipe->stream);
		if ((!pipe) || (!pipe->stream)) {
			ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
					    "free_mipi_frames(%p) exit: error: pipe or stream is null.\n",
					    pipe);
			return -EINVAL;
		}

		if (!buffers_needed(pipe)) {
			ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
					    "free_mipi_frames(%p) exit: error: wrong mode.\n",
					    pipe);
			return err;
		}

		if (!IS_ISP2401)
			port = (unsigned int)pipe->stream->config.source.port.port;
		else
			err = ia_css_mipi_is_source_port_valid(pipe, &port);

		assert(port < N_CSI_PORTS);

		if (port >= N_CSI_PORTS || err) {
			ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
					    "free_mipi_frames(%p, %d) exit: error: pipe port is not correct.\n",
					    pipe, port);
			return err;
		}

		if (ref_count_mipi_allocation[port] > 0) {
#if !defined(ISP2401)
			assert(ref_count_mipi_allocation[port] == 1);
			if (ref_count_mipi_allocation[port] != 1) {
				ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
						    "free_mipi_frames(%p) exit: error: wrong ref_count (ref_count=%d).\n",
						    pipe, ref_count_mipi_allocation[port]);
				return err;
			}
#endif

			ref_count_mipi_allocation[port]--;

			if (ref_count_mipi_allocation[port] == 0) {
				/* no streams are using this buffer, so free it */
				unsigned int i;

				for (i = 0; i < my_css.num_mipi_frames[port]; i++) {
					if (my_css.mipi_frames[port][i]) {
						ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
								    "free_mipi_frames(port=%d, num=%d).\n", port, i);
						ia_css_frame_free(my_css.mipi_frames[port][i]);
						my_css.mipi_frames[port][i] = NULL;
					}
					if (my_css.mipi_metadata[port][i]) {
						ia_css_metadata_free(my_css.mipi_metadata[port][i]);
						my_css.mipi_metadata[port][i] = NULL;
					}
				}

				ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
						    "free_mipi_frames(%p) exit (deallocated).\n", pipe);
			}
#if defined(ISP2401)
			else {
				/* 2401 system allows multiple streams to use same physical port. This is not
				 * true for 2400 system. Currently 2401 uses MIPI buffers as a temporary solution.
				 * TODO AM: Once that is changed (removed) this code should be removed as well.
				 * In that case only 2400 related code should remain.
				 */
				ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
						    "free_mipi_frames(%p) leave: nothing to do, other streams still use this port (port=%d).\n",
						    pipe, port);
			}
#endif
		}
	} else { /* pipe ==NULL */
		/* AM TEMP: free-ing all mipi buffers just like a legacy code. */
		for (port = CSI_PORT0_ID; port < N_CSI_PORTS; port++) {
			unsigned int i;

			for (i = 0; i < my_css.num_mipi_frames[port]; i++) {
				if (my_css.mipi_frames[port][i]) {
					ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
							    "free_mipi_frames(port=%d, num=%d).\n", port, i);
					ia_css_frame_free(my_css.mipi_frames[port][i]);
					my_css.mipi_frames[port][i] = NULL;
				}
				if (my_css.mipi_metadata[port][i]) {
					ia_css_metadata_free(my_css.mipi_metadata[port][i]);
					my_css.mipi_metadata[port][i] = NULL;
				}
			}
			ref_count_mipi_allocation[port] = 0;
		}
	}
	return 0;
}

int
send_mipi_frames(struct ia_css_pipe *pipe)
{
	int err = -EINVAL;
	unsigned int i;
#ifndef ISP2401
	unsigned int port;
#else
	unsigned int port = 0;
#endif

	IA_CSS_ENTER_PRIVATE("pipe=%p", pipe);

	assert(pipe);
	assert(pipe->stream);
	if (!pipe || !pipe->stream) {
		IA_CSS_ERROR("pipe or stream is null");
		return -EINVAL;
	}

	/* multi stream video needs mipi buffers */
	/* nothing to be done in other cases. */
	if (!buffers_needed(pipe)) {
		IA_CSS_LOG("nothing to be done for this mode");
		return 0;
		/* TODO: AM: maybe this should be returning an error. */
	}

	if (!IS_ISP2401)
		port = (unsigned int)pipe->stream->config.source.port.port;
	else
		err = ia_css_mipi_is_source_port_valid(pipe, &port);

	assert(port < N_CSI_PORTS);

	if (port >= N_CSI_PORTS || err) {
		IA_CSS_ERROR("send_mipi_frames(%p) exit: invalid port specified (port=%d).\n",
			     pipe, port);
		return err;
	}

	/* Hand-over the SP-internal mipi buffers */
	for (i = 0; i < my_css.num_mipi_frames[port]; i++) {
		/* Need to include the ofset for port. */
		sh_css_update_host2sp_mipi_frame(port * NUM_MIPI_FRAMES_PER_STREAM + i,
						 my_css.mipi_frames[port][i]);
		sh_css_update_host2sp_mipi_metadata(port * NUM_MIPI_FRAMES_PER_STREAM + i,
						    my_css.mipi_metadata[port][i]);
	}
	sh_css_update_host2sp_num_mipi_frames(my_css.num_mipi_frames[port]);

	/**********************************
	 * Send an event to inform the SP
	 * that all MIPI frames are passed.
	 **********************************/
	if (!sh_css_sp_is_running()) {
		/* SP is not running. The queues are not valid */
		IA_CSS_ERROR("sp is not running");
		return err;
	}

	ia_css_bufq_enqueue_psys_event(
	    IA_CSS_PSYS_SW_EVENT_MIPI_BUFFERS_READY,
	    (uint8_t)port,
	    (uint8_t)my_css.num_mipi_frames[port],
	    0 /* not used */);
	IA_CSS_LEAVE_ERR_PRIVATE(0);
	return 0;
}
