/*
 * (C) Copyright 2002
 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 * Marius Groeger <mgroeger@sysgo.de>
 *
 * (C) Copyright 2002
 * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
 *
 * (C) Copyright 2003
 * Texas Instruments, <www.ti.com>
 * Kshitij Gupta <Kshitij@ti.com>
 *
 * (C) Copyright 2004
 * ARM Ltd.
 * Philippe Robin, <philippe.robin@arm.com>
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <common.h>
#include <div64.h>

#ifdef CONFIG_ARCH_CINTEGRATOR
#define DIV_CLOCK_INIT	1
#define TIMER_LOAD_VAL	0xFFFFFFFFL
#else
#define DIV_CLOCK_INIT	256
#define TIMER_LOAD_VAL	0x0000FFFFL
#endif
/* The Integrator/CP timer1 is clocked at 1MHz
 * can be divided by 16 or 256
 * and can be set up as a 32-bit timer
 */
/* U-Boot expects a 32 bit timer, running at CONFIG_SYS_HZ */
/* Keep total timer count to avoid losing decrements < div_timer */
static unsigned long long total_count = 0;
static unsigned long long lastdec;	 /* Timer reading at last call	   */
/* Divisor applied to timer clock */
static unsigned long long div_clock = DIV_CLOCK_INIT;
static unsigned long long div_timer = 1; /* Divisor to convert timer reading
					  * change to U-Boot ticks
					  */
/* CONFIG_SYS_HZ = CONFIG_SYS_HZ_CLOCK/(div_clock * div_timer) */
static ulong timestamp;		/* U-Boot ticks since startup */

#define READ_TIMER (*(volatile ulong *)(CONFIG_SYS_TIMERBASE+4))

/* all function return values in U-Boot ticks i.e. (1/CONFIG_SYS_HZ) sec
 *  - unless otherwise stated
 */

/* starts up a counter
 * - the Integrator/CP timer can be set up to issue an interrupt */
int timer_init (void)
{
	/* Load timer with initial value */
	*(volatile ulong *)(CONFIG_SYS_TIMERBASE + 0) = TIMER_LOAD_VAL;
#ifdef CONFIG_ARCH_CINTEGRATOR
	/* Set timer to be
	 *	enabled		 1
	 *	periodic	 1
	 *	no interrupts	 0
	 *	X		 0
	 *	divider 1	00 == less rounding error
	 *	32 bit		 1
	 *	wrapping	 0
	 */
	*(volatile ulong *)(CONFIG_SYS_TIMERBASE + 8) = 0x000000C2;
#else
	/* Set timer to be
	 *	enabled		 1
	 *	free-running	 0
	 *	XX		00
	 *	divider 256	10
	 *	XX		00
	 */
	*(volatile ulong *)(CONFIG_SYS_TIMERBASE + 8) = 0x00000088;
#endif

	/* init the timestamp */
	total_count = 0ULL;
	/* capure current decrementer value    */
	lastdec	  = READ_TIMER;
	/* start "advancing" time stamp from 0 */
	timestamp = 0L;

	div_timer = CONFIG_SYS_HZ_CLOCK;
	do_div(div_timer, CONFIG_SYS_HZ);
	do_div(div_timer, div_clock);

	return (0);
}

/*
 * timer without interrupts
 */
ulong get_timer (ulong base_ticks)
{
	return get_timer_masked () - base_ticks;
}

/* delay usec useconds */
void __udelay (unsigned long usec)
{
	ulong tmo, tmp;

	/* Convert to U-Boot ticks */
	tmo  = usec * CONFIG_SYS_HZ;
	tmo /= (1000000L);

	tmp  = get_timer_masked();	/* get current timestamp */
	tmo += tmp;			/* form target timestamp */

	while (get_timer_masked () < tmo) {/* loop till event */
		/*NOP*/;
	}
}

/* converts the timer reading to U-Boot ticks	       */
/* the timestamp is the number of ticks since reset    */
ulong get_timer_masked (void)
{
	/* get current count */
	unsigned long long now = READ_TIMER;

	if(now > lastdec) {
		/* Must have wrapped */
		total_count += lastdec + TIMER_LOAD_VAL + 1 - now;
	} else {
		total_count += lastdec - now;
	}
	lastdec	= now;

	/* Reuse "now" */
	now = total_count;
	do_div(now, div_timer);
	timestamp = now;

	return timestamp;
}

/* waits specified delay value and resets timestamp */
void udelay_masked (unsigned long usec)
{
	udelay(usec);
}

/*
 * This function is derived from PowerPC code (read timebase as long long).
 * On ARM it just returns the timer value.
 */
unsigned long long get_ticks(void)
{
	return get_timer(0);
}

/*
 * Return the timebase clock frequency
 * i.e. how often the timer decrements
 */
ulong get_tbclk (void)
{
	unsigned long long tmp = CONFIG_SYS_HZ_CLOCK;

	do_div(tmp, div_clock);

	return tmp;
}
