// SPDX-License-Identifier: GPL-2.0+
/*
 * Texas Instruments power domain driver
 *
 * Copyright (C) 2020-2021 Texas Instruments Incorporated - http://www.ti.com/
 *	Tero Kristo <t-kristo@ti.com>
 */

#include <asm/io.h>
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <power-domain-uclass.h>
#include <soc.h>
#include <k3-dev.h>
#include <linux/iopoll.h>

#define PSC_PTCMD		0x120
#define PSC_PTSTAT		0x128
#define PSC_PDSTAT		0x200
#define PSC_PDCTL		0x300
#define PSC_MDSTAT		0x800
#define PSC_MDCTL		0xa00

#define PDCTL_STATE_MASK		0x1
#define PDCTL_STATE_OFF			0x0
#define PDCTL_STATE_ON			0x1

#define MDSTAT_STATE_MASK		0x3f
#define MDSTAT_BUSY_MASK		0x30
#define MDSTAT_STATE_SWRSTDISABLE	0x0
#define MDSTAT_STATE_ENABLE		0x3

#define LPSC_TIMEOUT		1000
#define PD_TIMEOUT		1000

static u32 psc_read(struct ti_psc *psc, u32 reg)
{
	u32 val;

	val = readl(psc->base + reg);
	debug("%s: 0x%x from %p\n", __func__, val, psc->base + reg);
	return val;
}

static void psc_write(u32 val, struct ti_psc *psc, u32 reg)
{
	debug("%s: 0x%x to %p\n", __func__, val, psc->base + reg);
	writel(val, psc->base + reg);
}

static u32 pd_read(struct ti_pd *pd, u32 reg)
{
	return psc_read(pd->psc, reg + 4 * pd->id);
}

static void pd_write(u32 val, struct ti_pd *pd, u32 reg)
{
	psc_write(val, pd->psc, reg + 4 * pd->id);
}

static u32 lpsc_read(struct ti_lpsc *lpsc, u32 reg)
{
	return psc_read(lpsc->psc, reg + 4 * lpsc->id);
}

static void lpsc_write(u32 val, struct ti_lpsc *lpsc, u32 reg)
{
	psc_write(val, lpsc->psc, reg + 4 * lpsc->id);
}

static const struct soc_attr ti_k3_soc_pd_data[] = {
#if IS_ENABLED(CONFIG_SOC_K3_J721E)
	{
		.family = "J721E",
		.data = &j721e_pd_platdata,
	},
	{
		.family = "J7200",
		.data = &j7200_pd_platdata,
	},
#endif
	{ /* sentinel */ }
};

static int ti_power_domain_probe(struct udevice *dev)
{
	struct ti_k3_pd_platdata *data = dev_get_priv(dev);
	const struct soc_attr *soc_match_data;
	const struct ti_k3_pd_platdata *pdata;

	printf("%s(dev=%p)\n", __func__, dev);

	if (!data)
		return -ENOMEM;

	soc_match_data = soc_device_match(ti_k3_soc_pd_data);
	if (!soc_match_data)
		return -ENODEV;

	pdata = (const struct ti_k3_pd_platdata *)soc_match_data->data;

	data->psc = pdata->psc;
	data->pd = pdata->pd;
	data->lpsc = pdata->lpsc;
	data->devs = pdata->devs;
	data->num_psc = pdata->num_psc;
	data->num_pd = pdata->num_pd;
	data->num_lpsc = pdata->num_lpsc;
	data->num_devs = pdata->num_devs;

	return 0;
}

static int ti_pd_wait(struct ti_pd *pd)
{
	u32 ptstat;
	int ret;

	ret = readl_poll_timeout(pd->psc->base + PSC_PTSTAT, ptstat,
				 !(ptstat & BIT(pd->id)), PD_TIMEOUT);

	if (ret)
		printf("%s: psc%d, pd%d failed to transition.\n", __func__,
		       pd->psc->id, pd->id);

	return ret;
}

static void ti_pd_transition(struct ti_pd *pd)
{
	psc_write(BIT(pd->id), pd->psc, PSC_PTCMD);
}

u8 ti_pd_state(struct ti_pd *pd)
{
	return pd_read(pd, PSC_PDCTL) & PDCTL_STATE_MASK;
}

static int ti_pd_get(struct ti_pd *pd)
{
	u32 pdctl;
	int ret;

	pd->usecount++;

	if (pd->usecount > 1)
		return 0;

	if (pd->depend) {
		ret = ti_pd_get(pd->depend);
		if (ret)
			return ret;
		ti_pd_transition(pd->depend);
		ret = ti_pd_wait(pd->depend);
		if (ret)
			return ret;
	}

	pdctl = pd_read(pd, PSC_PDCTL);

	if ((pdctl & PDCTL_STATE_MASK) == PDCTL_STATE_ON)
		return 0;

	debug("%s: enabling psc:%d, pd:%d\n", __func__, pd->psc->id, pd->id);

	pdctl &= ~PDCTL_STATE_MASK;
	pdctl |= PDCTL_STATE_ON;

	pd_write(pdctl, pd, PSC_PDCTL);

	return 0;
}

