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

#include <linux/rpmsg.h>

#include "delta.h"
#include "delta-ipc.h"
#include "delta-mem.h"

#define IPC_TIMEOUT 100
#define IPC_SANITY_TAG 0xDEADBEEF

enum delta_ipc_fw_command {
	DELTA_IPC_OPEN,
	DELTA_IPC_SET_STREAM,
	DELTA_IPC_DECODE,
	DELTA_IPC_CLOSE
};

#define to_rpmsg_driver(__drv) container_of(__drv, struct rpmsg_driver, drv)
#define to_delta(__d) container_of(__d, struct delta_dev, rpmsg_driver)

#define to_ctx(hdl) ((struct delta_ipc_ctx *)hdl)
#define to_pctx(ctx) container_of(ctx, struct delta_ctx, ipc_ctx)

struct delta_ipc_header_msg {
	u32 tag;
	void *host_hdl;
	u32 copro_hdl;
	u32 command;
};

#define to_host_hdl(ctx) ((void *)ctx)

#define msg_to_ctx(msg) ((struct delta_ipc_ctx *)(msg)->header.host_hdl)
#define msg_to_copro_hdl(msg) ((msg)->header.copro_hdl)

static inline dma_addr_t to_paddr(struct delta_ipc_ctx *ctx, void *vaddr)
{
	return (ctx->ipc_buf->paddr + (vaddr - ctx->ipc_buf->vaddr));
}

static inline bool is_valid_data(struct delta_ipc_ctx *ctx,
				 void *data, u32 size)
{
	return ((data >= ctx->ipc_buf->vaddr) &&
		((data + size) <= (ctx->ipc_buf->vaddr + ctx->ipc_buf->size)));
}

/*
 * IPC shared memory (@ipc_buf_size, @ipc_buf_paddr) is sent to copro
 * at each instance opening. This memory is allocated by IPC client
 * and given through delta_ipc_open(). All messages parameters
 * (open, set_stream, decode) will have their phy address within
 * this IPC shared memory, avoiding de-facto recopies inside delta-ipc.
 * All the below messages structures are used on both host and firmware
 * side and are packed (use only of 32 bits size fields in messages
 * structures to ensure packing):
 * - struct delta_ipc_open_msg
 * - struct delta_ipc_set_stream_msg
 * - struct delta_ipc_decode_msg
 * - struct delta_ipc_close_msg
 * - struct delta_ipc_cb_msg
 */
struct delta_ipc_open_msg {
	struct delta_ipc_header_msg header;
	u32 ipc_buf_size;
	dma_addr_t ipc_buf_paddr;
	char name[32];
	u32 param_size;
	dma_addr_t param_paddr;
};

struct delta_ipc_set_stream_msg {
	struct delta_ipc_header_msg header;
	u32 param_size;
	dma_addr_t param_paddr;
};

struct delta_ipc_decode_msg {
	struct delta_ipc_header_msg header;
	u32 param_size;
	dma_addr_t param_paddr;
	u32 status_size;
	dma_addr_t status_paddr;
};

struct delta_ipc_close_msg {
	struct delta_ipc_header_msg header;
};

struct delta_ipc_cb_msg {
	struct delta_ipc_header_msg header;
	int err;
};

static void build_msg_header(struct delta_ipc_ctx *ctx,
			     enum delta_ipc_fw_command command,
			     struct delta_ipc_header_msg *header)
{
	header->tag = IPC_SANITY_TAG;
	header->host_hdl = to_host_hdl(ctx);
	header->copro_hdl = ctx->copro_hdl;
	header->command = command;
}

int delta_ipc_open(struct delta_ctx *pctx, const char *name,
		   struct delta_ipc_param *param, u32 ipc_buf_size,
		   struct delta_buf **ipc_buf, void **hdl)
{
	struct delta_dev *delta = pctx->dev;
	struct rpmsg_device *rpmsg_device = delta->rpmsg_device;
	struct delta_ipc_ctx *ctx = &pctx->ipc_ctx;
	struct delta_ipc_open_msg msg;
	struct delta_buf *buf = &ctx->ipc_buf_struct;
	int ret;

