[U-Boot] [PATCH] ppc4xx: /PLLOUTB/CPU clock/ Default bootstrap options A, B, C, D

Rupjyoti Sarmah rsarmah at amcc.com
Fri Jul 24 07:54:01 CEST 2009


Unstable 440EPx operation due to default bootsrtap options settings.
The 440EPx fixed bootstrap options A,B,C,D sets PLL FWDVA to a value 1
that results PLLOUTB being greater
than the CPU clock frequency. This results unstable 440EPx operation
causing hang conditions.

This is a patch fixing this problem. The patch touches two files
speed.c and cpu_init.c.

Signed off by  Rupjyoti Sarmah < rsarmah at amcc.com > from Applied Micro
----------------------------------

diff --git a/a/u-boot-2009.06/cpu/ppc4xx/cpu_init.c
b/b/u-boot-2009.06/cpu/ppc4xx/cpu_init.c
old mode 100644
new mode 100755
index 577d33f..eb50c3c
--- a/a/u-boot-2009.06/cpu/ppc4xx/cpu_init.c
+++ b/b/u-boot-2009.06/cpu/ppc4xx/cpu_init.c
@@ -1,4 +1,4 @@
-/*
+ /*
  * (C) Copyright 2000-2007
  * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
  *
@@ -32,10 +32,19 @@
 DECLARE_GLOBAL_DATA_PTR;
 #endif
 
-#ifndef CONFIG_SYS_PLL_RECONFIG
-#define CONFIG_SYS_PLL_RECONFIG	0
+#ifndef CFG_PLL_RECONFIG
+#define CFG_PLL_RECONFIG	0
 #endif
 
+
+#define BOOT_STRAP_OPTION_A  0x00000000
+#define BOOT_STRAP_OPTION_B  0x00000001
+#define BOOT_STRAP_OPTION_D  0x00000003
+#define BOOT_STRAP_OPTION_E  0x00000004
+
+
+
+
 void reconfigure_pll(u32 new_cpu_freq)
 {
 #if defined(CONFIG_440EPX)
@@ -47,6 +56,7 @@ void reconfigure_pll(u32 new_cpu_freq)
 		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) {
@@ -111,17 +121,105 @@ void reconfigure_pll(u32 new_cpu_freq)
 			mtcpr(clk_spcid, reg);
 			reset_needed = 1;
 		}
+	}
+
+/*
+440EPx fixed bootstrap options A, B, D, and E currently set PLL FWDVA
to a
+divisor value = 1.  This results in the PLLOUTB being greater than the
CPU
+clock frequency which causes unstable 440EPx operation resulting in
various
+software hang conditions.  The user manual and the data sheet both
specify that
+a FWDVB = 1 is not a valid setting.
+
+If the customer uses the IIC attached EEPROM to set bootstrap options,
this is
+not a problem. Some customers choose to use one of the fixed bootstrap
options
+(A, B, D, or E)and do not have an EEPROM to use for programmable
bootstrap
+options. This requires that FWDVA and PRBDV0 be re-programmed early in
the chip
+initialization process by software.  The procedure for re-programming
the PLL
+is defined in the 440EPx user manual section 8.3, Bootstrap Options.
+*/
+
+
+
+
+
+
+
 
