/*
 *  linux/arch/arm/plat-mxc/epit.c
 *
 *  Copyright (C) 2010 Sascha Hauer <s.hauer@pengutronix.de>
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 */

#define EPITCR		0x00
#define EPITSR		0x04
#define EPITLR		0x08
#define EPITCMPR	0x0c
#define EPITCNR		0x10

#define EPITCR_EN			(1 << 0)
#define EPITCR_ENMOD			(1 << 1)
#define EPITCR_OCIEN			(1 << 2)
#define EPITCR_RLD			(1 << 3)
#define EPITCR_PRESC(x)			(((x) & 0xfff) << 4)
#define EPITCR_SWR			(1 << 16)
#define EPITCR_IOVW			(1 << 17)
#define EPITCR_DBGEN			(1 << 18)
#define EPITCR_WAITEN			(1 << 19)
#define EPITCR_RES			(1 << 20)
#define EPITCR_STOPEN			(1 << 21)
#define EPITCR_OM_DISCON		(0 << 22)
#define EPITCR_OM_TOGGLE		(1 << 22)
#define EPITCR_OM_CLEAR			(2 << 22)
#define EPITCR_OM_SET			(3 << 22)
#define EPITCR_CLKSRC_OFF		(0 << 24)
#define EPITCR_CLKSRC_PERIPHERAL	(1 << 24)
#define EPITCR_CLKSRC_REF_HIGH		(1 << 24)
#define EPITCR_CLKSRC_REF_LOW		(3 << 24)

#define EPITSR_OCIF			(1 << 0)

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

#include <mach/hardware.h>
#include <asm/mach/time.h>
#include <mach/common.h>

static struct clock_event_device clockevent_epit;
static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;

static void __iomem *timer_base;

static inline void epit_irq_disable(void)
{
	u32 val;

	val = __raw_readl(timer_base + EPITCR);
	val &= ~EPITCR_OCIEN;
	__raw_writel(val, timer_base + EPITCR);
}

static inline void epit_irq_enable(void)
{
	u32 val;

	val = __raw_readl(timer_base + EPITCR);
	val |= EPITCR_OCIEN;
	__raw_writel(val, timer_base + EPITCR);
}

static void epit_irq_acknowledge(void)
{
	__raw_writel(EPITSR_OCIF, timer_base + EPITSR);
}

static int __init epit_clocksource_init(struct clk *timer_clk)
{
	unsigned int c = clk_get_rate(timer_clk);

	return clocksource_mmio_init(timer_base + EPITCNR, "epit", c, 200, 32,
			clocksource_mmio_readl_down);
}

/* clock event */

static int epit_set_next_event(unsigned long evt,
			      struct clock_event_device *unused)
{
	unsigned long tcmp;

	tcmp = __raw_readl(timer_base + EPITCNR);

	__raw_writel(tcmp - evt, timer_base + EPITCMPR);

	return 0;
}

static void epit_set_mode(enum clock_event_mode mode,
				struct clock_event_device *evt)
{
	unsigned long flags;

	/*
	 * The timer interrupt generation is disabled at least
	 * for enough time to call epit_set_next_event()
	 */
	local_irq_save(flags);

	/* Disable interrupt in GPT module */
	epit_irq_disable();

	if (mode != clockevent_mode) {
		/* Set event time into far-far future */

		/* Clear pending interrupt */
		epit_irq_acknowledge();
	}

	/* Remember timer mode */
	clockevent_mode = mode;
	local_irq_restore(flags);

	switch (mode) {
	case CLOCK_EVT_MODE_PERIODIC:
		printk(KERN_ERR "epit_set_mode: Periodic mode is not "
				"supported for i.MX EPIT\n");
		break;
	case CLOCK_EVT_MODE_ONESHOT:
	/*
	 * Do not put overhead of interrupt enable/disable into
	 * epit_set_next_event(), the core has about 4 minutes
	 * to call epit_set_next_event() or shutdown clock after
	 * mode switching
	 */
		local_irq_save(flags);
		epit_irq_enable();
		local_irq_restore(flags);
		break;
	case CLOCK_EVT_MODE_SHUTDOWN:
	case CLOCK_EVT_MODE_UNUSED:
	case CLOCK_EVT_MODE_RESUME:
		/* Left event sources disabled, no more interrupts appear */
		break;
	}
}

/*
 * IRQ handler for the timer
 */
static irqreturn_t epit_timer_interrupt(int irq, void *dev_id)
{
	struct clock_event_device *evt = &clockevent_epit;

	epit_irq_acknowledge();

	evt->event_handler(evt);

	return IRQ_HANDLED;
}

static struct irqaction epit_timer_irq = {
	.name		= "i.MX EPIT Timer Tick",
	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
	.handler	= epit_timer_interrupt,
};

static struct clock_event_device clockevent_epit = {
	.name		= "epit",
	.features	= CLOCK_EVT_FEAT_ONESHOT,
	.shift		= 32,
	.set_mode	= epit_set_mode,
	.set_next_event	= epit_set_next_event,
	.rating		= 200,
};

static int __init epit_clockevent_init(struct clk *timer_clk)
{
	unsigned int c = clk_get_rate(timer_clk);

	clockevent_epit.mult = div_sc(c, NSEC_PER_SEC,
					clockevent_epit.shift);
	clockevent_epit.max_delta_ns =
			clockevent_delta2ns(0xfffffffe, &clockevent_epit);
	clockevent_epit.min_delta_ns =
			clockevent_delta2ns(0x800, &clockevent_epit);

	clockevent_epit.cpumask = cpumask_of(0);

	clockevents_register_device(&clockevent_epit);

	return 0;
}

void __init epit_timer_init(void __iomem *base, int irq)
{
	struct clk *timer_clk;

	timer_clk = clk_get_sys("imx-epit.0", NULL);
	if (IS_ERR(timer_clk)) {
		pr_err("i.MX epit: unable to get clk\n");
		return;
	}

	clk_prepare_enable(timer_clk);

	timer_base = base;

	/*
	 * Initialise to a known state (all timers off, and timing reset)
	 */
	__raw_writel(0x0, timer_base + EPITCR);

	__raw_writel(0xffffffff, timer_base + EPITLR);
	__raw_writel(EPITCR_EN | EPITCR_CLKSRC_REF_HIGH | EPITCR_WAITEN,
			timer_base + EPITCR);

	/* init and register the timer to the framework */
	epit_clocksource_init(timer_clk);
	epit_clockevent_init(timer_clk);

	/* Make irqs happen */
	setup_irq(irq, &epit_timer_irq);
}
