]>
Commit | Line | Data |
---|---|---|
1df49e27 WD |
1 | /* |
2 | * (C) Copyright 2001 | |
3 | * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc. | |
4 | * | |
5 | * See file CREDITS for list of people who contributed to this | |
6 | * project. | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public License as | |
10 | * published by the Free Software Foundation; either version 2 of | |
11 | * the License, or (at your option) any later version. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
21 | * MA 02111-1307 USA | |
22 | */ | |
23 | ||
24 | /* | |
25 | * cpu.c | |
26 | * | |
27 | * CPU specific code | |
28 | * | |
29 | * written or collected and sometimes rewritten by | |
30 | * Magnus Damm <damm@bitsmart.com> | |
31 | * | |
32 | * minor modifications by | |
33 | * Wolfgang Denk <wd@denx.de> | |
34 | * | |
35 | * more modifications by | |
36 | * Josh Huber <huber@mclx.com> | |
37 | * added support for the 74xx series of cpus | |
38 | * added support for the 7xx series of cpus | |
39 | * made the code a little less hard-coded, and more auto-detectish | |
40 | */ | |
41 | ||
42 | #include <common.h> | |
43 | #include <command.h> | |
44 | #include <74xx_7xx.h> | |
45 | #include <asm/cache.h> | |
46 | ||
589c0427 GVB |
47 | #if defined(CONFIG_OF_LIBFDT) |
48 | #include <libfdt.h> | |
49 | #include <fdt_support.h> | |
50 | #endif | |
51 | ||
c7de829c WD |
52 | #ifdef CONFIG_AMIGAONEG3SE |
53 | #include "../board/MAI/AmigaOneG3SE/via686.h" | |
54 | #include "../board/MAI/AmigaOneG3SE/memio.h" | |
55 | #endif | |
56 | ||
d87080b7 WD |
57 | DECLARE_GLOBAL_DATA_PTR; |
58 | ||
1df49e27 WD |
59 | cpu_t |
60 | get_cpu_type(void) | |
61 | { | |
62 | uint pvr = get_pvr(); | |
63 | cpu_t type; | |
64 | ||
65 | type = CPU_UNKNOWN; | |
66 | ||
67 | switch (PVR_VER(pvr)) { | |
68 | case 0x000c: | |
69 | type = CPU_7400; | |
70 | break; | |
71 | case 0x0008: | |
72 | type = CPU_750; | |
73 | ||
72755c71 | 74 | if (((pvr >> 8) & 0xff) == 0x01) { |
1df49e27 WD |
75 | type = CPU_750CX; /* old CX (80100 and 8010x?)*/ |
76 | } else if (((pvr >> 8) & 0xff) == 0x22) { | |
77 | type = CPU_750CX; /* CX (82201,82202) and CXe (82214) */ | |
78 | } else if (((pvr >> 8) & 0xff) == 0x33) { | |
79 | type = CPU_750CX; /* CXe (83311) */ | |
80 | } else if (((pvr >> 12) & 0xF) == 0x3) { | |
81 | type = CPU_755; | |
72755c71 WD |
82 | } |
83 | break; | |
84 | ||
85 | case 0x7000: | |
86 | type = CPU_750FX; | |
1df49e27 WD |
87 | break; |
88 | ||
3a473b2a WD |
89 | case 0x7002: |
90 | type = CPU_750GX; | |
91 | break; | |
92 | ||
1df49e27 WD |
93 | case 0x800C: |
94 | type = CPU_7410; | |
95 | break; | |
96 | ||
72755c71 | 97 | case 0x8000: |
1df49e27 WD |
98 | type = CPU_7450; |
99 | break; | |
100 | ||
3a473b2a WD |
101 | case 0x8001: |
102 | type = CPU_7455; | |
103 | break; | |
104 | ||
105 | case 0x8002: | |
106 | type = CPU_7457; | |
107 | break; | |
108 | ||
4c52783b | 109 | case 0x8003: |
110 | type = CPU_7447A; | |
111 | break; | |
c9c1eeed | 112 | |
4c52783b | 113 | case 0x8004: |
114 | type = CPU_7448; | |
115 | break; | |
c9c1eeed | 116 | |
1df49e27 WD |
117 | default: |
118 | break; | |
119 | } | |
120 | ||
121 | return type; | |
122 | } | |
123 | ||
124 | /* ------------------------------------------------------------------------- */ | |
125 | ||
126 | #if !defined(CONFIG_BAB7xx) | |
127 | int checkcpu (void) | |
128 | { | |
1df49e27 WD |
129 | uint type = get_cpu_type(); |
130 | uint pvr = get_pvr(); | |
131 | ulong clock = gd->cpu_clk; | |
132 | char buf[32]; | |
133 | char *str; | |
134 | ||
135 | puts ("CPU: "); | |
136 | ||
137 | switch (type) { | |
138 | case CPU_750CX: | |
139 | printf ("750CX%s v%d.%d", (pvr&0xf0)?"e":"", | |
140 | (pvr>>8) & 0xf, | |
141 | pvr & 0xf); | |
142 | goto PR_CLK; | |
143 | ||
144 | case CPU_750: | |
145 | str = "750"; | |
146 | break; | |
147 | ||
72755c71 WD |
148 | case CPU_750FX: |
149 | str = "750FX"; | |
150 | break; | |
151 | ||
3a473b2a WD |
152 | case CPU_750GX: |
153 | str = "750GX"; | |
154 | break; | |
155 | ||
1df49e27 WD |
156 | case CPU_755: |
157 | str = "755"; | |
158 | break; | |
159 | ||
160 | case CPU_7400: | |
161 | str = "MPC7400"; | |
162 | break; | |
163 | ||
72755c71 WD |
164 | case CPU_7410: |
165 | str = "MPC7410"; | |
1df49e27 WD |
166 | break; |
167 | ||
c9c1eeed | 168 | case CPU_7447A: |
169 | str = "MPC7447A"; | |
170 | break; | |
171 | ||
1eac2a71 SR |
172 | case CPU_7448: |
173 | str = "MPC7448"; | |
1df49e27 WD |
174 | break; |
175 | ||
72755c71 WD |
176 | case CPU_7450: |
177 | str = "MPC7450"; | |
1df49e27 WD |
178 | break; |
179 | ||
3a473b2a WD |
180 | case CPU_7455: |
181 | str = "MPC7455"; | |
182 | break; | |
183 | ||
184 | case CPU_7457: | |
185 | str = "MPC7457"; | |
186 | break; | |
187 | ||
1df49e27 | 188 | default: |
72755c71 | 189 | printf("Unknown CPU -- PVR: 0x%08x\n", pvr); |
1df49e27 WD |
190 | return -1; |
191 | } | |
192 | ||
193 | printf ("%s v%d.%d", str, (pvr >> 8) & 0xFF, pvr & 0xFF); | |
194 | PR_CLK: | |
195 | printf (" @ %s MHz\n", strmhz(buf, clock)); | |
196 | ||
197 | return (0); | |
198 | } | |
199 | #endif | |
200 | /* these two functions are unimplemented currently [josh] */ | |
201 | ||
72755c71 WD |
202 | /* -------------------------------------------------------------------- */ |
203 | /* L1 i-cache */ | |
1df49e27 WD |
204 | |
205 | int | |
206 | checkicache(void) | |
207 | { | |
208 | return 0; /* XXX */ | |
209 | } | |
210 | ||
72755c71 WD |
211 | /* -------------------------------------------------------------------- */ |
212 | /* L1 d-cache */ | |
1df49e27 WD |
213 | |
214 | int | |
215 | checkdcache(void) | |
216 | { | |
217 | return 0; /* XXX */ | |
218 | } | |
219 | ||
72755c71 | 220 | /* -------------------------------------------------------------------- */ |
1df49e27 WD |
221 | |
222 | static inline void | |
223 | soft_restart(unsigned long addr) | |
224 | { | |
225 | /* SRR0 has system reset vector, SRR1 has default MSR value */ | |
226 | /* rfi restores MSR from SRR1 and sets the PC to the SRR0 value */ | |
227 | ||
228 | __asm__ __volatile__ ("mtspr 26, %0" :: "r" (addr)); | |
229 | __asm__ __volatile__ ("li 4, (1 << 6)" ::: "r4"); | |
230 | __asm__ __volatile__ ("mtspr 27, 4"); | |
231 | __asm__ __volatile__ ("rfi"); | |
232 | ||
233 | while(1); /* not reached */ | |
234 | } | |
235 | ||
236 | ||
237 | #if !defined(CONFIG_PCIPPC2) && \ | |
238 | !defined(CONFIG_BAB7xx) && \ | |
f5e0d039 HS |
239 | !defined(CONFIG_ELPPC) && \ |
240 | !defined(CONFIG_PPMC7XX) | |
1df49e27 WD |
241 | /* no generic way to do board reset. simply call soft_reset. */ |
242 | void | |
8bde7f77 | 243 | do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) |
1df49e27 | 244 | { |
dd520bf3 | 245 | ulong addr; |
1df49e27 WD |
246 | /* flush and disable I/D cache */ |
247 | __asm__ __volatile__ ("mfspr 3, 1008" ::: "r3"); | |
248 | __asm__ __volatile__ ("ori 5, 5, 0xcc00" ::: "r5"); | |
249 | __asm__ __volatile__ ("ori 4, 3, 0xc00" ::: "r4"); | |
250 | __asm__ __volatile__ ("andc 5, 3, 5" ::: "r5"); | |
251 | __asm__ __volatile__ ("sync"); | |
252 | __asm__ __volatile__ ("mtspr 1008, 4"); | |
253 | __asm__ __volatile__ ("isync"); | |
254 | __asm__ __volatile__ ("sync"); | |
255 | __asm__ __volatile__ ("mtspr 1008, 5"); | |
256 | __asm__ __volatile__ ("isync"); | |
257 | __asm__ __volatile__ ("sync"); | |
258 | ||
259 | #ifdef CFG_RESET_ADDRESS | |
260 | addr = CFG_RESET_ADDRESS; | |
261 | #else | |
262 | /* | |
263 | * note: when CFG_MONITOR_BASE points to a RAM address, | |
264 | * CFG_MONITOR_BASE - sizeof (ulong) is usually a valid | |
265 | * address. Better pick an address known to be invalid on your | |
266 | * system and assign it to CFG_RESET_ADDRESS. | |
267 | */ | |
268 | addr = CFG_MONITOR_BASE - sizeof (ulong); | |
269 | #endif | |
270 | soft_restart(addr); | |
271 | while(1); /* not reached */ | |
272 | } | |
273 | #endif | |
274 | ||
275 | /* ------------------------------------------------------------------------- */ | |
276 | ||
277 | /* | |
278 | * For the 7400 the TB clock runs at 1/4 the cpu bus speed. | |
279 | */ | |
4c52783b | 280 | #if defined(CONFIG_AMIGAONEG3SE) || defined(CFG_CONFIG_BUS_CLK) |
c7de829c | 281 | unsigned long get_tbclk(void) |
1df49e27 | 282 | { |
c7de829c | 283 | return (gd->bus_clk / 4); |
1df49e27 | 284 | } |
4c52783b | 285 | #else /* ! CONFIG_AMIGAONEG3SE and !CFG_CONFIG_BUS_CLK*/ |
1df49e27 | 286 | |
c7de829c WD |
287 | unsigned long get_tbclk (void) |
288 | { | |
289 | return CFG_BUS_HZ / 4; | |
290 | } | |
4c52783b | 291 | #endif /* CONFIG_AMIGAONEG3SE or CFG_CONFIG_BUS_CLK*/ |
1df49e27 | 292 | /* ------------------------------------------------------------------------- */ |
1df49e27 WD |
293 | #if defined(CONFIG_WATCHDOG) |
294 | #if !defined(CONFIG_PCIPPC2) && !defined(CONFIG_BAB7xx) | |
295 | void | |
296 | watchdog_reset(void) | |
297 | { | |
298 | ||
299 | } | |
300 | #endif /* !CONFIG_PCIPPC2 && !CONFIG_BAB7xx */ | |
301 | #endif /* CONFIG_WATCHDOG */ | |
302 | ||
303 | /* ------------------------------------------------------------------------- */ | |
4c52783b | 304 | |
589c0427 GVB |
305 | #ifdef CONFIG_OF_LIBFDT |
306 | void ft_cpu_setup(void *blob, bd_t *bd) | |
4c52783b | 307 | { |
589c0427 GVB |
308 | do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, |
309 | "timebase-frequency", bd->bi_busfreq / 4, 1); | |
310 | do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, | |
311 | "bus-frequency", bd->bi_busfreq, 1); | |
312 | do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, | |
313 | "clock-frequency", bd->bi_intfreq, 1); | |
647d3c3e | 314 | |
589c0427 | 315 | fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize); |
4c52783b | 316 | |
589c0427 | 317 | fdt_fixup_ethernet(blob, bd); |
4c52783b | 318 | } |
319 | #endif | |
320 | /* ------------------------------------------------------------------------- */ |