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