sun50i: h5: Add initial NanoPi NEO2 support
[oweals/u-boot.git] / arch / powerpc / cpu / ppc4xx / speed.c
1 /*
2  * (C) Copyright 2000-2008
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 #include <common.h>
9 #include <ppc_asm.tmpl>
10 #include <asm/ppc4xx.h>
11 #include <asm/processor.h>
12
13 DECLARE_GLOBAL_DATA_PTR;
14
15 #define ONE_BILLION        1000000000
16 #ifdef DEBUG
17 #define DEBUGF(fmt,args...) printf(fmt ,##args)
18 #else
19 #define DEBUGF(fmt,args...)
20 #endif
21
22 #if defined(CONFIG_405GP)
23
24 void get_sys_info (PPC4xx_SYS_INFO * sysInfo)
25 {
26         unsigned long pllmr;
27         unsigned long sysClkPeriodPs = ONE_BILLION / (CONFIG_SYS_CLK_FREQ / 1000);
28         uint pvr = get_pvr();
29         unsigned long psr;
30         unsigned long m;
31
32         /*
33          * Read PLL Mode register
34          */
35         pllmr = mfdcr (CPC0_PLLMR);
36
37         /*
38          * Read Pin Strapping register
39          */
40         psr = mfdcr (CPC0_PSR);
41
42         /*
43          * Determine FWD_DIV.
44          */
45         sysInfo->pllFwdDiv = 8 - ((pllmr & PLLMR_FWD_DIV_MASK) >> 29);
46
47         /*
48          * Determine FBK_DIV.
49          */
50         sysInfo->pllFbkDiv = ((pllmr & PLLMR_FB_DIV_MASK) >> 25);
51         if (sysInfo->pllFbkDiv == 0) {
52                 sysInfo->pllFbkDiv = 16;
53         }
54
55         /*
56          * Determine PLB_DIV.
57          */
58         sysInfo->pllPlbDiv = ((pllmr & PLLMR_CPU_TO_PLB_MASK) >> 17) + 1;
59
60         /*
61          * Determine PCI_DIV.
62          */
63         sysInfo->pllPciDiv = ((pllmr & PLLMR_PCI_TO_PLB_MASK) >> 13) + 1;
64
65         /*
66          * Determine EXTBUS_DIV.
67          */
68         sysInfo->pllExtBusDiv = ((pllmr & PLLMR_EXB_TO_PLB_MASK) >> 11) + 2;
69
70         /*
71          * Determine OPB_DIV.
72          */
73         sysInfo->pllOpbDiv = ((pllmr & PLLMR_OPB_TO_PLB_MASK) >> 15) + 1;
74
75         /*
76          * Check if PPC405GPr used (mask minor revision field)
77          */
78         if ((pvr & 0xfffffff0) == (PVR_405GPR_RB & 0xfffffff0)) {
79                 /*
80                  * Determine FWD_DIV B (only PPC405GPr with new mode strapping).
81                  */
82                 sysInfo->pllFwdDivB = 8 - (pllmr & PLLMR_FWDB_DIV_MASK);
83
84                 /*
85                  * Determine factor m depending on PLL feedback clock source
86                  */
87                 if (!(psr & PSR_PCI_ASYNC_EN)) {
88                         if (psr & PSR_NEW_MODE_EN) {
89                                 /*
90                                  * sync pci clock used as feedback (new mode)
91                                  */
92                                 m = 1 * sysInfo->pllFwdDivB * 2 * sysInfo->pllPciDiv;
93                         } else {
94                                 /*
95                                  * sync pci clock used as feedback (legacy mode)
96                                  */
97                                 m = 1 * sysInfo->pllFwdDivB * sysInfo->pllPlbDiv * sysInfo->pllPciDiv;
98                         }
99                 } else if (psr & PSR_NEW_MODE_EN) {
100                         if (psr & PSR_PERCLK_SYNC_MODE_EN) {
101                                 /*
102                                  * PerClk used as feedback (new mode)
103                                  */
104                                 m = 1 * sysInfo->pllFwdDivB * 2 * sysInfo->pllExtBusDiv;
105                         } else {
106                                 /*
107                                  * CPU clock used as feedback (new mode)
108                                  */
109                                 m = sysInfo->pllFbkDiv * sysInfo->pllFwdDiv;
110                         }
111                 } else if (sysInfo->pllExtBusDiv == sysInfo->pllFbkDiv) {
112                         /*
113                          * PerClk used as feedback (legacy mode)
114                          */
115                         m = 1 * sysInfo->pllFwdDivB * sysInfo->pllPlbDiv * sysInfo->pllExtBusDiv;
116                 } else {
117                         /*
118                          * PLB clock used as feedback (legacy mode)
119                          */
120                         m = sysInfo->pllFbkDiv * sysInfo->pllFwdDivB * sysInfo->pllPlbDiv;
121                 }
122
123                 sysInfo->freqVCOHz = (1000000000000LL * (unsigned long long)m) /
124                         (unsigned long long)sysClkPeriodPs;
125                 sysInfo->freqProcessor = sysInfo->freqVCOHz / sysInfo->pllFwdDiv;
126                 sysInfo->freqPLB = sysInfo->freqVCOHz / (sysInfo->pllFwdDivB * sysInfo->pllPlbDiv);
127         } else {
128                 /*
129                  * Check pllFwdDiv to see if running in bypass mode where the CPU speed
130                  * is equal to the 405GP SYS_CLK_FREQ. If not in bypass mode, check VCO
131                  * to make sure it is within the proper range.
132                  *    spec:    VCO = SYS_CLOCK x FBKDIV x PLBDIV x FWDDIV
133                  * Note freqVCO is calculated in MHz to avoid errors introduced by rounding.
134                  */
135                 if (sysInfo->pllFwdDiv == 1) {
136                         sysInfo->freqProcessor = CONFIG_SYS_CLK_FREQ;
137                         sysInfo->freqPLB = CONFIG_SYS_CLK_FREQ / sysInfo->pllPlbDiv;
138                 } else {
139                         sysInfo->freqVCOHz = ( 1000000000000LL *
140                                                (unsigned long long)sysInfo->pllFwdDiv *
141                                                (unsigned long long)sysInfo->pllFbkDiv *
142                                                (unsigned long long)sysInfo->pllPlbDiv
143                                 ) / (unsigned long long)sysClkPeriodPs;
144                         sysInfo->freqPLB = (ONE_BILLION / ((sysClkPeriodPs * 10) /
145                                                            sysInfo->pllFbkDiv)) * 10000;
146                         sysInfo->freqProcessor = sysInfo->freqPLB * sysInfo->pllPlbDiv;
147                 }
148         }
149
150         sysInfo->freqOPB = sysInfo->freqPLB / sysInfo->pllOpbDiv;
151         sysInfo->freqEBC = sysInfo->freqPLB / sysInfo->pllExtBusDiv;
152         sysInfo->freqUART = sysInfo->freqProcessor;
153 }
154
155
156 /********************************************
157  * get_PCI_freq
158  * return PCI bus freq in Hz
159  *********************************************/
160 ulong get_PCI_freq (void)
161 {
162         ulong val;
163         PPC4xx_SYS_INFO sys_info;
164
165         get_sys_info (&sys_info);
166         val = sys_info.freqPLB / sys_info.pllPciDiv;
167         return val;
168 }
169
170
171 #elif defined(CONFIG_440)
172
173 #if defined(CONFIG_460EX) || defined(CONFIG_460GT) || \
174     defined(CONFIG_460SX)
175 static u8 pll_fwdv_multi_bits[] = {
176         /* values for:  1 - 16 */
177         0x00, 0x01, 0x0f, 0x04, 0x09, 0x0a, 0x0d, 0x0e, 0x03, 0x0c,
178         0x05, 0x08, 0x07, 0x02, 0x0b, 0x06
179 };
180
181 u32 get_cpr0_fwdv(unsigned long cpr_reg_fwdv)
182 {
183         u32 index;
184
185         for (index = 0; index < ARRAY_SIZE(pll_fwdv_multi_bits); index++)
186                 if (cpr_reg_fwdv == (u32)pll_fwdv_multi_bits[index])
187                         return index + 1;
188
189         return 0;
190 }
191
192 static u8 pll_fbdv_multi_bits[] = {
193         /* values for:  1 - 100 */
194         0x00, 0xff, 0x7e, 0xfd, 0x7a, 0xf5, 0x6a, 0xd5, 0x2a, 0xd4,
195         0x29, 0xd3, 0x26, 0xcc, 0x19, 0xb3, 0x67, 0xce, 0x1d, 0xbb,
196         0x77, 0xee, 0x5d, 0xba, 0x74, 0xe9, 0x52, 0xa5, 0x4b, 0x96,
197         0x2c, 0xd8, 0x31, 0xe3, 0x46, 0x8d, 0x1b, 0xb7, 0x6f, 0xde,
198         0x3d, 0xfb, 0x76, 0xed, 0x5a, 0xb5, 0x6b, 0xd6, 0x2d, 0xdb,
199         0x36, 0xec, 0x59, 0xb2, 0x64, 0xc9, 0x12, 0xa4, 0x48, 0x91,
200         0x23, 0xc7, 0x0e, 0x9c, 0x38, 0xf0, 0x61, 0xc2, 0x05, 0x8b,
201         0x17, 0xaf, 0x5f, 0xbe, 0x7c, 0xf9, 0x72, 0xe5, 0x4a, 0x95,
202         0x2b, 0xd7, 0x2e, 0xdc, 0x39, 0xf3, 0x66, 0xcd, 0x1a, 0xb4,
203         0x68, 0xd1, 0x22, 0xc4, 0x09, 0x93, 0x27, 0xcf, 0x1e, 0xbc,
204         /* values for:  101 - 200 */
205         0x78, 0xf1, 0x62, 0xc5, 0x0a, 0x94, 0x28, 0xd0, 0x21, 0xc3,
206         0x06, 0x8c, 0x18, 0xb0, 0x60, 0xc1, 0x02, 0x84, 0x08, 0x90,
207         0x20, 0xc0, 0x01, 0x83, 0x07, 0x8f, 0x1f, 0xbf, 0x7f, 0xfe,
208         0x7d, 0xfa, 0x75, 0xea, 0x55, 0xaa, 0x54, 0xa9, 0x53, 0xa6,
209         0x4c, 0x99, 0x33, 0xe7, 0x4e, 0x9d, 0x3b, 0xf7, 0x6e, 0xdd,
210         0x3a, 0xf4, 0x69, 0xd2, 0x25, 0xcb, 0x16, 0xac, 0x58, 0xb1,
211         0x63, 0xc6, 0x0d, 0x9b, 0x37, 0xef, 0x5e, 0xbd, 0x7b, 0xf6,
212         0x6d, 0xda, 0x35, 0xeb, 0x56, 0xad, 0x5b, 0xb6, 0x6c, 0xd9,
213         0x32, 0xe4, 0x49, 0x92, 0x24, 0xc8, 0x11, 0xa3, 0x47, 0x8e,
214         0x1c, 0xb8, 0x70, 0xe1, 0x42, 0x85, 0x0b, 0x97, 0x2f, 0xdf,
215         /* values for:  201 - 255 */
216         0x3e, 0xfc, 0x79, 0xf2, 0x65, 0xca, 0x15, 0xab, 0x57, 0xae,
217         0x5c, 0xb9, 0x73, 0xe6, 0x4d, 0x9a, 0x34, 0xe8, 0x51, 0xa2,
218         0x44, 0x89, 0x13, 0xa7, 0x4f, 0x9e, 0x3c, 0xf8, 0x71, 0xe2,
219         0x45, 0x8a, 0x14, 0xa8, 0x50, 0xa1, 0x43, 0x86, 0x0c, 0x98,
220         0x30, 0xe0, 0x41, 0x82, 0x04, 0x88, 0x10, 0xa0, 0x40, 0x81,
221         0x03, 0x87, 0x0f, 0x9f, 0x3f  /* END */
222 };
223
224 u32 get_cpr0_fbdv(unsigned long cpr_reg_fbdv)
225 {
226         u32 index;
227
228         for (index = 0; index < ARRAY_SIZE(pll_fbdv_multi_bits); index++)
229                 if (cpr_reg_fbdv == (u32)pll_fbdv_multi_bits[index])
230                         return index + 1;
231
232         return 0;
233 }
234
235 /*
236  * AMCC_TODO: verify this routine against latest EAS, cause stuff changed
237  *            with latest EAS
238  */
239 void get_sys_info (sys_info_t * sysInfo)
240 {
241         unsigned long strp0;
242         unsigned long strp1;
243         unsigned long temp;
244         unsigned long m;
245         unsigned long plbedv0;
246
247         /* Extract configured divisors */
248         mfsdr(SDR0_SDSTP0, strp0);
249         mfsdr(SDR0_SDSTP1, strp1);
250
251         temp = ((strp0 & PLLSYS0_FWD_DIV_A_MASK) >> 4);
252         sysInfo->pllFwdDivA = get_cpr0_fwdv(temp);
253
254         temp = (strp0 & PLLSYS0_FWD_DIV_B_MASK);
255         sysInfo->pllFwdDivB = get_cpr0_fwdv(temp);
256
257         temp = (strp0 & PLLSYS0_FB_DIV_MASK) >> 8;
258         sysInfo->pllFbkDiv = get_cpr0_fbdv(temp);
259
260         temp = (strp1 & PLLSYS0_OPB_DIV_MASK) >> 26;
261         sysInfo->pllOpbDiv = temp ? temp : 4;
262
263         /* AMCC_TODO: verify the SDR0_SDSTP1.PERDV0 value sysInfo->pllExtBusDiv */
264         temp = (strp1 & PLLSYS0_PERCLK_DIV_MASK) >> 24;
265         sysInfo->pllExtBusDiv = temp ? temp : 4;
266
267         temp = (strp1 & PLLSYS0_PLBEDV0_DIV_MASK) >> 29;
268         plbedv0 = temp ? temp: 8;
269
270         /* Calculate 'M' based on feedback source */
271         temp = (strp0 & PLLSYS0_SEL_MASK) >> 27;
272         if (temp == 0) {
273                 /* PLL internal feedback */
274                 m = sysInfo->pllFbkDiv;
275         } else {
276                 /* PLL PerClk feedback */
277                 m = sysInfo->pllFwdDivA * plbedv0 * sysInfo->pllOpbDiv *
278                         sysInfo->pllExtBusDiv;
279         }
280
281         /* Now calculate the individual clocks */
282         sysInfo->freqVCOMhz = (m * CONFIG_SYS_CLK_FREQ) + (m >> 1);
283         sysInfo->freqProcessor = sysInfo->freqVCOMhz/sysInfo->pllFwdDivA;
284         sysInfo->freqPLB = sysInfo->freqVCOMhz / sysInfo->pllFwdDivA / plbedv0;
285         sysInfo->freqOPB = sysInfo->freqPLB / sysInfo->pllOpbDiv;
286         sysInfo->freqEBC = sysInfo->freqOPB / sysInfo->pllExtBusDiv;
287         sysInfo->freqDDR = sysInfo->freqPLB;
288         sysInfo->freqUART = sysInfo->freqPLB;
289
290         return;
291 }
292
293 #elif defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
294     defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
295 void get_sys_info (sys_info_t *sysInfo)
296 {
297         unsigned long temp;
298         unsigned long reg;
299         unsigned long lfdiv;
300         unsigned long m;
301         unsigned long prbdv0;
302         /*
303           WARNING: ASSUMES the following:
304           ENG=1
305           PRADV0=1
306           PRBDV0=1
307         */
308
309         /* Decode CPR0_PLLD0 for divisors */
310         mfcpr(CPR0_PLLD, reg);
311         temp = (reg & PLLD_FWDVA_MASK) >> 16;
312         sysInfo->pllFwdDivA = temp ? temp : 16;
313         temp = (reg & PLLD_FWDVB_MASK) >> 8;
314         sysInfo->pllFwdDivB = temp ? temp: 8 ;
315         temp = (reg & PLLD_FBDV_MASK) >> 24;
316         sysInfo->pllFbkDiv = temp ? temp : 32;
317         lfdiv = reg & PLLD_LFBDV_MASK;
318
319         mfcpr(CPR0_OPBD0, reg);
320         temp = (reg & OPBDDV_MASK) >> 24;
321         sysInfo->pllOpbDiv = temp ? temp : 4;
322
323         mfcpr(CPR0_PERD, reg);
324         temp = (reg & PERDV_MASK) >> 24;
325         sysInfo->pllExtBusDiv = temp ? temp : 8;
326
327         mfcpr(CPR0_PRIMBD0, reg);
328         temp = (reg & PRBDV_MASK) >> 24;
329         prbdv0 = temp ? temp : 8;
330
331         mfcpr(CPR0_SPCID, reg);
332         temp = (reg & SPCID_MASK) >> 24;
333         sysInfo->pllPciDiv = temp ? temp : 4;
334
335         /* Calculate 'M' based on feedback source */
336         mfsdr(SDR0_SDSTP0, reg);
337         temp = (reg & PLLSYS0_SEL_MASK) >> 27;
338         if (temp == 0) { /* PLL output */
339                 /* Figure which pll to use */
340                 mfcpr(CPR0_PLLC, reg);
341                 temp = (reg & PLLC_SRC_MASK) >> 29;
342                 if (!temp) /* PLLOUTA */
343                         m = sysInfo->pllFbkDiv * lfdiv * sysInfo->pllFwdDivA;
344                 else       /* PLLOUTB */
345                         m = sysInfo->pllFbkDiv * lfdiv * sysInfo->pllFwdDivB;
346         }
347         else if (temp == 1) /* CPU output */
348                 m = sysInfo->pllFbkDiv * sysInfo->pllFwdDivA;
349         else /* PerClk */
350                 m = sysInfo->pllExtBusDiv * sysInfo->pllOpbDiv * sysInfo->pllFwdDivB;
351
352         /* Now calculate the individual clocks */
353         sysInfo->freqVCOMhz = (m * CONFIG_SYS_CLK_FREQ) + (m>>1);
354         sysInfo->freqProcessor = sysInfo->freqVCOMhz/sysInfo->pllFwdDivA;
355         sysInfo->freqPLB = sysInfo->freqVCOMhz/sysInfo->pllFwdDivB/prbdv0;
356         sysInfo->freqOPB = sysInfo->freqPLB/sysInfo->pllOpbDiv;
357         sysInfo->freqEBC = sysInfo->freqPLB/sysInfo->pllExtBusDiv;
358         sysInfo->freqPCI = sysInfo->freqPLB/sysInfo->pllPciDiv;
359         sysInfo->freqUART = sysInfo->freqPLB;
360
361         /* Figure which timer source to use */
362         if (mfspr(SPRN_CCR1) & 0x0080) {
363                 /* External Clock, assume same as SYS_CLK */
364                 temp = sysInfo->freqProcessor / 2;  /* Max extern clock speed */
365                 if (CONFIG_SYS_CLK_FREQ > temp)
366                         sysInfo->freqTmrClk = temp;
367                 else
368                         sysInfo->freqTmrClk = CONFIG_SYS_CLK_FREQ;
369         }
370         else  /* Internal clock */
371                 sysInfo->freqTmrClk = sysInfo->freqProcessor;
372 }
373
374 /********************************************
375  * get_PCI_freq
376  * return PCI bus freq in Hz
377  *********************************************/
378 ulong get_PCI_freq (void)
379 {
380         sys_info_t sys_info;
381         get_sys_info (&sys_info);
382         return sys_info.freqPCI;
383 }
384
385 #elif !defined(CONFIG_440GX) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) \
386         && !defined(CONFIG_XILINX_440)
387 void get_sys_info (sys_info_t * sysInfo)
388 {
389         unsigned long strp0;
390         unsigned long temp;
391         unsigned long m;
392
393         /* Extract configured divisors */
394         strp0 = mfdcr( CPC0_STRP0 );
395         sysInfo->pllFwdDivA = 8 - ((strp0 & PLLSYS0_FWD_DIV_A_MASK) >> 15);
396         sysInfo->pllFwdDivB = 8 - ((strp0 & PLLSYS0_FWD_DIV_B_MASK) >> 12);
397         temp = (strp0 & PLLSYS0_FB_DIV_MASK) >> 18;
398         sysInfo->pllFbkDiv = temp ? temp : 16;
399         sysInfo->pllOpbDiv = 1 + ((strp0 & PLLSYS0_OPB_DIV_MASK) >> 10);
400         sysInfo->pllExtBusDiv = 1 + ((strp0 & PLLSYS0_EPB_DIV_MASK) >> 8);
401
402         /* Calculate 'M' based on feedback source */
403         if( strp0 & PLLSYS0_EXTSL_MASK )
404                 m = sysInfo->pllExtBusDiv * sysInfo->pllOpbDiv * sysInfo->pllFwdDivB;
405         else
406                 m = sysInfo->pllFbkDiv * sysInfo->pllFwdDivA;
407
408         /* Now calculate the individual clocks */
409         sysInfo->freqVCOMhz = (m * CONFIG_SYS_CLK_FREQ) + (m>>1);
410         sysInfo->freqProcessor = sysInfo->freqVCOMhz/sysInfo->pllFwdDivA;
411         sysInfo->freqPLB = sysInfo->freqVCOMhz/sysInfo->pllFwdDivB;
412         if( get_pvr() == PVR_440GP_RB ) /* Rev B divs an extra 2 -- geez! */
413                 sysInfo->freqPLB >>= 1;
414         sysInfo->freqOPB = sysInfo->freqPLB/sysInfo->pllOpbDiv;
415         sysInfo->freqEBC = sysInfo->freqOPB/sysInfo->pllExtBusDiv;
416         sysInfo->freqUART = sysInfo->freqPLB;
417 }
418 #else
419
420 #if !defined(CONFIG_XILINX_440)
421 void get_sys_info (sys_info_t * sysInfo)
422 {
423         unsigned long strp0;
424         unsigned long strp1;
425         unsigned long temp;
426         unsigned long temp1;
427         unsigned long lfdiv;
428         unsigned long m;
429         unsigned long prbdv0;
430
431 #if defined(CONFIG_YUCCA)
432         unsigned long sys_freq;
433         unsigned long sys_per=0;
434         unsigned long msr;
435         unsigned long pci_clock_per;
436         unsigned long sdr_ddrpll;
437
438         /*-------------------------------------------------------------------------+
439          | Get the system clock period.
440          +-------------------------------------------------------------------------*/
441         sys_per = determine_sysper();
442
443         msr = (mfmsr () & ~(MSR_EE));   /* disable interrupts */
444
445         /*-------------------------------------------------------------------------+
446          | Calculate the system clock speed from the period.
447          +-------------------------------------------------------------------------*/
448         sys_freq = (ONE_BILLION / sys_per) * 1000;
449 #endif
450
451         /* Extract configured divisors */
452         mfsdr( SDR0_SDSTP0,strp0 );
453         mfsdr( SDR0_SDSTP1,strp1 );
454
455         temp = ((strp0 & PLLSYS0_FWD_DIV_A_MASK) >> 8);
456         sysInfo->pllFwdDivA = temp ? temp : 16 ;
457         temp = ((strp0 & PLLSYS0_FWD_DIV_B_MASK) >> 5);
458         sysInfo->pllFwdDivB = temp ? temp: 8 ;
459         temp = (strp0 & PLLSYS0_FB_DIV_MASK) >> 12;
460         sysInfo->pllFbkDiv = temp ? temp : 32;
461         temp = (strp0 & PLLSYS0_OPB_DIV_MASK);
462         sysInfo->pllOpbDiv = temp ? temp : 4;
463         temp = (strp1 & PLLSYS1_PERCLK_DIV_MASK) >> 24;
464         sysInfo->pllExtBusDiv = temp ? temp : 4;
465         prbdv0 = (strp0 >> 2) & 0x7;
466
467         /* Calculate 'M' based on feedback source */
468         temp = (strp0 & PLLSYS0_SEL_MASK) >> 27;
469         temp1 = (strp1 & PLLSYS1_LF_DIV_MASK) >> 26;
470         lfdiv = temp1 ? temp1 : 64;
471         if (temp == 0) { /* PLL output */
472                 /* Figure which pll to use */
473                 temp = (strp0 & PLLSYS0_SRC_MASK) >> 30;
474                 if (!temp)
475                         m = sysInfo->pllFbkDiv * lfdiv * sysInfo->pllFwdDivA;
476                 else
477                         m = sysInfo->pllFbkDiv * lfdiv * sysInfo->pllFwdDivB;
478         }
479         else if (temp == 1) /* CPU output */
480                 m = sysInfo->pllFbkDiv * sysInfo->pllFwdDivA;
481         else /* PerClk */
482                 m = sysInfo->pllExtBusDiv * sysInfo->pllOpbDiv * sysInfo->pllFwdDivB;
483
484         /* Now calculate the individual clocks */
485 #if defined(CONFIG_YUCCA)
486         sysInfo->freqVCOMhz = (m * sys_freq) ;
487 #else
488         sysInfo->freqVCOMhz = (m * CONFIG_SYS_CLK_FREQ) + (m >> 1);
489 #endif
490         sysInfo->freqProcessor = sysInfo->freqVCOMhz/sysInfo->pllFwdDivA;
491         sysInfo->freqPLB = sysInfo->freqVCOMhz/sysInfo->pllFwdDivB/prbdv0;
492         sysInfo->freqOPB = sysInfo->freqPLB/sysInfo->pllOpbDiv;
493         sysInfo->freqEBC = sysInfo->freqOPB/sysInfo->pllExtBusDiv;
494
495 #if defined(CONFIG_YUCCA)
496         /* Determine PCI Clock Period */
497         pci_clock_per = determine_pci_clock_per();
498         sysInfo->freqPCI = (ONE_BILLION/pci_clock_per) * 1000;
499         mfsdr(SDR0_DDR0, sdr_ddrpll);
500         sysInfo->freqDDR = ((sysInfo->freqPLB) * SDR0_DDR0_DDRM_DECODE(sdr_ddrpll));
501 #endif
502
503         sysInfo->freqUART = sysInfo->freqPLB;
504 }
505
506 #endif
507 #endif /* CONFIG_XILINX_440 */
508
509 #if defined(CONFIG_YUCCA)
510 unsigned long determine_sysper(void)
511 {
512         unsigned int fpga_clocking_reg;
513         unsigned int master_clock_selection;
514         unsigned long master_clock_per = 0;
515         unsigned long fb_div_selection;
516         unsigned int vco_div_reg_value;
517         unsigned long vco_div_selection;
518         unsigned long sys_per = 0;
519         int extClkVal;
520
521         /*-------------------------------------------------------------------------+
522          | Read FPGA reg 0 and reg 1 to get FPGA reg information
523          +-------------------------------------------------------------------------*/
524         fpga_clocking_reg = in16(FPGA_REG16);
525
526
527         /* Determine Master Clock Source Selection */
528         master_clock_selection = fpga_clocking_reg & FPGA_REG16_MASTER_CLK_MASK;
529
530         switch(master_clock_selection) {
531                 case FPGA_REG16_MASTER_CLK_66_66:
532                         master_clock_per = PERIOD_66_66MHZ;
533                         break;
534                 case FPGA_REG16_MASTER_CLK_50:
535                         master_clock_per = PERIOD_50_00MHZ;
536                         break;
537                 case FPGA_REG16_MASTER_CLK_33_33:
538                         master_clock_per = PERIOD_33_33MHZ;
539                         break;
540                 case FPGA_REG16_MASTER_CLK_25:
541                         master_clock_per = PERIOD_25_00MHZ;
542                         break;
543                 case FPGA_REG16_MASTER_CLK_EXT:
544                         if ((extClkVal==EXTCLK_33_33)
545                                         && (extClkVal==EXTCLK_50)
546                                         && (extClkVal==EXTCLK_66_66)
547                                         && (extClkVal==EXTCLK_83)) {
548                                 /* calculate master clock period from external clock value */
549                                 master_clock_per=(ONE_BILLION/extClkVal) * 1000;
550                         } else {
551                                 /* Unsupported */
552                                 DEBUGF ("%s[%d] *** master clock selection failed ***\n", __FUNCTION__,__LINE__);
553                                 hang();
554                         }
555                         break;
556                 default:
557                         /* Unsupported */
558                         DEBUGF ("%s[%d] *** master clock selection failed ***\n", __FUNCTION__,__LINE__);
559                         hang();
560                         break;
561         }
562
563         /* Determine FB divisors values */
564         if ((fpga_clocking_reg & FPGA_REG16_FB1_DIV_MASK) == FPGA_REG16_FB1_DIV_LOW) {
565                 if ((fpga_clocking_reg & FPGA_REG16_FB2_DIV_MASK) == FPGA_REG16_FB2_DIV_LOW)
566                         fb_div_selection = FPGA_FB_DIV_6;
567                 else
568                         fb_div_selection = FPGA_FB_DIV_12;
569         } else {
570                 if ((fpga_clocking_reg & FPGA_REG16_FB2_DIV_MASK) == FPGA_REG16_FB2_DIV_LOW)
571                         fb_div_selection = FPGA_FB_DIV_10;
572                 else
573                         fb_div_selection = FPGA_FB_DIV_20;
574         }
575
576         /* Determine VCO divisors values */
577         vco_div_reg_value = fpga_clocking_reg & FPGA_REG16_VCO_DIV_MASK;
578
579         switch(vco_div_reg_value) {
580                 case FPGA_REG16_VCO_DIV_4:
581                         vco_div_selection = FPGA_VCO_DIV_4;
582                         break;
583                 case FPGA_REG16_VCO_DIV_6:
584                         vco_div_selection = FPGA_VCO_DIV_6;
585                         break;
586                 case FPGA_REG16_VCO_DIV_8:
587                         vco_div_selection = FPGA_VCO_DIV_8;
588                         break;
589                 case FPGA_REG16_VCO_DIV_10:
590                 default:
591                         vco_div_selection = FPGA_VCO_DIV_10;
592                         break;
593         }
594
595         if (master_clock_selection == FPGA_REG16_MASTER_CLK_EXT) {
596                 switch(master_clock_per) {
597                         case PERIOD_25_00MHZ:
598                                 if (fb_div_selection == FPGA_FB_DIV_12) {
599                                         if (vco_div_selection == FPGA_VCO_DIV_4)
600                                                 sys_per = PERIOD_75_00MHZ;
601                                         if (vco_div_selection == FPGA_VCO_DIV_6)
602                                                 sys_per = PERIOD_50_00MHZ;
603                                 }
604                                 break;
605                         case PERIOD_33_33MHZ:
606                                 if (fb_div_selection == FPGA_FB_DIV_6) {
607                                         if (vco_div_selection == FPGA_VCO_DIV_4)
608                                                 sys_per = PERIOD_50_00MHZ;
609                                         if (vco_div_selection == FPGA_VCO_DIV_6)
610                                                 sys_per = PERIOD_33_33MHZ;
611                                 }
612                                 if (fb_div_selection == FPGA_FB_DIV_10) {
613                                         if (vco_div_selection == FPGA_VCO_DIV_4)
614                                                 sys_per = PERIOD_83_33MHZ;
615                                         if (vco_div_selection == FPGA_VCO_DIV_10)
616                                                 sys_per = PERIOD_33_33MHZ;
617                                 }
618                                 if (fb_div_selection == FPGA_FB_DIV_12) {
619                                         if (vco_div_selection == FPGA_VCO_DIV_4)
620                                                 sys_per = PERIOD_100_00MHZ;
621                                         if (vco_div_selection == FPGA_VCO_DIV_6)
622                                                 sys_per = PERIOD_66_66MHZ;
623                                         if (vco_div_selection == FPGA_VCO_DIV_8)
624                                                 sys_per = PERIOD_50_00MHZ;
625                                 }
626                                 break;
627                         case PERIOD_50_00MHZ:
628                                 if (fb_div_selection == FPGA_FB_DIV_6) {
629                                         if (vco_div_selection == FPGA_VCO_DIV_4)
630                                                 sys_per = PERIOD_75_00MHZ;
631                                         if (vco_div_selection == FPGA_VCO_DIV_6)
632                                                 sys_per = PERIOD_50_00MHZ;
633                                 }
634                                 if (fb_div_selection == FPGA_FB_DIV_10) {
635                                         if (vco_div_selection == FPGA_VCO_DIV_6)
636                                                 sys_per = PERIOD_83_33MHZ;
637                                         if (vco_div_selection == FPGA_VCO_DIV_10)
638                                                 sys_per = PERIOD_50_00MHZ;
639                                 }
640                                 if (fb_div_selection == FPGA_FB_DIV_12) {
641                                         if (vco_div_selection == FPGA_VCO_DIV_6)
642                                                 sys_per = PERIOD_100_00MHZ;
643                                         if (vco_div_selection == FPGA_VCO_DIV_8)
644                                                 sys_per = PERIOD_75_00MHZ;
645                                 }
646                                 break;
647                         case PERIOD_66_66MHZ:
648                                 if (fb_div_selection == FPGA_FB_DIV_6) {
649                                         if (vco_div_selection == FPGA_VCO_DIV_4)
650                                                 sys_per = PERIOD_100_00MHZ;
651                                         if (vco_div_selection == FPGA_VCO_DIV_6)
652                                                 sys_per = PERIOD_66_66MHZ;
653                                         if (vco_div_selection == FPGA_VCO_DIV_8)
654                                                 sys_per = PERIOD_50_00MHZ;
655                                 }
656                                 if (fb_div_selection == FPGA_FB_DIV_10) {
657                                         if (vco_div_selection == FPGA_VCO_DIV_8)
658                                                 sys_per = PERIOD_83_33MHZ;
659                                         if (vco_div_selection == FPGA_VCO_DIV_10)
660                                                 sys_per = PERIOD_66_66MHZ;
661                                 }
662                                 if (fb_div_selection == FPGA_FB_DIV_12) {
663                                         if (vco_div_selection == FPGA_VCO_DIV_8)
664                                                 sys_per = PERIOD_100_00MHZ;
665                                 }
666                                 break;
667                         default:
668                                 break;
669                 }
670
671                 if (sys_per == 0) {
672                         /* Other combinations are not supported */
673                         DEBUGF ("%s[%d] *** sys period compute failed ***\n", __FUNCTION__,__LINE__);
674                         hang();
675                 }
676         } else {
677                 /* calcul system clock without cheking */
678                 /* if engineering option clock no check is selected */
679                 /* sys_per = master_clock_per * vco_div_selection / fb_div_selection */
680                 sys_per = (master_clock_per/fb_div_selection) * vco_div_selection;
681         }
682
683         return(sys_per);
684 }
685
686 /*-------------------------------------------------------------------------+
687 | determine_pci_clock_per.
688 +-------------------------------------------------------------------------*/
689 unsigned long determine_pci_clock_per(void)
690 {
691         unsigned long pci_clock_selection,  pci_period;
692
693         /*-------------------------------------------------------------------------+
694          | Read FPGA reg 6 to get PCI 0 FPGA reg information
695          +-------------------------------------------------------------------------*/
696         pci_clock_selection = in16(FPGA_REG16); /* was reg6 averifier */
697
698
699         pci_clock_selection = pci_clock_selection & FPGA_REG16_PCI0_CLK_MASK;
700
701         switch (pci_clock_selection) {
702                 case FPGA_REG16_PCI0_CLK_133_33:
703                         pci_period = PERIOD_133_33MHZ;
704                         break;
705                 case FPGA_REG16_PCI0_CLK_100:
706                         pci_period = PERIOD_100_00MHZ;
707                         break;
708                 case FPGA_REG16_PCI0_CLK_66_66:
709                         pci_period = PERIOD_66_66MHZ;
710                         break;
711                 default:
712                         pci_period = PERIOD_33_33MHZ;;
713                         break;
714         }
715
716         return(pci_period);
717 }
718 #endif
719
720 #elif defined(CONFIG_XILINX_405)
721 extern void get_sys_info (sys_info_t * sysInfo);
722 extern ulong get_PCI_freq (void);
723
724 #elif defined(CONFIG_405)
725
726 void get_sys_info (sys_info_t * sysInfo)
727 {
728         sysInfo->freqVCOMhz=3125000;
729         sysInfo->freqProcessor=12*1000*1000;
730         sysInfo->freqPLB=50*1000*1000;
731         sysInfo->freqPCI=66*1000*1000;
732 }
733
734 #elif defined(CONFIG_405EP)
735 void get_sys_info (PPC4xx_SYS_INFO * sysInfo)
736 {
737         unsigned long pllmr0;
738         unsigned long pllmr1;
739         unsigned long sysClkPeriodPs = ONE_BILLION / (CONFIG_SYS_CLK_FREQ / 1000);
740         unsigned long m;
741         unsigned long pllmr0_ccdv;
742
743         /*
744          * Read PLL Mode registers
745          */
746         pllmr0 = mfdcr (CPC0_PLLMR0);
747         pllmr1 = mfdcr (CPC0_PLLMR1);
748
749         /*
750          * Determine forward divider A
751          */
752         sysInfo->pllFwdDiv = 8 - ((pllmr1 & PLLMR1_FWDVA_MASK) >> 16);
753
754         /*
755          * Determine forward divider B (should be equal to A)
756          */
757         sysInfo->pllFwdDivB = 8 - ((pllmr1 & PLLMR1_FWDVB_MASK) >> 12);
758
759         /*
760          * Determine FBK_DIV.
761          */
762         sysInfo->pllFbkDiv = ((pllmr1 & PLLMR1_FBMUL_MASK) >> 20);
763         if (sysInfo->pllFbkDiv == 0)
764                 sysInfo->pllFbkDiv = 16;
765
766         /*
767          * Determine PLB_DIV.
768          */
769         sysInfo->pllPlbDiv = ((pllmr0 & PLLMR0_CPU_TO_PLB_MASK) >> 16) + 1;
770
771         /*
772          * Determine PCI_DIV.
773          */
774         sysInfo->pllPciDiv = (pllmr0 & PLLMR0_PCI_TO_PLB_MASK) + 1;
775
776         /*
777          * Determine EXTBUS_DIV.
778          */
779         sysInfo->pllExtBusDiv = ((pllmr0 & PLLMR0_EXB_TO_PLB_MASK) >> 8) + 2;
780
781         /*
782          * Determine OPB_DIV.
783          */
784         sysInfo->pllOpbDiv = ((pllmr0 & PLLMR0_OPB_TO_PLB_MASK) >> 12) + 1;
785
786         /*
787          * Determine the M factor
788          */
789         m = sysInfo->pllFbkDiv * sysInfo->pllFwdDivB;
790
791         /*
792          * Determine VCO clock frequency
793          */
794         sysInfo->freqVCOHz = (1000000000000LL * (unsigned long long)m) /
795                 (unsigned long long)sysClkPeriodPs;
796
797         /*
798          * Determine CPU clock frequency
799          */
800         pllmr0_ccdv = ((pllmr0 & PLLMR0_CPU_DIV_MASK) >> 20) + 1;
801         if (pllmr1 & PLLMR1_SSCS_MASK) {
802                 /*
803                  * This is true if FWDVA == FWDVB:
804                  * sysInfo->freqProcessor = (CONFIG_SYS_CLK_FREQ * sysInfo->pllFbkDiv)
805                  *      / pllmr0_ccdv;
806                  */
807                 sysInfo->freqProcessor = (CONFIG_SYS_CLK_FREQ * sysInfo->pllFbkDiv * sysInfo->pllFwdDivB)
808                         / sysInfo->pllFwdDiv / pllmr0_ccdv;
809         } else {
810                 sysInfo->freqProcessor = CONFIG_SYS_CLK_FREQ / pllmr0_ccdv;
811         }
812
813         /*
814          * Determine PLB clock frequency
815          */
816         sysInfo->freqPLB = sysInfo->freqProcessor / sysInfo->pllPlbDiv;
817
818         sysInfo->freqEBC = sysInfo->freqPLB / sysInfo->pllExtBusDiv;
819
820         sysInfo->freqOPB = sysInfo->freqPLB / sysInfo->pllOpbDiv;
821
822         sysInfo->freqUART = sysInfo->freqProcessor * pllmr0_ccdv;
823 }
824
825
826 /********************************************
827  * get_PCI_freq
828  * return PCI bus freq in Hz
829  *********************************************/
830 ulong get_PCI_freq (void)
831 {
832         ulong val;
833         PPC4xx_SYS_INFO sys_info;
834
835         get_sys_info (&sys_info);
836         val = sys_info.freqPLB / sys_info.pllPciDiv;
837         return val;
838 }
839
840 #elif defined(CONFIG_405EZ)
841 void get_sys_info (PPC4xx_SYS_INFO * sysInfo)
842 {
843         unsigned long cpr_plld;
844         unsigned long cpr_pllc;
845         unsigned long cpr_primad;
846         unsigned long sysClkPeriodPs = ONE_BILLION / (CONFIG_SYS_CLK_FREQ/1000);
847         unsigned long primad_cpudv;
848         unsigned long m;
849         unsigned long plloutb;
850
851         /*
852          * Read PLL Mode registers
853          */
854         mfcpr(CPR0_PLLD, cpr_plld);
855         mfcpr(CPR0_PLLC, cpr_pllc);
856
857         /*
858          * Determine forward divider A
859          */
860         sysInfo->pllFwdDiv = ((cpr_plld & PLLD_FWDVA_MASK) >> 16);
861
862         /*
863          * Determine forward divider B
864          */
865         sysInfo->pllFwdDivB = ((cpr_plld & PLLD_FWDVB_MASK) >> 8);
866         if (sysInfo->pllFwdDivB == 0)
867                 sysInfo->pllFwdDivB = 8;
868
869         /*
870          * Determine FBK_DIV.
871          */
872         sysInfo->pllFbkDiv = ((cpr_plld & PLLD_FBDV_MASK) >> 24);
873         if (sysInfo->pllFbkDiv == 0)
874                 sysInfo->pllFbkDiv = 256;
875
876         /*
877          * Read CPR_PRIMAD register
878          */
879         mfcpr(CPR0_PRIMAD, cpr_primad);
880
881         /*
882          * Determine PLB_DIV.
883          */
884         sysInfo->pllPlbDiv = ((cpr_primad & PRIMAD_PLBDV_MASK) >> 16);
885         if (sysInfo->pllPlbDiv == 0)
886                 sysInfo->pllPlbDiv = 16;
887
888         /*
889          * Determine EXTBUS_DIV.
890          */
891         sysInfo->pllExtBusDiv = (cpr_primad & PRIMAD_EBCDV_MASK);
892         if (sysInfo->pllExtBusDiv == 0)
893                 sysInfo->pllExtBusDiv = 16;
894
895         /*
896          * Determine OPB_DIV.
897          */
898         sysInfo->pllOpbDiv = ((cpr_primad & PRIMAD_OPBDV_MASK) >> 8);
899         if (sysInfo->pllOpbDiv == 0)
900                 sysInfo->pllOpbDiv = 16;
901
902         /*
903          * Determine the M factor
904          */
905         if (cpr_pllc & PLLC_SRC_MASK)
906                 m = sysInfo->pllFbkDiv * sysInfo->pllFwdDivB;
907         else
908                 m = sysInfo->pllFbkDiv * sysInfo->pllFwdDiv;
909
910         /*
911          * Determine VCO clock frequency
912          */
913         sysInfo->freqVCOHz = (1000000000000LL * (unsigned long long)m) /
914                 (unsigned long long)sysClkPeriodPs;
915
916         /*
917          * Determine CPU clock frequency
918          */
919         primad_cpudv = ((cpr_primad & PRIMAD_CPUDV_MASK) >> 24);
920         if (primad_cpudv == 0)
921                 primad_cpudv = 16;
922
923         sysInfo->freqProcessor = (CONFIG_SYS_CLK_FREQ * m) /
924                 sysInfo->pllFwdDiv / primad_cpudv;
925
926         /*
927          * Determine PLB clock frequency
928          */
929         sysInfo->freqPLB = (CONFIG_SYS_CLK_FREQ * m) /
930                 sysInfo->pllFwdDiv / sysInfo->pllPlbDiv;
931
932         sysInfo->freqOPB = (CONFIG_SYS_CLK_FREQ * sysInfo->pllFbkDiv) /
933                 sysInfo->pllOpbDiv;
934
935         sysInfo->freqEBC = (CONFIG_SYS_CLK_FREQ * sysInfo->pllFbkDiv) /
936                 sysInfo->pllExtBusDiv;
937
938         plloutb = ((CONFIG_SYS_CLK_FREQ * ((cpr_pllc & PLLC_SRC_MASK) ?
939                 sysInfo->pllFwdDivB : sysInfo->pllFwdDiv) * sysInfo->pllFbkDiv) /
940                 sysInfo->pllFwdDivB);
941         sysInfo->freqUART = plloutb;
942 }
943
944 #elif defined(CONFIG_405EX)
945
946 /*
947  * TODO: We need to get the CPR registers and calculate these values correctly!!!!
948  *   We need the specs!!!!
949  */
950 static unsigned char get_fbdv(unsigned char index)
951 {
952         unsigned char ret = 0;
953         /* This is table should be 256 bytes.
954          * Only take first 52 values.
955          */
956         unsigned char fbdv_tb[] = {
957                 0x00, 0xff, 0x7f, 0xfd,
958                 0x7a, 0xf5, 0x6a, 0xd5,
959                 0x2a, 0xd4, 0x29, 0xd3,
960                 0x26, 0xcc, 0x19, 0xb3,
961                 0x67, 0xce, 0x1d, 0xbb,
962                 0x77, 0xee, 0x5d, 0xba,
963                 0x74, 0xe9, 0x52, 0xa5,
964                 0x4b, 0x96, 0x2c, 0xd8,
965                 0x31, 0xe3, 0x46, 0x8d,
966                 0x1b, 0xb7, 0x6f, 0xde,
967                 0x3d, 0xfb, 0x76, 0xed,
968                 0x5a, 0xb5, 0x6b, 0xd6,
969                 0x2d, 0xdb, 0x36, 0xec,
970
971         };
972
973         if ((index & 0x7f) == 0)
974                 return 1;
975         while (ret < sizeof (fbdv_tb)) {
976                 if (fbdv_tb[ret] == index)
977                         break;
978                 ret++;
979         }
980         ret++;
981
982         return ret;
983 }
984
985 #define PLL_FBK_PLL_LOCAL       0
986 #define PLL_FBK_CPU             1
987 #define PLL_FBK_PERCLK          5
988
989 void get_sys_info (sys_info_t * sysInfo)
990 {
991         unsigned long sysClkPeriodPs = ONE_BILLION / (CONFIG_SYS_CLK_FREQ / 1000);
992         unsigned long m = 1;
993         unsigned int  tmp;
994         unsigned char fwdva[16] = {
995                 1, 2, 14, 9, 4, 11, 16, 13,
996                 12, 5, 6, 15, 10, 7, 8, 3,
997         };
998         unsigned char sel, cpudv0, plb2xDiv;
999
1000         mfcpr(CPR0_PLLD, tmp);
1001
1002         /*
1003          * Determine forward divider A
1004          */
1005         sysInfo->pllFwdDiv = fwdva[((tmp >> 16) & 0x0f)];       /* FWDVA */
1006
1007         /*
1008          * Determine FBK_DIV.
1009          */
1010         sysInfo->pllFbkDiv = get_fbdv(((tmp >> 24) & 0x0ff)); /* FBDV */
1011
1012         /*
1013          * Determine PLBDV0
1014          */
1015         sysInfo->pllPlbDiv = 2;
1016
1017         /*
1018          * Determine PERDV0
1019          */
1020         mfcpr(CPR0_PERD, tmp);
1021         tmp = (tmp >> 24) & 0x03;
1022         sysInfo->pllExtBusDiv = (tmp == 0) ? 4 : tmp;
1023
1024         /*
1025          * Determine OPBDV0
1026          */
1027         mfcpr(CPR0_OPBD0, tmp);
1028         tmp = (tmp >> 24) & 0x03;
1029         sysInfo->pllOpbDiv = (tmp == 0) ? 4 : tmp;
1030
1031         /* Determine PLB2XDV0 */
1032         mfcpr(CPR0_PLBD, tmp);
1033         tmp = (tmp >> 16) & 0x07;
1034         plb2xDiv = (tmp == 0) ? 8 : tmp;
1035
1036         /* Determine CPUDV0 */
1037         mfcpr(CPR0_CPUD, tmp);
1038         tmp = (tmp >> 24) & 0x07;
1039         cpudv0 = (tmp == 0) ? 8 : tmp;
1040
1041         /* Determine SEL(5:7) in CPR0_PLLC */
1042         mfcpr(CPR0_PLLC, tmp);
1043         sel = (tmp >> 24) & 0x07;
1044
1045         /*
1046          * Determine the M factor
1047          * PLL local: M = FBDV
1048          * CPU clock: M = FBDV * FWDVA * CPUDV0
1049          * PerClk       : M = FBDV * FWDVA * PLB2XDV0 * PLBDV0(2) * OPBDV0 * PERDV0
1050          *
1051          */
1052         switch (sel) {
1053         case PLL_FBK_CPU:
1054                 m = sysInfo->pllFwdDiv * cpudv0;
1055                 break;
1056         case PLL_FBK_PERCLK:
1057                 m = sysInfo->pllFwdDiv * plb2xDiv * 2
1058                         * sysInfo->pllOpbDiv * sysInfo->pllExtBusDiv;
1059                 break;
1060         case PLL_FBK_PLL_LOCAL:
1061                 break;
1062         default:
1063                 printf("%s unknown m\n", __FUNCTION__);
1064                 return;
1065
1066         }
1067         m *= sysInfo->pllFbkDiv;
1068
1069         /*
1070          * Determine VCO clock frequency
1071          */
1072         sysInfo->freqVCOHz = (1000000000000LL * (unsigned long long)m) /
1073                 (unsigned long long)sysClkPeriodPs;
1074
1075         /*
1076          * Determine CPU clock frequency
1077          */
1078         sysInfo->freqProcessor = sysInfo->freqVCOHz / (sysInfo->pllFwdDiv * cpudv0);
1079
1080         /*
1081          * Determine PLB clock frequency, ddr1x should be the same
1082          */
1083         sysInfo->freqPLB = sysInfo->freqVCOHz / (sysInfo->pllFwdDiv * plb2xDiv * 2);
1084         sysInfo->freqOPB = sysInfo->freqPLB/sysInfo->pllOpbDiv;
1085         sysInfo->freqDDR = sysInfo->freqPLB;
1086         sysInfo->freqEBC = sysInfo->freqOPB / sysInfo->pllExtBusDiv;
1087         sysInfo->freqUART = sysInfo->freqPLB;
1088 }
1089
1090 #endif
1091
1092 int get_clocks (void)
1093 {
1094         sys_info_t sys_info;
1095
1096         get_sys_info (&sys_info);
1097         gd->cpu_clk = sys_info.freqProcessor;
1098         gd->bus_clk = sys_info.freqPLB;
1099
1100         return (0);
1101 }
1102
1103
1104 /********************************************
1105  * get_bus_freq
1106  * return PLB bus freq in Hz
1107  *********************************************/
1108 ulong get_bus_freq (ulong dummy)
1109 {
1110         ulong val;
1111
1112 #if defined(CONFIG_405GP) || \
1113     defined(CONFIG_405EP) || defined(CONFIG_405EZ) || \
1114     defined(CONFIG_405EX) || defined(CONFIG_405) || \
1115     defined(CONFIG_440)
1116         sys_info_t sys_info;
1117
1118         get_sys_info (&sys_info);
1119         val = sys_info.freqPLB;
1120 #else
1121 # error get_bus_freq() not implemented
1122 #endif
1123
1124         return val;
1125 }
1126
1127 ulong get_OPB_freq (void)
1128 {
1129         PPC4xx_SYS_INFO sys_info;
1130
1131         get_sys_info (&sys_info);
1132
1133         return sys_info.freqOPB;
1134 }