// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2020, Linaro Limited
 *
 * Tests scmi_agent uclass and the SCMI drivers implemented in other
 * uclass devices probe when a SCMI server exposes resources.
 *
 * Note in test.dts the protocol@10 node in scmi node. Protocol 0x10 is not
 * implemented in U-Boot SCMI components but the implementation is expected
 * to not complain on unknown protocol IDs, as long as it is not used. Note
 * in test.dts tests that SCMI drivers probing does not fail for such an
 * unknown SCMI protocol ID.
 */

#include <common.h>
#include <clk.h>
#include <dm.h>
#include <reset.h>
#include <scmi_agent.h>
#include <scmi_protocols.h>
#include <asm/scmi_test.h>
#include <dm/device-internal.h>
#include <dm/test.h>
#include <linux/kconfig.h>
#include <power/regulator.h>
#include <test/ut.h>

static int ut_assert_scmi_state_postprobe(struct unit_test_state *uts,
					  struct sandbox_scmi_agent *agent,
					  struct udevice *dev)
{
	struct sandbox_scmi_devices *scmi_devices;

	/* Device references to check context against test sequence */
	scmi_devices = sandbox_scmi_devices_ctx(dev);
	ut_assertnonnull(scmi_devices);
	ut_asserteq(2, scmi_devices->clk_count);
	ut_asserteq(1, scmi_devices->reset_count);
	ut_asserteq(2, scmi_devices->regul_count);

	/* State of the simulated SCMI server exposed */
	ut_asserteq(3, agent->clk_count);
	ut_assertnonnull(agent->clk);
	ut_asserteq(1, agent->reset_count);
	ut_assertnonnull(agent->reset);
	ut_asserteq(2, agent->voltd_count);
	ut_assertnonnull(agent->voltd);

	return 0;
}

static int load_sandbox_scmi_test_devices(struct unit_test_state *uts,
					  struct sandbox_scmi_agent **ctx,
					  struct udevice **dev)
{
	struct udevice *agent_dev;

	ut_assertok(uclass_get_device_by_name(UCLASS_SCMI_AGENT, "scmi",
					      &agent_dev));
	ut_assertnonnull(agent_dev);

	*ctx = sandbox_scmi_agent_ctx(agent_dev);
	ut_assertnonnull(*ctx);

	/* probe */
	ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "sandbox_scmi",
					      dev));
	ut_assertnonnull(*dev);

	return ut_assert_scmi_state_postprobe(uts, *ctx, *dev);
}

static int release_sandbox_scmi_test_devices(struct unit_test_state *uts,
					     struct udevice *dev)
{
	/* un-probe */
	ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));

	return 0;
}

/*
 * Test SCMI states when loading and releasing resources
 * related to SCMI drivers.
 */
static int dm_test_scmi_sandbox_agent(struct unit_test_state *uts)
{
	struct sandbox_scmi_agent *ctx;
	struct udevice *dev = NULL;
	int ret;

	ret = load_sandbox_scmi_test_devices(uts, &ctx, &dev);
	if (!ret)
		ret = release_sandbox_scmi_test_devices(uts, dev);

	return ret;
}
DM_TEST(dm_test_scmi_sandbox_agent, UT_TESTF_SCAN_FDT);

static int dm_test_scmi_clocks(struct unit_test_state *uts)
{
	struct sandbox_scmi_agent *agent;
	struct sandbox_scmi_devices *scmi_devices;
	struct udevice *agent_dev, *clock_dev, *dev;
	int ret_dev;
	int ret;

	ret = load_sandbox_scmi_test_devices(uts, &agent, &dev);
	if (ret)
		return ret;

	scmi_devices = sandbox_scmi_devices_ctx(dev);
	ut_assertnonnull(scmi_devices);

	/* Sandbox SCMI clock protocol has its own channel */
	ut_assertok(uclass_get_device_by_name(UCLASS_SCMI_AGENT, "scmi",
					      &agent_dev));
	ut_assertnonnull(agent_dev);
	clock_dev = scmi_get_protocol(agent_dev, SCMI_PROTOCOL_ID_CLOCK);
	ut_assertnonnull(clock_dev);
	ut_asserteq(0x14, sandbox_scmi_channel_id(clock_dev));

	/* Test SCMI clocks rate manipulation */
	ut_asserteq(333, agent->clk[0].rate);
	ut_asserteq(200, agent->clk[1].rate);
	ut_asserteq(1000, agent->clk[2].rate);

	ut_asserteq(1000, clk_get_rate(&scmi_devices->clk[0]));
	ut_asserteq(333, clk_get_rate(&scmi_devices->clk[1]));

	ret_dev = clk_set_rate(&scmi_devices->clk[1], 1088);
	ut_assert(!ret_dev || ret_dev == 1088);

	ut_asserteq(1088, agent->clk[0].rate);
	ut_asserteq(200, agent->clk[1].rate);
	ut_asserteq(1000, agent->clk[2].rate);

	ut_asserteq(1000, clk_get_rate(&scmi_devices->clk[0]));
	ut_asserteq(1088, clk_get_rate(&scmi_devices->clk[1]));

	/* restore original rate for further tests */
	ret_dev = clk_set_rate(&scmi_devices->clk[1], 333);
	ut_assert(!ret_dev || ret_dev == 333);

	/* Test SCMI clocks gating manipulation */
	ut_assert(!agent->clk[0].enabled);
	ut_assert(!agent->clk[1].enabled);
	ut_assert(!agent->clk[2].enabled);

	ut_asserteq(0, clk_enable(&scmi_devices->clk[1]));

	ut_assert(agent->clk[0].enabled);
	ut_assert(!agent->clk[1].enabled);
	ut_assert(!agent->clk[2].enabled);

	ut_assertok(clk_disable(&scmi_devices->clk[1]));

	ut_assert(!agent->clk[0].enabled);
	ut_assert(!agent->clk[1].enabled);
	ut_assert(!agent->clk[2].enabled);

	return release_sandbox_scmi_test_devices(uts, dev);
}
DM_TEST(dm_test_scmi_clocks, UT_TESTF_SCAN_FDT);