	if (!rpmsg_device) {
		dev_err(delta->dev,
			"%s   ipc: failed to open, rpmsg is not initialized\n",
			pctx->name);
		pctx->sys_errors++;
		return -EINVAL;
	}

	if (!name) {
		dev_err(delta->dev,
			"%s   ipc: failed to open, no name given\n",
			pctx->name);
		return -EINVAL;
	}

	if (!param || !param->data || !param->size) {
		dev_err(delta->dev,
			"%s  ipc: failed to open, empty parameter\n",
			pctx->name);
		return -EINVAL;
	}

	if (!ipc_buf_size) {
		dev_err(delta->dev,
			"%s   ipc: failed to open, no size given for ipc buffer\n",
			pctx->name);
		return -EINVAL;
	}

	if (param->size > ipc_buf_size) {
		dev_err(delta->dev,
			"%s   ipc: failed to open, too large ipc parameter (%d bytes while max %d expected)\n",
			pctx->name,
			param->size, ctx->ipc_buf->size);
		return -EINVAL;
	}

	/* init */
	init_completion(&ctx->done);

	/*
	 * allocation of contiguous buffer for
	 * data of commands exchanged between
	 * host and firmware coprocessor
	 */
	ret = hw_alloc(pctx, ipc_buf_size,
		       "ipc data buffer", buf);
	if (ret)
		return ret;
	ctx->ipc_buf = buf;

	/* build rpmsg message */
	build_msg_header(ctx, DELTA_IPC_OPEN, &msg.header);

	msg.ipc_buf_size = ipc_buf_size;
	msg.ipc_buf_paddr = ctx->ipc_buf->paddr;

	strscpy(msg.name, name, sizeof(msg.name));

	msg.param_size = param->size;
	memcpy(ctx->ipc_buf->vaddr, param->data, msg.param_size);
	msg.param_paddr = ctx->ipc_buf->paddr;

	/* send it */
	ret = rpmsg_send(rpmsg_device->ept, &msg, sizeof(msg));
	if (ret) {
		dev_err(delta->dev,
			"%s   ipc: failed to open, rpmsg_send failed (%d) for DELTA_IPC_OPEN (name=%s, size=%d, data=%p)\n",
			pctx->name,
			ret, name, param->size, param->data);
		goto err;
	}

	/* wait for acknowledge */
	if (!wait_for_completion_timeout
	    (&ctx->done, msecs_to_jiffies(IPC_TIMEOUT))) {
		dev_err(delta->dev,
			"%s   ipc: failed to open, timeout waiting for DELTA_IPC_OPEN callback (name=%s, size=%d, data=%p)\n",
			pctx->name,
			name, param->size, param->data);
		ret = -ETIMEDOUT;
		goto err;
	}

	/* command completed, check error */
	if (ctx->cb_err) {
		dev_err(delta->dev,
			"%s   ipc: failed to open, DELTA_IPC_OPEN completed but with error (%d) (name=%s, size=%d, data=%p)\n",
			pctx->name,
			ctx->cb_err, name, param->size, param->data);
		ret = -EIO;
		goto err;
	}

	*ipc_buf = ctx->ipc_buf;
	*hdl = (void *)ctx;

	return 0;

err:
	pctx->sys_errors++;
	hw_free(pctx, ctx->ipc_buf);
	ctx->ipc_buf = NULL;

	return ret;
};

