// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) STMicroelectronics SA 2013
 * Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
 */

#include <linux/slab.h>

#include "delta.h"
#include "delta-ipc.h"
#include "delta-mjpeg.h"
#include "delta-mjpeg-fw.h"

#define DELTA_MJPEG_MAX_RESO DELTA_MAX_RESO

struct delta_mjpeg_ctx {
	/* jpeg header */
	struct mjpeg_header header_struct;
	struct mjpeg_header *header;

	/* ipc */
	void *ipc_hdl;
	struct delta_buf *ipc_buf;

	/* decoded output frame */
	struct delta_frame *out_frame;

	unsigned char str[3000];
};

#define to_ctx(ctx) ((struct delta_mjpeg_ctx *)(ctx)->priv)

static char *ipc_open_param_str(struct jpeg_video_decode_init_params_t *p,
				char *str, unsigned int len)
{
	char *b = str;

	if (!p)
		return "";

	b += snprintf(b, len,
		      "jpeg_video_decode_init_params_t\n"
		      "circular_buffer_begin_addr_p 0x%x\n"
		      "circular_buffer_end_addr_p   0x%x\n",
		      p->circular_buffer_begin_addr_p,
		      p->circular_buffer_end_addr_p);

	return str;
}

static char *ipc_decode_param_str(struct jpeg_decode_params_t *p,
				  char *str, unsigned int len)
{
	char *b = str;

	if (!p)
		return "";

	b += snprintf(b, len,
		      "jpeg_decode_params_t\n"
		      "picture_start_addr_p                  0x%x\n"
		      "picture_end_addr_p                    0x%x\n"
		      "decoding_mode                        %d\n"
		      "display_buffer_addr.display_decimated_luma_p   0x%x\n"
		      "display_buffer_addr.display_decimated_chroma_p 0x%x\n"
		      "main_aux_enable                       %d\n"
		      "additional_flags                     0x%x\n"
		      "field_flag                           %x\n"
		      "is_jpeg_image                        %x\n",
		      p->picture_start_addr_p,
		      p->picture_end_addr_p,
		      p->decoding_mode,
		      p->display_buffer_addr.display_decimated_luma_p,
		      p->display_buffer_addr.display_decimated_chroma_p,
		      p->main_aux_enable, p->additional_flags,
		      p->field_flag,
		      p->is_jpeg_image);

	return str;
}

static inline bool is_stream_error(enum jpeg_decoding_error_t err)
{
	switch (err) {
	case JPEG_DECODER_UNDEFINED_HUFF_TABLE:
	case JPEG_DECODER_BAD_RESTART_MARKER:
	case JPEG_DECODER_BAD_SOS_SPECTRAL:
	case JPEG_DECODER_BAD_SOS_SUCCESSIVE:
	case JPEG_DECODER_BAD_HEADER_LENGTH:
	case JPEG_DECODER_BAD_COUNT_VALUE:
	case JPEG_DECODER_BAD_DHT_MARKER:
	case JPEG_DECODER_BAD_INDEX_VALUE:
	case JPEG_DECODER_BAD_NUMBER_HUFFMAN_TABLES:
	case JPEG_DECODER_BAD_QUANT_TABLE_LENGTH:
	case JPEG_DECODER_BAD_NUMBER_QUANT_TABLES:
	case JPEG_DECODER_BAD_COMPONENT_COUNT:
		return true;
	default:
		return false;
	}
}

