
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;