Exynos5420: ddr3: fine tuning the DDR3 timing values
Fine tuning DDR timings value for better stability
* Changed Data Driver Strength from 34 ohms to 30 ohms, expected to
enhance signal integrity.
* Changed DQ signal from 0xf to 0x1f000f, to keep default value safe.
* Changed mrs[2] and added new mrs direct command for setting WL/RL
without resetting DLL.
* Added explicit reset value write in phy_con0 instead of just setting
a bit, to ensure that reset happens.
* Added DREX automatic control for ctrl_pd in none read memory state.
This is ported from: https://gerrit.chromium.org/gerrit/61405
Signed-off-by: David Hendricks <dhendrix@chromium.org>
BUG=none
BRANCH=none
TEST=booted on pit, suspend_stress_test --memory_check -c10 passed
Change-Id: I59e96e6dede7b49c6572548aca664d82ad110bb1
Reviewed-on: https://chromium-review.googlesource.com/66995
Reviewed-by: ron minnich <rminnich@chromium.org>
Commit-Queue: David Hendricks <dhendrix@chromium.org>
Tested-by: David Hendricks <dhendrix@chromium.org>
diff --git a/src/cpu/samsung/exynos5420/dmc.h b/src/cpu/samsung/exynos5420/dmc.h
index c974db2..89fac42 100644
--- a/src/cpu/samsung/exynos5420/dmc.h
+++ b/src/cpu/samsung/exynos5420/dmc.h
@@ -291,7 +291,7 @@
};
enum {
- MEM_TIMINGS_MSR_COUNT = 4,
+ MEM_TIMINGS_MSR_COUNT = 5,
};
diff --git a/src/cpu/samsung/exynos5420/dmc_init_ddr3.c b/src/cpu/samsung/exynos5420/dmc_init_ddr3.c
index e236e99..a758433 100644
--- a/src/cpu/samsung/exynos5420/dmc_init_ddr3.c
+++ b/src/cpu/samsung/exynos5420/dmc_init_ddr3.c
@@ -99,8 +99,8 @@
*/
val = (0x7 << CA_CK_DRVR_DS_OFFSET) | (0x7 << CA_CKE_DRVR_DS_OFFSET) |
(0x7 << CA_CS_DRVR_DS_OFFSET) | (0x7 << CA_ADR_DRVR_DS_OFFSET);
- val |= (0x6 << DA_3_DS_OFFSET) | (0x6 << DA_2_DS_OFFSET) |
- (0x6 << DA_1_DS_OFFSET) | (0x6 << DA_0_DS_OFFSET);
+ val |= (0x7 << DA_3_DS_OFFSET) | (0x7 << DA_2_DS_OFFSET) |
+ (0x7 << DA_1_DS_OFFSET) | (0x7 << DA_0_DS_OFFSET);
writel(val, &phy0_ctrl->phy_con39);
writel(val, &phy1_ctrl->phy_con39);
@@ -112,8 +112,12 @@
clrbits_le32(&phy1_ctrl->phy_con16, ZQ_CLK_DIV_EN);
/* DQ Signal */
- writel(mem->phy0_pulld_dqs, &phy0_ctrl->phy_con14);
- writel(mem->phy1_pulld_dqs, &phy1_ctrl->phy_con14);
+ val = readl(&phy0_ctrl->phy_con14);
+ val |= mem->phy0_pulld_dqs;
+ writel(val, &phy0_ctrl->phy_con14);
+ val = readl(&phy1_ctrl->phy_con14);
+ val |= mem->phy1_pulld_dqs;
+ writel(val, &phy1_ctrl->phy_con14);
val = MEM_TERM_EN | PHY_TERM_EN;
writel(val, &drex0->phycontrol0);
@@ -225,8 +229,8 @@
if (mem->gate_leveling_enable) {
- setbits_le32(&phy0_ctrl->phy_con0, CTRL_ATGATE);
- setbits_le32(&phy1_ctrl->phy_con0, CTRL_ATGATE);
+ writel(PHY_CON0_RESET_VAL, &phy0_ctrl->phy_con0);
+ writel(PHY_CON0_RESET_VAL, &phy1_ctrl->phy_con0);
setbits_le32(&phy0_ctrl->phy_con0, P0_CMD_EN);
setbits_le32(&phy1_ctrl->phy_con0, P0_CMD_EN);
@@ -236,12 +240,6 @@
writel(val, &phy0_ctrl->phy_con2);
writel(val, &phy1_ctrl->phy_con2);
- val = PHY_CON0_RESET_VAL;
- val |= P0_CMD_EN;
- val |= BYTE_RDLVL_EN;
- writel(val, &phy0_ctrl->phy_con0);
- writel(val, &phy1_ctrl->phy_con0);
-
val = readl(&phy0_ctrl->phy_con1);
val |= (RDLVL_PASS_ADJ_VAL << RDLVL_PASS_ADJ_OFFSET);
writel(val, &phy0_ctrl->phy_con1);
@@ -339,12 +337,18 @@
writel(mem->memcontrol, &drex0->memcontrol);
writel(mem->memcontrol, &drex1->memcontrol);
- /* Set DMC Concontrol and enable auto-refresh counter */
+ /*
+ * Set DMC Concontrol: Enable auto-refresh counter, provide
+ * read data fetch cycles and enable DREX auto set powerdown
+ * for input buffer of I/O in none read memory state.
+ */
writel(mem->concontrol | (mem->aref_en << CONCONTROL_AREF_EN_SHIFT) |
- (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT),
+ (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT)|
+ DMC_CONCONTROL_IO_PD_CON(0x2),
&drex0->concontrol);
writel(mem->concontrol | (mem->aref_en << CONCONTROL_AREF_EN_SHIFT) |
- (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT),
+ (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT)|
+ DMC_CONCONTROL_IO_PD_CON(0x2),
&drex1->concontrol);
/* Enable Clock Gating Control for DMC
diff --git a/src/cpu/samsung/exynos5420/setup.h b/src/cpu/samsung/exynos5420/setup.h
index 9dc49d8..3bd36b2 100644
--- a/src/cpu/samsung/exynos5420/setup.h
+++ b/src/cpu/samsung/exynos5420/setup.h
@@ -181,6 +181,8 @@
#define CLK_DIV_FSYS1_VAL 0x04f13c4f
#define CLK_DIV_FSYS2_VAL 0x041d0000
+#define DMC_CONCONTROL_IO_PD_CON(x) (x << 6)
+
/* CLK_DIV_CPU1 */
#define HPM_RATIO 0x2
#define COPY_RATIO 0x0
diff --git a/src/mainboard/google/kirby/memory.c b/src/mainboard/google/kirby/memory.c
index 74f3e6e..48e5b1e 100644
--- a/src/mainboard/google/kirby/memory.c
+++ b/src/mainboard/google/kirby/memory.c
@@ -32,7 +32,8 @@
.mem_type = DDR_MODE_DDR3,
.frequency_mhz = 800,
.direct_cmd_msr = {
- 0x00020018, 0x00030000, 0x00010002, 0x00000d70
+ 0x00020018, 0x00030000, 0x00010046, 0x00000d70,
+ 0x00000c70
},
.timing_ref = 0x000000bb,
.timing_row = 0x6836650f,
diff --git a/src/mainboard/google/pit/memory.c b/src/mainboard/google/pit/memory.c
index 74f3e6e..ddd7aa0 100644
--- a/src/mainboard/google/pit/memory.c
+++ b/src/mainboard/google/pit/memory.c
@@ -32,7 +32,8 @@
.mem_type = DDR_MODE_DDR3,
.frequency_mhz = 800,
.direct_cmd_msr = {
- 0x00020018, 0x00030000, 0x00010002, 0x00000d70
+ 0x00020018, 0x00030000, 0x00010046, 0x00000d70,
+ 0x00000c70
},
.timing_ref = 0x000000bb,
.timing_row = 0x6836650f,
@@ -65,7 +66,7 @@
.rd_fetch = 0x3,
- .zq_mode_dds = 0x6,
+ .zq_mode_dds = 0x7,
.zq_mode_term = 0x1,
.zq_mode_noterm = 1,