// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2013 Pengutronix
 * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
 */

#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt

#include <linux/kernel.h>
#include <linux/clocksource.h>
#include <linux/clockchips.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/clk.h>

#define TIMERn_CTRL			0x00
#define TIMERn_CTRL_PRESC(val)			(((val) & 0xf) << 24)
#define TIMERn_CTRL_PRESC_1024			TIMERn_CTRL_PRESC(10)
#define TIMERn_CTRL_CLKSEL(val)			(((val) & 0x3) << 16)
#define TIMERn_CTRL_CLKSEL_PRESCHFPERCLK	TIMERn_CTRL_CLKSEL(0)
#define TIMERn_CTRL_OSMEN			0x00000010
#define TIMERn_CTRL_MODE(val)			(((val) & 0x3) <<  0)
#define TIMERn_CTRL_MODE_UP			TIMERn_CTRL_MODE(0)
#define TIMERn_CTRL_MODE_DOWN			TIMERn_CTRL_MODE(1)

#define TIMERn_CMD			0x04
#define TIMERn_CMD_START			0x00000001
#define TIMERn_CMD_STOP				0x00000002

#define TIMERn_IEN			0x0c
#define TIMERn_IF			0x10
#define TIMERn_IFS			0x14
#define TIMERn_IFC			0x18
#define TIMERn_IRQ_UF				0x00000002

#define TIMERn_TOP			0x1c
#define TIMERn_CNT			0x24

struct efm32_clock_event_ddata {
	struct clock_event_device evtdev;
	void __iomem *base;
	unsigned periodic_top;
};

static int efm32_clock_event_shutdown(struct clock_event_device *evtdev)
{
	struct efm32_clock_event_ddata *ddata =
		container_of(evtdev, struct efm32_clock_event_ddata, evtdev);

	writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD);
	return 0;
}

static int efm32_clock_event_set_oneshot(struct clock_event_device *evtdev)
{
	struct efm32_clock_event_ddata *ddata =
		container_of(evtdev, struct efm32_clock_event_ddata, evtdev);

	writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD);
	writel_relaxed(TIMERn_CTRL_PRESC_1024 |
		       TIMERn_CTRL_CLKSEL_PRESCHFPERCLK |
		       TIMERn_CTRL_OSMEN |
		       TIMERn_CTRL_MODE_DOWN,
		       ddata->base + TIMERn_CTRL);
	return 0;
}

static int efm32_clock_event_set_periodic(struct clock_event_device *evtdev)
{
	struct efm32_clock_event_ddata *ddata =
		container_of(evtdev, struct efm32_clock_event_ddata, evtdev);

	writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD);
	writel_relaxed(ddata->periodic_top, ddata->base + TIMERn_TOP);
	writel_relaxed(TIMERn_CTRL_PRESC_1024 |
		       TIMERn_CTRL_CLKSEL_PRESCHFPERCLK |
		       TIMERn_CTRL_MODE_DOWN,
		       ddata->base + TIMERn_CTRL);
	writel_relaxed(TIMERn_CMD_START, ddata->base + TIMERn_CMD);
	return 0;
}

static int efm32_clock_event_set_next_event(unsigned long evt,
					    struct clock_event_device *evtdev)
{
	struct efm32_clock_event_ddata *ddata =
		container_of(evtdev, struct efm32_clock_event_ddata, evtdev);

	writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD);
	writel_relaxed(evt, ddata->base + TIMERn_CNT);
	writel_relaxed(TIMERn_CMD_START, ddata->base + TIMERn_CMD);

	return 0;
}

static irqreturn_t efm32_clock_event_handler(int irq, void *dev_id)
{
	struct efm32_clock_event_ddata *ddata = dev_id;

	writel_relaxed(TIMERn_IRQ_UF, ddata->base + TIMERn_IFC);

	ddata->evtdev.event_handler(&ddata->evtdev);

	return IRQ_HANDLED;
}

static struct efm32_clock_event_ddata clock_event_ddata = {
	.evtdev = {
		.name = "efm32 clockevent",
		.features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
		.set_state_shutdown = efm32_clock_event_shutdown,
		.set_state_periodic = efm32_clock_event_set_periodic,
		.set_state_oneshot = efm32_clock_event_set_oneshot,
		.set_next_event = efm32_clock_event_set_next_event,
		.rating = 200,
	},
};

