summaryrefslogtreecommitdiff
path: root/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c
diff options
context:
space:
mode:
authorYu-Ping Wu <yupingso@chromium.org>2019-10-07 15:55:57 +0800
committerPatrick Georgi <pgeorgi@google.com>2019-10-17 15:03:03 +0000
commitffb5ea3dc4b1189f39bdd4a2e288f0b973e759c1 (patch)
tree41c8036f56d2841e963d2df594365188ab7f73ec /src/soc/mediatek/mt8183/dramc_pi_calibration_api.c
parent7689a0f7921d49a8e8f68f7c054881b13a642450 (diff)
downloadcoreboot-ffb5ea3dc4b1189f39bdd4a2e288f0b973e759c1.tar.xz
soc/mediatek/mt8183: Handle memory test failure
If DRAM calibration fails or mem test fails using the cached calibration results stored in flash, rerun DRAM full calibration. If partial calibration fails or the mem test following it fails, hang forever. Partial calibration acts as a fallback approach in case of full calibration failure. Therefore, if it fails, there would be no other ways to initialize DRAM. Instead of falling into reboot loop and draining out of battery, it is better to just hang so that the end user may notice that and send to RMA. BUG=b:80501386,b:139099592 BRANCH=kukui TEST=Boots correctly on Kukui Change-Id: I8e1d4f5bc7b45f45a8bfef74e86ec0ff6a556af4 Signed-off-by: Huayang Duan <huayang.duan@mediatek.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/35481 Reviewed-by: Hung-Te Lin <hungte@chromium.org> Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/soc/mediatek/mt8183/dramc_pi_calibration_api.c')
-rw-r--r--src/soc/mediatek/mt8183/dramc_pi_calibration_api.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c b/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c
index 6537af0987..711e4bc6cc 100644
--- a/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c
+++ b/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c
@@ -1969,11 +1969,13 @@ static void dramc_dle_factor_handler(u8 chn, u8 val, u8 freq_group)
}
static u8 dramc_rx_datlat_cal(u8 chn, u8 rank, u8 freq_group,
- const struct sdram_params *params, const bool fast_calib)
+ const struct sdram_params *params, const bool fast_calib,
+ bool *test_passed)
{
- u32 datlat, begin = 0, first = 0, sum = 0, best_step;
+ u32 datlat, begin = 0, first = 0, sum = 0, best_step;
u32 datlat_start = 7;
+ *test_passed = true;
best_step = read32(&ch[chn].ao.shu[0].conf[1]) & SHU_CONF1_DATLAT_MASK;
dramc_dbg("[DATLAT] start. CH%d RK%d DATLAT Default: 0x%x\n",
@@ -2010,7 +2012,11 @@ static u8 dramc_rx_datlat_cal(u8 chn, u8 rank, u8 freq_group,
dramc_engine2_end(chn, dummy_rd_backup);
- assert(sum != 0);
+ *test_passed = (sum != 0);
+ if (!*test_passed) {
+ dramc_show("DRAM memory test failed\n");
+ return 0;
+ }
if (sum <= 3)
best_step = first + (sum >> 1);
@@ -2111,7 +2117,7 @@ static void dramc_rx_dqs_gating_post_process(u8 chn, u8 freq_group)
(0xff << 8) | (0x9 << 2) | ROEN);
}
-void dramc_calibrate_all_channels(const struct sdram_params *pams, u8 freq_group)
+int dramc_calibrate_all_channels(const struct sdram_params *pams, u8 freq_group)
{
bool fast_calib;
switch (pams->source) {
@@ -2123,9 +2129,10 @@ void dramc_calibrate_all_channels(const struct sdram_params *pams, u8 freq_group
break;
default:
die("Invalid DRAM param source %u\n", pams->source);
- return;
+ return -1;
}
+ bool test_passed;
u8 rx_datlat[RANK_MAX] = {0};
for (u8 chn = 0; chn < CHANNEL_MAX; chn++) {
for (u8 rk = RANK_0; rk < RANK_MAX; rk++) {
@@ -2144,7 +2151,9 @@ void dramc_calibrate_all_channels(const struct sdram_params *pams, u8 freq_group
dramc_window_perbit_cal(chn, rk, freq_group,
TX_WIN_DQ_ONLY, pams, fast_calib);
rx_datlat[rk] = dramc_rx_datlat_cal(chn, rk, freq_group,
- pams, fast_calib);
+ pams, fast_calib, &test_passed);
+ if (!test_passed)
+ return -2;
dramc_window_perbit_cal(chn, rk, freq_group,
RX_WIN_TEST_ENG, pams, fast_calib);
}
@@ -2152,4 +2161,5 @@ void dramc_calibrate_all_channels(const struct sdram_params *pams, u8 freq_group
dramc_rx_dqs_gating_post_process(chn, freq_group);
dramc_dual_rank_rx_datlat_cal(chn, freq_group, rx_datlat[0], rx_datlat[1]);
}
+ return 0;
}