Tristan Hsieh has uploaded this change for review. ( https://review.coreboot.org/28837
Change subject: mediatek/mt8183: Add DDR driver of software impedance part ......................................................................
mediatek/mt8183: Add DDR driver of software impedance part
BUG=b:80501386 BRANCH=none TEST=Boots correctly on Kukui, and inits DRAM successfully with related patches.
Change-Id: I42a33ffb66ffa2f938f85484ffc3a0d3788816b3 Signed-off-by: Huayang Duan huayang.duan@mediatek.com --- M src/soc/mediatek/mt8183/Makefile.inc A src/soc/mediatek/mt8183/dramc_pi_basic_api.c M src/soc/mediatek/mt8183/emi.c M src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h 4 files changed, 132 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/37/28837/1
diff --git a/src/soc/mediatek/mt8183/Makefile.inc b/src/soc/mediatek/mt8183/Makefile.inc index 3cd845d..e9b5f42 100644 --- a/src/soc/mediatek/mt8183/Makefile.inc +++ b/src/soc/mediatek/mt8183/Makefile.inc @@ -21,6 +21,7 @@ verstage-y += ../common/wdt.c
romstage-y += ../common/cbmem.c emi.c +romstage-y += dramc_pi_basic_api.c romstage-y += memory.c romstage-y += ../common/gpio.c gpio.c romstage-y += ../common/mmu_operations.c mmu_operations.c diff --git a/src/soc/mediatek/mt8183/dramc_pi_basic_api.c b/src/soc/mediatek/mt8183/dramc_pi_basic_api.c new file mode 100644 index 0000000..4c95814 --- /dev/null +++ b/src/soc/mediatek/mt8183/dramc_pi_basic_api.c @@ -0,0 +1,124 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2018 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <arch/io.h> +#include <delay.h> +#include <soc/emi.h> +#include <soc/dramc_register.h> +#include <soc/dramc_pi_api.h> + +static void sw_imp_cal_vref_sel(u8 term_option, u8 impcal_stage) +{ + u8 vref_sel = 0; + + if (term_option == 1) { + vref_sel = IMP_LP4X_TERM_VREF_SEL; + } else { + if (impcal_stage == IMPCAL_STAGE_DRVP) + vref_sel = IMP_DRVP_LP4X_UNTERM_VREF_SEL; + else if (impcal_stage == IMPCAL_STAGE_DRVN) + vref_sel = IMP_DRVN_LP4X_UNTERM_VREF_SEL; + else + vref_sel = IMP_TRACK_LP4X_UNTERM_VREF_SEL; + } + + dramc_dbg("[%s] IMP_VREF_SEL 0x%x\n", __func__, vref_sel); + clrsetbits_le32(&ch[0].phy.shu[0].ca_cmd[11], 0x3f << 8, vref_sel << 8); +} + +void dramc_sw_impedance(const struct sdram_params *params) +{ + u32 broadcast_bak = dramc_get_broadcast(); + u8 term = 0, ca_term = ODT_OFF, dq_term = ODT_ON; + u32 sw_impedance[2][4] = { {0}, {0} }; + + for (term = 0; term < 2; term++) + for (u8 i = 0; i < 4; i++) + sw_impedance[term][i] = params->impedance[term][i]; + + sw_impedance[ODT_OFF][2] = sw_impedance[ODT_ON][2]; + sw_impedance[ODT_OFF][3] = sw_impedance[ODT_ON][3]; + dramc_set_broadcast(DRAMC_BROADCAST_ON); + + clrsetbits_le32(&ch[0].phy.shu[0].ca_cmd[11], 0xFF, 0x3); + + /* Set IMP_VREF_SEL value for DRVP */ + sw_imp_cal_vref_sel(dq_term, IMPCAL_STAGE_DRVP); + + /* DQ */ + clrsetbits_le32(&ch[0].ao.shu[0].drving[0], (0x1F << 5) | (0x1F << 0), + (sw_impedance[dq_term][0] << 5) | + (sw_impedance[dq_term][1] << 0)); + clrsetbits_le32(&ch[0].ao.shu[0].drving[1], + (0x1F << 25)|(0x1F << 20) | (1 << 31), + (sw_impedance[dq_term][0] << 25) | + (sw_impedance[dq_term][1] << 20) | (!dq_term << 31)); + clrsetbits_le32(&ch[0].ao.shu[0].drving[2], (0x1F << 5) | (0x1F << 0), + (sw_impedance[dq_term][2] << 5) | + (sw_impedance[dq_term][3] << 0)); + clrsetbits_le32(&ch[0].ao.shu[0].drving[3], (0x1F << 25) | (0x1F << 20), + (sw_impedance[dq_term][2] << 25) | + (sw_impedance[dq_term][3] << 20)); + + /* DQS */ + for (u8 i = 0; i <= 2; i += 2) { + clrsetbits_le32(&ch[0].ao.shu[0].drving[i], + (0x1F << 25) | (0x1F << 20), + (sw_impedance[dq_term][i] << 25) | + (sw_impedance[dq_term][i + 1] << 20)); + clrsetbits_le32(&ch[0].ao.shu[0].drving[i], + (0x1F << 15) | (0x1F << 10), + (sw_impedance[dq_term][i] << 15) | + (sw_impedance[dq_term][i + 1] << 10)); + } + + /* CMD & CLK */ + for (u8 i = 1; i <= 3; i += 2) { + clrsetbits_le32(&ch[0].ao.shu[0].drving[i], + (0x1F << 15) | (0x1F << 10), + (sw_impedance[ca_term][i - 1] << 15) | + (sw_impedance[ca_term][i] << 10)); + clrsetbits_le32(&ch[0].ao.shu[0].drving[i], + (0x1F << 5) | (0x1F << 0), + (sw_impedance[ca_term][i - 1] << 5) | + (sw_impedance[ca_term][i] << 0)); + } + + /* RG_TX_*RCKE_DRVP/RG_TX_*RCKE_DRVN doesn't set, so set 0xA first */ + clrsetbits_le32(&ch[0].phy.shu[0].ca_cmd[11], 0x1f << 17, + sw_impedance[ca_term][0] << 17); + clrsetbits_le32(&ch[0].phy.shu[0].ca_cmd[11], 0x1f << 22, + sw_impedance[ca_term][1] << 22); + /* DRVP[4:0] = RG_TX_ARCMD_PU_PRE<1:0>, RG_TX_ARCLK_DRVN_PRE<2:0> */ + clrsetbits_le32(&ch[0].phy.shu[0].ca_cmd[3], + SHU1_CA_CMD3_RG_TX_ARCMD_PU_PRE_MASK, + (((8 >> 3) & 0x3) << SHU1_CA_CMD3_RG_TX_ARCMD_PU_PRE_SHIFT)); + clrsetbits_le32(&ch[0].phy.shu[0].ca_cmd[0], + SHU1_CA_CMD0_RG_TX_ARCLK_DRVN_PRE_MASK, + ((8 & 0x7) << SHU1_CA_CMD0_RG_TX_ARCLK_DRVN_PRE_SHIFT)); + + dramc_set_broadcast(DRAMC_BROADCAST_OFF); + clrsetbits_le32(&ch[0].phy.shu[0].ca_dll[1], 0x1F << 16, 0x9 << 16); + clrsetbits_le32(&ch[1].phy.shu[0].ca_dll[1], 0x1F << 16, 0x9 << 16); + dramc_set_broadcast(DRAMC_BROADCAST_ON); + + for (term = 0; term < 2; term++) { + dramc_show("term=%d, Reg: DRVP=%d, DRVN=%d, ODTN=%d\n", + term, sw_impedance[term][0], + sw_impedance[term][1], sw_impedance[term][3]); + } + dramc_set_broadcast(broadcast_bak); +} + diff --git a/src/soc/mediatek/mt8183/emi.c b/src/soc/mediatek/mt8183/emi.c index 7008ccc..37997aa 100644 --- a/src/soc/mediatek/mt8183/emi.c +++ b/src/soc/mediatek/mt8183/emi.c @@ -287,6 +287,7 @@
dramc_set_broadcast(DRAMC_BROADCAST_ON); dramc_init_pre_settings(); + dramc_sw_impedance(params);
dramc_init(); emi_init2(params); 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 e24bd6c..af96316 100644 --- a/src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h +++ b/src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h @@ -39,6 +39,11 @@ #define DRAMC_BROADCAST_OFF 0x0 #define MAX_BACKUP_REG_CNT 32
+#define IMP_LP4X_TERM_VREF_SEL 0x1b +#define IMP_DRVP_LP4X_UNTERM_VREF_SEL 0x1a +#define IMP_DRVN_LP4X_UNTERM_VREF_SEL 0x16 +#define IMP_TRACK_LP4X_UNTERM_VREF_SEL 0x1a + enum dram_te_op { TE_OP_WRITE_READ_CHECK = 0, TE_OP_READ_CHECK @@ -132,4 +137,5 @@ void dramc_get_rank_size(u64 *dram_rank_size); void dramc_set_broadcast(u32 onoff); u32 dramc_get_broadcast(void); +void dramc_sw_impedance(const struct sdram_params *params); #endif /* _DRAMC_PI_API_MT8183_H */