[U-Boot] [PATCH 85xx-next 0/8] Updates for Wind River sbc8548 board

This updates the sbc8548 board support with several improvements for the end users.
-ability to use SPD DDR config for easy RAM upgrades -ability to use alternate SODIMM flash for backup u-boot image -localbus config settings fixed so 128MB LBC SDRAM works reliably
The discovery of a hardware errata (overlapping I2C SPD addresses) is at the core of what now allows the use of SPD configuration.
The relocation of the 64MB user flash is to align it on a 64MB boundary, which simplifies a whole lot of things, both in the code and for the end user. (The previous mapping meant the last sector on the chip wasn't consistently the last sector in the address space assigned to the chip for all jumper configurations.)
Reverting a bogus commit from the past that incorrectly set the windows for the 64MB flash to 128MB was the starting point for getting this all working.
Paul.
--- The following changes since commit cba9a894fdb1cb49b60fcd1d1d6919cbd7995dd5:
Prepare v2011.12 (2011-12-23 20:25:35 +0100)
are available in the git repository at: git://openlinux.windriver.com/people/paulg/u-boot sbc8548-Dec30_2011
Paul Gortmaker (8): Revert "SBC8548: fix address mask to allow 64M flash" sbc8548: relocate 64MB user flash to sane boundary sbc8548: enable ability to boot from alternate flash sbc8548: Fix LBC SDRAM initialization settings sbc8548: Make enabling SPD RAM configuration work sbc8548: relocate fixed ddr init code to ddr.c file sbc8548: enable support for hardware SPD errata workaround sbc8548: Fix up local bus init to be frequency aware
board/sbc8548/ddr.c | 77 +++++++++++++++++++++++ board/sbc8548/law.c | 16 +++++- board/sbc8548/sbc8548.c | 111 +++++++++++++++------------------ board/sbc8548/tlb.c | 24 ++++++-- doc/README.sbc8548 | 79 ++++++++++++++++++++++-- include/configs/sbc8548.h | 151 +++++++++++++++++++++++++++++++++++---------- 6 files changed, 355 insertions(+), 103 deletions(-)

This reverts commit ccf1ad535ae1c0dc2d466235c668adbdfe3a55b7.
The commit "SBC8548: fix address mask to allow 64M flash" essentially made this change:
* OR6: - * Addr Mask = 64M = OR6[0:16] = 1111 1100 0000 0000 0 + * Addr Mask = 64M = OR6[0:16] = 1111 1000 0000 0000 0
But this makes no sense, as section 13.3.1.2.1 in the MPC8548ERM v2 clearly indicates the masks:
1111_1111_1000_0000_0 8 Mbytes 1111_1100_0000_0000_0 64 Mbytes 1111_1000_0000_0000_0 128 Mbytes
So the original value was correct, and the commit was invalid, causing a 128MB mapping for a 64MB flash device. The problem rears its head when trying to configure u-boot to have access to both flash, since the default memory map is:
FB80_0000 – FF7F_FFFF 32-bits 64MB FLASH SODIMM FF80_0000 – FFFF_FFFF 8-bits 8MB FLASH
By extending the mapping of the 64MB flash to 128MB, it now conflicts with the normal 8MB boot flash, causing issues.
Signed-off-by: Paul Gortmaker paul.gortmaker@windriver.com --- include/configs/sbc8548.h | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/include/configs/sbc8548.h b/include/configs/sbc8548.h index ba7612c..7c26207 100644 --- a/include/configs/sbc8548.h +++ b/include/configs/sbc8548.h @@ -173,7 +173,7 @@ * 1111 1111 1000 0000 0110 1110 0110 0101 = ff806e65 OR0 * * OR6: - * Addr Mask = 64M = OR6[0:16] = 1111 1000 0000 0000 0 + * Addr Mask = 64M = OR6[0:16] = 1111 1100 0000 0000 0 * XAM = OR6[17:18] = 11 * CSNT = OR6[20] = 1 * ACS = half cycle delay = OR6[21:22] = 11 @@ -182,7 +182,7 @@ * EAD = use external address latch delay = OR6[31] = 1 * * 0 4 8 12 16 20 24 28 - * 1111 1000 0000 0000 0110 1110 0110 0101 = f8006e65 OR6 + * 1111 1100 0000 0000 0110 1110 0110 0101 = fc006e65 OR6 */
#define CONFIG_SYS_BOOT_BLOCK 0xff800000 /* start of 8MB Flash */ @@ -193,7 +193,7 @@ #define CONFIG_SYS_BR6_PRELIM 0xfb801801
#define CONFIG_SYS_OR0_PRELIM 0xff806e65 -#define CONFIG_SYS_OR6_PRELIM 0xf8006e65 +#define CONFIG_SYS_OR6_PRELIM 0xfc006e65
#define CONFIG_SYS_FLASH_BANKS_LIST {CONFIG_SYS_FLASH_BASE, \ CONFIG_SYS_ALT_FLASH}

The current situation has the 64MB user flash at an awkward alignment; shifted back from 0xfc00_0000 by 8M, to leave an 8MB hole for the soldered on boot flash @ EOM. But to switch to optionally supporting booting off the 64MB flash, the 64MB will then be mapped at the sane address of 0xfc00_0000.
This leads to awkward things when programming the 64MB flash prior to transitioning to it -- i.e. even though the chip spans from 0xfb80_0000 to 0xff7f_ffff, you would have to program a u-boot image into the two sectors from 0xfbf0_0000 --> 0xfbff_ffff so that it was in the right place when JP12/SW2.8 were switched to make the 64MB on /CS0. (i.e. the chip is only looking at the bits in mask 0x3ff_ffff)
We also have to have three TLB entries responsible for dealing with mapping the 64MB flash due to this 8MB of misalignment.
In the end, there is address space from 0xec00_0000 to 0xefff_ffff where we can map it, and then the transition from booting from one config to the other will be a simple 0xec --> 0xfc mapping. Plus we can toss out a TLB entry.
Note that TLB0 is kept at 64MB and not shrunk down to the 8MB boot flash; this means we won't have to change it when the alternate config uses the full 64MB for booting, in TLB0.
Signed-off-by: Paul Gortmaker paul.gortmaker@windriver.com --- board/sbc8548/law.c | 3 ++- board/sbc8548/tlb.c | 23 ++++++++--------------- doc/README.sbc8548 | 8 +++++++- include/configs/sbc8548.h | 10 +++++----- 4 files changed, 22 insertions(+), 22 deletions(-)
diff --git a/board/sbc8548/law.c b/board/sbc8548/law.c index 5fa9db0..febb682 100644 --- a/board/sbc8548/law.c +++ b/board/sbc8548/law.c @@ -36,9 +36,9 @@ * 0xe000_0000 0xe000_ffff CCSR 1M * 0xe200_0000 0xe27f_ffff PCI1 IO 8M * 0xe280_0000 0xe2ff_ffff PCIe IO 8M + * 0xec00_0000 0xefff_ffff FLASH (2nd bank) 64M * 0xf000_0000 0xf7ff_ffff SDRAM 128M * 0xf8b0_0000 0xf80f_ffff EEPROM 1M - * 0xfb80_0000 0xff7f_ffff FLASH (2nd bank) 64M * 0xff80_0000 0xffff_ffff FLASH (boot bank) 8M * * Notes: @@ -47,6 +47,7 @@ */
struct law_entry law_table[] = { + SET_LAW(CONFIG_SYS_ALT_FLASH, LAW_SIZE_64M, LAW_TRGT_IF_LBC), #ifndef CONFIG_SPD_EEPROM SET_LAW(CONFIG_SYS_DDR_SDRAM_BASE, LAW_SIZE_256M, LAW_TRGT_IF_DDR), #endif diff --git a/board/sbc8548/tlb.c b/board/sbc8548/tlb.c index bb4c052..e9cedc7 100644 --- a/board/sbc8548/tlb.c +++ b/board/sbc8548/tlb.c @@ -46,12 +46,14 @@ struct fsl_e_tlb_entry tlb_table[] = {
/* * TLB 0: 64M Non-cacheable, guarded - * 0xfc000000 56M 8MB -> 64MB of user flash + * 0xfc000000 56M unused * 0xff800000 8M boot FLASH + * .... or .... + * 0xfc000000 64M user flash + * * Out of reset this entry is only 4K. */ - SET_TLB_ENTRY(1, CONFIG_SYS_ALT_FLASH + 0x800000, - CONFIG_SYS_ALT_FLASH + 0x800000, + SET_TLB_ENTRY(1, 0xfc000000, 0xfc000000, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 0, BOOKE_PAGESZ_64M, 1),
@@ -103,21 +105,12 @@ struct fsl_e_tlb_entry tlb_table[] = { 0, 5, BOOKE_PAGESZ_16M, 1),
/* - * TLB 6: 4M Non-cacheable, guarded - * 0xfb800000 4M 1st 4MB block of 64MB user FLASH + * TLB 6: 64M Non-cacheable, guarded + * 0xec000000 64M 64MB user FLASH */ SET_TLB_ENTRY(1, CONFIG_SYS_ALT_FLASH, CONFIG_SYS_ALT_FLASH, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, - 0, 6, BOOKE_PAGESZ_4M, 1), - - /* - * TLB 7: 4M Non-cacheable, guarded - * 0xfbc00000 4M 2nd 4MB block of 64MB user FLASH - */ - SET_TLB_ENTRY(1, CONFIG_SYS_ALT_FLASH + 0x400000, - CONFIG_SYS_ALT_FLASH + 0x400000, - MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, - 0, 7, BOOKE_PAGESZ_4M, 1), + 0, 6, BOOKE_PAGESZ_64M, 1),
};
diff --git a/doc/README.sbc8548 b/doc/README.sbc8548 index 6cbe12f..5fa9c93 100644 --- a/doc/README.sbc8548 +++ b/doc/README.sbc8548 @@ -100,6 +100,9 @@ Boot flash:
Sodimm flash: intel V28F128Jx, 16384x8 (4 devices) at 0xfb80_0000 + Note that this address reflects the default setting for + the JTAG debugging tools, but since the alignment is + rather inconvenient, u-boot puts it at 0xec00_0000.
Jumpers: @@ -187,9 +190,12 @@ start end CS<n> width Desc. 0000_0000 0fff_ffff MCS0,1 64 DDR2 (256MB) f000_0000 f7ff_ffff CS3,4 32 LB SDRAM (128MB) f800_0000 f8b0_1fff CS5 - EPLD -fb80_0000 ff7f_ffff CS6 32 SODIMM flash (64MB) +fb80_0000 ff7f_ffff CS6 32 SODIMM flash (64MB) [*] ff80_0000 ffff_ffff CS0 8 Boot flash (8MB)
+[*] fb80 represents the default programmed by WR JTAG register files, + but u-boot places the flash at either ec00 or fc00 based on JP12. + The EPLD on CS5 demuxes the following devices at the following offsets:
offset size width device diff --git a/include/configs/sbc8548.h b/include/configs/sbc8548.h index 7c26207..cea0179 100644 --- a/include/configs/sbc8548.h +++ b/include/configs/sbc8548.h @@ -140,7 +140,7 @@ * FLASH on the Local Bus * Two banks, one 8MB the other 64MB, using the CFI driver. * Boot from BR0/OR0 bank at 0xff80_0000 - * Alternate BR6/OR6 bank at 0xfb80_0000 + * Alternate BR6/OR6 bank at 0xec00_0000 * * BR0: * Base address 0 = 0xff80_0000 = BR0[0:16] = 1111 1111 1000 0000 0 @@ -152,13 +152,13 @@ * 1111 1111 1000 0000 0000 1000 0000 0001 = ff800801 BR0 * * BR6: - * Base address 6 = 0xfb80_0000 = BR6[0:16] = 1111 1011 1000 0000 0 + * Base address 6 = 0xec00_0000 = BR6[0:16] = 1110 1100 0000 0000 0 * Port Size = 32 bits = BRx[19:20] = 11 * Use GPCM = BRx[24:26] = 000 * Valid = BRx[31] = 1 * * 0 4 8 12 16 20 24 28 - * 1111 1011 1000 0000 0001 1000 0000 0001 = fb801801 BR6 + * 1110 1100 0000 0000 0001 1000 0000 0001 = ec001801 BR6 * * OR0: * Addr Mask = 8M = OR1[0:16] = 1111 1111 1000 0000 0 @@ -186,11 +186,11 @@ */
#define CONFIG_SYS_BOOT_BLOCK 0xff800000 /* start of 8MB Flash */ -#define CONFIG_SYS_ALT_FLASH 0xfb800000 /* 64MB "user" flash */ +#define CONFIG_SYS_ALT_FLASH 0xec000000 /* 64MB "user" flash */ #define CONFIG_SYS_FLASH_BASE CONFIG_SYS_BOOT_BLOCK /* start of FLASH 16M */
#define CONFIG_SYS_BR0_PRELIM 0xff800801 -#define CONFIG_SYS_BR6_PRELIM 0xfb801801 +#define CONFIG_SYS_BR6_PRELIM 0xec001801
#define CONFIG_SYS_OR0_PRELIM 0xff806e65 #define CONFIG_SYS_OR6_PRELIM 0xfc006e65

This board has an 8MB soldered on flash, and a 64MB SODIMM flash module. Normally the board boots from the 8MB flash, but the hardware can be configured for booting from the 64MB flash as well by swapping CS0 and CS6. This can be handy for recovery purposes, or for supporting u-boot and VxBoot at the same time.
To support this in u-boot, we need to have different BR0/OR0 and BR6/OR6 settings in place for when the board is configured in this way, and a different TEXT_BASE needs to be used due to the larger sector size of the 64MB flash module.
We introduce the suffix _8M and _64M for the BR0/BR6 and the OR0/OR6 values so it is clear which is being used to map what specific device.
The larger sector size (512k) of the alternate flash needs a larger malloc pool, otherwise you'll get failures when running saveenv, so bump it up accordingly.
Signed-off-by: Paul Gortmaker paul.gortmaker@windriver.com --- board/sbc8548/law.c | 8 +++ board/sbc8548/sbc8548.c | 2 +- board/sbc8548/tlb.c | 19 ++++++++ doc/README.sbc8548 | 34 +++++++++++++-- include/configs/sbc8548.h | 106 +++++++++++++++++++++++++++++++++++--------- 5 files changed, 142 insertions(+), 27 deletions(-)
diff --git a/board/sbc8548/law.c b/board/sbc8548/law.c index febb682..c263191 100644 --- a/board/sbc8548/law.c +++ b/board/sbc8548/law.c @@ -41,13 +41,21 @@ * 0xf8b0_0000 0xf80f_ffff EEPROM 1M * 0xff80_0000 0xffff_ffff FLASH (boot bank) 8M * + * If swapped CS0/CS6 via JP12+SW2.8: + * 0xef80_0000 0xefff_ffff FLASH (2nd bank) 8M + * 0xfc00_0000 0xffff_ffff FLASH (boot bank) 64M + * * Notes: * CCSRBAR and L2-as-SRAM don't need a configured Local Access Window. * If flash is 8M at default position (last 8M), no LAW needed. */
struct law_entry law_table[] = { +#ifdef CONFIG_SYS_ALT_BOOT + SET_LAW(CONFIG_SYS_ALT_FLASH, LAW_SIZE_8M, LAW_TRGT_IF_LBC), +#else SET_LAW(CONFIG_SYS_ALT_FLASH, LAW_SIZE_64M, LAW_TRGT_IF_LBC), +#endif #ifndef CONFIG_SPD_EEPROM SET_LAW(CONFIG_SYS_DDR_SDRAM_BASE, LAW_SIZE_256M, LAW_TRGT_IF_DDR), #endif diff --git a/board/sbc8548/sbc8548.c b/board/sbc8548/sbc8548.c index 26095a5..63d504d 100644 --- a/board/sbc8548/sbc8548.c +++ b/board/sbc8548/sbc8548.c @@ -113,7 +113,7 @@ void lbc_sdram_init(void)
puts(" SDRAM: ");
- print_size (CONFIG_SYS_LBC_SDRAM_SIZE * 1024 * 1024, "\n"); + print_size(CONFIG_SYS_LBC_SDRAM_SIZE * 1024 * 1024, "\n");
/* * Setup SDRAM Base and Option Registers diff --git a/board/sbc8548/tlb.c b/board/sbc8548/tlb.c index e9cedc7..4bf7214 100644 --- a/board/sbc8548/tlb.c +++ b/board/sbc8548/tlb.c @@ -104,6 +104,7 @@ struct fsl_e_tlb_entry tlb_table[] = { MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 5, BOOKE_PAGESZ_16M, 1),
+#ifndef CONFIG_SYS_ALT_BOOT /* * TLB 6: 64M Non-cacheable, guarded * 0xec000000 64M 64MB user FLASH @@ -111,6 +112,24 @@ struct fsl_e_tlb_entry tlb_table[] = { SET_TLB_ENTRY(1, CONFIG_SYS_ALT_FLASH, CONFIG_SYS_ALT_FLASH, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 6, BOOKE_PAGESZ_64M, 1), +#else + /* + * TLB 6: 4M Non-cacheable, guarded + * 0xef800000 4M 1st 1/2 8MB soldered FLASH + */ + SET_TLB_ENTRY(1, CONFIG_SYS_ALT_FLASH, CONFIG_SYS_ALT_FLASH, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 6, BOOKE_PAGESZ_4M, 1), + + /* + * TLB 7: 4M Non-cacheable, guarded + * 0xefc00000 4M 2nd half 8MB soldered FLASH + */ + SET_TLB_ENTRY(1, CONFIG_SYS_ALT_FLASH + 0x400000, + CONFIG_SYS_ALT_FLASH + 0x400000, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 7, BOOKE_PAGESZ_4M, 1), +#endif
};
diff --git a/doc/README.sbc8548 b/doc/README.sbc8548 index 5fa9c93..e6b8abe 100644 --- a/doc/README.sbc8548 +++ b/doc/README.sbc8548 @@ -86,6 +86,33 @@ The "md" steps in the above are just a precautionary step that allow you to confirm the u-boot version that was downloaded, and then confirm that it was copied to flash.
+The above assumes that you are using the default board settings which +have u-boot in the 8MB flash, tied to /CS0. + +If you are running the default 8MB /CS0 settings but want to store an +image in the SODIMM that is built with CONFIG_SYS_ALT_BOOT enabled, +(as a backup, etc) then the steps will become: + + tftp u-boot.bin + md 200000 10 + protect off all + era eff00000 efffffff + cp.b 200000 eff00000 100000 + md eff00000 10 + protect on all + +Finally, if you are running the alternate 64MB /CS0 settings and want +to update the in-use u-boot image, then (again with CONFIG_SYS_ALT_BOOT +enabled) the steps will become: + + tftp u-boot.bin + md 200000 10 + protect off all + era fff00000 ffffffff + cp.b 200000 fff00000 100000 + md fff00000 10 + protect on all +
Hardware Reference: =================== @@ -127,10 +154,9 @@ JP19 PCI mode PCI PCI-X onto /CS0 and the SODIMM flash on /CS6 (default). When JP12 is jumpered parallel to the LBC-SDRAM, then /CS0 is for the SODIMM flash and /CS6 is for the boot flash. Note that in this -alternate setting, you also need to switch SW2.8 to ON. Currently -u-boot doesn't support booting off the SODIMM in this alternate -setting without manually altering BR0/OR0 and BR6/OR6 in the -board config file appropriately. +alternate setting, you also need to switch SW2.8 to ON. +See the setting CONFIG_SYS_ALT_BOOT if you want to use this setting +and boot u-boot from the 64MB SODIMM
Switches: diff --git a/include/configs/sbc8548.h b/include/configs/sbc8548.h index cea0179..fb07d09 100644 --- a/include/configs/sbc8548.h +++ b/include/configs/sbc8548.h @@ -57,9 +57,19 @@ #define CONFIG_MPC8548 1 /* MPC8548 specific */ #define CONFIG_SBC8548 1 /* SBC8548 board specific */
+/* + * If you want to boot from the SODIMM flash, instead of the soldered + * on flash, set this, and change JP12, SW2:8 accordingly. + */ +#undef CONFIG_SYS_ALT_BOOT + #ifndef CONFIG_SYS_TEXT_BASE +#ifdef CONFIG_SYS_ALT_BOOT +#define CONFIG_SYS_TEXT_BASE 0xfff00000 +#else #define CONFIG_SYS_TEXT_BASE 0xfffa0000 #endif +#endif
#undef CONFIG_RIO
@@ -139,28 +149,54 @@ /* * FLASH on the Local Bus * Two banks, one 8MB the other 64MB, using the CFI driver. - * Boot from BR0/OR0 bank at 0xff80_0000 - * Alternate BR6/OR6 bank at 0xec00_0000 + * JP12+SW2.8 are used to swap CS0 and CS6, defaults are to have + * CS0 the 8MB boot flash, and CS6 the 64MB flash. * - * BR0: + * Default: + * ec00_0000 efff_ffff 64MB SODIMM + * ff80_0000 ffff_ffff 8MB soldered flash + * + * Alternate: + * ef80_0000 efff_ffff 8MB soldered flash + * fc00_0000 ffff_ffff 64MB SODIMM + * + * BR0_8M: * Base address 0 = 0xff80_0000 = BR0[0:16] = 1111 1111 1000 0000 0 * Port Size = 8 bits = BRx[19:20] = 01 * Use GPCM = BRx[24:26] = 000 * Valid = BRx[31] = 1 * - * 0 4 8 12 16 20 24 28 - * 1111 1111 1000 0000 0000 1000 0000 0001 = ff800801 BR0 - * - * BR6: - * Base address 6 = 0xec00_0000 = BR6[0:16] = 1110 1100 0000 0000 0 + * BR0_64M: + * Base address 0 = 0xfc00_0000 = BR0[0:16] = 1111 1100 0000 0000 0 * Port Size = 32 bits = BRx[19:20] = 11 + * + * 0 4 8 12 16 20 24 28 + * 1111 1111 1000 0000 0000 1000 0000 0001 = ff800801 BR0_8M + * 1111 1100 0000 0000 0001 1000 0000 0001 = fc001801 BR0_64M + */ +#define CONFIG_SYS_BR0_8M 0xff800801 +#define CONFIG_SYS_BR0_64M 0xfc001801 + +/* + * BR6_8M: + * Base address 6 = 0xef80_0000 = BR6[0:16] = 1110 1111 1000 0000 0 + * Port Size = 8 bits = BRx[19:20] = 01 * Use GPCM = BRx[24:26] = 000 * Valid = BRx[31] = 1 + + * BR6_64M: + * Base address 6 = 0xec00_0000 = BR6[0:16] = 1110 1100 0000 0000 0 + * Port Size = 32 bits = BRx[19:20] = 11 * * 0 4 8 12 16 20 24 28 - * 1110 1100 0000 0000 0001 1000 0000 0001 = ec001801 BR6 - * - * OR0: + * 1110 1111 1000 0000 0000 1000 0000 0001 = ef800801 BR6_8M + * 1110 1100 0000 0000 0001 1000 0000 0001 = ec001801 BR6_64M + */ +#define CONFIG_SYS_BR6_8M 0xef800801 +#define CONFIG_SYS_BR6_64M 0xec001801 + +/* + * OR0_8M: * Addr Mask = 8M = OR1[0:16] = 1111 1111 1000 0000 0 * XAM = OR0[17:18] = 11 * CSNT = OR0[20] = 1 @@ -169,11 +205,20 @@ * TRLX = use relaxed timing = OR0[29] = 1 * EAD = use external address latch delay = OR0[31] = 1 * - * 0 4 8 12 16 20 24 28 - * 1111 1111 1000 0000 0110 1110 0110 0101 = ff806e65 OR0 + * OR0_64M: + * Addr Mask = 64M = OR1[0:16] = 1111 1100 0000 0000 0 * - * OR6: - * Addr Mask = 64M = OR6[0:16] = 1111 1100 0000 0000 0 + * + * 0 4 8 12 16 20 24 28 + * 1111 1111 1000 0000 0110 1110 0110 0101 = ff806e65 OR0_8M + * 1111 1100 0000 0000 0110 1110 0110 0101 = fc006e65 OR0_64M + */ +#define CONFIG_SYS_OR0_8M 0xff806e65 +#define CONFIG_SYS_OR0_64M 0xfc006e65 + +/* + * OR6_8M: + * Addr Mask = 8M = OR6[0:16] = 1111 1111 1000 0000 0 * XAM = OR6[17:18] = 11 * CSNT = OR6[20] = 1 * ACS = half cycle delay = OR6[21:22] = 11 @@ -181,20 +226,37 @@ * TRLX = use relaxed timing = OR6[29] = 1 * EAD = use external address latch delay = OR6[31] = 1 * + * OR6_64M: + * Addr Mask = 64M = OR6[0:16] = 1111 1100 0000 0000 0 + * * 0 4 8 12 16 20 24 28 - * 1111 1100 0000 0000 0110 1110 0110 0101 = fc006e65 OR6 + * 1111 1111 1000 0000 0110 1110 0110 0101 = ff806e65 OR6_8M + * 1111 1100 0000 0000 0110 1110 0110 0101 = fc006e65 OR6_64M */ +#define CONFIG_SYS_OR6_8M 0xff806e65 +#define CONFIG_SYS_OR6_64M 0xfc006e65
+#ifndef CONFIG_SYS_ALT_BOOT /* JP12 in default position */ #define CONFIG_SYS_BOOT_BLOCK 0xff800000 /* start of 8MB Flash */ #define CONFIG_SYS_ALT_FLASH 0xec000000 /* 64MB "user" flash */ -#define CONFIG_SYS_FLASH_BASE CONFIG_SYS_BOOT_BLOCK /* start of FLASH 16M */
-#define CONFIG_SYS_BR0_PRELIM 0xff800801 -#define CONFIG_SYS_BR6_PRELIM 0xec001801 +#define CONFIG_SYS_BR0_PRELIM CONFIG_SYS_BR0_8M +#define CONFIG_SYS_OR0_PRELIM CONFIG_SYS_OR0_8M + +#define CONFIG_SYS_BR6_PRELIM CONFIG_SYS_BR6_64M +#define CONFIG_SYS_OR6_PRELIM CONFIG_SYS_OR6_64M +#else /* JP12 in alternate position */ +#define CONFIG_SYS_BOOT_BLOCK 0xfc000000 /* start 64MB Flash */ +#define CONFIG_SYS_ALT_FLASH 0xef800000 /* 8MB soldered flash */
-#define CONFIG_SYS_OR0_PRELIM 0xff806e65 -#define CONFIG_SYS_OR6_PRELIM 0xfc006e65 +#define CONFIG_SYS_BR0_PRELIM CONFIG_SYS_BR0_64M +#define CONFIG_SYS_OR0_PRELIM CONFIG_SYS_OR0_64M + +#define CONFIG_SYS_BR6_PRELIM CONFIG_SYS_BR6_8M +#define CONFIG_SYS_OR6_PRELIM CONFIG_SYS_OR6_8M +#endif
+#define CONFIG_SYS_FLASH_BASE CONFIG_SYS_BOOT_BLOCK #define CONFIG_SYS_FLASH_BANKS_LIST {CONFIG_SYS_FLASH_BASE, \ CONFIG_SYS_ALT_FLASH} #define CONFIG_SYS_MAX_FLASH_BANKS 2 /* number of banks */ @@ -330,7 +392,7 @@ * thing for MONITOR_LEN in both cases. */ #define CONFIG_SYS_MONITOR_LEN (~CONFIG_SYS_TEXT_BASE + 1) -#define CONFIG_SYS_MALLOC_LEN (128 * 1024) /* Reserved for malloc */ +#define CONFIG_SYS_MALLOC_LEN (1024 * 1024) /* Reserved for malloc */
/* Serial Port */ #define CONFIG_CONS_INDEX 1

These were cloned from the mpc8548cds platform which has a different memory layout (1/2 the size). Set the values by comparing to the register file for the board used during JTAG init sequence:
LSDMR1 0x2863B727 /* PCHALL */ LSDMR2 0x0863B727 /* NORMAL */ LSDMR3 0x1863B727 /* MRW */ LSDMR4 0x4063B727 /* RFEN */
This differs from what was there already in that the RFEN is not bundled in all four steps implicitly, but issued once as the final step.
The other difference seen when comparing vs. the register file init, is that since the memory is split across /CS3 and /CS4, the dummy writes need to go to 0xf000_0000 _and_ to 0xf400_0000.
We also rewrite the final LBC SDRAM inits as macros, as there is no real need for them to be a local variable that is modified on the fly at runtime.
Signed-off-by: Paul Gortmaker paul.gortmaker@windriver.com --- board/sbc8548/sbc8548.c | 29 ++++++++++++++++------------- include/configs/sbc8548.h | 21 ++++++++++++++------- 2 files changed, 30 insertions(+), 20 deletions(-)
diff --git a/board/sbc8548/sbc8548.c b/board/sbc8548/sbc8548.c index 63d504d..96554b2 100644 --- a/board/sbc8548/sbc8548.c +++ b/board/sbc8548/sbc8548.c @@ -107,13 +107,14 @@ void lbc_sdram_init(void) #if defined(CONFIG_SYS_LBC_SDRAM_SIZE)
uint idx; + const unsigned long size = CONFIG_SYS_LBC_SDRAM_SIZE * 1024 * 1024; volatile fsl_lbc_t *lbc = LBC_BASE_ADDR; uint *sdram_addr = (uint *)CONFIG_SYS_LBC_SDRAM_BASE; - uint lsdmr_common; + uint *sdram_addr2 = (uint *)(CONFIG_SYS_LBC_SDRAM_BASE + size/2);
puts(" SDRAM: ");
- print_size(CONFIG_SYS_LBC_SDRAM_SIZE * 1024 * 1024, "\n"); + print_size(size, "\n");
/* * Setup SDRAM Base and Option Registers @@ -131,47 +132,49 @@ void lbc_sdram_init(void) asm("msync");
/* - * MPC8548 uses "new" 15-16 style addressing. - */ - lsdmr_common = CONFIG_SYS_LBC_LSDMR_COMMON; - lsdmr_common |= LSDMR_BSMA1516; - - /* * Issue PRECHARGE ALL command. */ - out_be32(&lbc->lsdmr, lsdmr_common | LSDMR_OP_PCHALL); + out_be32(&lbc->lsdmr, CONFIG_SYS_LBC_LSDMR_PCHALL); asm("sync;msync"); *sdram_addr = 0xff; ppcDcbf((unsigned long) sdram_addr); + *sdram_addr2 = 0xff; + ppcDcbf((unsigned long) sdram_addr2); udelay(100);
/* * Issue 8 AUTO REFRESH commands. */ for (idx = 0; idx < 8; idx++) { - out_be32(&lbc->lsdmr, lsdmr_common | LSDMR_OP_ARFRSH); + out_be32(&lbc->lsdmr, CONFIG_SYS_LBC_LSDMR_ARFRSH); asm("sync;msync"); *sdram_addr = 0xff; ppcDcbf((unsigned long) sdram_addr); + *sdram_addr2 = 0xff; + ppcDcbf((unsigned long) sdram_addr2); udelay(100); }
/* * Issue 8 MODE-set command. */ - out_be32(&lbc->lsdmr, lsdmr_common | LSDMR_OP_MRW); + out_be32(&lbc->lsdmr, CONFIG_SYS_LBC_LSDMR_MRW); asm("sync;msync"); *sdram_addr = 0xff; ppcDcbf((unsigned long) sdram_addr); + *sdram_addr2 = 0xff; + ppcDcbf((unsigned long) sdram_addr2); udelay(100);
/* - * Issue NORMAL OP command. + * Issue RFEN command. */ - out_be32(&lbc->lsdmr, lsdmr_common | LSDMR_OP_NORMAL); + out_be32(&lbc->lsdmr, CONFIG_SYS_LBC_LSDMR_RFEN); asm("sync;msync"); *sdram_addr = 0xff; ppcDcbf((unsigned long) sdram_addr); + *sdram_addr2 = 0xff; + ppcDcbf((unsigned long) sdram_addr2); udelay(200); /* Overkill. Must wait > 200 bus cycles */
#endif /* enable SDRAM init */ diff --git a/include/configs/sbc8548.h b/include/configs/sbc8548.h index fb07d09..1df2225 100644 --- a/include/configs/sbc8548.h +++ b/include/configs/sbc8548.h @@ -362,19 +362,26 @@
/* * Common settings for all Local Bus SDRAM commands. - * At run time, either BSMA1516 (for CPU 1.1) - * or BSMA1617 (for CPU 1.0) (old) - * is OR'ed in too. */ #define CONFIG_SYS_LBC_LSDMR_COMMON ( LSDMR_RFCR16 \ - | LSDMR_PRETOACT7 \ - | LSDMR_ACTTORW7 \ + | LSDMR_BSMA1516 \ + | LSDMR_PRETOACT3 \ + | LSDMR_ACTTORW3 \ + | LSDMR_BUFCMD \ | LSDMR_BL8 \ - | LSDMR_WRC4 \ + | LSDMR_WRC2 \ | LSDMR_CL3 \ - | LSDMR_RFEN \ )
+#define CONFIG_SYS_LBC_LSDMR_PCHALL \ + (CONFIG_SYS_LBC_LSDMR_COMMON | LSDMR_OP_PCHALL) +#define CONFIG_SYS_LBC_LSDMR_ARFRSH \ + (CONFIG_SYS_LBC_LSDMR_COMMON | LSDMR_OP_ARFRSH) +#define CONFIG_SYS_LBC_LSDMR_MRW \ + (CONFIG_SYS_LBC_LSDMR_COMMON | LSDMR_OP_MRW) +#define CONFIG_SYS_LBC_LSDMR_RFEN \ + (CONFIG_SYS_LBC_LSDMR_COMMON | LSDMR_RFEN) + #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xe4010000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_SIZE 0x4000 /* Size of used area in RAM */

Previously, SPD configuration of RAM was non functional on this board. Now that the root cause is known (an i2c address conflict), there is a simple end-user workaround - remove the old slower local bus 128MB module and then SPD detection on the main DDR2 memory module works fine.
We make the enablement of the LBC SDRAM support conditional on being not SPD enabled. We can revisit this dependency as the hardware workaround becomes available.
Turning off LBC SDRAM support revealed a couple implict dependencies in the tlb/law code that always expected an LBC SDRAM address.
This has been tested with the default 256MB module, a 512MB a 1GB and a 2GB, of varying speeds, and the SPD autoconfiguration worked fine in all cases.
The default configuration remains to go with the hard coded DDR config, so the default build will continue to work on boards where people don't bother to read the docs. But the advantage of going to the SPD config is that even the small default module gets configured for CL3 instead of CL4.
Signed-off-by: Paul Gortmaker paul.gortmaker@windriver.com --- board/sbc8548/law.c | 5 +++++ board/sbc8548/tlb.c | 2 ++ doc/README.sbc8548 | 21 +++++++++++++++++++++ include/configs/sbc8548.h | 13 ++++++++++++- 4 files changed, 40 insertions(+), 1 deletions(-)
diff --git a/board/sbc8548/law.c b/board/sbc8548/law.c index c263191..322af76 100644 --- a/board/sbc8548/law.c +++ b/board/sbc8548/law.c @@ -59,8 +59,13 @@ struct law_entry law_table[] = { #ifndef CONFIG_SPD_EEPROM SET_LAW(CONFIG_SYS_DDR_SDRAM_BASE, LAW_SIZE_256M, LAW_TRGT_IF_DDR), #endif +#ifdef CONFIG_SYS_LBC_SDRAM_BASE /* LBC window - maps 256M 0xf0000000 -> 0xffffffff */ SET_LAW(CONFIG_SYS_LBC_SDRAM_BASE, LAW_SIZE_256M, LAW_TRGT_IF_LBC), +#else + /* LBC window - maps 128M 0xf8000000 -> 0xffffffff */ + SET_LAW(CONFIG_SYS_EPLD_BASE, LAW_SIZE_128M, LAW_TRGT_IF_LBC), +#endif };
int num_law_entries = ARRAY_SIZE(law_table); diff --git a/board/sbc8548/tlb.c b/board/sbc8548/tlb.c index 4bf7214..af927f1 100644 --- a/board/sbc8548/tlb.c +++ b/board/sbc8548/tlb.c @@ -76,6 +76,7 @@ struct fsl_e_tlb_entry tlb_table[] = { MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 2, BOOKE_PAGESZ_64M, 1),
+#ifdef CONFIG_SYS_LBC_SDRAM_BASE /* * TLB 3: 64M Cacheable, non-guarded * 0xf0000000 64M LBC SDRAM First half @@ -92,6 +93,7 @@ struct fsl_e_tlb_entry tlb_table[] = { CONFIG_SYS_LBC_SDRAM_BASE + 0x4000000, MAS3_SX|MAS3_SW|MAS3_SR, 0, 0, 4, BOOKE_PAGESZ_64M, 1), +#endif
/* * TLB 5: 16M Cacheable, non-guarded diff --git a/doc/README.sbc8548 b/doc/README.sbc8548 index e6b8abe..f9e2dea 100644 --- a/doc/README.sbc8548 +++ b/doc/README.sbc8548 @@ -62,6 +62,27 @@ a 33MHz PCI configuration is currently untested.) 02.00.00 0x1148 0x9e00 Network controller 0x00 =>
+Memory Size and using SPD: +========================== + +The default configuration uses hard coded memory configuration settings +for 256MB of DDR2 @400MHz. It does not by default use the DDR2 SPD +EEPROM data to read what memory is installed. + +There is a hardware errata, which causes the older local bus SDRAM +SPD EEPROM to land at the same address as the DDR2 SPD EEPROM, so +that the SPD data can not be read reliably. + +If you want to upgrade to larger RAM size, you can simply enable + #define CONFIG_SPD_EEPROM + #define CONFIG_DDR_SPD +in include/configs/sbc8548.h file. (The lines are already there +but listed as #undef). + +Note that you will have to physically remove the LBC 128MB DIMM +from the board's socket to resolve the above i2c address overlap +issue and allow SPD autodetection of RAM to work. +
Updating U-boot with U-boot: ============================ diff --git a/include/configs/sbc8548.h b/include/configs/sbc8548.h index 1df2225..44c7526 100644 --- a/include/configs/sbc8548.h +++ b/include/configs/sbc8548.h @@ -119,9 +119,15 @@ /* DDR Setup */ #define CONFIG_FSL_DDR2 #undef CONFIG_FSL_DDR_INTERACTIVE +#undef CONFIG_DDR_ECC /* only for ECC DDR module */ +/* + * A hardware errata caused the LBC SDRAM SPD and the DDR2 SPD + * to collide, meaning you couldn't reliably read either. So + * physically remove the LBC PC100 SDRAM module from the board + * before enabling the two SPD options below. + */ #undef CONFIG_SPD_EEPROM /* Use SPD EEPROM for DDR setup */ #undef CONFIG_DDR_SPD -#undef CONFIG_DDR_ECC /* only for ECC DDR module */
#define CONFIG_ECC_INIT_VIA_DDRCONTROLLER /* DDR controller or DMA? */ #define CONFIG_MEM_INIT_VALUE 0xDeadBeef @@ -283,9 +289,14 @@
/* * SDRAM on the Local Bus (CS3 and CS4) + * Note that most boards have a hardware errata where both the + * LBC SDRAM and the DDR2 SDRAM decode at 0x51, making it impossible + * to use CONFIG_DDR_SPD unless you physically remove the LBC DIMM. */ +#ifndef CONFIG_DDR_SPD #define CONFIG_SYS_LBC_SDRAM_BASE 0xf0000000 /* Localbus SDRAM */ #define CONFIG_SYS_LBC_SDRAM_SIZE 128 /* LBC SDRAM is 128MB */ +#endif
/* * Base Register 3 and Option Register 3 configure the 1st 1/2 SDRAM.

Nothing to see here, just a relocation of the fixed ddr init sequence to live in the actual ddr.c file itself.
Signed-off-by: Paul Gortmaker paul.gortmaker@windriver.com --- board/sbc8548/ddr.c | 48 +++++++++++++++++++++++++++++++++++++++++++++ board/sbc8548/sbc8548.c | 44 ----------------------------------------- include/configs/sbc8548.h | 1 + 3 files changed, 49 insertions(+), 44 deletions(-)
diff --git a/board/sbc8548/ddr.c b/board/sbc8548/ddr.c index 996ffe2..0d9a1ba 100644 --- a/board/sbc8548/ddr.c +++ b/board/sbc8548/ddr.c @@ -54,3 +54,51 @@ void fsl_ddr_board_options(memctl_options_t *popts, */ popts->half_strength_driver_enable = 0; } + +#if !defined(CONFIG_SPD_EEPROM) +/* + * fixed_sdram init -- doesn't use serial presence detect. + * Assumes 256MB DDR2 SDRAM SODIMM, without ECC, running at DDR400 speed. + */ +phys_size_t fixed_sdram(void) +{ + volatile ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC85xx_DDR_ADDR); + + out_be32(&ddr->cs0_bnds, 0x0000007f); + out_be32(&ddr->cs1_bnds, 0x008000ff); + out_be32(&ddr->cs2_bnds, 0x00000000); + out_be32(&ddr->cs3_bnds, 0x00000000); + + out_be32(&ddr->cs0_config, 0x80010101); + out_be32(&ddr->cs1_config, 0x80010101); + out_be32(&ddr->cs2_config, 0x00000000); + out_be32(&ddr->cs3_config, 0x00000000); + + out_be32(&ddr->timing_cfg_3, 0x00000000); + out_be32(&ddr->timing_cfg_0, 0x00220802); + out_be32(&ddr->timing_cfg_1, 0x38377322); + out_be32(&ddr->timing_cfg_2, 0x0fa044C7); + + out_be32(&ddr->sdram_cfg, 0x4300C000); + out_be32(&ddr->sdram_cfg_2, 0x24401000); + + out_be32(&ddr->sdram_mode, 0x23C00542); + out_be32(&ddr->sdram_mode_2, 0x00000000); + + out_be32(&ddr->sdram_interval, 0x05080100); + out_be32(&ddr->sdram_md_cntl, 0x00000000); + out_be32(&ddr->sdram_data_init, 0x00000000); + out_be32(&ddr->sdram_clk_cntl, 0x03800000); + asm("sync;isync;msync"); + udelay(500); + + #ifdef CONFIG_DDR_ECC + /* Enable ECC checking */ + out_be32(&ddr->sdram_cfg, CONFIG_SYS_DDR_CONTROL | 0x20000000); + #else + out_be32(&ddr->sdram_cfg, CONFIG_SYS_DDR_CONTROL); + #endif + + return CONFIG_SYS_SDRAM_SIZE * 1024 * 1024; +} +#endif diff --git a/board/sbc8548/sbc8548.c b/board/sbc8548/sbc8548.c index 96554b2..d1ef3be 100644 --- a/board/sbc8548/sbc8548.c +++ b/board/sbc8548/sbc8548.c @@ -219,50 +219,6 @@ testdram(void) } #endif
-#if !defined(CONFIG_SPD_EEPROM) -#define CONFIG_SYS_DDR_CONTROL 0xc300c000 -/************************************************************************* - * fixed_sdram init -- doesn't use serial presence detect. - * assumes 256MB DDR2 SDRAM SODIMM, without ECC, running at DDR400 speed. - ************************************************************************/ -phys_size_t fixed_sdram(void) -{ - volatile ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC85xx_DDR_ADDR); - - out_be32(&ddr->cs0_bnds, 0x0000007f); - out_be32(&ddr->cs1_bnds, 0x008000ff); - out_be32(&ddr->cs2_bnds, 0x00000000); - out_be32(&ddr->cs3_bnds, 0x00000000); - out_be32(&ddr->cs0_config, 0x80010101); - out_be32(&ddr->cs1_config, 0x80010101); - out_be32(&ddr->cs2_config, 0x00000000); - out_be32(&ddr->cs3_config, 0x00000000); - out_be32(&ddr->timing_cfg_3, 0x00000000); - out_be32(&ddr->timing_cfg_0, 0x00220802); - out_be32(&ddr->timing_cfg_1, 0x38377322); - out_be32(&ddr->timing_cfg_2, 0x0fa044C7); - out_be32(&ddr->sdram_cfg, 0x4300C000); - out_be32(&ddr->sdram_cfg_2, 0x24401000); - out_be32(&ddr->sdram_mode, 0x23C00542); - out_be32(&ddr->sdram_mode_2, 0x00000000); - out_be32(&ddr->sdram_interval, 0x05080100); - out_be32(&ddr->sdram_md_cntl, 0x00000000); - out_be32(&ddr->sdram_data_init, 0x00000000); - out_be32(&ddr->sdram_clk_cntl, 0x03800000); - asm("sync;isync;msync"); - udelay(500); - - #if defined (CONFIG_DDR_ECC) - /* Enable ECC checking */ - out_be32(&ddr->sdram_cfg, CONFIG_SYS_DDR_CONTROL | 0x20000000); - #else - out_be32(&ddr->sdram_cfg, CONFIG_SYS_DDR_CONTROL); - #endif - - return CONFIG_SYS_SDRAM_SIZE * 1024 * 1024; -} -#endif - #ifdef CONFIG_PCI1 static struct pci_controller pci1_hose; #endif /* CONFIG_PCI1 */ diff --git a/include/configs/sbc8548.h b/include/configs/sbc8548.h index 44c7526..09245b5 100644 --- a/include/configs/sbc8548.h +++ b/include/configs/sbc8548.h @@ -148,6 +148,7 @@ */ #ifndef CONFIG_SPD_EEPROM #define CONFIG_SYS_SDRAM_SIZE 256 /* DDR is 256MB */ + #define CONFIG_SYS_DDR_CONTROL 0xc300c000 #endif
#undef CONFIG_CLOCKS_IN_MHZ

Existing boards by default have an issue where the LBC SDRAM SPD EEPROM and the DDR2 SDRAM SPD EEPROM both land at 0x51.
After the hardware modification listed in the README is made, then the DDR2 SPD EEPROM appears at 0x53. So this implements a board specific get_spd() by taking advantage of the existing weak linkage, that 1st tries reading at 0x53 and then if that fails, it falls back to the old 0x51.
Since the old dependency issue of "SPD implies no LBC SDRAM" gets removed with the hardware errata fix, remove that restriction in the code, so both LBC SDRAM and SPD can be selected.
Signed-off-by: Paul Gortmaker paul.gortmaker@windriver.com --- board/sbc8548/ddr.c | 31 ++++++++++++++++++++++++++++++- doc/README.sbc8548 | 20 ++++++++++++++++++-- include/configs/sbc8548.h | 14 ++++++++++---- 3 files changed, 58 insertions(+), 7 deletions(-)
diff --git a/board/sbc8548/ddr.c b/board/sbc8548/ddr.c index 0d9a1ba..45ec485 100644 --- a/board/sbc8548/ddr.c +++ b/board/sbc8548/ddr.c @@ -7,6 +7,7 @@ */
#include <common.h> +#include <i2c.h>
#include <asm/fsl_ddr_sdram.h> #include <asm/fsl_ddr_dimm_params.h> @@ -55,7 +56,35 @@ void fsl_ddr_board_options(memctl_options_t *popts, popts->half_strength_driver_enable = 0; }
-#if !defined(CONFIG_SPD_EEPROM) +#ifdef CONFIG_SPD_EEPROM +/* + * Workaround for hardware errata. An i2c address conflict + * existed on earlier boards; the workaround moved the DDR + * SPD from 0x51 to 0x53. So we try and read 0x53 1st, and + * if that fails, then fall back to reading at 0x51. + */ +void get_spd(generic_spd_eeprom_t *spd, u8 i2c_address) +{ + int ret; + +#ifdef ALT_SPD_EEPROM_ADDRESS + if (i2c_address == SPD_EEPROM_ADDRESS) { + ret = i2c_read(ALT_SPD_EEPROM_ADDRESS, 0, 1, (uchar *)spd, + sizeof(generic_spd_eeprom_t)); + if (ret == 0) + return; /* Good data at 0x53 */ + memset(spd, 0, sizeof(generic_spd_eeprom_t)); + } +#endif + ret = i2c_read(i2c_address, 0, 1, (uchar *)spd, + sizeof(generic_spd_eeprom_t)); + if (ret) { + printf("DDR: failed to read SPD from addr %u\n", i2c_address); + memset(spd, 0, sizeof(generic_spd_eeprom_t)); + } +} + +#else /* * fixed_sdram init -- doesn't use serial presence detect. * Assumes 256MB DDR2 SDRAM SODIMM, without ECC, running at DDR400 speed. diff --git a/doc/README.sbc8548 b/doc/README.sbc8548 index f9e2dea..0f3f543 100644 --- a/doc/README.sbc8548 +++ b/doc/README.sbc8548 @@ -71,7 +71,22 @@ EEPROM data to read what memory is installed.
There is a hardware errata, which causes the older local bus SDRAM SPD EEPROM to land at the same address as the DDR2 SPD EEPROM, so -that the SPD data can not be read reliably. +that the SPD data can not be read reliably. You can test if your +board has the errata fix by running "i2c probe". If you see 0x53 +as a valid device, it has been fixed. If you only see 0x50, 0x51 +then your board does not have the fix. + +You can also visually inspect the board to see if this hardware +fix has been applied: + + 1) Remove R314 (RES-R0174-033, 1K, 0603). R314 is located on + the back of the PCB behind the DDR SDRAM SODIMM connector. + 2) Solder RES-R0174-033 (1K, 0603) resistor from R314 pin 2 pad + to R313 pin 2. Pin 2 for each resistor is the end of the + resistor closest to the CPU. + +Boards without the mod will have R314 and R313 in parallel, like "||". +After the mod, they will be touching and form an "L" shape.
If you want to upgrade to larger RAM size, you can simply enable #define CONFIG_SPD_EEPROM @@ -79,7 +94,8 @@ If you want to upgrade to larger RAM size, you can simply enable in include/configs/sbc8548.h file. (The lines are already there but listed as #undef).
-Note that you will have to physically remove the LBC 128MB DIMM +If you did the i2c test, and your board does not have the errata +fix, then you will have to physically remove the LBC 128MB DIMM from the board's socket to resolve the above i2c address overlap issue and allow SPD autodetection of RAM to work.
diff --git a/include/configs/sbc8548.h b/include/configs/sbc8548.h index 09245b5..d87394c 100644 --- a/include/configs/sbc8548.h +++ b/include/configs/sbc8548.h @@ -124,7 +124,9 @@ * A hardware errata caused the LBC SDRAM SPD and the DDR2 SPD * to collide, meaning you couldn't reliably read either. So * physically remove the LBC PC100 SDRAM module from the board - * before enabling the two SPD options below. + * before enabling the two SPD options below, or check that you + * have the hardware fix on your board via "i2c probe" and looking + * for a device at 0x53. */ #undef CONFIG_SPD_EEPROM /* Use SPD EEPROM for DDR setup */ #undef CONFIG_DDR_SPD @@ -140,8 +142,13 @@ #define CONFIG_DIMM_SLOTS_PER_CTLR 1 #define CONFIG_CHIP_SELECTS_PER_CTRL 2
-/* I2C addresses of SPD EEPROMs */ +/* + * The hardware fix for the I2C address collision puts the DDR + * SPD at 0x53, but if we are running on an older board w/o the + * fix, it will still be at 0x51. We check 0x53 1st. + */ #define SPD_EEPROM_ADDRESS 0x51 /* CTLR 0 DIMM 0 */ +#define ALT_SPD_EEPROM_ADDRESS 0x53 /* CTLR 0 DIMM 0 */
/* * Make sure required options are set @@ -293,11 +300,10 @@ * Note that most boards have a hardware errata where both the * LBC SDRAM and the DDR2 SDRAM decode at 0x51, making it impossible * to use CONFIG_DDR_SPD unless you physically remove the LBC DIMM. + * A hardware workaround is also available, see README.sbc8548 file. */ -#ifndef CONFIG_DDR_SPD #define CONFIG_SYS_LBC_SDRAM_BASE 0xf0000000 /* Localbus SDRAM */ #define CONFIG_SYS_LBC_SDRAM_SIZE 128 /* LBC SDRAM is 128MB */ -#endif
/* * Base Register 3 and Option Register 3 configure the 1st 1/2 SDRAM.

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 --- board/sbc8548/sbc8548.c | 38 +++++++++++++++++++++++++++++++++++--- 1 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/board/sbc8548/sbc8548.c b/board/sbc8548/sbc8548.c index d1ef3be..371d076 100644 --- a/board/sbc8548/sbc8548.c +++ b/board/sbc8548/sbc8548.c @@ -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 */ }

