xref: /rk3399_rockchip-uboot/arch/arm/mach-rmobile/timer.c (revision c98b171e1098f94b2ff7720c45a25a602882f876)
1*badbb63cSNobuhiro Iwamatsu /*
2*badbb63cSNobuhiro Iwamatsu  * (C) Copyright 2012 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
3*badbb63cSNobuhiro Iwamatsu  * (C) Copyright 2012 Renesas Solutions Corp.
4*badbb63cSNobuhiro Iwamatsu  *
5*badbb63cSNobuhiro Iwamatsu  * SPDX-License-Identifier:	GPL-2.0+
6*badbb63cSNobuhiro Iwamatsu  */
7*badbb63cSNobuhiro Iwamatsu 
8*badbb63cSNobuhiro Iwamatsu #include <common.h>
9*badbb63cSNobuhiro Iwamatsu #include <div64.h>
10*badbb63cSNobuhiro Iwamatsu #include <asm/io.h>
11*badbb63cSNobuhiro Iwamatsu #include <asm/arch-armv7/globaltimer.h>
12*badbb63cSNobuhiro Iwamatsu #include <asm/arch/rmobile.h>
13*badbb63cSNobuhiro Iwamatsu 
14*badbb63cSNobuhiro Iwamatsu static struct globaltimer *global_timer = \
15*badbb63cSNobuhiro Iwamatsu 		(struct globaltimer *)GLOBAL_TIMER_BASE_ADDR;
16*badbb63cSNobuhiro Iwamatsu 
17*badbb63cSNobuhiro Iwamatsu #define CLK2MHZ(clk)	(clk / 1000 / 1000)
get_cpu_global_timer(void)18*badbb63cSNobuhiro Iwamatsu static u64 get_cpu_global_timer(void)
19*badbb63cSNobuhiro Iwamatsu {
20*badbb63cSNobuhiro Iwamatsu 	u32 low, high;
21*badbb63cSNobuhiro Iwamatsu 	u64 timer;
22*badbb63cSNobuhiro Iwamatsu 
23*badbb63cSNobuhiro Iwamatsu 	u32 old = readl(&global_timer->cnt_h);
24*badbb63cSNobuhiro Iwamatsu 	while (1) {
25*badbb63cSNobuhiro Iwamatsu 		low = readl(&global_timer->cnt_l);
26*badbb63cSNobuhiro Iwamatsu 		high = readl(&global_timer->cnt_h);
27*badbb63cSNobuhiro Iwamatsu 		if (old == high)
28*badbb63cSNobuhiro Iwamatsu 			break;
29*badbb63cSNobuhiro Iwamatsu 		else
30*badbb63cSNobuhiro Iwamatsu 			old = high;
31*badbb63cSNobuhiro Iwamatsu 	}
32*badbb63cSNobuhiro Iwamatsu 
33*badbb63cSNobuhiro Iwamatsu 	timer = high;
34*badbb63cSNobuhiro Iwamatsu 	return (u64)((timer << 32) | low);
35*badbb63cSNobuhiro Iwamatsu }
36*badbb63cSNobuhiro Iwamatsu 
get_time_us(void)37*badbb63cSNobuhiro Iwamatsu static u64 get_time_us(void)
38*badbb63cSNobuhiro Iwamatsu {
39*badbb63cSNobuhiro Iwamatsu 	u64 timer = get_cpu_global_timer();
40*badbb63cSNobuhiro Iwamatsu 
41*badbb63cSNobuhiro Iwamatsu 	timer = ((timer << 2) + (CLK2MHZ(CONFIG_SYS_CPU_CLK) >> 1));
42*badbb63cSNobuhiro Iwamatsu 	do_div(timer, CLK2MHZ(CONFIG_SYS_CPU_CLK));
43*badbb63cSNobuhiro Iwamatsu 	return timer;
44*badbb63cSNobuhiro Iwamatsu }
45*badbb63cSNobuhiro Iwamatsu 
get_time_ms(void)46*badbb63cSNobuhiro Iwamatsu static ulong get_time_ms(void)
47*badbb63cSNobuhiro Iwamatsu {
48*badbb63cSNobuhiro Iwamatsu 	u64 us = get_time_us();
49*badbb63cSNobuhiro Iwamatsu 
50*badbb63cSNobuhiro Iwamatsu 	do_div(us, 1000);
51*badbb63cSNobuhiro Iwamatsu 	return us;
52*badbb63cSNobuhiro Iwamatsu }
53*badbb63cSNobuhiro Iwamatsu 
timer_init(void)54*badbb63cSNobuhiro Iwamatsu int timer_init(void)
55*badbb63cSNobuhiro Iwamatsu {
56*badbb63cSNobuhiro Iwamatsu 	writel(0x01, &global_timer->ctl);
57*badbb63cSNobuhiro Iwamatsu 	return 0;
58*badbb63cSNobuhiro Iwamatsu }
59*badbb63cSNobuhiro Iwamatsu 
__udelay(unsigned long usec)60*badbb63cSNobuhiro Iwamatsu void __udelay(unsigned long usec)
61*badbb63cSNobuhiro Iwamatsu {
62*badbb63cSNobuhiro Iwamatsu 	u64 start, current;
63*badbb63cSNobuhiro Iwamatsu 	u64 wait;
64*badbb63cSNobuhiro Iwamatsu 
65*badbb63cSNobuhiro Iwamatsu 	start = get_cpu_global_timer();
66*badbb63cSNobuhiro Iwamatsu 	wait = (u64)((usec * CLK2MHZ(CONFIG_SYS_CPU_CLK)) >> 2);
67*badbb63cSNobuhiro Iwamatsu 	do {
68*badbb63cSNobuhiro Iwamatsu 		current = get_cpu_global_timer();
69*badbb63cSNobuhiro Iwamatsu 	} while ((current - start) < wait);
70*badbb63cSNobuhiro Iwamatsu }
71*badbb63cSNobuhiro Iwamatsu 
get_timer(ulong base)72*badbb63cSNobuhiro Iwamatsu ulong get_timer(ulong base)
73*badbb63cSNobuhiro Iwamatsu {
74*badbb63cSNobuhiro Iwamatsu 	return get_time_ms() - base;
75*badbb63cSNobuhiro Iwamatsu }
76*badbb63cSNobuhiro Iwamatsu 
get_ticks(void)77*badbb63cSNobuhiro Iwamatsu unsigned long long get_ticks(void)
78*badbb63cSNobuhiro Iwamatsu {
79*badbb63cSNobuhiro Iwamatsu 	return get_cpu_global_timer();
80*badbb63cSNobuhiro Iwamatsu }
81*badbb63cSNobuhiro Iwamatsu 
get_tbclk(void)82*badbb63cSNobuhiro Iwamatsu ulong get_tbclk(void)
83*badbb63cSNobuhiro Iwamatsu {
84*badbb63cSNobuhiro Iwamatsu 	return (ulong)(CONFIG_SYS_CPU_CLK >> 2);
85*badbb63cSNobuhiro Iwamatsu }
86