Skip to contentSkip to conversation

PPC440EPx: Reconfigure PLL for 667MHz processor

PATCH Superseded Mike Nuss 3 participants 3 messages Feb 20, 2008 – Mar 27, 2008

lore
Share & tools
lore

Mike Nuss

author
#0 lore raw

PATCH v2 1/1 PPC440EPx: Reconfigure PLL for 667MHz processor

On PPC440EPx without a bootstrap I2C EEPROM, the PLL can be reconfigured after startup to change the speed of the clocks. This patch adds the option CFG_PLL_RECONFIG. If this option is set to 667, the CPU initialization code will reconfigure the PLL to run the system with a CPU frequency of 667MHz and PLB frequency of 166MHz, without the need for an external EEPROM.

Cc Stefan Roese <[email protected]>

--
Sorry for the duplicate - updated the patch description.

Addresses changes suggested by Stefan; move PLL reconfiguration into a separate function.

cpu/ppc4xx/cpu_init.c +99 -1
index 2e0dd6f..fd663af 100644
@@ -99,10 +99,107 @@ DECLARE_GLOBAL_DATA_PTR;
 # endif
 #endif /* CFG_INIT_DCACHE_CS */
 
+#ifndef CFG_PLL_RECONFIG
+#define CFG_PLL_RECONFIG	0
+#endif
+
+void reconfigure_pll(u32 new_cpu_freq)
+{
+#if defined(CONFIG_440EPX)
+	int	reset_needed = 0;
+	u32	reg, temp;
+	u32	prbdv0, target_prbdv0,				/* CLK_PRIMBD */
+		fwdva, target_fwdva, fwdvb, target_fwdvb,	/* CLK_PLLD */
+		fbdv, target_fbdv, lfbdv, target_lfbdv,
+		perdv0,	target_perdv0,				/* CLK_PERD */
+		spcid0,	target_spcid0;				/* CLK_SPCID */
+
+	/* Reconfigure clocks if necessary.
+	 * See PPC440EPx User's Manual, sections 8.2 and 14 */
+	if (new_cpu_freq == 667) {
+		target_prbdv0 = 2;
+		target_fwdva = 2;
+		target_fwdvb = 4;
+		target_fbdv = 20;
+		target_lfbdv = 1;
+		target_perdv0 = 4;
+		target_spcid0 = 4;
+
+		mfcpr(clk_primbd, reg);
+		temp = (reg & PRBDV_MASK) >> 24;
+		prbdv0 = temp ? temp : 8;
+		if (prbdv0 != target_prbdv0) {
+			reg &= ~PRBDV_MASK;
+			reg |= ((target_prbdv0 == 8 ? 0 : target_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 != target_fwdva || fbdv != target_fbdv || lfbdv != target_lfbdv) {
+			reg &= ~(PLLD_FWDVA_MASK | PLLD_FWDVB_MASK |
+				 PLLD_FBDV_MASK | PLLD_LFBDV_MASK);
+			reg |= ((target_fwdva == 16 ? 0 : target_fwdva) << 16) |
+				((target_fwdvb == 8 ? 0 : target_fwdvb) << 8) |
+				((target_fbdv == 32 ? 0 : target_fbdv) << 24) |
+				(target_lfbdv == 64 ? 0 : target_lfbdv);
+			mtcpr(clk_plld, reg);
+			reset_needed = 1;
+		}
+
+		mfcpr(clk_perd, reg);
+		perdv0 = (reg & CPR0_PERD_PERDV0_MASK) >> 24;
+		if (perdv0 != target_perdv0) {
+			reg &= ~CPR0_PERD_PERDV0_MASK;
+			reg |= (target_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 != target_spcid0) {
+			reg &= ~CPR0_SPCID_SPCIDV0_MASK;
+			reg |= ((target_spcid0 == 4 ? 0 : target_spcid0) << 24);
+			mtcpr(clk_spcid, reg);
+			reset_needed = 1;
+		}
+
+		/* Set reload inhibit so configuration will persist across
+		 * processor resets */
+		mfcpr(clk_icfg, reg);
+		reg &= ~CPR0_ICFG_RLI_MASK;
+		reg |= 1 << 31;
+		mtcpr(clk_icfg, reg);
+	}
+
+	/* Reset processor if configuration changed */
+	if (reset_needed) {
+		__asm__ __volatile__ ("sync; isync");
+		mtspr(dbcr0, 0x20000000);
+	}
+#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 +208,7 @@ cpu_init_f (void)
 #if defined(CONFIG_WATCHDOG)
 	unsigned long val;
 #endif
+	reconfigure_pll(CFG_PLL_RECONFIG);
 
 #if (defined(CONFIG_405EP) || defined (CONFIG_405EX)) && !defined(CFG_4xx_GPIO_TABLE)
 	/*
#1 lore raw

PATCH v2 1/1 PPC440EPx: Reconfigure PLL for 667MHz processor

Hi Mike,

don't you think this is a little bit to shortsighted?
There are many other parameters beyond the CPU clock that could be modified in such a way. We have some code in the PMC440 board code that sets up the PCI sync clock dynamically dependant on
a GPIO (M66EN pci pin). So I would vote for a more generic configuration than by a CPU frequency parameter. Just think about this: should 667 MHz on an EPx always mean 166 MHz PLB clock? 667MHZ with 133MHz PLB might also be a typical configuration (e.g. when you need 66MHz EBC clock ....).

So what about a function that takes the complete strapping values as parameters (I think 4 longs) instead of nothing but the CPU frequency.

Matthias

Quoted 9 lines · On Wednesday 20 February 2008 17:54:20 Mike Nuss wrote:

On PPC440EPx without a bootstrap I2C EEPROM, the PLL can be reconfigured after startup to change the speed of the clocks. This patch adds the option CFG_PLL_RECONFIG. If this option is set to 667, the CPU initialization code will reconfigure the PLL to run the system with a CPU frequency of 667MHz and PLB frequency of 166MHz, without the need for an external EEPROM.

Cc Stefan Roese <[email protected]>
#2 lore raw

PATCH v2 1/1 PPC440EPx: Reconfigure PLL for 667MHz processor

In reply to Mike Nuss
Quoted 9 lines · Mike Nuss

On PPC440EPx without a bootstrap I2C EEPROM, the PLL can be reconfigured after startup to change the speed of the clocks. This patch adds the option CFG_PLL_RECONFIG. If this option is set to 667, the CPU initialization code will reconfigure the PLL to run the system with a CPU frequency of 667MHz and PLB frequency of 166MHz, without the need for an external EEPROM.

Cc Stefan Roese <[email protected]>

Applied to u-boot-ppc4xx locally. Thanks.

Best regards,
Stefan

=====================================================================
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office at denx.de
=====================================================================