summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHuayang Duan <huayang.duan@mediatek.com>2020-06-23 16:07:36 +0800
committerHung-Te Lin <hungte@chromium.org>2020-12-31 03:07:52 +0000
commitc43e9899662fa6342f38a3ca42a2e2b4282e4484 (patch)
tree48b38e43c14a62e8d6f40501f654470bc35bde92
parent2d0117e2fe424f613bb3f3d156099d67bbe0515d (diff)
soc/mediatek/mt8192: Do dramc duty calibration
Signed-off-by: Huayang Duan <huayang.duan@mediatek.com> Change-Id: I317451e41774e983c07566dc71c7ba8833c7f55e Reviewed-on: https://review.coreboot.org/c/coreboot/+/44710 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Yu-Ping Wu <yupingso@google.com>
-rw-r--r--src/soc/mediatek/mt8192/dramc_pi_basic_api.c1
-rw-r--r--src/soc/mediatek/mt8192/dramc_pi_calibration_api.c78
2 files changed, 79 insertions, 0 deletions
diff --git a/src/soc/mediatek/mt8192/dramc_pi_basic_api.c b/src/soc/mediatek/mt8192/dramc_pi_basic_api.c
index 24f9620149..eeeeceae8a 100644
--- a/src/soc/mediatek/mt8192/dramc_pi_basic_api.c
+++ b/src/soc/mediatek/mt8192/dramc_pi_basic_api.c
@@ -3791,6 +3791,7 @@ static void dramc_init(const struct ddr_cali *cali)
dramc_setting(cali);
dramc_reset_delay_chain_before_calibration();
dramc_8_phase_cal(cali);
+ dramc_duty_calibration(cali->params);
}
static void dramc_before_calibration(const struct ddr_cali *cali)
diff --git a/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c b/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c
index 19a964ae77..e4dc896829 100644
--- a/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c
+++ b/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c
@@ -577,3 +577,81 @@ void dramc_8_phase_cal(const struct ddr_cali *cali)
for (size_t i = 0; i < ARRAY_SIZE(regs_bak); i++)
write32(regs_bak[i].addr, regs_bak[i].value);
}
+
+static void duty_delay_reg_convert(s8 duty_delay, u8 *delay)
+{
+ if (duty_delay < 0)
+ *delay = -duty_delay;
+ else if (duty_delay > 0)
+ *delay = duty_delay + (1 << 5);
+ else
+ *delay = 0;
+}
+
+static void dramc_duty_set_clk_delay_cell(u8 chn, const s8 *duty_delay)
+{
+ u8 delay;
+
+ duty_delay_reg_convert(duty_delay[RANK_0], &delay);
+ SET32_BITFIELDS(&ch[chn].phy_ao.shu_ca_txduty,
+ SHU_CA_TXDUTY_DA_TX_ARCLK_DUTY_DLY, delay);
+}
+
+static void dramc_duty_set_dqs_delay_cell(u8 chn, const s8 *duty_delay)
+{
+ u8 dqs;
+ u8 delay;
+
+ for (dqs = 0; dqs < DQS_NUMBER; dqs++) {
+ duty_delay_reg_convert(duty_delay[dqs], &delay);
+ SET32_BITFIELDS(&ch[chn].phy_ao.byte[dqs].shu_b0_txduty,
+ SHU_B0_TXDUTY_DA_TX_ARDQS_DUTY_DLY_B0, delay);
+ }
+}
+
+static void dramc_duty_set_wck_delay_cell(u8 chn, const s8 *duty_delay)
+{
+ u8 dqs;
+ u8 delay;
+
+ for (dqs = 0; dqs < DQS_NUMBER; dqs++) {
+ duty_delay_reg_convert(duty_delay[dqs], &delay);
+ SET32_BITFIELDS(&ch[chn].phy_ao.byte[dqs].shu_b0_txduty,
+ SHU_B0_TXDUTY_DA_TX_ARWCK_DUTY_DLY_B0, delay);
+ }
+}
+
+static void dramc_duty_set_dqdqm_delay_cell(u8 chn, const s8 *duty_delay,
+ u8 k_type)
+{
+ u8 dqs;
+ u8 delay;
+
+ for (dqs = 0; dqs < DQS_NUMBER; dqs++) {
+ duty_delay_reg_convert(duty_delay[dqs], &delay);
+
+ if (k_type == DUTYSCAN_K_DQ)
+ SET32_BITFIELDS(&ch[chn].phy_ao.byte[dqs].shu_b0_txduty,
+ SHU_B0_TXDUTY_DA_TX_ARDQ_DUTY_DLY_B0, delay);
+ else if (k_type == DUTYSCAN_K_DQM)
+ SET32_BITFIELDS(&ch[chn].phy_ao.byte[dqs].shu_b0_txduty,
+ SHU_B0_TXDUTY_DA_TX_ARDQM_DUTY_DLY_B0, delay);
+ }
+}
+
+void dramc_duty_calibration(const struct sdram_params *params)
+{
+ u32 bc_bak = dramc_get_broadcast();
+ dramc_set_broadcast(DRAMC_BROADCAST_OFF);
+ for (u8 chn = 0; chn < CHANNEL_MAX; chn++) {
+ dramc_duty_set_clk_delay_cell(chn, params->duty_clk_delay[chn]);
+ dramc_duty_set_dqs_delay_cell(chn, params->duty_dqs_delay[chn]);
+ dramc_duty_set_wck_delay_cell(chn, params->duty_wck_delay[chn]);
+ dramc_duty_set_dqdqm_delay_cell(chn, params->duty_dqm_delay[chn],
+ DUTYSCAN_K_DQM);
+ dramc_duty_set_dqdqm_delay_cell(chn, params->duty_dq_delay[chn],
+ DUTYSCAN_K_DQ);
+ }
+
+ dramc_set_broadcast(bc_bak);
+}