int delta_ipc_set_stream(void *hdl, struct delta_ipc_param *param)
{
	struct delta_ipc_ctx *ctx = to_ctx(hdl);
	struct delta_ctx *pctx = to_pctx(ctx);
	struct delta_dev *delta = pctx->dev;
	struct rpmsg_device *rpmsg_device = delta->rpmsg_device;
	struct delta_ipc_set_stream_msg msg;
	int ret;

	if (!hdl) {
		dev_err(delta->dev,
			"%s   ipc: failed to set stream, invalid ipc handle\n",
			pctx->name);
		return -EINVAL;
	}

	if (!rpmsg_device) {
		dev_err(delta->dev,
			"%s   ipc: failed to set stream, rpmsg is not initialized\n",
			pctx->name);
		return -EINVAL;
	}

	if (!param || !param->data || !param->size) {
		dev_err(delta->dev,
			"%s  ipc: failed to set stream, empty parameter\n",
			pctx->name);
		return -EINVAL;
	}

	if (param->size > ctx->ipc_buf->size) {
		dev_err(delta->dev,
			"%s   ipc: failed to set stream, too large ipc parameter(%d bytes while max %d expected)\n",
			pctx->name,
			param->size, ctx->ipc_buf->size);
		return -EINVAL;
	}

	if (!is_valid_data(ctx, param->data, param->size)) {
		dev_err(delta->dev,
			"%s   ipc: failed to set stream, parameter is not in expected address range (size=%d, data=%p not in %p..%p)\n",
			pctx->name,
			param->size,
			param->data,
			ctx->ipc_buf->vaddr,
			ctx->ipc_buf->vaddr + ctx->ipc_buf->size - 1);
		return -EINVAL;
	}

	/* build rpmsg message */
	build_msg_header(ctx, DELTA_IPC_SET_STREAM, &msg.header);

	msg.param_size = param->size;
	msg.param_paddr = to_paddr(ctx, param->data);

	/* send it */
	ret = rpmsg_send(rpmsg_device->ept, &msg, sizeof(msg));
	if (ret) {
		dev_err(delta->dev,
			"%s   ipc: failed to set stream, rpmsg_send failed (%d) for DELTA_IPC_SET_STREAM (size=%d, data=%p)\n",
			pctx->name,
			ret, param->size, param->data);
		pctx->sys_errors++;
		return ret;
	}

	/* wait for acknowledge */
	if (!wait_for_completion_timeout
	    (&ctx->done, msecs_to_jiffies(IPC_TIMEOUT))) {
		dev_err(delta->dev,
			"%s   ipc: failed to set stream, timeout waiting for DELTA_IPC_SET_STREAM callback (size=%d, data=%p)\n",
			pctx->name,
			param->size, param->data);
		pctx->sys_errors++;
		return -ETIMEDOUT;
	}

	/* command completed, check status */
	if (ctx->cb_err) {
		dev_err(delta->dev,
			"%s   ipc: failed to set stream, DELTA_IPC_SET_STREAM completed but with error (%d) (size=%d, data=%p)\n",
			pctx->name,
			ctx->cb_err, param->size, param->data);
		pctx->sys_errors++;
		return -EIO;
	}

	return 0;
}

int delta_ipc_decode(void *hdl, struct delta_ipc_param *param,
		     struct delta_ipc_param *status)
{
	struct delta_ipc_ctx *ctx = to_ctx(hdl);
	struct delta_ctx *pctx = to_pctx(ctx);
	struct delta_dev *delta = pctx->dev;
	struct rpmsg_device *rpmsg_device = delta->rpmsg_device;
	struct delta_ipc_decode_msg msg;
	int ret;

	if (!hdl) {
		dev_err(delta->dev,
			"%s   ipc: failed to decode, invalid ipc handle\n",
			pctx->name);
		return -EINVAL;
	}

	if (!rpmsg_device) {
		dev_err(delta->dev,
			"%s   ipc: failed to decode, rpmsg is not initialized\n",
			pctx->name);
		return -EINVAL;
	}

	if (!param || !param->data || !param->size) {
		dev_err(delta->dev,
			"%s  ipc: failed to decode, empty parameter\n",
			pctx->name);
		return -EINVAL;
	}

