]>
Commit | Line | Data |
---|---|---|
65458987 | 1 | /* |
a187559e | 2 | * U-Boot - interrupts.c Interrupt related routines |
65458987 | 3 | * |
9171fc81 | 4 | * Copyright (c) 2005-2008 Analog Devices Inc. |
65458987 AL |
5 | * |
6 | * This file is based on interrupts.c | |
7 | * Copyright 1996 Roman Zippel | |
8 | * Copyright 1999 D. Jeff Dionne <jeff@uclinux.org> | |
9 | * Copyright 2000-2001 Lineo, Inc. D. Jefff Dionne <jeff@lineo.ca> | |
10 | * Copyright 2002 Arcturus Networks Inc. MaTed <mated@sympatico.ca> | |
11 | * Copyright 2003 Metrowerks/Motorola | |
12 | * Copyright 2003 Bas Vermeulen <bas@buyways.nl>, | |
13 | * BuyWays B.V. (www.buyways.nl) | |
14 | * | |
15 | * (C) Copyright 2000-2004 | |
16 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | |
65458987 | 17 | * |
9171fc81 | 18 | * Licensed under the GPL-2 or later. |
65458987 AL |
19 | */ |
20 | ||
21 | #include <common.h> | |
65458987 | 22 | #include <config.h> |
1f003cf4 | 23 | #include <watchdog.h> |
65458987 AL |
24 | #include <asm/blackfin.h> |
25 | #include "cpu.h" | |
26 | ||
27 | static ulong timestamp; | |
28 | static ulong last_time; | |
29 | static int int_flag; | |
30 | ||
31 | int irq_flags; /* needed by asm-blackfin/system.h */ | |
32 | ||
33 | /* Functions just to satisfy the linker */ | |
34 | ||
35 | /* | |
36 | * This function is derived from PowerPC code (read timebase as long long). | |
9171fc81 | 37 | * On Blackfin it just returns the timer value. |
65458987 AL |
38 | */ |
39 | unsigned long long get_ticks(void) | |
40 | { | |
41 | return get_timer(0); | |
42 | } | |
43 | ||
44 | /* | |
45 | * This function is derived from PowerPC code (timebase clock frequency). | |
9171fc81 | 46 | * On Blackfin it returns the number of timer ticks per second. |
65458987 AL |
47 | */ |
48 | ulong get_tbclk(void) | |
49 | { | |
63a7578e | 50 | return CONFIG_SYS_HZ; |
65458987 AL |
51 | } |
52 | ||
53 | void enable_interrupts(void) | |
54 | { | |
9171fc81 | 55 | local_irq_restore(int_flag); |
65458987 AL |
56 | } |
57 | ||
58 | int disable_interrupts(void) | |
59 | { | |
9171fc81 | 60 | local_irq_save(int_flag); |
65458987 AL |
61 | return 1; |
62 | } | |
63 | ||
3eb90bad | 64 | void __udelay(unsigned long usec) |
65458987 AL |
65 | { |
66 | unsigned long delay, start, stop; | |
67 | unsigned long cclk; | |
68 | cclk = (CONFIG_CCLK_HZ); | |
69 | ||
70 | while (usec > 1) { | |
1f003cf4 MF |
71 | WATCHDOG_RESET(); |
72 | ||
65458987 AL |
73 | /* |
74 | * how many clock ticks to delay? | |
75 | * - request(in useconds) * clock_ticks(Hz) / useconds/second | |
76 | */ | |
77 | if (usec < 1000) { | |
78 | delay = (usec * (cclk / 244)) >> 12; | |
79 | usec = 0; | |
80 | } else { | |
81 | delay = (1000 * (cclk / 244)) >> 12; | |
82 | usec -= 1000; | |
83 | } | |
84 | ||
9171fc81 | 85 | asm volatile (" %0 = CYCLES;" : "=r" (start)); |
65458987 | 86 | do { |
9171fc81 | 87 | asm volatile (" %0 = CYCLES; " : "=r" (stop)); |
65458987 AL |
88 | } while (stop - start < delay); |
89 | } | |
90 | ||
91 | return; | |
92 | } | |
93 | ||
9171fc81 MF |
94 | #define MAX_TIM_LOAD 0xFFFFFFFF |
95 | int timer_init(void) | |
65458987 | 96 | { |
f948158f | 97 | bfin_write_TCNTL(0x1); |
ec01481d | 98 | CSYNC(); |
f948158f MF |
99 | bfin_write_TSCALE(0x0); |
100 | bfin_write_TCOUNT(MAX_TIM_LOAD); | |
101 | bfin_write_TPERIOD(MAX_TIM_LOAD); | |
102 | bfin_write_TCNTL(0x7); | |
ec01481d | 103 | CSYNC(); |
65458987 AL |
104 | |
105 | timestamp = 0; | |
106 | last_time = 0; | |
9171fc81 MF |
107 | |
108 | return 0; | |
65458987 AL |
109 | } |
110 | ||
111 | /* | |
112 | * Any network command or flash | |
113 | * command is started get_timer shall | |
114 | * be called before TCOUNT gets reset, | |
115 | * to implement the accurate timeouts. | |
116 | * | |
117 | * How ever milliconds doesn't return | |
118 | * the number that has been elapsed from | |
119 | * the last reset. | |
120 | * | |
121 | * As get_timer is used in the u-boot | |
122 | * only for timeouts this should be | |
123 | * sufficient | |
124 | */ | |
125 | ulong get_timer(ulong base) | |
126 | { | |
127 | ulong milisec; | |
128 | ||
129 | /* Number of clocks elapsed */ | |
f948158f | 130 | ulong clocks = (MAX_TIM_LOAD - bfin_read_TCOUNT()); |
65458987 AL |
131 | |
132 | /* | |
133 | * Find if the TCOUNT is reset | |
134 | * timestamp gives the number of times | |
135 | * TCOUNT got reset | |
136 | */ | |
137 | if (clocks < last_time) | |
138 | timestamp++; | |
139 | last_time = clocks; | |
140 | ||
141 | /* Get the number of milliseconds */ | |
142 | milisec = clocks / (CONFIG_CCLK_HZ / 1000); | |
143 | ||
144 | /* | |
9171fc81 MF |
145 | * Find the number of millisonds that |
146 | * got elapsed before this TCOUNT cycle | |
65458987 AL |
147 | */ |
148 | milisec += timestamp * (MAX_TIM_LOAD / (CONFIG_CCLK_HZ / 1000)); | |
149 | ||
150 | return (milisec - base); | |
151 | } |