-		/* Set reload inhibit so configuration will persist
across
-		 * processor resets */
+	                                            /* Get current value
of FWDVA.*/
+
+	mfcpr(clk_plld, reg);
+    temp = (reg & PLLD_FWDVA_MASK) >> 16;
+                                                /* Check to see if
FWDVA has   */
+                                                /* been set to a value
of 1. if*/
+                                                /* it has we must
modify it.   */
+
+    if (temp == 1) {
+
+		mfcpr(clk_plld, reg);
+
+                                                /* Get current value of
fbdv.  */
+		temp = (reg & PLLD_FBDV_MASK) >> 24;
+		fbdv = temp ? temp : 32;
+                                                /* Get current value of
lfbdv. */
+		temp = (reg & PLLD_LFBDV_MASK);
+		lfbdv = temp ? temp : 64;
+
+	                                            /* Load register
that contains */
+	                                            /* current boot
strapping      */
+	                                            /* option.
*/
 		mfcpr(clk_icfg, reg);
-		reg &= ~CPR0_ICFG_RLI_MASK;
-		reg |= 1 << 31;
-		mtcpr(clk_icfg, reg);
-	}
+		                                        /* Shift
strapping option into */
+		                                        /* low 3 bits.
*/
+		reg = (reg >> 28);
+
+		switch(reg) {
+			case BOOT_STRAP_OPTION_A:
+			case BOOT_STRAP_OPTION_B:
+			case BOOT_STRAP_OPTION_D:
+			case BOOT_STRAP_OPTION_E:
+		                                         /* Get current
value of FWDVA.*/
+		                                         /* Assign
current FWDVA to    */
+		                                         /* new FWDVB.
*/
+				  mfcpr(clk_plld, reg);
+			      target_fwdvb = (reg & PLLD_FWDVA_MASK) >>
16;
+			      fwdvb = target_fwdvb ? target_fwdvb : 8;
+		                                         /* Get current
value of FWDVB.*/
+		                                         /* Assign
current FWDVB to    */
+		                                         /* new FWDVA.
*/
+		          target_fwdva = (reg & PLLD_FWDVB_MASK) >> 8;
+		          fwdva = target_fwdva ? target_fwdva : 16;
+		                                         /* Update
clk_plld with       */
+		                                         /* switched
FWDVA and FWDVB.  */
+			      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);
+		                                         /* Acknowledge
that a reset   */
+		                                         /* is required.
*/
+
+				  reset_needed = 1;
+				break;
+
+			default:
+				                                /* All
other case are OK.      */
+				                                /*
Nothing to do.              */
+			break;
+		}
 
-	/* Reset processor if configuration changed */
-	if (reset_needed) {
+    }
+
+    if (reset_needed) {
+	                                            /* Set reload
inhibit so       */
+	                                            /* configuration
will persist  */
+	                                            /* across processor
reset.     */
+	    mfcpr(clk_icfg, reg);
+	    reg &= ~CPR0_ICFG_RLI_MASK;
+	    reg |= 1 << 31;
+	    mtcpr(clk_icfg, reg);
+		                                        /* Reset
processor if          */
+		                                        /* configuration
changed.      */
 		__asm__ __volatile__ ("sync; isync");
 		mtspr(dbcr0, 0x20000000);
 	}
@@ -142,32 +240,34 @@ cpu_init_f (void)
 	u32 val;
 #endif
 
-	reconfigure_pll(CONFIG_SYS_PLL_RECONFIG);
+	reconfigure_pll(CFG_PLL_RECONFIG);
 
-#if (defined(CONFIG_405EP) || defined (CONFIG_405EX)) &&
!defined(CONFIG_SYS_4xx_GPIO_TABLE)
+#ifndef CONFIG_KAVORKA
+#if (defined(CONFIG_405EP) || defined (CONFIG_405EX)) &&
!defined(CFG_4xx_GPIO_TABLE)
 	/*
 	 * GPIO0 setup (select GPIO or alternate function)
 	 */
-#if defined(CONFIG_SYS_GPIO0_OR)
-	out32(GPIO0_OR, CONFIG_SYS_GPIO0_OR);		/* set initial
state of output pins	*/
+#if defined(CFG_GPIO0_OR)
+	out32(GPIO0_OR, CFG_GPIO0_OR);		/* set initial state of
output pins	*/
 #endif
-#if defined(CONFIG_SYS_GPIO0_ODR)
-	out32(GPIO0_ODR, CONFIG_SYS_GPIO0_ODR);	/* open-drain select
*/
+#if defined(CFG_GPIO0_ODR)
+	out32(GPIO0_ODR, CFG_GPIO0_ODR);	/* open-drain select
*/
 #endif