static inline const char *err_str(enum jpeg_decoding_error_t err)
{
	switch (err) {
	case JPEG_DECODER_NO_ERROR:
		return "JPEG_DECODER_NO_ERROR";
	case JPEG_DECODER_UNDEFINED_HUFF_TABLE:
		return "JPEG_DECODER_UNDEFINED_HUFF_TABLE";
	case JPEG_DECODER_UNSUPPORTED_MARKER:
		return "JPEG_DECODER_UNSUPPORTED_MARKER";
	case JPEG_DECODER_UNABLE_ALLOCATE_MEMORY:
		return "JPEG_DECODER_UNABLE_ALLOCATE_MEMORY";
	case JPEG_DECODER_NON_SUPPORTED_SAMP_FACTORS:
		return "JPEG_DECODER_NON_SUPPORTED_SAMP_FACTORS";
	case JPEG_DECODER_BAD_PARAMETER:
		return "JPEG_DECODER_BAD_PARAMETER";
	case JPEG_DECODER_DECODE_ERROR:
		return "JPEG_DECODER_DECODE_ERROR";
	case JPEG_DECODER_BAD_RESTART_MARKER:
		return "JPEG_DECODER_BAD_RESTART_MARKER";
	case JPEG_DECODER_UNSUPPORTED_COLORSPACE:
		return "JPEG_DECODER_UNSUPPORTED_COLORSPACE";
	case JPEG_DECODER_BAD_SOS_SPECTRAL:
		return "JPEG_DECODER_BAD_SOS_SPECTRAL";
	case JPEG_DECODER_BAD_SOS_SUCCESSIVE:
		return "JPEG_DECODER_BAD_SOS_SUCCESSIVE";
	case JPEG_DECODER_BAD_HEADER_LENGTH:
		return "JPEG_DECODER_BAD_HEADER_LENGTH";
	case JPEG_DECODER_BAD_COUNT_VALUE:
		return "JPEG_DECODER_BAD_COUNT_VALUE";
	case JPEG_DECODER_BAD_DHT_MARKER:
		return "JPEG_DECODER_BAD_DHT_MARKER";
	case JPEG_DECODER_BAD_INDEX_VALUE:
		return "JPEG_DECODER_BAD_INDEX_VALUE";
	case JPEG_DECODER_BAD_NUMBER_HUFFMAN_TABLES:
		return "JPEG_DECODER_BAD_NUMBER_HUFFMAN_TABLES";
	case JPEG_DECODER_BAD_QUANT_TABLE_LENGTH:
		return "JPEG_DECODER_BAD_QUANT_TABLE_LENGTH";
	case JPEG_DECODER_BAD_NUMBER_QUANT_TABLES:
		return "JPEG_DECODER_BAD_NUMBER_QUANT_TABLES";
	case JPEG_DECODER_BAD_COMPONENT_COUNT:
		return "JPEG_DECODER_BAD_COMPONENT_COUNT";
	case JPEG_DECODER_DIVIDE_BY_ZERO_ERROR:
		return "JPEG_DECODER_DIVIDE_BY_ZERO_ERROR";
	case JPEG_DECODER_NOT_JPG_IMAGE:
		return "JPEG_DECODER_NOT_JPG_IMAGE";
	case JPEG_DECODER_UNSUPPORTED_ROTATION_ANGLE:
		return "JPEG_DECODER_UNSUPPORTED_ROTATION_ANGLE";
	case JPEG_DECODER_UNSUPPORTED_SCALING:
		return "JPEG_DECODER_UNSUPPORTED_SCALING";
	case JPEG_DECODER_INSUFFICIENT_OUTPUTBUFFER_SIZE:
		return "JPEG_DECODER_INSUFFICIENT_OUTPUTBUFFER_SIZE";
	case JPEG_DECODER_BAD_HWCFG_GP_VERSION_VALUE:
		return "JPEG_DECODER_BAD_HWCFG_GP_VERSION_VALUE";
	case JPEG_DECODER_BAD_VALUE_FROM_RED:
		return "JPEG_DECODER_BAD_VALUE_FROM_RED";
	case JPEG_DECODER_BAD_SUBREGION_PARAMETERS:
		return "JPEG_DECODER_BAD_SUBREGION_PARAMETERS";
	case JPEG_DECODER_PROGRESSIVE_DECODE_NOT_SUPPORTED:
		return "JPEG_DECODER_PROGRESSIVE_DECODE_NOT_SUPPORTED";
	case JPEG_DECODER_ERROR_TASK_TIMEOUT:
		return "JPEG_DECODER_ERROR_TASK_TIMEOUT";
	case JPEG_DECODER_ERROR_FEATURE_NOT_SUPPORTED:
		return "JPEG_DECODER_ERROR_FEATURE_NOT_SUPPORTED";
	default:
		return "!unknown MJPEG error!";
	}
}

static bool delta_mjpeg_check_status(struct delta_ctx *pctx,
				     struct jpeg_decode_return_params_t *status)
{
	struct delta_dev *delta = pctx->dev;
	bool dump = false;

	if (status->error_code == JPEG_DECODER_NO_ERROR)
		goto out;

