Hello Duan huayang,
I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/44718
to review the following change.
Change subject: soc/mediatek/mt8192: Do rx dqs gating training ......................................................................
soc/mediatek/mt8192: Do rx dqs gating training
Signed-off-by: Huayang Duan huayang.duan@mediatek.com Change-Id: I141abc1fdd283f4898d0772736bc777e87017561 --- M src/soc/mediatek/mt8192/dramc_pi_calibration_api.c M src/soc/mediatek/mt8192/dramc_pi_main.c 2 files changed, 323 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/18/44718/1
diff --git a/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c b/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c index e531de0..8d65a67 100644 --- a/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c +++ b/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c @@ -18,6 +18,15 @@ }, };
+struct rxdqs_gating_best_win { + u8 dqsien_dly_mck[DQS_NUMBER]; + u8 dqsien_dly_ui[DQS_NUMBER]; + u8 dqsien_dly_pi[DQS_NUMBER]; + u8 dqsien_dly_mck_p1[DQS_NUMBER]; + u8 dqsien_dly_ui_p1[DQS_NUMBER]; + u8 dqsien_dly_pi_p1[DQS_NUMBER]; +}; + static const u8 imp_vref_sel[ODT_MAX][IMP_DRV_MAX] = { /* DRVP DRVN ODTP ODTN */ [ODT_OFF] = {0x37, 0x33, 0x00, 0x37}, @@ -1378,3 +1387,311 @@
dramc_set_broadcast(bc_bak); } + +static u8 rxdqs_gating_get_tx_dly_min(dram_freq_grp freq_group, + struct rxdqs_gating_best_win *rxdqs_best_win) +{ + u8 tx_dly_dqs_gated = 0, tx_dly_min = 0xff; + + for (u8 dqs = 0; dqs < DQS_NUMBER; dqs++) { + dramc_dbg("best DQS%d dly(MCK, UI, PI) = (%d, %d, %d)\n", dqs, + rxdqs_best_win->dqsien_dly_mck[dqs], + rxdqs_best_win->dqsien_dly_ui[dqs], + rxdqs_best_win->dqsien_dly_pi[dqs]); + + tx_dly_dqs_gated = (rxdqs_best_win->dqsien_dly_mck[dqs] << 4) + + rxdqs_best_win->dqsien_dly_ui[dqs]; + + if (freq_group != DDRFREQ_400) + tx_dly_dqs_gated >>= 3; + else + tx_dly_dqs_gated >>= 2; + + if (tx_dly_dqs_gated < tx_dly_min) + tx_dly_min = tx_dly_dqs_gated; + } + return tx_dly_min; +} + +static u8 rxdqs_gating_get_tx_dly_max(dram_freq_grp freq_group, + struct rxdqs_gating_best_win *rxdqs_best_win) +{ + u8 tx_dly_dqs_gated = 0, tx_dly_max = 0; + + for (u8 dqs = 0; dqs < DQS_NUMBER; dqs++) { + dramc_dbg("best DQS%d P1 dly(MCK, UI, PI) = (%d, %d, %d)\n", dqs, + rxdqs_best_win->dqsien_dly_mck_p1[dqs], + rxdqs_best_win->dqsien_dly_ui_p1[dqs], + rxdqs_best_win->dqsien_dly_pi_p1[dqs]); + + tx_dly_dqs_gated = (rxdqs_best_win->dqsien_dly_mck_p1[dqs] << 4) + + rxdqs_best_win->dqsien_dly_ui_p1[dqs]; + + if (freq_group != DDRFREQ_400) + tx_dly_dqs_gated >>= 3; + else + tx_dly_dqs_gated >>= 2; + + if (tx_dly_dqs_gated > tx_dly_max) + tx_dly_max = tx_dly_dqs_gated; + } + return tx_dly_max; +} + +void dramc_rx_dqs_gating_cal(const struct ddr_cali* cali, + u8 *tx_dly_min, u8 *tx_dly_max) +{ + u8 chn, rank; + u8 pi_per_ui, ui_per_mck, freq_div; + dram_freq_grp freq_group; + struct rxdqs_gating_best_win best_win = {0}; + const struct sdram_params *params = cali->params; + + chn = cali->chn; + rank = cali->rank; + freq_group = get_freq_group(cali); + + struct reg_bak regs_bak[] = { + {&ch[chn].ao.refctrl0}, + {&ch[chn].phy_ao.dvs_b[0].b0_dq6}, + {&ch[chn].phy_ao.dvs_b[1].b0_dq6}, + {&ch[chn].phy_ao.misc_stbcal1}, + {&ch[chn].phy_ao.misc_stbcal2}, + }; + for (size_t i = 0; i < ARRAY_SIZE(regs_bak); i++) + regs_bak[i].value = read32(regs_bak[i].addr); + + pi_per_ui = 32; + ui_per_mck = 16; + if (get_div_mode(cali) == DIV4_MODE) + freq_div = 2; + else + freq_div = 4; + + for (u8 dqs = 0; dqs < DQS_NUMBER; dqs++) { + best_win.dqsien_dly_mck[dqs] = params->gating_MCK[chn][rank][dqs]; + best_win.dqsien_dly_ui[dqs] = params->gating_UI[chn][rank][dqs]; + best_win.dqsien_dly_pi[dqs] = params->gating_PI[chn][rank][dqs]; + + /* Calculate P1 */ + best_win.dqsien_dly_ui_p1[dqs] = + best_win.dqsien_dly_mck[dqs] * ui_per_mck + + best_win.dqsien_dly_ui[dqs] + freq_div; + best_win.dqsien_dly_mck_p1[dqs] = + best_win.dqsien_dly_ui_p1[dqs] / ui_per_mck; + best_win.dqsien_dly_ui_p1[dqs] = + best_win.dqsien_dly_ui_p1[dqs] % ui_per_mck; + dramc_dbg("[FAST_K] CH%d RK%d best DQS%d dly(MCK, UI, PI) = (%d, %d, %d)\n", + chn, rank, dqs, best_win.dqsien_dly_mck[dqs], + best_win.dqsien_dly_ui[dqs], + best_win.dqsien_dly_pi[dqs]); + dramc_dbg("[FAST_K] CH%d RK%d best DQS%d P1 dly(MCK, UI, PI) = (%d, %d, %d)\n", + chn, rank, dqs, best_win.dqsien_dly_mck_p1[dqs], + best_win.dqsien_dly_ui_p1[dqs], + best_win.dqsien_dly_pi_p1[dqs]); + } + + *tx_dly_min = rxdqs_gating_get_tx_dly_min(freq_group, &best_win); + *tx_dly_max = rxdqs_gating_get_tx_dly_max(freq_group, &best_win); + + SET32_BITFIELDS(&ch[chn].phy_ao.byte[0].rk[rank].shu_dqsien_mck_ui_dly, + SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_MCK_P0_B0, best_win.dqsien_dly_mck[0], + SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_UI_P0_B0, best_win.dqsien_dly_ui[0], + SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_MCK_P1_B0, best_win.dqsien_dly_mck_p1[0], + SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_UI_P1_B0, best_win.dqsien_dly_ui_p1[0]); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[1].rk[rank].shu_dqsien_mck_ui_dly, + SHU_RK_B1_DQSIEN_MCK_UI_DLY_DQSIEN_MCK_P0_B1, best_win.dqsien_dly_mck[1], + SHU_RK_B1_DQSIEN_MCK_UI_DLY_DQSIEN_UI_P0_B1, best_win.dqsien_dly_ui[1], + SHU_RK_B1_DQSIEN_MCK_UI_DLY_DQSIEN_MCK_P1_B1, best_win.dqsien_dly_mck_p1[1], + SHU_RK_B1_DQSIEN_MCK_UI_DLY_DQSIEN_UI_P1_B1, best_win.dqsien_dly_ui_p1[1]); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[0].rk[rank].shu_rk_b0_dqsien_pi_dly, + SHU_RK_B0_DQSIEN_PI_DLY_DQSIEN_PI_B0, best_win.dqsien_dly_pi[0]); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[1].rk[rank].shu_rk_b0_dqsien_pi_dly, + SHU_RK_B1_DQSIEN_PI_DLY_DQSIEN_PI_B1, best_win.dqsien_dly_pi[1]); + + for (size_t i = 0; i < ARRAY_SIZE(regs_bak); i++) + write32(regs_bak[i].addr, regs_bak[i].value); + + dramc_phy_reset(chn); +} + +static void dramc_rx_dqs_gating_post_process_find_best_coarse( + const struct ddr_cali* cali, s8 change_dqs_inctl, u8 mck2ui_shift) +{ + u8 chn, rk; + u8 best_coarse_mck[RANK_MAX][DQS_NUMBER]; + u8 best_coarse_ui[RANK_MAX][DQS_NUMBER]; + u8 best_coarse_mck_P1[RANK_MAX][DQS_NUMBER]; + u8 best_coarse_ui_P1[RANK_MAX][DQS_NUMBER]; + u32 rank_sel_mck_p0[2], rank_sel_mck_p1[2]; + + chn = cali->chn; + for (rk = 0; rk < cali->support_ranks; rk++) { + best_coarse_mck[rk][0] = + READ32_BITFIELD(&ch[chn].phy_ao.byte[0].rk[rk].shu_dqsien_mck_ui_dly, + SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_MCK_P0_B0); + best_coarse_ui[rk][0] = + READ32_BITFIELD(&ch[chn].phy_ao.byte[0].rk[rk].shu_dqsien_mck_ui_dly, + SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_UI_P0_B0); + best_coarse_mck_P1[rk][0] = + READ32_BITFIELD(&ch[chn].phy_ao.byte[0].rk[rk].shu_dqsien_mck_ui_dly, + SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_MCK_P1_B0); + best_coarse_ui_P1[rk][0] = + READ32_BITFIELD(&ch[chn].phy_ao.byte[0].rk[rk].shu_dqsien_mck_ui_dly, + SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_UI_P1_B0); + + best_coarse_mck[rk][1] = + READ32_BITFIELD(&ch[chn].phy_ao.byte[1].rk[rk].shu_dqsien_mck_ui_dly, + SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_MCK_P0_B0); + best_coarse_ui[rk][1] = + READ32_BITFIELD(&ch[chn].phy_ao.byte[1].rk[rk].shu_dqsien_mck_ui_dly, + SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_UI_P0_B0); + best_coarse_mck_P1[rk][1] = + READ32_BITFIELD(&ch[chn].phy_ao.byte[1].rk[rk].shu_dqsien_mck_ui_dly, + SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_MCK_P1_B0); + best_coarse_ui_P1[rk][1] = + READ32_BITFIELD(&ch[chn].phy_ao.byte[1].rk[rk].shu_dqsien_mck_ui_dly, + SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_UI_P1_B0); + } + + if (change_dqs_inctl != 0) { + for (rk = 0; rk < cali->support_ranks; rk++) { + for (u8 dqs = 0; dqs < DQS_NUMBER; dqs++) { + u8 total_ui, total_ui_P1; + total_ui = (best_coarse_mck[rk][dqs] << 4) + + best_coarse_ui[rk][dqs]; + total_ui_P1 = (best_coarse_mck_P1[rk][dqs] << 4) + + best_coarse_ui_P1[rk][dqs]; + + total_ui += (change_dqs_inctl << mck2ui_shift); + total_ui_P1 += (change_dqs_inctl << mck2ui_shift); + + best_coarse_mck[rk][dqs] = (total_ui >> 4); + best_coarse_ui[rk][dqs] = total_ui & 0xf; + + best_coarse_mck_P1[rk][dqs] = (total_ui_P1 >> 4); + best_coarse_ui_P1[rk][dqs] = total_ui_P1 & 0xf; + dramc_dbg("best DQS%d dly(2T, 0.5T) = (%d, %d)\n", + dqs, best_coarse_mck[rk][dqs], + best_coarse_ui[rk][dqs]); + } + for (u8 dqs = 0; dqs < DQS_NUMBER; dqs++) + dramc_dbg("best DQS%d P1 dly(2T, 0.5T) = (%d, %d)\n", + dqs, best_coarse_mck_P1[rk][dqs], + best_coarse_ui_P1[rk][dqs]); + } + + for (rk = 0; rk < cali->support_ranks; rk++) { + SET32_BITFIELDS(&ch[chn].phy_ao.byte[0].rk[rk].shu_dqsien_mck_ui_dly, + SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_MCK_P0_B0, + best_coarse_mck[rk][0], + SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_UI_P0_B0, + best_coarse_ui[rk][0], + SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_MCK_P1_B0, + best_coarse_mck_P1[rk][0], + SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_UI_P1_B0, + best_coarse_ui_P1[rk][0]); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[1].rk[rk].shu_dqsien_mck_ui_dly, + SHU_RK_B1_DQSIEN_MCK_UI_DLY_DQSIEN_MCK_P0_B1, + best_coarse_mck[rk][1], + SHU_RK_B1_DQSIEN_MCK_UI_DLY_DQSIEN_UI_P0_B1, + best_coarse_ui[rk][1], + SHU_RK_B1_DQSIEN_MCK_UI_DLY_DQSIEN_MCK_P1_B1, + best_coarse_mck_P1[rk][1], + SHU_RK_B1_DQSIEN_MCK_UI_DLY_DQSIEN_UI_P1_B1, + best_coarse_ui_P1[rk][1]); + } + } + + for (u8 dqs = 0; dqs < DQS_NUMBER; dqs++) { + if (best_coarse_mck[RANK_0][dqs] > best_coarse_mck[RANK_1][dqs]) { + rank_sel_mck_p0[dqs] = (best_coarse_mck[RANK_0][dqs] > 0) ? + (best_coarse_mck[RANK_0][dqs] - 1) : 0; + rank_sel_mck_p1[dqs] = (best_coarse_mck_P1[RANK_0][dqs] > 0) ? + (best_coarse_mck_P1[RANK_0][dqs] - 1) : 0; + } else { + rank_sel_mck_p0[dqs] = (best_coarse_mck[RANK_1][dqs] > 0) ? + (best_coarse_mck[RANK_1][dqs] - 1) : 0; + rank_sel_mck_p1[dqs] = (best_coarse_mck_P1[RANK_1][dqs] > 0) ? + (best_coarse_mck_P1[RANK_1][dqs] - 1) : 0; + } + } + + SET32_BITFIELDS(&ch[chn].phy_ao.byte[0].shu_b0_rank_selph_ui_dly, + SHU_B0_RANK_SELPH_UI_DLY_RANKSEL_MCK_DLY_P0_B0, rank_sel_mck_p0[0], + SHU_B0_RANK_SELPH_UI_DLY_RANKSEL_MCK_DLY_P1_B0, rank_sel_mck_p1[0]); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[1].shu_b0_rank_selph_ui_dly, + SHU_B1_RANK_SELPH_UI_DLY_RANKSEL_MCK_DLY_P0_B1, rank_sel_mck_p0[1], + SHU_B1_RANK_SELPH_UI_DLY_RANKSEL_MCK_DLY_P1_B1, rank_sel_mck_p1[1]); +} + +void dramc_rx_dqs_gating_post_process(const struct ddr_cali* cali, + u8 tx_dly_min, u8 tx_dly_max) +{ + u8 chn, rank; + dram_freq_grp freq_group; + + u8 mck2ui_shift; + s8 change_dqs_inctl; + u16 phs_inctl = 0; + u32 read_dqs_inctl, rank_inctl_root, xrtr2r, tx_dly_dqs_gate_min = 0; + u32 rank_inctl_stb; + + chn = cali->chn; + rank = cali->rank; + freq_group = get_freq_group(cali); + + if (get_div_mode(cali) == DIV8_MODE) { + if (freq_group > DDRFREQ_1200) + tx_dly_dqs_gate_min = 2; + else + tx_dly_dqs_gate_min = 1; + mck2ui_shift = 3; + } else { + tx_dly_dqs_gate_min = 2; + mck2ui_shift = 2; + } + + change_dqs_inctl = tx_dly_dqs_gate_min - tx_dly_min; + dramc_dbg("[RxdqsGatingPostProcess] freq %d\n" + "ChangeDQSINCTL %d, tx_dly_dqs_gate_min %d, tx_dly_min %d\n", + get_frequency(cali), + change_dqs_inctl, tx_dly_dqs_gate_min, tx_dly_min); + + dramc_rx_dqs_gating_post_process_find_best_coarse(cali, change_dqs_inctl, mck2ui_shift); + + read_dqs_inctl = READ32_BITFIELD(&ch[chn].phy_ao.misc_rk[rank].misc_shu_rk_dqsctl, + MISC_SHU_RK_DQSCTL_DQSINCTL); + read_dqs_inctl -= change_dqs_inctl; + rank_inctl_stb = (read_dqs_inctl > 2) ? (read_dqs_inctl - 2) : 0; + phs_inctl = (read_dqs_inctl == 0) ? 0 : (read_dqs_inctl - 1); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_shu_rankctl, + MISC_SHU_RANKCTL_RANKINCTL_STB, rank_inctl_stb); + SET32_BITFIELDS(&ch[chn].phy_ao.shu_misc_rank_sel_stb, + SHU_MISC_RANK_SEL_STB_RANK_SEL_PHSINCTL, phs_inctl); + + if (read_dqs_inctl >= 2) + rank_inctl_root = read_dqs_inctl - 2; + else + rank_inctl_root = 0; + + SET32_BITFIELDS(&ch[chn].phy_ao.misc_rk[0].misc_shu_rk_dqsctl, + MISC_SHU_RK_DQSCTL_DQSINCTL, read_dqs_inctl); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_rk[1].misc_shu_rk_dqsctl, + MISC_SHU_RK_DQSCTL_DQSINCTL, read_dqs_inctl); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_shu_rankctl, + MISC_SHU_RANKCTL_RANKINCTL_PHY, read_dqs_inctl); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_shu_rankctl, + MISC_SHU_RANKCTL_RANKINCTL, rank_inctl_root); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_shu_rankctl, + MISC_SHU_RANKCTL_RANKINCTL_ROOT1, rank_inctl_root); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_shu_rankctl, + MISC_SHU_RANKCTL_RANKINCTL_RXDLY, rank_inctl_root); + xrtr2r = READ32_BITFIELD(&ch[chn].ao.shu_actim_xrt, + SHU_ACTIM_XRT_XRTR2R); + dramc_dbg("TX_dly_DQSgated check: min %d max %d, ChangeDQSINCTL=%d\n", + tx_dly_min, tx_dly_max, change_dqs_inctl); + dramc_dbg("DQSINCTL=%d, RANKINCTL=%d, xrtr2r=%d\n", + read_dqs_inctl, rank_inctl_root, xrtr2r); +} + diff --git a/src/soc/mediatek/mt8192/dramc_pi_main.c b/src/soc/mediatek/mt8192/dramc_pi_main.c index 2be3962..4b77c85 100644 --- a/src/soc/mediatek/mt8192/dramc_pi_main.c +++ b/src/soc/mediatek/mt8192/dramc_pi_main.c @@ -220,6 +220,7 @@
static void dramc_calibration_single_channel(struct ddr_cali *cali, u8 chn) { + u8 txdly_min, txdly_max; u8 dqs_final_delay[RANK_MAX][DQS_NUMBER];
cali->chn = chn; @@ -243,7 +244,12 @@ /* should disable the auto refresh before do write leveling */ dramc_auto_refresh_switch(chn, false); dramc_write_leveling(cali, dqs_final_delay); + + /* should enable the auto refresh before do RX and TX calibration */ + dramc_auto_refresh_switch(chn, true); + dramc_rx_dqs_gating_cal(cali, &txdly_min, &txdly_max); } + dramc_rx_dqs_gating_post_process(cali, txdly_min, txdly_max); }
static void dramc_calibration_all_channels(struct ddr_cali *cali)
build bot (Jenkins) has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/44718 )
Change subject: soc/mediatek/mt8192: Do rx dqs gating training ......................................................................
Patch Set 1:
(3 comments)
https://review.coreboot.org/c/coreboot/+/44718/1/src/soc/mediatek/mt8192/dra... File src/soc/mediatek/mt8192/dramc_pi_calibration_api.c:
https://review.coreboot.org/c/coreboot/+/44718/1/src/soc/mediatek/mt8192/dra... PS1, Line 1441: void dramc_rx_dqs_gating_cal(const struct ddr_cali* cali, "foo* bar" should be "foo *bar"
https://review.coreboot.org/c/coreboot/+/44718/1/src/soc/mediatek/mt8192/dra... PS1, Line 1519: const struct ddr_cali* cali, s8 change_dqs_inctl, u8 mck2ui_shift) "foo* bar" should be "foo *bar"
https://review.coreboot.org/c/coreboot/+/44718/1/src/soc/mediatek/mt8192/dra... PS1, Line 1628: void dramc_rx_dqs_gating_post_process(const struct ddr_cali* cali, "foo* bar" should be "foo *bar"
Hello build bot (Jenkins), Julius Werner, Duan huayang,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/44718
to look at the new patch set (#2).
Change subject: soc/mediatek/mt8192: Do rx dqs gating training ......................................................................
soc/mediatek/mt8192: Do rx dqs gating training
Signed-off-by: Huayang Duan huayang.duan@mediatek.com Change-Id: I141abc1fdd283f4898d0772736bc777e87017561 --- M src/soc/mediatek/mt8192/dramc_pi_calibration_api.c M src/soc/mediatek/mt8192/dramc_pi_main.c 2 files changed, 323 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/18/44718/2
Yidi Lin has uploaded a new patch set (#24) to the change originally created by CK HU. ( https://review.coreboot.org/c/coreboot/+/44718 )
Change subject: soc/mediatek/mt8192: Do rx dqs gating training ......................................................................
soc/mediatek/mt8192: Do rx dqs gating training
Signed-off-by: Huayang Duan huayang.duan@mediatek.com Change-Id: I141abc1fdd283f4898d0772736bc777e87017561 --- M src/soc/mediatek/mt8192/dramc_pi_calibration_api.c M src/soc/mediatek/mt8192/dramc_pi_main.c 2 files changed, 323 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/18/44718/24
Yidi Lin has uploaded a new patch set (#34) to the change originally created by CK HU. ( https://review.coreboot.org/c/coreboot/+/44718 )
Change subject: soc/mediatek/mt8192: Do rx dqs gating training ......................................................................
soc/mediatek/mt8192: Do rx dqs gating training
Signed-off-by: Huayang Duan huayang.duan@mediatek.com Change-Id: I141abc1fdd283f4898d0772736bc777e87017561 --- M src/soc/mediatek/mt8192/dramc_pi_calibration_api.c M src/soc/mediatek/mt8192/dramc_pi_main.c 2 files changed, 323 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/18/44718/34
Yidi Lin has uploaded a new patch set (#36) to the change originally created by CK HU. ( https://review.coreboot.org/c/coreboot/+/44718 )
Change subject: soc/mediatek/mt8192: Do rx dqs gating training ......................................................................
soc/mediatek/mt8192: Do rx dqs gating training
Signed-off-by: Huayang Duan huayang.duan@mediatek.com Change-Id: I141abc1fdd283f4898d0772736bc777e87017561 --- M src/soc/mediatek/mt8192/dramc_pi_calibration_api.c M src/soc/mediatek/mt8192/dramc_pi_main.c 2 files changed, 323 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/18/44718/36
Yidi Lin has uploaded a new patch set (#44) to the change originally created by CK HU. ( https://review.coreboot.org/c/coreboot/+/44718 )
Change subject: soc/mediatek/mt8192: Do rx dqs gating training ......................................................................
soc/mediatek/mt8192: Do rx dqs gating training
Signed-off-by: Huayang Duan huayang.duan@mediatek.com Change-Id: I141abc1fdd283f4898d0772736bc777e87017561 --- M src/soc/mediatek/mt8192/dramc_pi_calibration_api.c M src/soc/mediatek/mt8192/dramc_pi_main.c 2 files changed, 323 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/18/44718/44
Yu-Ping Wu has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/44718 )
Change subject: soc/mediatek/mt8192: Do rx dqs gating training ......................................................................
Patch Set 44:
(37 comments)
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... File src/soc/mediatek/mt8192/dramc_pi_calibration_api.c:
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1369: struct const
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1368: static u8 rxdqs_gating_get_tx_dly_min(dram_freq_grp freq_group, : struct rxdqs_gating_best_win *rxdqs_best_win) One argument per line:
static u8 rxdqs_gating_get_tx_dly_min( dram_freq_grp freq_group, struct rxdqs_gating_best_win *rxdqs_best_win)
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1371: = 0 No initialization
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1371: 0xff UINT8_MAX
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1374: d u
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1380: Just one tab
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1387: if (tx_dly_dqs_gated < tx_dly_min) : tx_dly_min = tx_dly_dqs_gated; tx_dly_min = MIN(tx_dly_min, tx_dly_dqs_gated);
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1393: rxdqs_gating_get_tx_dly_max This is almost identical to rxdqs_gating_get_tx_dly_min(). Please merge these 2 functions:
static rxdqs_gating_get_tx_dly(freq_group, *rxdqs_best_win, *tx_dly_min, *tx_dly_max)
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1419: u8 Align with 'const struct'
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1424: = {0} No need to initialize.
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1438: size_t int
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1441: pi_per_ui = 32; : ui_per_mck = 16; Add 'const' for these.
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1449: MCK Please change to lowercase. Same below.
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1461: d u
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1489: size_t int
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1501: P p
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1507: best_coarse_mck[rk][0] = Can we use a for loop?
for (u8 dqs = 0; dqs < DQS_NUMBER; dqs++) { best_coarse_ui[rk][dqs] = ... }
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1522: SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_MCK_P0_B0 Shouldn't this be SHU_RK_B1_DQSIEN_MCK_UI_DLY_DQSIEN_UI_P0_B1 (B0 vs B1)?
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1537: P p
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1546: ( No parentheses.
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1549: ( No parentheses.
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1551: 2T, 0.5T What do 2T and 0.5T mean? Can we use
dly(MCK, UI)
just like in rxdqs_gating_get_tx_dly_min()?
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1555: for Please merge it into the previous for loop. I don't think the order of debugging logs is that important.
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1556: P1 Out of curiosity, what does "P" mean here?
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1584: if (best_coarse_mck[RANK_0][dqs] > best_coarse_mck[RANK_1][dqs]) { : rank_sel_mck_p0[dqs] = (best_coarse_mck[RANK_0][dqs] > 0) ? : (best_coarse_mck[RANK_0][dqs] - 1) : 0; : rank_sel_mck_p1[dqs] = (best_coarse_mck_P1[RANK_0][dqs] > 0) ? : (best_coarse_mck_P1[RANK_0][dqs] - 1) : 0; : } else { : rank_sel_mck_p0[dqs] = (best_coarse_mck[RANK_1][dqs] > 0) ? : (best_coarse_mck[RANK_1][dqs] - 1) : 0; : rank_sel_mck_p1[dqs] = (best_coarse_mck_P1[RANK_1][dqs] > 0) ? : (best_coarse_mck_P1[RANK_1][dqs] - 1) : 0; : } Simplify by
if (best_coarse_mck[RANK_0][dqs] > best_coarse_mck[RANK_1][dqs]) best_rk = RANK_0; else best_rk = RANK_1;
then do the calculation with best_k.
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1606: tx_dly_max This is only used for printing a debug message?
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1606: u8 Align
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1613: = 0 No need to initialize.
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1614: = 0 No need to initialize.
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1633: d u
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1634: Just one tab
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1641: MISC_SHU_RK_DQSCTL_DQSINCTL Align with &ch[chn]
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1642: change_dqs_inctl Is it guaranteed that (change_dqs_inctl <= read_dqs_inctl)?
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1650: if (read_dqs_inctl >= 2) : rank_inctl_root = read_dqs_inctl - 2; : else : rank_inctl_root = 0; Write "rank_inctl_root = (...) ? ... : ..." for consistency.
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1669: T Can we have a consistent prefix "[RxdqsGatingPostProcess]"? Maybe
"[RxdqsGatingPostProcess] min: %u, max: %u, change_dqs_inctl: %d\n"
Same below.
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1671: RANKINCTL rank_inctl_root
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... File src/soc/mediatek/mt8192/dramc_pi_main.c:
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 276: should enable the auto refresh before do RX and TX calibration Enable auto refresh before RX and TX calibration
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/44718 )
Change subject: soc/mediatek/mt8192: Do rx dqs gating training ......................................................................
Patch Set 44:
(4 comments)
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... File src/soc/mediatek/mt8192/dramc_pi_calibration_api.c:
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1382: if (freq_group != DDRFREQ_400) : tx_dly_dqs_gated >>= 3; : else : tx_dly_dqs_gated >>= 2; Maybe calculate the number of positions to shift out of the loop?
const u8 shift = freq_group == DDRFREQ_400 ? 2 : 3;
for (u8 dqs = 0; dqs < DQS_NUMBER; dqs++) {
...
tx_dly_dqs_gated >>= shift;
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1393: rxdqs_gating_get_tx_dly_max
This is almost identical to rxdqs_gating_get_tx_dly_min(). Please merge these 2 functions: […]
If one always wants to know the min and max values, then one function returning both is better. Another way to do this is to return a struct with two values:
struct ddr_minmax { u8 min; u8 max; };
static struct ddr_minmax rxdqs_gating_get_tx_dly_limits( const dram_freq_grp freq_group, const struct rxdqs_gating_best_win *rxdqs_best_win) { struct ddr_minmax minmax = { .min = UINT8_MAX, .max = 0, };
...
return minmax; }
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1438: size_t
int
size_t should be the right type to use for array indices
https://review.coreboot.org/c/coreboot/+/44718/44/src/soc/mediatek/mt8192/dr... PS44, Line 1443: if (get_div_mode(cali) == DIV4_MODE) : freq_div = 2; : else : freq_div = 4; Maybe make this const?
const u8 freq_div = get_div_mode(cali) == DIV4_MODE ? 2 : 4;
(No idea, but shouldn't the values be the other way around?)
CK HU has abandoned this change. ( https://review.coreboot.org/c/coreboot/+/44718 )
Change subject: soc/mediatek/mt8192: Do rx dqs gating training ......................................................................
Abandoned
Useless