-	out32(GPIO0_OSRH, CONFIG_SYS_GPIO0_OSRH);	/* output select
*/
-	out32(GPIO0_OSRL, CONFIG_SYS_GPIO0_OSRL);
-	out32(GPIO0_ISR1H, CONFIG_SYS_GPIO0_ISR1H);	/* input select
*/
-	out32(GPIO0_ISR1L, CONFIG_SYS_GPIO0_ISR1L);
-	out32(GPIO0_TSRH, CONFIG_SYS_GPIO0_TSRH);	/* three-state
select			*/
-	out32(GPIO0_TSRL, CONFIG_SYS_GPIO0_TSRL);
-#if defined(CONFIG_SYS_GPIO0_ISR2H)
-	out32(GPIO0_ISR2H, CONFIG_SYS_GPIO0_ISR2H);
-	out32(GPIO0_ISR2L, CONFIG_SYS_GPIO0_ISR2L);
+	out32(GPIO0_OSRH, CFG_GPIO0_OSRH);	/* output select
*/
+	out32(GPIO0_OSRL, CFG_GPIO0_OSRL);
+	out32(GPIO0_ISR1H, CFG_GPIO0_ISR1H);	/* input select
*/
+	out32(GPIO0_ISR1L, CFG_GPIO0_ISR1L);
+	out32(GPIO0_TSRH, CFG_GPIO0_TSRH);	/* three-state select
*/
+	out32(GPIO0_TSRL, CFG_GPIO0_TSRL);
+#if defined(CFG_GPIO0_ISR2H)
+	out32(GPIO0_ISR2H, CFG_GPIO0_ISR2H);
+	out32(GPIO0_ISR2L, CFG_GPIO0_ISR2L);
 #endif
-#if defined (CONFIG_SYS_GPIO0_TCR)
-	out32(GPIO0_TCR, CONFIG_SYS_GPIO0_TCR);	/* enable output driver
for outputs	*/
+#if defined (CFG_GPIO0_TCR)
+	out32(GPIO0_TCR, CFG_GPIO0_TCR);	/* enable output driver
for outputs	*/
 #endif
-#endif /* CONFIG_405EP ... && !CONFIG_SYS_4xx_GPIO_TABLE */
+#endif /* CONFIG_405EP ... && !CFG_4xx_GPIO_TABLE */
+#endif /* ifndef CONFIG_KAVORKA */
 
 #if defined (CONFIG_405EP)
 	/*
@@ -181,14 +281,14 @@ cpu_init_f (void)
 	mtdcr(cpc0_pci, mfdcr(cpc0_pci) | CPC0_PCI_HOST_CFG_EN |
CPC0_PCI_ARBIT_EN);
 #endif /* CONFIG_405EP */
 
-#if defined(CONFIG_SYS_4xx_GPIO_TABLE)
+#if defined(CFG_4xx_GPIO_TABLE)
 	gpio_set_chip_configuration();
-#endif /* CONFIG_SYS_4xx_GPIO_TABLE */
+#endif /* CFG_4xx_GPIO_TABLE */
 
 	/*
 	 * External Bus Controller (EBC) Setup
 	 */
-#if (defined(CONFIG_SYS_EBC_PB0AP) && defined(CONFIG_SYS_EBC_PB0CR))
+#if (defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR))
 #if (defined(CONFIG_405GP) || defined(CONFIG_405CR) || \
      defined(CONFIG_405EP) || defined(CONFIG_405EZ) || \
      defined(CONFIG_405EX) || defined(CONFIG_405))
@@ -209,47 +309,47 @@ cpu_init_f (void)
 	asm volatile("2:	bdnz	2b"		::: "ctr",
"cr0");
 #endif
 
-	mtebc(pb0ap, CONFIG_SYS_EBC_PB0AP);
-	mtebc(pb0cr, CONFIG_SYS_EBC_PB0CR);
+	mtebc(pb0ap, CFG_EBC_PB0AP);
+	mtebc(pb0cr, CFG_EBC_PB0CR);
 #endif
 
-#if (defined(CONFIG_SYS_EBC_PB1AP) && defined(CONFIG_SYS_EBC_PB1CR) &&
!(CONFIG_SYS_INIT_DCACHE_CS == 1))
-	mtebc(pb1ap, CONFIG_SYS_EBC_PB1AP);
-	mtebc(pb1cr, CONFIG_SYS_EBC_PB1CR);
+#if (defined(CFG_EBC_PB1AP) && defined(CFG_EBC_PB1CR) &&
!(CFG_INIT_DCACHE_CS == 1))
+	mtebc(pb1ap, CFG_EBC_PB1AP);
+	mtebc(pb1cr, CFG_EBC_PB1CR);
 #endif
 