static int __init efm32_clocksource_init(struct device_node *np)
{
	struct clk *clk;
	void __iomem *base;
	unsigned long rate;
	int ret;

	clk = of_clk_get(np, 0);
	if (IS_ERR(clk)) {
		ret = PTR_ERR(clk);
		pr_err("failed to get clock for clocksource (%d)\n", ret);
		goto err_clk_get;
	}

	ret = clk_prepare_enable(clk);
	if (ret) {
		pr_err("failed to enable timer clock for clocksource (%d)\n",
		       ret);
		goto err_clk_enable;
	}
	rate = clk_get_rate(clk);

	base = of_iomap(np, 0);
	if (!base) {
		ret = -EADDRNOTAVAIL;
		pr_err("failed to map registers for clocksource\n");
		goto err_iomap;
	}

	writel_relaxed(TIMERn_CTRL_PRESC_1024 |
		       TIMERn_CTRL_CLKSEL_PRESCHFPERCLK |
		       TIMERn_CTRL_MODE_UP, base + TIMERn_CTRL);
	writel_relaxed(TIMERn_CMD_START, base + TIMERn_CMD);

	ret = clocksource_mmio_init(base + TIMERn_CNT, "efm32 timer",
				    DIV_ROUND_CLOSEST(rate, 1024), 200, 16,
				    clocksource_mmio_readl_up);
	if (ret) {
		pr_err("failed to init clocksource (%d)\n", ret);
		goto err_clocksource_init;
	}

	return 0;

err_clocksource_init:

	iounmap(base);
err_iomap:

	clk_disable_unprepare(clk);
err_clk_enable:

	clk_put(clk);
err_clk_get:

	return ret;
}

static int __init efm32_clockevent_init(struct device_node *np)
{
	struct clk *clk;
	void __iomem *base;
	unsigned long rate;
	int irq;
	int ret;

	clk = of_clk_get(np, 0);
	if (IS_ERR(clk)) {
		ret = PTR_ERR(clk);
		pr_err("failed to get clock for clockevent (%d)\n", ret);
		goto err_clk_get;
	}

	ret = clk_prepare_enable(clk);
	if (ret) {
		pr_err("failed to enable timer clock for clockevent (%d)\n",
		       ret);
		goto err_clk_enable;
	}
	rate = clk_get_rate(clk);

	base = of_iomap(np, 0);
	if (!base) {
		ret = -EADDRNOTAVAIL;
		pr_err("failed to map registers for clockevent\n");
		goto err_iomap;
	}

	irq = irq_of_parse_and_map(np, 0);
	if (!irq) {
		ret = -ENOENT;
		pr_err("failed to get irq for clockevent\n");
		goto err_get_irq;
	}

	writel_relaxed(TIMERn_IRQ_UF, base + TIMERn_IEN);

	clock_event_ddata.base = base;
	clock_event_ddata.periodic_top = DIV_ROUND_CLOSEST(rate, 1024 * HZ);

	clockevents_config_and_register(&clock_event_ddata.evtdev,
					DIV_ROUND_CLOSEST(rate, 1024),
					0xf, 0xffff);

	ret = request_irq(irq, efm32_clock_event_handler, IRQF_TIMER,
			  "efm32 clockevent", &clock_event_ddata);
	if (ret) {
		pr_err("Failed setup irq\n");
		goto err_setup_irq;
	}

	return 0;

err_setup_irq:
err_get_irq:

	iounmap(base);
err_iomap:

	clk_disable_unprepare(clk);
err_clk_enable:

	clk_put(clk);
err_clk_get:

	return ret;
}

/*
 * This function asserts that we have exactly one clocksource and one
 * clock_event_device in the end.
 */
static int __init efm32_timer_init(struct device_node *np)
{
	static int has_clocksource, has_clockevent;
	int ret = 0;

	if (!has_clocksource) {
		ret = efm32_clocksource_init(np);
		if (!ret) {
			has_clocksource = 1;
			return 0;
		}
	}

	if (!has_clockevent) {
		ret = efm32_clockevent_init(np);
		if (!ret) {
			has_clockevent = 1;
			return 0;
		}
	}

	return ret;
}
TIMER_OF_DECLARE(efm32compat, "efm32,timer", efm32_timer_init);
TIMER_OF_DECLARE(efm32, "energymicro,efm32-timer", efm32_timer_init);
