]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
24e8bee5 AW |
2 | /* |
3 | * Copyright 2013 Freescale Semiconductor, Inc. | |
24e8bee5 AW |
4 | */ |
5 | ||
d678a59d | 6 | #include <common.h> |
691d719d | 7 | #include <init.h> |
1045315d | 8 | #include <time.h> |
401d1c4f | 9 | #include <asm/global_data.h> |
24e8bee5 AW |
10 | #include <asm/io.h> |
11 | #include <div64.h> | |
12 | #include <asm/arch/imx-regs.h> | |
13 | #include <asm/arch/clock.h> | |
c05ed00a | 14 | #include <linux/delay.h> |
24e8bee5 AW |
15 | |
16 | static struct pit_reg *cur_pit = (struct pit_reg *)PIT_BASE_ADDR; | |
17 | ||
18 | DECLARE_GLOBAL_DATA_PTR; | |
19 | ||
20 | #define TIMER_LOAD_VAL 0xffffffff | |
21 | ||
22 | static inline unsigned long long tick_to_time(unsigned long long tick) | |
23 | { | |
24 | tick *= CONFIG_SYS_HZ; | |
25 | do_div(tick, mxc_get_clock(MXC_IPG_CLK)); | |
26 | ||
27 | return tick; | |
28 | } | |
29 | ||
30 | static inline unsigned long long us_to_tick(unsigned long long usec) | |
31 | { | |
32 | usec = usec * mxc_get_clock(MXC_IPG_CLK) + 999999; | |
33 | do_div(usec, 1000000); | |
34 | ||
35 | return usec; | |
36 | } | |
37 | ||
38 | int timer_init(void) | |
39 | { | |
40 | __raw_writel(0, &cur_pit->mcr); | |
41 | ||
42 | __raw_writel(TIMER_LOAD_VAL, &cur_pit->ldval1); | |
43 | __raw_writel(0, &cur_pit->tctrl1); | |
44 | __raw_writel(1, &cur_pit->tctrl1); | |
45 | ||
46 | gd->arch.tbl = 0; | |
47 | gd->arch.tbu = 0; | |
48 | ||
49 | return 0; | |
50 | } | |
51 | ||
52 | unsigned long long get_ticks(void) | |
53 | { | |
54 | ulong now = TIMER_LOAD_VAL - __raw_readl(&cur_pit->cval1); | |
55 | ||
56 | /* increment tbu if tbl has rolled over */ | |
57 | if (now < gd->arch.tbl) | |
58 | gd->arch.tbu++; | |
59 | gd->arch.tbl = now; | |
60 | ||
61 | return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl; | |
62 | } | |
63 | ||
24e8bee5 AW |
64 | ulong get_timer(ulong base) |
65 | { | |
6180ea7e | 66 | return tick_to_time(get_ticks()) - base; |
24e8bee5 AW |
67 | } |
68 | ||
69 | /* delay x useconds AND preserve advance timstamp value */ | |
70 | void __udelay(unsigned long usec) | |
71 | { | |
72 | unsigned long long start; | |
73 | ulong tmo; | |
74 | ||
75 | start = get_ticks(); /* get current timestamp */ | |
76 | tmo = us_to_tick(usec); /* convert usecs to ticks */ | |
77 | while ((get_ticks() - start) < tmo) | |
78 | ; /* loop till time has passed */ | |
79 | } | |
80 | ||
81 | /* | |
82 | * This function is derived from PowerPC code (timebase clock frequency). | |
83 | * On ARM it returns the number of timer ticks per second. | |
84 | */ | |
85 | ulong get_tbclk(void) | |
86 | { | |
87 | return mxc_get_clock(MXC_IPG_CLK); | |
88 | } |