ef32bc64d29a4a151f4764ac889d68c4759a637a
[platform/kernel/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_460SX)
188 #define SDR0_PINSTP_SHIFT       29
189 static char *bootstrap_str[] = {
190         "EBC (8 bits)",
191         "EBC (16 bits)",
192         "EBC (32 bits)",
193         "NAND (8 bits)",
194         "I2C (Addr 0x54)",      /* A8 */
195         "I2C (Addr 0x52)",      /* A4 */
196 };
197 static char bootstrap_char[] = { 'A', 'B', 'C', 'D', 'E', 'G' };
198 #endif
199
200 #if defined(CONFIG_405EZ)
201 #define SDR0_PINSTP_SHIFT       28
202 static char *bootstrap_str[] = {
203         "EBC (8 bits)",
204         "SPI (fast)",
205         "NAND (512 page, 4 addr cycle)",
206         "I2C (Addr 0x50)",
207         "EBC (32 bits)",
208         "I2C (Addr 0x50)",
209         "NAND (2K page, 5 addr cycle)",
210         "I2C (Addr 0x50)",
211         "EBC (16 bits)",
212         "Reserved",
213         "NAND (2K page, 4 addr cycle)",
214         "I2C (Addr 0x50)",
215         "NAND (512 page, 3 addr cycle)",
216         "I2C (Addr 0x50)",
217         "SPI (slow)",
218         "I2C (Addr 0x50)",
219 };
220 static char bootstrap_char[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', \
221                                  'I', 'x', 'K', 'L', 'M', 'N', 'O', 'P' };
222 #endif
223
224 #if defined(CONFIG_405EX)
225 #define SDR0_PINSTP_SHIFT       29
226 static char *bootstrap_str[] = {
227         "EBC (8 bits)",
228         "EBC (16 bits)",
229         "EBC (16 bits)",
230         "NAND (8 bits)",
231         "NAND (8 bits)",
232         "I2C (Addr 0x54)",
233         "EBC (8 bits)",
234         "I2C (Addr 0x52)",
235 };
236 static char bootstrap_char[] = { 'A', 'B', 'C', 'D', 'E', 'G', 'F', 'H' };
237 #endif
238
239 #if defined(SDR0_PINSTP_SHIFT)
240 static int bootstrap_option(void)
241 {
242         unsigned long val;
243
244         mfsdr(SDR_PINSTP, val);
245         return ((val & 0xf0000000) >> SDR0_PINSTP_SHIFT);
246 }
247 #endif /* SDR0_PINSTP_SHIFT */
248
249
250 #if defined(CONFIG_440)
251 static int do_chip_reset (unsigned long sys0, unsigned long sys1)
252 {
253         /* Changes to cpc0_sys0 and cpc0_sys1 require chip
254          * reset.
255          */
256         mtdcr (cntrl0, mfdcr (cntrl0) | 0x80000000);    /* Set SWE */
257         mtdcr (cpc0_sys0, sys0);
258         mtdcr (cpc0_sys1, sys1);
259         mtdcr (cntrl0, mfdcr (cntrl0) & ~0x80000000);   /* Clr SWE */
260         mtspr (dbcr0, 0x20000000);      /* Reset the chip */
261
262         return 1;
263 }
264 #endif
265
266
267 int checkcpu (void)
268 {
269 #if !defined(CONFIG_405)        /* not used on Xilinx 405 FPGA implementations */
270         uint pvr = get_pvr();
271         ulong clock = gd->cpu_clk;
272         char buf[32];
273
274 #if !defined(CONFIG_IOP480)
275         char addstr[64] = "";
276         sys_info_t sys_info;
277
278         puts ("CPU:   ");
279
280         get_sys_info(&sys_info);
281
282         puts("AMCC PowerPC 4");
283
284 #if defined(CONFIG_405GP) || defined(CONFIG_405CR) || \
285     defined(CONFIG_405EP) || defined(CONFIG_405EZ) || \
286     defined(CONFIG_405EX)
287         puts("05");
288 #endif
289 #if defined(CONFIG_440)
290 #if defined(CONFIG_460EX) || defined(CONFIG_460GT)
291         puts("60");
292 #else
293         puts("40");
294 #endif
295 #endif
296
297         switch (pvr) {
298         case PVR_405GP_RB:
299                 puts("GP Rev. B");
300                 break;
301
302         case PVR_405GP_RC:
303                 puts("GP Rev. C");
304                 break;
305
306         case PVR_405GP_RD:
307                 puts("GP Rev. D");
308                 break;
309
310 #ifdef CONFIG_405GP
311         case PVR_405GP_RE: /* 405GP rev E and 405CR rev C have same PVR */
312                 puts("GP Rev. E");
313                 break;
314 #endif
315
316         case PVR_405CR_RA:
317                 puts("CR Rev. A");
318                 break;
319
320         case PVR_405CR_RB:
321                 puts("CR Rev. B");
322                 break;
323
324 #ifdef CONFIG_405CR
325         case PVR_405CR_RC: /* 405GP rev E and 405CR rev C have same PVR */
326                 puts("CR Rev. C");
327                 break;
328 #endif
329
330         case PVR_405GPR_RB:
331                 puts("GPr Rev. B");
332                 break;
333
334         case PVR_405EP_RB:
335                 puts("EP Rev. B");
336                 break;
337
338         case PVR_405EZ_RA:
339                 puts("EZ Rev. A");
340                 break;
341
342         case PVR_405EX1_RA:
343                 puts("EX Rev. A");
344                 strcpy(addstr, "Security support");
345                 break;
346
347         case PVR_405EX2_RA:
348                 puts("EX Rev. A");
349                 strcpy(addstr, "No Security support");
350                 break;
351
352         case PVR_405EXR1_RA:
353                 puts("EXr Rev. A");
354                 strcpy(addstr, "Security support");
355                 break;
356
357         case PVR_405EXR2_RA:
358                 puts("EXr Rev. A");
359                 strcpy(addstr, "No Security support");
360                 break;
361
362         case PVR_405EX1_RC:
363                 puts("EX Rev. C");
364                 strcpy(addstr, "Security support");
365                 break;
366
367         case PVR_405EX2_RC:
368                 puts("EX Rev. C");
369                 strcpy(addstr, "No Security support");
370                 break;
371
372         case PVR_405EXR1_RC:
373                 puts("EXr Rev. C");
374                 strcpy(addstr, "Security support");
375                 break;
376
377         case PVR_405EXR2_RC:
378                 puts("EXr Rev. C");
379                 strcpy(addstr, "No Security support");
380                 break;
381
382 #if defined(CONFIG_440)
383         case PVR_440GP_RB:
384                 puts("GP Rev. B");
385                 /* See errata 1.12: CHIP_4 */
386                 if ((mfdcr(cpc0_sys0) != mfdcr(cpc0_strp0)) ||
387                     (mfdcr(cpc0_sys1) != mfdcr(cpc0_strp1)) ){
388                         puts (  "\n\t CPC0_SYSx DCRs corrupted. "
389                                 "Resetting chip ...\n");
390                         udelay( 1000 * 1000 ); /* Give time for serial buf to clear */
391                         do_chip_reset ( mfdcr(cpc0_strp0),
392                                         mfdcr(cpc0_strp1) );
393                 }
394                 break;
395
396         case PVR_440GP_RC:
397                 puts("GP Rev. C");
398                 break;
399
400         case PVR_440GX_RA:
401                 puts("GX Rev. A");
402                 break;
403
404         case PVR_440GX_RB:
405                 puts("GX Rev. B");
406                 break;
407
408         case PVR_440GX_RC:
409                 puts("GX Rev. C");
410                 break;
411
412         case PVR_440GX_RF:
413                 puts("GX Rev. F");
414                 break;
415
416         case PVR_440EP_RA:
417                 puts("EP Rev. A");
418                 break;
419
420 #ifdef CONFIG_440EP
421         case PVR_440EP_RB: /* 440EP rev B and 440GR rev A have same PVR */
422                 puts("EP Rev. B");
423                 break;
424
425         case PVR_440EP_RC: /* 440EP rev C and 440GR rev B have same PVR */
426                 puts("EP Rev. C");
427                 break;
428 #endif /*  CONFIG_440EP */
429
430 #ifdef CONFIG_440GR
431         case PVR_440GR_RA: /* 440EP rev B and 440GR rev A have same PVR */
432                 puts("GR Rev. A");
433                 break;
434
435         case PVR_440GR_RB: /* 440EP rev C and 440GR rev B have same PVR */
436                 puts("GR Rev. B");
437                 break;
438 #endif /* CONFIG_440GR */
439 #endif /* CONFIG_440 */
440
441 #ifdef CONFIG_440EPX
442         case PVR_440EPX1_RA: /* 440EPx rev A and 440GRx rev A have same PVR */
443                 puts("EPx Rev. A");
444                 strcpy(addstr, "Security/Kasumi support");
445                 break;
446
447         case PVR_440EPX2_RA: /* 440EPx rev A and 440GRx rev A have same PVR */
448                 puts("EPx Rev. A");
449                 strcpy(addstr, "No Security/Kasumi support");
450                 break;
451 #endif /* CONFIG_440EPX */
452
453 #ifdef CONFIG_440GRX
454         case PVR_440GRX1_RA: /* 440EPx rev A and 440GRx rev A have same PVR */
455                 puts("GRx Rev. A");
456                 strcpy(addstr, "Security/Kasumi support");
457                 break;
458
459         case PVR_440GRX2_RA: /* 440EPx rev A and 440GRx rev A have same PVR */
460                 puts("GRx Rev. A");
461                 strcpy(addstr, "No Security/Kasumi support");
462                 break;
463 #endif /* CONFIG_440GRX */
464
465         case PVR_440SP_6_RAB:
466                 puts("SP Rev. A/B");
467                 strcpy(addstr, "RAID 6 support");
468                 break;
469
470         case PVR_440SP_RAB:
471                 puts("SP Rev. A/B");
472                 strcpy(addstr, "No RAID 6 support");
473                 break;
474
475         case PVR_440SP_6_RC:
476                 puts("SP Rev. C");
477                 strcpy(addstr, "RAID 6 support");
478                 break;
479
480         case PVR_440SP_RC:
481                 puts("SP Rev. C");
482                 strcpy(addstr, "No RAID 6 support");
483                 break;
484
485         case PVR_440SPe_6_RA:
486                 puts("SPe Rev. A");
487                 strcpy(addstr, "RAID 6 support");
488                 break;
489
490         case PVR_440SPe_RA:
491                 puts("SPe Rev. A");
492                 strcpy(addstr, "No RAID 6 support");
493                 break;
494
495         case PVR_440SPe_6_RB:
496                 puts("SPe Rev. B");
497                 strcpy(addstr, "RAID 6 support");
498                 break;
499
500         case PVR_440SPe_RB:
501                 puts("SPe Rev. B");
502                 strcpy(addstr, "No RAID 6 support");
503                 break;
504
505         case PVR_460EX_RA:
506                 puts("EX Rev. A");
507                 strcpy(addstr, "No Security/Kasumi support");
508                 break;
509
510         case PVR_460EX_SE_RA:
511                 puts("EX Rev. A");
512                 strcpy(addstr, "Security/Kasumi support");
513                 break;
514
515         case PVR_460GT_RA:
516                 puts("GT Rev. A");
517                 strcpy(addstr, "No Security/Kasumi support");
518                 break;
519
520         case PVR_460GT_SE_RA:
521                 puts("GT Rev. A");
522                 strcpy(addstr, "Security/Kasumi support");
523                 break;
524
525         case PVR_460SX_RA:
526                 puts("SX Rev. A");
527                 strcpy(addstr, "Security support");
528                 break;
529
530         case PVR_460SX_RA_V1:
531                 puts("SX Rev. A");
532                 strcpy(addstr, "No Security support");
533                 break;
534
535         case PVR_460GX_RA:
536                 puts("GX Rev. A");
537                 strcpy(addstr, "Security support");
538                 break;
539
540         case PVR_460GX_RA_V1:
541                 puts("GX Rev. A");
542                 strcpy(addstr, "No Security support");
543                 break;
544
545         default:
546                 printf (" UNKNOWN (PVR=%08x)", pvr);
547                 break;
548         }
549
550         printf (" at %s MHz (PLB=%lu, OPB=%lu, EBC=%lu MHz)\n", strmhz(buf, clock),
551                 sys_info.freqPLB / 1000000,
552                 get_OPB_freq() / 1000000,
553                 sys_info.freqEBC / 1000000);
554
555         if (addstr[0] != 0)
556                 printf("       %s\n", addstr);
557
558 #if defined(I2C_BOOTROM)
559         printf ("       I2C boot EEPROM %sabled\n", i2c_bootrom_enabled() ? "en" : "dis");
560 #endif  /* I2C_BOOTROM */
561 #if defined(SDR0_PINSTP_SHIFT)
562         printf ("       Bootstrap Option %c - ", bootstrap_char[bootstrap_option()]);
563         printf ("Boot ROM Location %s\n", bootstrap_str[bootstrap_option()]);
564 #endif  /* SDR0_PINSTP_SHIFT */
565
566 #if defined(CONFIG_PCI) && !defined(CONFIG_405EX)
567         printf ("       Internal PCI arbiter %sabled", pci_arbiter_enabled() ? "en" : "dis");
568 #endif
569
570 #if defined(PCI_ASYNC)
571         if (pci_async_enabled()) {
572                 printf (", PCI async ext clock used");
573         } else {
574                 printf (", PCI sync clock at %lu MHz",
575                        sys_info.freqPLB / sys_info.pllPciDiv / 1000000);
576         }
577 #endif
578
579 #if defined(CONFIG_PCI) && !defined(CONFIG_405EX)
580         putc('\n');
581 #endif
582
583 #if defined(CONFIG_405EP) || defined(CONFIG_405EZ) || defined(CONFIG_405EX)
584         printf ("       16 kB I-Cache 16 kB D-Cache");
585 #elif defined(CONFIG_440)
586         printf ("       32 kB I-Cache 32 kB D-Cache");
587 #else
588         printf ("       16 kB I-Cache %d kB D-Cache",
589                 ((pvr | 0x00000001) == PVR_405GPR_RB) ? 16 : 8);
590 #endif
591 #endif /* !defined(CONFIG_IOP480) */
592
593 #if defined(CONFIG_IOP480)
594         printf ("PLX IOP480 (PVR=%08x)", pvr);
595         printf (" at %s MHz:", strmhz(buf, clock));
596         printf (" %u kB I-Cache", 4);
597         printf (" %u kB D-Cache", 2);
598 #endif
599
600 #endif /* !defined(CONFIG_405) */
601
602         putc ('\n');
603
604         return 0;
605 }
606
607 int ppc440spe_revB() {
608         unsigned int pvr;
609
610         pvr = get_pvr();
611         if ((pvr == PVR_440SPe_6_RB) || (pvr == PVR_440SPe_RB))
612                 return 1;
613         else
614                 return 0;
615 }
616
617 /* ------------------------------------------------------------------------- */
618
619 int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
620 {
621 #if defined(CONFIG_BOARD_RESET)
622         board_reset();
623 #else
624 #if defined(CFG_4xx_RESET_TYPE)
625         mtspr(dbcr0, CFG_4xx_RESET_TYPE << 28);
626 #else
627         /*
628          * Initiate system reset in debug control register DBCR
629          */
630         mtspr(dbcr0, 0x30000000);
631 #endif /* defined(CFG_4xx_RESET_TYPE) */
632 #endif /* defined(CONFIG_BOARD_RESET) */
633
634         return 1;
635 }
636
637
638 /*
639  * Get timebase clock frequency
640  */
641 unsigned long get_tbclk (void)
642 {
643 #if !defined(CONFIG_IOP480)
644         sys_info_t  sys_info;
645
646         get_sys_info(&sys_info);
647         return (sys_info.freqProcessor);
648 #else
649         return (66000000);
650 #endif
651
652 }
653
654
655 #if defined(CONFIG_WATCHDOG)
656 void watchdog_reset(void)
657 {
658         int re_enable = disable_interrupts();
659         reset_4xx_watchdog();
660         if (re_enable) enable_interrupts();
661 }
662
663 void reset_4xx_watchdog(void)
664 {
665         /*
666          * Clear TSR(WIS) bit
667          */
668         mtspr(tsr, 0x40000000);
669 }
670 #endif  /* CONFIG_WATCHDOG */