]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/ixp/timer.c
doc: SPI: Add qspi test details on AM43xx
[karo-tx-uboot.git] / arch / arm / cpu / ixp / timer.c
1 /*
2  * (C) Copyright 2010
3  * Michael Schwingen, michael@schwingen.org
4  *
5  * (C) Copyright 2006
6  * Stefan Roese, DENX Software Engineering, sr@denx.de.
7  *
8  * (C) Copyright 2002
9  * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
10  * Marius Groeger <mgroeger@sysgo.de>
11  *
12  * (C) Copyright 2002
13  * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
14  * Alex Zuepke <azu@sysgo.de>
15  *
16  * SPDX-License-Identifier:     GPL-2.0+
17  */
18
19 #include <common.h>
20 #include <asm/arch/ixp425.h>
21 #include <asm/io.h>
22 #include <div64.h>
23
24 DECLARE_GLOBAL_DATA_PTR;
25
26 /*
27  * The IXP42x time-stamp timer runs at 2*OSC_IN (66.666MHz when using a
28  * 33.333MHz crystal).
29  */
30 static inline unsigned long long tick_to_time(unsigned long long tick)
31 {
32         tick *= CONFIG_SYS_HZ;
33         do_div(tick, CONFIG_IXP425_TIMER_CLK);
34         return tick;
35 }
36
37 static inline unsigned long long time_to_tick(unsigned long long time)
38 {
39         time *= CONFIG_IXP425_TIMER_CLK;
40         do_div(time, CONFIG_SYS_HZ);
41         return time;
42 }
43
44 static inline unsigned long long us_to_tick(unsigned long long us)
45 {
46         us = us * CONFIG_IXP425_TIMER_CLK + 999999;
47         do_div(us, 1000000);
48         return us;
49 }
50
51 unsigned long long get_ticks(void)
52 {
53         ulong now = readl(IXP425_OSTS_B);
54
55         if (readl(IXP425_OSST) & IXP425_OSST_TIMER_TS_PEND) {
56                 /* rollover of timestamp timer register */
57                 gd->arch.timestamp += (0xFFFFFFFF - gd->arch.lastinc) + now + 1;
58                 writel(IXP425_OSST_TIMER_TS_PEND, IXP425_OSST);
59         } else {
60                 /* move stamp forward with absolut diff ticks */
61                 gd->arch.timestamp += (now - gd->arch.lastinc);
62         }
63         gd->arch.lastinc = now;
64         return gd->arch.timestamp;
65 }
66
67
68 void reset_timer_masked(void)
69 {
70         /* capture current timestamp counter */
71         gd->arch.lastinc = readl(IXP425_OSTS_B);
72         /* start "advancing" time stamp from 0 */
73         gd->arch.timestamp = 0;
74 }
75
76 ulong get_timer_masked(void)
77 {
78         return tick_to_time(get_ticks());
79 }
80
81 ulong get_timer(ulong base)
82 {
83         return get_timer_masked() - base;
84 }
85
86 /* delay x useconds AND preserve advance timestamp value */
87 void __udelay(unsigned long usec)
88 {
89         unsigned long long tmp;
90
91         tmp = get_ticks() + us_to_tick(usec);
92
93         while (get_ticks() < tmp)
94                 ;
95 }
96
97 int timer_init(void)
98 {
99         writel(IXP425_OSST_TIMER_TS_PEND, IXP425_OSST);
100         return 0;
101 }