/*
 * Cirrus Logic EP93xx timer support.
 *
 * Copyright (C) 2009, 2010 Matthias Kaehlcke <matthias@kaehlcke.net>
 *
 * Copyright (C) 2004, 2005
 * Cory T. Tusar, Videon Central, Inc., <ctusar@videon-central.com>
 *
 * Based on the original intr.c Cirrus Logic EP93xx Rev D. interrupt support,
 * author unknown.
 *
 * 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.,
 * 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <common.h>
#include <linux/types.h>
#include <asm/arch/ep93xx.h>
#include <asm/io.h>
#include <div64.h>

#define TIMER_CLKSEL	(1 << 3)
#define TIMER_ENABLE	(1 << 7)

#define TIMER_FREQ			508469		/* ticks / second */
#define TIMER_MAX_VAL			0xFFFFFFFF

static struct ep93xx_timer
{
	unsigned long long ticks;
	unsigned long last_read;
} timer;

static inline unsigned long long usecs_to_ticks(unsigned long usecs)
{
	unsigned long long ticks = (unsigned long long)usecs * TIMER_FREQ;
	do_div(ticks, 1000 * 1000);

	return ticks;
}

static inline void read_timer(void)
{
	struct timer_regs *timer_regs = (struct timer_regs *)TIMER_BASE;
	const unsigned long now = TIMER_MAX_VAL - readl(&timer_regs->timer3.value);

	if (now >= timer.last_read)
		timer.ticks += now - timer.last_read;
	else
		/* an overflow occurred */
		timer.ticks += TIMER_MAX_VAL - timer.last_read + now;

	timer.last_read = now;
}

/*
 * Get the number of ticks (in CONFIG_SYS_HZ resolution)
 */
unsigned long long get_ticks(void)
{
	unsigned long long sys_ticks;

	read_timer();

	sys_ticks = timer.ticks * CONFIG_SYS_HZ;
	do_div(sys_ticks, TIMER_FREQ);

	return sys_ticks;
}

unsigned long get_timer_masked(void)
{
	return get_ticks();
}

unsigned long get_timer(unsigned long base)
{
	return get_timer_masked() - base;
}

void __udelay(unsigned long usec)
{
	unsigned long long target;

	read_timer();

	target = timer.ticks + usecs_to_ticks(usec);

	while (timer.ticks < target)
		read_timer();
}

int timer_init(void)
{
	struct timer_regs *timer_regs = (struct timer_regs *)TIMER_BASE;

	/* use timer 3 with 508KHz and free running, not enabled now */
	writel(TIMER_CLKSEL, &timer_regs->timer3.control);

	/* set initial timer value */
	writel(TIMER_MAX_VAL, &timer_regs->timer3.load);

	/* Enable the timer */
	writel(TIMER_ENABLE | TIMER_CLKSEL,
		&timer_regs->timer3.control);

	/* Reset the timer */
	read_timer();
	timer.ticks = 0;

	return 0;
}

/*
 * This function is derived from PowerPC code (timebase clock frequency).
 * On ARM it returns the number of timer ticks per second.
 */
unsigned long get_tbclk(void)
{
	return CONFIG_SYS_HZ;
}
