xref: /openbmc/u-boot/arch/arm/cpu/pxa/timer.c (revision dfe6f4d6)
1 /*
2  * Marvell PXA2xx/3xx timer driver
3  *
4  * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
5  *
6  * SPDX-License-Identifier:	GPL-2.0+
7  */
8 
9 #include <asm/arch/pxa-regs.h>
10 #include <asm/io.h>
11 #include <common.h>
12 #include <div64.h>
13 
14 DECLARE_GLOBAL_DATA_PTR;
15 
16 #define	TIMER_LOAD_VAL	0xffffffff
17 
18 #define	timestamp	(gd->arch.tbl)
19 #define	lastinc		(gd->arch.lastinc)
20 
21 #if defined(CONFIG_CPU_PXA27X) || defined(CONFIG_CPU_MONAHANS)
22 #define	TIMER_FREQ_HZ	3250000
23 #elif defined(CONFIG_CPU_PXA25X)
24 #define	TIMER_FREQ_HZ	3686400
25 #else
26 #error "Timer frequency unknown - please config PXA CPU type"
27 #endif
28 
29 static unsigned long long tick_to_time(unsigned long long tick)
30 {
31 	return lldiv(tick * CONFIG_SYS_HZ, TIMER_FREQ_HZ);
32 }
33 
34 static unsigned long long us_to_tick(unsigned long long us)
35 {
36 	return lldiv(us * TIMER_FREQ_HZ, 1000000);
37 }
38 
39 int timer_init(void)
40 {
41 	writel(0, OSCR);
42 	return 0;
43 }
44 
45 unsigned long long get_ticks(void)
46 {
47 	/* Current tick value */
48 	uint32_t now = readl(OSCR);
49 
50 	if (now >= lastinc) {
51 		/*
52 		 * Normal mode (non roll)
53 		 * Move stamp forward with absolute diff ticks
54 		 */
55 		timestamp += (now - lastinc);
56 	} else {
57 		/* We have rollover of incrementer */
58 		timestamp += (TIMER_LOAD_VAL - lastinc) + now;
59 	}
60 
61 	lastinc = now;
62 	return timestamp;
63 }
64 
65 ulong get_timer(ulong base)
66 {
67 	return tick_to_time(get_ticks()) - base;
68 }
69 
70 void __udelay(unsigned long usec)
71 {
72 	unsigned long long tmp;
73 	ulong tmo;
74 
75 	tmo = us_to_tick(usec);
76 	tmp = get_ticks() + tmo;	/* get current timestamp */
77 
78 	while (get_ticks() < tmp)	/* loop till event */
79 		 /*NOP*/;
80 }
81 
82 ulong get_tbclk(void)
83 {
84 	return TIMER_FREQ_HZ;
85 }
86