static int dm_test_scmi_resets(struct unit_test_state *uts)
{
	struct sandbox_scmi_agent *agent;
	struct sandbox_scmi_devices *scmi_devices;
	struct udevice *agent_dev, *reset_dev, *dev = NULL;
	int ret;

	ret = load_sandbox_scmi_test_devices(uts, &agent, &dev);
	if (ret)
		return ret;

	scmi_devices = sandbox_scmi_devices_ctx(dev);
	ut_assertnonnull(scmi_devices);

	/* Sandbox SCMI reset protocol doesn't have its own channel */
	ut_assertok(uclass_get_device_by_name(UCLASS_SCMI_AGENT, "scmi",
					      &agent_dev));
	ut_assertnonnull(agent_dev);
	reset_dev = scmi_get_protocol(agent_dev, SCMI_PROTOCOL_ID_RESET_DOMAIN);
	ut_assertnonnull(reset_dev);
	ut_asserteq(0x0, sandbox_scmi_channel_id(reset_dev));

	/* Test SCMI resect controller manipulation */
	ut_assert(!agent->reset[0].asserted);

	ut_assertok(reset_assert(&scmi_devices->reset[0]));
	ut_assert(agent->reset[0].asserted);

	ut_assertok(reset_deassert(&scmi_devices->reset[0]));
	ut_assert(!agent->reset[0].asserted);

	return release_sandbox_scmi_test_devices(uts, dev);
}
DM_TEST(dm_test_scmi_resets, UT_TESTF_SCAN_FDT);

static int dm_test_scmi_voltage_domains(struct unit_test_state *uts)
{
	struct sandbox_scmi_agent *agent;
	struct sandbox_scmi_devices *scmi_devices;
	struct dm_regulator_uclass_plat *uc_pdata;
	struct udevice *dev;
	struct udevice *regul0_dev;

	ut_assertok(load_sandbox_scmi_test_devices(uts, &agent, &dev));

	scmi_devices = sandbox_scmi_devices_ctx(dev);
	ut_assertnonnull(scmi_devices);

	/* Set/Get an SCMI voltage domain level */
	regul0_dev = scmi_devices->regul[0];
	ut_assert(regul0_dev);

	uc_pdata = dev_get_uclass_plat(regul0_dev);
	ut_assert(uc_pdata);

	ut_assertok(regulator_set_value(regul0_dev, uc_pdata->min_uV));
	ut_asserteq(agent->voltd[0].voltage_uv, uc_pdata->min_uV);

	ut_assert(regulator_get_value(regul0_dev) == uc_pdata->min_uV);

	ut_assertok(regulator_set_value(regul0_dev, uc_pdata->max_uV));
	ut_asserteq(agent->voltd[0].voltage_uv, uc_pdata->max_uV);

	ut_assert(regulator_get_value(regul0_dev) == uc_pdata->max_uV);

	/* Enable/disable SCMI voltage domains */
	ut_assertok(regulator_set_enable(scmi_devices->regul[0], false));
	ut_assertok(regulator_set_enable(scmi_devices->regul[1], false));
	ut_assert(!agent->voltd[0].enabled);
	ut_assert(!agent->voltd[1].enabled);

	ut_assertok(regulator_set_enable(scmi_devices->regul[0], true));
	ut_assert(agent->voltd[0].enabled);
	ut_assert(!agent->voltd[1].enabled);

	ut_assertok(regulator_set_enable(scmi_devices->regul[1], true));
	ut_assert(agent->voltd[0].enabled);
	ut_assert(agent->voltd[1].enabled);

	ut_assertok(regulator_set_enable(scmi_devices->regul[0], false));
	ut_assert(!agent->voltd[0].enabled);
	ut_assert(agent->voltd[1].enabled);

	return release_sandbox_scmi_test_devices(uts, dev);
}
DM_TEST(dm_test_scmi_voltage_domains, UT_TESTF_SCAN_FDT);