	if (!status || !status->data || !status->size) {
		dev_err(delta->dev,
			"%s  ipc: failed to decode, empty status\n",
			pctx->name);
		return -EINVAL;
	}

	if (param->size + status->size > ctx->ipc_buf->size) {
		dev_err(delta->dev,
			"%s   ipc: failed to decode, too large ipc parameter (%d bytes (param) + %d bytes (status) while max %d expected)\n",
			pctx->name,
			param->size,
			status->size,
			ctx->ipc_buf->size);
		return -EINVAL;
	}

	if (!is_valid_data(ctx, param->data, param->size)) {
		dev_err(delta->dev,
			"%s   ipc: failed to decode, parameter is not in expected address range (size=%d, data=%p not in %p..%p)\n",
			pctx->name,
			param->size,
			param->data,
			ctx->ipc_buf->vaddr,
			ctx->ipc_buf->vaddr + ctx->ipc_buf->size - 1);
		return -EINVAL;
	}

	if (!is_valid_data(ctx, status->data, status->size)) {
		dev_err(delta->dev,
			"%s   ipc: failed to decode, status is not in expected address range (size=%d, data=%p not in %p..%p)\n",
			pctx->name,
			status->size,
			status->data,
			ctx->ipc_buf->vaddr,
			ctx->ipc_buf->vaddr + ctx->ipc_buf->size - 1);
		return -EINVAL;
	}

	/* build rpmsg message */
	build_msg_header(ctx, DELTA_IPC_DECODE, &msg.header);

	msg.param_size = param->size;
	msg.param_paddr = to_paddr(ctx, param->data);

	msg.status_size = status->size;
	msg.status_paddr = to_paddr(ctx, status->data);

	/* send it */
	ret = rpmsg_send(rpmsg_device->ept, &msg, sizeof(msg));
	if (ret) {
		dev_err(delta->dev,
			"%s   ipc: failed to decode, rpmsg_send failed (%d) for DELTA_IPC_DECODE (size=%d, data=%p)\n",
			pctx->name,
			ret, param->size, param->data);
		pctx->sys_errors++;
		return ret;
	}

	/* wait for acknowledge */
	if (!wait_for_completion_timeout
	    (&ctx->done, msecs_to_jiffies(IPC_TIMEOUT))) {
		dev_err(delta->dev,
			"%s   ipc: failed to decode, timeout waiting for DELTA_IPC_DECODE callback (size=%d, data=%p)\n",
			pctx->name,
			param->size, param->data);
		pctx->sys_errors++;
		return -ETIMEDOUT;
	}

	/* command completed, check status */
	if (ctx->cb_err) {
		dev_err(delta->dev,
			"%s   ipc: failed to decode, DELTA_IPC_DECODE completed but with error (%d) (size=%d, data=%p)\n",
			pctx->name,
			ctx->cb_err, param->size, param->data);
		pctx->sys_errors++;
		return -EIO;
	}

	return 0;
};

void delta_ipc_close(void *hdl)
{
	struct delta_ipc_ctx *ctx = to_ctx(hdl);
	struct delta_ctx *pctx = to_pctx(ctx);
	struct delta_dev *delta = pctx->dev;
	struct rpmsg_device *rpmsg_device = delta->rpmsg_device;
	struct delta_ipc_close_msg msg;
	int ret;

	if (!hdl) {
		dev_err(delta->dev,
			"%s   ipc: failed to close, invalid ipc handle\n",
			pctx->name);
		return;
	}

	if (ctx->ipc_buf) {
		hw_free(pctx, ctx->ipc_buf);
		ctx->ipc_buf = NULL;
	}

	if (!rpmsg_device) {
		dev_err(delta->dev,
			"%s   ipc: failed to close, rpmsg is not initialized\n",
			pctx->name);
		return;
	}

	/* build rpmsg message */
	build_msg_header(ctx, DELTA_IPC_CLOSE, &msg.header);

	/* send it */
	ret = rpmsg_send(rpmsg_device->ept, &msg, sizeof(msg));
	if (ret) {
		dev_err(delta->dev,
			"%s   ipc: failed to close, rpmsg_send failed (%d) for DELTA_IPC_CLOSE\n",
			pctx->name, ret);
		pctx->sys_errors++;
		return;
	}

	/* wait for acknowledge */
	if (!wait_for_completion_timeout
	    (&ctx->done, msecs_to_jiffies(IPC_TIMEOUT))) {
		dev_err(delta->dev,
			"%s   ipc: failed to close, timeout waiting for DELTA_IPC_CLOSE callback\n",
			pctx->name);
		pctx->sys_errors++;
		return;
	}

	/* command completed, check status */
	if (ctx->cb_err) {
		dev_err(delta->dev,
			"%s   ipc: failed to close, DELTA_IPC_CLOSE completed but with error (%d)\n",
			pctx->name, ctx->cb_err);
		pctx->sys_errors++;
	}
};

