/*
 * 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 void __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))
		panic("Can't map registers");

	irq = irq_of_parse_and_map(node, 0);
	if (irq <= 0)
		panic("Can't parse IRQ");

	/* 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);

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

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