	if (is_stream_error(status->error_code)) {
		dev_warn_ratelimited(delta->dev,
				     "%s  firmware: stream error @ frame %d (%s)\n",
				     pctx->name, pctx->decoded_frames,
				     err_str(status->error_code));
		pctx->stream_errors++;
	} else {
		dev_warn_ratelimited(delta->dev,
				     "%s  firmware: decode error @ frame %d (%s)\n",
				     pctx->name, pctx->decoded_frames,
				     err_str(status->error_code));
		pctx->decode_errors++;
		dump = true;
	}

out:
	dev_dbg(delta->dev,
		"%s  firmware: decoding time(us)=%d\n", pctx->name,
		status->decode_time_in_us);

	return dump;
}

static int delta_mjpeg_ipc_open(struct delta_ctx *pctx)
{
	struct delta_dev *delta = pctx->dev;
	struct delta_mjpeg_ctx *ctx = to_ctx(pctx);
	int ret = 0;
	struct jpeg_video_decode_init_params_t params_struct;
	struct jpeg_video_decode_init_params_t *params = &params_struct;
	struct delta_buf *ipc_buf;
	u32 ipc_buf_size;
	struct delta_ipc_param ipc_param;
	void *hdl;

	memset(params, 0, sizeof(*params));
	params->circular_buffer_begin_addr_p = 0x00000000;
	params->circular_buffer_end_addr_p = 0xffffffff;

	dev_vdbg(delta->dev,
		 "%s  %s\n", pctx->name,
		 ipc_open_param_str(params, ctx->str, sizeof(ctx->str)));

	ipc_param.size = sizeof(*params);
	ipc_param.data = params;
	ipc_buf_size = sizeof(struct jpeg_decode_params_t) +
	    sizeof(struct jpeg_decode_return_params_t);
	ret = delta_ipc_open(pctx, "JPEG_DECODER_HW0", &ipc_param,
			     ipc_buf_size, &ipc_buf, &hdl);
	if (ret) {
		dev_err(delta->dev,
			"%s  dumping command %s\n", pctx->name,
			ipc_open_param_str(params, ctx->str, sizeof(ctx->str)));
		return ret;
	}

	ctx->ipc_buf = ipc_buf;
	ctx->ipc_hdl = hdl;

	return 0;
}

static int delta_mjpeg_ipc_decode(struct delta_ctx *pctx, struct delta_au *au)
{
	struct delta_dev *delta = pctx->dev;
	struct delta_mjpeg_ctx *ctx = to_ctx(pctx);
	int ret = 0;
	struct jpeg_decode_params_t *params = ctx->ipc_buf->vaddr;
	struct jpeg_decode_return_params_t *status =
	    ctx->ipc_buf->vaddr + sizeof(*params);
	struct delta_frame *frame;
	struct delta_ipc_param ipc_param, ipc_status;

	ret = delta_get_free_frame(pctx, &frame);
	if (ret)
		return ret;

	memset(params, 0, sizeof(*params));

	params->picture_start_addr_p = (u32)(au->paddr);
	params->picture_end_addr_p = (u32)(au->paddr + au->size - 1);

	/*
	 * !WARNING!
	 * the NV12 decoded frame is only available
	 * on decimated output when enabling flag
	 * "JPEG_ADDITIONAL_FLAG_420MB"...
	 * the non decimated output gives YUV422SP
	 */
	params->main_aux_enable = JPEG_DISP_AUX_EN;
	params->additional_flags = JPEG_ADDITIONAL_FLAG_420MB;
	params->horizontal_decimation_factor = JPEG_HDEC_1;
	params->vertical_decimation_factor = JPEG_VDEC_1;
	params->decoding_mode = JPEG_NORMAL_DECODE;

	params->display_buffer_addr.struct_size =
	    sizeof(struct jpeg_display_buffer_address_t);
	params->display_buffer_addr.display_decimated_luma_p =
	    (u32)frame->paddr;
	params->display_buffer_addr.display_decimated_chroma_p =
	    (u32)(frame->paddr
		  + frame->info.aligned_width * frame->info.aligned_height);

	dev_vdbg(delta->dev,
		 "%s  %s\n", pctx->name,
		 ipc_decode_param_str(params, ctx->str, sizeof(ctx->str)));

	/* status */
	memset(status, 0, sizeof(*status));
	status->error_code = JPEG_DECODER_NO_ERROR;

	ipc_param.size = sizeof(*params);
	ipc_param.data = params;
	ipc_status.size = sizeof(*status);
	ipc_status.data = status;
	ret = delta_ipc_decode(ctx->ipc_hdl, &ipc_param, &ipc_status);
	if (ret) {
		dev_err(delta->dev,
			"%s  dumping command %s\n", pctx->name,
			ipc_decode_param_str(params, ctx->str,
					     sizeof(ctx->str)));
		return ret;
	}

	pctx->decoded_frames++;

	/* check firmware decoding status */
	if (delta_mjpeg_check_status(pctx, status)) {
		dev_err(delta->dev,
			"%s  dumping command %s\n", pctx->name,
			ipc_decode_param_str(params, ctx->str,
					     sizeof(ctx->str)));
	}

	frame->field = V4L2_FIELD_NONE;
	frame->flags = V4L2_BUF_FLAG_KEYFRAME;
	frame->state |= DELTA_FRAME_DEC;

	ctx->out_frame = frame;

	return 0;
}

