[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