]>
Commit | Line | Data |
---|---|---|
c74b2108 SK |
1 | /* |
2 | * (C) Copyright 2003 | |
3 | * Texas Instruments <www.ti.com> | |
4 | * | |
5 | * (C) Copyright 2002 | |
6 | * Sysgo Real-Time Solutions, GmbH <www.elinos.com> | |
7 | * Marius Groeger <mgroeger@sysgo.de> | |
8 | * | |
9 | * (C) Copyright 2002 | |
10 | * Sysgo Real-Time Solutions, GmbH <www.elinos.com> | |
11 | * Alex Zuepke <azu@sysgo.de> | |
12 | * | |
13 | * (C) Copyright 2002-2004 | |
792a09eb | 14 | * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> |
c74b2108 SK |
15 | * |
16 | * (C) Copyright 2004 | |
17 | * Philippe Robin, ARM Ltd. <philippe.robin@arm.com> | |
18 | * | |
19 | * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net> | |
20 | * | |
1a459660 | 21 | * SPDX-License-Identifier: GPL-2.0+ |
c74b2108 SK |
22 | */ |
23 | ||
24 | #include <common.h> | |
9868a36d | 25 | #include <asm/io.h> |
de23e722 | 26 | #include <asm/arch/timer_defs.h> |
e21b3dfb | 27 | #include <div64.h> |
c74b2108 | 28 | |
e465cf23 NT |
29 | DECLARE_GLOBAL_DATA_PTR; |
30 | ||
9868a36d NT |
31 | static struct davinci_timer * const timer = |
32 | (struct davinci_timer *)CONFIG_SYS_TIMERBASE; | |
c74b2108 | 33 | |
e465cf23 | 34 | #define TIMER_LOAD_VAL 0xffffffff |
ea686f52 | 35 | |
e465cf23 | 36 | #define TIM_CLK_DIV 16 |
c74b2108 SK |
37 | |
38 | int timer_init(void) | |
39 | { | |
40 | /* We are using timer34 in unchained 32-bit mode, full speed */ | |
9868a36d NT |
41 | writel(0x0, &timer->tcr); |
42 | writel(0x0, &timer->tgcr); | |
43 | writel(0x06 | ((TIM_CLK_DIV - 1) << 8), &timer->tgcr); | |
44 | writel(0x0, &timer->tim34); | |
45 | writel(TIMER_LOAD_VAL, &timer->prd34); | |
9868a36d | 46 | writel(2 << 22, &timer->tcr); |
b339051c | 47 | gd->arch.timer_rate_hz = CONFIG_SYS_HZ_CLOCK / TIM_CLK_DIV; |
5f70714c | 48 | gd->arch.timer_reset_value = 0; |
c74b2108 SK |
49 | |
50 | return(0); | |
51 | } | |
52 | ||
e465cf23 NT |
53 | /* |
54 | * Get the current 64 bit timer tick count | |
55 | */ | |
56 | unsigned long long get_ticks(void) | |
c74b2108 | 57 | { |
e465cf23 NT |
58 | unsigned long now = readl(&timer->tim34); |
59 | ||
60 | /* increment tbu if tbl has rolled over */ | |
66ee6923 | 61 | if (now < gd->arch.tbl) |
8ff43b03 | 62 | gd->arch.tbu++; |
66ee6923 | 63 | gd->arch.tbl = now; |
e465cf23 | 64 | |
66ee6923 | 65 | return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl; |
c74b2108 SK |
66 | } |
67 | ||
80c40b76 DB |
68 | ulong get_timer(ulong base) |
69 | { | |
e465cf23 | 70 | unsigned long long timer_diff; |
80c40b76 | 71 | |
5f70714c | 72 | timer_diff = get_ticks() - gd->arch.timer_reset_value; |
e465cf23 | 73 | |
b339051c SG |
74 | return lldiv(timer_diff, |
75 | (gd->arch.timer_rate_hz / CONFIG_SYS_HZ)) - base; | |
c74b2108 SK |
76 | } |
77 | ||
3eb90bad | 78 | void __udelay(unsigned long usec) |
c74b2108 | 79 | { |
e465cf23 | 80 | unsigned long long endtime; |
c74b2108 | 81 | |
b339051c | 82 | endtime = lldiv((unsigned long long)usec * gd->arch.timer_rate_hz, |
e21b3dfb | 83 | 1000000UL); |
e465cf23 | 84 | endtime += get_ticks(); |
c74b2108 | 85 | |
e465cf23 NT |
86 | while (get_ticks() < endtime) |
87 | ; | |
c74b2108 SK |
88 | } |
89 | ||
90 | /* | |
91 | * This function is derived from PowerPC code (timebase clock frequency). | |
92 | * On ARM it returns the number of timer ticks per second. | |
93 | */ | |
94 | ulong get_tbclk(void) | |
95 | { | |
b339051c | 96 | return gd->arch.timer_rate_hz; |
c74b2108 | 97 | } |
bf569ac8 HS |
98 | |
99 | #ifdef CONFIG_HW_WATCHDOG | |
100 | static struct davinci_timer * const wdttimer = | |
101 | (struct davinci_timer *)CONFIG_SYS_WDTTIMERBASE; | |
102 | ||
103 | /* | |
104 | * See prufw2.pdf for using Timer as a WDT | |
105 | */ | |
106 | void davinci_hw_watchdog_enable(void) | |
107 | { | |
108 | writel(0x0, &wdttimer->tcr); | |
109 | writel(0x0, &wdttimer->tgcr); | |
110 | /* TIMMODE = 2h */ | |
111 | writel(0x08 | 0x03 | ((TIM_CLK_DIV - 1) << 8), &wdttimer->tgcr); | |
112 | writel(CONFIG_SYS_WDT_PERIOD_LOW, &wdttimer->prd12); | |
113 | writel(CONFIG_SYS_WDT_PERIOD_HIGH, &wdttimer->prd34); | |
114 | writel(2 << 22, &wdttimer->tcr); | |
115 | writel(0x0, &wdttimer->tim12); | |
116 | writel(0x0, &wdttimer->tim34); | |
117 | /* set WDEN bit, WDKEY 0xa5c6 */ | |
118 | writel(0xa5c64000, &wdttimer->wdtcr); | |
119 | /* clear counter register */ | |
120 | writel(0xda7e4000, &wdttimer->wdtcr); | |
121 | } | |
122 | ||
123 | void davinci_hw_watchdog_reset(void) | |
124 | { | |
125 | writel(0xa5c64000, &wdttimer->wdtcr); | |
126 | writel(0xda7e4000, &wdttimer->wdtcr); | |
127 | } | |
128 | #endif |