/*
 * linux/include/asm-arm/arch-omap/time.h
 *
 * BRIEF MODULE DESCRIPTION
 * 32kHz timer definition
 *
 * Copyright (C) 2000 RidgeRun, Inc.
 * Author: RidgeRun, Inc.
 *         Greg Lonnon (glonnon@ridgerun.com) or info@ridgerun.com
 *
 *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *  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.,
 *  675 Mass Ave, Cambridge, MA 02139, USA.
 */
#if !defined(__ASM_ARCH_OMAP_TIME_H)
#define __ASM_ARCH_OMAP_TIME_H

#include <asm/arch/hwtimer.h>

#define MPUTICKS_PER_USEC  6

/*
 * This marks the time at which jiffies was last incremented
 * in do_timer().
 */
static unsigned long jiffies_update_mark;

static inline unsigned long __noinstrument do_getmachinecycles()
{
	return 0 - read_mputimer(0);
}

static inline unsigned long __noinstrument machinecycles_to_usecs(unsigned long mputicks)
{
	return (((mputicks<<1) / MPUTICKS_PER_USEC)+1) >> 1;
}

static unsigned long omap1510_gettimeoffset(void)
{
	/* return elapsed usecs since jiffies was last incremented */
	return machinecycles_to_usecs(do_getmachinecycles() -
				      jiffies_update_mark);
}

static void omap1510_timer_interrupt(int irq, 
				     void *dev_id, 
				     struct pt_regs *regs)
{
	do_leds();
	/*
	 * jiffies is incremented by do_timer(), so mark
	 * the time at which this occured. Ideally, this
	 * time should be marked immediately after "jiffies++"
	 * in do_timer(), but no can do since it's generic code.
	 */
	jiffies_update_mark = do_getmachinecycles();
	do_timer(regs);
	do_profile(regs);
}

static inline void setup_timer(void)
{
        // since we don't call request_irq, we must init the structure

	gettimeoffset = omap1510_gettimeoffset;

        timer_irq.handler = omap1510_timer_interrupt;
	timer_irq.flags = SA_INTERRUPT;
#ifdef OMAP1510_USE_32KHZ_TIMER
	setup_arm_irq(INT_OS_32kHz_TIMER, &timer_irq);
#else
	setup_arm_irq(INT_TIMER2, &timer_irq);
        start_mputimer2(MPUTICKS_PER_USEC * 1000 * 10 - 1);
#endif
	timer32k_write(TIMER32k_CR, 0x0);
        timer32k_write(TIMER32k_TVR,TIMER32k_PERIOD);
        start_timer32k();
}

#endif
