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

#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 = dectoul(argv[1], NULL);
	lpsc_id = dectoul(argv[2], NULL);

	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_LONGHELP(pd,
	   "dump                 - show power domain status\n"
	   "enable [psc] [lpsc]  - enable power domain\n"
	   "disable [psc] [lpsc] - disable power domain\n");

U_BOOT_CMD(pd, 4, 1, ti_do_pd,
	   "TI power domain control", pd_help_text
);
