[coreboot-gerrit] New patch to review for coreboot: rockchip/rk3399: sdram: fix data training function

Patrick Georgi (pgeorgi@google.com) gerrit at coreboot.org
Mon Oct 24 12:11:47 CEST 2016


Patrick Georgi (pgeorgi at google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17105

-gerrit

commit f7d75ae54f725e87aabc0403c3647234b6bb7044
Author: Lin Huang <hl at rock-chips.com>
Date:   Sun Oct 9 09:37:10 2016 +0800

    rockchip/rk3399: sdram: fix data training function
    
    1. override write leveing value to 0x200.
    When the wrdqs slave delay is changed to 0x200, the phase between dqs
    and the clock is 0 degrees. The pcb layout can make sure tDQSS timing
    is smaller than 0.25tck, so this value is useful for both higher and
    lower frequencies.
    
    2. disable read leveing for LPDDR3.
    Read leveing result is unreliable,the value is not in the middle of
    read eye. So disable read leveing and fix the read DQSn slave delay
    setting for DQn to 0x080(1/4 cycle delay of the input signal).
    
    Check by shmoo read eye and stability test, fix to 0x80 is better.
    
    BUG=None
    BRANCH=None
    TEST=Boot from kevin
    
    Change-Id: Ia72b601d9bf4e34ba1b0b4584b2c5c3ce9dafbd4
    Signed-off-by: Patrick Georgi <pgeorgi at chromium.org>
    Original-Commit-Id: 37e8dfe783db3ce71aa026b4609ed0bfa16db06f
    Original-Change-Id: I2a5d40c0348449b2a7c609c1db65da4ed5f1c09f
    Original-Signed-off-by: Lin Huang <hl at rock-chips.com>
    Original-Signed-off-by: Jeff Chen <cym at rock-chips.com>
    Original-Reviewed-on: https://chromium-review.googlesource.com/396598
    Original-Commit-Ready: Douglas Anderson <dianders at chromium.org>
    Original-Reviewed-by: Derek Basehore <dbasehore at chromium.org>
---
 src/soc/rockchip/rk3399/sdram.c | 83 ++++++++++-------------------------------
 1 file changed, 19 insertions(+), 64 deletions(-)

diff --git a/src/soc/rockchip/rk3399/sdram.c b/src/soc/rockchip/rk3399/sdram.c
index 688bdeb..945c0bc 100644
--- a/src/soc/rockchip/rk3399/sdram.c
+++ b/src/soc/rockchip/rk3399/sdram.c
@@ -587,67 +587,14 @@ static void select_per_cs_training_index(u32 channel, u32 rank)
 	}
 }
 
