// SPDX-License-Identifier: GPL-2.0
/*
 * omap_wdt.c
 *
 * (C) Copyright 2013
 * Heiko Schocher, DENX Software Engineering, hs@denx.de.
 *
 * Based on:
 *
 * Watchdog driver for the TI OMAP 16xx & 24xx/34xx 32KHz (non-secure) watchdog
 *
 * commit 2d991a164a61858012651e13c59521975504e260
 * Author: Bill Pemberton <wfp5p@virginia.edu>
 * Date:   Mon Nov 19 13:21:41 2012 -0500
 *
 * watchdog: remove use of __devinit
 *
 * CONFIG_HOTPLUG is going away as an option so __devinit is no longer
 * needed.
 *
 * Author: MontaVista Software, Inc.
 *	 <gdavis@mvista.com> or <source@mvista.com>
 *
 * History:
 *
 * 20030527: George G. Davis <gdavis@mvista.com>
 *	Initially based on linux-2.4.19-rmk7-pxa1/drivers/char/sa1100_wdt.c
 *	(c) Copyright 2000 Oleg Drokin <green@crimea.edu>
 *	Based on SoftDog driver by Alan Cox <alan@lxorguk.ukuu.org.uk>
 *
 * Copyright (c) 2004 Texas Instruments.
 *	1. Modified to support OMAP1610 32-KHz watchdog timer
 *	2. Ported to 2.6 kernel
 *
 * Copyright (c) 2005 David Brownell
 *	Use the driver model and standard identifiers; handle bigger timeouts.
 */

#include <common.h>
#include <watchdog.h>
#include <asm/arch/hardware.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/arch/cpu.h>
#include <wdt.h>
#include <dm.h>
#include <errno.h>

/* Hardware timeout in seconds */
#define WDT_HW_TIMEOUT 60

#if !CONFIG_IS_ENABLED(WDT)
static unsigned int wdt_trgr_pattern = 0x1234;

void hw_watchdog_reset(void)
{
	struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;

	/*
	 * Somebody just triggered watchdog reset and write to WTGR register
	 * is in progress. It is resetting right now, no need to trigger it
	 * again
	 */
	if ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WTGR)
		return;

	wdt_trgr_pattern = ~wdt_trgr_pattern;
	writel(wdt_trgr_pattern, &wdt->wdtwtgr);

	/*
	 * Don't wait for posted write to complete, i.e. don't check
	 * WDT_WWPS_PEND_WTGR bit in WWPS register. There is no writes to
	 * WTGR register outside of this func, and if entering it
	 * we see WDT_WWPS_PEND_WTGR bit set, it means watchdog reset
	 * was just triggered. This prevents us from wasting time in busy
	 * polling of WDT_WWPS_PEND_WTGR bit.
	 */
}

static int omap_wdt_set_timeout(unsigned int timeout)
{
	struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
	u32 pre_margin = GET_WLDR_VAL(timeout);

	/* just count up at 32 KHz */
	while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WLDR)
		;

	writel(pre_margin, &wdt->wdtwldr);
	while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WLDR)
		;

	return 0;
}

void hw_watchdog_disable(void)
{
	struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;

	/*
	 * Disable watchdog
	 */
	writel(0xAAAA, &wdt->wdtwspr);
	while (readl(&wdt->wdtwwps) != 0x0)
		;
	writel(0x5555, &wdt->wdtwspr);
	while (readl(&wdt->wdtwwps) != 0x0)
		;
}

void hw_watchdog_init(void)
{
	struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;

	/*
	 * Make sure the watchdog is disabled. This is unfortunately required
	 * because writing to various registers with the watchdog running has no
	 * effect.
	 */
	hw_watchdog_disable();

	/* initialize prescaler */
	while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WCLR)
		;

	writel(WDT_WCLR_PRE | (PTV << WDT_WCLR_PTV_OFF), &wdt->wdtwclr);
	while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WCLR)
		;

	omap_wdt_set_timeout(WDT_HW_TIMEOUT);

	/* Sequence to enable the watchdog */
	writel(0xBBBB, &wdt->wdtwspr);
	while ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WSPR)
		;

	writel(0x4444, &wdt->wdtwspr);
	while ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WSPR)
		;
}

