summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorHuayang Duan <huayang.duan@mediatek.com>2020-01-21 10:40:01 +0800
committerPatrick Georgi <pgeorgi@google.com>2020-03-06 08:01:20 +0000
commit04571d8dbeb06376564b03759a5e7c22e9ece86a (patch)
tree003a9a9339587f01570fc5fae8a4903928f4632f /src
parent25930f4a3f7c518afadeb1d0298f9750707748e8 (diff)
downloadcoreboot-04571d8dbeb06376564b03759a5e7c22e9ece86a.tar.gz
coreboot-04571d8dbeb06376564b03759a5e7c22e9ece86a.tar.bz2
coreboot-04571d8dbeb06376564b03759a5e7c22e9ece86a.zip
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>
Diffstat (limited to 'src')
-rw-r--r--src/soc/mediatek/mt8183/dramc_pi_basic_api.c84
-rw-r--r--src/soc/mediatek/mt8183/dramc_pi_calibration_api.c146
-rw-r--r--src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h2
3 files changed, 109 insertions, 123 deletions
diff --git a/src/soc/mediatek/mt8183/dramc_pi_basic_api.c b/src/soc/mediatek/mt8183/dramc_pi_basic_api.c
index c7d6c748e79d..dc3676a9e39b 100644
--- a/src/soc/mediatek/mt8183/dramc_pi_basic_api.c
+++ b/src/soc/mediatek/mt8183/dramc_pi_basic_api.c
@@ -285,13 +285,13 @@ static void dramc_rx_input_delay_tracking(u8 chn)
(0x1 << 29) | (0xf << 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],
- (0x7 << 28) | (0x7 << 24),
- (0x1 << 28) | (0x0 << 24));
- setbits32(&ch[chn].phy.b[b].dq[5], 0x1 << 31);
- }
+ (0x7 << 28) | (0x7 << 24),
+ (0x1 << 28) | (0x0 << 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.b1_rxdvs[0], (0x1 << 28) | (0x1 << 31));
@@ -321,16 +321,14 @@ static void dramc_hw_dqs_gating_tracking(u8 chn)
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,
- (0x7 << 22) | (0x3 << 14) | (0x1 << 19) | (0x1 << 21));
- setbits32(&ch[chn].ao.stbcal, (0x1 << 20) | (0x3 << 28));
- setbits32(&ch[chn].phy.misc_ctrl1, 0x1 << 24);
+ clrbits32(&ch[chn].ao.stbcal,
+ (0x7 << 22) | (0x3 << 14) | (0x1 << 19) | (0x1 << 21));
+ setbits32(&ch[chn].ao.stbcal, (0x1 << 20) | (0x3 << 28));
+ setbits32(&ch[chn].phy.misc_ctrl1, 0x1 << 24);
- dramc_hw_dqs_gating_tracking(chn);
- }
+ dramc_hw_dqs_gating_tracking(chn);
}
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));
}
-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 (size_t b = 0; b < 2; b++) {
- clrbits32(&ch[chn].phy.b[b].dll_fine_tune[2],
- 0x3fffff << 10);
- write32(&ch[chn].phy.b[b].dll_fine_tune[3], 0x2e800);
- }
- clrsetbits32(&ch[chn].phy.ca_dll_fine_tune[2],
- 0x3fffff << 10, 0x2 << 10);
+ for (u8 b = 0; b < 2; b++) {
+ 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[0].phy.ca_dll_fine_tune[3], 0xba000);
- write32(&ch[1].phy.ca_dll_fine_tune[3], 0x3a000);
+ clrsetbits32(&ch[chn].phy.ca_dll_fine_tune[2],
+ 0x3fffff << 10, 0x2 << 10);
+ write32(&ch[chn].phy.ca_dll_fine_tune[3],
+ (chn == CHANNEL_A) ? 0xba000 : 0x3a000);
}
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)
{
- clrbits32(&ch[0].ao.refctrl0, 0x1 << 29);
- clrbits32(&ch[1].ao.refctrl0, 0x1 << 29);
+ for (u8 chn = 0; chn < CHANNEL_MAX; chn++)
+ clrbits32(&ch[chn].ao.refctrl0, 0x1 << 29);
transfer_pll_to_spm_control();
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);
- /* RX_TRACKING: ON */
- for (u8 chn = 0; chn < CHANNEL_MAX; chn++)
+ /* RX_TRACKING: ON */
dramc_rx_input_delay_tracking(chn);
- /* HW_GATING: ON */
- dramc_hw_gating_init();
- dramc_hw_gating_onoff(CHANNEL_A, true);
- dramc_hw_gating_onoff(CHANNEL_B, true);
+ /* HW_GATING: ON */
+ dramc_hw_gating_init(chn);
+ dramc_hw_gating_onoff(chn, true);
- /* HW_GATING DBG: OFF */
- for (size_t chn = 0; chn < CHANNEL_MAX; chn++)
+ /* HW_GATING DBG: OFF */
clrbits32(&ch[chn].ao.stbcal2,
- (0x3 << 4) | (0x3 << 8) | (0x1 << 28));
+ (0x3 << 4) | (0x3 << 8) | (0x1 << 28));
- /* DUMMY_READ_FOR_TRACKING: ON */
- for (u8 chn = 0; chn < CHANNEL_MAX; chn++)
+ /* DUMMY_READ_FOR_TRACKING: ON */
dramc_dummy_read_for_tracking_enable(chn);
- /* ZQCS_ENABLE_LP4: ON */
- clrbits32(&ch[0].ao.spcmdctrl, 0x1 << 30);
- clrbits32(&ch[1].ao.spcmdctrl, 0x1 << 30);
+ /* ZQCS_ENABLE_LP4: ON */
+ clrbits32(&ch[chn].ao.spcmdctrl, 0x1 << 30);
- /* LOWPOWER_GOLDEN_SETTINGS(DCM): ON */
- dramc_phy_low_power_enable();
- dramc_enable_phy_dcm(true);
+ /* LOWPOWER_GOLDEN_SETTINGS(DCM): ON */
+ dramc_phy_low_power_enable(chn);
+ dramc_enable_phy_dcm(chn, true);
- /* DUMMY_READ_FOR_DQS_GATING_RETRY: OFF */
- for (size_t chn = 0; chn < CHANNEL_MAX; chn++)
+ /* DUMMY_READ_FOR_DQS_GATING_RETRY: OFF */
for (size_t shu = 0; shu < DRAM_DFS_SHUFFLE_MAX; shu++)
clrbits32(&ch[chn].ao.shu[shu].dqsg_retry,
- (0x1 << 1) | (0x3 << 13));
+ (0x1 << 1) | (0x3 << 13));
+ }
/* SPM_CONTROL_AFTERK: ON */
write32(&ch[0].phy.misc_spm_ctrl0, 0xfbffefff);
diff --git a/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c b/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c
index 4ccc7fcb22ef..b9634a8ca835 100644
--- a/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c
+++ b/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c
@@ -282,18 +282,16 @@ static void dramc_cmd_bus_training(u8 chn, u8 rank, u8 freq_group,
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++)
- SET32_BITFIELDS(&ch[chn].phy.shu[0].b[b].dq[7],
- SHU1_B0_DQ7_R_DMDQMDBI_SHU_B0, on);
+ for (size_t b = 0; b < 2; b++)
+ SET32_BITFIELDS(&ch[chn].phy.shu[0].b[b].dq[7],
+ 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);
}
static void dramc_phy_dcm_2_channel(u8 chn, bool en)
@@ -313,64 +311,61 @@ static void dramc_phy_dcm_2_channel(u8 chn, bool en)
((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[1].dll_fine_tune[1], 0x1 << 20);
- clrbits32(&ch[chn].phy.ca_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.ca_dll_fine_tune[1], 0x1 << 20);
- for (size_t i = 0; i < DRAM_DFS_SHUFFLE_MAX; i++) {
- struct ddrphy_ao_shu *shu = &ch[chn].phy.shu[i];
- setbits32(&shu->b[0].dll[0], 0x1);
- setbits32(&shu->b[1].dll[0], 0x1);
- setbits32(&shu->ca_dll[0], 0x1);
- }
+ for (size_t i = 0; i < DRAM_DFS_SHUFFLE_MAX; i++) {
+ struct ddrphy_ao_shu *shu = &ch[chn].phy.shu[i];
+ setbits32(&shu->b[0].dll[0], 0x1);
+ setbits32(&shu->b[1].dll[0], 0x1);
+ setbits32(&shu->ca_dll[0], 0x1);
+ }
- clrsetbits32(&ch[chn].ao.dramc_pd_ctrl,
- (0x1 << 0) | (0x1 << 1) | (0x1 << 2) |
- (0x1 << 5) | (0x1 << 26) | (0x1 << 30) | (0x1 << 31),
- ((en ? 0x1 : 0) << 0) | ((en ? 0x1 : 0) << 1) |
- ((en ? 0x1 : 0) << 2) | ((en ? 0 : 0x1) << 5) |
- ((en ? 0 : 0x1) << 26) | ((en ? 0x1 : 0) << 30) |
- ((en ? 0x1 : 0) << 31));
-
- /* DCM on: CHANNEL_EMI free run; DCM off: mem_dcm */
- write32(&ch[chn].phy.misc_cg_ctrl2,
- 0x8060033e | (0x40 << (en ? 0x1 : 0)));
- write32(&ch[chn].phy.misc_cg_ctrl2,
- 0x8060033f | (0x40 << (en ? 0x1 : 0)));
- write32(&ch[chn].phy.misc_cg_ctrl2,
- 0x8060033e | (0x40 << (en ? 0x1 : 0)));
-
- clrsetbits32(&ch[chn].phy.misc_ctrl3, 0x3 << 26,
- (en ? 0 : 0x3) << 26);
- for (size_t i = 0; i < DRAM_DFS_SHUFFLE_MAX; i++) {
- u32 mask = 0x7 << 17;
- u32 value = (en ? 0x7 : 0) << 17;
- struct ddrphy_ao_shu *shu = &ch[chn].phy.shu[i];
-
- clrsetbits32(&shu->b[0].dq[7], mask, value);
- clrsetbits32(&shu->b[1].dq[7], mask, value);
- clrsetbits32(&shu->ca_cmd[7], mask, value);
- }
+ clrsetbits32(&ch[chn].ao.dramc_pd_ctrl,
+ (0x1 << 0) | (0x1 << 1) | (0x1 << 2) |
+ (0x1 << 5) | (0x1 << 26) | (0x1 << 30) | (0x1 << 31),
+ ((en ? 0x1 : 0) << 0) | ((en ? 0x1 : 0) << 1) |
+ ((en ? 0x1 : 0) << 2) | ((en ? 0 : 0x1) << 5) |
+ ((en ? 0 : 0x1) << 26) | ((en ? 0x1 : 0) << 30) |
+ ((en ? 0x1 : 0) << 31));
+
+ /* DCM on: CHANNEL_EMI free run; DCM off: mem_dcm */
+ write32(&ch[chn].phy.misc_cg_ctrl2,
+ 0x8060033e | (0x40 << (en ? 0x1 : 0)));
+ write32(&ch[chn].phy.misc_cg_ctrl2,
+ 0x8060033f | (0x40 << (en ? 0x1 : 0)));
+ write32(&ch[chn].phy.misc_cg_ctrl2,
+ 0x8060033e | (0x40 << (en ? 0x1 : 0)));
+
+ clrsetbits32(&ch[chn].phy.misc_ctrl3, 0x3 << 26,
+ (en ? 0 : 0x3) << 26);
+ for (size_t i = 0; i < DRAM_DFS_SHUFFLE_MAX; i++) {
+ u32 mask = 0x7 << 17;
+ u32 value = (en ? 0x7 : 0) << 17;
+ struct ddrphy_ao_shu *shu = &ch[chn].phy.shu[i];
- dramc_phy_dcm_2_channel(chn, en);
+ clrsetbits32(&shu->b[0].dq[7], mask, value);
+ clrsetbits32(&shu->b[1].dq[7], mask, value);
+ clrsetbits32(&shu->ca_cmd[7], mask, value);
}
+
+ 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++) {
- struct dramc_ddrphy_regs_shu_rk *rk;
- rk = &ch[chn].phy.shu[0].rk[rank];
- clrbits32(&rk->ca_cmd[0], 0xffffff << 0);
- clrbits32(&rk->b[0].dq[0], 0xfffffff << 0);
- clrbits32(&rk->b[1].dq[0], 0xfffffff << 0);
- clrbits32(&rk->b[0].dq[1], 0xf << 0);
- clrbits32(&rk->b[1].dq[1], 0xf << 0);
- }
+ for (size_t rank = 0; rank < RANK_MAX; rank++) {
+ struct dramc_ddrphy_regs_shu_rk *rk =
+ &ch[chn].phy.shu[0].rk[rank];
+ clrbits32(&rk->ca_cmd[0], 0xffffff << 0);
+ clrbits32(&rk->b[0].dq[0], 0xfffffff << 0);
+ clrbits32(&rk->b[1].dq[0], 0xfffffff << 0);
+ clrbits32(&rk->b[0].dq[1], 0xf << 0);
+ clrbits32(&rk->b[1].dq[1], 0xf << 0);
+ }
}
void dramc_hw_gating_onoff(u8 chn, bool on)
@@ -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)
{
- dramc_enable_phy_dcm(false);
- dramc_reset_delay_chain_before_calibration();
+ for (u8 chn = 0; chn < CHANNEL_MAX; chn++) {
+ 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[0].ao.spcmdctrl, 0x1 << 24);
- clrsetbits32(&ch[0].ao.shu[0].scintv, 0x1f << 1, 0x1b << 1);
+ setbits32(&ch[chn].ao.shu[0].conf[3], 0x1ff << 16);
+ setbits32(&ch[chn].ao.spcmdctrl, 0x1 << 24);
+ 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++)
- setbits32(&ch[0].ao.shu[shu].conf[3], 0x1ff << 0);
+ for (u8 shu = DRAM_DFS_SHUFFLE_1; shu < DRAM_DFS_SHUFFLE_MAX;
+ shu++)
+ setbits32(&ch[chn].ao.shu[shu].conf[3], 0x1ff << 0);
- clrbits32(&ch[0].ao.dramctrl, 0x1 << 18);
- clrbits32(&ch[0].ao.spcmdctrl, 0x1 << 31);
- clrbits32(&ch[0].ao.spcmdctrl, 0x1 << 30);
- clrbits32(&ch[0].ao.dqsoscr, 0x1 << 26);
- clrbits32(&ch[0].ao.dqsoscr, 0x1 << 25);
+ clrbits32(&ch[chn].ao.dramctrl, 0x1 << 18);
+ clrbits32(&ch[chn].ao.spcmdctrl, 0x1 << 31);
+ clrbits32(&ch[chn].ao.spcmdctrl, 0x1 << 30);
+ clrbits32(&ch[chn].ao.dqsoscr, 0x1 << 26);
+ clrbits32(&ch[chn].ao.dqsoscr, 0x1 << 25);
- dramc_write_dbi_onoff(false);
- dramc_read_dbi_onoff(false);
+ dramc_write_dbi_onoff(chn, 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.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);
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].phy.misc_ctrl1, MISC_CTRL1_R_DMSTBENCMP_RK,
rank);
-
}
static void set_selph_gating_value(uint32_t *addr, u8 dly, u8 dly_p1)
diff --git a/src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h b/src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h
index 59eb6dd3d442..c13aa013ee76 100644
--- a/src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h
+++ b/src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h
@@ -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,
u8 freq_group, const struct mr_value *mr);
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_cke_fix_onoff(u8 chn, bool fix_on, bool fix_off);
u32 get_shu_freq(u8 shu);