]>
Commit | Line | Data |
---|---|---|
2d5b561e | 1 | /* |
ce04bb41 MS |
2 | * (C) Copyright 2010 |
3 | * Michael Schwingen, michael@schwingen.org | |
4 | * | |
ba94a1bb WD |
5 | * (C) Copyright 2006 |
6 | * Stefan Roese, DENX Software Engineering, sr@denx.de. | |
7 | * | |
2d5b561e WD |
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 | * | |
1a459660 | 16 | * SPDX-License-Identifier: GPL-2.0+ |
2d5b561e WD |
17 | */ |
18 | ||
19 | #include <common.h> | |
20 | #include <asm/arch/ixp425.h> | |
ce04bb41 MS |
21 | #include <asm/io.h> |
22 | #include <div64.h> | |
2d5b561e | 23 | |
ce04bb41 | 24 | DECLARE_GLOBAL_DATA_PTR; |
b54384e3 JCPV |
25 | |
26 | /* | |
ce04bb41 MS |
27 | * The IXP42x time-stamp timer runs at 2*OSC_IN (66.666MHz when using a |
28 | * 33.333MHz crystal). | |
b54384e3 | 29 | */ |
ce04bb41 | 30 | static inline unsigned long long tick_to_time(unsigned long long tick) |
b54384e3 | 31 | { |
ce04bb41 MS |
32 | tick *= CONFIG_SYS_HZ; |
33 | do_div(tick, CONFIG_IXP425_TIMER_CLK); | |
34 | return tick; | |
b54384e3 JCPV |
35 | } |
36 | ||
ce04bb41 | 37 | static inline unsigned long long time_to_tick(unsigned long long time) |
b54384e3 | 38 | { |
ce04bb41 MS |
39 | time *= CONFIG_IXP425_TIMER_CLK; |
40 | do_div(time, CONFIG_SYS_HZ); | |
41 | return time; | |
b54384e3 JCPV |
42 | } |
43 | ||
ce04bb41 | 44 | static inline unsigned long long us_to_tick(unsigned long long us) |
b54384e3 | 45 | { |
ce04bb41 MS |
46 | us = us * CONFIG_IXP425_TIMER_CLK + 999999; |
47 | do_div(us, 1000000); | |
48 | return us; | |
b54384e3 JCPV |
49 | } |
50 | ||
ce04bb41 | 51 | unsigned long long get_ticks(void) |
b54384e3 | 52 | { |
ce04bb41 MS |
53 | ulong now = readl(IXP425_OSTS_B); |
54 | ||
55 | if (readl(IXP425_OSST) & IXP425_OSST_TIMER_TS_PEND) { | |
56 | /* rollover of timestamp timer register */ | |
b4d51db8 | 57 | gd->arch.timestamp += (0xFFFFFFFF - gd->arch.lastinc) + now + 1; |
ce04bb41 MS |
58 | writel(IXP425_OSST_TIMER_TS_PEND, IXP425_OSST); |
59 | } else { | |
60 | /* move stamp forward with absolut diff ticks */ | |
b4d51db8 | 61 | gd->arch.timestamp += (now - gd->arch.lastinc); |
ce04bb41 | 62 | } |
582601da | 63 | gd->arch.lastinc = now; |
b4d51db8 | 64 | return gd->arch.timestamp; |
ce04bb41 | 65 | } |
b54384e3 | 66 | |
b54384e3 | 67 | |
ce04bb41 | 68 | void reset_timer_masked(void) |
b13fb01a | 69 | { |
ce04bb41 | 70 | /* capture current timestamp counter */ |
582601da | 71 | gd->arch.lastinc = readl(IXP425_OSTS_B); |
ce04bb41 | 72 | /* start "advancing" time stamp from 0 */ |
b4d51db8 | 73 | gd->arch.timestamp = 0; |
b13fb01a WD |
74 | } |
75 | ||
ce04bb41 | 76 | ulong get_timer_masked(void) |
2d5b561e | 77 | { |
ce04bb41 | 78 | return tick_to_time(get_ticks()); |
2d5b561e WD |
79 | } |
80 | ||
ce04bb41 | 81 | ulong get_timer(ulong base) |
2d5b561e | 82 | { |
ce04bb41 MS |
83 | return get_timer_masked() - base; |
84 | } | |
2d5b561e | 85 | |
ce04bb41 MS |
86 | /* delay x useconds AND preserve advance timestamp value */ |
87 | void __udelay(unsigned long usec) | |
2d5b561e | 88 | { |
ce04bb41 MS |
89 | unsigned long long tmp; |
90 | ||
91 | tmp = get_ticks() + us_to_tick(usec); | |
92 | ||
93 | while (get_ticks() < tmp) | |
94 | ; | |
2d5b561e | 95 | } |
b54384e3 JCPV |
96 | |
97 | int timer_init(void) | |
98 | { | |
ce04bb41 | 99 | writel(IXP425_OSST_TIMER_TS_PEND, IXP425_OSST); |
b54384e3 JCPV |
100 | return 0; |
101 | } |