MINI2440: Updated early nand loader
[u-boot-openmoko/mini2440.git] / cpu / ppc4xx / speed.c
blobfa799529d375f17598db1a2e1fc5b10cac921ce2
1 /*
2 * (C) Copyright 2000-2008
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 * See file CREDITS for list of people who contributed to this
6 * project.
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.
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.
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
24 #include <common.h>
25 #include <ppc_asm.tmpl>
26 #include <ppc4xx.h>
27 #include <asm/processor.h>
29 DECLARE_GLOBAL_DATA_PTR;
31 #define ONE_BILLION 1000000000
32 #ifdef DEBUG
33 #define DEBUGF(fmt,args...) printf(fmt ,##args)
34 #else
35 #define DEBUGF(fmt,args...)
36 #endif
38 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
40 #if defined(CONFIG_405GP) || defined(CONFIG_405CR)
42 void get_sys_info (PPC4xx_SYS_INFO * sysInfo)
44 unsigned long pllmr;
45 unsigned long sysClkPeriodPs = ONE_BILLION / (CONFIG_SYS_CLK_FREQ / 1000);
46 uint pvr = get_pvr();
47 unsigned long psr;
48 unsigned long m;
51 * Read PLL Mode register
53 pllmr = mfdcr (pllmd);
56 * Read Pin Strapping register
58 psr = mfdcr (strap);
61 * Determine FWD_DIV.
63 sysInfo->pllFwdDiv = 8 - ((pllmr & PLLMR_FWD_DIV_MASK) >> 29);
66 * Determine FBK_DIV.
68 sysInfo->pllFbkDiv = ((pllmr & PLLMR_FB_DIV_MASK) >> 25);
69 if (sysInfo->pllFbkDiv == 0) {
70 sysInfo->pllFbkDiv = 16;
74 * Determine PLB_DIV.
76 sysInfo->pllPlbDiv = ((pllmr & PLLMR_CPU_TO_PLB_MASK) >> 17) + 1;
79 * Determine PCI_DIV.
81 sysInfo->pllPciDiv = ((pllmr & PLLMR_PCI_TO_PLB_MASK) >> 13) + 1;
84 * Determine EXTBUS_DIV.
86 sysInfo->pllExtBusDiv = ((pllmr & PLLMR_EXB_TO_PLB_MASK) >> 11) + 2;
89 * Determine OPB_DIV.
91 sysInfo->pllOpbDiv = ((pllmr & PLLMR_OPB_TO_PLB_MASK) >> 15) + 1;
94 * Check if PPC405GPr used (mask minor revision field)
96 if ((pvr & 0xfffffff0) == (PVR_405GPR_RB & 0xfffffff0)) {
98 * Determine FWD_DIV B (only PPC405GPr with new mode strapping).
100 sysInfo->pllFwdDivB = 8 - (pllmr & PLLMR_FWDB_DIV_MASK);
103 * Determine factor m depending on PLL feedback clock source
105 if (!(psr & PSR_PCI_ASYNC_EN)) {
106 if (psr & PSR_NEW_MODE_EN) {
108 * sync pci clock used as feedback (new mode)
110 m = 1 * sysInfo->pllFwdDivB * 2 * sysInfo->pllPciDiv;
111 } else {
113 * sync pci clock used as feedback (legacy mode)
115 m = 1 * sysInfo->pllFwdDivB * sysInfo->pllPlbDiv * sysInfo->pllPciDiv;
117 } else if (psr & PSR_NEW_MODE_EN) {
118 if (psr & PSR_PERCLK_SYNC_MODE_EN) {
120 * PerClk used as feedback (new mode)
122 m = 1 * sysInfo->pllFwdDivB * 2 * sysInfo->pllExtBusDiv;
123 } else {
125 * CPU clock used as feedback (new mode)
127 m = sysInfo->pllFbkDiv * sysInfo->pllFwdDiv;
129 } else if (sysInfo->pllExtBusDiv == sysInfo->pllFbkDiv) {
131 * PerClk used as feedback (legacy mode)
133 m = 1 * sysInfo->pllFwdDivB * sysInfo->pllPlbDiv * sysInfo->pllExtBusDiv;
134 } else {
136 * PLB clock used as feedback (legacy mode)
138 m = sysInfo->pllFbkDiv * sysInfo->pllFwdDivB * sysInfo->pllPlbDiv;
141 sysInfo->freqVCOHz = (1000000000000LL * (unsigned long long)m) /
142 (unsigned long long)sysClkPeriodPs;
143 sysInfo->freqProcessor = sysInfo->freqVCOHz / sysInfo->pllFwdDiv;
144 sysInfo->freqPLB = sysInfo->freqVCOHz / (sysInfo->pllFwdDivB * sysInfo->pllPlbDiv);
145 } else {
147 * Check pllFwdDiv to see if running in bypass mode where the CPU speed
148 * is equal to the 405GP SYS_CLK_FREQ. If not in bypass mode, check VCO
149 * to make sure it is within the proper range.
150 * spec: VCO = SYS_CLOCK x FBKDIV x PLBDIV x FWDDIV
151 * Note freqVCO is calculated in Mhz to avoid errors introduced by rounding.
153 if (sysInfo->pllFwdDiv == 1) {
154 sysInfo->freqProcessor = CONFIG_SYS_CLK_FREQ;
155 sysInfo->freqPLB = CONFIG_SYS_CLK_FREQ / sysInfo->pllPlbDiv;
156 } else {
157 sysInfo->freqVCOHz = ( 1000000000000LL *
158 (unsigned long long)sysInfo->pllFwdDiv *
159 (unsigned long long)sysInfo->pllFbkDiv *
160 (unsigned long long)sysInfo->pllPlbDiv
161 ) / (unsigned long long)sysClkPeriodPs;
162 sysInfo->freqPLB = (ONE_BILLION / ((sysClkPeriodPs * 10) /
163 sysInfo->pllFbkDiv)) * 10000;
164 sysInfo->freqProcessor = sysInfo->freqPLB * sysInfo->pllPlbDiv;
168 sysInfo->freqUART = sysInfo->freqProcessor;
172 /********************************************
173 * get_OPB_freq
174 * return OPB bus freq in Hz
175 *********************************************/
176 ulong get_OPB_freq (void)
178 ulong val = 0;
180 PPC4xx_SYS_INFO sys_info;
182 get_sys_info (&sys_info);
183 val = sys_info.freqPLB / sys_info.pllOpbDiv;
185 return val;
189 /********************************************
190 * get_PCI_freq
191 * return PCI bus freq in Hz
192 *********************************************/
193 ulong get_PCI_freq (void)
195 ulong val;
196 PPC4xx_SYS_INFO sys_info;
198 get_sys_info (&sys_info);
199 val = sys_info.freqPLB / sys_info.pllPciDiv;
200 return val;
204 #elif defined(CONFIG_440)
206 #if defined(CONFIG_460EX) || defined(CONFIG_460GT)
207 static u8 pll_fwdv_multi_bits[] = {
208 /* values for: 1 - 16 */
209 0x00, 0x01, 0x0f, 0x04, 0x09, 0x0a, 0x0d, 0x0e, 0x03, 0x0c,
210 0x05, 0x08, 0x07, 0x02, 0x0b, 0x06
213 u32 get_cpr0_fwdv(unsigned long cpr_reg_fwdv)
215 u32 index;
217 for (index = 0; index < ARRAY_SIZE(pll_fwdv_multi_bits); index++)
218 if (cpr_reg_fwdv == (u32)pll_fwdv_multi_bits[index])
219 return index + 1;
221 return 0;
224 static u8 pll_fbdv_multi_bits[] = {
225 /* values for: 1 - 100 */
226 0x00, 0xff, 0x7e, 0xfd, 0x7a, 0xf5, 0x6a, 0xd5, 0x2a, 0xd4,
227 0x29, 0xd3, 0x26, 0xcc, 0x19, 0xb3, 0x67, 0xce, 0x1d, 0xbb,
228 0x77, 0xee, 0x5d, 0xba, 0x74, 0xe9, 0x52, 0xa5, 0x4b, 0x96,
229 0x2c, 0xd8, 0x31, 0xe3, 0x46, 0x8d, 0x1b, 0xb7, 0x6f, 0xde,
230 0x3d, 0xfb, 0x76, 0xed, 0x5a, 0xb5, 0x6b, 0xd6, 0x2d, 0xdb,
231 0x36, 0xec, 0x59, 0xb2, 0x64, 0xc9, 0x12, 0xa4, 0x48, 0x91,
232 0x23, 0xc7, 0x0e, 0x9c, 0x38, 0xf0, 0x61, 0xc2, 0x05, 0x8b,
233 0x17, 0xaf, 0x5f, 0xbe, 0x7c, 0xf9, 0x72, 0xe5, 0x4a, 0x95,
234 0x2b, 0xd7, 0x2e, 0xdc, 0x39, 0xf3, 0x66, 0xcd, 0x1a, 0xb4,
235 0x68, 0xd1, 0x22, 0xc4, 0x09, 0x93, 0x27, 0xcf, 0x1e, 0xbc,
236 /* values for: 101 - 200 */
237 0x78, 0xf1, 0x62, 0xc5, 0x0a, 0x94, 0x28, 0xd0, 0x21, 0xc3,
238 0x06, 0x8c, 0x18, 0xb0, 0x60, 0xc1, 0x02, 0x84, 0x08, 0x90,
239 0x20, 0xc0, 0x01, 0x83, 0x77, 0xff, 0x1f, 0xbf, 0x7f, 0xfe,
240 0x7d, 0xfa, 0x75, 0xea, 0x55, 0xaa, 0x54, 0xa9, 0x53, 0xa6,
241 0x4c, 0x99, 0x33, 0xe7, 0x4e, 0x9d, 0x3b, 0xf7, 0x6e, 0xdd,
242 0x3a, 0xf4, 0x69, 0xd2, 0x25, 0xcb, 0x16, 0xac, 0x58, 0xb1,
243 0x63, 0xc6, 0x0d, 0x9b, 0x37, 0xef, 0x5e, 0xbd, 0x7b, 0xf6,
244 0x6d, 0xda, 0x35, 0xeb, 0x56, 0xad, 0x5b, 0xb6, 0x6c, 0xd9,
245 0x32, 0xe4, 0x49, 0x92, 0x24, 0xc8, 0x11, 0xa3, 0x47, 0x8e,
246 0x1c, 0xb8, 0x70, 0xe1, 0x42, 0x85, 0x0b, 0x97, 0x2f, 0xdf,
247 /* values for: 201 - 255 */
248 0x3e, 0xfc, 0x79, 0xf2, 0x65, 0xca, 0x15, 0xab, 0x57, 0xae,
249 0x5c, 0xb9, 0x73, 0xe6, 0x4d, 0x9a, 0x34, 0xe8, 0x51, 0xa2,
250 0x44, 0x89, 0x13, 0xa7, 0x4f, 0x9e, 0x3c, 0xf8, 0x71, 0xe2,
251 0x45, 0x8a, 0x14, 0xa8, 0x50, 0xa1, 0x43, 0x86, 0x0c, 0x98,
252 0x30, 0xe0, 0x41, 0x82, 0x04, 0x88, 0x10, 0xa0, 0x40, 0x81,
253 0x03, 0x87, 0x0f, 0x9f, 0x3f /* END */
256 u32 get_cpr0_fbdv(unsigned long cpr_reg_fbdv)
258 u32 index;
260 for (index = 0; index < ARRAY_SIZE(pll_fbdv_multi_bits); index++)
261 if (cpr_reg_fbdv == (u32)pll_fbdv_multi_bits[index])
262 return index + 1;
264 return 0;
268 * AMCC_TODO: verify this routine against latest EAS, cause stuff changed
269 * with latest EAS
271 void get_sys_info (sys_info_t * sysInfo)
273 unsigned long strp0;
274 unsigned long strp1;
275 unsigned long temp;
276 unsigned long m;
277 unsigned long plbedv0;
279 /* Extract configured divisors */
280 mfsdr(sdr_sdstp0, strp0);
281 mfsdr(sdr_sdstp1, strp1);
283 temp = ((strp0 & PLLSYS0_FWD_DIV_A_MASK) >> 4);
284 sysInfo->pllFwdDivA = get_cpr0_fwdv(temp);
286 temp = (strp0 & PLLSYS0_FWD_DIV_B_MASK);
287 sysInfo->pllFwdDivB = get_cpr0_fwdv(temp);
289 temp = (strp0 & PLLSYS0_FB_DIV_MASK) >> 8;
290 sysInfo->pllFbkDiv = get_cpr0_fbdv(temp);
292 temp = (strp1 & PLLSYS0_OPB_DIV_MASK) >> 26;
293 sysInfo->pllOpbDiv = temp ? temp : 4;
295 /* AMCC_TODO: verify the SDR0_SDSTP1.PERDV0 value sysInfo->pllExtBusDiv */
296 temp = (strp1 & PLLSYS0_PERCLK_DIV_MASK) >> 24;
297 sysInfo->pllExtBusDiv = temp ? temp : 4;
299 temp = (strp1 & PLLSYS0_PLBEDV0_DIV_MASK) >> 29;
300 plbedv0 = temp ? temp: 8;
302 /* Calculate 'M' based on feedback source */
303 temp = (strp0 & PLLSYS0_SEL_MASK) >> 27;
304 if (temp == 0) {
305 /* PLL internal feedback */
306 m = sysInfo->pllFbkDiv;
307 } else {
308 /* PLL PerClk feedback */
309 m = sysInfo->pllFwdDivA * plbedv0 * sysInfo->pllOpbDiv *
310 sysInfo->pllExtBusDiv;
313 /* Now calculate the individual clocks */
314 sysInfo->freqVCOMhz = (m * CONFIG_SYS_CLK_FREQ) + (m >> 1);
315 sysInfo->freqProcessor = sysInfo->freqVCOMhz/sysInfo->pllFwdDivA;
316 sysInfo->freqPLB = sysInfo->freqVCOMhz / sysInfo->pllFwdDivA / plbedv0;
317 sysInfo->freqOPB = sysInfo->freqPLB / sysInfo->pllOpbDiv;
318 sysInfo->freqEBC = sysInfo->freqOPB / sysInfo->pllExtBusDiv;
319 sysInfo->freqDDR = sysInfo->freqPLB;
320 sysInfo->freqUART = sysInfo->freqPLB;
322 return;
325 #elif defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
326 defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
327 void get_sys_info (sys_info_t *sysInfo)
329 unsigned long temp;
330 unsigned long reg;
331 unsigned long lfdiv;
332 unsigned long m;
333 unsigned long prbdv0;
335 WARNING: ASSUMES the following:
336 ENG=1
337 PRADV0=1
338 PRBDV0=1
341 /* Decode CPR0_PLLD0 for divisors */
342 mfcpr(clk_plld, reg);
343 temp = (reg & PLLD_FWDVA_MASK) >> 16;
344 sysInfo->pllFwdDivA = temp ? temp : 16;
345 temp = (reg & PLLD_FWDVB_MASK) >> 8;
346 sysInfo->pllFwdDivB = temp ? temp: 8 ;
347 temp = (reg & PLLD_FBDV_MASK) >> 24;
348 sysInfo->pllFbkDiv = temp ? temp : 32;
349 lfdiv = reg & PLLD_LFBDV_MASK;
351 mfcpr(clk_opbd, reg);
352 temp = (reg & OPBDDV_MASK) >> 24;
353 sysInfo->pllOpbDiv = temp ? temp : 4;
355 mfcpr(clk_perd, reg);
356 temp = (reg & PERDV_MASK) >> 24;
357 sysInfo->pllExtBusDiv = temp ? temp : 8;
359 mfcpr(clk_primbd, reg);
360 temp = (reg & PRBDV_MASK) >> 24;
361 prbdv0 = temp ? temp : 8;
363 mfcpr(clk_spcid, reg);
364 temp = (reg & SPCID_MASK) >> 24;
365 sysInfo->pllPciDiv = temp ? temp : 4;
367 /* Calculate 'M' based on feedback source */
368 mfsdr(sdr_sdstp0, reg);
369 temp = (reg & PLLSYS0_SEL_MASK) >> 27;
370 if (temp == 0) { /* PLL output */
371 /* Figure which pll to use */
372 mfcpr(clk_pllc, reg);
373 temp = (reg & PLLC_SRC_MASK) >> 29;
374 if (!temp) /* PLLOUTA */
375 m = sysInfo->pllFbkDiv * lfdiv * sysInfo->pllFwdDivA;
376 else /* PLLOUTB */
377 m = sysInfo->pllFbkDiv * lfdiv * sysInfo->pllFwdDivB;
379 else if (temp == 1) /* CPU output */
380 m = sysInfo->pllFbkDiv * sysInfo->pllFwdDivA;
381 else /* PerClk */
382 m = sysInfo->pllExtBusDiv * sysInfo->pllOpbDiv * sysInfo->pllFwdDivB;
384 /* Now calculate the individual clocks */
385 sysInfo->freqVCOMhz = (m * CONFIG_SYS_CLK_FREQ) + (m>>1);
386 sysInfo->freqProcessor = sysInfo->freqVCOMhz/sysInfo->pllFwdDivA;
387 sysInfo->freqPLB = sysInfo->freqVCOMhz/sysInfo->pllFwdDivB/prbdv0;
388 sysInfo->freqOPB = sysInfo->freqPLB/sysInfo->pllOpbDiv;
389 sysInfo->freqEBC = sysInfo->freqPLB/sysInfo->pllExtBusDiv;
390 sysInfo->freqPCI = sysInfo->freqPLB/sysInfo->pllPciDiv;
391 sysInfo->freqUART = sysInfo->freqPLB;
393 /* Figure which timer source to use */
394 if (mfspr(ccr1) & 0x0080) { /* External Clock, assume same as SYS_CLK */
395 temp = sysInfo->freqProcessor / 2; /* Max extern clock speed */
396 if (CONFIG_SYS_CLK_FREQ > temp)
397 sysInfo->freqTmrClk = temp;
398 else
399 sysInfo->freqTmrClk = CONFIG_SYS_CLK_FREQ;
401 else /* Internal clock */
402 sysInfo->freqTmrClk = sysInfo->freqProcessor;
405 /********************************************
406 * get_PCI_freq
407 * return PCI bus freq in Hz
408 *********************************************/
409 ulong get_PCI_freq (void)
411 sys_info_t sys_info;
412 get_sys_info (&sys_info);
413 return sys_info.freqPCI;
416 #elif !defined(CONFIG_440GX) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE)
417 void get_sys_info (sys_info_t * sysInfo)
419 unsigned long strp0;
420 unsigned long temp;
421 unsigned long m;
423 /* Extract configured divisors */
424 strp0 = mfdcr( cpc0_strp0 );
425 sysInfo->pllFwdDivA = 8 - ((strp0 & PLLSYS0_FWD_DIV_A_MASK) >> 15);
426 sysInfo->pllFwdDivB = 8 - ((strp0 & PLLSYS0_FWD_DIV_B_MASK) >> 12);
427 temp = (strp0 & PLLSYS0_FB_DIV_MASK) >> 18;
428 sysInfo->pllFbkDiv = temp ? temp : 16;
429 sysInfo->pllOpbDiv = 1 + ((strp0 & PLLSYS0_OPB_DIV_MASK) >> 10);
430 sysInfo->pllExtBusDiv = 1 + ((strp0 & PLLSYS0_EPB_DIV_MASK) >> 8);
432 /* Calculate 'M' based on feedback source */
433 if( strp0 & PLLSYS0_EXTSL_MASK )
434 m = sysInfo->pllExtBusDiv * sysInfo->pllOpbDiv * sysInfo->pllFwdDivB;
435 else
436 m = sysInfo->pllFbkDiv * sysInfo->pllFwdDivA;
438 /* Now calculate the individual clocks */
439 sysInfo->freqVCOMhz = (m * CONFIG_SYS_CLK_FREQ) + (m>>1);
440 sysInfo->freqProcessor = sysInfo->freqVCOMhz/sysInfo->pllFwdDivA;
441 sysInfo->freqPLB = sysInfo->freqVCOMhz/sysInfo->pllFwdDivB;
442 if( get_pvr() == PVR_440GP_RB ) /* Rev B divs an extra 2 -- geez! */
443 sysInfo->freqPLB >>= 1;
444 sysInfo->freqOPB = sysInfo->freqPLB/sysInfo->pllOpbDiv;
445 sysInfo->freqEBC = sysInfo->freqOPB/sysInfo->pllExtBusDiv;
446 sysInfo->freqUART = sysInfo->freqPLB;
448 #else
449 void get_sys_info (sys_info_t * sysInfo)
451 unsigned long strp0;
452 unsigned long strp1;
453 unsigned long temp;
454 unsigned long temp1;
455 unsigned long lfdiv;
456 unsigned long m;
457 unsigned long prbdv0;
459 #if defined(CONFIG_YUCCA)
460 unsigned long sys_freq;
461 unsigned long sys_per=0;
462 unsigned long msr;
463 unsigned long pci_clock_per;
464 unsigned long sdr_ddrpll;
466 /*-------------------------------------------------------------------------+
467 | Get the system clock period.
468 +-------------------------------------------------------------------------*/
469 sys_per = determine_sysper();
471 msr = (mfmsr () & ~(MSR_EE)); /* disable interrupts */
473 /*-------------------------------------------------------------------------+
474 | Calculate the system clock speed from the period.
475 +-------------------------------------------------------------------------*/
476 sys_freq = (ONE_BILLION / sys_per) * 1000;
477 #endif
479 /* Extract configured divisors */
480 mfsdr( sdr_sdstp0,strp0 );
481 mfsdr( sdr_sdstp1,strp1 );
483 temp = ((strp0 & PLLSYS0_FWD_DIV_A_MASK) >> 8);
484 sysInfo->pllFwdDivA = temp ? temp : 16 ;
485 temp = ((strp0 & PLLSYS0_FWD_DIV_B_MASK) >> 5);
486 sysInfo->pllFwdDivB = temp ? temp: 8 ;
487 temp = (strp0 & PLLSYS0_FB_DIV_MASK) >> 12;
488 sysInfo->pllFbkDiv = temp ? temp : 32;
489 temp = (strp0 & PLLSYS0_OPB_DIV_MASK);
490 sysInfo->pllOpbDiv = temp ? temp : 4;
491 temp = (strp1 & PLLSYS1_PERCLK_DIV_MASK) >> 24;
492 sysInfo->pllExtBusDiv = temp ? temp : 4;
493 prbdv0 = (strp0 >> 2) & 0x7;
495 /* Calculate 'M' based on feedback source */
496 temp = (strp0 & PLLSYS0_SEL_MASK) >> 27;
497 temp1 = (strp1 & PLLSYS1_LF_DIV_MASK) >> 26;
498 lfdiv = temp1 ? temp1 : 64;
499 if (temp == 0) { /* PLL output */
500 /* Figure which pll to use */
501 temp = (strp0 & PLLSYS0_SRC_MASK) >> 30;
502 if (!temp)
503 m = sysInfo->pllFbkDiv * lfdiv * sysInfo->pllFwdDivA;
504 else
505 m = sysInfo->pllFbkDiv * lfdiv * sysInfo->pllFwdDivB;
507 else if (temp == 1) /* CPU output */
508 m = sysInfo->pllFbkDiv * sysInfo->pllFwdDivA;
509 else /* PerClk */
510 m = sysInfo->pllExtBusDiv * sysInfo->pllOpbDiv * sysInfo->pllFwdDivB;
512 /* Now calculate the individual clocks */
513 #if defined(CONFIG_YUCCA)
514 sysInfo->freqVCOMhz = (m * sys_freq) ;
515 #else
516 sysInfo->freqVCOMhz = (m * CONFIG_SYS_CLK_FREQ) + (m >> 1);
517 #endif
518 sysInfo->freqProcessor = sysInfo->freqVCOMhz/sysInfo->pllFwdDivA;
519 sysInfo->freqPLB = sysInfo->freqVCOMhz/sysInfo->pllFwdDivB/prbdv0;
520 sysInfo->freqOPB = sysInfo->freqPLB/sysInfo->pllOpbDiv;
521 sysInfo->freqEBC = sysInfo->freqOPB/sysInfo->pllExtBusDiv;
523 #if defined(CONFIG_YUCCA)
524 /* Determine PCI Clock Period */
525 pci_clock_per = determine_pci_clock_per();
526 sysInfo->freqPCI = (ONE_BILLION/pci_clock_per) * 1000;
527 mfsdr(sdr_ddr0, sdr_ddrpll);
528 sysInfo->freqDDR = ((sysInfo->freqPLB) * SDR0_DDR0_DDRM_DECODE(sdr_ddrpll));
529 #endif
531 sysInfo->freqUART = sysInfo->freqPLB;
534 #endif
536 #if defined(CONFIG_YUCCA)
537 unsigned long determine_sysper(void)
539 unsigned int fpga_clocking_reg;
540 unsigned int master_clock_selection;
541 unsigned long master_clock_per = 0;
542 unsigned long fb_div_selection;
543 unsigned int vco_div_reg_value;
544 unsigned long vco_div_selection;
545 unsigned long sys_per = 0;
546 int extClkVal;
548 /*-------------------------------------------------------------------------+
549 | Read FPGA reg 0 and reg 1 to get FPGA reg information
550 +-------------------------------------------------------------------------*/
551 fpga_clocking_reg = in16(FPGA_REG16);
554 /* Determine Master Clock Source Selection */
555 master_clock_selection = fpga_clocking_reg & FPGA_REG16_MASTER_CLK_MASK;
557 switch(master_clock_selection) {
558 case FPGA_REG16_MASTER_CLK_66_66:
559 master_clock_per = PERIOD_66_66MHZ;
560 break;
561 case FPGA_REG16_MASTER_CLK_50:
562 master_clock_per = PERIOD_50_00MHZ;
563 break;
564 case FPGA_REG16_MASTER_CLK_33_33:
565 master_clock_per = PERIOD_33_33MHZ;
566 break;
567 case FPGA_REG16_MASTER_CLK_25:
568 master_clock_per = PERIOD_25_00MHZ;
569 break;
570 case FPGA_REG16_MASTER_CLK_EXT:
571 if ((extClkVal==EXTCLK_33_33)
572 && (extClkVal==EXTCLK_50)
573 && (extClkVal==EXTCLK_66_66)
574 && (extClkVal==EXTCLK_83)) {
575 /* calculate master clock period from external clock value */
576 master_clock_per=(ONE_BILLION/extClkVal) * 1000;
577 } else {
578 /* Unsupported */
579 DEBUGF ("%s[%d] *** master clock selection failed ***\n", __FUNCTION__,__LINE__);
580 hang();
582 break;
583 default:
584 /* Unsupported */
585 DEBUGF ("%s[%d] *** master clock selection failed ***\n", __FUNCTION__,__LINE__);
586 hang();
587 break;
590 /* Determine FB divisors values */
591 if ((fpga_clocking_reg & FPGA_REG16_FB1_DIV_MASK) == FPGA_REG16_FB1_DIV_LOW) {
592 if ((fpga_clocking_reg & FPGA_REG16_FB2_DIV_MASK) == FPGA_REG16_FB2_DIV_LOW)
593 fb_div_selection = FPGA_FB_DIV_6;
594 else
595 fb_div_selection = FPGA_FB_DIV_12;
596 } else {
597 if ((fpga_clocking_reg & FPGA_REG16_FB2_DIV_MASK) == FPGA_REG16_FB2_DIV_LOW)
598 fb_div_selection = FPGA_FB_DIV_10;
599 else
600 fb_div_selection = FPGA_FB_DIV_20;
603 /* Determine VCO divisors values */
604 vco_div_reg_value = fpga_clocking_reg & FPGA_REG16_VCO_DIV_MASK;
606 switch(vco_div_reg_value) {
607 case FPGA_REG16_VCO_DIV_4:
608 vco_div_selection = FPGA_VCO_DIV_4;
609 break;
610 case FPGA_REG16_VCO_DIV_6:
611 vco_div_selection = FPGA_VCO_DIV_6;
612 break;
613 case FPGA_REG16_VCO_DIV_8:
614 vco_div_selection = FPGA_VCO_DIV_8;
615 break;
616 case FPGA_REG16_VCO_DIV_10:
617 default:
618 vco_div_selection = FPGA_VCO_DIV_10;
619 break;
622 if (master_clock_selection == FPGA_REG16_MASTER_CLK_EXT) {
623 switch(master_clock_per) {
624 case PERIOD_25_00MHZ:
625 if (fb_div_selection == FPGA_FB_DIV_12) {
626 if (vco_div_selection == FPGA_VCO_DIV_4)
627 sys_per = PERIOD_75_00MHZ;
628 if (vco_div_selection == FPGA_VCO_DIV_6)
629 sys_per = PERIOD_50_00MHZ;
631 break;
632 case PERIOD_33_33MHZ:
633 if (fb_div_selection == FPGA_FB_DIV_6) {
634 if (vco_div_selection == FPGA_VCO_DIV_4)
635 sys_per = PERIOD_50_00MHZ;
636 if (vco_div_selection == FPGA_VCO_DIV_6)
637 sys_per = PERIOD_33_33MHZ;
639 if (fb_div_selection == FPGA_FB_DIV_10) {
640 if (vco_div_selection == FPGA_VCO_DIV_4)
641 sys_per = PERIOD_83_33MHZ;
642 if (vco_div_selection == FPGA_VCO_DIV_10)
643 sys_per = PERIOD_33_33MHZ;
645 if (fb_div_selection == FPGA_FB_DIV_12) {
646 if (vco_div_selection == FPGA_VCO_DIV_4)
647 sys_per = PERIOD_100_00MHZ;
648 if (vco_div_selection == FPGA_VCO_DIV_6)
649 sys_per = PERIOD_66_66MHZ;
650 if (vco_div_selection == FPGA_VCO_DIV_8)
651 sys_per = PERIOD_50_00MHZ;
653 break;
654 case PERIOD_50_00MHZ:
655 if (fb_div_selection == FPGA_FB_DIV_6) {
656 if (vco_div_selection == FPGA_VCO_DIV_4)
657 sys_per = PERIOD_75_00MHZ;
658 if (vco_div_selection == FPGA_VCO_DIV_6)
659 sys_per = PERIOD_50_00MHZ;
661 if (fb_div_selection == FPGA_FB_DIV_10) {
662 if (vco_div_selection == FPGA_VCO_DIV_6)
663 sys_per = PERIOD_83_33MHZ;
664 if (vco_div_selection == FPGA_VCO_DIV_10)
665 sys_per = PERIOD_50_00MHZ;
667 if (fb_div_selection == FPGA_FB_DIV_12) {
668 if (vco_div_selection == FPGA_VCO_DIV_6)
669 sys_per = PERIOD_100_00MHZ;
670 if (vco_div_selection == FPGA_VCO_DIV_8)
671 sys_per = PERIOD_75_00MHZ;
673 break;
674 case PERIOD_66_66MHZ:
675 if (fb_div_selection == FPGA_FB_DIV_6) {
676 if (vco_div_selection == FPGA_VCO_DIV_4)
677 sys_per = PERIOD_100_00MHZ;
678 if (vco_div_selection == FPGA_VCO_DIV_6)
679 sys_per = PERIOD_66_66MHZ;
680 if (vco_div_selection == FPGA_VCO_DIV_8)
681 sys_per = PERIOD_50_00MHZ;
683 if (fb_div_selection == FPGA_FB_DIV_10) {
684 if (vco_div_selection == FPGA_VCO_DIV_8)
685 sys_per = PERIOD_83_33MHZ;
686 if (vco_div_selection == FPGA_VCO_DIV_10)
687 sys_per = PERIOD_66_66MHZ;
689 if (fb_div_selection == FPGA_FB_DIV_12) {
690 if (vco_div_selection == FPGA_VCO_DIV_8)
691 sys_per = PERIOD_100_00MHZ;
693 break;
694 default:
695 break;
698 if (sys_per == 0) {
699 /* Other combinations are not supported */
700 DEBUGF ("%s[%d] *** sys period compute failed ***\n", __FUNCTION__,__LINE__);
701 hang();
703 } else {
704 /* calcul system clock without cheking */
705 /* if engineering option clock no check is selected */
706 /* sys_per = master_clock_per * vco_div_selection / fb_div_selection */
707 sys_per = (master_clock_per/fb_div_selection) * vco_div_selection;
710 return(sys_per);
713 /*-------------------------------------------------------------------------+
714 | determine_pci_clock_per.
715 +-------------------------------------------------------------------------*/
716 unsigned long determine_pci_clock_per(void)
718 unsigned long pci_clock_selection, pci_period;
720 /*-------------------------------------------------------------------------+
721 | Read FPGA reg 6 to get PCI 0 FPGA reg information
722 +-------------------------------------------------------------------------*/
723 pci_clock_selection = in16(FPGA_REG16); /* was reg6 averifier */
726 pci_clock_selection = pci_clock_selection & FPGA_REG16_PCI0_CLK_MASK;
728 switch (pci_clock_selection) {
729 case FPGA_REG16_PCI0_CLK_133_33:
730 pci_period = PERIOD_133_33MHZ;
731 break;
732 case FPGA_REG16_PCI0_CLK_100:
733 pci_period = PERIOD_100_00MHZ;
734 break;
735 case FPGA_REG16_PCI0_CLK_66_66:
736 pci_period = PERIOD_66_66MHZ;
737 break;
738 default:
739 pci_period = PERIOD_33_33MHZ;;
740 break;
743 return(pci_period);
745 #endif
747 ulong get_OPB_freq (void)
750 sys_info_t sys_info;
751 get_sys_info (&sys_info);
752 return sys_info.freqOPB;
755 #elif defined(CONFIG_XILINX_ML300)
756 extern void get_sys_info (sys_info_t * sysInfo);
757 extern ulong get_PCI_freq (void);
759 #elif defined(CONFIG_AP1000)
760 void get_sys_info (sys_info_t * sysInfo)
762 sysInfo->freqProcessor = 240 * 1000 * 1000;
763 sysInfo->freqPLB = 80 * 1000 * 1000;
764 sysInfo->freqPCI = 33 * 1000 * 1000;
767 #elif defined(CONFIG_405)
769 void get_sys_info (sys_info_t * sysInfo)
771 sysInfo->freqVCOMhz=3125000;
772 sysInfo->freqProcessor=12*1000*1000;
773 sysInfo->freqPLB=50*1000*1000;
774 sysInfo->freqPCI=66*1000*1000;
777 #elif defined(CONFIG_405EP)
778 void get_sys_info (PPC4xx_SYS_INFO * sysInfo)
780 unsigned long pllmr0;
781 unsigned long pllmr1;
782 unsigned long sysClkPeriodPs = ONE_BILLION / (CONFIG_SYS_CLK_FREQ / 1000);
783 unsigned long m;
784 unsigned long pllmr0_ccdv;
787 * Read PLL Mode registers
789 pllmr0 = mfdcr (cpc0_pllmr0);
790 pllmr1 = mfdcr (cpc0_pllmr1);
793 * Determine forward divider A
795 sysInfo->pllFwdDiv = 8 - ((pllmr1 & PLLMR1_FWDVA_MASK) >> 16);
798 * Determine forward divider B (should be equal to A)
800 sysInfo->pllFwdDivB = 8 - ((pllmr1 & PLLMR1_FWDVB_MASK) >> 12);
803 * Determine FBK_DIV.
805 sysInfo->pllFbkDiv = ((pllmr1 & PLLMR1_FBMUL_MASK) >> 20);
806 if (sysInfo->pllFbkDiv == 0)
807 sysInfo->pllFbkDiv = 16;
810 * Determine PLB_DIV.
812 sysInfo->pllPlbDiv = ((pllmr0 & PLLMR0_CPU_TO_PLB_MASK) >> 16) + 1;
815 * Determine PCI_DIV.
817 sysInfo->pllPciDiv = (pllmr0 & PLLMR0_PCI_TO_PLB_MASK) + 1;
820 * Determine EXTBUS_DIV.
822 sysInfo->pllExtBusDiv = ((pllmr0 & PLLMR0_EXB_TO_PLB_MASK) >> 8) + 2;
825 * Determine OPB_DIV.
827 sysInfo->pllOpbDiv = ((pllmr0 & PLLMR0_OPB_TO_PLB_MASK) >> 12) + 1;
830 * Determine the M factor
832 m = sysInfo->pllFbkDiv * sysInfo->pllFwdDivB;
835 * Determine VCO clock frequency
837 sysInfo->freqVCOHz = (1000000000000LL * (unsigned long long)m) /
838 (unsigned long long)sysClkPeriodPs;
841 * Determine CPU clock frequency
843 pllmr0_ccdv = ((pllmr0 & PLLMR0_CPU_DIV_MASK) >> 20) + 1;
844 if (pllmr1 & PLLMR1_SSCS_MASK) {
846 * This is true if FWDVA == FWDVB:
847 * sysInfo->freqProcessor = (CONFIG_SYS_CLK_FREQ * sysInfo->pllFbkDiv)
848 * / pllmr0_ccdv;
850 sysInfo->freqProcessor = (CONFIG_SYS_CLK_FREQ * sysInfo->pllFbkDiv * sysInfo->pllFwdDivB)
851 / sysInfo->pllFwdDiv / pllmr0_ccdv;
852 } else {
853 sysInfo->freqProcessor = CONFIG_SYS_CLK_FREQ / pllmr0_ccdv;
857 * Determine PLB clock frequency
859 sysInfo->freqPLB = sysInfo->freqProcessor / sysInfo->pllPlbDiv;
861 sysInfo->freqEBC = sysInfo->freqPLB / sysInfo->pllExtBusDiv;
863 sysInfo->freqUART = sysInfo->freqProcessor * pllmr0_ccdv;
867 /********************************************
868 * get_OPB_freq
869 * return OPB bus freq in Hz
870 *********************************************/
871 ulong get_OPB_freq (void)
873 ulong val = 0;
875 PPC4xx_SYS_INFO sys_info;
877 get_sys_info (&sys_info);
878 val = sys_info.freqPLB / sys_info.pllOpbDiv;
880 return val;
884 /********************************************
885 * get_PCI_freq
886 * return PCI bus freq in Hz
887 *********************************************/
888 ulong get_PCI_freq (void)
890 ulong val;
891 PPC4xx_SYS_INFO sys_info;
893 get_sys_info (&sys_info);
894 val = sys_info.freqPLB / sys_info.pllPciDiv;
895 return val;
898 #elif defined(CONFIG_405EZ)
899 void get_sys_info (PPC4xx_SYS_INFO * sysInfo)
901 unsigned long cpr_plld;
902 unsigned long cpr_pllc;
903 unsigned long cpr_primad;
904 unsigned long sysClkPeriodPs = ONE_BILLION / (CONFIG_SYS_CLK_FREQ/1000);
905 unsigned long primad_cpudv;
906 unsigned long m;
909 * Read PLL Mode registers
911 mfcpr(cprplld, cpr_plld);
912 mfcpr(cprpllc, cpr_pllc);
915 * Determine forward divider A
917 sysInfo->pllFwdDiv = ((cpr_plld & PLLD_FWDVA_MASK) >> 16);
920 * Determine forward divider B
922 sysInfo->pllFwdDivB = ((cpr_plld & PLLD_FWDVB_MASK) >> 8);
923 if (sysInfo->pllFwdDivB == 0)
924 sysInfo->pllFwdDivB = 8;
927 * Determine FBK_DIV.
929 sysInfo->pllFbkDiv = ((cpr_plld & PLLD_FBDV_MASK) >> 24);
930 if (sysInfo->pllFbkDiv == 0)
931 sysInfo->pllFbkDiv = 256;
934 * Read CPR_PRIMAD register
936 mfcpr(cprprimad, cpr_primad);
939 * Determine PLB_DIV.
941 sysInfo->pllPlbDiv = ((cpr_primad & PRIMAD_PLBDV_MASK) >> 16);
942 if (sysInfo->pllPlbDiv == 0)
943 sysInfo->pllPlbDiv = 16;
946 * Determine EXTBUS_DIV.
948 sysInfo->pllExtBusDiv = (cpr_primad & PRIMAD_EBCDV_MASK);
949 if (sysInfo->pllExtBusDiv == 0)
950 sysInfo->pllExtBusDiv = 16;
953 * Determine OPB_DIV.
955 sysInfo->pllOpbDiv = ((cpr_primad & PRIMAD_OPBDV_MASK) >> 8);
956 if (sysInfo->pllOpbDiv == 0)
957 sysInfo->pllOpbDiv = 16;
960 * Determine the M factor
962 if (cpr_pllc & PLLC_SRC_MASK)
963 m = sysInfo->pllFbkDiv * sysInfo->pllFwdDivB;
964 else
965 m = sysInfo->pllFbkDiv * sysInfo->pllFwdDiv;
968 * Determine VCO clock frequency
970 sysInfo->freqVCOHz = (1000000000000LL * (unsigned long long)m) /
971 (unsigned long long)sysClkPeriodPs;
974 * Determine CPU clock frequency
976 primad_cpudv = ((cpr_primad & PRIMAD_CPUDV_MASK) >> 24);
977 if (primad_cpudv == 0)
978 primad_cpudv = 16;
980 sysInfo->freqProcessor = (CONFIG_SYS_CLK_FREQ * m) /
981 sysInfo->pllFwdDiv / primad_cpudv;
984 * Determine PLB clock frequency
986 sysInfo->freqPLB = (CONFIG_SYS_CLK_FREQ * m) /
987 sysInfo->pllFwdDiv / sysInfo->pllPlbDiv;
989 sysInfo->freqEBC = (CONFIG_SYS_CLK_FREQ * sysInfo->pllFbkDiv) /
990 sysInfo->pllExtBusDiv;
992 sysInfo->freqUART = sysInfo->freqVCOHz;
995 /********************************************
996 * get_OPB_freq
997 * return OPB bus freq in Hz
998 *********************************************/
999 ulong get_OPB_freq (void)
1001 ulong val = 0;
1003 PPC4xx_SYS_INFO sys_info;
1005 get_sys_info (&sys_info);
1006 val = (CONFIG_SYS_CLK_FREQ * sys_info.pllFbkDiv) / sys_info.pllOpbDiv;
1008 return val;
1011 #elif defined(CONFIG_405EX)
1014 * TODO: We need to get the CPR registers and calculate these values correctly!!!!
1015 * We need the specs!!!!
1017 static unsigned char get_fbdv(unsigned char index)
1019 unsigned char ret = 0;
1020 /* This is table should be 256 bytes.
1021 * Only take first 52 values.
1023 unsigned char fbdv_tb[] = {
1024 0x00, 0xff, 0x7f, 0xfd,
1025 0x7a, 0xf5, 0x6a, 0xd5,
1026 0x2a, 0xd4, 0x29, 0xd3,
1027 0x26, 0xcc, 0x19, 0xb3,
1028 0x67, 0xce, 0x1d, 0xbb,
1029 0x77, 0xee, 0x5d, 0xba,
1030 0x74, 0xe9, 0x52, 0xa5,
1031 0x4b, 0x96, 0x2c, 0xd8,
1032 0x31, 0xe3, 0x46, 0x8d,
1033 0x1b, 0xb7, 0x6f, 0xde,
1034 0x3d, 0xfb, 0x76, 0xed,
1035 0x5a, 0xb5, 0x6b, 0xd6,
1036 0x2d, 0xdb, 0x36, 0xec,
1040 if ((index & 0x7f) == 0)
1041 return 1;
1042 while (ret < sizeof (fbdv_tb)) {
1043 if (fbdv_tb[ret] == index)
1044 break;
1045 ret++;
1047 ret++;
1049 return ret;
1052 #define PLL_FBK_PLL_LOCAL 0
1053 #define PLL_FBK_CPU 1
1054 #define PLL_FBK_PERCLK 5
1056 void get_sys_info (sys_info_t * sysInfo)
1058 unsigned long sysClkPeriodPs = ONE_BILLION / (CONFIG_SYS_CLK_FREQ / 1000);
1059 unsigned long m = 1;
1060 unsigned int tmp;
1061 unsigned char fwdva[16] = {
1062 1, 2, 14, 9, 4, 11, 16, 13,
1063 12, 5, 6, 15, 10, 7, 8, 3,
1065 unsigned char sel, cpudv0, plb2xDiv;
1067 mfcpr(cpr0_plld, tmp);
1070 * Determine forward divider A
1072 sysInfo->pllFwdDiv = fwdva[((tmp >> 16) & 0x0f)]; /* FWDVA */
1075 * Determine FBK_DIV.
1077 sysInfo->pllFbkDiv = get_fbdv(((tmp >> 24) & 0x0ff)); /* FBDV */
1080 * Determine PLBDV0
1082 sysInfo->pllPlbDiv = 2;
1085 * Determine PERDV0
1087 mfcpr(cpr0_perd, tmp);
1088 tmp = (tmp >> 24) & 0x03;
1089 sysInfo->pllExtBusDiv = (tmp == 0) ? 4 : tmp;
1092 * Determine OPBDV0
1094 mfcpr(cpr0_opbd, tmp);
1095 tmp = (tmp >> 24) & 0x03;
1096 sysInfo->pllOpbDiv = (tmp == 0) ? 4 : tmp;
1098 /* Determine PLB2XDV0 */
1099 mfcpr(cpr0_plbd, tmp);
1100 tmp = (tmp >> 16) & 0x07;
1101 plb2xDiv = (tmp == 0) ? 8 : tmp;
1103 /* Determine CPUDV0 */
1104 mfcpr(cpr0_cpud, tmp);
1105 tmp = (tmp >> 24) & 0x07;
1106 cpudv0 = (tmp == 0) ? 8 : tmp;
1108 /* Determine SEL(5:7) in CPR0_PLLC */
1109 mfcpr(cpr0_pllc, tmp);
1110 sel = (tmp >> 24) & 0x07;
1113 * Determine the M factor
1114 * PLL local: M = FBDV
1115 * CPU clock: M = FBDV * FWDVA * CPUDV0
1116 * PerClk : M = FBDV * FWDVA * PLB2XDV0 * PLBDV0(2) * OPBDV0 * PERDV0
1119 switch (sel) {
1120 case PLL_FBK_CPU:
1121 m = sysInfo->pllFwdDiv * cpudv0;
1122 break;
1123 case PLL_FBK_PERCLK:
1124 m = sysInfo->pllFwdDiv * plb2xDiv * 2
1125 * sysInfo->pllOpbDiv * sysInfo->pllExtBusDiv;
1126 break;
1127 case PLL_FBK_PLL_LOCAL:
1128 break;
1129 default:
1130 printf("%s unknown m\n", __FUNCTION__);
1131 return;
1134 m *= sysInfo->pllFbkDiv;
1137 * Determine VCO clock frequency
1139 sysInfo->freqVCOHz = (1000000000000LL * (unsigned long long)m) /
1140 (unsigned long long)sysClkPeriodPs;
1143 * Determine CPU clock frequency
1145 sysInfo->freqProcessor = sysInfo->freqVCOHz / (sysInfo->pllFwdDiv * cpudv0);
1148 * Determine PLB clock frequency, ddr1x should be the same
1150 sysInfo->freqPLB = sysInfo->freqVCOHz / (sysInfo->pllFwdDiv * plb2xDiv * 2);
1151 sysInfo->freqOPB = sysInfo->freqPLB/sysInfo->pllOpbDiv;
1152 sysInfo->freqDDR = sysInfo->freqPLB;
1153 sysInfo->freqEBC = sysInfo->freqOPB / sysInfo->pllExtBusDiv;
1154 sysInfo->freqUART = sysInfo->freqPLB;
1157 /********************************************
1158 * get_OPB_freq
1159 * return OPB bus freq in Hz
1160 *********************************************/
1161 ulong get_OPB_freq (void)
1163 ulong val = 0;
1165 PPC4xx_SYS_INFO sys_info;
1167 get_sys_info (&sys_info);
1168 val = sys_info.freqPLB / sys_info.pllOpbDiv;
1170 return val;
1173 #endif
1175 int get_clocks (void)
1177 #if defined(CONFIG_405GP) || defined(CONFIG_405CR) || \
1178 defined(CONFIG_405EP) || defined(CONFIG_405EZ) || \
1179 defined(CONFIG_405EX) || defined(CONFIG_405) || \
1180 defined(CONFIG_440)
1181 sys_info_t sys_info;
1183 get_sys_info (&sys_info);
1184 gd->cpu_clk = sys_info.freqProcessor;
1185 gd->bus_clk = sys_info.freqPLB;
1187 #endif /* defined(CONFIG_405GP) || defined(CONFIG_405CR) */
1189 #ifdef CONFIG_IOP480
1190 gd->cpu_clk = 66000000;
1191 gd->bus_clk = 66000000;
1192 #endif
1193 return (0);
1197 /********************************************
1198 * get_bus_freq
1199 * return PLB bus freq in Hz
1200 *********************************************/
1201 ulong get_bus_freq (ulong dummy)
1203 ulong val;
1205 #if defined(CONFIG_405GP) || defined(CONFIG_405CR) || \
1206 defined(CONFIG_405EP) || defined(CONFIG_405EZ) || \
1207 defined(CONFIG_405EX) || defined(CONFIG_405) || \
1208 defined(CONFIG_440)
1209 sys_info_t sys_info;
1211 get_sys_info (&sys_info);
1212 val = sys_info.freqPLB;
1214 #elif defined(CONFIG_IOP480)
1216 val = 66;
1218 #else
1219 # error get_bus_freq() not implemented
1220 #endif
1222 return val;