static int delta_mjpeg_open(struct delta_ctx *pctx)
{
	struct delta_mjpeg_ctx *ctx;

	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
	if (!ctx)
		return -ENOMEM;
	pctx->priv = ctx;

	return 0;
}

static int delta_mjpeg_close(struct delta_ctx *pctx)
{
	struct delta_mjpeg_ctx *ctx = to_ctx(pctx);

	if (ctx->ipc_hdl) {
		delta_ipc_close(ctx->ipc_hdl);
		ctx->ipc_hdl = NULL;
	}

	kfree(ctx);

	return 0;
}

static int delta_mjpeg_get_streaminfo(struct delta_ctx *pctx,
				      struct delta_streaminfo *streaminfo)
{
	struct delta_mjpeg_ctx *ctx = to_ctx(pctx);

	if (!ctx->header)
		goto nodata;

	streaminfo->streamformat = V4L2_PIX_FMT_MJPEG;
	streaminfo->width = ctx->header->frame_width;
	streaminfo->height = ctx->header->frame_height;

	/* progressive stream */
	streaminfo->field = V4L2_FIELD_NONE;

	streaminfo->dpb = 1;

	return 0;

nodata:
	return -ENODATA;
}

static int delta_mjpeg_decode(struct delta_ctx *pctx, struct delta_au *pau)
{
	struct delta_dev *delta = pctx->dev;
	struct delta_mjpeg_ctx *ctx = to_ctx(pctx);
	int ret;
	struct delta_au au = *pau;
	unsigned int data_offset = 0;
	struct mjpeg_header *header = &ctx->header_struct;

	if (!ctx->header) {
		ret = delta_mjpeg_read_header(pctx, au.vaddr, au.size,
					      header, &data_offset);
		if (ret) {
			pctx->stream_errors++;
			goto err;
		}
		if (header->frame_width * header->frame_height >
		    DELTA_MJPEG_MAX_RESO) {
			dev_err(delta->dev,
				"%s  stream resolution too large: %dx%d > %d pixels budget\n",
				pctx->name,
				header->frame_width,
				header->frame_height, DELTA_MJPEG_MAX_RESO);
			ret = -EINVAL;
			goto err;
		}
		ctx->header = header;
		goto out;
	}

	if (!ctx->ipc_hdl) {
		ret = delta_mjpeg_ipc_open(pctx);
		if (ret)
			goto err;
	}

	ret = delta_mjpeg_read_header(pctx, au.vaddr, au.size,
				      ctx->header, &data_offset);
	if (ret) {
		pctx->stream_errors++;
		goto err;
	}

	au.paddr += data_offset;
	au.vaddr += data_offset;

	ret = delta_mjpeg_ipc_decode(pctx, &au);
	if (ret)
		goto err;

out:
	return 0;

err:
	return ret;
}

static int delta_mjpeg_get_frame(struct delta_ctx *pctx,
				 struct delta_frame **frame)
{
	struct delta_mjpeg_ctx *ctx = to_ctx(pctx);

	if (!ctx->out_frame)
		return -ENODATA;

	*frame = ctx->out_frame;

	ctx->out_frame = NULL;

	return 0;
}

const struct delta_dec mjpegdec = {
	.name = "MJPEG",
	.streamformat = V4L2_PIX_FMT_MJPEG,
	.pixelformat = V4L2_PIX_FMT_NV12,
	.open = delta_mjpeg_open,
	.close = delta_mjpeg_close,
	.get_streaminfo = delta_mjpeg_get_streaminfo,
	.get_frameinfo = delta_get_frameinfo_default,
	.decode = delta_mjpeg_decode,
	.get_frame = delta_mjpeg_get_frame,
	.recycle = delta_recycle_default,
};
