/*
 * Copyright 2012-2013 Freescale Semiconductor, Inc.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 */

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

/*
 * Each pit takes 0x10 Bytes register space
 */
#define PITMCR		0x00
#define PIT0_OFFSET	0x100
#define PITn_OFFSET(n)	(PIT0_OFFSET + 0x10 * (n))
#define PITLDVAL	0x00
#define PITCVAL		0x04
#define PITTCTRL	0x08
#define PITTFLG		0x0c

#define PITMCR_MDIS	(0x1 << 1)

#define PITTCTRL_TEN	(0x1 << 0)
#define PITTCTRL_TIE	(0x1 << 1)
#define PITCTRL_CHN	(0x1 << 2)

#define PITTFLG_TIF	0x1

static void __iomem *clksrc_base;
static void __iomem *clkevt_base;
static unsigned long cycle_per_jiffy;

static inline void pit_timer_enable(void)
{
	__raw_writel(PITTCTRL_TEN | PITTCTRL_TIE, clkevt_base + PITTCTRL);
}

static inline void pit_timer_disable(void)
{
	__raw_writel(0, clkevt_base + PITTCTRL);
}

static inline void pit_irq_acknowledge(void)
{
	__raw_writel(PITTFLG_TIF, clkevt_base + PITTFLG);
}

static u64 pit_read_sched_clock(void)
{
	return __raw_readl(clksrc_base + PITCVAL);
}

static int __init pit_clocksource_init(unsigned long rate)
{
	/* set the max load value and start the clock source counter */
	__raw_writel(0, clksrc_base + PITTCTRL);
	__raw_writel(~0UL, clksrc_base + PITLDVAL);
	__raw_writel(PITTCTRL_TEN, clksrc_base + PITTCTRL);

	sched_clock_register(pit_read_sched_clock, 32, rate);
	return clocksource_mmio_init(clksrc_base + PITCVAL, "vf-pit", rate,
			300, 32, clocksource_mmio_readl_down);
}

static int pit_set_next_event(unsigned long delta,
				struct clock_event_device *unused)
{
	/*
	 * set a new value to PITLDVAL register will not restart the timer,
	 * to abort the current cycle and start a timer period with the new
	 * value, the timer must be disabled and enabled again.
	 * and the PITLAVAL should be set to delta minus one according to pit
	 * hardware requirement.
	 */
	pit_timer_disable();
	__raw_writel(delta - 1, clkevt_base + PITLDVAL);
	pit_timer_enable();

	return 0;
}

static void pit_set_mode(enum clock_event_mode mode,
				struct clock_event_device *evt)
{
	switch (mode) {
	case CLOCK_EVT_MODE_PERIODIC:
		pit_set_next_event(cycle_per_jiffy, evt);
		break;
	default:
		break;
	}
}

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

	pit_irq_acknowledge();

	/*
	 * pit hardware doesn't support oneshot, it will generate an interrupt
	 * and reload the counter value from PITLDVAL when PITCVAL reach zero,
	 * and start the counter again. So software need to disable the timer
	 * to stop the counter loop in ONESHOT mode.
	 */
	if (likely(evt->mode == CLOCK_EVT_MODE_ONESHOT))
		pit_timer_disable();

	evt->event_handler(evt);

	return IRQ_HANDLED;
}

static struct clock_event_device clockevent_pit = {
	.name		= "VF pit timer",
	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
	.set_mode	= pit_set_mode,
	.set_next_event	= pit_set_next_event,
	.rating		= 300,
};

static struct irqaction pit_timer_irq = {
	.name		= "VF pit timer",
	.flags		= IRQF_TIMER | IRQF_IRQPOLL,
	.handler	= pit_timer_interrupt,
	.dev_id		= &clockevent_pit,
};

static int __init pit_clockevent_init(unsigned long rate, int irq)
{
	__raw_writel(0, clkevt_base + PITTCTRL);
	__raw_writel(PITTFLG_TIF, clkevt_base + PITTFLG);

	BUG_ON(setup_irq(irq, &pit_timer_irq));

	clockevent_pit.cpumask = cpumask_of(0);
	clockevent_pit.irq = irq;
	/*
	 * The value for the LDVAL register trigger is calculated as:
	 * LDVAL trigger = (period / clock period) - 1
	 * The pit is a 32-bit down count timer, when the conter value
	 * reaches 0, it will generate an interrupt, thus the minimal
	 * LDVAL trigger value is 1. And then the min_delta is
	 * minimal LDVAL trigger value + 1, and the max_delta is full 32-bit.
	 */
	clockevents_config_and_register(&clockevent_pit, rate, 2, 0xffffffff);

	return 0;
}

static void __init pit_timer_init(struct device_node *np)
{
	struct clk *pit_clk;
	void __iomem *timer_base;
	unsigned long clk_rate;
	int irq;

	timer_base = of_iomap(np, 0);
	BUG_ON(!timer_base);

	/*
	 * PIT0 and PIT1 can be chained to build a 64-bit timer,
	 * so choose PIT2 as clocksource, PIT3 as clockevent device,
	 * and leave PIT0 and PIT1 unused for anyone else who needs them.
	 */
	clksrc_base = timer_base + PITn_OFFSET(2);
	clkevt_base = timer_base + PITn_OFFSET(3);

	irq = irq_of_parse_and_map(np, 0);
	BUG_ON(irq <= 0);

	pit_clk = of_clk_get(np, 0);
	BUG_ON(IS_ERR(pit_clk));

	BUG_ON(clk_prepare_enable(pit_clk));

	clk_rate = clk_get_rate(pit_clk);
	cycle_per_jiffy = clk_rate / (HZ);

	/* enable the pit module */
	__raw_writel(~PITMCR_MDIS, timer_base + PITMCR);

	BUG_ON(pit_clocksource_init(clk_rate));

	pit_clockevent_init(clk_rate, irq);
}
CLOCKSOURCE_OF_DECLARE(vf610, "fsl,vf610-pit", pit_timer_init);
