/*
 * arch/arm/mach-pxa/time.c
 *
 * PXA clocksource, clockevents, and OST interrupt handlers.
 * Copyright (c) 2007 by Bill Gatliff <bgat@billgatliff.com>.
 *
 * Derived from Nicolas Pitre's PXA timer handler Copyright (c) 2001
 * by MontaVista Software, Inc.  (Nico, your code rocks!)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/clockchips.h>

#include <asm/mach/irq.h>
#include <asm/mach/time.h>
#include <asm/arch/pxa-regs.h>

static irqreturn_t
pxa_ost0_interrupt(int irq, void *dev_id)
{
	int next_match;
	struct clock_event_device *c = dev_id;

	if (c->mode == CLOCK_EVT_MODE_ONESHOT) {
		/* Disarm the compare/match, signal the event. */
		OIER &= ~OIER_E0;
		c->event_handler(c);
	} else if (c->mode == CLOCK_EVT_MODE_PERIODIC) {
		/* Call the event handler as many times as necessary
		 * to recover missed events, if any (if we update
		 * OSMR0 and OSCR0 is still ahead of us, we've missed
		 * the event).  As we're dealing with that, re-arm the
		 * compare/match for the next event.
		 *
		 * HACK ALERT:
		 *
		 * There's a latency between the instruction that
		 * writes to OSMR0 and the actual commit to the
		 * physical hardware, because the CPU doesn't (have
		 * to) run at bus speed, there's a write buffer
		 * between the CPU and the bus, etc. etc.  So if the
		 * target OSCR0 is "very close", to the OSMR0 load
		 * value, the update to OSMR0 might not get to the
		 * hardware in time and we'll miss that interrupt.
		 *
		 * To be safe, if the new OSMR0 is "very close" to the
		 * target OSCR0 value, we call the event_handler as
		 * though the event actually happened.  According to
		 * Nico's comment in the previous version of this
		 * code, experience has shown that 6 OSCR ticks is
		 * "very close" but he went with 8.  We will use 16,
		 * based on the results of testing on PXA270.
		 *
		 * To be doubly sure, we also tell clkevt via
		 * clockevents_register_device() not to ask for
		 * anything that might put us "very close".
	 */
#define MIN_OSCR_DELTA 16
	do {
			OSSR = OSSR_M0;
		next_match = (OSMR0 += LATCH);
			c->event_handler(c);
		} while (((signed long)(next_match - OSCR) <= MIN_OSCR_DELTA)
			 && (c->mode == CLOCK_EVT_MODE_PERIODIC));
	}

	return IRQ_HANDLED;
}

static int
pxa_osmr0_set_next_event(unsigned long delta, struct clock_event_device *dev)
{
	unsigned long irqflags;

	raw_local_irq_save(irqflags);
	OSMR0 = OSCR + delta;
	OSSR = OSSR_M0;
	OIER |= OIER_E0;
	raw_local_irq_restore(irqflags);
	return 0;
}

static void
pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
{
	unsigned long irqflags;

	switch (mode) {
	case CLOCK_EVT_MODE_PERIODIC:
		raw_local_irq_save(irqflags);
		OSMR0 = OSCR + LATCH;
		OSSR = OSSR_M0;
		OIER |= OIER_E0;
		raw_local_irq_restore(irqflags);
		break;

	case CLOCK_EVT_MODE_ONESHOT:
		raw_local_irq_save(irqflags);
		OIER &= ~OIER_E0;
		raw_local_irq_restore(irqflags);
		break;

	case CLOCK_EVT_MODE_UNUSED:
	case CLOCK_EVT_MODE_SHUTDOWN:
		/* initializing, released, or preparing for suspend */
		raw_local_irq_save(irqflags);
		OIER &= ~OIER_E0;
		raw_local_irq_restore(irqflags);
		break;
	}
}

static struct clock_event_device ckevt_pxa_osmr0 = {
	.name		= "osmr0",
	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
	.shift		= 32,
	.rating		= 200,
	.cpumask	= CPU_MASK_CPU0,
	.set_next_event	= pxa_osmr0_set_next_event,
	.set_mode	= pxa_osmr0_set_mode,
};

static cycle_t pxa_read_oscr(void)
{
	return OSCR;
}

static struct clocksource cksrc_pxa_oscr0 = {
	.name           = "oscr0",
	.rating         = 200,
	.read           = pxa_read_oscr,
	.mask           = CLOCKSOURCE_MASK(32),
	.shift          = 20,
	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
};

static struct irqaction pxa_ost0_irq = {
	.name		= "ost0",
	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
	.handler	= pxa_ost0_interrupt,
	.dev_id		= &ckevt_pxa_osmr0,
};

static void __init pxa_timer_init(void)
{
	OIER = 0;
	OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3;

	ckevt_pxa_osmr0.mult =
		div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, ckevt_pxa_osmr0.shift);
	ckevt_pxa_osmr0.max_delta_ns =
		clockevent_delta2ns(0x7fffffff, &ckevt_pxa_osmr0);
	ckevt_pxa_osmr0.min_delta_ns =
		clockevent_delta2ns(MIN_OSCR_DELTA, &ckevt_pxa_osmr0) + 1;

	cksrc_pxa_oscr0.mult =
		clocksource_hz2mult(CLOCK_TICK_RATE, cksrc_pxa_oscr0.shift);

	setup_irq(IRQ_OST0, &pxa_ost0_irq);

	clocksource_register(&cksrc_pxa_oscr0);
	clockevents_register_device(&ckevt_pxa_osmr0);
}

#ifdef CONFIG_PM
static unsigned long osmr[4], oier;

static void pxa_timer_suspend(void)
{
	osmr[0] = OSMR0;
	osmr[1] = OSMR1;
	osmr[2] = OSMR2;
	osmr[3] = OSMR3;
	oier = OIER;
}

static void pxa_timer_resume(void)
{
	OSMR0 = osmr[0];
	OSMR1 = osmr[1];
	OSMR2 = osmr[2];
	OSMR3 = osmr[3];
	OIER = oier;

	/*
	 * OSCR0 is the system timer, which has to increase
	 * monotonically until it rolls over in hardware.  The value
	 * (OSMR0 - LATCH) is OSCR0 at the most recent system tick,
	 * which is a handy value to restore to OSCR0.
	 */
	OSCR = OSMR0 - LATCH;
}
#else
#define pxa_timer_suspend NULL
#define pxa_timer_resume NULL
#endif

struct sys_timer pxa_timer = {
	.init		= pxa_timer_init,
	.suspend	= pxa_timer_suspend,
	.resume		= pxa_timer_resume,
};