-#if (defined(CONFIG_SYS_EBC_PB2AP) && defined(CONFIG_SYS_EBC_PB2CR) &&
!(CONFIG_SYS_INIT_DCACHE_CS == 2))
-	mtebc(pb2ap, CONFIG_SYS_EBC_PB2AP);
-	mtebc(pb2cr, CONFIG_SYS_EBC_PB2CR);
+#if (defined(CFG_EBC_PB2AP) && defined(CFG_EBC_PB2CR) &&
!(CFG_INIT_DCACHE_CS == 2))
+	mtebc(pb2ap, CFG_EBC_PB2AP);
+	mtebc(pb2cr, CFG_EBC_PB2CR);
 #endif
 
-#if (defined(CONFIG_SYS_EBC_PB3AP) && defined(CONFIG_SYS_EBC_PB3CR) &&
!(CONFIG_SYS_INIT_DCACHE_CS == 3))
-	mtebc(pb3ap, CONFIG_SYS_EBC_PB3AP);
-	mtebc(pb3cr, CONFIG_SYS_EBC_PB3CR);
+#if (defined(CFG_EBC_PB3AP) && defined(CFG_EBC_PB3CR) &&
!(CFG_INIT_DCACHE_CS == 3))
+	mtebc(pb3ap, CFG_EBC_PB3AP);
+	mtebc(pb3cr, CFG_EBC_PB3CR);
 #endif
 
-#if (defined(CONFIG_SYS_EBC_PB4AP) && defined(CONFIG_SYS_EBC_PB4CR) &&
!(CONFIG_SYS_INIT_DCACHE_CS == 4))
-	mtebc(pb4ap, CONFIG_SYS_EBC_PB4AP);
-	mtebc(pb4cr, CONFIG_SYS_EBC_PB4CR);
+#if (defined(CFG_EBC_PB4AP) && defined(CFG_EBC_PB4CR) &&
!(CFG_INIT_DCACHE_CS == 4))
+	mtebc(pb4ap, CFG_EBC_PB4AP);
+	mtebc(pb4cr, CFG_EBC_PB4CR);
 #endif
 
-#if (defined(CONFIG_SYS_EBC_PB5AP) && defined(CONFIG_SYS_EBC_PB5CR) &&
!(CONFIG_SYS_INIT_DCACHE_CS == 5))
-	mtebc(pb5ap, CONFIG_SYS_EBC_PB5AP);
-	mtebc(pb5cr, CONFIG_SYS_EBC_PB5CR);
+#if (defined(CFG_EBC_PB5AP) && defined(CFG_EBC_PB5CR) &&
!(CFG_INIT_DCACHE_CS == 5))
+	mtebc(pb5ap, CFG_EBC_PB5AP);
+	mtebc(pb5cr, CFG_EBC_PB5CR);
 #endif
 
-#if (defined(CONFIG_SYS_EBC_PB6AP) && defined(CONFIG_SYS_EBC_PB6CR) &&
!(CONFIG_SYS_INIT_DCACHE_CS == 6))
-	mtebc(pb6ap, CONFIG_SYS_EBC_PB6AP);
-	mtebc(pb6cr, CONFIG_SYS_EBC_PB6CR);
+#if (defined(CFG_EBC_PB6AP) && defined(CFG_EBC_PB6CR) &&
!(CFG_INIT_DCACHE_CS == 6))
+	mtebc(pb6ap, CFG_EBC_PB6AP);
+	mtebc(pb6cr, CFG_EBC_PB6CR);
 #endif
 
