soc/mediatek/mt8183: Improve the DRAMC runtime config flow

Move channel loop at the top level to deduplicate the logic.

BUG=none
BRANCH=kukui
TEST=Boots correctly on Kukui

Change-Id: Iea623d1bd1f7d736e81f66f191a1bf8476d30404
Signed-off-by: Huayang Duan <huayang.duan@mediatek.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/38490
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Hung-Te Lin <hungte@chromium.org>
This commit is contained in:
Huayang Duan
2020-01-21 10:40:01 +08:00
committed by Patrick Georgi
parent 25930f4a3f
commit 04571d8dbe
3 changed files with 111 additions and 125 deletions

View File

@@ -285,13 +285,13 @@ static void dramc_rx_input_delay_tracking(u8 chn)
(0x1 << 29) | (0xf << 4) | (0x1 << 0), (0x1 << 29) | (0xf << 4) | (0x1 << 0),
(0x1 << 29) | (0x0 << 4) | (0x1 << 0)); (0x1 << 29) | (0x0 << 4) | (0x1 << 0));
for (u8 b = 0; b < 2; b++) { for (u8 b = 0; b < 2; b++)
clrsetbits32(&ch[chn].phy.b[b].dq[9], clrsetbits32(&ch[chn].phy.b[b].dq[9],
(0x7 << 28) | (0x7 << 24), (0x7 << 28) | (0x7 << 24),
(0x1 << 28) | (0x0 << 24)); (0x1 << 28) | (0x0 << 24));
setbits32(&ch[chn].phy.b[b].dq[5], 0x1 << 31);
}
clrbits32(&ch[chn].phy.ca_cmd[10], (0x7 << 28) | (0x7 << 24)); clrbits32(&ch[chn].phy.ca_cmd[10], (0x7 << 28) | (0x7 << 24));
for (u8 b = 0; b < 2; b++)
setbits32(&ch[chn].phy.b[b].dq[5], 0x1 << 31);
setbits32(&ch[chn].phy.b0_rxdvs[0], (0x1 << 28) | (0x1 << 31)); setbits32(&ch[chn].phy.b0_rxdvs[0], (0x1 << 28) | (0x1 << 31));
setbits32(&ch[chn].phy.b1_rxdvs[0], (0x1 << 28) | (0x1 << 31)); setbits32(&ch[chn].phy.b1_rxdvs[0], (0x1 << 28) | (0x1 << 31));
@@ -321,9 +321,8 @@ static void dramc_hw_dqs_gating_tracking(u8 chn)
clrbits32(&ch[chn].phy.ca_cmd[6], 0x1 << 31); clrbits32(&ch[chn].phy.ca_cmd[6], 0x1 << 31);
} }
static void dramc_hw_gating_init(void) static void dramc_hw_gating_init(u8 chn)
{ {
for (size_t chn = 0; chn < CHANNEL_MAX; chn++) {
clrbits32(&ch[chn].ao.stbcal, clrbits32(&ch[chn].ao.stbcal,
(0x7 << 22) | (0x3 << 14) | (0x1 << 19) | (0x1 << 21)); (0x7 << 22) | (0x3 << 14) | (0x1 << 19) | (0x1 << 21));
setbits32(&ch[chn].ao.stbcal, (0x1 << 20) | (0x3 << 28)); setbits32(&ch[chn].ao.stbcal, (0x1 << 20) | (0x3 << 28));
@@ -331,7 +330,6 @@ static void dramc_hw_gating_init(void)
dramc_hw_dqs_gating_tracking(chn); dramc_hw_dqs_gating_tracking(chn);
} }
}
static void dramc_impedance_tracking_enable(void) static void dramc_impedance_tracking_enable(void)
{ {
@@ -348,19 +346,16 @@ static void dramc_impedance_tracking_enable(void)
setbits32(&ch[chn].ao.refctrl0, (0x1 << 2) | (0x1 << 3)); setbits32(&ch[chn].ao.refctrl0, (0x1 << 2) | (0x1 << 3));
} }
static void dramc_phy_low_power_enable(void) static void dramc_phy_low_power_enable(u8 chn)
{ {
for (size_t chn = 0; chn < CHANNEL_MAX; chn++) { for (u8 b = 0; b < 2; b++) {
for (size_t b = 0; b < 2; b++) { clrbits32(&ch[chn].phy.b[b].dll_fine_tune[2], 0x3fffff << 10);
clrbits32(&ch[chn].phy.b[b].dll_fine_tune[2],
0x3fffff << 10);
write32(&ch[chn].phy.b[b].dll_fine_tune[3], 0x2e800); write32(&ch[chn].phy.b[b].dll_fine_tune[3], 0x2e800);
} }
clrsetbits32(&ch[chn].phy.ca_dll_fine_tune[2], clrsetbits32(&ch[chn].phy.ca_dll_fine_tune[2],
0x3fffff << 10, 0x2 << 10); 0x3fffff << 10, 0x2 << 10);
} write32(&ch[chn].phy.ca_dll_fine_tune[3],
write32(&ch[0].phy.ca_dll_fine_tune[3], 0xba000); (chn == CHANNEL_A) ? 0xba000 : 0x3a000);
write32(&ch[1].phy.ca_dll_fine_tune[3], 0x3a000);
} }
static void dramc_dummy_read_for_tracking_enable(u8 chn) static void dramc_dummy_read_for_tracking_enable(u8 chn)
@@ -421,46 +416,41 @@ static void dramc_enable_dramc_dcm(void)
void dramc_runtime_config(void) void dramc_runtime_config(void)
{ {
clrbits32(&ch[0].ao.refctrl0, 0x1 << 29); for (u8 chn = 0; chn < CHANNEL_MAX; chn++)
clrbits32(&ch[1].ao.refctrl0, 0x1 << 29); clrbits32(&ch[chn].ao.refctrl0, 0x1 << 29);
transfer_pll_to_spm_control(); transfer_pll_to_spm_control();
setbits32(&mtk_spm->spm_power_on_val0, 0x1 << 25); setbits32(&mtk_spm->spm_power_on_val0, 0x1 << 25);
for (u8 chn = 0; chn < CHANNEL_MAX; chn++) for (u8 chn = 0; chn < CHANNEL_MAX; chn++) {
dramc_hw_dqsosc(chn); dramc_hw_dqsosc(chn);
/* RX_TRACKING: ON */ /* RX_TRACKING: ON */
for (u8 chn = 0; chn < CHANNEL_MAX; chn++)
dramc_rx_input_delay_tracking(chn); dramc_rx_input_delay_tracking(chn);
/* HW_GATING: ON */ /* HW_GATING: ON */
dramc_hw_gating_init(); dramc_hw_gating_init(chn);
dramc_hw_gating_onoff(CHANNEL_A, true); dramc_hw_gating_onoff(chn, true);
dramc_hw_gating_onoff(CHANNEL_B, true);
/* HW_GATING DBG: OFF */ /* HW_GATING DBG: OFF */
for (size_t chn = 0; chn < CHANNEL_MAX; chn++)
clrbits32(&ch[chn].ao.stbcal2, clrbits32(&ch[chn].ao.stbcal2,
(0x3 << 4) | (0x3 << 8) | (0x1 << 28)); (0x3 << 4) | (0x3 << 8) | (0x1 << 28));
/* DUMMY_READ_FOR_TRACKING: ON */ /* DUMMY_READ_FOR_TRACKING: ON */
for (u8 chn = 0; chn < CHANNEL_MAX; chn++)
dramc_dummy_read_for_tracking_enable(chn); dramc_dummy_read_for_tracking_enable(chn);
/* ZQCS_ENABLE_LP4: ON */ /* ZQCS_ENABLE_LP4: ON */
clrbits32(&ch[0].ao.spcmdctrl, 0x1 << 30); clrbits32(&ch[chn].ao.spcmdctrl, 0x1 << 30);
clrbits32(&ch[1].ao.spcmdctrl, 0x1 << 30);
/* LOWPOWER_GOLDEN_SETTINGS(DCM): ON */ /* LOWPOWER_GOLDEN_SETTINGS(DCM): ON */
dramc_phy_low_power_enable(); dramc_phy_low_power_enable(chn);
dramc_enable_phy_dcm(true); dramc_enable_phy_dcm(chn, true);
/* DUMMY_READ_FOR_DQS_GATING_RETRY: OFF */ /* DUMMY_READ_FOR_DQS_GATING_RETRY: OFF */
for (size_t chn = 0; chn < CHANNEL_MAX; chn++)
for (size_t shu = 0; shu < DRAM_DFS_SHUFFLE_MAX; shu++) for (size_t shu = 0; shu < DRAM_DFS_SHUFFLE_MAX; shu++)
clrbits32(&ch[chn].ao.shu[shu].dqsg_retry, clrbits32(&ch[chn].ao.shu[shu].dqsg_retry,
(0x1 << 1) | (0x3 << 13)); (0x1 << 1) | (0x3 << 13));
}
/* SPM_CONTROL_AFTERK: ON */ /* SPM_CONTROL_AFTERK: ON */
write32(&ch[0].phy.misc_spm_ctrl0, 0xfbffefff); write32(&ch[0].phy.misc_spm_ctrl0, 0xfbffefff);

View File

@@ -282,17 +282,15 @@ static void dramc_cmd_bus_training(u8 chn, u8 rank, u8 freq_group,
dramc_mode_reg_write_by_rank(chn, rank, 12, final_vref); dramc_mode_reg_write_by_rank(chn, rank, 12, final_vref);
} }
static void dramc_read_dbi_onoff(bool on) static void dramc_read_dbi_onoff(size_t chn, bool on)
{ {
for (size_t chn = 0; chn < CHANNEL_MAX; chn++)
for (size_t b = 0; b < 2; b++) for (size_t b = 0; b < 2; b++)
SET32_BITFIELDS(&ch[chn].phy.shu[0].b[b].dq[7], SET32_BITFIELDS(&ch[chn].phy.shu[0].b[b].dq[7],
SHU1_B0_DQ7_R_DMDQMDBI_SHU_B0, on); SHU1_B0_DQ7_R_DMDQMDBI_SHU_B0, on);
} }
static void dramc_write_dbi_onoff(bool onoff) static void dramc_write_dbi_onoff(size_t chn, bool onoff)
{ {
for (size_t chn = 0; chn < CHANNEL_MAX; chn++)
SET32_BITFIELDS(&ch[chn].ao.shu[0].wodt, SHU1_WODT_DBIWR, onoff); SET32_BITFIELDS(&ch[chn].ao.shu[0].wodt, SHU1_WODT_DBIWR, onoff);
} }
@@ -313,9 +311,8 @@ static void dramc_phy_dcm_2_channel(u8 chn, bool en)
((en ? 0x7 : 0) << 16) | ((en ? 0x7 : 0) << 20)); ((en ? 0x7 : 0) << 16) | ((en ? 0x7 : 0) << 20));
} }
void dramc_enable_phy_dcm(bool en) void dramc_enable_phy_dcm(u8 chn, bool en)
{ {
for (size_t chn = 0; chn < CHANNEL_MAX ; chn++) {
clrbits32(&ch[chn].phy.b[0].dll_fine_tune[1], 0x1 << 20); clrbits32(&ch[chn].phy.b[0].dll_fine_tune[1], 0x1 << 20);
clrbits32(&ch[chn].phy.b[1].dll_fine_tune[1], 0x1 << 20); clrbits32(&ch[chn].phy.b[1].dll_fine_tune[1], 0x1 << 20);
clrbits32(&ch[chn].phy.ca_dll_fine_tune[1], 0x1 << 20); clrbits32(&ch[chn].phy.ca_dll_fine_tune[1], 0x1 << 20);
@@ -357,14 +354,12 @@ void dramc_enable_phy_dcm(bool en)
dramc_phy_dcm_2_channel(chn, en); dramc_phy_dcm_2_channel(chn, en);
} }
}
static void dramc_reset_delay_chain_before_calibration(void) static void dramc_reset_delay_chain_before_calibration(size_t chn)
{ {
for (size_t chn = 0; chn < CHANNEL_MAX; chn++)
for (size_t rank = 0; rank < RANK_MAX; rank++) { for (size_t rank = 0; rank < RANK_MAX; rank++) {
struct dramc_ddrphy_regs_shu_rk *rk; struct dramc_ddrphy_regs_shu_rk *rk =
rk = &ch[chn].phy.shu[0].rk[rank]; &ch[chn].phy.shu[0].rk[rank];
clrbits32(&rk->ca_cmd[0], 0xffffff << 0); clrbits32(&rk->ca_cmd[0], 0xffffff << 0);
clrbits32(&rk->b[0].dq[0], 0xfffffff << 0); clrbits32(&rk->b[0].dq[0], 0xfffffff << 0);
clrbits32(&rk->b[1].dq[0], 0xfffffff << 0); clrbits32(&rk->b[1].dq[0], 0xfffffff << 0);
@@ -394,29 +389,31 @@ static void dramc_rx_input_delay_tracking_init_by_freq(u8 chn)
void dramc_apply_config_before_calibration(u8 freq_group) void dramc_apply_config_before_calibration(u8 freq_group)
{ {
dramc_enable_phy_dcm(false); for (u8 chn = 0; chn < CHANNEL_MAX; chn++) {
dramc_reset_delay_chain_before_calibration(); dramc_enable_phy_dcm(chn, false);
dramc_reset_delay_chain_before_calibration(chn);
setbits32(&ch[0].ao.shu[0].conf[3], 0x1ff << 16); setbits32(&ch[chn].ao.shu[0].conf[3], 0x1ff << 16);
setbits32(&ch[0].ao.spcmdctrl, 0x1 << 24); setbits32(&ch[chn].ao.spcmdctrl, 0x1 << 24);
clrsetbits32(&ch[0].ao.shu[0].scintv, 0x1f << 1, 0x1b << 1); clrsetbits32(&ch[chn].ao.shu[0].scintv, 0x1f << 1, 0x1b << 1);
for (size_t shu = DRAM_DFS_SHUFFLE_1; shu < DRAM_DFS_SHUFFLE_MAX; shu++) for (u8 shu = DRAM_DFS_SHUFFLE_1; shu < DRAM_DFS_SHUFFLE_MAX;
setbits32(&ch[0].ao.shu[shu].conf[3], 0x1ff << 0); shu++)
setbits32(&ch[chn].ao.shu[shu].conf[3], 0x1ff << 0);
clrbits32(&ch[0].ao.dramctrl, 0x1 << 18); clrbits32(&ch[chn].ao.dramctrl, 0x1 << 18);
clrbits32(&ch[0].ao.spcmdctrl, 0x1 << 31); clrbits32(&ch[chn].ao.spcmdctrl, 0x1 << 31);
clrbits32(&ch[0].ao.spcmdctrl, 0x1 << 30); clrbits32(&ch[chn].ao.spcmdctrl, 0x1 << 30);
clrbits32(&ch[0].ao.dqsoscr, 0x1 << 26); clrbits32(&ch[chn].ao.dqsoscr, 0x1 << 26);
clrbits32(&ch[0].ao.dqsoscr, 0x1 << 25); clrbits32(&ch[chn].ao.dqsoscr, 0x1 << 25);
dramc_write_dbi_onoff(false); dramc_write_dbi_onoff(chn, false);
dramc_read_dbi_onoff(false); dramc_read_dbi_onoff(chn, false);
for (size_t chn = 0; chn < CHANNEL_MAX; chn++) {
setbits32(&ch[chn].ao.spcmdctrl, 0x1 << 29); setbits32(&ch[chn].ao.spcmdctrl, 0x1 << 29);
setbits32(&ch[chn].ao.dqsoscr, 0x1 << 24); setbits32(&ch[chn].ao.dqsoscr, 0x1 << 24);
for (size_t shu = DRAM_DFS_SHUFFLE_1; shu < DRAM_DFS_SHUFFLE_MAX; shu++) for (u8 shu = DRAM_DFS_SHUFFLE_1; shu < DRAM_DFS_SHUFFLE_MAX;
shu++)
setbits32(&ch[chn].ao.shu[shu].scintv, 0x1 << 30); setbits32(&ch[chn].ao.shu[shu].scintv, 0x1 << 30);
clrbits32(&ch[chn].ao.dummy_rd, (0x1 << 7) | (0x7 << 20)); clrbits32(&ch[chn].ao.dummy_rd, (0x1 << 7) | (0x7 << 20));
@@ -787,7 +784,6 @@ static void dramc_rx_dqs_gating_cal_pre(u8 chn, u8 rank)
SET32_BITFIELDS(&ch[chn].ao.spcmd, SPCMD_DQSGCNTRST, 0); SET32_BITFIELDS(&ch[chn].ao.spcmd, SPCMD_DQSGCNTRST, 0);
SET32_BITFIELDS(&ch[chn].phy.misc_ctrl1, MISC_CTRL1_R_DMSTBENCMP_RK, SET32_BITFIELDS(&ch[chn].phy.misc_ctrl1, MISC_CTRL1_R_DMSTBENCMP_RK,
rank); rank);
} }
static void set_selph_gating_value(uint32_t *addr, u8 dly, u8 dly_p1) static void set_selph_gating_value(uint32_t *addr, u8 dly, u8 dly_p1)

View File

@@ -113,7 +113,7 @@ void dramc_apply_config_after_calibration(const struct mr_value *mr);
int dramc_calibrate_all_channels(const struct sdram_params *pams, int dramc_calibrate_all_channels(const struct sdram_params *pams,
u8 freq_group, const struct mr_value *mr); u8 freq_group, const struct mr_value *mr);
void dramc_hw_gating_onoff(u8 chn, bool onoff); void dramc_hw_gating_onoff(u8 chn, bool onoff);
void dramc_enable_phy_dcm(bool bEn); void dramc_enable_phy_dcm(u8 chn, bool bEn);
void dramc_mode_reg_write(u8 chn, u8 mr_idx, u8 value); void dramc_mode_reg_write(u8 chn, u8 mr_idx, u8 value);
void dramc_cke_fix_onoff(u8 chn, bool fix_on, bool fix_off); void dramc_cke_fix_onoff(u8 chn, bool fix_on, bool fix_off);
u32 get_shu_freq(u8 shu); u32 get_shu_freq(u8 shu);