// SPDX-License-Identifier: GPL-2.0-only
/*
 * watchdog driver for ZTE's zx2967 family
 *
 * Copyright (C) 2017 ZTE Ltd.
 *
 * Author: Baoyou Xie <baoyou.xie@linaro.org>
 */

#include <linux/clk.h>
#include <linux/io.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/watchdog.h>

#define ZX2967_WDT_CFG_REG			0x4
#define ZX2967_WDT_LOAD_REG			0x8
#define ZX2967_WDT_REFRESH_REG			0x18
#define ZX2967_WDT_START_REG			0x1c

#define ZX2967_WDT_REFRESH_MASK			GENMASK(5, 0)

#define ZX2967_WDT_CFG_DIV(n)			((((n) & 0xff) - 1) << 8)
#define ZX2967_WDT_START_EN			0x1

/*
 * Hardware magic number.
 * When watchdog reg is written, the lowest 16 bits are valid, but
 * the highest 16 bits should be always this number.
 */
#define ZX2967_WDT_WRITEKEY			(0x1234 << 16)
#define ZX2967_WDT_VAL_MASK			GENMASK(15, 0)

#define ZX2967_WDT_DIV_DEFAULT			16
#define ZX2967_WDT_DEFAULT_TIMEOUT		32
#define ZX2967_WDT_MIN_TIMEOUT			1
#define ZX2967_WDT_MAX_TIMEOUT			524
#define ZX2967_WDT_MAX_COUNT			0xffff

#define ZX2967_WDT_CLK_FREQ			0x8000

#define ZX2967_WDT_FLAG_REBOOT_MON		BIT(0)

struct zx2967_wdt {
	struct watchdog_device	wdt_device;
	void __iomem		*reg_base;
	struct clk		*clock;
};

static inline u32 zx2967_wdt_readl(struct zx2967_wdt *wdt, u16 reg)
{
	return readl_relaxed(wdt->reg_base + reg);
}

static inline void zx2967_wdt_writel(struct zx2967_wdt *wdt, u16 reg, u32 val)
{
	writel_relaxed(val | ZX2967_WDT_WRITEKEY, wdt->reg_base + reg);
}

static void zx2967_wdt_refresh(struct zx2967_wdt *wdt)
{
	u32 val;

	val = zx2967_wdt_readl(wdt, ZX2967_WDT_REFRESH_REG);
	/*
	 * Bit 4-5, 1 and 2: refresh config info
	 * Bit 2-3, 1 and 2: refresh counter
	 * Bit 0-1, 1 and 2: refresh int-value
	 * we shift each group value between 1 and 2 to refresh all data.
	 */
	val ^= ZX2967_WDT_REFRESH_MASK;
	zx2967_wdt_writel(wdt, ZX2967_WDT_REFRESH_REG,
			  val & ZX2967_WDT_VAL_MASK);
}

static int
zx2967_wdt_set_timeout(struct watchdog_device *wdd, unsigned int timeout)
{
	struct zx2967_wdt *wdt = watchdog_get_drvdata(wdd);
	unsigned int divisor = ZX2967_WDT_DIV_DEFAULT;
	u32 count;

	count = timeout * ZX2967_WDT_CLK_FREQ;
	if (count > divisor * ZX2967_WDT_MAX_COUNT)
		divisor = DIV_ROUND_UP(count, ZX2967_WDT_MAX_COUNT);
	count = DIV_ROUND_UP(count, divisor);
	zx2967_wdt_writel(wdt, ZX2967_WDT_CFG_REG,
			ZX2967_WDT_CFG_DIV(divisor) & ZX2967_WDT_VAL_MASK);
	zx2967_wdt_writel(wdt, ZX2967_WDT_LOAD_REG,
			count & ZX2967_WDT_VAL_MASK);
	zx2967_wdt_refresh(wdt);
	wdd->timeout =  (count * divisor) / ZX2967_WDT_CLK_FREQ;

	return 0;
}

static void __zx2967_wdt_start(struct zx2967_wdt *wdt)
{
	u32 val;

	val = zx2967_wdt_readl(wdt, ZX2967_WDT_START_REG);
	val |= ZX2967_WDT_START_EN;
	zx2967_wdt_writel(wdt, ZX2967_WDT_START_REG,
			val & ZX2967_WDT_VAL_MASK);
}

static void __zx2967_wdt_stop(struct zx2967_wdt *wdt)
{
	u32 val;

	val = zx2967_wdt_readl(wdt, ZX2967_WDT_START_REG);
	val &= ~ZX2967_WDT_START_EN;
	zx2967_wdt_writel(wdt, ZX2967_WDT_START_REG,
			val & ZX2967_WDT_VAL_MASK);
}

static int zx2967_wdt_start(struct watchdog_device *wdd)
{
	struct zx2967_wdt *wdt = watchdog_get_drvdata(wdd);

	zx2967_wdt_set_timeout(wdd, wdd->timeout);
	__zx2967_wdt_start(wdt);

	return 0;
}