-#if (defined(CONFIG_SYS_EBC_PB7AP) && defined(CONFIG_SYS_EBC_PB7CR) &&
!(CONFIG_SYS_INIT_DCACHE_CS == 7))
-	mtebc(pb7ap, CONFIG_SYS_EBC_PB7AP);
-	mtebc(pb7cr, CONFIG_SYS_EBC_PB7CR);
+#if (defined(CFG_EBC_PB7AP) && defined(CFG_EBC_PB7CR) &&
!(CFG_INIT_DCACHE_CS == 7))
+	mtebc(pb7ap, CFG_EBC_PB7AP);
+	mtebc(pb7cr, CFG_EBC_PB7CR);
 #endif
 
-#if defined (CONFIG_SYS_EBC_CFG)
-	mtebc(EBC0_CFG, CONFIG_SYS_EBC_CFG);
+#if defined (CFG_EBC_CFG)
+	mtebc(EBC0_CFG, CFG_EBC_CFG);
 #endif
 
 #if defined(CONFIG_WATCHDOG)
@@ -261,9 +361,9 @@ cpu_init_f (void)
 #else
 	val |= 0xf0000000;      /* generate system reset after 2.684
seconds */
 #endif
-#if defined(CONFIG_SYS_4xx_RESET_TYPE)
+#if defined(CFG_4xx_RESET_TYPE)
 	val &= ~0x30000000;			/* clear WRC bits */
-	val |= CONFIG_SYS_4xx_RESET_TYPE << 28;	/* set board specific
WRC type */
+	val |= CFG_4xx_RESET_TYPE << 28;	/* set board specific
WRC type */
 #endif
 	mtspr(tcr, val);
 
@@ -321,10 +421,34 @@ cpu_init_f (void)
  */
 int cpu_init_r (void)
 {
+#if defined(CONFIG_405GP)  || defined(CONFIG_405EP)
+	bd_t *bd = gd->bd;
+	unsigned long reg;
 #if defined(CONFIG_405GP)
 	uint pvr = get_pvr();
+#endif
 
 	/*
+	 * Write Ethernetaddress into on-chip register
+	 */
+	reg = 0x00000000;
+	reg |= bd->bi_enetaddr[0];           /* set high address */
+	reg = reg << 8;
+	reg |= bd->bi_enetaddr[1];
+	out32 (EMAC_IAH, reg);
+
+	reg = 0x00000000;
+	reg |= bd->bi_enetaddr[2];           /* set low address  */
+	reg = reg << 8;
+	reg |= bd->bi_enetaddr[3];
+	reg = reg << 8;
+	reg |= bd->bi_enetaddr[4];
+	reg = reg << 8;
+	reg |= bd->bi_enetaddr[5];
+	out32 (EMAC_IAL, reg);
+
+#if defined(CONFIG_405GP)
+	/*
 	 * Set edge conditioning circuitry on PPC405GPr
 	 * for compatibility to existing PPC405GP designs.
 	 */
@@ -332,6 +456,7 @@ int cpu_init_r (void)
 		mtdcr(ecr, 0x60606000);
 	}
 #endif  /* defined(CONFIG_405GP) */
+#endif  /* defined(CONFIG_405GP) || defined(CONFIG_405EP) */
 
-	return 0;
+	return (0);
 }

diff --git a/a/u-boot-2009.06/cpu/ppc4xx/speed.c
b/b/u-boot-2009.06/cpu/ppc4xx/speed.c
old mode 100644
new mode 100755
index ed6e55b..d21bd82
--- a/a/u-boot-2009.06/cpu/ppc4xx/speed.c
+++ b/b/u-boot-2009.06/cpu/ppc4xx/speed.c
@@ -148,7 +148,7 @@ void get_sys_info (PPC4xx_SYS_INFO * sysInfo)
 		 * is equal to the 405GP SYS_CLK_FREQ. If not in bypass
mode, check VCO
 		 * to make sure it is within the proper range.
 		 *    spec:    VCO = SYS_CLOCK x FBKDIV x PLBDIV x
FWDDIV
-		 * Note freqVCO is calculated in MHz to avoid errors
introduced by rounding.
+		 * Note freqVCO is calculated in Mhz to avoid errors
introduced by rounding.
 		 */
 		if (sysInfo->pllFwdDiv == 1) {
 			sysInfo->freqProcessor = CONFIG_SYS_CLK_FREQ;


More information about the U-Boot mailing list