// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2020, Linaro Limited
 */

#include <common.h>
#include <dm.h>
#include <malloc.h>
#include <scmi_agent.h>
#include <scmi_agent-uclass.h>
#include <scmi_protocols.h>
#include <asm/io.h>
#include <asm/scmi_test.h>
#include <dm/device_compat.h>

/*
 * The sandbox SCMI agent driver simulates to some extend a SCMI message
 * processing. It simulates few of the SCMI services for some of the
 * SCMI protocols embedded in U-Boot. Currently:
 * - SCMI clock protocol: emulate 2 agents each exposing few clocks
 * - SCMI reset protocol: emulate 1 agents each exposing a reset
 *
 * Agent #0 simulates 2 clocks and 1 reset domain.
 * See IDs in scmi0_clk[]/scmi0_reset[] and "sandbox-scmi-agent@0" in test.dts.
 *
 * Agent #1 simulates 1 clock.
 * See IDs in scmi1_clk[] and "sandbox-scmi-agent@1" in test.dts.
 *
 * All clocks are default disabled and reset levels down.
 *
 * This Driver exports sandbox_scmi_service_ct() for the test sequence to
 * get the state of the simulated services (clock state, rate, ...) and
 * check back-end device state reflects the request send through the
 * various uclass devices, as clocks and reset controllers.
 */

#define SANDBOX_SCMI_AGENT_COUNT	2

static struct sandbox_scmi_clk scmi0_clk[] = {
	{ .id = 7, .rate = 1000 },
	{ .id = 3, .rate = 333 },
};

static struct sandbox_scmi_reset scmi0_reset[] = {
	{ .id = 3 },
};

static struct sandbox_scmi_clk scmi1_clk[] = {
	{ .id = 1, .rate = 44 },
};

/* The list saves to simulted end devices references for test purpose */
struct sandbox_scmi_agent *sandbox_scmi_agent_list[SANDBOX_SCMI_AGENT_COUNT];

static struct sandbox_scmi_service sandbox_scmi_service_state = {
	.agent = sandbox_scmi_agent_list,
	.agent_count = SANDBOX_SCMI_AGENT_COUNT,
};

struct sandbox_scmi_service *sandbox_scmi_service_ctx(void)
{
	return &sandbox_scmi_service_state;
}

static void debug_print_agent_state(struct udevice *dev, char *str)
{
	struct sandbox_scmi_agent *agent = dev_get_priv(dev);

	dev_dbg(dev, "Dump sandbox_scmi_agent %u: %s\n", agent->idx, str);
	dev_dbg(dev, " scmi%u_clk   (%zu): %d/%ld, %d/%ld, %d/%ld, ...\n",
		agent->idx,
		agent->clk_count,
		agent->clk_count ? agent->clk[0].enabled : -1,
		agent->clk_count ? agent->clk[0].rate : -1,
		agent->clk_count > 1 ? agent->clk[1].enabled : -1,
		agent->clk_count > 1 ? agent->clk[1].rate : -1,
		agent->clk_count > 2 ? agent->clk[2].enabled : -1,
		agent->clk_count > 2 ? agent->clk[2].rate : -1);
	dev_dbg(dev, " scmi%u_reset (%zu): %d, %d, ...\n",
		agent->idx,
		agent->reset_count,
		agent->reset_count ? agent->reset[0].asserted : -1,
		agent->reset_count > 1 ? agent->reset[1].asserted : -1);
};

static struct sandbox_scmi_clk *get_scmi_clk_state(uint agent_id, uint clock_id)
{
	struct sandbox_scmi_clk *target = NULL;
	size_t target_count = 0;
	size_t n;

	switch (agent_id) {
	case 0:
		target = scmi0_clk;
		target_count = ARRAY_SIZE(scmi0_clk);
		break;
	case 1:
		target = scmi1_clk;
		target_count = ARRAY_SIZE(scmi1_clk);
		break;
	default:
		return NULL;
	}

	for (n = 0; n < target_count; n++)
		if (target[n].id == clock_id)
			return target + n;

	return NULL;
}

static struct sandbox_scmi_reset *get_scmi_reset_state(uint agent_id,
						       uint reset_id)
{
	size_t n;

	if (agent_id == 0) {
		for (n = 0; n < ARRAY_SIZE(scmi0_reset); n++)
			if (scmi0_reset[n].id == reset_id)
				return scmi0_reset + n;
	}

	return NULL;
}

/*
 * Sandbox SCMI agent ops
 */

static int sandbox_scmi_clock_rate_set(struct udevice *dev,
				       struct scmi_msg *msg)
{
	struct sandbox_scmi_agent *agent = dev_get_priv(dev);
	struct scmi_clk_rate_set_in *in = NULL;
	struct scmi_clk_rate_set_out *out = NULL;
	struct sandbox_scmi_clk *clk_state = NULL;

