Merge branch 'master' of git+ssh://10.10.0.7/home/wd/git/u-boot/master
[pandora-u-boot.git] / cpu / ppc4xx / cpu.c
1 /*
2  * (C) Copyright 2000-2007
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 DECLARE_GLOBAL_DATA_PTR;
41
42 void board_reset(void);
43
44 #if defined(CONFIG_405GP) || \
45     defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
46     defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
47
48 #define PCI_ASYNC
49
50 static int pci_async_enabled(void)
51 {
52 #if defined(CONFIG_405GP)
53         return (mfdcr(strap) & PSR_PCI_ASYNC_EN);
54 #endif
55
56 #if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
57     defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
58     defined(CONFIG_460EX) || defined(CONFIG_460GT)
59         unsigned long val;
60
61         mfsdr(sdr_sdstp1, val);
62         return (val & SDR0_SDSTP1_PAME_MASK);
63 #endif
64 }
65 #endif
66
67 #if defined(CONFIG_PCI) && !defined(CONFIG_IOP480) && \
68     !defined(CONFIG_405) && !defined(CONFIG_405EX)
69 static int pci_arbiter_enabled(void)
70 {
71 #if defined(CONFIG_405GP)
72         return (mfdcr(strap) & PSR_PCI_ARBIT_EN);
73 #endif
74
75 #if defined(CONFIG_405EP)
76         return (mfdcr(cpc0_pci) & CPC0_PCI_ARBIT_EN);
77 #endif
78
79 #if defined(CONFIG_440GP)
80         return (mfdcr(cpc0_strp1) & CPC0_STRP1_PAE_MASK);
81 #endif
82
83 #if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
84         unsigned long val;
85
86         mfsdr(sdr_xcr, val);
87         return (val & 0x80000000);
88 #endif
89 #if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
90     defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
91     defined(CONFIG_460EX) || defined(CONFIG_460GT)
92         unsigned long val;
93
94         mfsdr(sdr_pci0, val);
95         return (val & 0x80000000);
96 #endif
97 }
98 #endif
99
100 #if defined(CONFIG_405EP)
101 #define I2C_BOOTROM
102
103 static int i2c_bootrom_enabled(void)
104 {
105 #if defined(CONFIG_405EP)
106         return (mfdcr(cpc0_boot) & CPC0_BOOT_SEP);
107 #else
108         unsigned long val;
109
110         mfsdr(sdr_sdcs, val);
111         return (val & SDR0_SDCS_SDD);
112 #endif
113 }
114 #endif
115
116 #if defined(CONFIG_440GX)
117 #define SDR0_PINSTP_SHIFT       29
118 static char *bootstrap_str[] = {
119         "EBC (16 bits)",
120         "EBC (8 bits)",
121         "EBC (32 bits)",
122         "EBC (8 bits)",
123         "PCI",
124         "I2C (Addr 0x54)",
125         "Reserved",
126         "I2C (Addr 0x50)",
127 };
128 static char bootstrap_char[] = { 'A', 'B', 'C', 'B', 'D', 'E', 'x', 'F' };
129 #endif
130
131 #if defined(CONFIG_440SP) || defined(CONFIG_440SPE)
132 #define SDR0_PINSTP_SHIFT       30
133 static char *bootstrap_str[] = {
134         "EBC (8 bits)",
135         "PCI",
136         "I2C (Addr 0x54)",
137         "I2C (Addr 0x50)",
138 };
139 static char bootstrap_char[] = { 'A', 'B', 'C', 'D'};
140 #endif
141
142 #if defined(CONFIG_440EP) || defined(CONFIG_440GR)
143 #define SDR0_PINSTP_SHIFT       29
144 static char *bootstrap_str[] = {
145         "EBC (8 bits)",
146         "PCI",
147         "NAND (8 bits)",
148         "EBC (16 bits)",
149         "EBC (16 bits)",
150         "I2C (Addr 0x54)",
151         "PCI",
152         "I2C (Addr 0x52)",
153 };
154 static char bootstrap_char[] = { 'A', 'B', 'C', 'D', 'E', 'G', 'F', 'H' };
155 #endif
156
157 #if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
158 #define SDR0_PINSTP_SHIFT       29
159 static char *bootstrap_str[] = {
160         "EBC (8 bits)",
161         "EBC (16 bits)",
162         "EBC (16 bits)",
163         "NAND (8 bits)",
164         "PCI",
165         "I2C (Addr 0x54)",
166         "PCI",
167         "I2C (Addr 0x52)",
168 };
169 static char bootstrap_char[] = { 'A', 'B', 'C', 'D', 'E', 'G', 'F', 'H' };
170 #endif
171
172 #if defined(CONFIG_460EX) || defined(CONFIG_460GT)
173 #define SDR0_PINSTP_SHIFT       29
174 static char *bootstrap_str[] = {
175         "EBC (8 bits)",
176         "EBC (16 bits)",
177         "PCI",
178         "PCI",
179         "EBC (16 bits)",
180         "NAND (8 bits)",
181         "I2C (Addr 0x54)",      /* A8 */
182         "I2C (Addr 0x52)",      /* A4 */
183 };
184 static char bootstrap_char[] = { 'A', 'B', 'C', 'D', 'E', 'G', 'F', 'H' };
185 #endif
186
187 #if defined(CONFIG_405EZ)
188 #define SDR0_PINSTP_SHIFT       28
189 static char *bootstrap_str[] = {
190         "EBC (8 bits)",
191         "SPI (fast)",
192         "NAND (512 page, 4 addr cycle)",
193         "I2C (Addr 0x50)",
194         "EBC (32 bits)",
195         "I2C (Addr 0x50)",
196         "NAND (2K page, 5 addr cycle)",
197         "I2C (Addr 0x50)",
198         "EBC (16 bits)",
199         "Reserved",
200         "NAND (2K page, 4 addr cycle)",
201         "I2C (Addr 0x50)",
202         "NAND (512 page, 3 addr cycle)",
203         "I2C (Addr 0x50)",
204         "SPI (slow)",
205         "I2C (Addr 0x50)",
206 };
207 static char bootstrap_char[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', \
208                                  'I', 'x', 'K', 'L', 'M', 'N', 'O', 'P' };
209 #endif
210
211 #if defined(CONFIG_405EX)
212 #define SDR0_PINSTP_SHIFT       29
213 static char *bootstrap_str[] = {
214         "EBC (8 bits)",
215         "EBC (16 bits)",
216         "EBC (16 bits)",
217         "NAND (8 bits)",
218         "NAND (8 bits)",
219         "I2C (Addr 0x54)",
220         "EBC (8 bits)",
221         "I2C (Addr 0x52)",
222 };
223 static char bootstrap_char[] = { 'A', 'B', 'C', 'D', 'E', 'G', 'F', 'H' };
224 #endif
225
226 #if defined(SDR0_PINSTP_SHIFT)
227 static int bootstrap_option(void)
228 {
229         unsigned long val;
230
231         mfsdr(SDR_PINSTP, val);
232         return ((val & 0xf0000000) >> SDR0_PINSTP_SHIFT);
233 }
234 #endif /* SDR0_PINSTP_SHIFT */
235
236
237 #if defined(CONFIG_440)
238 static int do_chip_reset (unsigned long sys0, unsigned long sys1)
239 {
240         /* Changes to cpc0_sys0 and cpc0_sys1 require chip
241          * reset.
242          */
243         mtdcr (cntrl0, mfdcr (cntrl0) | 0x80000000);    /* Set SWE */
244         mtdcr (cpc0_sys0, sys0);
245         mtdcr (cpc0_sys1, sys1);
246         mtdcr (cntrl0, mfdcr (cntrl0) & ~0x80000000);   /* Clr SWE */
247         mtspr (dbcr0, 0x20000000);      /* Reset the chip */
248
249         return 1;
250 }
251 #endif
252
253
254 int checkcpu (void)
255 {
256 #if !defined(CONFIG_405)        /* not used on Xilinx 405 FPGA implementations */
257         uint pvr = get_pvr();
258         ulong clock = gd->cpu_clk;
259         char buf[32];
260
261 #if !defined(CONFIG_IOP480)
262         char addstr[64] = "";
263         sys_info_t sys_info;
264
265         puts ("CPU:   ");
266
267         get_sys_info(&sys_info);
268
269         puts("AMCC PowerPC 4");
270
271 #if defined(CONFIG_405GP) || defined(CONFIG_405CR) || \
272     defined(CONFIG_405EP) || defined(CONFIG_405EZ) || \
273     defined(CONFIG_405EX)
274         puts("05");
275 #endif
276 #if defined(CONFIG_440)
277 #if defined(CONFIG_460EX) || defined(CONFIG_460GT)
278         puts("60");
279 #else
280         puts("40");
281 #endif
282 #endif
283
284         switch (pvr) {
285         case PVR_405GP_RB:
286                 puts("GP Rev. B");
287                 break;
288
289         case PVR_405GP_RC:
290                 puts("GP Rev. C");
291                 break;
292
293         case PVR_405GP_RD:
294                 puts("GP Rev. D");
295                 break;
296
297 #ifdef CONFIG_405GP
298         case PVR_405GP_RE: /* 405GP rev E and 405CR rev C have same PVR */
299                 puts("GP Rev. E");
300                 break;
301 #endif
302
303         case PVR_405CR_RA:
304                 puts("CR Rev. A");
305                 break;
306
307         case PVR_405CR_RB:
308                 puts("CR Rev. B");
309                 break;
310
311 #ifdef CONFIG_405CR
312         case PVR_405CR_RC: /* 405GP rev E and 405CR rev C have same PVR */
313                 puts("CR Rev. C");
314                 break;
315 #endif
316
317         case PVR_405GPR_RB:
318                 puts("GPr Rev. B");
319                 break;
320
321         case PVR_405EP_RB:
322                 puts("EP Rev. B");
323                 break;
324
325         case PVR_405EZ_RA:
326                 puts("EZ Rev. A");
327                 break;
328
329         case PVR_405EX1_RA:
330                 puts("EX Rev. A");
331                 strcpy(addstr, "Security support");
332                 break;
333
334         case PVR_405EX2_RA:
335                 puts("EX Rev. A");
336                 strcpy(addstr, "No Security support");
337                 break;
338
339         case PVR_405EXR1_RA:
340                 puts("EXr Rev. A");
341                 strcpy(addstr, "Security support");
342                 break;
343
344         case PVR_405EXR2_RA:
345                 puts("EXr Rev. A");
346                 strcpy(addstr, "No Security support");
347                 break;
348
349 #if defined(CONFIG_440)
350         case PVR_440GP_RB:
351                 puts("GP Rev. B");
352                 /* See errata 1.12: CHIP_4 */
353                 if ((mfdcr(cpc0_sys0) != mfdcr(cpc0_strp0)) ||
354                     (mfdcr(cpc0_sys1) != mfdcr(cpc0_strp1)) ){
355                         puts (  "\n\t CPC0_SYSx DCRs corrupted. "
356                                 "Resetting chip ...\n");
357                         udelay( 1000 * 1000 ); /* Give time for serial buf to clear */
358                         do_chip_reset ( mfdcr(cpc0_strp0),
359                                         mfdcr(cpc0_strp1) );
360                 }
361                 break;
362
363         case PVR_440GP_RC:
364                 puts("GP Rev. C");
365                 break;
366
367         case PVR_440GX_RA:
368                 puts("GX Rev. A");
369                 break;
370
371         case PVR_440GX_RB:
372                 puts("GX Rev. B");
373                 break;
374
375         case PVR_440GX_RC:
376                 puts("GX Rev. C");
377                 break;
378
379         case PVR_440GX_RF:
380                 puts("GX Rev. F");
381                 break;
382
383         case PVR_440EP_RA:
384                 puts("EP Rev. A");
385                 break;
386
387 #ifdef CONFIG_440EP
388         case PVR_440EP_RB: /* 440EP rev B and 440GR rev A have same PVR */
389                 puts("EP Rev. B");
390                 break;
391
392         case PVR_440EP_RC: /* 440EP rev C and 440GR rev B have same PVR */
393                 puts("EP Rev. C");
394                 break;
395 #endif /*  CONFIG_440EP */
396
397 #ifdef CONFIG_440GR
398         case PVR_440GR_RA: /* 440EP rev B and 440GR rev A have same PVR */
399                 puts("GR Rev. A");
400                 break;
401
402         case PVR_440GR_RB: /* 440EP rev C and 440GR rev B have same PVR */
403                 puts("GR Rev. B");
404                 break;
405 #endif /* CONFIG_440GR */
406 #endif /* CONFIG_440 */
407
408 #ifdef CONFIG_440EPX
409         case PVR_440EPX1_RA: /* 440EPx rev A and 440GRx rev A have same PVR */
410                 puts("EPx Rev. A");
411                 strcpy(addstr, "Security/Kasumi support");
412                 break;
413
414         case PVR_440EPX2_RA: /* 440EPx rev A and 440GRx rev A have same PVR */
415                 puts("EPx Rev. A");
416                 strcpy(addstr, "No Security/Kasumi support");
417                 break;
418 #endif /* CONFIG_440EPX */
419
420 #ifdef CONFIG_440GRX
421         case PVR_440GRX1_RA: /* 440EPx rev A and 440GRx rev A have same PVR */
422                 puts("GRx Rev. A");
423                 strcpy(addstr, "Security/Kasumi support");
424                 break;
425
426         case PVR_440GRX2_RA: /* 440EPx rev A and 440GRx rev A have same PVR */
427                 puts("GRx Rev. A");
428                 strcpy(addstr, "No Security/Kasumi support");
429                 break;
430 #endif /* CONFIG_440GRX */
431
432         case PVR_440SP_6_RAB:
433                 puts("SP Rev. A/B");
434                 strcpy(addstr, "RAID 6 support");
435                 break;
436
437         case PVR_440SP_RAB:
438                 puts("SP Rev. A/B");
439                 strcpy(addstr, "No RAID 6 support");
440                 break;
441
442         case PVR_440SP_6_RC:
443                 puts("SP Rev. C");
444                 strcpy(addstr, "RAID 6 support");
445                 break;
446
447         case PVR_440SP_RC:
448                 puts("SP Rev. C");
449                 strcpy(addstr, "No RAID 6 support");
450                 break;
451
452         case PVR_440SPe_6_RA:
453                 puts("SPe Rev. A");
454                 strcpy(addstr, "RAID 6 support");
455                 break;
456
457         case PVR_440SPe_RA:
458                 puts("SPe Rev. A");
459                 strcpy(addstr, "No RAID 6 support");
460                 break;
461
462         case PVR_440SPe_6_RB:
463                 puts("SPe Rev. B");
464                 strcpy(addstr, "RAID 6 support");
465                 break;
466
467         case PVR_440SPe_RB:
468                 puts("SPe Rev. B");
469                 strcpy(addstr, "No RAID 6 support");
470                 break;
471
472         case PVR_460EX_RA:
473                 puts("EX Rev. A");
474                 strcpy(addstr, "No Security/Kasumi support");
475                 break;
476
477         case PVR_460EX_SE_RA:
478                 puts("EX Rev. A");
479                 strcpy(addstr, "Security/Kasumi support");
480                 break;
481
482         case PVR_460GT_RA:
483                 puts("GT Rev. A");
484                 strcpy(addstr, "No Security/Kasumi support");
485                 break;
486
487         case PVR_460GT_SE_RA:
488                 puts("GT Rev. A");
489                 strcpy(addstr, "Security/Kasumi support");
490                 break;
491
492         default:
493                 printf (" UNKNOWN (PVR=%08x)", pvr);
494                 break;
495         }
496
497         printf (" at %s MHz (PLB=%lu, OPB=%lu, EBC=%lu MHz)\n", strmhz(buf, clock),
498                 sys_info.freqPLB / 1000000,
499                 get_OPB_freq() / 1000000,
500                 sys_info.freqEBC / 1000000);
501
502         if (addstr[0] != 0)
503                 printf("       %s\n", addstr);
504
505 #if defined(I2C_BOOTROM)
506         printf ("       I2C boot EEPROM %sabled\n", i2c_bootrom_enabled() ? "en" : "dis");
507 #endif  /* I2C_BOOTROM */
508 #if defined(SDR0_PINSTP_SHIFT)
509         printf ("       Bootstrap Option %c - ", bootstrap_char[bootstrap_option()]);
510         printf ("Boot ROM Location %s\n", bootstrap_str[bootstrap_option()]);
511 #endif  /* SDR0_PINSTP_SHIFT */
512
513 #if defined(CONFIG_PCI) && !defined(CONFIG_405EX)
514         printf ("       Internal PCI arbiter %sabled", pci_arbiter_enabled() ? "en" : "dis");
515 #endif
516
517 #if defined(PCI_ASYNC)
518         if (pci_async_enabled()) {
519                 printf (", PCI async ext clock used");
520         } else {
521                 printf (", PCI sync clock at %lu MHz",
522                        sys_info.freqPLB / sys_info.pllPciDiv / 1000000);
523         }
524 #endif
525
526 #if defined(CONFIG_PCI) && !defined(CONFIG_405EX)
527         putc('\n');
528 #endif
529
530 #if defined(CONFIG_405EP) || defined(CONFIG_405EZ) || defined(CONFIG_405EX)
531         printf ("       16 kB I-Cache 16 kB D-Cache");
532 #elif defined(CONFIG_440)
533         printf ("       32 kB I-Cache 32 kB D-Cache");
534 #else
535         printf ("       16 kB I-Cache %d kB D-Cache",
536                 ((pvr | 0x00000001) == PVR_405GPR_RB) ? 16 : 8);
537 #endif
538 #endif /* !defined(CONFIG_IOP480) */
539
540 #if defined(CONFIG_IOP480)
541         printf ("PLX IOP480 (PVR=%08x)", pvr);
542         printf (" at %s MHz:", strmhz(buf, clock));
543         printf (" %u kB I-Cache", 4);
544         printf (" %u kB D-Cache", 2);
545 #endif
546
547 #endif /* !defined(CONFIG_405) */
548
549         putc ('\n');
550
551         return 0;
552 }
553
554 int ppc440spe_revB() {
555         unsigned int pvr;
556
557         pvr = get_pvr();
558         if ((pvr == PVR_440SPe_6_RB) || (pvr == PVR_440SPe_RB))
559                 return 1;
560         else
561                 return 0;
562 }
563
564 /* ------------------------------------------------------------------------- */
565
566 int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
567 {
568 #if defined(CONFIG_BOARD_RESET)
569         board_reset();
570 #else
571 #if defined(CFG_4xx_RESET_TYPE)
572         mtspr(dbcr0, CFG_4xx_RESET_TYPE << 28);
573 #else
574         /*
575          * Initiate system reset in debug control register DBCR
576          */
577         mtspr(dbcr0, 0x30000000);
578 #endif /* defined(CFG_4xx_RESET_TYPE) */
579 #endif /* defined(CONFIG_BOARD_RESET) */
580
581         return 1;
582 }
583
584
585 /*
586  * Get timebase clock frequency
587  */
588 unsigned long get_tbclk (void)
589 {
590 #if !defined(CONFIG_IOP480)
591         sys_info_t  sys_info;
592
593         get_sys_info(&sys_info);
594         return (sys_info.freqProcessor);
595 #else
596         return (66000000);
597 #endif
598
599 }
600
601
602 #if defined(CONFIG_WATCHDOG)
603 void watchdog_reset(void)
604 {
605         int re_enable = disable_interrupts();
606         reset_4xx_watchdog();
607         if (re_enable) enable_interrupts();
608 }
609
610 void reset_4xx_watchdog(void)
611 {
612         /*
613          * Clear TSR(WIS) bit
614          */
615         mtspr(tsr, 0x40000000);
616 }
617 #endif  /* CONFIG_WATCHDOG */