static int ti_pd_put(struct ti_pd *pd)
{
	u32 pdctl;
	int ret;

	pd->usecount--;

	if (pd->usecount > 0)
		return 0;

	pdctl = pd_read(pd, PSC_PDCTL);
	if ((pdctl & PDCTL_STATE_MASK) == PDCTL_STATE_OFF)
		return 0;

	pdctl &= ~PDCTL_STATE_MASK;
	pdctl |= PDCTL_STATE_OFF;

	debug("%s: disabling psc:%d, pd:%d\n", __func__, pd->psc->id, pd->id);

	pd_write(pdctl, pd, PSC_PDCTL);

	if (pd->depend) {
		ti_pd_transition(pd);
		ret = ti_pd_wait(pd);
		if (ret)
			return ret;

		ret = ti_pd_put(pd->depend);
		if (ret)
			return ret;
		ti_pd_transition(pd->depend);
		ret = ti_pd_wait(pd->depend);
		if (ret)
			return ret;
	}

	return 0;
}

static int ti_lpsc_wait(struct ti_lpsc *lpsc)
{
	u32 mdstat;
	int ret;

	ret = readl_poll_timeout(lpsc->psc->base + PSC_MDSTAT + lpsc->id * 4,
				 mdstat,
				 !(mdstat & MDSTAT_BUSY_MASK), LPSC_TIMEOUT);

	if (ret)
		printf("%s: module %d failed to transition.\n", __func__,
		       lpsc->id);

	return ret;
}

u8 lpsc_get_state(struct ti_lpsc *lpsc)
{
	return lpsc_read(lpsc, PSC_MDCTL) & MDSTAT_STATE_MASK;
}

int ti_lpsc_transition(struct ti_lpsc *lpsc, u8 state)
{
	struct ti_pd *psc_pd;
	int ret;
	u32 mdctl;

	psc_pd = lpsc->pd;

	if (state == MDSTAT_STATE_ENABLE) {
		lpsc->usecount++;
		if (lpsc->usecount > 1)
			return 0;
	} else {
		lpsc->usecount--;
		if (lpsc->usecount >= 1)
			return 0;
	}

	debug("%s: transitioning psc:%d, lpsc:%d to %x\n", __func__,
	      lpsc->psc->id, lpsc->id, state);

	if (lpsc->depend)
		ti_lpsc_transition(lpsc->depend, state);

	mdctl = lpsc_read(lpsc, PSC_MDCTL);
	if ((mdctl & MDSTAT_STATE_MASK) == state)
		return 0;

	if (state == MDSTAT_STATE_ENABLE)
		ti_pd_get(psc_pd);
	else
		ti_pd_put(psc_pd);

	mdctl &= ~MDSTAT_STATE_MASK;
	mdctl |= state;

	lpsc_write(mdctl, lpsc, PSC_MDCTL);

	ti_pd_transition(psc_pd);
	ret = ti_pd_wait(psc_pd);
	if (ret)
		return ret;

	return ti_lpsc_wait(lpsc);
}

static int ti_power_domain_transition(struct power_domain *pd, u8 state)
{
	struct ti_lpsc *lpsc = pd->priv;

	return ti_lpsc_transition(lpsc, state);
}

static int ti_power_domain_on(struct power_domain *pd)
{
	debug("%s(pd=%p, id=%lu)\n", __func__, pd, pd->id);

	return ti_power_domain_transition(pd, MDSTAT_STATE_ENABLE);
}

static int ti_power_domain_off(struct power_domain *pd)
{
	debug("%s(pd=%p, id=%lu)\n", __func__, pd, pd->id);

	return ti_power_domain_transition(pd, MDSTAT_STATE_SWRSTDISABLE);
}

static struct ti_lpsc *lpsc_lookup(struct ti_k3_pd_platdata *data, int id)
{
	int idx;

	for (idx = 0; idx < data->num_devs; idx++)
		if (data->devs[idx].id == id)
			return data->devs[idx].lpsc;

	return NULL;
}

static int ti_power_domain_of_xlate(struct power_domain *pd,
				    struct ofnode_phandle_args *args)
{
	struct ti_k3_pd_platdata *data = dev_get_priv(pd->dev);
	struct ti_lpsc *lpsc;

	debug("%s(power_domain=%p, id=%d)\n", __func__, pd, args->args[0]);

	if (args->args_count < 1) {
		printf("Invalid args_count: %d\n", args->args_count);
		return -EINVAL;
	}

	lpsc = lpsc_lookup(data, args->args[0]);
	if (!lpsc) {
		printf("%s: invalid dev-id: %d\n", __func__, args->args[0]);
		return -ENOENT;
	}

	pd->id = lpsc->id;
	pd->priv = lpsc;

	return 0;
}

static int ti_power_domain_request(struct power_domain *pd)
{
	return 0;
}

static int ti_power_domain_free(struct power_domain *pd)
{
	return 0;
}

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

static struct power_domain_ops ti_power_domain_ops = {
	.on = ti_power_domain_on,
	.off = ti_power_domain_off,
	.of_xlate = ti_power_domain_of_xlate,
	.request = ti_power_domain_request,
	.rfree = ti_power_domain_free,
};

U_BOOT_DRIVER(ti_pm_domains) = {
	.name = "ti-pm-domains",
	.id = UCLASS_POWER_DOMAIN,
	.of_match = ti_power_domain_of_match,
	.probe = ti_power_domain_probe,
	.priv_auto = sizeof(struct ti_k3_pd_platdata),
	.ops = &ti_power_domain_ops,
};
