]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
6ad43d0d NI |
2 | /* |
3 | * Copyright (C) 2007,2008 Nobobuhiro Iwamatsu <iwamatsu@nigauri.org> | |
4 | * Copyright (C) 2008 Renesas Solutions Corp. | |
5 | * | |
6 | * (C) Copyright 2003 | |
7 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | |
6ad43d0d NI |
8 | */ |
9 | ||
d678a59d | 10 | #include <common.h> |
691d719d | 11 | #include <init.h> |
1045315d | 12 | #include <time.h> |
6ad43d0d NI |
13 | #include <asm/io.h> |
14 | #include <asm/processor.h> | |
c05ed00a | 15 | #include <linux/delay.h> |
6ad43d0d | 16 | |
85cb052e | 17 | #define CMT_CMCSR_INIT 0x0001 /* PCLK/32 */ |
6ad43d0d NI |
18 | #define CMT_CMCSR_CALIB 0x0000 |
19 | #define CMT_MAX_COUNTER (0xFFFFFFFF) | |
20 | #define CMT_TIMER_RESET (0xFFFF) | |
21 | ||
22 | static vu_long cmt0_timer; | |
23 | ||
24 | static void cmt_timer_start(unsigned int timer) | |
25 | { | |
26 | writew(readw(CMSTR) | 0x01, CMSTR); | |
27 | } | |
28 | ||
29 | static void cmt_timer_stop(unsigned int timer) | |
30 | { | |
31 | writew(readw(CMSTR) & ~0x01, CMSTR); | |
32 | } | |
33 | ||
34 | int timer_init(void) | |
35 | { | |
36 | cmt0_timer = 0; | |
37 | /* Divide clock by 32 */ | |
38 | readw(CMCSR_0); | |
39 | writew(CMT_CMCSR_INIT, CMCSR_0); | |
40 | ||
41 | /* User Device 0 only */ | |
42 | cmt_timer_stop(0); | |
5c8404af | 43 | writew(CMT_TIMER_RESET, CMCOR_0); |
6ad43d0d NI |
44 | cmt_timer_start(0); |
45 | ||
46 | return 0; | |
47 | } | |
48 | ||
49 | unsigned long long get_ticks(void) | |
50 | { | |
51 | return cmt0_timer; | |
52 | } | |
53 | ||
d8bbc51c NI |
54 | static vu_long cmcnt = 0; |
55 | static unsigned long get_usec (void) | |
6ad43d0d NI |
56 | { |
57 | ulong data = readw(CMCNT_0); | |
58 | ||
59 | if (data >= cmcnt) | |
60 | cmcnt = data - cmcnt; | |
61 | else | |
62 | cmcnt = (CMT_TIMER_RESET - cmcnt) + data; | |
63 | ||
64 | if ((cmt0_timer + cmcnt) > CMT_MAX_COUNTER) | |
65 | cmt0_timer = ((cmt0_timer + cmcnt) - CMT_MAX_COUNTER); | |
66 | else | |
67 | cmt0_timer += cmcnt; | |
68 | ||
69 | cmcnt = data; | |
d8bbc51c NI |
70 | return cmt0_timer; |
71 | } | |
72 | ||
73 | /* return msec */ | |
74 | ulong get_timer(ulong base) | |
75 | { | |
85cb052e | 76 | return (get_usec() / 1000) - base; |
6ad43d0d NI |
77 | } |
78 | ||
3eb90bad | 79 | void __udelay(unsigned long usec) |
6ad43d0d | 80 | { |
d8bbc51c | 81 | unsigned long end = get_usec() + usec; |
6ad43d0d | 82 | |
d8bbc51c | 83 | while (get_usec() < end) |
6ad43d0d NI |
84 | continue; |
85 | } | |
86 | ||
87 | unsigned long get_tbclk(void) | |
88 | { | |
8f0960e8 | 89 | return CONFIG_SH_CMT_CLK_FREQ; |
6ad43d0d | 90 | } |