void watchdog_reset(void)
{
	hw_watchdog_reset();
}

#else

static int omap3_wdt_reset(struct udevice *dev)
{
	struct omap3_wdt_priv *priv = dev_get_priv(dev);

/*
 * Somebody just triggered watchdog reset and write to WTGR register
 * is in progress. It is resetting right now, no need to trigger it
 * again
 */
	if ((readl(&priv->regs->wdtwwps)) & WDT_WWPS_PEND_WTGR)
		return 0;

	priv->wdt_trgr_pattern = ~(priv->wdt_trgr_pattern);
	writel(priv->wdt_trgr_pattern, &priv->regs->wdtwtgr);
/*
 * Don't wait for posted write to complete, i.e. don't check
 * WDT_WWPS_PEND_WTGR bit in WWPS register. There is no writes to
 * WTGR register outside of this func, and if entering it
 * we see WDT_WWPS_PEND_WTGR bit set, it means watchdog reset
 * was just triggered. This prevents us from wasting time in busy
 * polling of WDT_WWPS_PEND_WTGR bit.
 */
	return 0;
}

static int omap3_wdt_stop(struct udevice *dev)
{
	struct omap3_wdt_priv *priv = dev_get_priv(dev);

/* disable watchdog */
	writel(0xAAAA, &priv->regs->wdtwspr);
	while (readl(&priv->regs->wdtwwps) != 0x0)
		;
	writel(0x5555, &priv->regs->wdtwspr);
	while (readl(&priv->regs->wdtwwps) != 0x0)
		;
	return 0;
}

static int omap3_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
{
	struct omap3_wdt_priv *priv = dev_get_priv(dev);
	u32 pre_margin = GET_WLDR_VAL(timeout_ms);
/*
 * Make sure the watchdog is disabled. This is unfortunately required
 * because writing to various registers with the watchdog running has no
 * effect.
 */
	omap3_wdt_stop(dev);

/* initialize prescaler */
	while (readl(&priv->regs->wdtwwps) & WDT_WWPS_PEND_WCLR)
		;

	writel(WDT_WCLR_PRE | (PTV << WDT_WCLR_PTV_OFF), &priv->regs->wdtwclr);
	while (readl(&priv->regs->wdtwwps) & WDT_WWPS_PEND_WCLR)
		;
/* just count up at 32 KHz */
	while (readl(&priv->regs->wdtwwps) & WDT_WWPS_PEND_WLDR)
		;

	writel(pre_margin, &priv->regs->wdtwldr);
	while (readl(&priv->regs->wdtwwps) & WDT_WWPS_PEND_WLDR)
		;
/* Sequence to enable the watchdog */
	writel(0xBBBB, &priv->regs->wdtwspr);
	while ((readl(&priv->regs->wdtwwps)) & WDT_WWPS_PEND_WSPR)
		;

	writel(0x4444, &priv->regs->wdtwspr);
	while ((readl(&priv->regs->wdtwwps)) & WDT_WWPS_PEND_WSPR)
		;

	return 0;
}

static int omap3_wdt_probe(struct udevice *dev)
{
	struct omap3_wdt_priv *priv = dev_get_priv(dev);

	priv->regs = (struct wd_timer *)devfdt_get_addr(dev);
	if (!priv->regs)
		return -EINVAL;

	priv->wdt_trgr_pattern = 0x1234;
	debug("%s: Probing wdt%u\n", __func__, dev->seq);
	return 0;
}

static const struct wdt_ops omap3_wdt_ops = {
	.start = omap3_wdt_start,
	.stop = omap3_wdt_stop,
	.reset = omap3_wdt_reset,
};

static const struct udevice_id omap3_wdt_ids[] = {
	{ .compatible = "ti,omap3-wdt" },
	{ }
};

U_BOOT_DRIVER(omap3_wdt) = {
	.name = "omap3_wdt",
	.id = UCLASS_WDT,
	.of_match = omap3_wdt_ids,
	.ops = &omap3_wdt_ops,
	.probe = omap3_wdt_probe,
	.priv_auto_alloc_size = sizeof(struct omap3_wdt_priv),
};
#endif /* !CONFIG_IS_ENABLED(WDT) */
