Somehow we need 1.39V for the 4GB DDR3 to work reliably. No idea so far why this is though. --- board/goldelico/letux-cortex15/lc15.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
diff --git a/board/goldelico/letux-cortex15/lc15.c b/board/goldelico/letux-cortex15/lc15.c --- a/board/goldelico/letux-cortex15/lc15.c +++ b/board/goldelico/letux-cortex15/lc15.c @@ -248,6 +248,8 @@ static void simple_ram_test(void) printf("WARNING: DDR RAM is not working! (%x)\n", v[0]); }
+#define SMPS6_VOLTAGE 0x2f + int board_mmc_init(bd_t *bis) { int hard_select = 7; /* gpio to select uSD (0) or eMMC (1) by external hw signal */ @@ -256,6 +258,23 @@ int board_mmc_init(bd_t *bis)
int val; /* is the value of soft_select gpio after processing */
+#ifdef CONFIG_DUAL_RANK_DDR3 + int err; + + /* + * REVISIT: Somehow the 4GB K4B8G1646D-MYK0 part needs SMPS9 voltage + * set to 1.39V (0x5f) instead of 1.35V (0x5d) with 1.37V (0x5d) + * also being flakey. + */ + if (running_from_sdram()) { + err = palmas_i2c_write_u8(TWL603X_CHIP_P1, + SMPS6_VOLTAGE, 0x5f); + if (err) + printf("Could not raise SMPS9 voltage for DDR3: %i\n", + err); + } +#endif + simple_ram_test(); int vers = get_board_version(); #if 1
Based on igepv5 u-boot commit 4521f304a913 ("IGEPv5: Modify lisa_regs structure, added ma_hm_interleave variable") by Manel Caro mcaro@iseebcn.com, we need to configure interleaving for 4GB DDR3 to work properly. --- arch/arm/cpu/armv7/omap-common/emif-common.c | 5 +++++ arch/arm/include/asm/emif.h | 1 + board/goldelico/letux-cortex15/lc15.c | 14 ++++++++++++++ 3 files changed, 20 insertions(+)
diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c --- a/arch/arm/cpu/armv7/omap-common/emif-common.c +++ b/arch/arm/cpu/armv7/omap-common/emif-common.c @@ -1339,6 +1339,11 @@ void dmm_init(u32 base) &hw_lisa_map_regs->dmm_lisa_map_0);
setbits_le32(MA_PRIORITY, MA_HIMEM_INTERLEAVE_UN_MASK); + + /* MA_PRIORITY[8] HIMEM_INTERLEAVE_UN bit to 0x1 */ + if (lisa_map_regs->is_ma_hm_interleave) + __raw_writel(__raw_readl(MA_PRIORITY) | + (1 << 8) , MA_PRIORITY); }
/* diff --git a/arch/arm/include/asm/emif.h b/arch/arm/include/asm/emif.h --- a/arch/arm/include/asm/emif.h +++ b/arch/arm/include/asm/emif.h @@ -756,6 +756,7 @@ struct dmm_lisa_map_regs { u32 dmm_lisa_map_2; u32 dmm_lisa_map_3; u8 is_ma_present; + u8 is_ma_hm_interleave; };
#define CS0 0 diff --git a/board/goldelico/letux-cortex15/lc15.c b/board/goldelico/letux-cortex15/lc15.c --- a/board/goldelico/letux-cortex15/lc15.c +++ b/board/goldelico/letux-cortex15/lc15.c @@ -78,6 +78,20 @@ void dram_init_banksize(void) /* report 4 GB during boot */ gd->ram_size = gd->bd->bi_dram[0].size + gd->bd->bi_dram[1].size; } + +const struct dmm_lisa_map_regs lisa_map_pyra_4g = { + .dmm_lisa_map_0 = 0x0, + .dmm_lisa_map_1 = 0x0, + .dmm_lisa_map_2 = 0x80740300, + .dmm_lisa_map_3 = 0xFF020100, + .is_ma_present = 0x1, + .is_ma_hm_interleave = 0x1, +}; + +void emif_get_dmm_regs(const struct dmm_lisa_map_regs **dmm_lisa_regs) +{ + *dmm_lisa_regs = &lisa_map_pyra_4g; +} #endif
/*
I dumped these out from igepv5 u-boot and they seem to work for pyra-4g. Need to figure out why they work.. I left the original timings ifdeffed out to make it easy to compare.
Note that I also booted LPAE kernel using the igepv5 memory config: mem=2032M@0x80000000 mem=2048M@0x300000000
I think Matthijs was using 0x200000000? --- board/goldelico/letux-cortex15/lc15.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
diff --git a/board/goldelico/letux-cortex15/lc15.c b/board/goldelico/letux-cortex15/lc15.c --- a/board/goldelico/letux-cortex15/lc15.c +++ b/board/goldelico/letux-cortex15/lc15.c @@ -37,6 +37,7 @@ const struct omap_sysinfo sysinfo = { */
const struct emif_regs emif_regs_ddr3_532_mhz_2cs_es2 = { +#if 0 .sdram_config_init = 0x61851B3A, .sdram_config = 0x61851B3A, .sdram_config2 = 0x0, @@ -58,6 +59,29 @@ const struct emif_regs emif_regs_ddr3_532_mhz_2cs_es2 = { .emif_rd_wr_lvl_rmp_ctl = 0x80000000, .emif_rd_wr_lvl_ctl = 0x00000000, .emif_rd_wr_exec_thresh = 0x40000305 +#endif + + .sdram_config_init = 0x61851b32, + .sdram_config = 0x61851b32, + .sdram_config2 = 0x00000000, + .ref_ctrl = 0x00001035, + .sdram_tim1 = 0xcccf36b3, + .sdram_tim2 = 0x308f7fda, + .sdram_tim3 = 0x027f88a8, + .read_idle_ctrl = 0x00050000, + .zq_config = 0x5007190b, + .temp_alert_config = 0x00000000, + .emif_ddr_phy_ctlr_1_init = 0x0030400a, + .emif_ddr_phy_ctlr_1 = 0x0034400a, + .emif_ddr_ext_phy_ctrl_1 = 0x04040100, + .emif_ddr_ext_phy_ctrl_2 = 0x00000000, + .emif_ddr_ext_phy_ctrl_3 = 0x00000000, + .emif_ddr_ext_phy_ctrl_4 = 0x00000000, + .emif_ddr_ext_phy_ctrl_5 = 0x4350d435, + .emif_rd_wr_lvl_rmp_win = 0x00000000, + .emif_rd_wr_lvl_rmp_ctl = 0x80000000, + .emif_rd_wr_lvl_ctl = 0x00000000, + .emif_rd_wr_exec_thresh = 0x40000305, };
void emif_get_reg_dump(u32 emif_nr, const struct emif_regs **regs) @@ -82,8 +106,13 @@ void dram_init_banksize(void) const struct dmm_lisa_map_regs lisa_map_pyra_4g = { .dmm_lisa_map_0 = 0x0, .dmm_lisa_map_1 = 0x0, +#if 0 .dmm_lisa_map_2 = 0x80740300, .dmm_lisa_map_3 = 0xFF020100, +#endif + .dmm_lisa_map_2 = 0x807c0300, + .dmm_lisa_map_3 = 0xff020100, + .is_ma_present = 0x1, .is_ma_hm_interleave = 0x1, };
On 14 August 2017 at 06:43, Tony Lindgren tony@atomide.com wrote:
+#if 0 .sdram_config_init = 0x61851B3A, .sdram_config = 0x61851B3A, ... +#endif
.sdram_config_init = 0x61851b32,
.sdram_config = 0x61851b32,
uhh?? bit 3 configures whether there is 1 rank or 2 ranks...
* Matthijs van Duin matthijsvanduin@gmail.com [170814 02:36]:
On 14 August 2017 at 06:43, Tony Lindgren tony@atomide.com wrote:
+#if 0 .sdram_config_init = 0x61851B3A, .sdram_config = 0x61851B3A, ... +#endif
.sdram_config_init = 0x61851b32,
.sdram_config = 0x61851b32,
uhh?? bit 3 configures whether there is 1 rank or 2 ranks...
Yeh no idea so far, your settings seem more correct, this is just the raw dump from igepv5 that happens to work..
Maybe bit 3 means two ranks per emif instance here?
Regards,
Tony
* Tony Lindgren tony@atomide.com [170814 07:11]:
- Matthijs van Duin matthijsvanduin@gmail.com [170814 02:36]:
On 14 August 2017 at 06:43, Tony Lindgren tony@atomide.com wrote:
+#if 0 .sdram_config_init = 0x61851B3A, .sdram_config = 0x61851B3A, ... +#endif
.sdram_config_init = 0x61851b32,
.sdram_config = 0x61851b32,
uhh?? bit 3 configures whether there is 1 rank or 2 ranks...
Yeh no idea so far, your settings seem more correct, this is just the raw dump from igepv5 that happens to work..
Maybe bit 3 means two ranks per emif instance here?
The data sheet "3.2 Stacked / Dual - die DDR3 SDRAM x16 Ballout" seems show just one chip select per die? One die per emif?
Regards,
Tony
On 14 August 2017 at 16:11, Tony Lindgren tony@atomide.com wrote:
Maybe bit 3 means two ranks per emif instance here?
Um, yes? All emif settings are per emif instance obviously (although both of them are configured the same).
On 14 August 2017 at 16:27, Tony Lindgren tony@atomide.com wrote:
The data sheet "3.2 Stacked / Dual - die DDR3 SDRAM x16 Ballout" seems show just one chip select per die?
That's why it's called "chip select".
One die per emif?
Four dies per emif. Each emif has two chip select lines (ranks), and moreover there are two 16-bit dual-rank ram devices side by side since each emif has a 32-bit data bus.
See figure 15-46 on page 3403 of the public TRM (SWPU249AF). Figure 7-48 on page 331 of the datasheet (SWPS051K) is also useful.
* Matthijs van Duin matthijsvanduin@gmail.com [170814 07:47]:
On 14 August 2017 at 16:11, Tony Lindgren tony@atomide.com wrote:
Maybe bit 3 means two ranks per emif instance here?
Um, yes? All emif settings are per emif instance obviously (although both of them are configured the same).
On 14 August 2017 at 16:27, Tony Lindgren tony@atomide.com wrote:
The data sheet "3.2 Stacked / Dual - die DDR3 SDRAM x16 Ballout" seems show just one chip select per die?
That's why it's called "chip select".
One die per emif?
Four dies per emif. Each emif has two chip select lines (ranks), and moreover there are two 16-bit dual-rank ram devices side by side since each emif has a 32-bit data bus.
OK I trust you there. Weird that it works at all with just one chip select configured..
See figure 15-46 on page 3403 of the public TRM (SWPU249AF). Figure 7-48 on page 331 of the datasheet (SWPS051K) is also useful.
Yeah I was looking at that but the fact it works got me doubting everything.
Regards,
Tony
On 14 August 2017 at 18:10, Tony Lindgren tony@atomide.com wrote:
OK I trust you there. Weird that it works at all with just one chip select configured..
That makes no sense to me, I'd expect this config to result in the upper 2G being an alias of the lower 2G. Any chance it might just be working by accident because only a small portion of the memory is actually being used?
* Matthijs van Duin matthijsvanduin@gmail.com [170814 09:15]:
On 14 August 2017 at 18:10, Tony Lindgren tony@atomide.com wrote:
OK I trust you there. Weird that it works at all with just one chip select configured..
That makes no sense to me, I'd expect this config to result in the upper 2G being an alias of the lower 2G. Any chance it might just be working by accident because only a small portion of the memory is actually being used?
Yes totally. I continued trying to boil down the minimal changes and was running two instances of memtester 1500M with just the following changes:
1. smps6 set to 1.41V (0x61)
And the kernel also set to the same voltage in the dts. No idea what the voltage should be really at this point..
2. Termination changed to 0
So your original ddr3 config with just termination changed, no mem kernel command line option. I'm seeing hangs pretty easily with two instances of memtester 1500M running, and have not tested yet if what I had yesterday is any better. Patch below for reference.
I've noticed that if I wait 10 seconds with power completely off, booting to u-boot works more reliably. So there may be some temperature issue or a wait missing somewhere after register writes.
Later,
Tony
8< ---------------- --- a/board/goldelico/letux-cortex15/lc15.c +++ b/board/goldelico/letux-cortex15/lc15.c @@ -37,8 +37,8 @@ const struct omap_sysinfo sysinfo = { */
const struct emif_regs emif_regs_ddr3_532_mhz_2cs_es2 = { - .sdram_config_init = 0x61851B3A, - .sdram_config = 0x61851B3A, + .sdram_config_init = 0x60851B3A, + .sdram_config = 0x60851B3A, .sdram_config2 = 0x0, .ref_ctrl = 0x00001035, .sdram_tim1 = 0xCCCF36B3,