sbc8548: enable support for hardware SPD errata workaround
authorPaul Gortmaker <paul.gortmaker@windriver.com>
Sat, 31 Dec 2011 04:53:12 +0000 (23:53 -0500)
committerKumar Gala <galak@kernel.crashing.org>
Wed, 11 Jan 2012 19:59:14 +0000 (13:59 -0600)
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>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
board/sbc8548/ddr.c
doc/README.sbc8548
include/configs/sbc8548.h

index 0d9a1ba62b7e6a02471cc7a716cf8ff4ac55e246..45ec485c50b88a48a2bebdea1b80ff47508e8248 100644 (file)
@@ -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.
index f9e2dea573c980e1896c026cb3f8f041c05d0d83..0f3f5432f2656ac6dcb4407cb29afaa68bf6fdca 100644 (file)
@@ -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.
 
index 09245b5b0ca3febd4bf494f99dc9e7b559f92b4e..d87394c8d11f926820fde8463e1f0c664682c215 100644 (file)
  * 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
 #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
  * 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.