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

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@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@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;

Hi Rup,
On Friday 24 July 2009 07:54:01 Rupjyoti Sarmah wrote:
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.
Again, you don't have to mention which files are changed. git has all this information and we don't need to store it into the commit text.
Signed off by Rupjyoti Sarmah < rsarmah@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 @@ -/*
- /*
This line is changed incorrectly. Please keep it.
- (C) Copyright 2000-2007
- Wolfgang Denk, DENX Software Engineering, wd@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
Ups. No. We moved from using "CFG_" to "CONFIG_SYS" quite a while ago. Which U-Boot version did you base this patch on? Please use current tot (top of tree) version as bases for you patches.
#endif
Don't add empty lines.
+#define BOOT_STRAP_OPTION_A 0x00000000 +#define BOOT_STRAP_OPTION_B 0x00000001 +#define BOOT_STRAP_OPTION_D 0x00000003 +#define BOOT_STRAP_OPTION_E 0x00000004
And please don't add so many empty lines. One is enough.
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 */
Patch is line wrapped. Please fix. Otherwise it can't be applied.
spcid0, target_spcid0; /*
CLK_SPCID */
No more empty lines here.
/* 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;
Indentation is incorrect. Use tabs instead of spaces.
/* Check to see if
FWDVA has */
/* been set to a value
of 1. if*/
/* it has we must
modify it. */
- if (temp == 1) {
Again, please don't add some many empty lines.
I'll stop my review here. Please fix the problems mentioned above. And especially rebase your patch against the latest version.
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@denx.de =====================================================================
participants (2)
-
Rupjyoti Sarmah
-
Stefan Roese