// 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 <linux/of_device.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include "vpu.h"
#include "vpu_mbox.h"
#include "vpu_msgs.h"

static void vpu_mbox_rx_callback(struct mbox_client *cl, void *msg)
{
	struct vpu_mbox *rx = container_of(cl, struct vpu_mbox, cl);
	struct vpu_core *core = container_of(rx, struct vpu_core, rx);

	vpu_isr(core, *(u32 *)msg);
}

static int vpu_mbox_request_channel(struct device *dev, struct vpu_mbox *mbox)
{
	struct mbox_chan *ch;
	struct mbox_client *cl;

	if (!dev || !mbox)
		return -EINVAL;
	if (mbox->ch)
		return 0;

	cl = &mbox->cl;
	cl->dev = dev;
	if (mbox->block) {
		cl->tx_block = true;
		cl->tx_tout = 1000;
	} else {
		cl->tx_block = false;
	}
	cl->knows_txdone = false;
	cl->rx_callback = vpu_mbox_rx_callback;

	ch = mbox_request_channel_byname(cl, mbox->name);
	if (IS_ERR(ch)) {
		dev_err(dev, "Failed to request mbox chan %s, ret : %ld\n",
			mbox->name, PTR_ERR(ch));
		return PTR_ERR(ch);
	}

	mbox->ch = ch;
	return 0;
}

int vpu_mbox_init(struct vpu_core *core)
{
	scnprintf(core->tx_type.name, sizeof(core->tx_type.name) - 1, "tx0");
	core->tx_type.block = true;

	scnprintf(core->tx_data.name, sizeof(core->tx_data.name) - 1, "tx1");
	core->tx_data.block = false;

	scnprintf(core->rx.name, sizeof(core->rx.name) - 1, "rx");
	core->rx.block = true;

	return 0;
}

int vpu_mbox_request(struct vpu_core *core)
{
	int ret;

	ret = vpu_mbox_request_channel(core->dev, &core->tx_type);
	if (ret)
		goto error;
	ret = vpu_mbox_request_channel(core->dev, &core->tx_data);
	if (ret)
		goto error;
	ret = vpu_mbox_request_channel(core->dev, &core->rx);
	if (ret)
		goto error;

	dev_dbg(core->dev, "%s request mbox\n", vpu_core_type_desc(core->type));
	return 0;
error:
	vpu_mbox_free(core);
	return ret;
}

void vpu_mbox_free(struct vpu_core *core)
{
	mbox_free_channel(core->tx_type.ch);
	mbox_free_channel(core->tx_data.ch);
	mbox_free_channel(core->rx.ch);
	core->tx_type.ch = NULL;
	core->tx_data.ch = NULL;
	core->rx.ch = NULL;
	dev_dbg(core->dev, "%s free mbox\n", vpu_core_type_desc(core->type));
}

void vpu_mbox_send_type(struct vpu_core *core, u32 type)
{
	mbox_send_message(core->tx_type.ch, &type);
}

void vpu_mbox_send_msg(struct vpu_core *core, u32 type, u32 data)
{
	mbox_send_message(core->tx_data.ch, &data);
	mbox_send_message(core->tx_type.ch, &type);
}

void vpu_mbox_enable_rx(struct vpu_dev *dev)
{
}
