From cf6526c21135f81acca43d1fcc4566d7c1a86681 Mon Sep 17 00:00:00 2001 From: PH Hsu Date: Tue, 17 May 2016 08:47:56 +0800 Subject: mt8173: dram: Add more sample points to improve dram timing margin BRANCH=none BUG=chrome-os-partner:52959 TEST=verified on elm-EVT SKU1/SKU2, Oak-rev5 2GB/4GB models. Change-Id: I228c629d9a3d6cd8fc5c4e8ba24cc52d5283b4e6 Signed-off-by: Martin Roth Original-Commit-Id: 3c19e7d Original-Change-Id: I22356aa8d196c4c126742cfc7e85cc693acd9b39 Original-Signed-off-by: PH Hsu Original-Reviewed-on: https://chromium-review.googlesource.com/347716 Original-Commit-Ready: Yidi Lin Original-Tested-by: Yidi Lin Original-Reviewed-by: Julius Werner Reviewed-on: https://review.coreboot.org/15115 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- .../oak/sdram_inf/sdram-lpddr3-K4E6E304EB-4GB.inc | 8 ++--- .../oak/sdram_inf/sdram-lpddr3-hynix-2GB.inc | 4 +-- .../oak/sdram_inf/sdram-lpddr3-hynix-4GB.inc | 10 +++--- src/soc/mediatek/mt8173/dramc_pi_basic_api.c | 6 ++++ src/soc/mediatek/mt8173/dramc_pi_calibration_api.c | 41 ++++++++++------------ 5 files changed, 36 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/mainboard/google/oak/sdram_inf/sdram-lpddr3-K4E6E304EB-4GB.inc b/src/mainboard/google/oak/sdram_inf/sdram-lpddr3-K4E6E304EB-4GB.inc index 3dd795d589..0fe16a6104 100644 --- a/src/mainboard/google/oak/sdram_inf/sdram-lpddr3-K4E6E304EB-4GB.inc +++ b/src/mainboard/google/oak/sdram_inf/sdram-lpddr3-K4E6E304EB-4GB.inc @@ -21,12 +21,12 @@ .gating_win = { [CHANNEL_A] = { - { 28, 56}, - { 28, 56} + { 28, 64}, + { 28, 64} }, [CHANNEL_B] = { - { 28, 56}, - { 28, 56} + { 28, 64}, + { 28, 64} } }, diff --git a/src/mainboard/google/oak/sdram_inf/sdram-lpddr3-hynix-2GB.inc b/src/mainboard/google/oak/sdram_inf/sdram-lpddr3-hynix-2GB.inc index 4e728e358a..578343b7c0 100644 --- a/src/mainboard/google/oak/sdram_inf/sdram-lpddr3-hynix-2GB.inc +++ b/src/mainboard/google/oak/sdram_inf/sdram-lpddr3-hynix-2GB.inc @@ -21,11 +21,11 @@ .gating_win = { [CHANNEL_A] = { - { 28, 56}, + { 28, 64}, { 0, 0} }, [CHANNEL_B] = { - { 28, 56}, + { 28, 64}, { 0, 0} } }, diff --git a/src/mainboard/google/oak/sdram_inf/sdram-lpddr3-hynix-4GB.inc b/src/mainboard/google/oak/sdram_inf/sdram-lpddr3-hynix-4GB.inc index 76a1aa9a94..099a07c1dc 100644 --- a/src/mainboard/google/oak/sdram_inf/sdram-lpddr3-hynix-4GB.inc +++ b/src/mainboard/google/oak/sdram_inf/sdram-lpddr3-hynix-4GB.inc @@ -21,18 +21,18 @@ .gating_win = { [CHANNEL_A] = { - { 28, 56}, - { 28, 56} + { 28, 64}, + { 28, 64} }, [CHANNEL_B] = { - { 28, 56}, - { 28, 56} + { 28, 64}, + { 28, 64} } }, .rx_dqs_dly = { [CHANNEL_A] = 0x110e0b0b, - [CHANNEL_B] = 0x12100d0d + [CHANNEL_B] = 0x0D100d0d }, .rx_dq_dly = { diff --git a/src/soc/mediatek/mt8173/dramc_pi_basic_api.c b/src/soc/mediatek/mt8173/dramc_pi_basic_api.c index ac28373a39..e3efec9cf8 100644 --- a/src/soc/mediatek/mt8173/dramc_pi_basic_api.c +++ b/src/soc/mediatek/mt8173/dramc_pi_basic_api.c @@ -539,8 +539,11 @@ void dramc_init(u32 channel, const struct mt8173_sdram_params *sdram_params) write32(&ch[channel].ao_regs->conf1, sdram_params->ac_timing.conf1); + /* bit 17,18 would bypass some dummy path */ write32(&ch[channel].ddrphy_regs->dqsgctl, 0x1 << 31 | 0x1 << 30 | + 0x1 << 17 | + 0x1 << 18 | 0x1 << 4 | 0x1 << 0); @@ -691,6 +694,9 @@ void dramc_phy_reset(u32 channel) void dramc_runtime_config(u32 channel, const struct mt8173_sdram_params *sdram_params) { + setbits_le32(&ch[channel].ddrphy_regs->dqsgctl, + BIT(17)|BIT(18)); + /* enable hw gating */ setbits_le32(&ch[channel].ao_regs->dqscal0, 1 << DQSCAL0_STBCALEN_SHIFT); diff --git a/src/soc/mediatek/mt8173/dramc_pi_calibration_api.c b/src/soc/mediatek/mt8173/dramc_pi_calibration_api.c index 1237b2e0ba..fa69f2e4c2 100644 --- a/src/soc/mediatek/mt8173/dramc_pi_calibration_api.c +++ b/src/soc/mediatek/mt8173/dramc_pi_calibration_api.c @@ -13,9 +13,9 @@ * GNU General Public License for more details. */ -#include -#include #include +#include +#include #include #include #include @@ -305,32 +305,28 @@ static int dqs_gw_test(u32 channel) static u8 dqs_gw_fine_tune_calib(u32 channel, u8 fine_val) { u8 i, opt_fine_val; - s8 gw_ret[3], delta[3] = {0, -16, 16}; + s8 delta[7] = {-48, -32, -16, 0, 16, 32, 48}; + int matches = 0, sum = 0; - for (i = 0; i < 3; i++) { - /* adjust gw fine tune */ + /* fine tune range from 0 to 127 */ + fine_val = min(max(fine_val, 0 - delta[0]), 127 - delta[6]); + + /* test gw fine tune */ + for (i = 0; i < ARRAY_SIZE(delta); i++) { opt_fine_val = fine_val + delta[i]; set_gw_fine_factor(channel, opt_fine_val, 0); - /* get gw test result */ - gw_ret[i] = dqs_gw_test(channel); + if (dqs_gw_test(channel)) { + matches++; + sum += delta[i]; + } } - /* start fine tune adjustment from default fine value */ - opt_fine_val = fine_val; - - if (gw_ret[0] && gw_ret[1] && gw_ret[2]) { - opt_fine_val += ((delta[0] + delta[1] + delta[2]) / 3); - } - else if (gw_ret[0] && gw_ret[1]) { - opt_fine_val += ((delta[0] + delta[1]) / 2); - } - else if (gw_ret[0] && gw_ret[2]) { - opt_fine_val += ((delta[0] + delta[2]) / 2); - } - else { /* abnormal test result, set to default fine tune value */ - printk(BIOS_ERR, "[GW] ERROR, No found fine tune!!!\n"); + if (matches == 0) { + die("[GW] ERROR, Fine-Tuning failed.\n"); } + opt_fine_val = fine_val + (sum / matches); + return opt_fine_val; } @@ -737,7 +733,8 @@ u8 rx_datlat_cal(u32 channel, u8 rank, if (err[0]) { /* dle test error */ - printk(BIOS_ERR, "[DLE] calibration ERROR!\n"); + printk(BIOS_ERR, "[DLE] CH:%d calibration ERROR CMP_ERR =%xh,\n", + channel, err[0]); } else { /* judge dle test result */ for (i = 0; i < DLE_TEST_NUM; i++) { -- cgit v1.2.3