// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2016 Freescale Semiconductor, Inc.
 */

#include <common.h>
#include <cpu_func.h>
#include <asm/io.h>
#include <asm/arch/imx-regs.h>
#include <dm.h>
#include <wdt.h>

/*
 * MX7ULP WDOG Register Map
 */
struct wdog_regs {
	u32 cs;
	u32 cnt;
	u32 toval;
	u32 win;
};

struct ulp_wdt_priv {
	struct wdog_regs *wdog;
	u32 clk_rate;
};

#define REFRESH_WORD0 0xA602 /* 1st refresh word */
#define REFRESH_WORD1 0xB480 /* 2nd refresh word */

#define UNLOCK_WORD0 0xC520 /* 1st unlock word */
#define UNLOCK_WORD1 0xD928 /* 2nd unlock word */

#define UNLOCK_WORD 0xD928C520 /* unlock word */
#define REFRESH_WORD 0xB480A602 /* refresh word */

#define WDGCS_WDGE                      BIT(7)
#define WDGCS_WDGUPDATE                 BIT(5)

#define WDGCS_RCS                       BIT(10)
#define WDGCS_ULK                       BIT(11)
#define WDOG_CS_PRES                    BIT(12)
#define WDGCS_CMD32EN                   BIT(13)
#define WDGCS_FLG                       BIT(14)
#define WDGCS_INT			BIT(6)

#define WDG_BUS_CLK                      (0x0)
#define WDG_LPO_CLK                      (0x1)
#define WDG_32KHZ_CLK                    (0x2)
#define WDG_EXT_CLK                      (0x3)

#define CLK_RATE_1KHZ			1000
#define CLK_RATE_32KHZ			125

void hw_watchdog_set_timeout(u16 val)
{
	/* setting timeout value */
	struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;

	writel(val, &wdog->toval);
}

void ulp_watchdog_reset(struct wdog_regs *wdog)
{
	if (readl(&wdog->cs) & WDGCS_CMD32EN) {
		writel(REFRESH_WORD, &wdog->cnt);
	} else {
		dmb();
		__raw_writel(REFRESH_WORD0, &wdog->cnt);
		__raw_writel(REFRESH_WORD1, &wdog->cnt);
		dmb();
	}
}

void ulp_watchdog_init(struct wdog_regs *wdog, u16 timeout)
{
	u32 cmd32 = 0;

	if (readl(&wdog->cs) & WDGCS_CMD32EN) {
		writel(UNLOCK_WORD, &wdog->cnt);
		cmd32 = WDGCS_CMD32EN;
	} else {
		dmb();
		__raw_writel(UNLOCK_WORD0, &wdog->cnt);
		__raw_writel(UNLOCK_WORD1, &wdog->cnt);
		dmb();
	}

	/* Wait WDOG Unlock */
	while (!(readl(&wdog->cs) & WDGCS_ULK))
		;

	hw_watchdog_set_timeout(timeout);
	writel(0, &wdog->win);

	/* setting 1-kHz clock source, enable counter running, and clear interrupt */
	if (IS_ENABLED(CONFIG_ARCH_IMX9))
		writel((cmd32 | WDGCS_WDGE | WDGCS_WDGUPDATE | (WDG_LPO_CLK << 8) |
		       WDGCS_FLG | WDOG_CS_PRES | WDGCS_INT), &wdog->cs);
	else
		writel((cmd32 | WDGCS_WDGE | WDGCS_WDGUPDATE | (WDG_LPO_CLK << 8) |
		       WDGCS_FLG), &wdog->cs);

	/* Wait WDOG reconfiguration */
	while (!(readl(&wdog->cs) & WDGCS_RCS))
		;

	ulp_watchdog_reset(wdog);
}

void hw_watchdog_reset(void)
{
	struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;

	ulp_watchdog_reset(wdog);
}

void hw_watchdog_init(void)
{
	struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;

	ulp_watchdog_init(wdog, CONFIG_WATCHDOG_TIMEOUT_MSECS);
}

void reset_cpu(void)
{
	struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
	u32 cmd32 = 0;

	if (readl(&wdog->cs) & WDGCS_CMD32EN) {
		writel(UNLOCK_WORD, &wdog->cnt);
		cmd32 = WDGCS_CMD32EN;
	} else {
		dmb();
		__raw_writel(UNLOCK_WORD0, &wdog->cnt);
		__raw_writel(UNLOCK_WORD1, &wdog->cnt);
		dmb();
	}

	/* Wait WDOG Unlock */
	while (!(readl(&wdog->cs) & WDGCS_ULK))
		;

	hw_watchdog_set_timeout(5); /* 5ms timeout for general; 40ms timeout for imx93 */
	writel(0, &wdog->win);

	/* enable counter running */
	if (IS_ENABLED(CONFIG_ARCH_IMX9))
		writel((cmd32 | WDGCS_WDGE | (WDG_LPO_CLK << 8) | WDOG_CS_PRES |
		       WDGCS_INT), &wdog->cs);
	else
		writel((cmd32 | WDGCS_WDGE | (WDG_LPO_CLK << 8)), &wdog->cs);

	/* Wait WDOG reconfiguration */
	while (!(readl(&wdog->cs) & WDGCS_RCS))
		;

	hw_watchdog_reset();

	while (1);
}

static int ulp_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
{
	struct ulp_wdt_priv *priv = dev_get_priv(dev);
	u64 timeout = 0;

	timeout = (timeout_ms * priv->clk_rate) / 1000;
	if (timeout > U16_MAX)
		return -EINVAL;

	ulp_watchdog_init(priv->wdog, (u16)timeout);

	return 0;
}

static int ulp_wdt_reset(struct udevice *dev)
{
	struct ulp_wdt_priv *priv = dev_get_priv(dev);

	ulp_watchdog_reset(priv->wdog);

	return 0;
}

static int ulp_wdt_probe(struct udevice *dev)
{
	struct ulp_wdt_priv *priv = dev_get_priv(dev);

	priv->wdog = dev_read_addr_ptr(dev);
	if (!priv->wdog)
		return -EINVAL;

	priv->clk_rate = (u32)dev_get_driver_data(dev);
	if (!priv->clk_rate)
		return -EINVAL;

	return 0;
}

static const struct wdt_ops ulp_wdt_ops = {
	.start = ulp_wdt_start,
	.reset = ulp_wdt_reset,
};

static const struct udevice_id ulp_wdt_ids[] = {
	{ .compatible = "fsl,imx7ulp-wdt", .data = CLK_RATE_1KHZ },
	{ .compatible = "fsl,imx8ulp-wdt", .data = CLK_RATE_1KHZ },
	{ .compatible = "fsl,imx93-wdt", .data = CLK_RATE_32KHZ },
	{}
};

U_BOOT_DRIVER(ulp_wdt) = {
	.name	= "ulp_wdt",
	.id	= UCLASS_WDT,
	.of_match	= ulp_wdt_ids,
	.priv_auto	= sizeof(struct ulp_wdt_priv),
	.probe		= ulp_wdt_probe,
	.ops	= &ulp_wdt_ops,
};
