[PATCH 0/3] Improve AST26x0 DDR4 timing and signal quality

This patch series fine-tunes the read & write DQS/DQ timing, CLK/CA timing and termination (RTT_NOM, RTT_PARK and RTT_WR) for Aspeed AST26x0 SOC to get better signal quality and hence improve the stability. Also, a typing error of the DDR-PHY status polling is fixed.
Dylan Hung (3): ram: ast2600: Fix incorrect statement of the register polling ram: ast2600: Improve ddr4 timing and signal quality ram: ast2600: Align the RL and WL setting
.../include/asm/arch-aspeed/sdram_ast2600.h | 4 + drivers/ram/aspeed/sdram_ast2600.c | 179 +++++++++++++++--- 2 files changed, 152 insertions(+), 31 deletions(-)

The condition "~data" in the if-statement is a typo. The original intention is to poll if SDRAM_PHYCTRL0_INIT bit equals to 0. So use "data == 0" for instead.
Besides, the bit[1] of "phy_status" register is hardwired to SDRAM_PHYCTRL0_INIT (with inverse logic). Since SDRAM_PHYCTRL0_INIT has already done, remove the unnecessary checking of phy_status[1].
Fixes: fde93143469f ("ram: aspeed: Add AST2600 DRAM control support")
Signed-off-by: Dylan Hung dylan_hung@aspeedtech.com --- drivers/ram/aspeed/sdram_ast2600.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/drivers/ram/aspeed/sdram_ast2600.c b/drivers/ram/aspeed/sdram_ast2600.c index 9ad398d24155..b09232a30413 100644 --- a/drivers/ram/aspeed/sdram_ast2600.c +++ b/drivers/ram/aspeed/sdram_ast2600.c @@ -449,7 +449,7 @@ static void ast2600_sdramphy_kick_training(struct dram_info *info)
while (1) { data = readl(®s->phy_ctrl[0]) & SDRAM_PHYCTRL0_INIT; - if (~data) + if (data == 0) break; } } @@ -984,11 +984,6 @@ static int ast2600_sdrammc_probe(struct udevice *dev) L_ast2600_sdramphy_train: ast2600_sdrammc_init_ddr4(priv);
- /* make sure DDR-PHY is ready before access */ - do { - reg = readl(priv->phy_status) & BIT(1); - } while (reg == 0); - if (ast2600_sdramphy_check_status(priv) != 0) { printf("DDR4 PHY training fail, retrain\n"); goto L_ast2600_sdramphy_train;

-----Original Message----- From: Dylan Hung dylan_hung@aspeedtech.com Sent: Friday, November 11, 2022 3:30 PM To: Ryan Chen ryan_chen@aspeedtech.com; ChiaWei Wang chiawei_wang@aspeedtech.com; joel@jms.id.au; Dylan Hung dylan_hung@aspeedtech.com; u-boot@lists.denx.de Cc: BMC-SW BMC-SW@aspeedtech.com Subject: [PATCH 1/3] ram: ast2600: Fix incorrect statement of the register polling
The condition "~data" in the if-statement is a typo. The original intention is to poll if SDRAM_PHYCTRL0_INIT bit equals to 0. So use "data == 0" for instead.
Besides, the bit[1] of "phy_status" register is hardwired to SDRAM_PHYCTRL0_INIT (with inverse logic). Since SDRAM_PHYCTRL0_INIT has already done, remove the unnecessary checking of phy_status[1].
Fixes: fde93143469f ("ram: aspeed: Add AST2600 DRAM control support")
Signed-off-by: Dylan Hung dylan_hung@aspeedtech.com
Review-by: Ryan Chen ryan_chen@aspeedtech.com
drivers/ram/aspeed/sdram_ast2600.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/drivers/ram/aspeed/sdram_ast2600.c b/drivers/ram/aspeed/sdram_ast2600.c index 9ad398d24155..b09232a30413 100644 --- a/drivers/ram/aspeed/sdram_ast2600.c +++ b/drivers/ram/aspeed/sdram_ast2600.c @@ -449,7 +449,7 @@ static void ast2600_sdramphy_kick_training(struct dram_info *info)
while (1) { data = readl(®s->phy_ctrl[0]) & SDRAM_PHYCTRL0_INIT;
if (~data)
}if (data == 0) break;
} @@ -984,11 +984,6 @@ static int ast2600_sdrammc_probe(struct udevice *dev) L_ast2600_sdramphy_train: ast2600_sdrammc_init_ddr4(priv);
- /* make sure DDR-PHY is ready before access */
- do {
reg = readl(priv->phy_status) & BIT(1);
- } while (reg == 0);
- if (ast2600_sdramphy_check_status(priv) != 0) { printf("DDR4 PHY training fail, retrain\n"); goto L_ast2600_sdramphy_train;
-- 2.25.1

On Fri, Nov 11, 2022 at 03:30:06PM +0800, Dylan Hung wrote:
The condition "~data" in the if-statement is a typo. The original intention is to poll if SDRAM_PHYCTRL0_INIT bit equals to 0. So use "data == 0" for instead.
Besides, the bit[1] of "phy_status" register is hardwired to SDRAM_PHYCTRL0_INIT (with inverse logic). Since SDRAM_PHYCTRL0_INIT has already done, remove the unnecessary checking of phy_status[1].
Fixes: fde93143469f ("ram: aspeed: Add AST2600 DRAM control support")
Signed-off-by: Dylan Hung dylan_hung@aspeedtech.com
Applied to u-boot/master, thanks!

Adjust the following settings to get better timing and signal quality.
1. write DQS/DQ delay - 1e6e2304[0] - 1e6e2304[15:8]
2. read DQS/DQ delay - 0x1e6e0298[0] - 0x1e6e0298[15:8]
3. CLK/CA timing - 0x1e6e01a8[31]
4. Read and write termination - change RTT_ROM from 40 ohm to 48 ohm (MR1[10:8]) - change RTT_PARK from disable to 48 ohm (MR5[8:6]) - change RTT_WR from 120 ohm to disable (MR2[11:9]) - change PHY ODT from 40 ohm to 80 ohm (0x1e6e0130[10:8])
Note1: Both DDR-PHY and DDR controller have their own registers for DDR4 Mode Registers (MR0~MR6). This patch introduces macros to synchronize the MR value on both sides.
Note2: the waveform meansurement can be found in item #21 of Aspeed AST26x0 Application note (AP note).
Signed-off-by: Dylan Hung dylan_hung@aspeedtech.com --- drivers/ram/aspeed/sdram_ast2600.c | 163 ++++++++++++++++++++++++----- 1 file changed, 138 insertions(+), 25 deletions(-)
diff --git a/drivers/ram/aspeed/sdram_ast2600.c b/drivers/ram/aspeed/sdram_ast2600.c index b09232a30413..bda02d062900 100644 --- a/drivers/ram/aspeed/sdram_ast2600.c +++ b/drivers/ram/aspeed/sdram_ast2600.c @@ -20,6 +20,119 @@ #define DDR_PHY_TBL_CHG_ADDR 0xaeeddeea #define DDR_PHY_TBL_END 0xaeededed
+/** + * phyr030[18:16] - Ron PU (PHY side) + * phyr030[14:12] - Ron PD (PHY side) + * b'000 : disable + * b'001 : 240 ohm + * b'010 : 120 ohm + * b'011 : 80 ohm + * b'100 : 60 ohm + * b'101 : 48 ohm + * b'110 : 40 ohm + * b'111 : 34 ohm (default) + */ +#define PHY_RON ((0x7 << 16) | (0x7 << 12)) + +/** + * phyr030[10:8] - ODT configuration (PHY side) + * b'000 : ODT disabled + * b'001 : 240 ohm + * b'010 : 120 ohm + * b'011 : 80 ohm (default) + * b'100 : 60 ohm + * b'101 : 48 ohm + * b'110 : 40 ohm + * b'111 : 34 ohm + */ +#define PHY_ODT (0x3 << 8) + +/** + * MR1[2:1] output driver impedance + * b'00 : 34 ohm (default) + * b'01 : 48 ohm + */ +#define DRAM_RON (0x0 << 1) + +/** + * DRAM ODT - synchronous ODT mode + * RTT_WR: disable + * RTT_NOM = RTT_PARK + * + * MR1[10:8] RTT_NOM + * b'000 : RTT_NOM disable + * b'001 : 60 ohm + * b'010 : 120 ohm + * b'011 : 40 ohm + * b'100 : 240 ohm + * b'101 : 48 ohm (default) + * b'110 : 80 ohm + * b'111 : 34 ohm + * + * MR5[8:6] RTT_PARK + * b'000 : RTT_PARK disable + * b'001 : 60 ohm + * b'010 : 120 ohm + * b'011 : 40 ohm + * b'100 : 240 ohm + * b'101 : 48 ohm (default) + * b'110 : 80 ohm + * b'111 : 34 ohm + * + * MR2[11:9] RTT_WR + * b'000 : Dynamic ODT off (default) + * b'001 : 120 ohm + * b'010 : 240 ohm + * b'011 : Hi-Z + * b'100 : 80 ohm + */ +#define RTT_WR (0x0 << 9) +#define RTT_NOM (0x5 << 8) +#define RTT_PARK (0x5 << 6) + +/** + * MR6[6] VrefDQ training range + * b'0 : range 1 + * b'1 : range 2 (default) + */ +#define VREFDQ_RANGE_2 BIT(6) + +/** + * Latency setting: + * AL = PL = 0 (hardware fixed setting) + * -> WL = AL + CWL + PL = CWL + * -> RL = AL + CL + PL = CL + */ +#define CONFIG_WL 9 +#define CONFIG_RL 12 +#define T_RDDATA_EN ((CONFIG_RL - 2) << 8) +#define T_PHY_WRLAT (CONFIG_WL - 2) + +/* MR0 */ +#define MR0_CL_12 (BIT(4) | BIT(2)) +#define MR0_WR12_RTP6 BIT(9) +#define MR0_DLL_RESET BIT(8) +#define MR0_VAL (MR0_CL_12 | MR0_WR12_RTP6 | MR0_DLL_RESET) + +/* MR1 */ +#define MR1_VAL (0x0001 | RTT_NOM | DRAM_RON) + +/* MR2 */ +#define MR2_CWL_9 0 +#define MR2_VAL (0x0000 | RTT_WR | MR2_CWL_9) + +/* MR3 ~ MR6 */ +#define MR3_VAL 0x0000 +#define MR4_VAL 0x0000 +#define MR5_VAL (0x0400 | RTT_PARK) +#define MR6_VAL 0x0400 + +/** + * The offset value applied to the DDR PHY write data eye training result + * to fine-tune the write DQ/DQS alignment + */ +#define WR_DATA_EYE_OFFSET (0x10 << 8) + #if defined(CONFIG_ASPEED_DDR4_800) u32 ast2600_sdramphy_config[165] = { 0x1e6e0100, // start address @@ -35,7 +148,7 @@ u32 ast2600_sdramphy_config[165] = { 0x20000000, // phyr024 0x00000008, // phyr028 0x00000000, // phyr02c - 0x00077600, // phyr030 + (PHY_RON | PHY_ODT), /* phyr030 */ 0x00000000, // phyr034 0x00000000, // phyr038 0x20000000, // phyr03c @@ -44,18 +157,18 @@ u32 ast2600_sdramphy_config[165] = { 0x00002f07, // phyr048 0x00003080, // phyr04c 0x04000000, // phyr050 - 0x00000200, // phyr054 - 0x03140201, // phyr058 - 0x04800000, // phyr05c - 0x0800044e, // phyr060 + ((MR3_VAL << 16) | MR2_VAL), /* phyr054 */ + ((MR0_VAL << 16) | MR1_VAL), /* phyr058 */ + ((MR5_VAL << 16) | MR4_VAL), /* phyr05c */ + ((0x0800 << 16) | MR6_VAL | VREFDQ_RANGE_2 | 0xe), /* phyr060 */ 0x00000000, // phyr064 0x00180008, // phyr068 0x00e00400, // phyr06c 0x00140206, // phyr070 0x1d4c0000, // phyr074 - 0x493e0107, // phyr078 + (0x493e0100 | T_PHY_WRLAT), /* phyr078 */ 0x08060404, // phyr07c - 0x90000a00, // phyr080 + (0x90000000 | T_RDDATA_EN), /* phyr080 */ 0x06420618, // phyr084 0x00001002, // phyr088 0x05701016, // phyr08c @@ -94,7 +207,7 @@ u32 ast2600_sdramphy_config[165] = { 0x20202020, // phyr09c 0x20202020, // phyr0a0 0x00002020, // phyr0a4 - 0x80000000, // phyr0a8 + 0x00000000, /* phyr0a8 */ 0x00000001, // phyr0ac 0xaeeddeea, // change address 0x1e6e0318, // new address @@ -154,7 +267,7 @@ u32 ast2600_sdramphy_config[165] = { 0x20202020, // phyr170 0xaeeddeea, // change address 0x1e6e0298, // new address - 0x20200800, // phyr198 + 0x20200000, /* phyr198 */ 0x20202020, // phyr19c 0x20202020, // phyr1a0 0x20202020, // phyr1a4 @@ -177,7 +290,7 @@ u32 ast2600_sdramphy_config[165] = { 0x00002020, // phyr1e8 0xaeeddeea, // change address 0x1e6e0304, // new address - 0x00000800, // phyr204 + (0x00000001 | WR_DATA_EYE_OFFSET), /* phyr204 */ 0xaeeddeea, // change address 0x1e6e027c, // new address 0x4e400000, // phyr17c @@ -203,7 +316,7 @@ u32 ast2600_sdramphy_config[165] = { 0x20000000, // phyr024 0x00000008, // phyr028 0x00000000, // phyr02c - 0x00077600, // phyr030 + (PHY_RON | PHY_ODT), /* phyr030 */ 0x00000000, // phyr034 0x00000000, // phyr038 0x20000000, // phyr03c @@ -212,18 +325,18 @@ u32 ast2600_sdramphy_config[165] = { 0x00002f07, // phyr048 0x00003080, // phyr04c 0x04000000, // phyr050 - 0x00000200, // phyr054 - 0x03140501, // phyr058-rtt:40 - 0x04800000, // phyr05c - 0x0800044e, // phyr060 + ((MR3_VAL << 16) | MR2_VAL), /* phyr054 */ + ((MR0_VAL << 16) | MR1_VAL), /* phyr058 */ + ((MR5_VAL << 16) | MR4_VAL), /* phyr05c */ + ((0x0800 << 16) | MR6_VAL | VREFDQ_RANGE_2 | 0xe), /* phyr060 */ 0x00000000, // phyr064 0x00180008, // phyr068 0x00e00400, // phyr06c 0x00140206, // phyr070 0x1d4c0000, // phyr074 - 0x493e0107, // phyr078 + (0x493e0100 | T_PHY_WRLAT), /* phyr078 */ 0x08060404, // phyr07c - 0x90000a00, // phyr080 + (0x90000000 | T_RDDATA_EN), /* phyr080 */ 0x06420c30, // phyr084 0x00001002, // phyr088 0x05701016, // phyr08c @@ -256,13 +369,13 @@ u32 ast2600_sdramphy_config[165] = { 0x00000000, // phyr200 0xaeeddeea, // change address 0x1e6e0194, // new address - 0x801112e0, // phyr094 - bit12=1,15=0,- write window is ok + 0x801112e0, // phyr094 0xaeeddeea, // change address 0x1e6e019c, // new address 0x20202020, // phyr09c 0x20202020, // phyr0a0 0x00002020, // phyr0a4 - 0x80000000, // phyr0a8 + 0x00000000, /* phyr0a8 */ 0x00000001, // phyr0ac 0xaeeddeea, // change address 0x1e6e0318, // new address @@ -322,7 +435,7 @@ u32 ast2600_sdramphy_config[165] = { 0x20202020, // phyr170 0xaeeddeea, // change address 0x1e6e0298, // new address - 0x20200800, // phyr198 + 0x20200000, /* phyr198 */ 0x20202020, // phyr19c 0x20202020, // phyr1a0 0x20202020, // phyr1a4 @@ -345,7 +458,7 @@ u32 ast2600_sdramphy_config[165] = { 0x00002020, // phyr1e8 0xaeeddeea, // change address 0x1e6e0304, // new address - 0x00000800, // phyr204 + (0x00000001 | WR_DATA_EYE_OFFSET), /* phyr204 */ 0xaeeddeea, // change address 0x1e6e027c, // new address 0x4e400000, // phyr17c @@ -388,10 +501,10 @@ u32 ast2600_sdramphy_config[165] = { * AC timing and SDRAM mode register setting * for real chip are derived from the model GDDR4-1600 */ -#define DDR4_MR01_MODE 0x03010510 -#define DDR4_MR23_MODE 0x00000000 -#define DDR4_MR45_MODE 0x04000000 -#define DDR4_MR6_MODE 0x00000400 +#define DDR4_MR01_MODE ((MR1_VAL << 16) | MR0_VAL) +#define DDR4_MR23_MODE ((MR3_VAL << 16) | MR2_VAL) +#define DDR4_MR45_MODE ((MR5_VAL << 16) | MR4_VAL) +#define DDR4_MR6_MODE MR6_VAL #define DDR4_TRFC_1600 0x467299f1 #define DDR4_TRFC_1333 0x3a5f80c9 #define DDR4_TRFC_800 0x23394c78

-----Original Message----- From: Dylan Hung dylan_hung@aspeedtech.com Sent: Friday, November 11, 2022 3:30 PM To: Ryan Chen ryan_chen@aspeedtech.com; ChiaWei Wang chiawei_wang@aspeedtech.com; joel@jms.id.au; Dylan Hung dylan_hung@aspeedtech.com; u-boot@lists.denx.de Cc: BMC-SW BMC-SW@aspeedtech.com Subject: [PATCH 2/3] ram: ast2600: Improve ddr4 timing and signal quality
Adjust the following settings to get better timing and signal quality.
- write DQS/DQ delay
- 1e6e2304[0]
- 1e6e2304[15:8]
- read DQS/DQ delay
- 0x1e6e0298[0]
- 0x1e6e0298[15:8]
- CLK/CA timing
- 0x1e6e01a8[31]
- Read and write termination
- change RTT_ROM from 40 ohm to 48 ohm (MR1[10:8])
- change RTT_PARK from disable to 48 ohm (MR5[8:6])
- change RTT_WR from 120 ohm to disable (MR2[11:9])
- change PHY ODT from 40 ohm to 80 ohm (0x1e6e0130[10:8])
Note1: Both DDR-PHY and DDR controller have their own registers for DDR4 Mode Registers (MR0~MR6). This patch introduces macros to synchronize the MR value on both sides.
Note2: the waveform meansurement can be found in item #21 of Aspeed AST26x0 Application note (AP note).
Signed-off-by: Dylan Hung dylan_hung@aspeedtech.com
Review-by: Ryan Chen ryan_chen@aspeedtech.com
drivers/ram/aspeed/sdram_ast2600.c | 163 ++++++++++++++++++++++++----- 1 file changed, 138 insertions(+), 25 deletions(-)
diff --git a/drivers/ram/aspeed/sdram_ast2600.c b/drivers/ram/aspeed/sdram_ast2600.c index b09232a30413..bda02d062900 100644 --- a/drivers/ram/aspeed/sdram_ast2600.c +++ b/drivers/ram/aspeed/sdram_ast2600.c @@ -20,6 +20,119 @@ #define DDR_PHY_TBL_CHG_ADDR 0xaeeddeea #define DDR_PHY_TBL_END 0xaeededed
+/**
- phyr030[18:16] - Ron PU (PHY side)
- phyr030[14:12] - Ron PD (PHY side)
- b'000 : disable
- b'001 : 240 ohm
- b'010 : 120 ohm
- b'011 : 80 ohm
- b'100 : 60 ohm
- b'101 : 48 ohm
- b'110 : 40 ohm
- b'111 : 34 ohm (default)
- */
+#define PHY_RON ((0x7 << 16) | (0x7 << 12))
+/**
- phyr030[10:8] - ODT configuration (PHY side)
- b'000 : ODT disabled
- b'001 : 240 ohm
- b'010 : 120 ohm
- b'011 : 80 ohm (default)
- b'100 : 60 ohm
- b'101 : 48 ohm
- b'110 : 40 ohm
- b'111 : 34 ohm
- */
+#define PHY_ODT (0x3 << 8)
+/**
- MR1[2:1] output driver impedance
- b'00 : 34 ohm (default)
- b'01 : 48 ohm
- */
+#define DRAM_RON (0x0 << 1)
+/**
- DRAM ODT - synchronous ODT mode
- RTT_WR: disable
- RTT_NOM = RTT_PARK
- MR1[10:8] RTT_NOM
- b'000 : RTT_NOM disable
- b'001 : 60 ohm
- b'010 : 120 ohm
- b'011 : 40 ohm
- b'100 : 240 ohm
- b'101 : 48 ohm (default)
- b'110 : 80 ohm
- b'111 : 34 ohm
- MR5[8:6] RTT_PARK
- b'000 : RTT_PARK disable
- b'001 : 60 ohm
- b'010 : 120 ohm
- b'011 : 40 ohm
- b'100 : 240 ohm
- b'101 : 48 ohm (default)
- b'110 : 80 ohm
- b'111 : 34 ohm
- MR2[11:9] RTT_WR
- b'000 : Dynamic ODT off (default)
- b'001 : 120 ohm
- b'010 : 240 ohm
- b'011 : Hi-Z
- b'100 : 80 ohm
- */
+#define RTT_WR (0x0 << 9) +#define RTT_NOM (0x5 << 8) +#define RTT_PARK (0x5 << 6)
+/**
- MR6[6] VrefDQ training range
- b'0 : range 1
- b'1 : range 2 (default)
- */
+#define VREFDQ_RANGE_2 BIT(6)
+/**
- Latency setting:
- AL = PL = 0 (hardware fixed setting)
- -> WL = AL + CWL + PL = CWL
- -> RL = AL + CL + PL = CL
- */
+#define CONFIG_WL 9 +#define CONFIG_RL 12 +#define T_RDDATA_EN ((CONFIG_RL - 2) << 8) +#define T_PHY_WRLAT (CONFIG_WL - 2)
+/* MR0 */ +#define MR0_CL_12 (BIT(4) | BIT(2)) +#define MR0_WR12_RTP6 BIT(9) +#define MR0_DLL_RESET BIT(8) +#define MR0_VAL (MR0_CL_12 | MR0_WR12_RTP6 | MR0_DLL_RESET)
+/* MR1 */ +#define MR1_VAL (0x0001 | RTT_NOM | DRAM_RON)
+/* MR2 */ +#define MR2_CWL_9 0 +#define MR2_VAL (0x0000 | RTT_WR | MR2_CWL_9)
+/* MR3 ~ MR6 */ +#define MR3_VAL 0x0000 +#define MR4_VAL 0x0000 +#define MR5_VAL (0x0400 | RTT_PARK) +#define MR6_VAL 0x0400
+/**
- The offset value applied to the DDR PHY write data eye training
+result
- to fine-tune the write DQ/DQS alignment */
+#define WR_DATA_EYE_OFFSET (0x10 << 8)
#if defined(CONFIG_ASPEED_DDR4_800) u32 ast2600_sdramphy_config[165] = { 0x1e6e0100, // start address @@ -35,7 +148,7 @@ u32 ast2600_sdramphy_config[165] = { 0x20000000, // phyr024 0x00000008, // phyr028 0x00000000, // phyr02c
- 0x00077600, // phyr030
- (PHY_RON | PHY_ODT), /* phyr030 */ 0x00000000, // phyr034 0x00000000, // phyr038 0x20000000, // phyr03c
@@ -44,18 +157,18 @@ u32 ast2600_sdramphy_config[165] = { 0x00002f07, // phyr048 0x00003080, // phyr04c 0x04000000, // phyr050
- 0x00000200, // phyr054
- 0x03140201, // phyr058
- 0x04800000, // phyr05c
- 0x0800044e, // phyr060
- ((MR3_VAL << 16) | MR2_VAL), /* phyr054 */
- ((MR0_VAL << 16) | MR1_VAL), /* phyr058 */
- ((MR5_VAL << 16) | MR4_VAL), /* phyr05c */
- ((0x0800 << 16) | MR6_VAL | VREFDQ_RANGE_2 | 0xe), /* phyr060 */ 0x00000000, // phyr064 0x00180008, // phyr068 0x00e00400, // phyr06c 0x00140206, // phyr070 0x1d4c0000, // phyr074
- 0x493e0107, // phyr078
- (0x493e0100 | T_PHY_WRLAT), /* phyr078 */ 0x08060404, // phyr07c
- 0x90000a00, // phyr080
- (0x90000000 | T_RDDATA_EN), /* phyr080 */ 0x06420618, // phyr084 0x00001002, // phyr088 0x05701016, // phyr08c
@@ -94,7 +207,7 @@ u32 ast2600_sdramphy_config[165] = { 0x20202020, // phyr09c 0x20202020, // phyr0a0 0x00002020, // phyr0a4
- 0x80000000, // phyr0a8
- 0x00000000, /* phyr0a8 */ 0x00000001, // phyr0ac 0xaeeddeea, // change address 0x1e6e0318, // new address
@@ -154,7 +267,7 @@ u32 ast2600_sdramphy_config[165] = { 0x20202020, // phyr170 0xaeeddeea, // change address 0x1e6e0298, // new address
- 0x20200800, // phyr198
- 0x20200000, /* phyr198 */ 0x20202020, // phyr19c 0x20202020, // phyr1a0 0x20202020, // phyr1a4
@@ -177,7 +290,7 @@ u32 ast2600_sdramphy_config[165] = { 0x00002020, // phyr1e8 0xaeeddeea, // change address 0x1e6e0304, // new address
- 0x00000800, // phyr204
- (0x00000001 | WR_DATA_EYE_OFFSET), /* phyr204 */ 0xaeeddeea, // change address 0x1e6e027c, // new address 0x4e400000, // phyr17c
@@ -203,7 +316,7 @@ u32 ast2600_sdramphy_config[165] = { 0x20000000, // phyr024 0x00000008, // phyr028 0x00000000, // phyr02c
- 0x00077600, // phyr030
- (PHY_RON | PHY_ODT), /* phyr030 */ 0x00000000, // phyr034 0x00000000, // phyr038 0x20000000, // phyr03c
@@ -212,18 +325,18 @@ u32 ast2600_sdramphy_config[165] = { 0x00002f07, // phyr048 0x00003080, // phyr04c 0x04000000, // phyr050
- 0x00000200, // phyr054
- 0x03140501, // phyr058-rtt:40
- 0x04800000, // phyr05c
- 0x0800044e, // phyr060
- ((MR3_VAL << 16) | MR2_VAL), /* phyr054 */
- ((MR0_VAL << 16) | MR1_VAL), /* phyr058 */
- ((MR5_VAL << 16) | MR4_VAL), /* phyr05c */
- ((0x0800 << 16) | MR6_VAL | VREFDQ_RANGE_2 | 0xe), /* phyr060 */ 0x00000000, // phyr064 0x00180008, // phyr068 0x00e00400, // phyr06c 0x00140206, // phyr070 0x1d4c0000, // phyr074
- 0x493e0107, // phyr078
- (0x493e0100 | T_PHY_WRLAT), /* phyr078 */ 0x08060404, // phyr07c
- 0x90000a00, // phyr080
- (0x90000000 | T_RDDATA_EN), /* phyr080 */ 0x06420c30, // phyr084 0x00001002, // phyr088 0x05701016, // phyr08c
@@ -256,13 +369,13 @@ u32 ast2600_sdramphy_config[165] = { 0x00000000, // phyr200 0xaeeddeea, // change address 0x1e6e0194, // new address
- 0x801112e0, // phyr094 - bit12=1,15=0,- write window is ok
- 0x801112e0, // phyr094 0xaeeddeea, // change address 0x1e6e019c, // new address 0x20202020, // phyr09c 0x20202020, // phyr0a0 0x00002020, // phyr0a4
- 0x80000000, // phyr0a8
- 0x00000000, /* phyr0a8 */ 0x00000001, // phyr0ac 0xaeeddeea, // change address 0x1e6e0318, // new address
@@ -322,7 +435,7 @@ u32 ast2600_sdramphy_config[165] = { 0x20202020, // phyr170 0xaeeddeea, // change address 0x1e6e0298, // new address
- 0x20200800, // phyr198
- 0x20200000, /* phyr198 */ 0x20202020, // phyr19c 0x20202020, // phyr1a0 0x20202020, // phyr1a4
@@ -345,7 +458,7 @@ u32 ast2600_sdramphy_config[165] = { 0x00002020, // phyr1e8 0xaeeddeea, // change address 0x1e6e0304, // new address
- 0x00000800, // phyr204
- (0x00000001 | WR_DATA_EYE_OFFSET), /* phyr204 */ 0xaeeddeea, // change address 0x1e6e027c, // new address 0x4e400000, // phyr17c
@@ -388,10 +501,10 @@ u32 ast2600_sdramphy_config[165] = {
- AC timing and SDRAM mode register setting
- for real chip are derived from the model GDDR4-1600
*/ -#define DDR4_MR01_MODE 0x03010510 -#define DDR4_MR23_MODE 0x00000000 -#define DDR4_MR45_MODE 0x04000000 -#define DDR4_MR6_MODE 0x00000400 +#define DDR4_MR01_MODE ((MR1_VAL << 16) | MR0_VAL) +#define DDR4_MR23_MODE ((MR3_VAL << 16) | MR2_VAL) +#define DDR4_MR45_MODE ((MR5_VAL << 16) | MR4_VAL) +#define DDR4_MR6_MODE MR6_VAL #define DDR4_TRFC_1600 0x467299f1 #define DDR4_TRFC_1333 0x3a5f80c9
#define DDR4_TRFC_800 0x23394c78
2.25.1

On Fri, Nov 11, 2022 at 03:30:07PM +0800, Dylan Hung wrote:
Adjust the following settings to get better timing and signal quality.
- write DQS/DQ delay
- 1e6e2304[0]
- 1e6e2304[15:8]
- read DQS/DQ delay
- 0x1e6e0298[0]
- 0x1e6e0298[15:8]
- CLK/CA timing
- 0x1e6e01a8[31]
- Read and write termination
- change RTT_ROM from 40 ohm to 48 ohm (MR1[10:8])
- change RTT_PARK from disable to 48 ohm (MR5[8:6])
- change RTT_WR from 120 ohm to disable (MR2[11:9])
- change PHY ODT from 40 ohm to 80 ohm (0x1e6e0130[10:8])
Note1: Both DDR-PHY and DDR controller have their own registers for DDR4 Mode Registers (MR0~MR6). This patch introduces macros to synchronize the MR value on both sides.
Note2: the waveform meansurement can be found in item #21 of Aspeed AST26x0 Application note (AP note).
Signed-off-by: Dylan Hung dylan_hung@aspeedtech.com
Applied to u-boot/master, thanks!

Use macro to represent the RL and WL setting to ensure the PHY and controller setting are aligned.
Signed-off-by: Dylan Hung dylan_hung@aspeedtech.com --- arch/arm/include/asm/arch-aspeed/sdram_ast2600.h | 4 ++++ drivers/ram/aspeed/sdram_ast2600.c | 9 +++++++++ 2 files changed, 13 insertions(+)
diff --git a/arch/arm/include/asm/arch-aspeed/sdram_ast2600.h b/arch/arm/include/asm/arch-aspeed/sdram_ast2600.h index d2408c0020f8..b0a91ae40d44 100644 --- a/arch/arm/include/asm/arch-aspeed/sdram_ast2600.h +++ b/arch/arm/include/asm/arch-aspeed/sdram_ast2600.h @@ -104,6 +104,10 @@ #define SDRAM_FORCE_PRECHARGE_EN BIT(4) #define SDRAM_REFRESH_EN BIT(0)
+/* MCR14 */ +#define SDRAM_WL_SETTING GENMASK(23, 20) +#define SDRAM_CL_SETTING GENMASK(19, 16) + #define SDRAM_TEST_LEN_SHIFT 4 #define SDRAM_TEST_LEN_MASK 0xfffff #define SDRAM_TEST_START_ADDR_SHIFT 24 diff --git a/drivers/ram/aspeed/sdram_ast2600.c b/drivers/ram/aspeed/sdram_ast2600.c index bda02d062900..5d426088be3e 100644 --- a/drivers/ram/aspeed/sdram_ast2600.c +++ b/drivers/ram/aspeed/sdram_ast2600.c @@ -15,6 +15,7 @@ #include <asm/global_data.h> #include <linux/err.h> #include <linux/kernel.h> +#include <linux/bitfield.h> #include <dt-bindings/clock/ast2600-clock.h>
#define DDR_PHY_TBL_CHG_ADDR 0xaeeddeea @@ -935,6 +936,7 @@ static void ast2600_sdrammc_lock(struct dram_info *info) static void ast2600_sdrammc_common_init(struct ast2600_sdrammc_regs *regs) { int i; + u32 reg;
writel(MCR34_MREQI_DIS | MCR34_RESETN_DIS, ®s->power_ctrl); writel(SDRAM_VIDEO_UNLOCK_KEY, ®s->gm_protection_key); @@ -969,6 +971,13 @@ static void ast2600_sdrammc_common_init(struct ast2600_sdrammc_regs *regs) for (i = 0; i < ARRAY_SIZE(ddr4_ac_timing); ++i) writel(ddr4_ac_timing[i], ®s->ac_timing[i]);
+ /* update CL and WL */ + reg = readl(®s->ac_timing[1]); + reg &= ~(SDRAM_WL_SETTING | SDRAM_CL_SETTING); + reg |= FIELD_PREP(SDRAM_WL_SETTING, CONFIG_WL - 5) | + FIELD_PREP(SDRAM_CL_SETTING, CONFIG_RL - 5); + writel(reg, ®s->ac_timing[1]); + writel(DDR4_MR01_MODE, ®s->mr01_mode_setting); writel(DDR4_MR23_MODE, ®s->mr23_mode_setting); writel(DDR4_MR45_MODE, ®s->mr45_mode_setting);

-----Original Message----- From: Dylan Hung dylan_hung@aspeedtech.com Sent: Friday, November 11, 2022 3:30 PM To: Ryan Chen ryan_chen@aspeedtech.com; ChiaWei Wang chiawei_wang@aspeedtech.com; joel@jms.id.au; Dylan Hung dylan_hung@aspeedtech.com; u-boot@lists.denx.de Cc: BMC-SW BMC-SW@aspeedtech.com Subject: [PATCH 3/3] ram: ast2600: Align the RL and WL setting
Use macro to represent the RL and WL setting to ensure the PHY and controller setting are aligned.
Signed-off-by: Dylan Hung dylan_hung@aspeedtech.com
Review-by: Ryan Chen ryan_chen@aspeedtech.com
arch/arm/include/asm/arch-aspeed/sdram_ast2600.h | 4 ++++ drivers/ram/aspeed/sdram_ast2600.c | 9 +++++++++ 2 files changed, 13 insertions(+)
diff --git a/arch/arm/include/asm/arch-aspeed/sdram_ast2600.h b/arch/arm/include/asm/arch-aspeed/sdram_ast2600.h index d2408c0020f8..b0a91ae40d44 100644 --- a/arch/arm/include/asm/arch-aspeed/sdram_ast2600.h +++ b/arch/arm/include/asm/arch-aspeed/sdram_ast2600.h @@ -104,6 +104,10 @@ #define SDRAM_FORCE_PRECHARGE_EN BIT(4) #define SDRAM_REFRESH_EN BIT(0)
+/* MCR14 */ +#define SDRAM_WL_SETTING GENMASK(23, 20) +#define SDRAM_CL_SETTING GENMASK(19, 16)
#define SDRAM_TEST_LEN_SHIFT 4 #define SDRAM_TEST_LEN_MASK 0xfffff #define SDRAM_TEST_START_ADDR_SHIFT 24 diff --git a/drivers/ram/aspeed/sdram_ast2600.c b/drivers/ram/aspeed/sdram_ast2600.c index bda02d062900..5d426088be3e 100644 --- a/drivers/ram/aspeed/sdram_ast2600.c +++ b/drivers/ram/aspeed/sdram_ast2600.c @@ -15,6 +15,7 @@ #include <asm/global_data.h> #include <linux/err.h> #include <linux/kernel.h> +#include <linux/bitfield.h> #include <dt-bindings/clock/ast2600-clock.h>
#define DDR_PHY_TBL_CHG_ADDR 0xaeeddeea @@ -935,6 +936,7 @@ static void ast2600_sdrammc_lock(struct dram_info *info) static void ast2600_sdrammc_common_init(struct ast2600_sdrammc_regs *regs) { int i;
u32 reg;
writel(MCR34_MREQI_DIS | MCR34_RESETN_DIS, ®s->power_ctrl); writel(SDRAM_VIDEO_UNLOCK_KEY, ®s->gm_protection_key); @@
-969,6 +971,13 @@ static void ast2600_sdrammc_common_init(struct ast2600_sdrammc_regs *regs) for (i = 0; i < ARRAY_SIZE(ddr4_ac_timing); ++i) writel(ddr4_ac_timing[i], ®s->ac_timing[i]);
- /* update CL and WL */
- reg = readl(®s->ac_timing[1]);
- reg &= ~(SDRAM_WL_SETTING | SDRAM_CL_SETTING);
- reg |= FIELD_PREP(SDRAM_WL_SETTING, CONFIG_WL - 5) |
FIELD_PREP(SDRAM_CL_SETTING, CONFIG_RL - 5);
- writel(reg, ®s->ac_timing[1]);
- writel(DDR4_MR01_MODE, ®s->mr01_mode_setting); writel(DDR4_MR23_MODE, ®s->mr23_mode_setting); writel(DDR4_MR45_MODE, ®s->mr45_mode_setting);
-- 2.25.1

On Fri, Nov 11, 2022 at 03:30:08PM +0800, Dylan Hung wrote:
Use macro to represent the RL and WL setting to ensure the PHY and controller setting are aligned.
Signed-off-by: Dylan Hung dylan_hung@aspeedtech.com
Applied to u-boot/master, thanks!
participants (3)
-
Dylan Hung
-
Ryan Chen
-
Tom Rini