/*
 * Copyright (C) 2013 Pengutronix
 * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License version 2 as published by the
 * Free Software Foundation.
 */

#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 struct irqaction efm32_clock_event_irq = {
	.name = "efm32 clockevent",
	.flags = IRQF_TIMER,
	.handler = efm32_clock_event_handler,
	.dev_id = &clock_event_ddata,
};

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 = setup_irq(irq, &efm32_clock_event_irq);
	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);
