// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
 * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
 */

#include <linux/err.h>
#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/printk.h>
#include <linux/mailbox_client.h>
#include <linux/amlogic/scpi_protocol.h>
#include <linux/slab.h>
#include "meson_mhu_dsp.h"

#define CMD_TAG			(2 << 25)

struct scpi_data_buf {
	int client_id;
	struct mhu_data_buf *data;
	struct completion complete;
};

enum scpi_error_codes {
	SCPI_SUCCESS = 0, /* Success */
	SCPI_ERR_PARAM = 1, /* Invalid parameter(s) */
	SCPI_ERR_ALIGN = 2, /* Invalid alignment */
	SCPI_ERR_SIZE = 3, /* Invalid size */
	SCPI_ERR_HANDLER = 4, /* Invalid handler/callback */
	SCPI_ERR_ACCESS = 5, /* Invalid access/permission denied */
	SCPI_ERR_RANGE = 6, /* Value out of range */
	SCPI_ERR_TIMEOUT = 7, /* Timeout has occurred */
	SCPI_ERR_NOMEM = 8, /* Invalid memory area or pointer */
	SCPI_ERR_PWRSTATE = 9, /* Invalid power state */
	SCPI_ERR_SUPPORT = 10, /* Not supported or disabled */
	SCPI_ERR_DEVICE = 11, /* Device error */
	SCPI_ERR_MAX
};

static int scpi_linux_errmap[SCPI_ERR_MAX] = {
	0, -EINVAL, -ENOEXEC, -EMSGSIZE,
	-EINVAL, -EACCES, -ERANGE, -ETIMEDOUT,
	-ENOMEM, -EINVAL, -EOPNOTSUPP, -EIO,
};

static inline int scpi_to_linux_errno(int errno)
{
	if (errno >= SCPI_SUCCESS && errno < SCPI_ERR_MAX)
		return scpi_linux_errmap[errno];
	return -EIO;
}

static void scpi_rx_callback(struct mbox_client *cl, void *msg)
{
	struct mhu_data_buf *data = (struct mhu_data_buf *)msg;
	struct scpi_data_buf *scpi_buf = data->cl_data;

	complete(&scpi_buf->complete);
}

static int send_scpi_cmd(struct scpi_data_buf *scpi_buf, int client_id)
{
	struct mbox_chan *chan;
	struct mbox_client cl = {0};
	struct mhu_data_buf *data = scpi_buf->data;
	u32 status;

	cl.dev = dsp_scpi_device;
	cl.rx_callback = scpi_rx_callback;
	pr_debug("dsp %p\n", dsp_scpi_device);
	chan = mbox_request_channel(&cl, client_id);
	if (IS_ERR(chan))
		return PTR_ERR(chan);

	init_completion(&scpi_buf->complete);
	if (mbox_send_message(chan, (void *)data) < 0) {
		status = SCPI_ERR_TIMEOUT;
		goto free_channel;
	}

	wait_for_completion(&scpi_buf->complete);
	status = *(u32 *)(data->rx_buf); /* read first word */

free_channel:
	mbox_free_channel(chan);

	return scpi_to_linux_errno(status);
}

#define SCPI_SETUP_DBUF_SIZE(scpi_buf, mhu_buf, _client_id,\
			_cmd, _tx_buf, _tx_size, _rx_buf, _rx_size) \
do {						\
	struct mhu_data_buf *pdata = &(mhu_buf);\
	pdata->cmd = _cmd;			\
	pdata->tx_buf = _tx_buf;		\
	pdata->tx_size = _tx_size;		\
	pdata->rx_buf = _rx_buf;		\
	pdata->rx_size = _rx_size;		\
	scpi_buf.client_id = _client_id;	\
	scpi_buf.data = pdata;			\
} while (0)

static int scpi_execute_cmd(struct scpi_data_buf *scpi_buf)
{
	struct mhu_data_buf *data;

	if (!scpi_buf || !scpi_buf->data)
		return -EINVAL;
	data = scpi_buf->data;
	data->cmd = (data->cmd & 0xffff)
		    | (data->tx_size & 0x1ff) << 16
		    | CMD_TAG; //Sync Flag
	data->cl_data = scpi_buf;

	return send_scpi_cmd(scpi_buf, scpi_buf->client_id);
}

int scpi_send_dsp_data(void *data, int size, bool to_dspa)
{
	struct scpi_data_buf sdata;
	struct mhu_data_buf mdata;
	int client_id = 0;

	struct __packed {
		u32 status;
	} buf;

	if (!to_dspa)
		client_id = 3;
	else
		client_id = 1;

	SCPI_SETUP_DBUF_SIZE(sdata, mdata, client_id,
			     SCPI_CMD_SEND_DSP_DATA, data,
			     size, &buf, sizeof(buf));
	if (scpi_execute_cmd(&sdata))
		return -EPERM;
	return buf.status;
}
EXPORT_SYMBOL_GPL(scpi_send_dsp_data);

int scpi_send_dsp_cmd(void *data, int size, bool to_dspa,
		      int cmd, int taskid)
{
	struct scpi_data_buf sdata;
	struct mhu_data_buf mdata;
	int client_id = 0;

	struct __packed {
		u32 status;
	} buf;

	struct txbuf {
		u64 taskid;
		char data[240];
	} txbuf;

	if (!to_dspa)
		client_id = 3;
	else
		client_id = 1;

	txbuf.taskid = taskid;
	memcpy(txbuf.data, data, size);

	SCPI_SETUP_DBUF_SIZE(sdata, mdata, client_id,
			     cmd, (void *)&txbuf,
			     sizeof(txbuf), &buf, sizeof(buf));
	if (scpi_execute_cmd(&sdata))
		return -EPERM;
	return buf.status;
}
EXPORT_SYMBOL_GPL(scpi_send_dsp_cmd);

int scpi_req_handle(void *p, u32 size, u32 cmd, int idx)
{
	int ret = 0;
	unsigned int dspid = 0;
	struct hifi4syslog *phifilogbuf = NULL;

	if (BIT(idx) & 0xc)
		dspid = 1;
	else if (BIT(idx) & 0x3)
		dspid = 0;
	else
		dspid = 0;

	switch (cmd) {
	case SCPI_REQ_INVALID:
		break;
	case SCPI_CMD_HIFI4SYSTLOG:
		phifilogbuf = (struct hifi4syslog *)p;
		strcpy(hifi4logbuffer[dspid].syslogstate,
		       phifilogbuf->syslogstate);
		hifi4logbuffer[dspid].logbaseaddr = phifilogbuf->logbaseaddr;
		hifi4logbuffer[dspid].syslogsize = phifilogbuf->syslogsize;
		hifi4logbuffer[dspid].loghead = phifilogbuf->loghead;
		hifi4logbuffer[dspid].logtail = phifilogbuf->logtail;
		ret = 1;
		break;
	case SCPI_CMD_HIFI4STOP:
		ret = 1;
		break;
	default:
		break;
	}
	return ret;
}