static int delta_ipc_cb(struct rpmsg_device *rpdev, void *data,
			int len, void *priv, u32 src)
{
	struct delta_ipc_ctx *ctx;
	struct delta_ipc_cb_msg *msg;

	/* sanity check */
	if (!rpdev) {
		dev_err(NULL, "rpdev is NULL\n");
		return -EINVAL;
	}

	if (!data || !len) {
		dev_err(&rpdev->dev,
			"unexpected empty message received from src=%d\n", src);
		return -EINVAL;
	}

	if (len != sizeof(*msg)) {
		dev_err(&rpdev->dev,
			"unexpected message length received from src=%d (received %d bytes while %zu bytes expected)\n",
			len, src, sizeof(*msg));
		return -EINVAL;
	}

	msg = (struct delta_ipc_cb_msg *)data;
	if (msg->header.tag != IPC_SANITY_TAG) {
		dev_err(&rpdev->dev,
			"unexpected message tag received from src=%d (received %x tag while %x expected)\n",
			src, msg->header.tag, IPC_SANITY_TAG);
		return -EINVAL;
	}

	ctx = msg_to_ctx(msg);
	if (!ctx) {
		dev_err(&rpdev->dev,
			"unexpected message with NULL host_hdl received from src=%d\n",
			src);
		return -EINVAL;
	}

	/*
	 * if not already known, save copro instance context
	 * to ensure re-entrance on copro side
	 */
	if (!ctx->copro_hdl)
		ctx->copro_hdl = msg_to_copro_hdl(msg);

	/*
	 * all is fine,
	 * update status & complete command
	 */
	ctx->cb_err = msg->err;
	complete(&ctx->done);

	return 0;
}

static int delta_ipc_probe(struct rpmsg_device *rpmsg_device)
{
	struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpmsg_device->dev.driver);
	struct delta_dev *delta = to_delta(rpdrv);

	delta->rpmsg_device = rpmsg_device;

	return 0;
}

static void delta_ipc_remove(struct rpmsg_device *rpmsg_device)
{
	struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpmsg_device->dev.driver);
	struct delta_dev *delta = to_delta(rpdrv);

	delta->rpmsg_device = NULL;
}

static struct rpmsg_device_id delta_ipc_device_id_table[] = {
	{.name = "rpmsg-delta"},
	{},
};

static struct rpmsg_driver delta_rpmsg_driver = {
	.drv = {.name = KBUILD_MODNAME},
	.id_table = delta_ipc_device_id_table,
	.probe = delta_ipc_probe,
	.callback = delta_ipc_cb,
	.remove = delta_ipc_remove,
};

int delta_ipc_init(struct delta_dev *delta)
{
	delta->rpmsg_driver = delta_rpmsg_driver;

	return register_rpmsg_driver(&delta->rpmsg_driver);
}

void delta_ipc_exit(struct delta_dev *delta)
{
	unregister_rpmsg_driver(&delta->rpmsg_driver);
}
