// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2020-2021 NXP
 */

#include <linux/init.h>
#include <linux/interconnect.h>
#include <linux/ioctl.h>
#include <linux/list.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include "vpu.h"
#include "vpu_core.h"
#include "vpu_rpc.h"
#include "vpu_mbox.h"
#include "vpu_defs.h"
#include "vpu_cmds.h"
#include "vpu_msgs.h"
#include "vpu_v4l2.h"

#define VPU_PKT_HEADER_LENGTH		3

struct vpu_msg_handler {
	u32 id;
	void (*done)(struct vpu_inst *inst, struct vpu_rpc_event *pkt);
};

static void vpu_session_handle_start_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
{
	vpu_trace(inst->dev, "[%d]\n", inst->id);
}

static void vpu_session_handle_mem_request(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
{
	struct vpu_pkt_mem_req_data req_data;

	vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&req_data);
	vpu_trace(inst->dev, "[%d] %d:%d %d:%d %d:%d\n",
		  inst->id,
		  req_data.enc_frame_size,
		  req_data.enc_frame_num,
		  req_data.ref_frame_size,
		  req_data.ref_frame_num,
		  req_data.act_buf_size,
		  req_data.act_buf_num);
	call_void_vop(inst, mem_request,
		      req_data.enc_frame_size,
		      req_data.enc_frame_num,
		      req_data.ref_frame_size,
		      req_data.ref_frame_num,
		      req_data.act_buf_size,
		      req_data.act_buf_num);
}

static void vpu_session_handle_stop_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
{
	vpu_trace(inst->dev, "[%d]\n", inst->id);

	call_void_vop(inst, stop_done);
}

static void vpu_session_handle_seq_hdr(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
{
	struct vpu_dec_codec_info info;
	const struct vpu_core_resources *res;

	memset(&info, 0, sizeof(info));
	res = vpu_get_resource(inst);
	info.stride = res ? res->stride : 1;
	vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info);
	call_void_vop(inst, event_notify, VPU_MSG_ID_SEQ_HDR_FOUND, &info);
}

static void vpu_session_handle_resolution_change(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
{
	call_void_vop(inst, event_notify, VPU_MSG_ID_RES_CHANGE, NULL);
}

static void vpu_session_handle_enc_frame_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
{
	struct vpu_enc_pic_info info;

	vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info);
	dev_dbg(inst->dev, "[%d] frame id = %d, wptr = 0x%x, size = %d\n",
		inst->id, info.frame_id, info.wptr, info.frame_size);
	call_void_vop(inst, get_one_frame, &info);
}

static void vpu_session_handle_frame_request(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
{
	struct vpu_fs_info fs;

	vpu_iface_unpack_msg_data(inst->core, pkt, &fs);
	call_void_vop(inst, event_notify, VPU_MSG_ID_FRAME_REQ, &fs);
}

static void vpu_session_handle_frame_release(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
{
	if (inst->core->type == VPU_CORE_TYPE_ENC) {
		struct vpu_frame_info info;

		memset(&info, 0, sizeof(info));
		vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info.sequence);
		dev_dbg(inst->dev, "[%d] %d\n", inst->id, info.sequence);
		info.type = inst->out_format.type;
		call_void_vop(inst, buf_done, &info);
	} else if (inst->core->type == VPU_CORE_TYPE_DEC) {
		struct vpu_fs_info fs;

		vpu_iface_unpack_msg_data(inst->core, pkt, &fs);
		call_void_vop(inst, event_notify, VPU_MSG_ID_FRAME_RELEASE, &fs);
	}
}

static void vpu_session_handle_input_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
{
	dev_dbg(inst->dev, "[%d]\n", inst->id);
	call_void_vop(inst, input_done);
}

static void vpu_session_handle_pic_decoded(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
{
	struct vpu_dec_pic_info info;

	vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info);
	call_void_vop(inst, get_one_frame, &info);
}

static void vpu_session_handle_pic_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
{
	struct vpu_dec_pic_info info;
	struct vpu_frame_info frame;

	memset(&frame, 0, sizeof(frame));
	vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info);
	if (inst->core->type == VPU_CORE_TYPE_DEC)
		frame.type = inst->cap_format.type;
	frame.id = info.id;
	frame.luma = info.luma;
	frame.skipped = info.skipped;
	frame.timestamp = info.timestamp;

	call_void_vop(inst, buf_done, &frame);
}

