// SPDX-License-Identifier: GPL-2.0+
/*
 * Power Domain test commands
 *
 * Copyright (C) 2020 Texas Instruments Incorporated, <www.ti.com>
 */

#include <common.h>
#include <command.h>
#include <dm.h>
#include <k3-dev.h>

static const struct udevice_id ti_pd_of_match[] = {
	{ .compatible = "ti,sci-pm-domain" },
	{ /* sentinel */ }
};

static struct ti_k3_pd_platdata *ti_pd_find_data(void)
{
	struct udevice *dev;
	int i = 0;

	while (1) {
		uclass_get_device(UCLASS_POWER_DOMAIN, i++, &dev);
		if (!dev)
			return NULL;

		if (device_is_compatible(dev,
					 ti_pd_of_match[0].compatible))
			return  dev_get_priv(dev);
	}

	return NULL;
}

static void dump_lpsc(struct ti_k3_pd_platdata *data, struct ti_pd *pd)
{
	int i;
	struct ti_lpsc *lpsc;
	u8 state;
	static const char * const lpsc_states[] = {
		"swrstdis", "syncrst", "disable", "enable", "autosleep",
		"autowake", "unknown",
	};

	for (i = 0; i < data->num_lpsc; i++) {
		lpsc = &data->lpsc[i];
		if (lpsc->pd != pd)
			continue;
		state = lpsc_get_state(lpsc);
		if (state > ARRAY_SIZE(lpsc_states))
			state = ARRAY_SIZE(lpsc_states) - 1;
		printf("    LPSC%d: state=%s, usecount=%d\n",
		       lpsc->id, lpsc_states[state], lpsc->usecount);
	}
}

static void dump_pd(struct ti_k3_pd_platdata *data, struct ti_psc *psc)
{
	int i;
	struct ti_pd *pd;
	u8 state;
	static const char * const pd_states[] = {
		"off", "on", "unknown"
	};

	for (i = 0; i < data->num_pd; i++) {
		pd = &data->pd[i];
		if (pd->psc != psc)
			continue;
		state = ti_pd_state(pd);
		if (state > ARRAY_SIZE(pd_states))
			state = ARRAY_SIZE(pd_states) - 1;
		printf("  PD%d: state=%s, usecount=%d:\n",
		       pd->id, pd_states[state], pd->usecount);
		dump_lpsc(data, pd);
	}
}

static void dump_psc(struct ti_k3_pd_platdata *data)
{
	int i;
	struct ti_psc *psc;

	for (i = 0; i < data->num_psc; i++) {
		psc = &data->psc[i];
		printf("PSC%d [%p]:\n", psc->id, psc->base);
		dump_pd(data, psc);
	}
}

static int do_pd_dump(struct cmd_tbl *cmdtp, int flag, int argc,
		      char *const argv[])
{
	struct ti_k3_pd_platdata *data;

	data = ti_pd_find_data();
	if (!data)
		return CMD_RET_FAILURE;

	dump_psc(data);

	return 0;
}

static int do_pd_endis(int argc, char *const argv[], u8 state)
{
	u32 psc_id;
	u32 lpsc_id;
	int i;
	struct ti_k3_pd_platdata *data;
	struct ti_lpsc *lpsc;
	int ret;

	if (argc < 3)
		return CMD_RET_FAILURE;

	data = ti_pd_find_data();
	if (!data)
		return CMD_RET_FAILURE;

	psc_id = simple_strtoul(argv[1], NULL, 10);
	lpsc_id = simple_strtoul(argv[2], NULL, 10);

	for (i = 0; i < data->num_lpsc; i++) {
		lpsc = &data->lpsc[i];
		if (lpsc->pd->psc->id != psc_id)
			continue;
		if (lpsc->id != lpsc_id)
			continue;
		printf("%s pd [PSC:%d,LPSC:%d]...\n",
		       state == MDSTAT_STATE_ENABLE ? "Enabling" : "Disabling",
		       psc_id, lpsc_id);
		ret = ti_lpsc_transition(lpsc, state);
		if (ret)
			return CMD_RET_FAILURE;
		else
			return 0;
	}

	printf("No matching psc/lpsc found.\n");

	return CMD_RET_FAILURE;
}

static int do_pd_enable(struct cmd_tbl *cmdtp, int flag, int argc,
			char *const argv[])
{
	return do_pd_endis(argc, argv, MDSTAT_STATE_ENABLE);
}

static int do_pd_disable(struct cmd_tbl *cmdtp, int flag, int argc,
			 char *const argv[])
{
	return do_pd_endis(argc, argv, MDSTAT_STATE_SWRSTDISABLE);
}

static struct cmd_tbl cmd_pd[] = {
	U_BOOT_CMD_MKENT(dump, 1, 0, do_pd_dump, "", ""),
	U_BOOT_CMD_MKENT(enable, 3, 0, do_pd_enable, "", ""),
	U_BOOT_CMD_MKENT(disable, 3, 0, do_pd_disable, "", ""),
};

static int ti_do_pd(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
{
	struct cmd_tbl *c;

	argc--;
	argv++;

	c = find_cmd_tbl(argv[0], cmd_pd, ARRAY_SIZE(cmd_pd));
	if (c)
		return c->cmd(cmdtp, flag, argc, argv);
	else
		return CMD_RET_USAGE;
}

U_BOOT_CMD(pd, 4, 1, ti_do_pd,
	   "TI power domain control",
#if CONFIG_IS_ENABLED(SYS_LONGHELP)
	   "dump                 - show power domain status\n"
	   "enable [psc] [lpsc]  - enable power domain\n"
	   "disable [psc] [lpsc] - disable power domain\n"
#endif
);
