// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2019 NXP
 *
 */

#include <common.h>
#include <asm/io.h>
#include <dm.h>
#include <dm/lists.h>
#include <dm/root.h>
#include <dm/device-internal.h>
#include <dm/uclass-internal.h>
#include <misc.h>
#include <asm/mach-imx/imx_vservice.h>
#include <imx_m4_mu.h>

static LIST_HEAD(vservice_channels);

void * __weak board_imx_vservice_get_buffer(struct imx_vservice_channel *node, u32 size)
{
	if (size <= CONFIG_IMX_VSERVICE_SHARED_BUFFER_SIZE)
		return (void * )CONFIG_IMX_VSERVICE_SHARED_BUFFER;

	return NULL;
}

void * imx_vservice_get_buffer(struct imx_vservice_channel *node, u32 size)
{
	return board_imx_vservice_get_buffer(node, size);
}

int imx_vservice_blocking_request(struct imx_vservice_channel *node, u8 *buf, u32* size)
{
	int ret = 0;
	union imx_m4_msg msg;

	msg.format.seq = node->msg_seq;
	msg.format.type = MU_MSG_REQ;
	msg.format.buffer = (u32)(ulong)buf;
	msg.format.size = *size;

	ret = misc_call(node->mu_dev, 1000000, &msg, 4, &msg, 4);
	if (ret) {
		printf("%s: Send request MU message failed, ret %d\n", __func__, ret);
		goto MU_ERR;
	}

	if (msg.format.type != MU_MSG_RESP|| msg.format.seq != node->msg_seq) {
		printf("%s: wrong msg response: type %d, seq %d, expect seq %d\n",
			__func__, msg.format.type, msg.format.seq, node->msg_seq);
		ret = -EIO;
		goto MU_ERR;
	}

	*size = msg.format.size;

MU_ERR:
	node->msg_seq++;

	return ret;
}

static int imx_vservice_connect(struct imx_vservice_channel *node)
{
	int ret = 0;
	union imx_m4_msg msg;

	unsigned long timeout = timer_get_us() + 2000000; /* 2s timeout */

	for (;;) {
		msg.format.seq = 0;
		msg.format.type = MU_MSG_READY_A;
		msg.format.buffer = 0;
		msg.format.size = 0;

		ret = misc_call(node->mu_dev, 100000, &msg, 4, &msg, 4);
		if (!ret && msg.format.type == MU_MSG_READY_B)
			return 0;

		if (time_after(timer_get_us(), timeout)) {
			printf("%s: Timeout to connect peer, %d\n", __func__, ret);
			return -ETIMEDOUT;
		}
	}

	return -EIO;
}

struct udevice * __weak board_imx_vservice_find_mu(struct udevice *virt_dev)
{
	int ret;
	struct ofnode_phandle_args args;
	struct udevice *mu_dev;

	/* Default get mu from "fsl,vservice-mu" property*/
	ret = dev_read_phandle_with_args(virt_dev, "fsl,vservice-mu",
					 NULL, 0, 0, &args);
	if (ret) {
		printf("Can't find \"fsl,vservice-mu\" property\n");
		return NULL;
	}

	ret = uclass_find_device_by_ofnode(UCLASS_MISC, args.node, &mu_dev);
	if (ret) {
		printf("Can't find MU device, err %d\n", ret);
		return NULL;
	}

	return mu_dev;
}

static struct udevice * imx_vservice_find_mu(struct udevice *virt_dev)
{
	return board_imx_vservice_find_mu(virt_dev);
}

struct imx_vservice_channel * imx_vservice_setup(struct udevice *virt_dev)
{
	int ret;
	 struct udevice *mu_dev;
	 struct imx_vservice_channel *channel;

	mu_dev = imx_vservice_find_mu(virt_dev);
	if (mu_dev == NULL) {
		printf("No MU device for virtual service %s connection\n", virt_dev->name);
		return NULL;
	}

	ret = device_probe(mu_dev);
	if (ret) {
		printf("Probe MU device failed\n");
		return NULL;
	}

	list_for_each_entry(channel, &vservice_channels, channel_head) {
		if (channel->mu_dev == mu_dev)
			return channel;
	}

	channel = malloc(sizeof(struct imx_vservice_channel));
	if (!channel) {
		printf("Malloc vservice channel is failed\n");
		return NULL;
	}

	channel->msg_seq = 0;
	channel->mu_dev = mu_dev;
	INIT_LIST_HEAD(&channel->channel_head);

	ret = imx_vservice_connect(channel);
	if (ret) {
		printf("VService: Connection is failed, ret %d\n", ret);
		free(channel);
		return NULL;
	}

	list_add_tail(&channel->channel_head, &vservice_channels);

	printf("VService: Connection is ok on MU %s\n", mu_dev->name);

	return channel;
}
