/*
 * arch/arm/mach-lpc32xx/timer.c
 *
 * Author: Kevin Wells <kevin.wells@nxp.com>
 *
 * Copyright (C) 2009 - 2010 NXP Semiconductors
 * Copyright (C) 2009 Fontys University of Applied Sciences, Eindhoven
 *                    Ed Schouten <e.schouten@fontys.nl>
 *                    Laurens Timmermans <l.timmermans@fontys.nl>
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/time.h>
#include <linux/err.h>
#include <linux/clockchips.h>

#include <asm/mach/time.h>

#include <mach/hardware.h>
#include <mach/platform.h>
#include "common.h"

static int lpc32xx_clkevt_next_event(unsigned long delta,
    struct clock_event_device *dev)
{
	__raw_writel(LPC32XX_TIMER_CNTR_TCR_RESET,
		LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE));
	__raw_writel(delta, LPC32XX_TIMER_PR(LPC32XX_TIMER0_BASE));
	__raw_writel(LPC32XX_TIMER_CNTR_TCR_EN,
		LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE));

	return 0;
}

static void lpc32xx_clkevt_mode(enum clock_event_mode mode,
    struct clock_event_device *dev)
{
	switch (mode) {
	case CLOCK_EVT_MODE_PERIODIC:
		WARN_ON(1);
		break;

	case CLOCK_EVT_MODE_ONESHOT:
	case CLOCK_EVT_MODE_SHUTDOWN:
		/*
		 * Disable the timer. When using oneshot, we must also
		 * disable the timer to wait for the first call to
		 * set_next_event().
		 */
		__raw_writel(0, LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE));
		break;

	case CLOCK_EVT_MODE_UNUSED:
	case CLOCK_EVT_MODE_RESUME:
		break;
	}
}

static struct clock_event_device lpc32xx_clkevt = {
	.name		= "lpc32xx_clkevt",
	.features	= CLOCK_EVT_FEAT_ONESHOT,
	.rating		= 300,
	.set_next_event	= lpc32xx_clkevt_next_event,
	.set_mode	= lpc32xx_clkevt_mode,
};

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

	/* Clear match */
	__raw_writel(LPC32XX_TIMER_CNTR_MTCH_BIT(0),
		LPC32XX_TIMER_IR(LPC32XX_TIMER0_BASE));

	evt->event_handler(evt);

	return IRQ_HANDLED;
}

static struct irqaction lpc32xx_timer_irq = {
	.name		= "LPC32XX Timer Tick",
	.flags		= IRQF_TIMER | IRQF_IRQPOLL,
	.handler	= lpc32xx_timer_interrupt,
};

/*
 * The clock management driver isn't initialized at this point, so the
 * clocks need to be enabled here manually and then tagged as used in
 * the clock driver initialization
 */
void __init lpc32xx_timer_init(void)
{
	u32 clkrate, pllreg;

	/* Enable timer clock */
	__raw_writel(LPC32XX_CLKPWR_TMRPWMCLK_TIMER0_EN |
		LPC32XX_CLKPWR_TMRPWMCLK_TIMER1_EN,
		LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1);

	/*
	 * The clock driver isn't initialized at this point. So determine if
	 * the SYSCLK is driven from the PLL397 or main oscillator and then use
	 * it to compute the PLL frequency and the PCLK divider to get the base
	 * timer rates. This rate is needed to compute the tick rate.
	 */
	if (clk_is_sysclk_mainosc() != 0)
		clkrate = LPC32XX_MAIN_OSC_FREQ;
	else
		clkrate = 397 * LPC32XX_CLOCK_OSC_FREQ;

	/* Get ARM HCLKPLL register and convert it into a frequency */
	pllreg = __raw_readl(LPC32XX_CLKPWR_HCLKPLL_CTRL) & 0x1FFFF;
	clkrate = clk_get_pllrate_from_reg(clkrate, pllreg);

	/* Get PCLK divider and divide ARM PLL clock by it to get timer rate */
	clkrate = clkrate / clk_get_pclk_div();

	/* Initial timer setup */
	__raw_writel(0, LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE));
	__raw_writel(LPC32XX_TIMER_CNTR_MTCH_BIT(0),
		LPC32XX_TIMER_IR(LPC32XX_TIMER0_BASE));
	__raw_writel(1, LPC32XX_TIMER_MR0(LPC32XX_TIMER0_BASE));
	__raw_writel(LPC32XX_TIMER_CNTR_MCR_MTCH(0) |
		LPC32XX_TIMER_CNTR_MCR_STOP(0) |
		LPC32XX_TIMER_CNTR_MCR_RESET(0),
		LPC32XX_TIMER_MCR(LPC32XX_TIMER0_BASE));

	/* Setup tick interrupt */
	setup_irq(IRQ_LPC32XX_TIMER0, &lpc32xx_timer_irq);

	/* Setup the clockevent structure. */
	lpc32xx_clkevt.cpumask = cpumask_of(0);
	clockevents_config_and_register(&lpc32xx_clkevt, clkrate, 1, -1);

	/* Use timer1 as clock source. */
	__raw_writel(LPC32XX_TIMER_CNTR_TCR_RESET,
		LPC32XX_TIMER_TCR(LPC32XX_TIMER1_BASE));
	__raw_writel(0, LPC32XX_TIMER_PR(LPC32XX_TIMER1_BASE));
	__raw_writel(0, LPC32XX_TIMER_MCR(LPC32XX_TIMER1_BASE));
	__raw_writel(LPC32XX_TIMER_CNTR_TCR_EN,
		LPC32XX_TIMER_TCR(LPC32XX_TIMER1_BASE));

	clocksource_mmio_init(LPC32XX_TIMER_TC(LPC32XX_TIMER1_BASE),
		"lpc32xx_clksrc", clkrate, 300, 32, clocksource_mmio_readl_up);
}
