[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