	if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
	    !msg->out_msg || msg->out_msg_sz < sizeof(*out))
		return -EINVAL;

	in = (struct scmi_clk_rate_set_in *)msg->in_msg;
	out = (struct scmi_clk_rate_set_out *)msg->out_msg;

	clk_state = get_scmi_clk_state(agent->idx, in->clock_id);
	if (!clk_state) {
		dev_err(dev, "Unexpected clock ID %u\n", in->clock_id);

		out->status = SCMI_NOT_FOUND;
	} else {
		u64 rate = ((u64)in->rate_msb << 32) + in->rate_lsb;

		clk_state->rate = (ulong)rate;

		out->status = SCMI_SUCCESS;
	}

	return 0;
}

static int sandbox_scmi_clock_rate_get(struct udevice *dev,
				       struct scmi_msg *msg)
{
	struct sandbox_scmi_agent *agent = dev_get_priv(dev);
	struct scmi_clk_rate_get_in *in = NULL;
	struct scmi_clk_rate_get_out *out = NULL;
	struct sandbox_scmi_clk *clk_state = NULL;

	if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
	    !msg->out_msg || msg->out_msg_sz < sizeof(*out))
		return -EINVAL;

	in = (struct scmi_clk_rate_get_in *)msg->in_msg;
	out = (struct scmi_clk_rate_get_out *)msg->out_msg;

	clk_state = get_scmi_clk_state(agent->idx, in->clock_id);
	if (!clk_state) {
		dev_err(dev, "Unexpected clock ID %u\n", in->clock_id);

		out->status = SCMI_NOT_FOUND;
	} else {
		out->rate_msb = (u32)((u64)clk_state->rate >> 32);
		out->rate_lsb = (u32)clk_state->rate;

		out->status = SCMI_SUCCESS;
	}

	return 0;
}

static int sandbox_scmi_clock_gate(struct udevice *dev, struct scmi_msg *msg)
{
	struct sandbox_scmi_agent *agent = dev_get_priv(dev);
	struct scmi_clk_state_in *in = NULL;
	struct scmi_clk_state_out *out = NULL;
	struct sandbox_scmi_clk *clk_state = NULL;

	if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
	    !msg->out_msg || msg->out_msg_sz < sizeof(*out))
		return -EINVAL;

	in = (struct scmi_clk_state_in *)msg->in_msg;
	out = (struct scmi_clk_state_out *)msg->out_msg;

	clk_state = get_scmi_clk_state(agent->idx, in->clock_id);
	if (!clk_state) {
		dev_err(dev, "Unexpected clock ID %u\n", in->clock_id);

		out->status = SCMI_NOT_FOUND;
	} else if (in->attributes > 1) {
		out->status = SCMI_PROTOCOL_ERROR;
	} else {
		clk_state->enabled = in->attributes;

		out->status = SCMI_SUCCESS;
	}

	return 0;
}

static int sandbox_scmi_rd_attribs(struct udevice *dev, struct scmi_msg *msg)
{
	struct sandbox_scmi_agent *agent = dev_get_priv(dev);
	struct scmi_rd_attr_in *in = NULL;
	struct scmi_rd_attr_out *out = NULL;
	struct sandbox_scmi_reset *reset_state = NULL;

	if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
	    !msg->out_msg || msg->out_msg_sz < sizeof(*out))
		return -EINVAL;

	in = (struct scmi_rd_attr_in *)msg->in_msg;
	out = (struct scmi_rd_attr_out *)msg->out_msg;

	reset_state = get_scmi_reset_state(agent->idx, in->domain_id);
	if (!reset_state) {
		dev_err(dev, "Unexpected reset domain ID %u\n", in->domain_id);

		out->status = SCMI_NOT_FOUND;
	} else {
		memset(out, 0, sizeof(*out));
		snprintf(out->name, sizeof(out->name), "rd%u", in->domain_id);

		out->status = SCMI_SUCCESS;
	}

	return 0;
}

static int sandbox_scmi_rd_reset(struct udevice *dev, struct scmi_msg *msg)
{
	struct sandbox_scmi_agent *agent = dev_get_priv(dev);
	struct scmi_rd_reset_in *in = NULL;
	struct scmi_rd_reset_out *out = NULL;
	struct sandbox_scmi_reset *reset_state = NULL;

	if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
	    !msg->out_msg || msg->out_msg_sz < sizeof(*out))
		return -EINVAL;

	in = (struct scmi_rd_reset_in *)msg->in_msg;
	out = (struct scmi_rd_reset_out *)msg->out_msg;

	reset_state = get_scmi_reset_state(agent->idx, in->domain_id);
	if (!reset_state) {
		dev_err(dev, "Unexpected reset domain ID %u\n", in->domain_id);

		out->status = SCMI_NOT_FOUND;
	} else if (in->reset_state > 1) {
		dev_err(dev, "Invalid reset domain input attribute value\n");

		out->status = SCMI_INVALID_PARAMETERS;
	} else {
		if (in->flags & SCMI_RD_RESET_FLAG_CYCLE) {
			if (in->flags & SCMI_RD_RESET_FLAG_ASYNC) {
				out->status = SCMI_NOT_SUPPORTED;
			} else {
				/* Ends deasserted whatever current state */
				reset_state->asserted = false;
				out->status = SCMI_SUCCESS;
			}
		} else {
			reset_state->asserted = in->flags &
						SCMI_RD_RESET_FLAG_ASSERT;

			out->status = SCMI_SUCCESS;
		}
	}

	return 0;
}

