Hello Duan huayang,
I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/44710
to review the following change.
Change subject: soc/mediatek/mt8192: Do dramc duty calibration ......................................................................
soc/mediatek/mt8192: Do dramc duty calibration
Signed-off-by: Huayang Duan huayang.duan@mediatek.com Change-Id: I317451e41774e983c07566dc71c7ba8833c7f55e --- M src/soc/mediatek/mt8192/dramc_pi_basic_api.c M src/soc/mediatek/mt8192/dramc_pi_calibration_api.c 2 files changed, 84 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/10/44710/1
diff --git a/src/soc/mediatek/mt8192/dramc_pi_basic_api.c b/src/soc/mediatek/mt8192/dramc_pi_basic_api.c index b5b262b..091b21b 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 @@ 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 22a2545..e1f3d67 100644 --- a/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c +++ b/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c @@ -579,3 +579,86 @@ 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) +{ + u8 delay_tmp; + + if (duty_delay < 0) + delay_tmp = -duty_delay; + else if (duty_delay > 0) + delay_tmp = duty_delay + (1 << 5); + else + delay_tmp = 0; + + *delay = delay_tmp; +} + +static void dramc_duty_set_clk_delay_cell(u8 chn, const s8* duty_delay) +{ + u8 delay_tmp; + + duty_delay_reg_convert(duty_delay[0], &delay_tmp); + SET32_BITFIELDS(&ch[chn].phy_ao.shu_ca_txduty, + SHU_CA_TXDUTY_DA_TX_ARCLK_DUTY_DLY, delay_tmp); +} + +static void dramc_duty_set_dqs_delay_cell(u8 chn, const s8* duty_delay) +{ + u8 dqs; + u8 delay_tmp[DQS_NUMBER]; + + for (dqs = 0; dqs < DQS_NUMBER; dqs++) { + duty_delay_reg_convert(duty_delay[dqs], &(delay_tmp[dqs])); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[dqs].shu_b0_txduty, + SHU_B0_TXDUTY_DA_TX_ARDQS_DUTY_DLY_B0, delay_tmp[dqs]); + } +} + + +static void dramc_duty_set_wck_delay_cell(u8 chn, const s8* duty_delay) +{ + u8 dqs; + u8 delay_tmp[DQS_NUMBER]; + + for (dqs = 0; dqs < DQS_NUMBER; dqs++) { + duty_delay_reg_convert(duty_delay[dqs], &(delay_tmp[dqs])); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[dqs].shu_b0_txduty, + SHU_B0_TXDUTY_DA_TX_ARWCK_DUTY_DLY_B0, delay_tmp[dqs]); + } +} + +static void dramc_duty_set_dqdqm_delay_cell(u8 chn, + const s8* duty_delay, u8 k_type) +{ + u8 dqs; + u8 delay_tmp[DQS_NUMBER]; + + for (dqs = 0; dqs < DQS_NUMBER; dqs++) { + duty_delay_reg_convert(duty_delay[dqs], &(delay_tmp[dqs])); + + 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_tmp[dqs]); + 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_tmp[dqs]); + } +} + +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); +}