/*
 * (C) Copyright 2003
 * Texas Instruments <www.ti.com>
 *
 * (C) Copyright 2002
 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 * Marius Groeger <mgroeger@sysgo.de>
 *
 * (C) Copyright 2002
 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 * Alex Zuepke <azu@sysgo.de>
 *
 * (C) Copyright 2002-2004
 * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
 *
 * (C) Copyright 2004
 * Philippe Robin, ARM Ltd. <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>

#define TIMER_LOAD_VAL 0xFFFFFFFF

/* macro to read the 32 bit timer */
#include "mvOs.h"
#include "cntmr/mvCntmr.h"
#include "cntmr/mvCntmrRegs.h"
/* Global timer source clock is the Punit clock (which is L2 clock divided by 2) */
#define MV_BOARD_REFCLK MV_BOARD_REFCLK_25MHZ
#define READ_TIMER (mvCntmrRead(UBOOT_CNTR) / (MV_BOARD_REFCLK / 1000))

extern MV_U32 mvCpuL2ClkGet(MV_VOID);

static ulong timestamp;
static ulong lastdec;
extern MV_U32 mvBoardTclkGet(MV_VOID);

int timer_init_done = 0;

/* nothing really to do with interrupts, just starts up a counter. */
int timer_init(void)
{
	unsigned int cntmrCtrl;

	if (timer_init_done)
		return 0;

	/* init the counter */
	MV_REG_WRITE(CNTMR_RELOAD_REG(UBOOT_CNTR), TIMER_LOAD_VAL);
	MV_REG_WRITE(CNTMR_VAL_REG(UBOOT_CNTR), TIMER_LOAD_VAL);

	/* set control for timer \ cunter and enable */
	/* read control register */
	cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG(UBOOT_CNTR));
	cntmrCtrl |= CTCR_ARM_TIMER_EN(UBOOT_CNTR);
	cntmrCtrl |= CTCR_ARM_TIMER_AUTO_EN(UBOOT_CNTR);
	cntmrCtrl |= (1 << CTCR_ARM_TIMER_25MhzFRQ_ENABLE_OFFS(UBOOT_CNTR));

	MV_REG_WRITE(CNTMR_CTRL_REG(UBOOT_CNTR), cntmrCtrl);
	/* init the timestamp and lastdec value */
	reset_timer_masked();

	timer_init_done = 1;

	return 0;
}

/*
 * timer without interrupts
 */

void reset_timer(void)
{
	reset_timer_masked();
}

ulong get_timer(ulong base)
{
	return get_timer_masked() - base;
}

void set_timer(ulong t)
{
	timestamp = t;
}

/* delay x useconds AND perserve advance timstamp value */
#ifndef CONFIG_MARVELL
void udelay(unsigned long usec)
{
	ulong tmo, tmp;

	if (usec >= 1000) {             /* if "big" number, spread normalization to seconds */
		tmo = usec / 1000;      /* start to normalize for usec to ticks per sec */
		tmo *= CONFIG_SYS_HZ;   /* find number of "ticks" to wait to achieve target */
		tmo /= 1000;            /* finish normalize. */
	}else{                          /* else small number, don't kill it prior to HZ multiply */
		tmo = usec * CONFIG_SYS_HZ;
		tmo /= (1000 * 1000);
	}

	tmp = get_timer(0);                     /* get current timestamp */
	if ( (tmo + tmp + 1) < tmp)             /* if setting this fordward will roll time stamp */
		reset_timer_masked();           /* reset "advancing" timestamp to 0, set lastdec value */
	else
		tmo += tmp;                     /* else, set advancing stamp wake up time */

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

#else
/* FIXME: udelay supports only the maximum time needed for one round of the
                counter */
void __udelay(unsigned long usec)
{
	uint current;
	ulong delayticks;

	/* In case udelay is called before timier was initialized */
	if (!timer_init_done)
		timer_init();

	delayticks = (usec * (MV_BOARD_REFCLK / 1000000));

	current = mvCntmrRead(UBOOT_CNTR);
	if (current < delayticks) {
		delayticks -= current;
		while (mvCntmrRead(UBOOT_CNTR) < current) ;
		while ((TIMER_LOAD_VAL - delayticks) < mvCntmrRead(UBOOT_CNTR)) ;
	}else
		while (mvCntmrRead(UBOOT_CNTR) > (current - delayticks)) ;
}

#endif

void reset_timer_masked(void)
{
	/* reset time */
	lastdec = READ_TIMER;   /* capure current decrementer value time */
	timestamp = 0;          /* start "advancing" time stamp from 0 */
}

ulong get_timer_masked(void)
{
	ulong now = READ_TIMER;                 /* current tick value */

	if (lastdec >= now) {                   /* normal mode (non roll) */
		/* normal mode */
		timestamp += lastdec - now;     /* move stamp fordward with absoulte diff ticks */
	} else {                                /* we have overflow of the count down timer */
		/* nts = ts + ld + (TLV - now)
		 * ts=old stamp, ld=time that passed before passing through -1
		 * (TLV-now) amount of time after passing though -1
		 * nts = new "advancing time stamp"...it could also roll and cause problems.
		 */
		timestamp += lastdec + (TIMER_LOAD_VAL / (MV_BOARD_REFCLK / 1000)) - now;

	}
	lastdec = now;

	return timestamp;
}

/* waits specified delay value and resets timestamp */
void udelay_masked(unsigned long usec)
{
	ulong tmo;
	ulong endtime;
	signed long diff;

	if (usec >= 1000) {                                                                                     /* if "big" number, spread normalization to seconds */
		tmo = usec / 1000;                                                                              /* start to normalize for usec to ticks per sec */
		tmo *= CONFIG_SYS_HZ; /* find number of "ticks" to wait to achieve target */ tmo /= 1000;       /* finish normalize. */
	} else {                                                                                                /* else small number, don't kill it prior to HZ multiply */
		tmo = usec * CONFIG_SYS_HZ;
		tmo /= (1000 * 1000);
	}

	endtime = get_timer_masked() + tmo;

	do {
		ulong now = get_timer_masked();
		diff = endtime - now;
	} while (diff >= 0);
}

/*
 * 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);
}

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

	tbclk = CONFIG_SYS_HZ;
	return tbclk;
}
