1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright 2007 David Gibson, IBM Corporation.
5 * Based on earlier code:
6 * Matt Porter <mporter@kernel.crashing.org>
7 * Copyright 2002-2005 MontaVista Software Inc.
9 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
10 * Copyright (c) 2003, 2004 Zultys Technologies
12 * Copyright (C) 2009 Wind River Systems, Inc.
13 * Updated for supporting PPC405EX on Kilauea.
14 * Tiejun Chen <tiejun.chen@windriver.com>
24 static unsigned long chip_11_errata(unsigned long memsize
)
30 switch (pvr
& 0xf0000ff0) {
43 /* Read the 4xx SDRAM controller to get size of system memory. */
44 void ibm4xx_sdram_fixup_memsize(void)
47 unsigned long memsize
, bank_config
;
50 for (i
= 0; i
< ARRAY_SIZE(sdram_bxcr
); i
++) {
51 bank_config
= SDRAM0_READ(sdram_bxcr
[i
]);
52 if (bank_config
& SDRAM_CONFIG_BANK_ENABLE
)
53 memsize
+= SDRAM_CONFIG_BANK_SIZE(bank_config
);
56 memsize
= chip_11_errata(memsize
);
57 dt_fixup_memory(0, memsize
);
60 /* Read the 440SPe MQ controller to get size of system memory. */
61 #define DCRN_MQ0_B0BAS 0x40
62 #define DCRN_MQ0_B1BAS 0x41
63 #define DCRN_MQ0_B2BAS 0x42
64 #define DCRN_MQ0_B3BAS 0x43
66 static u64
ibm440spe_decode_bas(u32 bas
)
68 u64 base
= ((u64
)(bas
& 0xFFE00000u
)) << 2;
70 /* open coded because I'm paranoid about invalid values */
71 switch ((bas
>> 4) & 0xFFF) {
75 return base
+ 0x000800000ull
;
77 return base
+ 0x001000000ull
;
79 return base
+ 0x002000000ull
;
81 return base
+ 0x004000000ull
;
83 return base
+ 0x008000000ull
;
85 return base
+ 0x010000000ull
;
87 return base
+ 0x020000000ull
;
89 return base
+ 0x040000000ull
;
91 return base
+ 0x080000000ull
;
93 return base
+ 0x100000000ull
;
95 printf("Memory BAS value 0x%08x unsupported !\n", bas
);
99 void ibm440spe_fixup_memsize(void)
101 u64 banktop
, memsize
= 0;
103 /* Ultimately, we should directly construct the memory node
104 * so we are able to handle holes in the memory address space
106 banktop
= ibm440spe_decode_bas(mfdcr(DCRN_MQ0_B0BAS
));
107 if (banktop
> memsize
)
109 banktop
= ibm440spe_decode_bas(mfdcr(DCRN_MQ0_B1BAS
));
110 if (banktop
> memsize
)
112 banktop
= ibm440spe_decode_bas(mfdcr(DCRN_MQ0_B2BAS
));
113 if (banktop
> memsize
)
115 banktop
= ibm440spe_decode_bas(mfdcr(DCRN_MQ0_B3BAS
));
116 if (banktop
> memsize
)
119 dt_fixup_memory(0, memsize
);
123 /* 4xx DDR1/2 Denali memory controller support */
133 #define DDR_START 0x1
134 #define DDR_START_SHIFT 0
135 #define DDR_MAX_CS_REG 0x3
136 #define DDR_MAX_CS_REG_SHIFT 24
137 #define DDR_MAX_COL_REG 0xf
138 #define DDR_MAX_COL_REG_SHIFT 16
139 #define DDR_MAX_ROW_REG 0xf
140 #define DDR_MAX_ROW_REG_SHIFT 8
142 #define DDR_DDR2_MODE 0x1
143 #define DDR_DDR2_MODE_SHIFT 0
145 #define DDR_CS_MAP 0x3
146 #define DDR_CS_MAP_SHIFT 8
148 #define DDR_REDUC 0x1
149 #define DDR_REDUC_SHIFT 16
152 #define DDR_APIN_SHIFT 24
154 #define DDR_COL_SZ 0x7
155 #define DDR_COL_SZ_SHIFT 8
156 #define DDR_BANK8 0x1
157 #define DDR_BANK8_SHIFT 0
159 #define DDR_GET_VAL(val, mask, shift) (((val) >> (shift)) & (mask))
162 * Some U-Boot versions set the number of chipselects to two
163 * for Sequoia/Rainier boards while they only have one chipselect
164 * hardwired. Hardcode the number of chipselects to one
165 * for sequioa/rainer board models or read the actual value
166 * from the memory controller register DDR0_10 otherwise.
168 static inline u32
ibm4xx_denali_get_cs(void)
174 devp
= finddevice("/");
178 if (getprop(devp
, "model", model
, sizeof(model
)) <= 0)
181 model
[sizeof(model
)-1] = 0;
183 if (!strcmp(model
, "amcc,sequoia") ||
184 !strcmp(model
, "amcc,rainier"))
189 val
= SDRAM0_READ(DDR0_10
);
191 val
= DDR_GET_VAL(val
, DDR_CS_MAP
, DDR_CS_MAP_SHIFT
);
201 void ibm4xx_denali_fixup_memsize(void)
203 u32 val
, max_cs
, max_col
, max_row
;
204 u32 cs
, col
, row
, bank
, dpath
;
205 unsigned long memsize
;
207 val
= SDRAM0_READ(DDR0_02
);
208 if (!DDR_GET_VAL(val
, DDR_START
, DDR_START_SHIFT
))
209 fatal("DDR controller is not initialized\n");
211 /* get maximum cs col and row values */
212 max_cs
= DDR_GET_VAL(val
, DDR_MAX_CS_REG
, DDR_MAX_CS_REG_SHIFT
);
213 max_col
= DDR_GET_VAL(val
, DDR_MAX_COL_REG
, DDR_MAX_COL_REG_SHIFT
);
214 max_row
= DDR_GET_VAL(val
, DDR_MAX_ROW_REG
, DDR_MAX_ROW_REG_SHIFT
);
216 cs
= ibm4xx_denali_get_cs();
218 fatal("No memory installed\n");
220 fatal("DDR wrong CS configuration\n");
222 /* get data path bytes */
223 val
= SDRAM0_READ(DDR0_14
);
225 if (DDR_GET_VAL(val
, DDR_REDUC
, DDR_REDUC_SHIFT
))
226 dpath
= 4; /* 32 bits */
228 dpath
= 8; /* 64 bits */
230 /* get address pins (rows) */
231 val
= SDRAM0_READ(DDR0_42
);
233 row
= DDR_GET_VAL(val
, DDR_APIN
, DDR_APIN_SHIFT
);
235 fatal("DDR wrong APIN configuration\n");
238 /* get collomn size and banks */
239 val
= SDRAM0_READ(DDR0_43
);
241 col
= DDR_GET_VAL(val
, DDR_COL_SZ
, DDR_COL_SZ_SHIFT
);
243 fatal("DDR wrong COL configuration\n");
246 if (DDR_GET_VAL(val
, DDR_BANK8
, DDR_BANK8_SHIFT
))
247 bank
= 8; /* 8 banks */
249 bank
= 4; /* 4 banks */
251 memsize
= cs
* (1 << (col
+row
)) * bank
* dpath
;
252 memsize
= chip_11_errata(memsize
);
253 dt_fixup_memory(0, memsize
);
256 #define SPRN_DBCR0_40X 0x3F2
257 #define SPRN_DBCR0_44X 0x134
258 #define DBCR0_RST_SYSTEM 0x30000000
260 void ibm44x_dbcr_reset(void)
268 : "=&r"(tmp
) : "i"(SPRN_DBCR0_44X
), "i"(DBCR0_RST_SYSTEM
)
273 void ibm40x_dbcr_reset(void)
281 : "=&r"(tmp
) : "i"(SPRN_DBCR0_40X
), "i"(DBCR0_RST_SYSTEM
)
285 #define EMAC_RESET 0x20000000
286 void ibm4xx_quiesce_eth(u32
*emac0
, u32
*emac1
)
288 /* Quiesce the MAL and EMAC(s) since PIBS/OpenBIOS don't
296 mtdcr(DCRN_MAL0_CFG
, MAL_RESET
);
297 while (mfdcr(DCRN_MAL0_CFG
) & MAL_RESET
)
298 ; /* loop until reset takes effect */
301 /* Read 4xx EBC bus bridge registers to get mappings of the peripheral
302 * banks into the OPB address space */
303 void ibm4xx_fixup_ebc_ranges(const char *ebc
)
307 u32 ranges
[EBC_NUM_BANKS
*4];
311 for (i
= 0; i
< EBC_NUM_BANKS
; i
++) {
312 mtdcr(DCRN_EBC0_CFGADDR
, EBC_BXCR(i
));
313 bxcr
= mfdcr(DCRN_EBC0_CFGDATA
);
315 if ((bxcr
& EBC_BXCR_BU
) != EBC_BXCR_BU_OFF
) {
318 *p
++ = bxcr
& EBC_BXCR_BAS
;
319 *p
++ = EBC_BXCR_BANK_SIZE(bxcr
);
323 devp
= finddevice(ebc
);
325 fatal("Couldn't locate EBC node %s\n\r", ebc
);
327 setprop(devp
, "ranges", ranges
, (p
- ranges
) * sizeof(u32
));
330 /* Calculate 440GP clocks */
331 void ibm440gp_fixup_clocks(unsigned int sys_clk
, unsigned int ser_clk
)
333 u32 sys0
= mfdcr(DCRN_CPC0_SYS0
);
334 u32 cr0
= mfdcr(DCRN_CPC0_CR0
);
335 u32 cpu
, plb
, opb
, ebc
, tb
, uart0
, uart1
, m
;
336 u32 opdv
= CPC0_SYS0_OPDV(sys0
);
337 u32 epdv
= CPC0_SYS0_EPDV(sys0
);
339 if (sys0
& CPC0_SYS0_BYPASS
) {
340 /* Bypass system PLL */
343 if (sys0
& CPC0_SYS0_EXTSL
)
345 m
= CPC0_SYS0_FWDVB(sys0
) * opdv
* epdv
;
348 m
= CPC0_SYS0_FBDV(sys0
) * CPC0_SYS0_FWDVA(sys0
);
349 cpu
= sys_clk
* m
/ CPC0_SYS0_FWDVA(sys0
);
350 plb
= sys_clk
* m
/ CPC0_SYS0_FWDVB(sys0
);
356 /* FIXME: Check if this is for all 440GP, or just Ebony */
357 if ((mfpvr() & 0xf0000fff) == 0x40000440)
358 /* Rev. B 440GP, use external system clock */
361 /* Rev. C 440GP, errata force us to use internal clock */
364 if (cr0
& CPC0_CR0_U0EC
)
365 /* External UART clock */
368 /* Internal UART clock */
369 uart0
= plb
/ CPC0_CR0_UDIV(cr0
);
371 if (cr0
& CPC0_CR0_U1EC
)
372 /* External UART clock */
375 /* Internal UART clock */
376 uart1
= plb
/ CPC0_CR0_UDIV(cr0
);
378 printf("PPC440GP: SysClk = %dMHz (%x)\n\r",
379 (sys_clk
+ 500000) / 1000000, sys_clk
);
381 dt_fixup_cpu_clocks(cpu
, tb
, 0);
383 dt_fixup_clock("/plb", plb
);
384 dt_fixup_clock("/plb/opb", opb
);
385 dt_fixup_clock("/plb/opb/ebc", ebc
);
386 dt_fixup_clock("/plb/opb/serial@40000200", uart0
);
387 dt_fixup_clock("/plb/opb/serial@40000300", uart1
);
390 #define SPRN_CCR1 0x378
392 static inline u32
__fix_zero(u32 v
, u32 def
)
397 static unsigned int __ibm440eplike_fixup_clocks(unsigned int sys_clk
,
398 unsigned int tmr_clk
,
399 int per_clk_from_opb
)
402 u32 pllc
= CPR0_READ(DCRN_CPR0_PLLC
);
403 u32 plld
= CPR0_READ(DCRN_CPR0_PLLD
);
406 u32 fbdv
= __fix_zero((plld
>> 24) & 0x1f, 32);
407 u32 fwdva
= __fix_zero((plld
>> 16) & 0xf, 16);
408 u32 fwdvb
= __fix_zero((plld
>> 8) & 7, 8);
409 u32 lfbdv
= __fix_zero(plld
& 0x3f, 64);
410 u32 pradv0
= __fix_zero((CPR0_READ(DCRN_CPR0_PRIMAD
) >> 24) & 7, 8);
411 u32 prbdv0
= __fix_zero((CPR0_READ(DCRN_CPR0_PRIMBD
) >> 24) & 7, 8);
412 u32 opbdv0
= __fix_zero((CPR0_READ(DCRN_CPR0_OPBD
) >> 24) & 3, 4);
413 u32 perdv0
= __fix_zero((CPR0_READ(DCRN_CPR0_PERD
) >> 24) & 3, 4);
415 /* Input clocks for primary dividers */
418 /* Resulting clocks */
419 u32 cpu
, plb
, opb
, ebc
, vco
;
422 u32 ccr1
, tb
= tmr_clk
;
424 if (pllc
& 0x40000000) {
428 switch ((pllc
>> 24) & 7) {
431 m
= ((pllc
& 0x20000000) ? fwdvb
: fwdva
) * lfbdv
;
439 m
= fwdvb
* prbdv0
* opbdv0
* perdv0
;
442 printf("WARNING ! Invalid PLL feedback source !\n");
451 /* Bypass system PLL */
453 clk_a
= clk_b
= sys_clk
;
456 cpu
= clk_a
/ pradv0
;
457 plb
= clk_b
/ prbdv0
;
459 ebc
= (per_clk_from_opb
? opb
: plb
) / perdv0
;
461 /* Figure out timebase. Either CPU or default TmrClk */
462 ccr1
= mfspr(SPRN_CCR1
);
464 /* If passed a 0 tmr_clk, force CPU clock */
467 mtspr(SPRN_CCR1
, ccr1
);
469 if ((ccr1
& 0x0080) == 0)
472 dt_fixup_cpu_clocks(cpu
, tb
, 0);
473 dt_fixup_clock("/plb", plb
);
474 dt_fixup_clock("/plb/opb", opb
);
475 dt_fixup_clock("/plb/opb/ebc", ebc
);
480 static void eplike_fixup_uart_clk(int index
, const char *path
,
481 unsigned int ser_clk
,
482 unsigned int plb_clk
)
489 sdr
= SDR0_READ(DCRN_SDR0_UART0
);
492 sdr
= SDR0_READ(DCRN_SDR0_UART1
);
495 sdr
= SDR0_READ(DCRN_SDR0_UART2
);
498 sdr
= SDR0_READ(DCRN_SDR0_UART3
);
504 if (sdr
& 0x00800000u
)
507 clock
= plb_clk
/ __fix_zero(sdr
& 0xff, 256);
509 dt_fixup_clock(path
, clock
);
512 void ibm440ep_fixup_clocks(unsigned int sys_clk
,
513 unsigned int ser_clk
,
514 unsigned int tmr_clk
)
516 unsigned int plb_clk
= __ibm440eplike_fixup_clocks(sys_clk
, tmr_clk
, 0);
518 /* serial clocks need fixup based on int/ext */
519 eplike_fixup_uart_clk(0, "/plb/opb/serial@ef600300", ser_clk
, plb_clk
);
520 eplike_fixup_uart_clk(1, "/plb/opb/serial@ef600400", ser_clk
, plb_clk
);
521 eplike_fixup_uart_clk(2, "/plb/opb/serial@ef600500", ser_clk
, plb_clk
);
522 eplike_fixup_uart_clk(3, "/plb/opb/serial@ef600600", ser_clk
, plb_clk
);
525 void ibm440gx_fixup_clocks(unsigned int sys_clk
,
526 unsigned int ser_clk
,
527 unsigned int tmr_clk
)
529 unsigned int plb_clk
= __ibm440eplike_fixup_clocks(sys_clk
, tmr_clk
, 1);
531 /* serial clocks need fixup based on int/ext */
532 eplike_fixup_uart_clk(0, "/plb/opb/serial@40000200", ser_clk
, plb_clk
);
533 eplike_fixup_uart_clk(1, "/plb/opb/serial@40000300", ser_clk
, plb_clk
);
536 void ibm440spe_fixup_clocks(unsigned int sys_clk
,
537 unsigned int ser_clk
,
538 unsigned int tmr_clk
)
540 unsigned int plb_clk
= __ibm440eplike_fixup_clocks(sys_clk
, tmr_clk
, 1);
542 /* serial clocks need fixup based on int/ext */
543 eplike_fixup_uart_clk(0, "/plb/opb/serial@f0000200", ser_clk
, plb_clk
);
544 eplike_fixup_uart_clk(1, "/plb/opb/serial@f0000300", ser_clk
, plb_clk
);
545 eplike_fixup_uart_clk(2, "/plb/opb/serial@f0000600", ser_clk
, plb_clk
);
548 void ibm405gp_fixup_clocks(unsigned int sys_clk
, unsigned int ser_clk
)
550 u32 pllmr
= mfdcr(DCRN_CPC0_PLLMR
);
551 u32 cpc0_cr0
= mfdcr(DCRN_405_CPC0_CR0
);
552 u32 cpc0_cr1
= mfdcr(DCRN_405_CPC0_CR1
);
553 u32 psr
= mfdcr(DCRN_405_CPC0_PSR
);
554 u32 cpu
, plb
, opb
, ebc
, tb
, uart0
, uart1
, m
;
555 u32 fwdv
, fwdvb
, fbdv
, cbdv
, opdv
, epdv
, ppdv
, udiv
;
557 fwdv
= (8 - ((pllmr
& 0xe0000000) >> 29));
558 fbdv
= (pllmr
& 0x1e000000) >> 25;
561 cbdv
= ((pllmr
& 0x00060000) >> 17) + 1; /* CPU:PLB */
562 opdv
= ((pllmr
& 0x00018000) >> 15) + 1; /* PLB:OPB */
563 ppdv
= ((pllmr
& 0x00006000) >> 13) + 1; /* PLB:PCI */
564 epdv
= ((pllmr
& 0x00001800) >> 11) + 2; /* PLB:EBC */
565 udiv
= ((cpc0_cr0
& 0x3e) >> 1) + 1;
567 /* check for 405GPr */
568 if ((mfpvr() & 0xfffffff0) == (0x50910951 & 0xfffffff0)) {
569 fwdvb
= 8 - (pllmr
& 0x00000007);
570 if (!(psr
& 0x00001000)) /* PCI async mode enable == 0 */
571 if (psr
& 0x00000020) /* New mode enable */
572 m
= fwdvb
* 2 * ppdv
;
574 m
= fwdvb
* cbdv
* ppdv
;
575 else if (psr
& 0x00000020) /* New mode enable */
576 if (psr
& 0x00000800) /* PerClk synch mode */
577 m
= fwdvb
* 2 * epdv
;
580 else if (epdv
== fbdv
)
581 m
= fbdv
* cbdv
* epdv
;
583 m
= fbdv
* fwdvb
* cbdv
;
585 cpu
= sys_clk
* m
/ fwdv
;
586 plb
= sys_clk
* m
/ (fwdvb
* cbdv
);
588 m
= fwdv
* fbdv
* cbdv
;
589 cpu
= sys_clk
* m
/ fwdv
;
596 /* uart0 uses the external clock */
602 /* uart1 uses the external clock */
607 /* setup the timebase clock to tick at the cpu frequency */
608 cpc0_cr1
= cpc0_cr1
& ~0x00800000;
609 mtdcr(DCRN_405_CPC0_CR1
, cpc0_cr1
);
612 dt_fixup_cpu_clocks(cpu
, tb
, 0);
613 dt_fixup_clock("/plb", plb
);
614 dt_fixup_clock("/plb/opb", opb
);
615 dt_fixup_clock("/plb/ebc", ebc
);
616 dt_fixup_clock("/plb/opb/serial@ef600300", uart0
);
617 dt_fixup_clock("/plb/opb/serial@ef600400", uart1
);
621 void ibm405ep_fixup_clocks(unsigned int sys_clk
)
623 u32 pllmr0
= mfdcr(DCRN_CPC0_PLLMR0
);
624 u32 pllmr1
= mfdcr(DCRN_CPC0_PLLMR1
);
625 u32 cpc0_ucr
= mfdcr(DCRN_CPC0_UCR
);
626 u32 cpu
, plb
, opb
, ebc
, uart0
, uart1
;
627 u32 fwdva
, fwdvb
, fbdv
, cbdv
, opdv
, epdv
;
628 u32 pllmr0_ccdv
, tb
, m
;
630 fwdva
= 8 - ((pllmr1
& 0x00070000) >> 16);
631 fwdvb
= 8 - ((pllmr1
& 0x00007000) >> 12);
632 fbdv
= (pllmr1
& 0x00f00000) >> 20;
636 cbdv
= ((pllmr0
& 0x00030000) >> 16) + 1; /* CPU:PLB */
637 epdv
= ((pllmr0
& 0x00000300) >> 8) + 2; /* PLB:EBC */
638 opdv
= ((pllmr0
& 0x00003000) >> 12) + 1; /* PLB:OPB */
642 pllmr0_ccdv
= ((pllmr0
& 0x00300000) >> 20) + 1;
643 if (pllmr1
& 0x80000000)
644 cpu
= sys_clk
* m
/ (fwdva
* pllmr0_ccdv
);
646 cpu
= sys_clk
/ pllmr0_ccdv
;
652 uart0
= cpu
/ (cpc0_ucr
& 0x0000007f);
653 uart1
= cpu
/ ((cpc0_ucr
& 0x00007f00) >> 8);
655 dt_fixup_cpu_clocks(cpu
, tb
, 0);
656 dt_fixup_clock("/plb", plb
);
657 dt_fixup_clock("/plb/opb", opb
);
658 dt_fixup_clock("/plb/ebc", ebc
);
659 dt_fixup_clock("/plb/opb/serial@ef600300", uart0
);
660 dt_fixup_clock("/plb/opb/serial@ef600400", uart1
);
663 static u8 ibm405ex_fwdv_multi_bits
[] = {
664 /* values for: 1 - 16 */
665 0x01, 0x02, 0x0e, 0x09, 0x04, 0x0b, 0x10, 0x0d, 0x0c, 0x05,
666 0x06, 0x0f, 0x0a, 0x07, 0x08, 0x03
669 u32
ibm405ex_get_fwdva(unsigned long cpr_fwdv
)
673 for (index
= 0; index
< ARRAY_SIZE(ibm405ex_fwdv_multi_bits
); index
++)
674 if (cpr_fwdv
== (u32
)ibm405ex_fwdv_multi_bits
[index
])
680 static u8 ibm405ex_fbdv_multi_bits
[] = {
681 /* values for: 1 - 100 */
682 0x00, 0xff, 0x7e, 0xfd, 0x7a, 0xf5, 0x6a, 0xd5, 0x2a, 0xd4,
683 0x29, 0xd3, 0x26, 0xcc, 0x19, 0xb3, 0x67, 0xce, 0x1d, 0xbb,
684 0x77, 0xee, 0x5d, 0xba, 0x74, 0xe9, 0x52, 0xa5, 0x4b, 0x96,
685 0x2c, 0xd8, 0x31, 0xe3, 0x46, 0x8d, 0x1b, 0xb7, 0x6f, 0xde,
686 0x3d, 0xfb, 0x76, 0xed, 0x5a, 0xb5, 0x6b, 0xd6, 0x2d, 0xdb,
687 0x36, 0xec, 0x59, 0xb2, 0x64, 0xc9, 0x12, 0xa4, 0x48, 0x91,
688 0x23, 0xc7, 0x0e, 0x9c, 0x38, 0xf0, 0x61, 0xc2, 0x05, 0x8b,
689 0x17, 0xaf, 0x5f, 0xbe, 0x7c, 0xf9, 0x72, 0xe5, 0x4a, 0x95,
690 0x2b, 0xd7, 0x2e, 0xdc, 0x39, 0xf3, 0x66, 0xcd, 0x1a, 0xb4,
691 0x68, 0xd1, 0x22, 0xc4, 0x09, 0x93, 0x27, 0xcf, 0x1e, 0xbc,
692 /* values for: 101 - 200 */
693 0x78, 0xf1, 0x62, 0xc5, 0x0a, 0x94, 0x28, 0xd0, 0x21, 0xc3,
694 0x06, 0x8c, 0x18, 0xb0, 0x60, 0xc1, 0x02, 0x84, 0x08, 0x90,
695 0x20, 0xc0, 0x01, 0x83, 0x07, 0x8f, 0x1f, 0xbf, 0x7f, 0xfe,
696 0x7d, 0xfa, 0x75, 0xea, 0x55, 0xaa, 0x54, 0xa9, 0x53, 0xa6,
697 0x4c, 0x99, 0x33, 0xe7, 0x4e, 0x9d, 0x3b, 0xf7, 0x6e, 0xdd,
698 0x3a, 0xf4, 0x69, 0xd2, 0x25, 0xcb, 0x16, 0xac, 0x58, 0xb1,
699 0x63, 0xc6, 0x0d, 0x9b, 0x37, 0xef, 0x5e, 0xbd, 0x7b, 0xf6,
700 0x6d, 0xda, 0x35, 0xeb, 0x56, 0xad, 0x5b, 0xb6, 0x6c, 0xd9,
701 0x32, 0xe4, 0x49, 0x92, 0x24, 0xc8, 0x11, 0xa3, 0x47, 0x8e,
702 0x1c, 0xb8, 0x70, 0xe1, 0x42, 0x85, 0x0b, 0x97, 0x2f, 0xdf,
703 /* values for: 201 - 255 */
704 0x3e, 0xfc, 0x79, 0xf2, 0x65, 0xca, 0x15, 0xab, 0x57, 0xae,
705 0x5c, 0xb9, 0x73, 0xe6, 0x4d, 0x9a, 0x34, 0xe8, 0x51, 0xa2,
706 0x44, 0x89, 0x13, 0xa7, 0x4f, 0x9e, 0x3c, 0xf8, 0x71, 0xe2,
707 0x45, 0x8a, 0x14, 0xa8, 0x50, 0xa1, 0x43, 0x86, 0x0c, 0x98,
708 0x30, 0xe0, 0x41, 0x82, 0x04, 0x88, 0x10, 0xa0, 0x40, 0x81,
709 0x03, 0x87, 0x0f, 0x9f, 0x3f /* END */
712 u32
ibm405ex_get_fbdv(unsigned long cpr_fbdv
)
716 for (index
= 0; index
< ARRAY_SIZE(ibm405ex_fbdv_multi_bits
); index
++)
717 if (cpr_fbdv
== (u32
)ibm405ex_fbdv_multi_bits
[index
])
723 void ibm405ex_fixup_clocks(unsigned int sys_clk
, unsigned int uart_clk
)
726 u32 pllc
= CPR0_READ(DCRN_CPR0_PLLC
);
727 u32 plld
= CPR0_READ(DCRN_CPR0_PLLD
);
728 u32 cpud
= CPR0_READ(DCRN_CPR0_PRIMAD
);
729 u32 plbd
= CPR0_READ(DCRN_CPR0_PRIMBD
);
730 u32 opbd
= CPR0_READ(DCRN_CPR0_OPBD
);
731 u32 perd
= CPR0_READ(DCRN_CPR0_PERD
);
734 u32 fbdv
= ibm405ex_get_fbdv(__fix_zero((plld
>> 24) & 0xff, 1));
736 u32 fwdva
= ibm405ex_get_fwdva(__fix_zero((plld
>> 16) & 0x0f, 1));
738 u32 cpudv0
= __fix_zero((cpud
>> 24) & 7, 8);
740 /* PLBDV0 is hardwared to 010. */
742 u32 plb2xdv0
= __fix_zero((plbd
>> 16) & 7, 8);
744 u32 opbdv0
= __fix_zero((opbd
>> 24) & 3, 4);
746 u32 perdv0
= __fix_zero((perd
>> 24) & 3, 4);
748 /* Resulting clocks */
749 u32 cpu
, plb
, opb
, ebc
, vco
, tb
, uart0
, uart1
;
751 /* PLL's VCO is the source for primary forward ? */
752 if (pllc
& 0x40000000) {
756 switch ((pllc
>> 24) & 7) {
763 m
= fbdv
* fwdva
* cpudv0
;
767 m
= fbdv
* fwdva
* plb2xdv0
* plbdv0
* opbdv0
* perdv0
;
770 printf("WARNING ! Invalid PLL feedback source !\n");
774 vco
= (unsigned int)(sys_clk
* m
);
777 /* Bypass system PLL */
781 /* CPU = VCO / ( FWDVA x CPUDV0) */
782 cpu
= vco
/ (fwdva
* cpudv0
);
783 /* PLB = VCO / ( FWDVA x PLB2XDV0 x PLBDV0) */
784 plb
= vco
/ (fwdva
* plb2xdv0
* plbdv0
);
785 /* OPB = PLB / OPBDV0 */
787 /* EBC = OPB / PERDV0 */
791 uart0
= uart1
= uart_clk
;
793 dt_fixup_cpu_clocks(cpu
, tb
, 0);
794 dt_fixup_clock("/plb", plb
);
795 dt_fixup_clock("/plb/opb", opb
);
796 dt_fixup_clock("/plb/opb/ebc", ebc
);
797 dt_fixup_clock("/plb/opb/serial@ef600200", uart0
);
798 dt_fixup_clock("/plb/opb/serial@ef600300", uart1
);