]>
Commit | Line | Data |
---|---|---|
e66c49fa VM |
1 | /* |
2 | * (C) Copyright 2016 | |
3 | * Vikas Manocha, ST Micoelectronics, vikas.manocha@st.com. | |
4 | * | |
5 | * SPDX-License-Identifier: GPL-2.0+ | |
6 | */ | |
7 | ||
8 | #include <common.h> | |
9 | #include <asm/io.h> | |
10 | #include <asm/arch/stm32.h> | |
081de09d | 11 | #include <asm/arch/stm32_defs.h> |
e66c49fa | 12 | #include <asm/arch/gpt.h> |
e66c49fa VM |
13 | |
14 | #define READ_TIMER() (readl(&gpt1_regs_ptr->cnt) & GPT_FREE_RUNNING) | |
15 | #define GPT_RESOLUTION (CONFIG_SYS_HZ_CLOCK/CONFIG_STM32_HZ) | |
16 | ||
17 | DECLARE_GLOBAL_DATA_PTR; | |
18 | ||
19 | #define timestamp gd->arch.tbl | |
20 | #define lastdec gd->arch.lastinc | |
21 | ||
22 | int timer_init(void) | |
23 | { | |
24 | /* Timer2 clock configuration */ | |
081de09d | 25 | clock_setup(TIMER2_CLOCK_CFG); |
e66c49fa VM |
26 | /* Stop the timer */ |
27 | writel(readl(&gpt1_regs_ptr->cr1) & ~GPT_CR1_CEN, &gpt1_regs_ptr->cr1); | |
28 | ||
72dee54b | 29 | writel((CONFIG_SYS_CLK_FREQ / 2 / CONFIG_SYS_HZ_CLOCK) - 1, |
e66c49fa VM |
30 | &gpt1_regs_ptr->psc); |
31 | ||
32 | /* Configure timer for auto-reload */ | |
33 | writel(readl(&gpt1_regs_ptr->cr1) | GPT_MODE_AUTO_RELOAD, | |
34 | &gpt1_regs_ptr->cr1); | |
35 | ||
36 | /* load value for free running */ | |
37 | writel(GPT_FREE_RUNNING, &gpt1_regs_ptr->arr); | |
38 | ||
39 | /* start timer */ | |
40 | writel(readl(&gpt1_regs_ptr->cr1) | GPT_CR1_CEN, &gpt1_regs_ptr->cr1); | |
41 | ||
42 | writel(readl(&gpt1_regs_ptr->egr) | TIM_EGR_UG, &gpt1_regs_ptr->egr); | |
43 | ||
44 | /* Reset the timer */ | |
45 | lastdec = READ_TIMER(); | |
46 | timestamp = 0; | |
47 | ||
48 | return 0; | |
49 | } | |
50 | ||
51 | /* | |
52 | * timer without interrupts | |
53 | */ | |
54 | ulong get_timer(ulong base) | |
55 | { | |
56 | return (get_timer_masked() / GPT_RESOLUTION) - base; | |
57 | } | |
58 | ||
59 | void __udelay(unsigned long usec) | |
60 | { | |
61 | ulong tmo; | |
62 | ulong start = get_timer_masked(); | |
63 | ulong tenudelcnt = CONFIG_SYS_HZ_CLOCK / (1000 * 100); | |
64 | ulong rndoff; | |
65 | ||
66 | rndoff = (usec % 10) ? 1 : 0; | |
67 | ||
68 | /* tenudelcnt timer tick gives 10 microsecconds delay */ | |
69 | tmo = ((usec / 10) + rndoff) * tenudelcnt; | |
70 | ||
71 | while ((ulong) (get_timer_masked() - start) < tmo) | |
72 | ; | |
73 | } | |
74 | ||
75 | ulong get_timer_masked(void) | |
76 | { | |
77 | ulong now = READ_TIMER(); | |
78 | ||
79 | if (now >= lastdec) { | |
80 | /* normal mode */ | |
81 | timestamp += now - lastdec; | |
82 | } else { | |
83 | /* we have an overflow ... */ | |
84 | timestamp += now + GPT_FREE_RUNNING - lastdec; | |
85 | } | |
86 | lastdec = now; | |
87 | ||
88 | return timestamp; | |
89 | } | |
90 | ||
91 | void udelay_masked(unsigned long usec) | |
92 | { | |
93 | return udelay(usec); | |
94 | } | |
95 | ||
96 | /* | |
97 | * This function is derived from PowerPC code (read timebase as long long). | |
98 | * On ARM it just returns the timer value. | |
99 | */ | |
100 | unsigned long long get_ticks(void) | |
101 | { | |
102 | return get_timer(0); | |
103 | } | |
104 | ||
105 | /* | |
106 | * This function is derived from PowerPC code (timebase clock frequency). | |
107 | * On ARM it returns the number of timer ticks per second. | |
108 | */ | |
109 | ulong get_tbclk(void) | |
110 | { | |
111 | return CONFIG_STM32_HZ; | |
112 | } |