On Dec 30, 2011, at 10:53 PM, Paul Gortmaker wrote:
This updates the sbc8548 board support with several improvements for the end users.
-ability to use SPD DDR config for easy RAM upgrades -ability to use alternate SODIMM flash for backup u-boot image -localbus config settings fixed so 128MB LBC SDRAM works reliably
The discovery of a hardware errata (overlapping I2C SPD addresses) is at the core of what now allows the use of SPD configuration.
The relocation of the 64MB user flash is to align it on a 64MB boundary, which simplifies a whole lot of things, both in the code and for the end user. (The previous mapping meant the last sector on the chip wasn't consistently the last sector in the address space assigned to the chip for all jumper configurations.)
Reverting a bogus commit from the past that incorrectly set the windows for the 64MB flash to 128MB was the starting point for getting this all working.
Paul.
The following changes since commit cba9a894fdb1cb49b60fcd1d1d6919cbd7995dd5:
Prepare v2011.12 (2011-12-23 20:25:35 +0100)
are available in the git repository at: git://openlinux.windriver.com/people/paulg/u-boot sbc8548-Dec30_2011
Paul Gortmaker (8): Revert "SBC8548: fix address mask to allow 64M flash" sbc8548: relocate 64MB user flash to sane boundary sbc8548: enable ability to boot from alternate flash sbc8548: Fix LBC SDRAM initialization settings sbc8548: Make enabling SPD RAM configuration work sbc8548: relocate fixed ddr init code to ddr.c file sbc8548: enable support for hardware SPD errata workaround sbc8548: Fix up local bus init to be frequency aware
board/sbc8548/ddr.c | 77 +++++++++++++++++++++++ board/sbc8548/law.c | 16 +++++- board/sbc8548/sbc8548.c | 111 +++++++++++++++------------------ board/sbc8548/tlb.c | 24 ++++++-- doc/README.sbc8548 | 79 ++++++++++++++++++++++-- include/configs/sbc8548.h | 151 +++++++++++++++++++++++++++++++++++---------- 6 files changed, 355 insertions(+), 103 deletions(-)
--
applied to 85xx
- k
participants (2)
-
Kumar Gala
-
Paul Gortmaker