@ -2,6 +2,8 @@
* Copyright ( C ) Marvell International Ltd . and its affiliates
* Written - by : Prafulla Wadaskar < prafulla @ marvell . com >
*
* Copyright ( C ) 2015 Stefan Roese < sr @ denx . de >
*
* SPDX - License - Identifier : GPL - 2.0 +
*/
@ -9,108 +11,14 @@
# include <asm/io.h>
# include <asm/arch/soc.h>
# define UBOOT_CNTR 0 /* counter to use for U-Boot timer */
/*
* ARM Timers Registers Map
*/
# define CNTMR_CTRL_REG &tmr_regs->ctrl
# define CNTMR_RELOAD_REG(tmrnum) &tmr_regs->tmr[tmrnum].reload
# define CNTMR_VAL_REG(tmrnum) &tmr_regs->tmr[tmrnum].val
/*
* ARM Timers Control Register
* CPU_TIMERS_CTRL_REG ( CTCR )
*/
# define CTCR_ARM_TIMER_EN_OFFS(cntr) (cntr * 2)
# define CTCR_ARM_TIMER_EN(cntr) (1 << CTCR_ARM_TIMER_EN_OFFS(cntr))
# define CTCR_ARM_TIMER_AUTO_OFFS(cntr) ((cntr * 2) + 1)
# define CTCR_ARM_TIMER_AUTO_EN(cntr) (1 << CTCR_ARM_TIMER_AUTO_OFFS(cntr))
/* Only Armada XP have the 25MHz enable bit (Kirkwood doesn't) */
# if defined(CONFIG_ARMADA_XP)
# define CTCR_ARM_TIMER_25MHZ_OFFS(cntr) (cntr + 11)
# define CTCR_ARM_TIMER_25MHZ(cntr) (1 << CTCR_ARM_TIMER_25MHZ_OFFS(cntr))
# else
# define CTCR_ARM_TIMER_25MHZ(cntr) 0
# endif
# define TIMER_LOAD_VAL 0xffffffff
# define timestamp gd->arch.tbl
# define lastdec gd->arch.lastinc
static int init_done __attribute__ ( ( section ( " .data " ) ) ) = 0 ;
/* Timer reload and current value registers */
struct kwtmr_val {
u32 reload ; /* Timer reload reg */
u32 val ; /* Timer value reg */
} ;
/* Timer registers */
struct kwtmr_registers {
u32 ctrl ; /* Timer control reg */
u32 pad [ 3 ] ;
struct kwtmr_val tmr [ 4 ] ;
u32 wdt_reload ;
u32 wdt_val ;
} ;
DECLARE_GLOBAL_DATA_PTR ;
static struct kwtmr_registers * tmr_regs =
( struct kwtmr_registers * ) MVEBU_TIMER_BASE ;
static inline ulong read_timer ( void )
{
return readl ( CNTMR_VAL_REG ( UBOOT_CNTR ) ) / ( CONFIG_SYS_TCLK / 1000 ) ;
}
ulong get_timer_masked ( void )
{
ulong now = read_timer ( ) ;
if ( lastdec > = now ) {
/* normal mode */
timestamp + = lastdec - now ;
} else {
/* we have an overflow ... */
timestamp + = lastdec +
( TIMER_LOAD_VAL / ( CONFIG_SYS_TCLK / 1000 ) ) - now ;
}
lastdec = now ;
# define TIMER_LOAD_VAL 0xffffffff
return timestamp ;
}
ulong get_timer ( ulong base )
{
return get_timer_masked ( ) - base ;
}
void __udelay ( unsigned long usec )
{
uint current ;
ulong delayticks ;
current = readl ( CNTMR_VAL_REG ( UBOOT_CNTR ) ) ;
delayticks = ( usec * ( CONFIG_SYS_TCLK / 1000000 ) ) ;
if ( current < delayticks ) {
delayticks - = current ;
while ( readl ( CNTMR_VAL_REG ( UBOOT_CNTR ) ) < current ) ;
while ( ( TIMER_LOAD_VAL - delayticks ) <
readl ( CNTMR_VAL_REG ( UBOOT_CNTR ) ) ) ;
} else {
while ( readl ( CNTMR_VAL_REG ( UBOOT_CNTR ) ) >
( current - delayticks ) ) ;
}
}
static int init_done __attribute__ ( ( section ( " .data " ) ) ) = 0 ;
/*
* init the counter
* Timer initialization
*/
int timer_init ( void )
{
@ -120,35 +28,15 @@ int timer_init(void)
init_done = 1 ;
/* load value into timer */
writel ( TIMER_LOAD_VAL , CNTMR_RELOAD_REG ( UBOOT_CNTR ) ) ;
writel ( TIMER_LOAD_VAL , CNTMR_VAL_REG ( UBOOT_CNTR ) ) ;
writel ( TIMER_LOAD_VAL , MVEBU_TIMER_BASE + 0x10 ) ;
writel ( TIMER_LOAD_VAL , MVEBU_TIMER_BASE + 0x14 ) ;
# if defined(CONFIG_ARMADA_XP)
/* On Armada XP / 38x ..., the 25MHz clock source needs to be enabled */
setbits_le32 ( MVEBU_TIMER_BASE + 0x00 , BIT ( 11 ) ) ;
# endif
/* enable timer in auto reload mode */
clrsetbits_le32 ( CNTMR_CTRL_REG , CTCR_ARM_TIMER_25MHZ ( UBOOT_CNTR ) ,
CTCR_ARM_TIMER_EN ( UBOOT_CNTR ) |
CTCR_ARM_TIMER_AUTO_EN ( UBOOT_CNTR ) ) ;
/* init the timestamp and lastdec value */
lastdec = read_timer ( ) ;
timestamp = 0 ;
setbits_le32 ( MVEBU_TIMER_BASE + 0x00 , 0x3 ) ;
return 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 )
{
return ( ulong ) CONFIG_SYS_HZ ;
}