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