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