// 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;

	memcpy(msg.name, name, sizeof(msg.name));
	msg.name[sizeof(msg.name) - 1] = 0;

	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++;
	if (ctx->ipc_buf) {
		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);
}
