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