summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormtk11195 <huayang.duan@mediatek.com>2019-01-23 11:41:19 +0800
committerPatrick Georgi <pgeorgi@google.com>2019-06-21 09:57:28 +0000
commit16ad2d70caec5c0ec806b95c80128fd3213246d7 (patch)
tree4828760775ab2da84b7df110c01a1eb3b5def9cb /src
parent3d5bb2a5df7c16d0faa5e6e84b42f3220ccf8405 (diff)
downloadcoreboot-16ad2d70caec5c0ec806b95c80128fd3213246d7.tar.xz
mediatek/mt8183: enable DDR low power feature
BUG=b:80501386 BRANCH=none TEST=Boots correctly and stress test pass on Kukui. Change-Id: Ic48580e7e5db25dc1c29dabf41c4e3816fb946d3 Signed-off-by: Huayang Duan <huayang.duan@mediatek.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/32010 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Hung-Te Lin <hungte@chromium.org> Reviewed-by: Julius Werner <jwerner@chromium.org> Reviewed-by: Huayang Duan <huayang.duan@mediatek.corp-partner.google.com>
Diffstat (limited to 'src')
-rw-r--r--src/soc/mediatek/mt8183/dramc_pi_basic_api.c118
-rw-r--r--src/soc/mediatek/mt8183/dramc_pi_calibration_api.c119
-rw-r--r--src/soc/mediatek/mt8183/emi.c12
-rw-r--r--src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h4
-rw-r--r--src/soc/mediatek/mt8183/include/soc/dramc_register.h5
-rw-r--r--src/soc/mediatek/mt8183/include/soc/emi.h1
6 files changed, 206 insertions, 53 deletions
diff --git a/src/soc/mediatek/mt8183/dramc_pi_basic_api.c b/src/soc/mediatek/mt8183/dramc_pi_basic_api.c
index 3ca5c22fcc..cdba2af2df 100644
--- a/src/soc/mediatek/mt8183/dramc_pi_basic_api.c
+++ b/src/soc/mediatek/mt8183/dramc_pi_basic_api.c
@@ -20,7 +20,7 @@
#include <soc/dramc_register.h>
#include <soc/dramc_pi_api.h>
-static void sw_imp_cal_vref_sel(u8 term_option, u8 impcal_stage)
+static void dramc_sw_imp_cal_vref_sel(u8 term_option, u8 impcal_stage)
{
u8 vref_sel = 0;
@@ -56,7 +56,7 @@ void dramc_sw_impedance(const struct sdram_params *params)
sw_impedance[ODT_OFF][3] = sw_impedance[ODT_ON][3];
clrsetbits_le32(&ch[0].phy.shu[0].ca_cmd[11], 0xff, 0x3);
- sw_imp_cal_vref_sel(dq_term, IMPCAL_STAGE_DRVP);
+ dramc_sw_imp_cal_vref_sel(dq_term, IMPCAL_STAGE_DRVP);
/* DQ */
clrsetbits_le32(&ch[0].ao.shu[0].drving[0], (0x1f << 5) | (0x1f << 0),
@@ -154,9 +154,6 @@ static void dramc_rx_input_delay_tracking(u8 chn)
for (size_t r = 0; r < 2; r++)
for (size_t b = 0; b < 2; b++) {
- /* Track rising and update rising/falling together */
- clrbits_le32(&ch[chn].phy.r[r].b[b].rxdvs[2],
- 0x1 << 29);
clrsetbits_le32(&ch[chn].phy.r[r].b[b].rxdvs[7],
(0x3f << 0) | (0x3f << 8) |
(0x7f << 16) | (0x7f << 24),
@@ -172,8 +169,6 @@ static void dramc_rx_input_delay_tracking(u8 chn)
(0x3 << 18) | (0x3 << 16));
}
- clrbits_le32(&ch[chn].phy.ca_cmd[10], (0x7 << 28) | (0x7 << 24));
-
/* Rx DLY tracking setting (Static) */
clrsetbits_le32(&ch[chn].phy.b0_rxdvs[0],
(0x1 << 29) | (0xf << 4) | (0x1 << 0),
@@ -181,6 +176,7 @@ static void dramc_rx_input_delay_tracking(u8 chn)
clrsetbits_le32(&ch[chn].phy.b1_rxdvs[0],
(0x1 << 29) | (0xf << 4) | (0x1 << 0),
(0x1 << 29) | (0x0 << 4) | (0x1 << 0));
+ clrbits_le32(&ch[chn].phy.ca_cmd[10], (0x7 << 28) | (0x7 << 24));
for (u8 b = 0; b < 2; b++) {
clrsetbits_le32(&ch[chn].phy.b[b].dq[9],
@@ -201,10 +197,12 @@ static void dramc_rx_input_delay_tracking(u8 chn)
static void dramc_hw_dqs_gating_tracking(u8 chn)
{
- setbits_le32(&ch[chn].ao.stbcal, (0x3 << 26) | (0x1 << 0));
+ clrsetbits_le32(&ch[chn].ao.stbcal,
+ (0x1 << 21) | (0x3 << 15) | (0x1f << 8) | (0x1 << 4),
+ (0x3 << 26) | (0x1 << 0));
clrsetbits_le32(&ch[chn].ao.stbcal1,
(0xffff << 16) | (0x1 << 8) | (0x1 << 6),
- (0x1 << 16) | (0x1 << 8) | (0x0 << 6));
+ (0x1 << 16) | (0x1 << 8) | (0x1 << 6));
clrsetbits_le32(&ch[chn].phy.misc_ctrl0,
(0x1 << 24) | (0x1f << 11) | (0xf << 0),
@@ -262,6 +260,63 @@ static void dramc_phy_low_power_enable(void)
dramc_set_broadcast(broadcast_bak);
}
+
+static void dramc_dummy_read_for_tracking_enable(u8 chn)
+{
+ setbits_le32(&ch[chn].ao.dummy_rd, 0x3 << 16);
+
+ for (size_t r = 0; r < 2; r++)
+ for (size_t i = 0; i < 4; i++)
+ write32(&ch[chn].ao.rk[r].dummy_rd_wdata[i],
+ 0xaaaa5555);
+
+ clrsetbits_le32(&ch[chn].ao.test2_4, 0x7 << 28, 0x4 << 28);
+ for (size_t r = 0; r < 2; r++) {
+ clrsetbits_le32(&ch[chn].ao.rk[r].dummy_rd_adr,
+ (0x1ffff << 0) | (0x7ff << 17) | (0xf << 28),
+ (0x7fff << 0) | (0x3f0 << 17));
+ setbits_le32(&ch[chn].ao.rk[r].dummy_rd_bk, 0x7 << 0);
+ }
+
+ clrbits_le32(&ch[chn].ao.dummy_rd, 0x1 << 25 | 0x1 << 20);
+}
+
+static void dramc_set_CKE_2_rank_independent(u8 chn)
+{
+ clrsetbits_le32(&ch[chn].ao.rkcfg, (0x1 << 15) | (0x1 << 12), 0x1 << 2);
+ clrsetbits_le32(&ch[chn].ao.ckectrl,
+ (0x1 << 1) | (0xf << 8) | (0x7 << 13),
+ (0x4 << 8) | (0x2 << 13));
+
+ for (u8 shu = 0; shu < DRAM_DFS_SHUFFLE_MAX; shu++)
+ setbits_le32(&ch[chn].ao.shu[shu].conf[2],
+ (0x1 << 29) | (0x1 << 31));
+ clrbits_le32(&ch[chn].ao.dramctrl, 0x1 << 9);
+}
+
+static void dramc_pa_improve(u8 chn)
+{
+ clrbits_le32(&ch[chn].ao.clkar, 0xffff);
+ clrbits_le32(&ch[chn].ao.srefctrl, 0xf << 12);
+ clrbits_le32(&ch[chn].ao.zqcs, 0x1 << 19);
+ clrbits_le32(&ch[chn].ao.pre_tdqsck[0], 0x1 << 17);
+ clrbits_le32(&ch[chn].ao.zqcs, 0x1 << 19);
+ clrbits_le32(&ch[chn].ao.pre_tdqsck[0], 0x1 << 17);
+
+ for (u8 shu = 0; shu < DRAM_DFS_SHUFFLE_MAX; shu++)
+ clrbits_le32(&ch[chn].ao.shu[shu].odtctrl, 0x3 << 2);
+}
+
+static void dramc_enable_dramc_dcm(void)
+{
+ for (size_t chn = 0; chn < CHANNEL_MAX; chn++) {
+ clrsetbits_le32(&ch[chn].ao.dramc_pd_ctrl,
+ (0x7 << 0) | (0x1 << 26) | (0x1 << 30) | (0x1 << 31),
+ (0x7 << 0) | (0x1 << 30) | (0x1 << 31));
+ setbits_le32(&ch[chn].ao.clkar, 0x1 << 31);
+ }
+}
+
void dramc_runtime_config(void)
{
clrbits_le32(&ch[0].ao.refctrl0, 0x1 << 29);
@@ -270,39 +325,78 @@ void dramc_runtime_config(void)
transfer_pll_to_spm_control();
setbits_le32(&mtk_spm->spm_power_on_val0, 0x3 << 25);
+ /* RX_TRACKING: ON */
for (u8 chn = 0; chn < CHANNEL_MAX; chn++)
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 DBG: OFF */
for (size_t chn = 0; chn < CHANNEL_MAX; chn++)
clrbits_le32(&ch[chn].ao.stbcal2,
(0x3 << 4) | (0x3 << 8) | (0x1 << 28));
+ /* DUMMY_READ_FOR_TRACKING: ON */
+ for (u8 chn = 0; chn < CHANNEL_MAX; chn++)
+ dramc_dummy_read_for_tracking_enable(chn);
+
+ /* ZQCS_ENABLE_LP4: ON */
clrbits_le32(&ch[0].ao.spcmdctrl, 0x1 << 30);
clrbits_le32(&ch[1].ao.spcmdctrl, 0x1 << 30);
+ /* LOWPOWER_GOLDEN_SETTINGS(DCM): ON */
dramc_phy_low_power_enable();
dramc_enable_phy_dcm(true);
+ /* 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++)
clrbits_le32(&ch[chn].ao.shu[shu].dqsg_retry,
(0x1 << 1) | (0x3 << 13));
+ /* SPM_CONTROL_AFTERK: ON */
write32(&ch[0].phy.misc_spm_ctrl0, 0xfbffefff);
write32(&ch[1].phy.misc_spm_ctrl0, 0xfbffefff);
write32(&ch[0].phy.misc_spm_ctrl2, 0xffffffef);
write32(&ch[1].phy.misc_spm_ctrl2, 0x7fffffef);
+ /* IMPEDANCE_TRACKING: ON */
dramc_impedance_tracking_enable();
for (size_t chn = 0; chn < CHANNEL_MAX; chn++) {
+ /* TEMP_SENSOR: ON */
clrbits_le32(&ch[chn].ao.spcmdctrl, 0x3 << 28);
setbits_le32(&ch[chn].ao.hw_mrr_fun, (0x1 << 0) | (0x1 << 11));
- clrbits_le32(&ch[0].ao.refctrl0, 0x1 << 18);
- setbits_le32(&ch[chn].phy.dvfs_emi_clk, 0x1 << 24);
- setbits_le32(&ch[chn].ao.dvfsdll, 0x1 << 7);
+
+ /* PER_BANK_REFRESH: ON */
+ clrbits_le32(&ch[chn].ao.refctrl0, 0x1 << 18);
+
+ /* HW_SAVE_FOR_SR: ON */
+ clrbits_le32(&ch[chn].ao.rstmask, (0x1 << 25) | (0x1 << 28));
+ setbits_le32(&ch[chn].ao.refctrl1, 0x1 << 0);
+ clrsetbits_le32(&ch[chn].ao.srefctrl, 0x1 << 20, 0x1 << 22);
+
+ /* SET_CKE_2_RANK_INDEPENDENT_RUN_TIME: ON */
+ dramc_set_CKE_2_rank_independent(chn);
+
+ /* CLK_FREE_FUN_FOR_DRAMC_PSEL: ON */
+ clrbits_le32(&ch[chn].ao.refctrl1, (0x1 << 6) | (0x3 << 2));
+ clrbits_le32(&ch[chn].ao.clkar, 0x1 << 19);
+
+ /* PA_IMPROVEMENT_FOR_DRAMC_ACTIVE_POWER: ON */
+ dramc_pa_improve(chn);
+
+ /* DRAM DRS DISABLE */
+ clrsetbits_le32(&ch[chn].ao.drsctrl,
+ (0x1 << 21) | (0x3f << 12) | (0xf << 8) | (0x1 << 6),
+ (0x1 << 19) | (0x3 << 12) | (0x8 << 8) |
+ (0x3 << 4) | (0x1 << 2) | (0x1 << 0));
+ setbits_le32(&ch[chn].ao.dummy_rd, 0x3 << 26);
}
+
+ enable_emi_dcm();
+ dramc_enable_dramc_dcm();
}
diff --git a/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c b/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c
index f3c76a9273..6dc8fa6588 100644
--- a/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c
+++ b/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c
@@ -86,7 +86,7 @@ struct per_byte_dly {
u16 final_dly;
};
-static void auto_refresh_switch(u8 chn, bool option)
+static void dramc_auto_refresh_switch(u8 chn, bool option)
{
clrsetbits_le32(&ch[chn].ao.refctrl0, 1 << REFCTRL0_REFDIS_SHIFT,
(option ? 0 : 1) << REFCTRL0_REFDIS_SHIFT);
@@ -157,7 +157,7 @@ static void dramc_write_leveling(u8 chn, u8 rank,
}
}
-static void cmd_bus_training(u8 chn, u8 rank,
+static void dramc_cmd_bus_training(u8 chn, u8 rank,
const struct sdram_params *params)
{
u32 cbt_cs, mr12_value;
@@ -257,7 +257,7 @@ void dramc_enable_phy_dcm(bool en)
dramc_set_broadcast(broadcast_bak);
}
-static void reset_delay_chain_before_calibration(void)
+static void dramc_reset_delay_chain_before_calibration(void)
{
for (size_t chn = 0; chn < CHANNEL_MAX; chn++)
for (size_t rank = 0; rank < RANK_MAX; rank++) {
@@ -290,10 +290,10 @@ static void dramc_rx_input_delay_tracking_init_by_freq(u8 chn)
clrbits_le32(&shu->b[1].dq[7], (0x1 << 12) | (0x1 << 13));
}
-void dramc_apply_pre_calibration_config(void)
+void dramc_apply_config_before_calibration(void)
{
dramc_enable_phy_dcm(false);
- reset_delay_chain_before_calibration();
+ dramc_reset_delay_chain_before_calibration();
setbits_le32(&ch[0].ao.shu[0].conf[3], 0x1ff << 16);
setbits_le32(&ch[0].ao.spcmdctrl, 0x1 << 24);
@@ -344,7 +344,53 @@ void dramc_apply_pre_calibration_config(void)
}
}
-static void rx_dqs_isi_pulse_cg_switch(u8 chn, bool flag)
+static void dramc_set_mr13_vrcg_to_Normal(u8 chn)
+{
+ for (u8 rank = 0; rank < RANK_MAX; rank++)
+ dramc_mode_reg_write_by_rank(chn, rank, 13, 0xd0);
+
+ for (u8 shu = 0; shu < DRAM_DFS_SHUFFLE_MAX; shu++)
+ clrbits_le32(&ch[chn].ao.shu[shu].hwset_vrcg, 0x1 << 19);
+}
+
+void dramc_apply_config_after_calibration(void)
+{
+ for (size_t chn = 0; chn < CHANNEL_MAX; chn++) {
+ setbits_le32(&ch[chn].phy.misc_cg_ctrl4, 0x11400000);
+ clrbits_le32(&ch[chn].ao.refctrl1, 0x1 << 7);
+ clrbits_le32(&ch[chn].ao.shuctrl, 0x1 << 2);
+ clrbits_le32(&ch[chn].phy.ca_cmd[6], 0x1 << 6);
+ dramc_set_mr13_vrcg_to_Normal(chn);
+
+ clrbits_le32(&ch[chn].phy.b[0].dq[6], 0x3);
+ clrbits_le32(&ch[chn].phy.b[1].dq[6], 0x3);
+ clrbits_le32(&ch[chn].phy.ca_cmd[6], 0x3);
+ setbits_le32(&ch[chn].phy.b[0].dq[6], 0x1 << 5);
+ setbits_le32(&ch[chn].phy.b[1].dq[6], 0x1 << 5);
+ setbits_le32(&ch[chn].phy.ca_cmd[6], 0x1 << 5);
+
+ clrbits_le32(&ch[chn].ao.impcal, 0x3 << 24);
+ clrbits_le32(&ch[chn].phy.misc_imp_ctrl0, 0x7);
+
+ clrbits_le32(&ch[chn].phy.misc_ctrl0, 0x1 << 31);
+ clrbits_le32(&ch[chn].phy.misc_ctrl1, 0x1 << 25);
+
+ setbits_le32(&ch[chn].ao.spcmdctrl, 1 << 29);
+ setbits_le32(&ch[chn].ao.dqsoscr, 1 << 24);
+
+ for (u8 shu = 0; shu < DRAM_DFS_SHUFFLE_MAX; shu++)
+ clrbits_le32(&ch[chn].ao.shu[shu].scintv, 0x1 << 30);
+
+ clrbits_le32(&ch[chn].ao.dummy_rd, (0x7 << 20) | (0x1 << 7));
+ dramc_cke_fix_onoff(chn, false, false);
+ clrbits_le32(&ch[chn].ao.dramc_pd_ctrl, 0x1 << 26);
+
+ clrbits_le32(&ch[chn].ao.eyescan, 0x7 << 8);
+ clrsetbits_le32(&ch[chn].ao.test2_4, 0x7 << 28, 0x4 << 28);
+ }
+}
+
+static void dramc_rx_dqs_isi_pulse_cg_switch(u8 chn, bool flag)
{
for (size_t b = 0; b < 2; b++)
clrsetbits_le32(&ch[chn].phy.b[b].dq[6], 1 << 5,
@@ -468,7 +514,7 @@ static void dramc_engine2_end(u8 chn)
clrbits_le32(&ch[chn].ao.test2_4, 0x1 << 17);
}
-static void find_gating_window(u32 result_r, u32 result_f, u32 *debug_cnt,
+static void dramc_find_gating_window(u32 result_r, u32 result_f, u32 *debug_cnt,
u8 dly_coarse_large, u8 dly_coarse_0p5t, u8 *pass_begin,
u8 *pass_count, u8 *dly_fine_xt, u32 *coarse_tune, u8 *dqs_high)
{
@@ -509,7 +555,7 @@ static void find_gating_window(u32 result_r, u32 result_f, u32 *debug_cnt,
}
}
-static void find_dly_tune(u8 chn, u8 dly_coarse_large, u8 dly_coarse_0p5t,
+static void dramc_find_dly_tune(u8 chn, u8 dly_coarse_large, u8 dly_coarse_0p5t,
u8 dly_fine_xt, u8 *dqs_high, u8 *dly_coarse_large_cnt,
u8 *dly_coarse_0p5t_cnt, u8 *dly_fine_tune_cnt, u8 *dqs_trans)
{
@@ -577,7 +623,7 @@ static void dramc_set_gating_mode(u8 chn, bool mode)
static void dramc_rx_dqs_gating_cal_pre(u8 chn, u8 rank)
{
- rx_dqs_isi_pulse_cg_switch(chn, false);
+ dramc_rx_dqs_isi_pulse_cg_switch(chn, false);
clrbits_le32(&ch[chn].ao.refctrl0, 1 << REFCTRL0_PBREFEN_SHIFT);
dramc_hw_gating_onoff(chn, false);
@@ -606,7 +652,7 @@ static void dramc_write_dqs_gating_result(u8 chn, u8 rank,
u8 best_coarse_rodt_p1[DQS_NUMBER];
u8 best_coarse_0p5t_rodt_p1[DQS_NUMBER];
- rx_dqs_isi_pulse_cg_switch(chn, true);
+ dramc_rx_dqs_isi_pulse_cg_switch(chn, true);
write32(&ch[chn].ao.shu[0].rk[rank].selph_dqsg0,
((u32) best_coarse_tune2t[0] <<
@@ -807,9 +853,9 @@ static void dramc_rx_dqs_gating_cal(u8 chn, u8 rank)
dramc_set_gating_mode(chn, 1);
dramc_engine2_run(chn, TE_OP_READ_CHECK);
- find_dly_tune(chn, dly_coarse_large, dly_coarse_0p5t,
- dly_fine_xt, dqs_high, dly_coarse_large_cnt,
- dly_coarse_0p5t_cnt,
+ dramc_find_dly_tune(chn, dly_coarse_large,
+ dly_coarse_0p5t, dly_fine_xt, dqs_high,
+ dly_coarse_large_cnt, dly_coarse_0p5t_cnt,
dly_fine_tune_cnt, dqs_transition);
dramc_dbg("%d %d %d |", dly_coarse_large,
@@ -825,7 +871,7 @@ static void dramc_rx_dqs_gating_cal(u8 chn, u8 rank)
}
dramc_dbg("\n");
- find_gating_window(result_r, result_f, debug_cnt,
+ dramc_find_gating_window(result_r, result_f, debug_cnt,
dly_coarse_large, dly_coarse_0p5t, pass_begin,
pass_count, &dly_fine_xt, &coarse_tune,
dqs_high);
@@ -971,7 +1017,7 @@ static void dramc_transfer_dly_tune(
dly_tune->coarse_tune_large_oen = tmp_val >> 3;
}
-static void set_rx_dly_factor(u8 chn, u8 rank, enum RX_TYPE type, u32 val)
+static void dramc_set_rx_dly_factor(u8 chn, u8 rank, enum RX_TYPE type, u32 val)
{
u32 tmp, mask;
@@ -1006,7 +1052,8 @@ static void set_rx_dly_factor(u8 chn, u8 rank, enum RX_TYPE type, u32 val)
}
}
-static void set_tx_dly_factor(u8 chn, u8 rank, enum CAL_TYPE type, u32 val)
+static void dramc_set_tx_dly_factor(u8 chn, u8 rank,
+ enum CAL_TYPE type, u32 val)
{
struct tx_dly_tune dly_tune = {0};
u32 coarse_tune_large = 0, coarse_tune_large_oen = 0;
@@ -1203,19 +1250,18 @@ static void dramc_set_rx_dly(u8 chn, u8 rank, s32 dly)
{
if (dly <= 0) {
/* Hold time calibration */
- set_rx_dly_factor(chn, rank, RX_DQS, -dly);
+ dramc_set_rx_dly_factor(chn, rank, RX_DQS, -dly);
dram_phy_reset(chn);
} else {
/* Setup time calibration */
- set_rx_dly_factor(chn, rank, RX_DQS, 0);
- set_rx_dly_factor(chn, rank, RX_DQM, dly);
+ dramc_set_rx_dly_factor(chn, rank, RX_DQS, 0);
+ dramc_set_rx_dly_factor(chn, rank, RX_DQM, dly);
dram_phy_reset(chn);
- set_rx_dly_factor(chn, rank, RX_DQ, dly);
+ dramc_set_rx_dly_factor(chn, rank, RX_DQ, dly);
}
-
}
-static void set_tx_best_dly_factor(u8 chn, u8 rank_start,
+static void dramc_set_tx_best_dly_factor(u8 chn, u8 rank_start,
struct per_byte_dly *tx_perbyte_dly, u16 dq_precal_result[])
{
u32 coarse_tune_large = 0;
@@ -1268,7 +1314,7 @@ static void set_tx_best_dly_factor(u8 chn, u8 rank_start,
FINE_TUNE_DQM_SHIFT));
}
-static void set_rx_best_dly_factor(u8 chn, u8 rank,
+static void dramc_set_rx_best_dly_factor(u8 chn, u8 rank,
struct dqdqs_perbit_dly *dqdqs_perbit_dly,
u32 *max_dqsdly_byte, u32 *ave_dqm_dly)
{
@@ -1335,7 +1381,7 @@ static void dramc_set_dqdqs_dly(u8 chn, u8 rank, enum CAL_TYPE type, s32 dly)
if ((type == RX_WIN_RD_DQC) || (type == RX_WIN_TEST_ENG))
dramc_set_rx_dly(chn, rank, dly);
else
- set_tx_dly_factor(chn, rank, type, dly);
+ dramc_set_tx_dly_factor(chn, rank, type, dly);
}
static void dramc_set_tx_best_dly(u8 chn, u8 rank,
@@ -1380,7 +1426,8 @@ static void dramc_set_tx_best_dly(u8 chn, u8 rank,
byte_dly_cell[i]);
}
- set_tx_best_dly_factor(chn, rank, tx_perbyte_dly, tx_dq_precal_result);
+ dramc_set_tx_best_dly_factor(chn, rank, tx_perbyte_dly,
+ tx_dq_precal_result);
}
static int dramc_set_rx_best_dly(u8 chn, u8 rank,
@@ -1425,7 +1472,7 @@ static int dramc_set_rx_best_dly(u8 chn, u8 rank,
return -1;
}
- set_rx_best_dly_factor(chn, rank, rx_dly, max_dqsdly_byte,
+ dramc_set_rx_best_dly_factor(chn, rank, rx_dly, max_dqsdly_byte,
ave_dqmdly_byte);
return 0;
}
@@ -1546,8 +1593,10 @@ static u8 dramc_window_perbit_cal(u8 chn, u8 rank,
dramc_set_vref(chn, rank, type, vref_dly.vref);
if ((type == RX_WIN_RD_DQC) || (type == RX_WIN_TEST_ENG)) {
- set_rx_dly_factor(chn, rank, RX_DQM, FIRST_DQ_DELAY);
- set_rx_dly_factor(chn, rank, RX_DQ, FIRST_DQ_DELAY);
+ dramc_set_rx_dly_factor(chn, rank,
+ RX_DQM, FIRST_DQ_DELAY);
+ dramc_set_rx_dly_factor(chn, rank,
+ RX_DQ, FIRST_DQ_DELAY);
}
dramc_get_dly_range(chn, rank, type, dq_precal_result,
@@ -1625,7 +1674,7 @@ static u8 dramc_window_perbit_cal(u8 chn, u8 rank,
return 0;
}
-static void dle_factor_handler(u8 chn, u8 val)
+static void dramc_dle_factor_handler(u8 chn, u8 val)
{
val = MAX(val, 2);
clrsetbits_le32(&ch[chn].ao.shu[0].conf[1],
@@ -1650,7 +1699,7 @@ static u8 dramc_rx_datlat_cal(u8 chn, u8 rank)
dramc_engine2_init(chn, rank, 0x400, false);
for (datlat = 12; datlat < DATLAT_TAP_NUMBER; datlat++) {
- dle_factor_handler(chn, datlat);
+ dramc_dle_factor_handler(chn, datlat);
u32 err = dramc_engine2_run(chn, TE_OP_WRITE_READ_CHECK);
@@ -1679,7 +1728,7 @@ static u8 dramc_rx_datlat_cal(u8 chn, u8 rank)
assert(sum != 0);
- dle_factor_handler(chn, best_step);
+ dramc_dle_factor_handler(chn, best_step);
clrsetbits_le32(&ch[chn].ao.padctrl, PADCTRL_DQIENQKEND_MASK,
(0x1 << PADCTRL_DQIENQKEND_SHIFT) |
@@ -1691,7 +1740,7 @@ static u8 dramc_rx_datlat_cal(u8 chn, u8 rank)
static void dramc_dual_rank_rx_datlat_cal(u8 chn, u8 datlat0, u8 datlat1)
{
u8 final_datlat = MAX(datlat0, datlat1);
- dle_factor_handler(chn, final_datlat);
+ dramc_dle_factor_handler(chn, final_datlat);
}
static void dramc_rx_dqs_gating_post_process(u8 chn)
@@ -1794,10 +1843,10 @@ void dramc_calibrate_all_channels(const struct sdram_params *pams)
for (u8 chn = 0; chn < CHANNEL_MAX; chn++) {
for (u8 rk = RANK_0; rk < RANK_MAX; rk++) {
dramc_show("Start K ch:%d, rank:%d\n", chn, rk);
- auto_refresh_switch(chn, false);
- cmd_bus_training(chn, rk, pams);
+ dramc_auto_refresh_switch(chn, false);
+ dramc_cmd_bus_training(chn, rk, pams);
dramc_write_leveling(chn, rk, pams->wr_level);
- auto_refresh_switch(chn, true);
+ dramc_auto_refresh_switch(chn, true);
dramc_rx_dqs_gating_cal(chn, rk);
dramc_window_perbit_cal(chn, rk, RX_WIN_RD_DQC, pams);
dramc_window_perbit_cal(chn, rk, TX_WIN_DQ_DQM, pams);
diff --git a/src/soc/mediatek/mt8183/emi.c b/src/soc/mediatek/mt8183/emi.c
index 757a453de9..937d06de37 100644
--- a/src/soc/mediatek/mt8183/emi.c
+++ b/src/soc/mediatek/mt8183/emi.c
@@ -292,11 +292,21 @@ static void init_dram(const struct sdram_params *params)
emi_init2(params);
}
+void enable_emi_dcm(void)
+{
+ clrbits_le32(&emi_regs->conm, 0xff << 24);
+ clrbits_le32(&emi_regs->conn, 0xff << 24);
+
+ for (size_t chn = 0; chn < CHANNEL_MAX; chn++)
+ clrbits_le32(&ch[chn].emi.chn_conb, 0xff << 24);
+}
+
static void do_calib(const struct sdram_params *params)
{
- dramc_apply_pre_calibration_config();
+ dramc_apply_config_before_calibration();
dramc_calibrate_all_channels(params);
dramc_ac_timing_optimize();
+ dramc_apply_config_after_calibration();
dramc_runtime_config();
}
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 781443a397..23b5cf032c 100644
--- a/src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h
+++ b/src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h
@@ -123,8 +123,10 @@ void dramc_set_broadcast(u32 onoff);
u32 dramc_get_broadcast(void);
void dramc_init(void);
void dramc_sw_impedance(const struct sdram_params *params);
-void dramc_apply_pre_calibration_config(void);
+void dramc_apply_config_before_calibration(void);
+void dramc_apply_config_after_calibration(void);
void dramc_calibrate_all_channels(const struct sdram_params *params);
void dramc_hw_gating_onoff(u8 chn, bool onoff);
void dramc_enable_phy_dcm(bool bEn);
+
#endif /* _DRAMC_PI_API_MT8183_H */
diff --git a/src/soc/mediatek/mt8183/include/soc/dramc_register.h b/src/soc/mediatek/mt8183/include/soc/dramc_register.h
index 2487504a28..f0720a7272 100644
--- a/src/soc/mediatek/mt8183/include/soc/dramc_register.h
+++ b/src/soc/mediatek/mt8183/include/soc/dramc_register.h
@@ -265,10 +265,7 @@ check_member(dramc_nao_regs, cmddrv2, 0x0474);
struct dramc_ao_regs_rk {
uint32_t dqsosc;
uint32_t rsvd_1[5];
- uint32_t dummy_rd_wdata0;
- uint32_t dummy_rd_wdata1;
- uint32_t dummy_rd_wdata2;
- uint32_t dummy_rd_wdata3;
+ uint32_t dummy_rd_wdata[4];
uint32_t dummy_rd_adr;
uint32_t dummy_rd_bk;
uint32_t pre_tdqsck[12];
diff --git a/src/soc/mediatek/mt8183/include/soc/emi.h b/src/soc/mediatek/mt8183/include/soc/emi.h
index 81e3d91daa..2c04a50e9e 100644
--- a/src/soc/mediatek/mt8183/include/soc/emi.h
+++ b/src/soc/mediatek/mt8183/include/soc/emi.h
@@ -38,6 +38,7 @@ extern const u8 phy_mapping[CHANNEL_MAX][16];
int complex_mem_test(u8 *start, unsigned int len);
size_t sdram_size(void);
const struct sdram_params *get_sdram_config(void);
+void enable_emi_dcm(void);
void mt_set_emi(const struct sdram_params *params);
void mt_mem_init(const struct sdram_params *params);