static int sandbox_scmi_test_process_msg(struct udevice *dev,
					 struct scmi_msg *msg)
{
	switch (msg->protocol_id) {
	case SCMI_PROTOCOL_ID_CLOCK:
		switch (msg->message_id) {
		case SCMI_CLOCK_RATE_SET:
			return sandbox_scmi_clock_rate_set(dev, msg);
		case SCMI_CLOCK_RATE_GET:
			return sandbox_scmi_clock_rate_get(dev, msg);
		case SCMI_CLOCK_CONFIG_SET:
			return sandbox_scmi_clock_gate(dev, msg);
		default:
			break;
		}
		break;
	case SCMI_PROTOCOL_ID_RESET_DOMAIN:
		switch (msg->message_id) {
		case SCMI_RESET_DOMAIN_ATTRIBUTES:
			return sandbox_scmi_rd_attribs(dev, msg);
		case SCMI_RESET_DOMAIN_RESET:
			return sandbox_scmi_rd_reset(dev, msg);
		default:
			break;
		}
		break;
	case SCMI_PROTOCOL_ID_BASE:
	case SCMI_PROTOCOL_ID_POWER_DOMAIN:
	case SCMI_PROTOCOL_ID_SYSTEM:
	case SCMI_PROTOCOL_ID_PERF:
	case SCMI_PROTOCOL_ID_SENSOR:
		*(u32 *)msg->out_msg = SCMI_NOT_SUPPORTED;
		return 0;
	default:
		break;
	}

	dev_err(dev, "%s(%s): Unhandled protocol_id %#x/message_id %#x\n",
		__func__, dev->name, msg->protocol_id, msg->message_id);

	if (msg->out_msg_sz < sizeof(u32))
		return -EINVAL;

	/* Intentionnaly report unhandled IDs through the SCMI return code */
	*(u32 *)msg->out_msg = SCMI_PROTOCOL_ERROR;
	return 0;
}

static int sandbox_scmi_test_remove(struct udevice *dev)
{
	struct sandbox_scmi_agent *agent = dev_get_priv(dev);

	debug_print_agent_state(dev, "removed");

	/* We only need to dereference the agent in the context */
	sandbox_scmi_service_ctx()->agent[agent->idx] = NULL;

	return 0;
}

static int sandbox_scmi_test_probe(struct udevice *dev)
{
	static const char basename[] = "sandbox-scmi-agent@";
	struct sandbox_scmi_agent *agent = dev_get_priv(dev);
	const size_t basename_size = sizeof(basename) - 1;

	if (strncmp(basename, dev->name, basename_size))
		return -ENOENT;

	switch (dev->name[basename_size]) {
	case '0':
		*agent = (struct sandbox_scmi_agent){
			.idx = 0,
			.clk = scmi0_clk,
			.clk_count = ARRAY_SIZE(scmi0_clk),
			.reset = scmi0_reset,
			.reset_count = ARRAY_SIZE(scmi0_reset),
		};
		break;
	case '1':
		*agent = (struct sandbox_scmi_agent){
			.idx = 1,
			.clk = scmi1_clk,
			.clk_count = ARRAY_SIZE(scmi1_clk),
		};
		break;
	default:
		dev_err(dev, "%s(): Unexpected agent ID %s\n",
			__func__, dev->name + basename_size);
		return -ENOENT;
	}

	debug_print_agent_state(dev, "probed");

	/* Save reference for tests purpose */
	sandbox_scmi_service_ctx()->agent[agent->idx] = agent;

	return 0;
};

static const struct udevice_id sandbox_scmi_test_ids[] = {
	{ .compatible = "sandbox,scmi-agent" },
	{ }
};

struct scmi_agent_ops sandbox_scmi_test_ops = {
	.process_msg = sandbox_scmi_test_process_msg,
};

U_BOOT_DRIVER(sandbox_scmi_agent) = {
	.name = "sandbox-scmi_agent",
	.id = UCLASS_SCMI_AGENT,
	.of_match = sandbox_scmi_test_ids,
	.priv_auto_alloc_size = sizeof(struct sandbox_scmi_agent),
	.probe = sandbox_scmi_test_probe,
	.remove = sandbox_scmi_test_remove,
	.ops = &sandbox_scmi_test_ops,
};
