blob: 38e2e2879c8e556694b51990e858c3b487a50ed0 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/*
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
24DECLARE_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 */
30static 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
37static 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
44static 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
51unsigned 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
68void 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
76ulong get_timer_masked(void)
77{
78 return tick_to_time(get_ticks());
79}
80
81ulong get_timer(ulong base)
82{
83 return get_timer_masked() - base;
84}
85
86/* delay x useconds AND preserve advance timestamp value */
87void __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
97int timer_init(void)
98{
99 writel(IXP425_OSST_TIMER_TS_PEND, IXP425_OSST);
100 return 0;
101}