]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - cpu/ppc4xx/cpu.c
(no commit message)
[karo-tx-uboot.git] / cpu / ppc4xx / cpu.c
1 /*
2  * (C) Copyright 2000-2003
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
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 specific code
26  *
27  * written or collected and sometimes rewritten by
28  * Magnus Damm <damm@bitsmart.com>
29  *
30  * minor modifications by
31  * Wolfgang Denk <wd@denx.de>
32  */
33
34 #include <common.h>
35 #include <watchdog.h>
36 #include <command.h>
37 #include <asm/cache.h>
38 #include <ppc4xx.h>
39
40
41 #if defined(CONFIG_440)
42 #define FREQ_EBC                (sys_info.freqEPB)
43 #else
44 #define FREQ_EBC                (sys_info.freqPLB / sys_info.pllExtBusDiv)
45 #endif
46
47 #if defined(CONFIG_405GP) || defined(CONFIG_440EP) || defined(CONFIG_440GR)
48
49 #define PCI_ASYNC
50
51 int pci_async_enabled(void)
52 {
53 #if defined(CONFIG_405GP)
54         return (mfdcr(strap) & PSR_PCI_ASYNC_EN);
55 #endif
56
57 #if defined(CONFIG_440EP) || defined(CONFIG_440GR)
58         unsigned long val;
59
60         mfsdr(sdr_sdstp1, val);
61         return (val & SDR0_SDSTP1_PAME_MASK);
62 #endif
63 }
64 #endif
65
66 #if defined(CONFIG_PCI) && !defined(CONFIG_IOP480) && !defined(CONFIG_405)
67 int pci_arbiter_enabled(void)
68 {
69 #if defined(CONFIG_405GP)
70         return (mfdcr(strap) & PSR_PCI_ARBIT_EN);
71 #endif
72
73 #if defined(CONFIG_405EP)
74         return (mfdcr(cpc0_pci) & CPC0_PCI_ARBIT_EN);
75 #endif
76
77 #if defined(CONFIG_440GP)
78         return (mfdcr(cpc0_strp1) & CPC0_STRP1_PAE_MASK);
79 #endif
80
81 #if defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SP)
82         unsigned long val;
83
84         mfsdr(sdr_sdstp1, val);
85         return (val & SDR0_SDSTP1_PAE_MASK);
86 #endif
87 }
88 #endif
89
90 #if defined(CONFIG_405EP)|| defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
91         defined(CONFIG_440GX) || defined(CONFIG_440SP)
92
93 #define I2C_BOOTROM
94
95 int i2c_bootrom_enabled(void)
96 {
97 #if defined(CONFIG_405EP)
98         return (mfdcr(cpc0_boot) & CPC0_BOOT_SEP);
99 #endif
100
101 #if defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SP)
102         unsigned long val;
103
104         mfsdr(sdr_sdcs, val);
105         return (val & SDR0_SDCS_SDD);
106 #endif
107 }
108 #endif
109
110
111 #if defined(CONFIG_440)
112 static int do_chip_reset(unsigned long sys0, unsigned long sys1);
113 #endif
114
115
116 int checkcpu (void)
117 {
118 #if !defined(CONFIG_405)        /* not used on Xilinx 405 FPGA implementations */
119         DECLARE_GLOBAL_DATA_PTR;
120         uint pvr = get_pvr();
121         ulong clock = gd->cpu_clk;
122         char buf[32];
123
124 #if !defined(CONFIG_IOP480)
125         sys_info_t sys_info;
126
127         puts ("CPU:   ");
128
129         get_sys_info(&sys_info);
130
131         puts("AMCC PowerPC 4");
132
133 #if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405EP)
134         puts("05");
135 #endif
136 #if defined(CONFIG_440)
137         puts("40");
138 #endif
139
140         switch (pvr) {
141         case PVR_405GP_RB:
142                 puts("GP Rev. B");
143                 break;
144
145         case PVR_405GP_RC:
146                 puts("GP Rev. C");
147                 break;
148
149         case PVR_405GP_RD:
150                 puts("GP Rev. D");
151                 break;
152
153 #ifdef CONFIG_405GP
154         case PVR_405GP_RE: /* 405GP rev E and 405CR rev C have same PVR */
155                 puts("GP Rev. E");
156                 break;
157 #endif
158
159         case PVR_405CR_RA:
160                 puts("CR Rev. A");
161                 break;
162
163         case PVR_405CR_RB:
164                 puts("CR Rev. B");
165                 break;
166
167 #ifdef CONFIG_405CR
168         case PVR_405CR_RC: /* 405GP rev E and 405CR rev C have same PVR */
169                 puts("CR Rev. C");
170                 break;
171 #endif
172
173         case PVR_405GPR_RB:
174                 puts("GPr Rev. B");
175                 break;
176
177         case PVR_405EP_RB:
178                 puts("EP Rev. B");
179                 break;
180
181 #if defined(CONFIG_440)
182         case PVR_440GP_RB:
183                 puts("GP Rev. B");
184                 /* See errata 1.12: CHIP_4 */
185                 if ((mfdcr(cpc0_sys0) != mfdcr(cpc0_strp0)) ||
186                     (mfdcr(cpc0_sys1) != mfdcr(cpc0_strp1)) ){
187                         puts (  "\n\t CPC0_SYSx DCRs corrupted. "
188                                 "Resetting chip ...\n");
189                         udelay( 1000 * 1000 ); /* Give time for serial buf to clear */
190                         do_chip_reset ( mfdcr(cpc0_strp0),
191                                         mfdcr(cpc0_strp1) );
192                 }
193                 break;
194
195         case PVR_440GP_RC:
196                 puts("GP Rev. C");
197                 break;
198
199         case PVR_440GX_RA:
200                 puts("GX Rev. A");
201                 break;
202
203         case PVR_440GX_RB:
204                 puts("GX Rev. B");
205                 break;
206
207         case PVR_440GX_RC:
208                 puts("GX Rev. C");
209                 break;
210
211         case PVR_440GX_RF:
212                 puts("GX Rev. F");
213                 break;
214
215         case PVR_440EP_RA:
216                 puts("EP Rev. A");
217                 break;
218
219 #ifdef CONFIG_440EP
220         case PVR_440EP_RB: /* 440EP rev B and 440GR rev A have same PVR */
221                 puts("EP Rev. B");
222                 break;
223 #endif /*  CONFIG_440EP */
224
225 #ifdef CONFIG_440GR
226         case PVR_440GR_RA: /* 440EP rev B and 440GR rev A have same PVR */
227                 puts("GR Rev. A");
228                 break;
229 #endif /* CONFIG_440GR */
230 #endif /* CONFIG_440 */
231
232         case PVR_440SP_RA:
233                 puts("SP Rev. A");
234                 break;
235
236         case PVR_440SP_RB:
237                 puts("SP Rev. B");
238                 break;
239
240         default:
241                 printf (" UNKNOWN (PVR=%08x)", pvr);
242                 break;
243         }
244
245         printf (" at %s MHz (PLB=%lu, OPB=%lu, EBC=%lu MHz)\n", strmhz(buf, clock),
246                sys_info.freqPLB / 1000000,
247                sys_info.freqPLB / sys_info.pllOpbDiv / 1000000,
248                FREQ_EBC / 1000000);
249
250 #if defined(I2C_BOOTROM)
251         printf ("       I2C boot EEPROM %sabled\n", i2c_bootrom_enabled() ? "en" : "dis");
252 #endif
253
254 #if defined(CONFIG_PCI)
255         printf ("       Internal PCI arbiter %sabled", pci_arbiter_enabled() ? "en" : "dis");
256 #endif
257
258 #if defined(PCI_ASYNC)
259         if (pci_async_enabled()) {
260                 printf (", PCI async ext clock used");
261         } else {
262                 printf (", PCI sync clock at %lu MHz",
263                        sys_info.freqPLB / sys_info.pllPciDiv / 1000000);
264         }
265 #endif
266
267 #if defined(CONFIG_PCI)
268         putc('\n');
269 #endif
270
271 #if defined(CONFIG_405EP)
272         printf ("       16 kB I-Cache 16 kB D-Cache");
273 #elif defined(CONFIG_440)
274         printf ("       32 kB I-Cache 32 kB D-Cache");
275 #else
276         printf ("       16 kB I-Cache %d kB D-Cache",
277                 ((pvr | 0x00000001) == PVR_405GPR_RB) ? 16 : 8);
278 #endif
279 #endif /* !defined(CONFIG_IOP480) */
280
281 #if defined(CONFIG_IOP480)
282         printf ("PLX IOP480 (PVR=%08x)", pvr);
283         printf (" at %s MHz:", strmhz(buf, clock));
284         printf (" %u kB I-Cache", 4);
285         printf (" %u kB D-Cache", 2);
286 #endif
287
288 #endif /* !defined(CONFIG_405) */
289
290         putc ('\n');
291
292         return 0;
293 }
294
295
296 /* ------------------------------------------------------------------------- */
297
298 int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
299 {
300 #if defined(CONFIG_YOSEMITE) || defined(CONFIG_YELLOWSTONE)
301         /*give reset to BCSR*/
302         *(unsigned char*)(CFG_BCSR_BASE | 0x06) = 0x09;
303
304 #else
305
306         /*
307          * Initiate system reset in debug control register DBCR
308          */
309         __asm__ __volatile__("lis   3, 0x3000" ::: "r3");
310 #if defined(CONFIG_440)
311         __asm__ __volatile__("mtspr 0x134, 3");
312 #else
313         __asm__ __volatile__("mtspr 0x3f2, 3");
314 #endif
315
316 #endif/* defined(CONFIG_YOSEMITE) || defined(CONFIG_YELLOWSTONE)*/
317         return 1;
318 }
319
320 #if defined(CONFIG_440)
321 static int do_chip_reset (unsigned long sys0, unsigned long sys1)
322 {
323         /* Changes to cpc0_sys0 and cpc0_sys1 require chip
324          * reset.
325          */
326         mtdcr (cntrl0, mfdcr (cntrl0) | 0x80000000);    /* Set SWE */
327         mtdcr (cpc0_sys0, sys0);
328         mtdcr (cpc0_sys1, sys1);
329         mtdcr (cntrl0, mfdcr (cntrl0) & ~0x80000000);   /* Clr SWE */
330         mtspr (dbcr0, 0x20000000);      /* Reset the chip */
331
332         return 1;
333 }
334 #endif
335
336
337 /*
338  * Get timebase clock frequency
339  */
340 unsigned long get_tbclk (void)
341 {
342 #if !defined(CONFIG_IOP480)
343         sys_info_t  sys_info;
344
345         get_sys_info(&sys_info);
346         return (sys_info.freqProcessor);
347 #else
348         return (66000000);
349 #endif
350
351 }
352
353
354 #if defined(CONFIG_WATCHDOG)
355 void
356 watchdog_reset(void)
357 {
358         int re_enable = disable_interrupts();
359         reset_4xx_watchdog();
360         if (re_enable) enable_interrupts();
361 }
362
363 void
364 reset_4xx_watchdog(void)
365 {
366         /*
367          * Clear TSR(WIS) bit
368          */
369         mtspr(tsr, 0x40000000);
370 }
371 #endif  /* CONFIG_WATCHDOG */