static void vpu_session_handle_eos(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
{
	call_void_vop(inst, event_notify, VPU_MSG_ID_PIC_EOS, NULL);
}

static void vpu_session_handle_error(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
{
	char *str = (char *)pkt->data;

	if (strlen(str))
		dev_err(inst->dev, "instance %d firmware error : %s\n", inst->id, str);
	else
		dev_err(inst->dev, "instance %d is unsupported stream\n", inst->id);
	call_void_vop(inst, event_notify, VPU_MSG_ID_UNSUPPORTED, NULL);
	vpu_v4l2_set_error(inst);
}

static void vpu_session_handle_firmware_xcpt(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
{
	char *str = (char *)pkt->data;

	dev_err(inst->dev, "%s firmware xcpt: %s\n",
		vpu_core_type_desc(inst->core->type), str);
	call_void_vop(inst, event_notify, VPU_MSG_ID_FIRMWARE_XCPT, NULL);
	set_bit(inst->id, &inst->core->hang_mask);
	vpu_v4l2_set_error(inst);
}

static void vpu_session_handle_pic_skipped(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
{
	vpu_inst_lock(inst);
	vpu_skip_frame(inst, 1);
	vpu_inst_unlock(inst);
}

static struct vpu_msg_handler handlers[] = {
	{VPU_MSG_ID_START_DONE, vpu_session_handle_start_done},
	{VPU_MSG_ID_STOP_DONE, vpu_session_handle_stop_done},
	{VPU_MSG_ID_MEM_REQUEST, vpu_session_handle_mem_request},
	{VPU_MSG_ID_SEQ_HDR_FOUND, vpu_session_handle_seq_hdr},
	{VPU_MSG_ID_RES_CHANGE, vpu_session_handle_resolution_change},
	{VPU_MSG_ID_FRAME_INPUT_DONE, vpu_session_handle_input_done},
	{VPU_MSG_ID_FRAME_REQ, vpu_session_handle_frame_request},
	{VPU_MSG_ID_FRAME_RELEASE, vpu_session_handle_frame_release},
	{VPU_MSG_ID_ENC_DONE, vpu_session_handle_enc_frame_done},
	{VPU_MSG_ID_PIC_DECODED, vpu_session_handle_pic_decoded},
	{VPU_MSG_ID_DEC_DONE, vpu_session_handle_pic_done},
	{VPU_MSG_ID_PIC_EOS, vpu_session_handle_eos},
	{VPU_MSG_ID_UNSUPPORTED, vpu_session_handle_error},
	{VPU_MSG_ID_FIRMWARE_XCPT, vpu_session_handle_firmware_xcpt},
	{VPU_MSG_ID_PIC_SKIPPED, vpu_session_handle_pic_skipped},
};

static int vpu_session_handle_msg(struct vpu_inst *inst, struct vpu_rpc_event *msg)
{
	int ret;
	u32 msg_id;
	struct vpu_msg_handler *handler = NULL;
	unsigned int i;

	ret = vpu_iface_convert_msg_id(inst->core, msg->hdr.id);
	if (ret < 0)
		return -EINVAL;

	msg_id = ret;
	dev_dbg(inst->dev, "[%d] receive event(0x%x)\n", inst->id, msg_id);

	for (i = 0; i < ARRAY_SIZE(handlers); i++) {
		if (handlers[i].id == msg_id) {
			handler = &handlers[i];
			break;
		}
	}

	if (handler && handler->done)
		handler->done(inst, msg);

	vpu_response_cmd(inst, msg_id, 1);

	return 0;
}

static bool vpu_inst_receive_msg(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
{
	unsigned long bytes = sizeof(struct vpu_rpc_event_header);
	u32 ret;

	memset(pkt, 0, sizeof(*pkt));
	if (kfifo_len(&inst->msg_fifo) < bytes)
		return false;

	ret = kfifo_out(&inst->msg_fifo, pkt, bytes);
	if (ret != bytes)
		return false;

	if (pkt->hdr.num > 0) {
		bytes = pkt->hdr.num * sizeof(u32);
		ret = kfifo_out(&inst->msg_fifo, pkt->data, bytes);
		if (ret != bytes)
			return false;
	}

	return true;
}

void vpu_inst_run_work(struct work_struct *work)
{
	struct vpu_inst *inst = container_of(work, struct vpu_inst, msg_work);
	struct vpu_rpc_event pkt;

	while (vpu_inst_receive_msg(inst, &pkt))
		vpu_session_handle_msg(inst, &pkt);
}

static void vpu_inst_handle_msg(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
{
	unsigned long bytes;
	u32 id = pkt->hdr.id;
	int ret;

	if (!inst->workqueue)
		return;

	bytes = sizeof(pkt->hdr) + pkt->hdr.num * sizeof(u32);
	ret = kfifo_in(&inst->msg_fifo, pkt, bytes);
	if (ret != bytes)
		dev_err(inst->dev, "[%d:%d]overflow: %d\n", inst->core->id, inst->id, id);
	queue_work(inst->workqueue, &inst->msg_work);
}

static int vpu_handle_msg(struct vpu_core *core)
{
	struct vpu_rpc_event pkt;
	struct vpu_inst *inst;
	int ret;

	memset(&pkt, 0, sizeof(pkt));
	while (!vpu_iface_receive_msg(core, &pkt)) {
		dev_dbg(core->dev, "event index = %d, id = %d, num = %d\n",
			pkt.hdr.index, pkt.hdr.id, pkt.hdr.num);

		ret = vpu_iface_convert_msg_id(core, pkt.hdr.id);
		if (ret < 0)
			continue;

		inst = vpu_core_find_instance(core, pkt.hdr.index);
		if (inst) {
			vpu_response_cmd(inst, ret, 0);
			mutex_lock(&core->cmd_lock);
			vpu_inst_record_flow(inst, ret);
			mutex_unlock(&core->cmd_lock);

			vpu_inst_handle_msg(inst, &pkt);
			vpu_inst_put(inst);
		}
		memset(&pkt, 0, sizeof(pkt));
	}

	return 0;
}

static int vpu_isr_thread(struct vpu_core *core, u32 irq_code)
{
	dev_dbg(core->dev, "irq code = 0x%x\n", irq_code);
	switch (irq_code) {
	case VPU_IRQ_CODE_SYNC:
		vpu_mbox_send_msg(core, PRC_BUF_OFFSET, core->rpc.phys - core->fw.phys);
		vpu_mbox_send_msg(core, BOOT_ADDRESS, core->fw.phys);
		vpu_mbox_send_msg(core, INIT_DONE, 2);
		break;
	case VPU_IRQ_CODE_BOOT_DONE:
		break;
	case VPU_IRQ_CODE_SNAPSHOT_DONE:
		break;
	default:
		vpu_handle_msg(core);
		break;
	}

	return 0;
}

static void vpu_core_run_msg_work(struct vpu_core *core)
{
	const unsigned int SIZE = sizeof(u32);

	while (kfifo_len(&core->msg_fifo) >= SIZE) {
		u32 data = 0;

		if (kfifo_out(&core->msg_fifo, &data, SIZE) == SIZE)
			vpu_isr_thread(core, data);
	}
}

void vpu_msg_run_work(struct work_struct *work)
{
	struct vpu_core *core = container_of(work, struct vpu_core, msg_work);
	unsigned long delay = msecs_to_jiffies(10);

	vpu_core_run_msg_work(core);
	queue_delayed_work(core->workqueue, &core->msg_delayed_work, delay);
}

void vpu_msg_delayed_work(struct work_struct *work)
{
	struct vpu_core *core;
	struct delayed_work *dwork;
	unsigned long bytes = sizeof(u32);
	u32 i;

	if (!work)
		return;

	dwork = to_delayed_work(work);
	core = container_of(dwork, struct vpu_core, msg_delayed_work);
	if (kfifo_len(&core->msg_fifo) >= bytes)
		vpu_core_run_msg_work(core);

	bytes = sizeof(struct vpu_rpc_event_header);
	for (i = 0; i < core->supported_instance_count; i++) {
		struct vpu_inst *inst = vpu_core_find_instance(core, i);

		if (!inst)
			continue;

		if (inst->workqueue && kfifo_len(&inst->msg_fifo) >= bytes)
			queue_work(inst->workqueue, &inst->msg_work);

		vpu_inst_put(inst);
	}
}

int vpu_isr(struct vpu_core *core, u32 irq)
{
	switch (irq) {
	case VPU_IRQ_CODE_SYNC:
		break;
	case VPU_IRQ_CODE_BOOT_DONE:
		complete(&core->cmp);
		break;
	case VPU_IRQ_CODE_SNAPSHOT_DONE:
		complete(&core->cmp);
		break;
	default:
		break;
	}

	if (kfifo_in(&core->msg_fifo, &irq, sizeof(irq)) != sizeof(irq))
		dev_err(core->dev, "[%d]overflow: %d\n", core->id, irq);
	queue_work(core->workqueue, &core->msg_work);

	return 0;
}
