[U-Boot] [RFC] mpc83xx: add config options to spd_sdram

Andre Schwarz andre.schwarz at matrix-vision.de
Tue Apr 5 11:49:49 CEST 2011


Kim,

I have made some mods to spd_sdram.c for various reason:

1.
use SPD setup also for soldered RAM.
This allows DDR mounting options without U-Boot change because SPD data
is written during in-circuit/boundary-scan testing.

2.
read SPD data also from extended adressing EEPROMS used for e.g. HRCW 
storage.
Due to HRCW being being located at offset 0 we need an SPD data offset.

3.
for optimized signal integrity and power consumption we need more 
influence on
the on-die termination. Although the assumed default values are working they
are far from ideal.

4.
CPO values depend on internal bond wire length which has significantly
high variance on MPC837x, i.e. this value also should be board specific.


I have taken care not to increase code size and not to break existing 
boards.

Any comments from your side ?
Is this something you might ACK ?


Regards,
André


diff --git a/arch/powerpc/cpu/mpc83xx/spd_sdram.c 
b/arch/powerpc/cpu/mpc83xx/spd_sdram.c
index 44aaa9a..7d10c8c 100644
--- a/arch/powerpc/cpu/mpc83xx/spd_sdram.c
+++ b/arch/powerpc/cpu/mpc83xx/spd_sdram.c
@@ -68,6 +68,12 @@ void board_add_ram_info(int use_default)
  #ifndef    CONFIG_SYS_READ_SPD
  #define CONFIG_SYS_READ_SPD    i2c_read
  #endif
+#ifndef SPD_EEPROM_OFFSET
+#define SPD_EEPROM_OFFSET    0
+#endif
+#ifndef SPD_EEPROM_ADDR_LEN
+#define SPD_EEPROM_ADDR_LEN     1
+#endif

  /*
   * Convert picoseconds into clock cycles (rounding up if needed).
@@ -160,7 +166,8 @@ long int spd_sdram()
      isync();

      /* Read SPD parameters with I2C */
-    CONFIG_SYS_READ_SPD(SPD_EEPROM_ADDRESS, 0, 1, (uchar *) & spd, 
sizeof (spd));
+    CONFIG_SYS_READ_SPD(SPD_EEPROM_ADDRESS, SPD_EEPROM_OFFSET,
+        SPD_EEPROM_ADDR_LEN, (uchar *) & spd, sizeof (spd));
  #ifdef SPD_DEBUG
      spd_debug(&spd);
  #endif
@@ -562,6 +569,9 @@ long int spd_sdram()
       * Empirically, 0x3 == 6/8 clock delay is suggested for DDR I 266.
       */
      wr_data_delay = 2;
+#ifdef CONFIG_SYS_DDR_WRITE_DATA_DELAY
+    wr_data_delay = CONFIG_SYS_DDR_WRITE_DATA_DELAY;
+#endif

      /*
       * Write Latency
@@ -601,6 +611,9 @@ long int spd_sdram()
       */
      cpo = 0;
      if (spd.mem_type == SPD_MEMTYPE_DDR2) {
+#ifdef CONFIG_SYS_DDR_CPO
+        cpo = CONFIG_SYS_DDR_CPO;
+#else
          if (effective_data_rate == 266) {
              cpo = 0x4;        /* READ_LAT + 1/2 */
          } else if (effective_data_rate == 333) {
@@ -611,6 +624,7 @@ long int spd_sdram()
              /* Automatic calibration */
              cpo = 0x1f;
          }
+#endif
      }

      ddr->timing_cfg_2 = (0
@@ -673,12 +687,23 @@ long int spd_sdram()
               * Bit 2 == 0x04 == 75 Ohm, with 2 DIMM modules.
               * Bit 6 == 0x40 == 150 Ohm, with 1 DIMM module.
               */
+#if defined(CONFIG_SYS_DDR_MODE_ODT_OFF)
+            mode_odt_enable = 0x00;         /* disabled */
+#elif defined(CONFIG_SYS_DDR_MODE_ODT_50)
+            mode_odt_enable = 0x44;         /*  50 Ohm */
+#elif defined(CONFIG_SYS_DDR_MODE_ODT_75)
+            mode_odt_enable = 0x04;         /*  75 Ohm */
+#else
              mode_odt_enable = 0x40;         /* 150 Ohm */
+#endif
          }

          ddr->sdram_mode =
              (0
               | (1 << (16 + 10))             /* DQS Differential disable */
+#ifdef CONFIG_SYS_DDR_MODE_WEAK
+             | (1 << (16 + 1))        /* weak driver (~60%) */
+#endif
               | (add_lat << (16 + 3))        /* Additive Latency in 
EMRS1 */
               | (mode_odt_enable << 16)      /* ODT Enable in EMRS1 */
               | ((twr_clk - 1) << 9)         /* Write Recovery Autopre */
@@ -740,6 +765,9 @@ long int spd_sdram()
          odt_cfg = 0x2;        /* ODT to IOs during reads */
      }
  #endif
+#ifdef CONFIG_ALWAYS_ASSERT_ODT_TO_CPU
+    odt_cfg = 0x3;        /* ODT always on */
+#endif
      if (spd.mem_type == SPD_MEMTYPE_DDR2) {
          ddr->sdram_cfg2 = (0
                  | (0 << 26)    /* True DQS */
@@ -779,10 +807,12 @@ long int spd_sdram()
          sdram_type = SDRAM_CFG_SDRAM_TYPE_DDR2;

      sdram_cfg = (0
-             | SDRAM_CFG_MEM_EN        /* DDR enable */
               | SDRAM_CFG_SREN        /* Self refresh */
               | sdram_type        /* SDRAM type */
               );
+#ifdef CONFIG_DDR_HALF_STRENGTH
+    sdram_cfg |= SDRAM_CFG_HSE;
+#endif

      /* sdram_cfg[3] = RD_EN - registered DIMM enable */
      if (spd.mod_attr & 0x02)
@@ -822,6 +852,7 @@ long int spd_sdram()
       */
      sdram_cfg |= SDRAM_CFG_2T_EN;
  #endif
+    sdram_cfg |= SDRAM_CFG_MEM_EN;
      /* Enable controller, and GO! */
      ddr->sdram_cfg = sdram_cfg;
      asm("sync;isync");

MATRIX VISION GmbH, Talstrasse 16, DE-71570 Oppenweiler
Registergericht: Amtsgericht Stuttgart, HRB 271090
Geschaeftsfuehrer: Gerhard Thullner, Werner Armingeon, Uwe Furtner


More information about the U-Boot mailing list