]> git.sur5r.net Git - u-boot/blob - cpu/ppc4xx/cpu.c
Add support for AMCC 440SPe CPU based eval board (Yucca).
[u-boot] / cpu / ppc4xx / cpu.c
1 /*
2  * (C) Copyright 2000-2003
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
41 #if defined(CONFIG_440)
42 #define FREQ_EBC                (sys_info.freqEPB)
43 #else
44 #define FREQ_EBC                (sys_info.freqPLB / sys_info.pllExtBusDiv)
45 #endif
46
47 #if defined(CONFIG_405GP) || defined(CONFIG_440EP) || defined(CONFIG_440GR)
48
49 #define PCI_ASYNC
50
51 int pci_async_enabled(void)
52 {
53 #if defined(CONFIG_405GP)
54         return (mfdcr(strap) & PSR_PCI_ASYNC_EN);
55 #endif
56
57 #if defined(CONFIG_440EP) || defined(CONFIG_440GR)
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) && !defined(CONFIG_405)
67 int pci_arbiter_enabled(void)
68 {
69 #if defined(CONFIG_405GP)
70         return (mfdcr(strap) & PSR_PCI_ARBIT_EN);
71 #endif
72
73 #if defined(CONFIG_405EP)
74         return (mfdcr(cpc0_pci) & CPC0_PCI_ARBIT_EN);
75 #endif
76
77 #if defined(CONFIG_440GP)
78         return (mfdcr(cpc0_strp1) & CPC0_STRP1_PAE_MASK);
79 #endif
80
81 #if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \
82      defined(CONFIG_440GR) || defined(CONFIG_440SP) || \
83      defined(CONFIG_440SPE)
84         unsigned long val;
85
86         mfsdr(sdr_sdstp1, val);
87         return (val & SDR0_SDSTP1_PAE_MASK);
88 #endif
89 }
90 #endif
91
92 #if defined(CONFIG_405EP) || defined(CONFIG_440EP) || defined(CONFIG_440GR) ||  \
93      defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
94
95 #define I2C_BOOTROM
96
97 int i2c_bootrom_enabled(void)
98 {
99 #if defined(CONFIG_405EP)
100         return (mfdcr(cpc0_boot) & CPC0_BOOT_SEP);
101 #endif
102
103 #if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \
104      defined(CONFIG_440GR) || defined(CONFIG_440SP) || \
105         defined(CONFIG_440SPE)
106         unsigned long val;
107
108         mfsdr(sdr_sdcs, val);
109         return (val & SDR0_SDCS_SDD);
110 #endif
111 }
112 #endif
113
114
115 #if defined(CONFIG_440)
116 static int do_chip_reset(unsigned long sys0, unsigned long sys1);
117 #endif
118
119
120 int checkcpu (void)
121 {
122 #if !defined(CONFIG_405)        /* not used on Xilinx 405 FPGA implementations */
123         DECLARE_GLOBAL_DATA_PTR;
124         uint pvr = get_pvr();
125         ulong clock = gd->cpu_clk;
126         char buf[32];
127
128 #if !defined(CONFIG_IOP480)
129         sys_info_t sys_info;
130
131         puts ("CPU:   ");
132
133         get_sys_info(&sys_info);
134
135         puts("AMCC PowerPC 4");
136
137 #if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405EP)
138         puts("05");
139 #endif
140 #if defined(CONFIG_440)
141         puts("40");
142 #endif
143
144         switch (pvr) {
145         case PVR_405GP_RB:
146                 puts("GP Rev. B");
147                 break;
148
149         case PVR_405GP_RC:
150                 puts("GP Rev. C");
151                 break;
152
153         case PVR_405GP_RD:
154                 puts("GP Rev. D");
155                 break;
156
157 #ifdef CONFIG_405GP
158         case PVR_405GP_RE: /* 405GP rev E and 405CR rev C have same PVR */
159                 puts("GP Rev. E");
160                 break;
161 #endif
162
163         case PVR_405CR_RA:
164                 puts("CR Rev. A");
165                 break;
166
167         case PVR_405CR_RB:
168                 puts("CR Rev. B");
169                 break;
170
171 #ifdef CONFIG_405CR
172         case PVR_405CR_RC: /* 405GP rev E and 405CR rev C have same PVR */
173                 puts("CR Rev. C");
174                 break;
175 #endif
176
177         case PVR_405GPR_RB:
178                 puts("GPr Rev. B");
179                 break;
180
181         case PVR_405EP_RB:
182                 puts("EP Rev. B");
183                 break;
184
185 #if defined(CONFIG_440)
186         case PVR_440GP_RB:
187                 puts("GP Rev. B");
188                 /* See errata 1.12: CHIP_4 */
189                 if ((mfdcr(cpc0_sys0) != mfdcr(cpc0_strp0)) ||
190                     (mfdcr(cpc0_sys1) != mfdcr(cpc0_strp1)) ){
191                         puts (  "\n\t CPC0_SYSx DCRs corrupted. "
192                                 "Resetting chip ...\n");
193                         udelay( 1000 * 1000 ); /* Give time for serial buf to clear */
194                         do_chip_reset ( mfdcr(cpc0_strp0),
195                                         mfdcr(cpc0_strp1) );
196                 }
197                 break;
198
199         case PVR_440GP_RC:
200                 puts("GP Rev. C");
201                 break;
202
203         case PVR_440GX_RA:
204                 puts("GX Rev. A");
205                 break;
206
207         case PVR_440GX_RB:
208                 puts("GX Rev. B");
209                 break;
210
211         case PVR_440GX_RC:
212                 puts("GX Rev. C");
213                 break;
214
215         case PVR_440GX_RF:
216                 puts("GX Rev. F");
217                 break;
218
219         case PVR_440EP_RA:
220                 puts("EP Rev. A");
221                 break;
222
223 #ifdef CONFIG_440EP
224         case PVR_440EP_RB: /* 440EP rev B and 440GR rev A have same PVR */
225                 puts("EP Rev. B");
226                 break;
227 #endif /*  CONFIG_440EP */
228
229 #ifdef CONFIG_440GR
230         case PVR_440GR_RA: /* 440EP rev B and 440GR rev A have same PVR */
231                 puts("GR Rev. A");
232                 break;
233 #endif /* CONFIG_440GR */
234 #endif /* CONFIG_440 */
235
236         case PVR_440SP_RA:
237                 puts("SP Rev. A");
238                 break;
239
240         case PVR_440SP_RB:
241                 puts("SP Rev. B");
242                 break;
243
244         case PVR_440SPe_RA:
245                 puts("SPe 3GA533C");
246                 break;
247         case PVR_440SPe_RB:
248                 puts("SPe 3GB533C");
249                 break;
250         default:
251                 printf (" UNKNOWN (PVR=%08x)", pvr);
252                 break;
253         }
254
255         printf (" at %s MHz (PLB=%lu, OPB=%lu, EBC=%lu MHz)\n", strmhz(buf, clock),
256                sys_info.freqPLB / 1000000,
257                sys_info.freqPLB / sys_info.pllOpbDiv / 1000000,
258                FREQ_EBC / 1000000);
259
260 #if defined(I2C_BOOTROM)
261         printf ("       I2C boot EEPROM %sabled\n", i2c_bootrom_enabled() ? "en" : "dis");
262 #endif
263
264 #if defined(CONFIG_PCI)
265         printf ("       Internal PCI arbiter %sabled", pci_arbiter_enabled() ? "en" : "dis");
266 #endif
267
268 #if defined(PCI_ASYNC)
269         if (pci_async_enabled()) {
270                 printf (", PCI async ext clock used");
271         } else {
272                 printf (", PCI sync clock at %lu MHz",
273                        sys_info.freqPLB / sys_info.pllPciDiv / 1000000);
274         }
275 #endif
276
277 #if defined(CONFIG_PCI)
278         putc('\n');
279 #endif
280
281 #if defined(CONFIG_405EP)
282         printf ("       16 kB I-Cache 16 kB D-Cache");
283 #elif defined(CONFIG_440)
284         printf ("       32 kB I-Cache 32 kB D-Cache");
285 #else
286         printf ("       16 kB I-Cache %d kB D-Cache",
287                 ((pvr | 0x00000001) == PVR_405GPR_RB) ? 16 : 8);
288 #endif
289 #endif /* !defined(CONFIG_IOP480) */
290
291 #if defined(CONFIG_IOP480)
292         printf ("PLX IOP480 (PVR=%08x)", pvr);
293         printf (" at %s MHz:", strmhz(buf, clock));
294         printf (" %u kB I-Cache", 4);
295         printf (" %u kB D-Cache", 2);
296 #endif
297
298 #endif /* !defined(CONFIG_405) */
299
300         putc ('\n');
301
302         return 0;
303 }
304
305
306 /* ------------------------------------------------------------------------- */
307
308 int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
309 {
310 #if defined(CONFIG_YOSEMITE) || defined(CONFIG_YELLOWSTONE)
311         /*give reset to BCSR*/
312         *(unsigned char*)(CFG_BCSR_BASE | 0x06) = 0x09;
313
314 #else
315
316         /*
317          * Initiate system reset in debug control register DBCR
318          */
319         __asm__ __volatile__("lis   3, 0x3000" ::: "r3");
320 #if defined(CONFIG_440)
321         __asm__ __volatile__("mtspr 0x134, 3");
322 #else
323         __asm__ __volatile__("mtspr 0x3f2, 3");
324 #endif
325
326 #endif/* defined(CONFIG_YOSEMITE) || defined(CONFIG_YELLOWSTONE)*/
327         return 1;
328 }
329
330 #if defined(CONFIG_440)
331 static int do_chip_reset (unsigned long sys0, unsigned long sys1)
332 {
333         /* Changes to cpc0_sys0 and cpc0_sys1 require chip
334          * reset.
335          */
336         mtdcr (cntrl0, mfdcr (cntrl0) | 0x80000000);    /* Set SWE */
337         mtdcr (cpc0_sys0, sys0);
338         mtdcr (cpc0_sys1, sys1);
339         mtdcr (cntrl0, mfdcr (cntrl0) & ~0x80000000);   /* Clr SWE */
340         mtspr (dbcr0, 0x20000000);      /* Reset the chip */
341
342         return 1;
343 }
344 #endif
345
346
347 /*
348  * Get timebase clock frequency
349  */
350 unsigned long get_tbclk (void)
351 {
352 #if !defined(CONFIG_IOP480)
353         sys_info_t  sys_info;
354
355         get_sys_info(&sys_info);
356         return (sys_info.freqProcessor);
357 #else
358         return (66000000);
359 #endif
360
361 }
362
363
364 #if defined(CONFIG_WATCHDOG)
365 void
366 watchdog_reset(void)
367 {
368         int re_enable = disable_interrupts();
369         reset_4xx_watchdog();
370         if (re_enable) enable_interrupts();
371 }
372
373 void
374 reset_4xx_watchdog(void)
375 {
376         /*
377          * Clear TSR(WIS) bit
378          */
379         mtspr(tsr, 0x40000000);
380 }
381 #endif  /* CONFIG_WATCHDOG */