static int zx2967_wdt_stop(struct watchdog_device *wdd)
{
	struct zx2967_wdt *wdt = watchdog_get_drvdata(wdd);

	__zx2967_wdt_stop(wdt);

	return 0;
}

static int zx2967_wdt_keepalive(struct watchdog_device *wdd)
{
	struct zx2967_wdt *wdt = watchdog_get_drvdata(wdd);

	zx2967_wdt_refresh(wdt);

	return 0;
}

#define ZX2967_WDT_OPTIONS \
	(WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE)
static const struct watchdog_info zx2967_wdt_ident = {
	.options          =     ZX2967_WDT_OPTIONS,
	.identity         =	"zx2967 watchdog",
};

static const struct watchdog_ops zx2967_wdt_ops = {
	.owner = THIS_MODULE,
	.start = zx2967_wdt_start,
	.stop = zx2967_wdt_stop,
	.ping = zx2967_wdt_keepalive,
	.set_timeout = zx2967_wdt_set_timeout,
};

static void zx2967_wdt_reset_sysctrl(struct device *dev)
{
	int ret;
	void __iomem *regmap;
	unsigned int offset, mask, config;
	struct of_phandle_args out_args;

	ret = of_parse_phandle_with_fixed_args(dev->of_node,
			"zte,wdt-reset-sysctrl", 3, 0, &out_args);
	if (ret)
		return;

	offset = out_args.args[0];
	config = out_args.args[1];
	mask = out_args.args[2];

	regmap = syscon_node_to_regmap(out_args.np);
	if (IS_ERR(regmap)) {
		of_node_put(out_args.np);
		return;
	}

	regmap_update_bits(regmap, offset, mask, config);
	of_node_put(out_args.np);
}

static void zx2967_clk_disable_unprepare(void *data)
{
	clk_disable_unprepare(data);
}

static int zx2967_wdt_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct zx2967_wdt *wdt;
	int ret;
	struct reset_control *rstc;

	wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
	if (!wdt)
		return -ENOMEM;

	platform_set_drvdata(pdev, wdt);

	wdt->wdt_device.info = &zx2967_wdt_ident;
	wdt->wdt_device.ops = &zx2967_wdt_ops;
	wdt->wdt_device.timeout = ZX2967_WDT_DEFAULT_TIMEOUT;
	wdt->wdt_device.max_timeout = ZX2967_WDT_MAX_TIMEOUT;
	wdt->wdt_device.min_timeout = ZX2967_WDT_MIN_TIMEOUT;
	wdt->wdt_device.parent = dev;

	wdt->reg_base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(wdt->reg_base))
		return PTR_ERR(wdt->reg_base);

	zx2967_wdt_reset_sysctrl(dev);

	wdt->clock = devm_clk_get(dev, NULL);
	if (IS_ERR(wdt->clock)) {
		dev_err(dev, "failed to find watchdog clock source\n");
		return PTR_ERR(wdt->clock);
	}

	ret = clk_prepare_enable(wdt->clock);
	if (ret < 0) {
		dev_err(dev, "failed to enable clock\n");
		return ret;
	}
	ret = devm_add_action_or_reset(dev, zx2967_clk_disable_unprepare,
				       wdt->clock);
	if (ret)
		return ret;
	clk_set_rate(wdt->clock, ZX2967_WDT_CLK_FREQ);

	rstc = devm_reset_control_get_exclusive(dev, NULL);
	if (IS_ERR(rstc)) {
		dev_err(dev, "failed to get rstc");
		return PTR_ERR(rstc);
	}

	reset_control_assert(rstc);
	reset_control_deassert(rstc);

	watchdog_set_drvdata(&wdt->wdt_device, wdt);
	watchdog_init_timeout(&wdt->wdt_device,
			ZX2967_WDT_DEFAULT_TIMEOUT, dev);
	watchdog_set_nowayout(&wdt->wdt_device, WATCHDOG_NOWAYOUT);

	ret = devm_watchdog_register_device(dev, &wdt->wdt_device);
	if (ret)
		return ret;

	dev_info(dev, "watchdog enabled (timeout=%d sec, nowayout=%d)",
		 wdt->wdt_device.timeout, WATCHDOG_NOWAYOUT);

	return 0;
}

static const struct of_device_id zx2967_wdt_match[] = {
	{ .compatible = "zte,zx296718-wdt", },
	{}
};
MODULE_DEVICE_TABLE(of, zx2967_wdt_match);

static struct platform_driver zx2967_wdt_driver = {
	.probe		= zx2967_wdt_probe,
	.driver		= {
		.name	= "zx2967-wdt",
		.of_match_table	= of_match_ptr(zx2967_wdt_match),
	},
};
module_platform_driver(zx2967_wdt_driver);

MODULE_AUTHOR("Baoyou Xie <baoyou.xie@linaro.org>");
MODULE_DESCRIPTION("ZTE zx2967 Watchdog Device Driver");
MODULE_LICENSE("GPL v2");