-/*
- * After write leveling for all ranks, check the PHY_CLK_WRDQS_SLAVE_DELAY
- * result, if the two ranks in one slice both met
- * "0x200-PHY_CLK_WRDQS_SLAVE_DELAY < 0x20 or
- * 0x200-PHY_CLK_WRDQS_SLAVE > 0x1E0",
- * enable PHY_WRLVL_EARLY_FORCE_ZERO for this slice, and trigger write
- * leveling again. Else no additional write leveling is required.
- */
-static void check_write_leveling_value(u32 channel,
-				       const struct rk3399_sdram_params
-				       *sdram_params)
+static void override_write_leveling_value(u32 channel)
 {
 	u32 *denali_ctl = rk3399_ddr_pctl[channel]->denali_ctl;
 	u32 *denali_phy = rk3399_ddr_publ[channel]->denali_phy;
-	u32 i, j;
-	u32 wl_value[2][4];
-	u32 rank = sdram_params->ch[channel].rank;
+	u32 byte;
 
-	for (i = 0; i < rank; i++) {
-		/*
-		 * PHY_8/136/264/392
-		 * phy_per_cs_training_index_X 1bit offset_24
-		 */
-		clrsetbits_le32(&denali_phy[8], 0x1 << 24, i << 24);
-		clrsetbits_le32(&denali_phy[136], 0x1 << 24, i << 24);
-		clrsetbits_le32(&denali_phy[264], 0x1 << 24, i << 24);
-		clrsetbits_le32(&denali_phy[392], 0x1 << 24, i << 24);
-		wl_value[i][0] = (read32(&denali_phy[63]) >> 16) & 0x3ff;
-		wl_value[i][1] = (read32(&denali_phy[191]) >> 16) & 0x3ff;
-		wl_value[i][2] = (read32(&denali_phy[319]) >> 16) & 0x3ff;
-		wl_value[i][3] = (read32(&denali_phy[447]) >> 16) & 0x3ff;
-	}
-
-	/*
-	 * PHY_8/136/264/392
-	 * phy_per_cs_training_multicast_en_X 1bit offset_16
-	 */
-	clrsetbits_le32(&denali_phy[8], 0x1 << 16, 0 << 16);
-	clrsetbits_le32(&denali_phy[136], 0x1 << 16, 0 << 16);
-	clrsetbits_le32(&denali_phy[264], 0x1 << 16, 0 << 16);
-	clrsetbits_le32(&denali_phy[392], 0x1 << 16, 0 << 16);
-
-	for (i = 0; i < rank; i++) {
-		clrsetbits_le32(&denali_phy[8], 0x1 << 24, i << 24);
-		clrsetbits_le32(&denali_phy[136], 0x1 << 24, i << 24);
-		clrsetbits_le32(&denali_phy[264], 0x1 << 24, i << 24);
-		clrsetbits_le32(&denali_phy[392], 0x1 << 24, i << 24);
-		for (j = 0; j < 4; j++) {
-			if (wl_value[i][j] < 0x80)
-				clrsetbits_le32(&denali_phy[63+j*128],
-						0x3ff << 16,
-						(wl_value[i][j]+0x200) << 16);
-			else if ((wl_value[i][j] >= 0x80) &&
-				 (wl_value[i][j] < 0x100))
-				clrsetbits_le32(&denali_phy[78+j*128],
-						0x7 << 8, 0x1 << 8);
-		}
-	}
-
-	/* CTL_200 ctrlupd_req 1bit offset_8 */
-	clrsetbits_le32(&denali_ctl[200], 0x1 << 8, 0x1 << 8);
+	/* PHY_896 PHY_FREQ_SEL_MULTICAST_EN 1bit offset_0 */
+	setbits_le32(&denali_phy[896], 1);
 
 	/*
 	 * PHY_8/136/264/392
@@ -657,6 +604,16 @@ static void check_write_leveling_value(u32 channel,
 	clrsetbits_le32(&denali_phy[136], 0x1 << 16, 1 << 16);
 	clrsetbits_le32(&denali_phy[264], 0x1 << 16, 1 << 16);
 	clrsetbits_le32(&denali_phy[392], 0x1 << 16, 1 << 16);
+
+	for (byte = 0; byte < 4; byte++)
+		clrsetbits_le32(&denali_phy[63 + (128 * byte)], 0xffff << 16,
+			0x200 << 16);
+
+	/* PHY_896 PHY_FREQ_SEL_MULTICAST_EN 1bit offset_0 */
+	clrbits_le32(&denali_phy[896], 1);
+
+	/* CTL_200 ctrlupd_req 1bit offset_8 */
+	clrsetbits_le32(&denali_ctl[200], 0x1 << 8, 0x1 << 8);
 }
 
 static int data_training(u32 channel,
@@ -679,8 +636,7 @@ static int data_training(u32 channel,
 					PI_READ_LEVELING | PI_WDQ_LEVELING;
 		} else if (sdram_params->dramtype == LPDDR3) {
 			training_flag = PI_CA_TRAINING | PI_WRITE_LEVELING |
-					PI_READ_GATE_TRAINING |
-					PI_READ_LEVELING;
+					PI_READ_GATE_TRAINING;
 		} else if (sdram_params->dramtype == DDR3) {
 			training_flag = PI_WRITE_LEVELING |
 					PI_READ_GATE_TRAINING |
@@ -761,18 +717,17 @@ static int data_training(u32 channel,
 				if ((((tmp >> 10) & 0x1) == 0x1) &&
 				    (((tmp >> 13) & 0x1) == 0x1) &&
 				    (((tmp >> 4) & 0x1) == 0x0) &&
-				    (obs_err == 0)) {
-					if ((rank == 2) && (i == 1))
-						check_write_leveling_value
-							(channel, sdram_params);
+				    (obs_err == 0))
 					break;
-				} else if ((((tmp >> 4) & 0x1) == 0x1) ||
+				else if ((((tmp >> 4) & 0x1) == 0x1) ||
 					 (obs_err == 1))
 					return -1;
 			}
 			/* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
 			write32((&denali_pi[175]), 0x00003f7c);
 		}
+
+		override_write_leveling_value(channel);
 		clrbits_le32(&denali_pi[60], 0x3 << 8);
 	}
 



More information about the coreboot-gerrit mailing list