CK HU would like Duan huayang to review this change.

View Change

soc/mediatek/mt8192: Do dramc software impedance calibration

Signed-off-by: Huayang Duan <huayang.duan@mediatek.com>
Change-Id: I2c6ffe885717997540a0a9721310e355a3b6a87d
---
M src/soc/mediatek/mt8192/Makefile.inc
A src/soc/mediatek/mt8192/dramc_pi_calibration_api.c
M src/soc/mediatek/mt8192/dramc_pi_main.c
3 files changed, 184 insertions(+), 1 deletion(-)

git pull ssh://review.coreboot.org:29418/coreboot refs/changes/04/44704/1
diff --git a/src/soc/mediatek/mt8192/Makefile.inc b/src/soc/mediatek/mt8192/Makefile.inc
index e82f182..bf819ec 100644
--- a/src/soc/mediatek/mt8192/Makefile.inc
+++ b/src/soc/mediatek/mt8192/Makefile.inc
@@ -16,7 +16,7 @@
verstage-y += ../common/uart.c

romstage-y += ../common/cbmem.c
-romstage-y += dramc_pi_main.c dramc_pi_basic_api.c dramc_utility.c
+romstage-y += dramc_pi_main.c dramc_pi_basic_api.c dramc_pi_calibration_api.c dramc_utility.c
romstage-y += emi.c
romstage-y += flash_controller.c
romstage-y += ../common/gpio.c gpio.c
diff --git a/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c b/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c
new file mode 100644
index 0000000..04ff5d7
--- /dev/null
+++ b/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c
@@ -0,0 +1,180 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <string.h>
+#include <soc/dramc_pi_api.h>
+#include <soc/dramc_register.h>
+#include <timer.h>
+
+static const u8 imp_vref_sel[ODT_MAX][IMP_DRV_MAX] = {
+ /* DRVP DRVN ODTP ODTN */
+ [ODT_OFF] = {0x37, 0x33, 0x00, 0x37},
+ [ODT_ON] = {0x3a, 0x33, 0x00, 0x3a},
+};
+
+static void dramc_imp_cal_vref_sel(dram_odt_state odt, imp_drv_type drv_type)
+{
+ u8 vref_tmp = 0;
+ vref_tmp = imp_vref_sel[odt][drv_type];
+
+ switch (drv_type) {
+ case DRVP:
+ SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_cmd12,
+ SHU_CA_CMD12_RG_RIMP_VREF_SEL_DRVP, vref_tmp);
+ break;
+ case DRVN:
+ SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_cmd12,
+ SHU_CA_CMD12_RG_RIMP_VREF_SEL_DRVN, vref_tmp);
+ break;
+ case ODTN:
+ SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_cmd12,
+ SHU_CA_CMD12_RG_RIMP_VREF_SEL_ODTN, vref_tmp);
+ break;
+ default:
+ die("Can't support drv_type %d\n", drv_type);
+ break;
+ }
+}
+
+static u32 dramc_sw_imp_cal_result(imp_drv_type drv_type)
+{
+ u32 drive = 0, cal_res = 0;
+ u32 change = (drv_type == DRVP) ? 1: 0;
+
+ const char *drv_str = NULL;
+ switch (drv_type) {
+ case DRVP:
+ drv_str = "DRVP";
+ break;
+ case DRVN:
+ drv_str = "DRVN";
+ break;
+ case ODTP:
+ drv_str = "ODTP";
+ break;
+ case ODTN:
+ drv_str = "ODTN";
+ break;
+ default:
+ die("Can't support drv_type %d\n", drv_type);
+ break;
+ }
+
+ for (drive = 0; drive < 32; drive++) {
+ if (drv_type == DRVP)
+ SET32_BITFIELDS(&ch[0].phy_ao.shu_misc_impcal1,
+ SHU_MISC_IMPCAL1_IMPDRVP, drive);
+ else if (drv_type == DRVN || drv_type == ODTN)
+ SET32_BITFIELDS(&ch[0].phy_ao.shu_misc_impcal1,
+ SHU_MISC_IMPCAL1_IMPDRVN, drive);
+
+ udelay(1);
+ cal_res = READ32_BITFIELD(&ch[0].phy_nao.misc_phy_rgs_cmd,
+ MISC_PHY_RGS_CMD_RGS_RIMPCALOUT);
+ dramc_dbg("OCD %s=%d ,CALOUT=%d\n", drv_str, drive, cal_res);
+
+ if (cal_res == change) {
+ dramc_info("%s calibration OK! result=%d\n", drv_str, drive);
+ break;
+ }
+ }
+
+ if (drive == 32) {
+ drive = 31;
+ dramc_err("OCD %s calibration FAIL! %s=%d\n", drv_str, drv_str, drive);
+ }
+
+ return drive;
+}
+
+void dramc_sw_impedance_cal(dram_odt_state odt, struct dram_impedance *imp)
+{
+ u8 chn = 0, i_chn, enp, enn;
+ u32 bc_bak, impcal_bak, cal_res = 0;
+ u32 drvp_result = 0xff, odtn_result = 0xff, drvn_result = 0xff;
+
+ bc_bak = dramc_get_broadcast();
+ dramc_set_broadcast(DRAMC_BROADCAST_OFF);
+ for (i_chn = 0; i_chn < CHANNEL_MAX; i_chn++) {
+ SET32_BITFIELDS(&ch[i_chn].phy_ao.misc_lp_ctrl,
+ MISC_LP_CTRL_RG_ARDMSUS_10, 0x0,
+ MISC_LP_CTRL_RG_ARDMSUS_10_LP_SEL, 0x0,
+ MISC_LP_CTRL_RG_RIMP_DMSUS_10, 0x0,
+ MISC_LP_CTRL_RG_RIMP_DMSUS_10_LP_SEL, 0x0);
+ SET32_BITFIELDS(&ch[i_chn].phy_ao.misc_impcal, MISC_IMPCAL_IMPCAL_HW, 0);
+ }
+
+ impcal_bak = read32(&ch[chn].phy_ao.misc_impcal);
+ SET32_BITFIELDS(&ch[chn].phy_ao.misc_imp_ctrl1, MISC_IMP_CTRL1_RG_RIMP_PRE_EN, 0);
+ SET32_BITFIELDS(&ch[chn].phy_ao.misc_impcal,
+ MISC_IMPCAL_IMPCAL_CALI_ENN, 0,
+ MISC_IMPCAL_IMPCAL_IMPPDP, 1,
+ MISC_IMPCAL_IMPCAL_IMPPDN, 1);
+ SET32_BITFIELDS(&ch[chn].phy_ao.misc_imp_ctrl1,
+ MISC_IMP_CTRL1_RG_IMP_EN, 1,
+ MISC_IMP_CTRL1_RG_RIMP_DDR3_SEL, 0,
+ MISC_IMP_CTRL1_RG_RIMP_VREF_EN, 1,
+ MISC_IMP_CTRL1_RG_RIMP_DDR4_SEL, 1);
+ udelay(1);
+ SET32_BITFIELDS(&ch[chn].phy_ao.misc_impcal, MISC_IMPCAL_IMPCAL_CALI_EN, 1);
+ SET32_BITFIELDS(&ch[chn].phy_ao.shu_misc_impcal1,
+ SHU_MISC_IMPCAL1_IMPDRVN, 0,
+ SHU_MISC_IMPCAL1_IMPDRVP, 0);
+
+ for (imp_drv_type drv_type = DRVP; drv_type < IMP_DRV_MAX; drv_type++) {
+ if (drv_type == ODTP)
+ continue;
+ dramc_imp_cal_vref_sel(odt, drv_type);
+
+ switch (drv_type) {
+ case DRVP:
+ enp = 0x1;
+ enn = 0x0;
+ drvp_result = 0;
+ break;
+ case DRVN:
+ case ODTN:
+ enp = 0x0;
+ enn = (drv_type == DRVN) ? 0x0 : 0x1;
+ break;
+ default:
+ die("Can't support drv_type %d\n", drv_type);
+ break;
+ }
+
+ SET32_BITFIELDS(&ch[chn].phy_ao.misc_impcal,
+ MISC_IMPCAL_IMPCAL_CALI_ENP, enp);
+ SET32_BITFIELDS(&ch[chn].phy_ao.misc_impcal,
+ MISC_IMPCAL_IMPCAL_CALI_ENN, enn);
+ SET32_BITFIELDS(&ch[chn].phy_ao.shu_misc_impcal1,
+ SHU_MISC_IMPCAL1_IMPDRVP, drvp_result);
+ SET32_BITFIELDS(&ch[chn].phy_ao.shu_ca_cmd12,
+ SHU_CA_CMD12_RG_RIMP_DRV05, 0);
+
+ cal_res = dramc_sw_imp_cal_result(drv_type);
+ switch (drv_type) {
+ case DRVP:
+ drvp_result = cal_res;
+ break;
+ case DRVN:
+ drvn_result = cal_res;
+ break;
+ case ODTN:
+ odtn_result = cal_res;
+ break;
+ default:
+ die("Can't support drv_type %d\n", drv_type);
+ break;
+ }
+ }
+
+ imp->result[odt][DRVP] = drvp_result;
+ imp->result[odt][DRVN] = drvn_result;
+ imp->result[odt][ODTP] = 0;
+ imp->result[odt][ODTN] = odtn_result;
+
+ dramc_info("freq_region=%d, Reg: DRVP=%d, DRVN=%d, ODTN=%d\n",
+ odt, drvp_result, drvn_result, odtn_result);
+
+ write32(&ch[chn].phy_ao.misc_impcal, impcal_bak);
+ dramc_set_broadcast(bc_bak);
+}
diff --git a/src/soc/mediatek/mt8192/dramc_pi_main.c b/src/soc/mediatek/mt8192/dramc_pi_main.c
index 184479d..355cc9d 100644
--- a/src/soc/mediatek/mt8192/dramc_pi_main.c
+++ b/src/soc/mediatek/mt8192/dramc_pi_main.c
@@ -73,6 +73,9 @@
emi_mdl_init(cali.emi_config);
dramc_set_broadcast(bc_bak);

+ dramc_sw_impedance_cal(ODT_OFF, &cali.impedance);
+ dramc_sw_impedance_cal(ODT_ON, &cali.impedance);
+
if (ddr_info->config_dvfs == DRAMC_ENABLE_DVFS)
k_shuffle_end = CALI_SEQ_MAX;
else

To view, visit change 44704. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I2c6ffe885717997540a0a9721310e355a3b6a87d
Gerrit-Change-Number: 44704
Gerrit-PatchSet: 1
Gerrit-Owner: CK HU <ck.hu@mediatek.com>
Gerrit-Reviewer: Duan huayang <huayang.duan@mediatek.com>
Gerrit-Reviewer: Julius Werner <jwerner@chromium.org>
Gerrit-Reviewer: Martin Roth <martinroth@google.com>
Gerrit-Reviewer: Patrick Georgi <pgeorgi@google.com>
Gerrit-MessageType: newchange