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