/*
 * Amlogic Meson6 SoCs timer handling.
 *
 * Copyright (C) 2014 Carlo Caione <carlo@caione.org>
 *
 * Based on code from Amlogic, Inc
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2.  This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */

#include <linux/clk.h>
#include <linux/clockchips.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/irqreturn.h>
#include <linux/sched_clock.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>

#define CED_ID			0
#define CSD_ID			4

#define TIMER_ISA_MUX		0
#define TIMER_ISA_VAL(t)	(((t) + 1) << 2)

#define TIMER_INPUT_BIT(t)	(2 * (t))
#define TIMER_ENABLE_BIT(t)	(16 + (t))
#define TIMER_PERIODIC_BIT(t)	(12 + (t))

#define TIMER_CED_INPUT_MASK	(3UL << TIMER_INPUT_BIT(CED_ID))
#define TIMER_CSD_INPUT_MASK	(7UL << TIMER_INPUT_BIT(CSD_ID))

#define TIMER_CED_UNIT_1US	0
#define TIMER_CSD_UNIT_1US	1

static void __iomem *timer_base;

static u64 notrace meson6_timer_sched_read(void)
{
	return (u64)readl(timer_base + TIMER_ISA_VAL(CSD_ID));
}

static void meson6_clkevt_time_stop(unsigned char timer)
{
	u32 val = readl(timer_base + TIMER_ISA_MUX);

	writel(val & ~TIMER_ENABLE_BIT(timer), timer_base + TIMER_ISA_MUX);
}

static void meson6_clkevt_time_setup(unsigned char timer, unsigned long delay)
{
	writel(delay, timer_base + TIMER_ISA_VAL(timer));
}

static void meson6_clkevt_time_start(unsigned char timer, bool periodic)
{
	u32 val = readl(timer_base + TIMER_ISA_MUX);

	if (periodic)
		val |= TIMER_PERIODIC_BIT(timer);
	else
		val &= ~TIMER_PERIODIC_BIT(timer);

	writel(val | TIMER_ENABLE_BIT(timer), timer_base + TIMER_ISA_MUX);
}

static int meson6_shutdown(struct clock_event_device *evt)
{
	meson6_clkevt_time_stop(CED_ID);
	return 0;
}

static int meson6_set_oneshot(struct clock_event_device *evt)
{
	meson6_clkevt_time_stop(CED_ID);
	meson6_clkevt_time_start(CED_ID, false);
	return 0;
}

static int meson6_set_periodic(struct clock_event_device *evt)
{
	meson6_clkevt_time_stop(CED_ID);
	meson6_clkevt_time_setup(CED_ID, USEC_PER_SEC / HZ - 1);
	meson6_clkevt_time_start(CED_ID, true);
	return 0;
}

static int meson6_clkevt_next_event(unsigned long evt,
				    struct clock_event_device *unused)
{
	meson6_clkevt_time_stop(CED_ID);
	meson6_clkevt_time_setup(CED_ID, evt);
	meson6_clkevt_time_start(CED_ID, false);

	return 0;
}

static struct clock_event_device meson6_clockevent = {
	.name			= "meson6_tick",
	.rating			= 400,
	.features		= CLOCK_EVT_FEAT_PERIODIC |
				  CLOCK_EVT_FEAT_ONESHOT,
	.set_state_shutdown	= meson6_shutdown,
	.set_state_periodic	= meson6_set_periodic,
	.set_state_oneshot	= meson6_set_oneshot,
	.tick_resume		= meson6_shutdown,
	.set_next_event		= meson6_clkevt_next_event,
};

static irqreturn_t meson6_timer_interrupt(int irq, void *dev_id)
{
	struct clock_event_device *evt = (struct clock_event_device *)dev_id;

	evt->event_handler(evt);

	return IRQ_HANDLED;
}

static struct irqaction meson6_timer_irq = {
	.name		= "meson6_timer",
	.flags		= IRQF_TIMER | IRQF_IRQPOLL,
	.handler	= meson6_timer_interrupt,
	.dev_id		= &meson6_clockevent,
};

static int __init meson6_timer_init(struct device_node *node)
{
	u32 val;
	int ret, irq;

	timer_base = of_io_request_and_map(node, 0, "meson6-timer");
	if (IS_ERR(timer_base)) {
		pr_err("Can't map registers\n");
		return -ENXIO;
	}

	irq = irq_of_parse_and_map(node, 0);
	if (irq <= 0) {
		pr_err("Can't parse IRQ\n");
		return -EINVAL;
	}

	/* Set 1us for timer E */
	val = readl(timer_base + TIMER_ISA_MUX);
	val &= ~TIMER_CSD_INPUT_MASK;
	val |= TIMER_CSD_UNIT_1US << TIMER_INPUT_BIT(CSD_ID);
	writel(val, timer_base + TIMER_ISA_MUX);

	sched_clock_register(meson6_timer_sched_read, 32, USEC_PER_SEC);
	clocksource_mmio_init(timer_base + TIMER_ISA_VAL(CSD_ID), node->name,
			      1000 * 1000, 300, 32, clocksource_mmio_readl_up);

	/* Timer A base 1us */
	val &= ~TIMER_CED_INPUT_MASK;
	val |= TIMER_CED_UNIT_1US << TIMER_INPUT_BIT(CED_ID);
	writel(val, timer_base + TIMER_ISA_MUX);

	/* Stop the timer A */
	meson6_clkevt_time_stop(CED_ID);

	ret = setup_irq(irq, &meson6_timer_irq);
	if (ret) {
		pr_warn("failed to setup irq %d\n", irq);
		return ret;
	}

	meson6_clockevent.cpumask = cpu_possible_mask;
	meson6_clockevent.irq = irq;

	clockevents_config_and_register(&meson6_clockevent, USEC_PER_SEC,
					1, 0xfffe);
	return 0;
}
TIMER_OF_DECLARE(meson6, "amlogic,meson6-timer",
		       meson6_timer_init);
