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