xref: /rk3399_rockchip-uboot/arch/arm/cpu/armv7/vf610/timer.c (revision 326ea986ac150acdc7656d57fca647db80b50158)
124e8bee5SAlison Wang /*
224e8bee5SAlison Wang  * Copyright 2013 Freescale Semiconductor, Inc.
324e8bee5SAlison Wang  *
4*1a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
524e8bee5SAlison Wang  */
624e8bee5SAlison Wang 
724e8bee5SAlison Wang #include <common.h>
824e8bee5SAlison Wang #include <asm/io.h>
924e8bee5SAlison Wang #include <div64.h>
1024e8bee5SAlison Wang #include <asm/arch/imx-regs.h>
1124e8bee5SAlison Wang #include <asm/arch/clock.h>
1224e8bee5SAlison Wang 
1324e8bee5SAlison Wang static struct pit_reg *cur_pit = (struct pit_reg *)PIT_BASE_ADDR;
1424e8bee5SAlison Wang 
1524e8bee5SAlison Wang DECLARE_GLOBAL_DATA_PTR;
1624e8bee5SAlison Wang 
1724e8bee5SAlison Wang #define TIMER_LOAD_VAL	0xffffffff
1824e8bee5SAlison Wang 
tick_to_time(unsigned long long tick)1924e8bee5SAlison Wang static inline unsigned long long tick_to_time(unsigned long long tick)
2024e8bee5SAlison Wang {
2124e8bee5SAlison Wang 	tick *= CONFIG_SYS_HZ;
2224e8bee5SAlison Wang 	do_div(tick, mxc_get_clock(MXC_IPG_CLK));
2324e8bee5SAlison Wang 
2424e8bee5SAlison Wang 	return tick;
2524e8bee5SAlison Wang }
2624e8bee5SAlison Wang 
us_to_tick(unsigned long long usec)2724e8bee5SAlison Wang static inline unsigned long long us_to_tick(unsigned long long usec)
2824e8bee5SAlison Wang {
2924e8bee5SAlison Wang 	usec = usec * mxc_get_clock(MXC_IPG_CLK)  + 999999;
3024e8bee5SAlison Wang 	do_div(usec, 1000000);
3124e8bee5SAlison Wang 
3224e8bee5SAlison Wang 	return usec;
3324e8bee5SAlison Wang }
3424e8bee5SAlison Wang 
timer_init(void)3524e8bee5SAlison Wang int timer_init(void)
3624e8bee5SAlison Wang {
3724e8bee5SAlison Wang 	__raw_writel(0, &cur_pit->mcr);
3824e8bee5SAlison Wang 
3924e8bee5SAlison Wang 	__raw_writel(TIMER_LOAD_VAL, &cur_pit->ldval1);
4024e8bee5SAlison Wang 	__raw_writel(0, &cur_pit->tctrl1);
4124e8bee5SAlison Wang 	__raw_writel(1, &cur_pit->tctrl1);
4224e8bee5SAlison Wang 
4324e8bee5SAlison Wang 	gd->arch.tbl = 0;
4424e8bee5SAlison Wang 	gd->arch.tbu = 0;
4524e8bee5SAlison Wang 
4624e8bee5SAlison Wang 	return 0;
4724e8bee5SAlison Wang }
4824e8bee5SAlison Wang 
get_ticks(void)4924e8bee5SAlison Wang unsigned long long get_ticks(void)
5024e8bee5SAlison Wang {
5124e8bee5SAlison Wang 	ulong now = TIMER_LOAD_VAL - __raw_readl(&cur_pit->cval1);
5224e8bee5SAlison Wang 
5324e8bee5SAlison Wang 	/* increment tbu if tbl has rolled over */
5424e8bee5SAlison Wang 	if (now < gd->arch.tbl)
5524e8bee5SAlison Wang 		gd->arch.tbu++;
5624e8bee5SAlison Wang 	gd->arch.tbl = now;
5724e8bee5SAlison Wang 
5824e8bee5SAlison Wang 	return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl;
5924e8bee5SAlison Wang }
6024e8bee5SAlison Wang 
get_timer_masked(void)6124e8bee5SAlison Wang ulong get_timer_masked(void)
6224e8bee5SAlison Wang {
6324e8bee5SAlison Wang 	return tick_to_time(get_ticks());
6424e8bee5SAlison Wang }
6524e8bee5SAlison Wang 
get_timer(ulong base)6624e8bee5SAlison Wang ulong get_timer(ulong base)
6724e8bee5SAlison Wang {
6824e8bee5SAlison Wang 	return get_timer_masked() - base;
6924e8bee5SAlison Wang }
7024e8bee5SAlison Wang 
7124e8bee5SAlison Wang /* delay x useconds AND preserve advance timstamp value */
__udelay(unsigned long usec)7224e8bee5SAlison Wang void __udelay(unsigned long usec)
7324e8bee5SAlison Wang {
7424e8bee5SAlison Wang 	unsigned long long start;
7524e8bee5SAlison Wang 	ulong tmo;
7624e8bee5SAlison Wang 
7724e8bee5SAlison Wang 	start = get_ticks();			/* get current timestamp */
7824e8bee5SAlison Wang 	tmo = us_to_tick(usec);			/* convert usecs to ticks */
7924e8bee5SAlison Wang 	while ((get_ticks() - start) < tmo)
8024e8bee5SAlison Wang 		;				/* loop till time has passed */
8124e8bee5SAlison Wang }
8224e8bee5SAlison Wang 
8324e8bee5SAlison Wang /*
8424e8bee5SAlison Wang  * This function is derived from PowerPC code (timebase clock frequency).
8524e8bee5SAlison Wang  * On ARM it returns the number of timer ticks per second.
8624e8bee5SAlison Wang  */
get_tbclk(void)8724e8bee5SAlison Wang ulong get_tbclk(void)
8824e8bee5SAlison Wang {
8924e8bee5SAlison Wang 	return mxc_get_clock(MXC_IPG_CLK);
9024e8bee5SAlison Wang }
91