[PATCH v2 0/5] board: verdin-imx8mp: ddr updates

From: Marcel Ziswiler marcel.ziswiler@toradex.com
This series contains the following DDR updates:
- update ddrc config for different lpddr4 memories - fix lpddr4 refresh timing - update lpddr4 configuration and training - compact slight different lpddr4 configuration - change prints in spl_dram_init function
Changes in v2: - Use puts rather than printf in the SPL as suggested by Fabio. Thanks!
Emanuele Ghidoli (5): board: verdin-imx8mp: update ddrc config for different lpddr4 memories board: verdin-imx8mp: fix lpddr4 refresh timing board: verdin-imx8mp: update lpddr4 configuration and training board: verdin-imx8mp: compact slight different lpddr4 configuration board: verdin-imx8mp: change prints in spl_dram_init function
board/toradex/verdin-imx8mp/lpddr4_timing.c | 423 ++++---------------- board/toradex/verdin-imx8mp/lpddr4_timing.h | 11 + board/toradex/verdin-imx8mp/spl.c | 19 +- 3 files changed, 106 insertions(+), 347 deletions(-) create mode 100644 board/toradex/verdin-imx8mp/lpddr4_timing.h

From: Emanuele Ghidoli emanuele.ghidoli@toradex.com
Add support to Verdin IMX8MP V1.1B SKU which uses MT53E1G32D2FW-046 WT:B memory. Compared to the 8 GB memory (MT53E2G32D4NQ-046 WT:A) used on Verdin IMX8MP V1.0A it has 16 row addresses instead of 17. In fact, the new memory, is a 2 GB/rank memory. The 8 GB memory is a 4 GB/rank memory.
Manually tweaking Host Interface addresses vs LPDDR4 signals mapping it is possible to have a single configuration working with both memories: - Old configuration: HIF bit 30 -> rank, HIF bit 29 -> Row 16 - New configuration: HIF bit 29 -> rank, HIF bit 30 -> Row 16
With this change the memory space from the host processor is contiguous for both the configurations and the correct memory size is computed using get_ram_size() at runtime.
Support for single rank memories still works thanks to the fact dual ranks training fails (ddr_init->ddr_cfg_phy) toward single rank memories.
Signed-off-by: Emanuele Ghidoli emanuele.ghidoli@toradex.com Signed-off-by: Marcel Ziswiler marcel.ziswiler@toradex.com ---
(no changes since v1)
board/toradex/verdin-imx8mp/lpddr4_timing.c | 4 ++-- board/toradex/verdin-imx8mp/spl.c | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/board/toradex/verdin-imx8mp/lpddr4_timing.c b/board/toradex/verdin-imx8mp/lpddr4_timing.c index 3e00d9b51e1..314b74e7df2 100644 --- a/board/toradex/verdin-imx8mp/lpddr4_timing.c +++ b/board/toradex/verdin-imx8mp/lpddr4_timing.c @@ -55,13 +55,13 @@ struct dram_cfg_param ddr_ddrc_cfg[] = { { 0x3d4001c4, 0x1 }, { 0x3d4000f4, 0xc99 }, { 0x3d400108, 0x9121c1c }, - { 0x3d400200, 0x18 }, + { 0x3d400200, 0x17 }, { 0x3d40020c, 0x0 }, { 0x3d400210, 0x1f1f }, { 0x3d400204, 0x80808 }, { 0x3d400214, 0x7070707 }, { 0x3d400218, 0x7070707 }, - { 0x3d40021c, 0xf07 }, + { 0x3d40021c, 0xf08 }, { 0x3d400250, 0x1705 }, { 0x3d400254, 0x2c }, { 0x3d40025c, 0x4000030 }, diff --git a/board/toradex/verdin-imx8mp/spl.c b/board/toradex/verdin-imx8mp/spl.c index ea99e370850..7b383cc0d53 100644 --- a/board/toradex/verdin-imx8mp/spl.c +++ b/board/toradex/verdin-imx8mp/spl.c @@ -34,11 +34,10 @@ int spl_board_boot_device(enum boot_device boot_dev_spl) void spl_dram_init(void) { /* - * try configuring for quad die, dual rank aka 8 GB falling back to - * dual die, single rank aka 1 GB (untested), 2 GB or 4 GB if it fails + * Try configuring for dual rank memory falling back to single rank */ if (ddr_init(&dram_timing)) { - printf("Quad die, dual rank failed, attempting dual die, single rank configuration.\n"); + printf("Dual rank failed, attempting single rank configuration.\n"); ddr_init(&dram_timing2); } }

From: Emanuele Ghidoli emanuele.ghidoli@toradex.com Add support to Verdin IMX8MP V1.1B SKU which uses MT53E1G32D2FW-046 WT:B memory. Compared to the 8 GB memory (MT53E2G32D4NQ-046 WT:A) used on Verdin IMX8MP V1.0A it has 16 row addresses instead of 17. In fact, the new memory, is a 2 GB/rank memory. The 8 GB memory is a 4 GB/rank memory. Manually tweaking Host Interface addresses vs LPDDR4 signals mapping it is possible to have a single configuration working with both memories:
- Old configuration: HIF bit 30 -> rank, HIF bit 29 -> Row 16
- New configuration: HIF bit 29 -> rank, HIF bit 30 -> Row 16
With this change the memory space from the host processor is contiguous for both the configurations and the correct memory size is computed using get_ram_size() at runtime. Support for single rank memories still works thanks to the fact dual ranks training fails (ddr_init->ddr_cfg_phy) toward single rank memories. Signed-off-by: Emanuele Ghidoli emanuele.ghidoli@toradex.com Signed-off-by: Marcel Ziswiler marcel.ziswiler@toradex.com
Applied to u-boot-imx, next, thanks !
Best regards, Stefano Babic

From: Emanuele Ghidoli emanuele.ghidoli@toradex.com
Change tRFCmin (tRFCab) from 280 ns to 380 ns to be compliant with current and futures memories.
Fixes: 2bc2f817cea7 ("board: toradex: add verdin imx8m plus support")
Signed-off-by: Emanuele Ghidoli emanuele.ghidoli@toradex.com Signed-off-by: Marcel Ziswiler marcel.ziswiler@toradex.com ---
(no changes since v1)
board/toradex/verdin-imx8mp/lpddr4_timing.c | 24 ++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/board/toradex/verdin-imx8mp/lpddr4_timing.c b/board/toradex/verdin-imx8mp/lpddr4_timing.c index 314b74e7df2..58278d2150a 100644 --- a/board/toradex/verdin-imx8mp/lpddr4_timing.c +++ b/board/toradex/verdin-imx8mp/lpddr4_timing.c @@ -21,7 +21,7 @@ struct dram_cfg_param ddr_ddrc_cfg[] = { { 0x3d400000, 0xa3080020 }, { 0x3d400020, 0x1303 }, { 0x3d400024, 0x1e84800 }, - { 0x3d400064, 0x7a0118 }, + { 0x3d400064, 0x7a017c }, { 0x3d400070, 0x61027f10 }, { 0x3d400074, 0x7b0 }, { 0x3d4000d0, 0xc00307a3 }, @@ -39,7 +39,7 @@ struct dram_cfg_param ddr_ddrc_cfg[] = { { 0x3d40011c, 0x501 }, { 0x3d400130, 0x20800 }, { 0x3d400134, 0xe100002 }, - { 0x3d400138, 0x120 }, + { 0x3d400138, 0x184 }, { 0x3d400144, 0xc80064 }, { 0x3d400180, 0x3e8001e }, { 0x3d400184, 0x3207a12 }, @@ -77,7 +77,7 @@ struct dram_cfg_param ddr_ddrc_cfg[] = { { 0x3d402020, 0x1001 }, { 0x3d402024, 0x30d400 }, { 0x3d402050, 0x20d000 }, - { 0x3d402064, 0xc001c }, + { 0x3d402064, 0xc0026 }, { 0x3d4020dc, 0x840000 }, { 0x3d4020e0, 0x330000 }, { 0x3d4020e8, 0x660048 }, @@ -92,7 +92,7 @@ struct dram_cfg_param ddr_ddrc_cfg[] = { { 0x3d40211c, 0x301 }, { 0x3d402130, 0x20300 }, { 0x3d402134, 0xa100002 }, - { 0x3d402138, 0x1d }, + { 0x3d402138, 0x27 }, { 0x3d402144, 0x14000a }, { 0x3d402180, 0x640004 }, { 0x3d402190, 0x3818200 }, @@ -102,7 +102,7 @@ struct dram_cfg_param ddr_ddrc_cfg[] = { { 0x3d403020, 0x1001 }, { 0x3d403024, 0xc3500 }, { 0x3d403050, 0x20d000 }, - { 0x3d403064, 0x30007 }, + { 0x3d403064, 0x3000a }, { 0x3d4030dc, 0x840000 }, { 0x3d4030e0, 0x330000 }, { 0x3d4030e8, 0x660048 }, @@ -117,7 +117,7 @@ struct dram_cfg_param ddr_ddrc_cfg[] = { { 0x3d40311c, 0x301 }, { 0x3d403130, 0x20300 }, { 0x3d403134, 0xa100002 }, - { 0x3d403138, 0x8 }, + { 0x3d403138, 0xa }, { 0x3d403144, 0x50003 }, { 0x3d403180, 0x190004 }, { 0x3d403190, 0x3818200 }, @@ -1841,7 +1841,7 @@ struct dram_cfg_param ddr_ddrc_cfg2[] = { { 0x3d400000, 0xa1080020 }, { 0x3d400020, 0x1303 }, { 0x3d400024, 0x1e84800 }, - { 0x3d400064, 0x7a0118 }, + { 0x3d400064, 0x7a017c }, { 0x3d400070, 0x61027f10 }, { 0x3d400074, 0x7b0 }, { 0x3d4000d0, 0xc00307a3 }, @@ -1859,7 +1859,7 @@ struct dram_cfg_param ddr_ddrc_cfg2[] = { { 0x3d40011c, 0x501 }, { 0x3d400130, 0x20800 }, { 0x3d400134, 0xe100002 }, - { 0x3d400138, 0x120 }, + { 0x3d400138, 0x184 }, { 0x3d400144, 0xc80064 }, { 0x3d400180, 0x3e8001e }, { 0x3d400184, 0x3207a12 }, @@ -1897,7 +1897,7 @@ struct dram_cfg_param ddr_ddrc_cfg2[] = { { 0x3d402020, 0x1001 }, { 0x3d402024, 0x30d400 }, { 0x3d402050, 0x20d000 }, - { 0x3d402064, 0xc001c }, + { 0x3d402064, 0xc0026 }, { 0x3d4020dc, 0x840000 }, { 0x3d4020e0, 0x330000 }, { 0x3d4020e8, 0x660048 }, @@ -1912,7 +1912,7 @@ struct dram_cfg_param ddr_ddrc_cfg2[] = { { 0x3d40211c, 0x301 }, { 0x3d402130, 0x20300 }, { 0x3d402134, 0xa100002 }, - { 0x3d402138, 0x1d }, + { 0x3d402138, 0x27 }, { 0x3d402144, 0x14000a }, { 0x3d402180, 0x640004 }, { 0x3d402190, 0x3818200 }, @@ -1922,7 +1922,7 @@ struct dram_cfg_param ddr_ddrc_cfg2[] = { { 0x3d403020, 0x1001 }, { 0x3d403024, 0xc3500 }, { 0x3d403050, 0x20d000 }, - { 0x3d403064, 0x30007 }, + { 0x3d403064, 0x3000a }, { 0x3d4030dc, 0x840000 }, { 0x3d4030e0, 0x330000 }, { 0x3d4030e8, 0x660048 }, @@ -1937,7 +1937,7 @@ struct dram_cfg_param ddr_ddrc_cfg2[] = { { 0x3d40311c, 0x301 }, { 0x3d403130, 0x20300 }, { 0x3d403134, 0xa100002 }, - { 0x3d403138, 0x8 }, + { 0x3d403138, 0xa }, { 0x3d403144, 0x50003 }, { 0x3d403180, 0x190004 }, { 0x3d403190, 0x3818200 },

From: Emanuele Ghidoli emanuele.ghidoli@toradex.com Change tRFCmin (tRFCab) from 280 ns to 380 ns to be compliant with current and futures memories. Fixes: 2bc2f817cea7 ("board: toradex: add verdin imx8m plus support") Signed-off-by: Emanuele Ghidoli emanuele.ghidoli@toradex.com Signed-off-by: Marcel Ziswiler marcel.ziswiler@toradex.com
Applied to u-boot-imx, next, thanks !
Best regards, Stefano Babic

From: Emanuele Ghidoli emanuele.ghidoli@toradex.com
Update LPDDR4 configuration and training using updated spreadsheet and tools from NXP using data from previous spreadsheet and verified toward datasheet: - MX8M_Plus_LPDDR4_RPA_v9.xlsx - mscale_ddr_tool_v3.30.exe
From: https://community.nxp.com/t5/i-MX-Processors-Knowledge-Base/i-MX-8M-Family-D...
Some register values differ due to these fixes/modifications:
- corrected calculation of T_CKPDX parameter (equal to tCKCKEH for LPDDR4) - corrected ECC related items, none of which affect normal operation when ECC is not enabled - corrected formula for calculation of tRTP in cell D122
Signed-off-by: Emanuele Ghidoli emanuele.ghidoli@toradex.com Signed-off-by: Marcel Ziswiler marcel.ziswiler@toradex.com ---
(no changes since v1)
board/toradex/verdin-imx8mp/lpddr4_timing.c | 49 +++++++++++---------- 1 file changed, 25 insertions(+), 24 deletions(-)
diff --git a/board/toradex/verdin-imx8mp/lpddr4_timing.c b/board/toradex/verdin-imx8mp/lpddr4_timing.c index 58278d2150a..4f0bbe6ce16 100644 --- a/board/toradex/verdin-imx8mp/lpddr4_timing.c +++ b/board/toradex/verdin-imx8mp/lpddr4_timing.c @@ -22,8 +22,8 @@ struct dram_cfg_param ddr_ddrc_cfg[] = { { 0x3d400020, 0x1303 }, { 0x3d400024, 0x1e84800 }, { 0x3d400064, 0x7a017c }, - { 0x3d400070, 0x61027f10 }, - { 0x3d400074, 0x7b0 }, + { 0x3d400070, 0x7027f90 }, + { 0x3d400074, 0x790 }, { 0x3d4000d0, 0xc00307a3 }, { 0x3d4000d4, 0xc50000 }, { 0x3d4000dc, 0xf4003f }, @@ -31,12 +31,12 @@ struct dram_cfg_param ddr_ddrc_cfg[] = { { 0x3d4000e8, 0x660048 }, { 0x3d4000ec, 0x160048 }, { 0x3d400100, 0x2028222a }, - { 0x3d400104, 0x807bf }, + { 0x3d400104, 0x8083f }, { 0x3d40010c, 0xe0e000 }, { 0x3d400110, 0x12040a12 }, { 0x3d400114, 0x2050f0f }, { 0x3d400118, 0x1010009 }, - { 0x3d40011c, 0x501 }, + { 0x3d40011c, 0x502 }, { 0x3d400130, 0x20800 }, { 0x3d400134, 0xe100002 }, { 0x3d400138, 0x184 }, @@ -53,9 +53,10 @@ struct dram_cfg_param ddr_ddrc_cfg[] = { { 0x3d4001b0, 0x11 }, { 0x3d4001c0, 0x1 }, { 0x3d4001c4, 0x1 }, - { 0x3d4000f4, 0xc99 }, - { 0x3d400108, 0x9121c1c }, + { 0x3d4000f4, 0x799 }, + { 0x3d400108, 0x9121b1c }, { 0x3d400200, 0x17 }, + { 0x3d400208, 0x0 }, { 0x3d40020c, 0x0 }, { 0x3d400210, 0x1f1f }, { 0x3d400204, 0x80808 }, @@ -89,7 +90,7 @@ struct dram_cfg_param ddr_ddrc_cfg[] = { { 0x3d402110, 0x2040202 }, { 0x3d402114, 0x2030202 }, { 0x3d402118, 0x1010004 }, - { 0x3d40211c, 0x301 }, + { 0x3d40211c, 0x302 }, { 0x3d402130, 0x20300 }, { 0x3d402134, 0xa100002 }, { 0x3d402138, 0x27 }, @@ -98,7 +99,7 @@ struct dram_cfg_param ddr_ddrc_cfg[] = { { 0x3d402190, 0x3818200 }, { 0x3d402194, 0x80303 }, { 0x3d4021b4, 0x100 }, - { 0x3d4020f4, 0xc99 }, + { 0x3d4020f4, 0x599 }, { 0x3d403020, 0x1001 }, { 0x3d403024, 0xc3500 }, { 0x3d403050, 0x20d000 }, @@ -114,7 +115,7 @@ struct dram_cfg_param ddr_ddrc_cfg[] = { { 0x3d403110, 0x2040202 }, { 0x3d403114, 0x2030202 }, { 0x3d403118, 0x1010004 }, - { 0x3d40311c, 0x301 }, + { 0x3d40311c, 0x302 }, { 0x3d403130, 0x20300 }, { 0x3d403134, 0xa100002 }, { 0x3d403138, 0xa }, @@ -123,7 +124,7 @@ struct dram_cfg_param ddr_ddrc_cfg[] = { { 0x3d403190, 0x3818200 }, { 0x3d403194, 0x80303 }, { 0x3d4031b4, 0x100 }, - { 0x3d4030f4, 0xc99 }, + { 0x3d4030f4, 0x599 }, { 0x3d400028, 0x0 }, };
@@ -1700,15 +1701,15 @@ struct dram_cfg_param ddr_phy_pie[] = { { 0x400d7, 0x20b }, { 0x2003a, 0x2 }, { 0x200be, 0x3 }, - { 0x2000b, 0x7d }, + { 0x2000b, 0x465 }, { 0x2000c, 0xfa }, { 0x2000d, 0x9c4 }, { 0x2000e, 0x2c }, - { 0x12000b, 0xc }, + { 0x12000b, 0x70 }, { 0x12000c, 0x19 }, { 0x12000d, 0xfa }, { 0x12000e, 0x10 }, - { 0x22000b, 0x3 }, + { 0x22000b, 0x1c }, { 0x22000c, 0x6 }, { 0x22000d, 0x3e }, { 0x22000e, 0x10 }, @@ -1842,8 +1843,8 @@ struct dram_cfg_param ddr_ddrc_cfg2[] = { { 0x3d400020, 0x1303 }, { 0x3d400024, 0x1e84800 }, { 0x3d400064, 0x7a017c }, - { 0x3d400070, 0x61027f10 }, - { 0x3d400074, 0x7b0 }, + { 0x3d400070, 0x7027f90 }, + { 0x3d400074, 0x790 }, { 0x3d4000d0, 0xc00307a3 }, { 0x3d4000d4, 0xc50000 }, { 0x3d4000dc, 0xf4003f }, @@ -1851,12 +1852,12 @@ struct dram_cfg_param ddr_ddrc_cfg2[] = { { 0x3d4000e8, 0x660048 }, { 0x3d4000ec, 0x160048 }, { 0x3d400100, 0x2028222a }, - { 0x3d400104, 0x807bf }, + { 0x3d400104, 0x8083f }, { 0x3d40010c, 0xe0e000 }, { 0x3d400110, 0x12040a12 }, { 0x3d400114, 0x2050f0f }, { 0x3d400118, 0x1010009 }, - { 0x3d40011c, 0x501 }, + { 0x3d40011c, 0x502 }, { 0x3d400130, 0x20800 }, { 0x3d400134, 0xe100002 }, { 0x3d400138, 0x184 }, @@ -1873,9 +1874,10 @@ struct dram_cfg_param ddr_ddrc_cfg2[] = { { 0x3d4001b0, 0x11 }, { 0x3d4001c0, 0x1 }, { 0x3d4001c4, 0x1 }, - { 0x3d4000f4, 0xc99 }, - { 0x3d400108, 0x9121c1c }, + { 0x3d4000f4, 0x799 }, + { 0x3d400108, 0x9121b1c }, { 0x3d400200, 0x1f }, + { 0x3d400208, 0x0 }, { 0x3d40020c, 0x0 }, { 0x3d400210, 0x1f1f }, { 0x3d400204, 0x80808 }, @@ -1909,7 +1911,7 @@ struct dram_cfg_param ddr_ddrc_cfg2[] = { { 0x3d402110, 0x2040202 }, { 0x3d402114, 0x2030202 }, { 0x3d402118, 0x1010004 }, - { 0x3d40211c, 0x301 }, + { 0x3d40211c, 0x302 }, { 0x3d402130, 0x20300 }, { 0x3d402134, 0xa100002 }, { 0x3d402138, 0x27 }, @@ -1918,7 +1920,7 @@ struct dram_cfg_param ddr_ddrc_cfg2[] = { { 0x3d402190, 0x3818200 }, { 0x3d402194, 0x80303 }, { 0x3d4021b4, 0x100 }, - { 0x3d4020f4, 0xc99 }, + { 0x3d4020f4, 0x599 }, { 0x3d403020, 0x1001 }, { 0x3d403024, 0xc3500 }, { 0x3d403050, 0x20d000 }, @@ -1934,7 +1936,7 @@ struct dram_cfg_param ddr_ddrc_cfg2[] = { { 0x3d403110, 0x2040202 }, { 0x3d403114, 0x2030202 }, { 0x3d403118, 0x1010004 }, - { 0x3d40311c, 0x301 }, + { 0x3d40311c, 0x302 }, { 0x3d403130, 0x20300 }, { 0x3d403134, 0xa100002 }, { 0x3d403138, 0xa }, @@ -1943,7 +1945,7 @@ struct dram_cfg_param ddr_ddrc_cfg2[] = { { 0x3d403190, 0x3818200 }, { 0x3d403194, 0x80303 }, { 0x3d4031b4, 0x100 }, - { 0x3d4030f4, 0xc99 }, + { 0x3d4030f4, 0x599 }, { 0x3d400028, 0x0 }, };
@@ -2076,7 +2078,6 @@ struct dram_cfg_param ddr_fsp0_2d_cfg2[] = { { 0x54008, 0x61 }, { 0x54009, 0xc8 }, { 0x5400b, 0x2 }, - { 0x5400d, 0x100 }, { 0x5400f, 0x100 }, { 0x54010, 0x1f7f }, { 0x54012, 0x110 },

From: Emanuele Ghidoli emanuele.ghidoli@toradex.com Update LPDDR4 configuration and training using updated spreadsheet and tools from NXP using data from previous spreadsheet and verified toward datasheet:
- MX8M_Plus_LPDDR4_RPA_v9.xlsx
- mscale_ddr_tool_v3.30.exe
From: https://community.nxp.com/t5/i-MX-Processors-Knowledge-Base/i-MX-8M-Family-D... Some register values differ due to these fixes/modifications:
- corrected calculation of T_CKPDX parameter (equal to tCKCKEH for LPDDR4)
- corrected ECC related items, none of which affect normal operation when ECC is not enabled
- corrected formula for calculation of tRTP in cell D122
Signed-off-by: Emanuele Ghidoli emanuele.ghidoli@toradex.com Signed-off-by: Marcel Ziswiler marcel.ziswiler@toradex.com
Applied to u-boot-imx, next, thanks !
Best regards, Stefano Babic

From: Emanuele Ghidoli emanuele.ghidoli@toradex.com
Deduplicate similar DDRC configurations and LPDDR4 training patterns by patching a single configuration.
The aim is to reduce the SPL memory footprint and simplify maintenance of lpddr4_timing.c
Signed-off-by: Emanuele Ghidoli emanuele.ghidoli@toradex.com Signed-off-by: Marcel Ziswiler marcel.ziswiler@toradex.com ---
(no changes since v1)
board/toradex/verdin-imx8mp/lpddr4_timing.c | 380 ++++---------------- board/toradex/verdin-imx8mp/lpddr4_timing.h | 11 + board/toradex/verdin-imx8mp/spl.c | 6 +- 3 files changed, 75 insertions(+), 322 deletions(-) create mode 100644 board/toradex/verdin-imx8mp/lpddr4_timing.h
diff --git a/board/toradex/verdin-imx8mp/lpddr4_timing.c b/board/toradex/verdin-imx8mp/lpddr4_timing.c index 4f0bbe6ce16..29ea31e1461 100644 --- a/board/toradex/verdin-imx8mp/lpddr4_timing.c +++ b/board/toradex/verdin-imx8mp/lpddr4_timing.c @@ -13,6 +13,33 @@
#include <linux/kernel.h> #include <asm/arch/ddr.h> +#include "lpddr4_timing.h" + +struct dram_cfg_param ddr_ddrc_cfg_single_rank_patch[] = { + { 0x3d400000, 0xa1080020}, + { 0x3d400200, 0x1f}, + { 0x3d40021c, 0xf07} +}; + +struct dram_cfg_param ddr_fsp0_cfg_single_rank_patch[] = { + { 0x54012, 0x110}, + { 0x5402c, 0x1} +}; + +struct dram_cfg_param ddr_fsp1_cfg_single_rank_patch[] = { + { 0x54012, 0x110}, + { 0x5402c, 0x1} +}; + +struct dram_cfg_param ddr_fsp2_cfg_single_rank_patch[] = { + { 0x54012, 0x110}, + { 0x5402c, 0x1} +}; + +struct dram_cfg_param ddr_fsp0_2d_cfg_single_rank_patch[] = { + { 0x54012, 0x110}, + { 0x5402c, 0x1} +};
struct dram_cfg_param ddr_ddrc_cfg[] = { /** Initialize DDRC registers **/ @@ -1835,311 +1862,7 @@ struct dram_fsp_msg ddr_dram_fsp_msg[] = { }, };
-struct dram_cfg_param ddr_ddrc_cfg2[] = { - /** Initialize DDRC registers **/ - { 0x3d400304, 0x1 }, - { 0x3d400030, 0x1 }, - { 0x3d400000, 0xa1080020 }, - { 0x3d400020, 0x1303 }, - { 0x3d400024, 0x1e84800 }, - { 0x3d400064, 0x7a017c }, - { 0x3d400070, 0x7027f90 }, - { 0x3d400074, 0x790 }, - { 0x3d4000d0, 0xc00307a3 }, - { 0x3d4000d4, 0xc50000 }, - { 0x3d4000dc, 0xf4003f }, - { 0x3d4000e0, 0x330000 }, - { 0x3d4000e8, 0x660048 }, - { 0x3d4000ec, 0x160048 }, - { 0x3d400100, 0x2028222a }, - { 0x3d400104, 0x8083f }, - { 0x3d40010c, 0xe0e000 }, - { 0x3d400110, 0x12040a12 }, - { 0x3d400114, 0x2050f0f }, - { 0x3d400118, 0x1010009 }, - { 0x3d40011c, 0x502 }, - { 0x3d400130, 0x20800 }, - { 0x3d400134, 0xe100002 }, - { 0x3d400138, 0x184 }, - { 0x3d400144, 0xc80064 }, - { 0x3d400180, 0x3e8001e }, - { 0x3d400184, 0x3207a12 }, - { 0x3d400188, 0x0 }, - { 0x3d400190, 0x49f820e }, - { 0x3d400194, 0x80303 }, - { 0x3d4001b4, 0x1f0e }, - { 0x3d4001a0, 0xe0400018 }, - { 0x3d4001a4, 0xdf00e4 }, - { 0x3d4001a8, 0x80000000 }, - { 0x3d4001b0, 0x11 }, - { 0x3d4001c0, 0x1 }, - { 0x3d4001c4, 0x1 }, - { 0x3d4000f4, 0x799 }, - { 0x3d400108, 0x9121b1c }, - { 0x3d400200, 0x1f }, - { 0x3d400208, 0x0 }, - { 0x3d40020c, 0x0 }, - { 0x3d400210, 0x1f1f }, - { 0x3d400204, 0x80808 }, - { 0x3d400214, 0x7070707 }, - { 0x3d400218, 0x7070707 }, - { 0x3d40021c, 0xf07 }, - { 0x3d400250, 0x1705 }, - { 0x3d400254, 0x2c }, - { 0x3d40025c, 0x4000030 }, - { 0x3d400264, 0x900093e7 }, - { 0x3d40026c, 0x2005574 }, - { 0x3d400400, 0x111 }, - { 0x3d400404, 0x72ff }, - { 0x3d400408, 0x72ff }, - { 0x3d400494, 0x2100e07 }, - { 0x3d400498, 0x620096 }, - { 0x3d40049c, 0x1100e07 }, - { 0x3d4004a0, 0xc8012c }, - { 0x3d402020, 0x1001 }, - { 0x3d402024, 0x30d400 }, - { 0x3d402050, 0x20d000 }, - { 0x3d402064, 0xc0026 }, - { 0x3d4020dc, 0x840000 }, - { 0x3d4020e0, 0x330000 }, - { 0x3d4020e8, 0x660048 }, - { 0x3d4020ec, 0x160048 }, - { 0x3d402100, 0xa040305 }, - { 0x3d402104, 0x30407 }, - { 0x3d402108, 0x203060b }, - { 0x3d40210c, 0x505000 }, - { 0x3d402110, 0x2040202 }, - { 0x3d402114, 0x2030202 }, - { 0x3d402118, 0x1010004 }, - { 0x3d40211c, 0x302 }, - { 0x3d402130, 0x20300 }, - { 0x3d402134, 0xa100002 }, - { 0x3d402138, 0x27 }, - { 0x3d402144, 0x14000a }, - { 0x3d402180, 0x640004 }, - { 0x3d402190, 0x3818200 }, - { 0x3d402194, 0x80303 }, - { 0x3d4021b4, 0x100 }, - { 0x3d4020f4, 0x599 }, - { 0x3d403020, 0x1001 }, - { 0x3d403024, 0xc3500 }, - { 0x3d403050, 0x20d000 }, - { 0x3d403064, 0x3000a }, - { 0x3d4030dc, 0x840000 }, - { 0x3d4030e0, 0x330000 }, - { 0x3d4030e8, 0x660048 }, - { 0x3d4030ec, 0x160048 }, - { 0x3d403100, 0xa010102 }, - { 0x3d403104, 0x30404 }, - { 0x3d403108, 0x203060b }, - { 0x3d40310c, 0x505000 }, - { 0x3d403110, 0x2040202 }, - { 0x3d403114, 0x2030202 }, - { 0x3d403118, 0x1010004 }, - { 0x3d40311c, 0x302 }, - { 0x3d403130, 0x20300 }, - { 0x3d403134, 0xa100002 }, - { 0x3d403138, 0xa }, - { 0x3d403144, 0x50003 }, - { 0x3d403180, 0x190004 }, - { 0x3d403190, 0x3818200 }, - { 0x3d403194, 0x80303 }, - { 0x3d4031b4, 0x100 }, - { 0x3d4030f4, 0x599 }, - { 0x3d400028, 0x0 }, -}; - -/* P0 message block parameter for training firmware */ -struct dram_cfg_param ddr_fsp0_cfg2[] = { - { 0xd0000, 0x0 }, - { 0x54003, 0xfa0 }, - { 0x54004, 0x2 }, - { 0x54005, 0x2228 }, - { 0x54006, 0x14 }, - { 0x54008, 0x131f }, - { 0x54009, 0xc8 }, - { 0x5400b, 0x2 }, - { 0x5400f, 0x100 }, - { 0x54012, 0x110 }, - { 0x54019, 0x3ff4 }, - { 0x5401a, 0x33 }, - { 0x5401b, 0x4866 }, - { 0x5401c, 0x4800 }, - { 0x5401e, 0x16 }, - { 0x5401f, 0x3ff4 }, - { 0x54020, 0x33 }, - { 0x54021, 0x4866 }, - { 0x54022, 0x4800 }, - { 0x54024, 0x16 }, - { 0x5402b, 0x1000 }, - { 0x5402c, 0x1 }, - { 0x54032, 0xf400 }, - { 0x54033, 0x333f }, - { 0x54034, 0x6600 }, - { 0x54035, 0x48 }, - { 0x54036, 0x48 }, - { 0x54037, 0x1600 }, - { 0x54038, 0xf400 }, - { 0x54039, 0x333f }, - { 0x5403a, 0x6600 }, - { 0x5403b, 0x48 }, - { 0x5403c, 0x48 }, - { 0x5403d, 0x1600 }, - { 0xd0000, 0x1 }, -}; - -/* P1 message block parameter for training firmware */ -struct dram_cfg_param ddr_fsp1_cfg2[] = { - { 0xd0000, 0x0 }, - { 0x54002, 0x101 }, - { 0x54003, 0x190 }, - { 0x54004, 0x2 }, - { 0x54005, 0x2228 }, - { 0x54006, 0x14 }, - { 0x54008, 0x121f }, - { 0x54009, 0xc8 }, - { 0x5400b, 0x2 }, - { 0x5400f, 0x100 }, - { 0x54012, 0x110 }, - { 0x54019, 0x84 }, - { 0x5401a, 0x33 }, - { 0x5401b, 0x4866 }, - { 0x5401c, 0x4800 }, - { 0x5401e, 0x16 }, - { 0x5401f, 0x84 }, - { 0x54020, 0x33 }, - { 0x54021, 0x4866 }, - { 0x54022, 0x4800 }, - { 0x54024, 0x16 }, - { 0x5402b, 0x1000 }, - { 0x5402c, 0x1 }, - { 0x54032, 0x8400 }, - { 0x54033, 0x3300 }, - { 0x54034, 0x6600 }, - { 0x54035, 0x48 }, - { 0x54036, 0x48 }, - { 0x54037, 0x1600 }, - { 0x54038, 0x8400 }, - { 0x54039, 0x3300 }, - { 0x5403a, 0x6600 }, - { 0x5403b, 0x48 }, - { 0x5403c, 0x48 }, - { 0x5403d, 0x1600 }, - { 0xd0000, 0x1 }, -}; - -/* P2 message block parameter for training firmware */ -struct dram_cfg_param ddr_fsp2_cfg2[] = { - { 0xd0000, 0x0 }, - { 0x54002, 0x102 }, - { 0x54003, 0x64 }, - { 0x54004, 0x2 }, - { 0x54005, 0x2228 }, - { 0x54006, 0x14 }, - { 0x54008, 0x121f }, - { 0x54009, 0xc8 }, - { 0x5400b, 0x2 }, - { 0x5400f, 0x100 }, - { 0x54012, 0x110 }, - { 0x54019, 0x84 }, - { 0x5401a, 0x33 }, - { 0x5401b, 0x4866 }, - { 0x5401c, 0x4800 }, - { 0x5401e, 0x16 }, - { 0x5401f, 0x84 }, - { 0x54020, 0x33 }, - { 0x54021, 0x4866 }, - { 0x54022, 0x4800 }, - { 0x54024, 0x16 }, - { 0x5402b, 0x1000 }, - { 0x5402c, 0x1 }, - { 0x54032, 0x8400 }, - { 0x54033, 0x3300 }, - { 0x54034, 0x6600 }, - { 0x54035, 0x48 }, - { 0x54036, 0x48 }, - { 0x54037, 0x1600 }, - { 0x54038, 0x8400 }, - { 0x54039, 0x3300 }, - { 0x5403a, 0x6600 }, - { 0x5403b, 0x48 }, - { 0x5403c, 0x48 }, - { 0x5403d, 0x1600 }, - { 0xd0000, 0x1 }, -}; - -/* P0 2D message block parameter for training firmware */ -struct dram_cfg_param ddr_fsp0_2d_cfg2[] = { - { 0xd0000, 0x0 }, - { 0x54003, 0xfa0 }, - { 0x54004, 0x2 }, - { 0x54005, 0x2228 }, - { 0x54006, 0x14 }, - { 0x54008, 0x61 }, - { 0x54009, 0xc8 }, - { 0x5400b, 0x2 }, - { 0x5400f, 0x100 }, - { 0x54010, 0x1f7f }, - { 0x54012, 0x110 }, - { 0x54019, 0x3ff4 }, - { 0x5401a, 0x33 }, - { 0x5401b, 0x4866 }, - { 0x5401c, 0x4800 }, - { 0x5401e, 0x16 }, - { 0x5401f, 0x3ff4 }, - { 0x54020, 0x33 }, - { 0x54021, 0x4866 }, - { 0x54022, 0x4800 }, - { 0x54024, 0x16 }, - { 0x5402b, 0x1000 }, - { 0x5402c, 0x1 }, - { 0x54032, 0xf400 }, - { 0x54033, 0x333f }, - { 0x54034, 0x6600 }, - { 0x54035, 0x48 }, - { 0x54036, 0x48 }, - { 0x54037, 0x1600 }, - { 0x54038, 0xf400 }, - { 0x54039, 0x333f }, - { 0x5403a, 0x6600 }, - { 0x5403b, 0x48 }, - { 0x5403c, 0x48 }, - { 0x5403d, 0x1600 }, - { 0xd0000, 0x1 }, -}; - -struct dram_fsp_msg ddr_dram_fsp_msg2[] = { - { - /* P0 4000mts 1D */ - .drate = 4000, - .fw_type = FW_1D_IMAGE, - .fsp_cfg = ddr_fsp0_cfg2, - .fsp_cfg_num = ARRAY_SIZE(ddr_fsp0_cfg2), - }, - { - /* P1 400mts 1D */ - .drate = 400, - .fw_type = FW_1D_IMAGE, - .fsp_cfg = ddr_fsp1_cfg2, - .fsp_cfg_num = ARRAY_SIZE(ddr_fsp1_cfg2), - }, - { - /* P2 100mts 1D */ - .drate = 100, - .fw_type = FW_1D_IMAGE, - .fsp_cfg = ddr_fsp2_cfg2, - .fsp_cfg_num = ARRAY_SIZE(ddr_fsp2_cfg2), - }, - { - /* P0 4000mts 2D */ - .drate = 4000, - .fw_type = FW_2D_IMAGE, - .fsp_cfg = ddr_fsp0_2d_cfg2, - .fsp_cfg_num = ARRAY_SIZE(ddr_fsp0_2d_cfg2), - }, -}; - -/* quad die, dual rank aka 8 GB DDR timing config params */ +/* ddr timing config params */ struct dram_timing_info dram_timing = { .ddrc_cfg = ddr_ddrc_cfg, .ddrc_cfg_num = ARRAY_SIZE(ddr_ddrc_cfg), @@ -2154,17 +1877,36 @@ struct dram_timing_info dram_timing = { .fsp_table = { 4000, 400, 100, }, };
-/* dual die, single rank aka 1 GB (untested), 2 GB or 4 GB DDR timing config params */ -struct dram_timing_info dram_timing2 = { - .ddrc_cfg = ddr_ddrc_cfg2, - .ddrc_cfg_num = ARRAY_SIZE(ddr_ddrc_cfg2), - .ddrphy_cfg = ddr_ddrphy_cfg, - .ddrphy_cfg_num = ARRAY_SIZE(ddr_ddrphy_cfg), - .fsp_msg = ddr_dram_fsp_msg2, - .fsp_msg_num = ARRAY_SIZE(ddr_dram_fsp_msg2), - .ddrphy_trained_csr = ddr_ddrphy_trained_csr, - .ddrphy_trained_csr_num = ARRAY_SIZE(ddr_ddrphy_trained_csr), - .ddrphy_pie = ddr_phy_pie, - .ddrphy_pie_num = ARRAY_SIZE(ddr_phy_pie), - .fsp_table = { 4000, 400, 100, }, -}; +static void apply_cfg_patch(struct dram_cfg_param *cfg, int cfg_sz, + struct dram_cfg_param *patch, int patch_sz) +{ + int i, j; + + for (i = 0; i < cfg_sz; i++) + for (j = 0; j < patch_sz; j++) + if (cfg[i].reg == patch[j].reg) + cfg[i].val = patch[j].val; +} + +void lpddr4_single_rank_training_patch(void) +{ + apply_cfg_patch(ddr_ddrc_cfg, ARRAY_SIZE(ddr_ddrc_cfg), + ddr_ddrc_cfg_single_rank_patch, + ARRAY_SIZE(ddr_ddrc_cfg_single_rank_patch)); + + apply_cfg_patch(ddr_fsp0_cfg, ARRAY_SIZE(ddr_fsp0_cfg), + ddr_fsp0_cfg_single_rank_patch, + ARRAY_SIZE(ddr_fsp0_cfg_single_rank_patch)); + + apply_cfg_patch(ddr_fsp1_cfg, ARRAY_SIZE(ddr_fsp1_cfg), + ddr_fsp1_cfg_single_rank_patch, + ARRAY_SIZE(ddr_fsp1_cfg_single_rank_patch)); + + apply_cfg_patch(ddr_fsp2_cfg, ARRAY_SIZE(ddr_fsp2_cfg), + ddr_fsp2_cfg_single_rank_patch, + ARRAY_SIZE(ddr_fsp2_cfg_single_rank_patch)); + + apply_cfg_patch(ddr_fsp0_2d_cfg, ARRAY_SIZE(ddr_fsp0_2d_cfg), + ddr_fsp0_2d_cfg_single_rank_patch, + ARRAY_SIZE(ddr_fsp0_2d_cfg_single_rank_patch)); +} diff --git a/board/toradex/verdin-imx8mp/lpddr4_timing.h b/board/toradex/verdin-imx8mp/lpddr4_timing.h new file mode 100644 index 00000000000..95e74e37baf --- /dev/null +++ b/board/toradex/verdin-imx8mp/lpddr4_timing.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright 2022 Toradex + */ + +#ifndef __LPDDR4_TIMING_H__ +#define __LPDDR4_TIMING_H__ + +void lpddr4_single_rank_training_patch(void); + +#endif /* __LPDDR4_TIMING_H__ */ diff --git a/board/toradex/verdin-imx8mp/spl.c b/board/toradex/verdin-imx8mp/spl.c index 7b383cc0d53..ab5bcbc0929 100644 --- a/board/toradex/verdin-imx8mp/spl.c +++ b/board/toradex/verdin-imx8mp/spl.c @@ -21,8 +21,7 @@ #include <dm/uclass.h> #include <power/pmic.h> #include <power/pca9450.h> - -extern struct dram_timing_info dram_timing2; +#include "lpddr4_timing.h"
DECLARE_GLOBAL_DATA_PTR;
@@ -38,7 +37,8 @@ void spl_dram_init(void) */ if (ddr_init(&dram_timing)) { printf("Dual rank failed, attempting single rank configuration.\n"); - ddr_init(&dram_timing2); + lpddr4_single_rank_training_patch(); + ddr_init(&dram_timing); } }

From: Emanuele Ghidoli emanuele.ghidoli@toradex.com Deduplicate similar DDRC configurations and LPDDR4 training patterns by patching a single configuration. The aim is to reduce the SPL memory footprint and simplify maintenance of lpddr4_timing.c Signed-off-by: Emanuele Ghidoli emanuele.ghidoli@toradex.com Signed-off-by: Marcel Ziswiler marcel.ziswiler@toradex.com
Applied to u-boot-imx, next, thanks !
Best regards, Stefano Babic

From: Emanuele Ghidoli emanuele.ghidoli@toradex.com
change prints to show which DDR configuration (single/dual rank) is used
Signed-off-by: Emanuele Ghidoli emanuele.ghidoli@toradex.com Signed-off-by: Marcel Ziswiler marcel.ziswiler@toradex.com
---
Changes in v2: - Use puts rather than printf in the SPL as suggested by Fabio. Thanks!
board/toradex/verdin-imx8mp/spl.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/board/toradex/verdin-imx8mp/spl.c b/board/toradex/verdin-imx8mp/spl.c index ab5bcbc0929..73729a42b45 100644 --- a/board/toradex/verdin-imx8mp/spl.c +++ b/board/toradex/verdin-imx8mp/spl.c @@ -35,11 +35,17 @@ void spl_dram_init(void) /* * Try configuring for dual rank memory falling back to single rank */ - if (ddr_init(&dram_timing)) { - printf("Dual rank failed, attempting single rank configuration.\n"); - lpddr4_single_rank_training_patch(); - ddr_init(&dram_timing); + if (!ddr_init(&dram_timing)) { + puts("DDR configured as dual rank\n"); + return; } + + lpddr4_single_rank_training_patch(); + if (!ddr_init(&dram_timing)) { + puts("DDR configured as single rank\n"); + return; + } + puts("DDR configuration failed\n"); }
void spl_board_init(void)

From: Emanuele Ghidoli emanuele.ghidoli@toradex.com change prints to show which DDR configuration (single/dual rank) is used Signed-off-by: Emanuele Ghidoli emanuele.ghidoli@toradex.com Signed-off-by: Marcel Ziswiler marcel.ziswiler@toradex.com
Applied to u-boot-imx, next, thanks !
Best regards, Stefano Babic

Hi Marcel,
On Mon, Apr 3, 2023 at 9:02 AM Marcel Ziswiler marcel@ziswiler.com wrote:
From: Marcel Ziswiler marcel.ziswiler@toradex.com
This series contains the following DDR updates:
- update ddrc config for different lpddr4 memories
- fix lpddr4 refresh timing
- update lpddr4 configuration and training
- compact slight different lpddr4 configuration
- change prints in spl_dram_init function
Changes in v2:
- Use puts rather than printf in the SPL as suggested by Fabio. Thanks!
For the whole series:
Reviewed-by: Fabio Estevam festevam@denx.de
participants (3)
-
Fabio Estevam
-
Marcel Ziswiler
-
sbabic@denx.de