[U-Boot-Users] [PATCH] PPC440EPx: Reconfigure PLL for 667MHz processor
Mike Nuss
mike at terascala.com
Tue Feb 5 18:08:19 CET 2008
On PPC440EPx without a bootstrap I2C EEPROM, the PLL can be reconfigured after
startup in order to change the speed of the clocks. This patch adds the option
CONFIG_667MHZ. If set, it will set the clocks to run at full speed on a 667MHz
PPC440EPx without the need for an external EEPROM.
Signed-off-by: Mike Nuss <mike at terascala.com>
Cc: Stefan Roese <sr at denx.de>
diff --git a/cpu/ppc4xx/cpu_init.c b/cpu/ppc4xx/cpu_init.c
index 2e0dd6f..14682c6 100644
--- a/cpu/ppc4xx/cpu_init.c
+++ b/cpu/ppc4xx/cpu_init.c
@@ -99,10 +99,21 @@ DECLARE_GLOBAL_DATA_PTR;
# endif
#endif /* CFG_INIT_DCACHE_CS */
+#if defined(CONFIG_440EPX) && defined(CONFIG_667MHZ)
+#define PRBDV0 2
+#define FWDVA 2
+#define FWDVB 4
+#define FBDV 20
+#define LFBDV 1
+#define PERDV0 4
+#define SPCID0 4
+#endif
+
/*
* Breath some life into the CPU...
*
- * Set up the memory map,
+ * Reconfigure PLL if necessary,
+ * set up the memory map,
* initialize a bunch of registers
*/
void
@@ -111,6 +122,78 @@ cpu_init_f (void)
#if defined(CONFIG_WATCHDOG)
unsigned long val;
#endif
+#if defined(CONFIG_440EPX) && defined(CONFIG_667MHZ)
+ int reset_needed = 0;
+ unsigned long reg, temp;
+ unsigned long prbdv0, fwdva, fwdvb, fbdv, lfbdv, perdv0, spcid0;
+
+ /* Configure clocks and reset if necessary */
+
+ mfcpr(clk_primbd, reg);
+ temp = (reg & PRBDV_MASK) >> 24;
+ prbdv0 = temp ? temp : 8;
+ if (prbdv0 != PRBDV0) {
+ reg &= ~PRBDV_MASK;
+ reg |= ((PRBDV0 == 8 ? 0 : PRBDV0) << 24);
+ mtcpr(clk_primbd, reg);
+ reset_needed = 1;
+ }
+
+ mfcpr(clk_plld, reg);
+
+ temp = (reg & PLLD_FWDVA_MASK) >> 16;
+ fwdva = temp ? temp : 16;
+
+ temp = (reg & PLLD_FWDVB_MASK) >> 8;
+ fwdvb = temp ? temp : 8;
+
+ temp = (reg & PLLD_FBDV_MASK) >> 24;
+ fbdv = temp ? temp : 32;
+
+ temp = (reg & PLLD_LFBDV_MASK);
+ lfbdv = temp ? temp : 64;
+
+ if (fwdva != FWDVA || fbdv != FBDV || lfbdv != LFBDV) {
+ reg &= ~(PLLD_FWDVA_MASK | PLLD_FWDVB_MASK |
+ PLLD_FBDV_MASK | PLLD_LFBDV_MASK);
+ reg |= ((FWDVA == 16 ? 0 : FWDVA) << 16) |
+ ((FWDVB == 8 ? 0 : FWDVB) << 8) |
+ ((FBDV == 32 ? 0 : FBDV) << 24) |
+ (LFBDV == 64 ? 0 : LFBDV);
+ mtcpr(clk_plld, reg);
+ reset_needed = 1;
+ }
+
+ mfcpr(clk_perd, reg);
+ perdv0 = (reg & CPR0_PERD_PERDV0_MASK) >> 24;
+ if (perdv0 != PERDV0) {
+ reg &= ~CPR0_PERD_PERDV0_MASK;
+ reg |= (PERDV0 << 24);
+ mtcpr(clk_perd, reg);
+ reset_needed = 1;
+ }
+
+ mfcpr(clk_spcid, reg);
+ temp = (reg & CPR0_SPCID_SPCIDV0_MASK) >> 24;
+ spcid0 = temp ? temp : 4;
+ if (spcid0 != SPCID0) {
+ reg &= ~CPR0_SPCID_SPCIDV0_MASK;
+ reg |= ((SPCID0 == 4 ? 0 : SPCID0) << 24);
+ mtcpr(clk_spcid, reg);
+ reset_needed = 1;
+ }
+
+ mfcpr(clk_icfg, reg);
+ reg &= ~CPR0_ICFG_RLI_MASK;
+ reg |= 1 << 31;
+ mtcpr(clk_icfg, reg);
+
+ if (reset_needed) {
+ __asm__ __volatile__ ("sync; isync");
+ mtspr(dbcr0, 0x20000000); /* Reset processor */
+ }
+#endif /* CONFIG_440EPX && CONFIG_667MHZ */
+
#if (defined(CONFIG_405EP) || defined (CONFIG_405EX)) && !defined(CFG_4xx_GPIO_TABLE)
/*
More information about the U-Boot
mailing list