sbc8548: Fix up local bus init to be frequency aware

The code here was copied from the mpc8548cds support, and it
wasn't using the CONFIG_SYS_LBC_LCRR define, and was just
unconditionally setting the LCRR_EADC bit.  Snooping with a
hardware debugger also showed we had LCRR_DBYP set, since we were
setting it based on a read of an uninitialized lcrr read via
clkdiv.  Borrow from the code in the tqm85xx.c support to add
LBC frequency aware masking of these bits.

This change will correct reliability issues associated with trying
to use the 128MB of LBC 100MHz SDRAM on this board.  Thanks to
Keith Savage for assistance in diagnosing the root cause of this.

Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
This commit is contained in:
Paul Gortmaker 2011-12-30 23:53:13 -05:00 committed by Kumar Gala
parent 3e3262bd14
commit e2b363ff53
1 changed files with 35 additions and 3 deletions

View File

@ -76,11 +76,15 @@ local_bus_init(void)
volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
volatile fsl_lbc_t *lbc = LBC_BASE_ADDR;
uint clkdiv;
uint clkdiv, lbc_mhz, lcrr = CONFIG_SYS_LBC_LCRR;
sys_info_t sysinfo;
get_sys_info(&sysinfo);
clkdiv = (in_be32(&lbc->lcrr) & LCRR_CLKDIV) * 2;
lbc_mhz = sysinfo.freqLocalBus / 1000000;
clkdiv = sysinfo.freqSystemBus / sysinfo.freqLocalBus;
debug("LCRR=0x%x, CD=%d, MHz=%d\n", lcrr, clkdiv, lbc_mhz);
out_be32(&gur->lbiuiplldcr1, 0x00078080);
if (clkdiv == 16) {
@ -91,10 +95,38 @@ local_bus_init(void)
out_be32(&gur->lbiuiplldcr0, 0x5c0f1bf0);
}
setbits_be32(&lbc->lcrr, 0x00030000);
/*
* Local Bus Clock > 83.3 MHz. According to timing
* specifications set LCRR[EADC] to 2 delay cycles.
*/
if (lbc_mhz > 83) {
lcrr &= ~LCRR_EADC;
lcrr |= LCRR_EADC_2;
}
/*
* According to MPC8548ERMAD Rev. 1.3, 13.3.1.16, 13-30
* disable PLL bypass for Local Bus Clock > 83 MHz.
*/
if (lbc_mhz >= 66)
lcrr &= (~LCRR_DBYP); /* DLL Enabled */
else
lcrr |= LCRR_DBYP; /* DLL Bypass */
out_be32(&lbc->lcrr, lcrr);
asm("sync;isync;msync");
/*
* According to MPC8548ERMAD Rev.1.3 read back LCRR
* and terminate with isync
*/
lcrr = in_be32(&lbc->lcrr);
asm ("isync;");
/* let DLL stabilize */
udelay(500);
out_be32(&lbc->ltesr, 0xffffffff); /* Clear LBC error IRQs */
out_be32(&lbc->lteir, 0xffffffff); /* Enable LBC error IRQs */
}