diff options
Diffstat (limited to 'src/soc/mediatek')
-rw-r--r-- | src/soc/mediatek/mt8183/dramc_init_setting.c | 46 | ||||
-rw-r--r-- | src/soc/mediatek/mt8183/dramc_pi_calibration_api.c | 344 | ||||
-rw-r--r-- | src/soc/mediatek/mt8183/emi.c | 4 | ||||
-rw-r--r-- | src/soc/mediatek/mt8183/include/soc/dramc_common_mt8183.h | 1 | ||||
-rw-r--r-- | src/soc/mediatek/mt8183/include/soc/dramc_param.h | 2 | ||||
-rw-r--r-- | src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h | 17 | ||||
-rw-r--r-- | src/soc/mediatek/mt8183/include/soc/dramc_register.h | 88 | ||||
-rw-r--r-- | src/soc/mediatek/mt8183/include/soc/emi.h | 1 |
8 files changed, 449 insertions, 54 deletions
diff --git a/src/soc/mediatek/mt8183/dramc_init_setting.c b/src/soc/mediatek/mt8183/dramc_init_setting.c index 794fad1c3d..8a5d319b29 100644 --- a/src/soc/mediatek/mt8183/dramc_init_setting.c +++ b/src/soc/mediatek/mt8183/dramc_init_setting.c @@ -11,24 +11,19 @@ #include <string.h> #include <timer.h> -enum { - CKE_FIXOFF = 0, - CKE_FIXON, - CKE_DYNAMIC -}; - -static void cke_fix_onoff(int option, u8 chn) +void dramc_cke_fix_onoff(enum cke_type option, u8 chn) { u8 on = 0, off = 0; /* if CKE is dynamic, set both CKE fix On and Off as 0 */ if (option != CKE_DYNAMIC) { on = option; - off = (1 - option); + off = 1 - option; } - clrsetbits32(&ch[chn].ao.ckectrl, - (0x1 << 6) | (0x1 << 7), (on << 6) | (off << 7)); + SET32_BITFIELDS(&ch[chn].ao.ckectrl, + CKECTRL_CKEFIXON, on, + CKECTRL_CKEFIXOFF, off); } static void dvfs_settings(u8 freq_group) @@ -296,8 +291,8 @@ static void ddr_phy_pll_setting(u8 chn, u8 freq_group) for (size_t i = 0; i < ARRAY_SIZE(regs_bak); i++) write32(regs_bak[i].addr, regs_bak[i].value); - cke_fix_onoff(CKE_DYNAMIC, CHANNEL_A); - cke_fix_onoff(CKE_DYNAMIC, CHANNEL_B); + dramc_cke_fix_onoff(CKE_DYNAMIC, CHANNEL_A); + dramc_cke_fix_onoff(CKE_DYNAMIC, CHANNEL_B); if (freq_group == LP4X_DDR3200 || freq_group == LP4X_DDR3600) { setbits32(&ch[chn].phy.shu[0].pll[5], 0x1 << 0); @@ -522,6 +517,19 @@ static void update_initial_settings(u8 freq_group) (0x1 << 31) | (0xa << 21) | (0xa << 26)); setbits32(&ch[0].ao.ckectrl, 0x1 << 23); clrbits32(&ch[0].ao.shu[0].rodtenstb, 0x1 << 31); + + /* CA prebit shift and delay */ + SET32_BITFIELDS(&ch[0].ao.shu[0].selph_ca7, + SHU_SELPH_CA7_DLY_RA0, 0x0, + SHU_SELPH_CA7_DLY_RA1, 0x0, + SHU_SELPH_CA7_DLY_RA2, 0x0, + SHU_SELPH_CA7_DLY_RA3, 0x0, + SHU_SELPH_CA7_DLY_RA4, 0x0, + SHU_SELPH_CA7_DLY_RA5, 0x0); + SET32_BITFIELDS(&ch[0].phy.shu[0].rk[0].ca_cmd[9], + SHU1_R0_CA_CMD9_RG_RK0_ARPI_CMD, 0x20); + SET32_BITFIELDS(&ch[0].phy.shu[0].rk[1].ca_cmd[9], + SHU1_R1_CA_CMD9_RG_RK1_ARPI_CMD, 0x20); } static void dramc_power_on_sequence(void) @@ -529,8 +537,8 @@ static void dramc_power_on_sequence(void) for (size_t chn = 0; chn < CHANNEL_MAX; chn++) clrbits32(&ch[chn].phy.misc_ctrl1, 0x1 << 13); - dramc_cke_fix_onoff(CHANNEL_A, false, true); - dramc_cke_fix_onoff(CHANNEL_B, false, true); + dramc_cke_fix_onoff(CKE_FIXOFF, CHANNEL_A); + dramc_cke_fix_onoff(CKE_FIXOFF, CHANNEL_B); udelay(200); for (size_t chn = 0; chn < CHANNEL_MAX; chn++) @@ -540,8 +548,8 @@ static void dramc_power_on_sequence(void) setbits32(&ch[chn].ao.dramc_pd_ctrl, 0x1 << 26); udelay(2000); - dramc_cke_fix_onoff(CHANNEL_A, true, false); - dramc_cke_fix_onoff(CHANNEL_B, true, false); + dramc_cke_fix_onoff(CKE_FIXON, CHANNEL_A); + dramc_cke_fix_onoff(CKE_FIXON, CHANNEL_B); udelay(2); } @@ -698,7 +706,7 @@ static u8 dramc_zq_calibration(u8 chn, u8 rank) regs_bak[i].value = read32(regs_bak[i].addr); setbits32(&ch[chn].ao.dramc_pd_ctrl, 0x1 << 26); - dramc_cke_fix_onoff(chn, true, false); + dramc_cke_fix_onoff(CKE_FIXON, chn); SET32_BITFIELDS(&ch[chn].ao.mrs, MRS_MRSRK, rank); SET32_BITFIELDS(&ch[chn].ao.mpc_option, MPC_OPTION_MPCRKEN, 1); @@ -842,8 +850,8 @@ static void auto_refresh_cke_off(void) setbits32(&ch[chn].ao.refctrl0, 0x1 << 29); udelay(3); - cke_fix_onoff(CKE_FIXOFF, CHANNEL_A); - cke_fix_onoff(CKE_FIXOFF, CHANNEL_B); + dramc_cke_fix_onoff(CKE_FIXOFF, CHANNEL_A); + dramc_cke_fix_onoff(CKE_FIXOFF, CHANNEL_B); dramc_set_broadcast(broadcast_bak); } diff --git a/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c b/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c index fce7c9ff4a..17fa2306e3 100644 --- a/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c +++ b/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c @@ -8,6 +8,7 @@ #include <soc/dramc_register.h> #include <soc/dramc_param.h> #include <soc/dramc_pi_api.h> +#include <soc/spm.h> #include <timer.h> enum { @@ -72,6 +73,11 @@ struct per_byte_dly { u16 final_dly; }; +static const u8 lp4_ca_mapping_pop[CHANNEL_MAX][CA_NUM_LP4] = { + [CHANNEL_A] = {1, 4, 3, 2, 0, 5}, + [CHANNEL_B] = {0, 3, 2, 4, 1, 5}, +}; + static void dramc_auto_refresh_switch(u8 chn, bool option) { SET32_BITFIELDS(&ch[chn].ao.refctrl0, REFCTRL0_REFDIS, option ? 0 : 1); @@ -86,13 +92,6 @@ static void dramc_auto_refresh_switch(u8 chn, bool option) } } -void dramc_cke_fix_onoff(u8 chn, bool cke_on, bool cke_off) -{ - SET32_BITFIELDS(&ch[chn].ao.ckectrl, - CKECTRL_CKEFIXON, cke_on, - CKECTRL_CKEFIXOFF, cke_off); -} - static u16 dramc_mode_reg_read(u8 chn, u8 mr_idx) { u16 value; @@ -116,7 +115,7 @@ void dramc_mode_reg_write(u8 chn, u8 mr_idx, u8 value) { u32 ckectrl_bak = read32(&ch[chn].ao.ckectrl); - dramc_cke_fix_onoff(chn, true, false); + dramc_cke_fix_onoff(CKE_FIXON, chn); SET32_BITFIELDS(&ch[chn].ao.mrs, MRS_MRSMA, mr_idx); SET32_BITFIELDS(&ch[chn].ao.mrs, MRS_MRSOP, value); SET32_BITFIELDS(&ch[chn].ao.spcmd, SPCMD_MRWEN, 1); @@ -255,33 +254,320 @@ static void dramc_write_leveling(u8 chn, u8 rank, u8 freq_group, } } -static void dramc_cmd_bus_training(u8 chn, u8 rank, u8 freq_group, - const struct sdram_params *params, const bool fast_calib) +static void cbt_set_perbit_delay_cell(u8 chn, u8 rank) { - u32 final_vref, clk_dly, cmd_dly, cs_dly; + SET32_BITFIELDS(&ch[chn].phy.shu[0].rk[rank].ca_cmd[0], + SHU1_R0_CA_CMD0_RK0_TX_ARCA0_DLY, 0, + SHU1_R0_CA_CMD0_RK0_TX_ARCA1_DLY, 0, + SHU1_R0_CA_CMD0_RK0_TX_ARCA2_DLY, 0, + SHU1_R0_CA_CMD0_RK0_TX_ARCA3_DLY, 0, + SHU1_R0_CA_CMD0_RK0_TX_ARCA4_DLY, 0, + SHU1_R0_CA_CMD0_RK0_TX_ARCA5_DLY, 0); +} - clk_dly = params->cbt_clk_dly[chn][rank]; - cmd_dly = params->cbt_cmd_dly[chn][rank]; - cs_dly = params->cbt_cs_dly[chn][rank]; - final_vref = params->cbt_final_vref[chn][rank]; +static void set_dram_mr_cbt_on_off(u8 chn, u8 rank, u8 fsp, + u8 cbt_on, struct mr_value *mr) +{ + u8 MR13Value = mr->MR13Value; - if (fast_calib) { + if (cbt_on) { + MR13Value |= 0x1; + if (fsp == FSP_1) + MR13Value &= 0x7f; + else + MR13Value |= 0x80; + } else { + MR13Value &= 0xfe; + if (fsp == FSP_1) + MR13Value |= 0x80; + else + MR13Value &= 0x7f; + } + + dramc_mode_reg_write_by_rank(chn, rank, 13, MR13Value); + mr->MR13Value = MR13Value; +} + +static void cbt_set_fsp(u8 chn, u8 rank, u8 fsp, struct mr_value *mr) +{ + u8 MR13Value = mr->MR13Value; + + if (fsp == FSP_0) { + MR13Value &= ~(BIT(6)); + MR13Value &= 0x7f; + } else { + MR13Value |= BIT(6); + MR13Value |= 0x80; + } + + dramc_mode_reg_write_by_rank(chn, rank, 13, MR13Value); + mr->MR13Value = MR13Value; +} + +static void o1_path_on_off(u8 cbt_on) +{ + u8 fix_dqien = (cbt_on == 1) ? 3 : 0; + + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) { + SET32_BITFIELDS(&ch[chn].ao.padctrl, PADCTRL_FIXDQIEN, fix_dqien); + SET32_BITFIELDS(&ch[chn].phy.b[0].dq[5], + B0_DQ5_RG_RX_ARDQ_EYE_VREF_EN_B0, cbt_on); + SET32_BITFIELDS(&ch[chn].phy.b[1].dq[5], + B1_DQ5_RG_RX_ARDQ_EYE_VREF_EN_B1, cbt_on); + SET32_BITFIELDS(&ch[chn].phy.b[0].dq[3], + B0_DQ3_RG_RX_ARDQ_SMT_EN_B0, cbt_on); + SET32_BITFIELDS(&ch[chn].phy.b[1].dq[3], + B1_DQ3_RG_RX_ARDQ_SMT_EN_B1, cbt_on); + } + udelay(1); +} + +static void cbt_entry(u8 chn, u8 rank, u8 fsp, struct mr_value *mr) +{ + SET32_BITFIELDS(&ch[chn].ao.dramc_pd_ctrl, + DRAMC_PD_CTRL_PHYCLKDYNGEN, 0, + DRAMC_PD_CTRL_DCMEN, 0); + SET32_BITFIELDS(&ch[chn].ao.stbcal, STBCAL_DQSIENCG_NORMAL_EN, 0); + SET32_BITFIELDS(&ch[chn].ao.dramc_pd_ctrl, DRAMC_PD_CTRL_MIOCKCTRLOFF, 1); + + dramc_cke_fix_onoff(CKE_FIXON, chn); + set_dram_mr_cbt_on_off(chn, rank, fsp, 1, mr); + SET32_BITFIELDS(&ch[chn].ao.write_lev, WRITE_LEV_WRITE_LEVEL_EN, 1); + + udelay(1); + dramc_cke_fix_onoff(CKE_FIXOFF, chn); + o1_path_on_off(1); +} + +static void cbt_exit(u8 chn, u8 rank, u8 fsp, struct mr_value *mr) +{ + dramc_cke_fix_onoff(CKE_FIXON, chn); + + udelay(1); + set_dram_mr_cbt_on_off(chn, rank, fsp, 0, mr); + o1_path_on_off(0); +} + +static void cbt_set_vref(u8 chn, u8 rank, u8 vref, bool is_final) +{ + if (!is_final) { + SET32_BITFIELDS(&ch[chn].ao.write_lev, WRITE_LEV_DMVREFCA, vref); + SET32_BITFIELDS(&ch[chn].ao.write_lev, WRITE_LEV_DQS_SEL, 1); + SET32_BITFIELDS(&ch[chn].ao.write_lev, WRITE_LEV_DQSBX_G, 0xa); + SET32_BITFIELDS(&ch[chn].ao.write_lev, WRITE_LEV_DQS_WLEV, 1); + udelay(1); + SET32_BITFIELDS(&ch[chn].ao.write_lev, WRITE_LEV_DQS_WLEV, 0); + } else { + vref |= BIT(6); + dramc_dbg("final_vref: %#x\n", vref); + + /* CBT set vref */ + dramc_mode_reg_write_by_rank(chn, rank, 12, vref); + } +} + +static void cbt_set_ca_clk_result(u8 chn, u8 rank, + const struct sdram_params *params) +{ + const u8 *perbit_dly; + u8 clk_dly = params->cbt_clk_dly[chn][rank]; + u8 cmd_dly = params->cbt_cmd_dly[chn][rank]; + const u8 *ca_mapping = lp4_ca_mapping_pop[chn]; + + for (u8 rk = 0; rk < rank + 1; rk++) { /* Set CLK and CA delay */ - SET32_BITFIELDS(&ch[chn].phy.shu[0].rk[rank].ca_cmd[9], + SET32_BITFIELDS(&ch[chn].phy.shu[0].rk[rk].ca_cmd[9], SHU1_R0_CA_CMD9_RG_RK0_ARPI_CMD, cmd_dly, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CLK, clk_dly); udelay(1); + + perbit_dly = params->cbt_ca_perbit_delay[chn][rk]; + + /* Set CA perbit delay line calibration results */ + SET32_BITFIELDS(&ch[chn].phy.shu[0].rk[rk].ca_cmd[0], + SHU1_R0_CA_CMD0_RK0_TX_ARCA0_DLY, perbit_dly[ca_mapping[0]], + SHU1_R0_CA_CMD0_RK0_TX_ARCA1_DLY, perbit_dly[ca_mapping[1]], + SHU1_R0_CA_CMD0_RK0_TX_ARCA2_DLY, perbit_dly[ca_mapping[2]], + SHU1_R0_CA_CMD0_RK0_TX_ARCA3_DLY, perbit_dly[ca_mapping[3]], + SHU1_R0_CA_CMD0_RK0_TX_ARCA4_DLY, perbit_dly[ca_mapping[4]], + SHU1_R0_CA_CMD0_RK0_TX_ARCA5_DLY, perbit_dly[ca_mapping[5]]); } +} - /* Set CLK and CS delay */ - SET32_BITFIELDS(&ch[chn].phy.shu[0].rk[rank].ca_cmd[9], - SHU1_R0_CA_CMD9_RG_RK0_ARPI_CS, cs_dly); +static u8 get_cbt_vref_pinmux_value(u8 chn, u8 vref_level) +{ + u8 vref_bit, vref_new, vref_org; - final_vref |= (1 << 6); + vref_new = 0; + vref_org = BIT(6) | (vref_level & 0x3f); + for (vref_bit = 0; vref_bit < 8; vref_bit++) { + if (vref_org & (1 << vref_bit)) + vref_new |= (1 << phy_mapping[chn][vref_bit]); + } + + dramc_dbg("vref_new: %#x --> %#x\n", vref_org, vref_new); + + return vref_new; +} + +static void cbt_dramc_dfs_direct_jump(u8 shu_level) +{ + u8 shu_ack = 0; + static bool phy_pll_en = true; + + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) + shu_ack |= (0x1 << chn); + + if (phy_pll_en) { + dramc_dbg("Disable CLRPLL\n"); + SET32_BITFIELDS(&ch[0].phy.pll2, PLL2_RG_RCLRPLL_EN, 0); + dramc_dbg("DFS jump to CLRPLL, shu lev=%d, ACK=%x\n", + shu_level, shu_ack); + } else { + dramc_dbg("Disable PHYPLL\n"); + SET32_BITFIELDS(&ch[0].phy.pll1, PLL1_RG_RPHYPLL_EN, 0); + dramc_dbg("DFS jump to PHYPLL, shu lev=%d, ACK=%x\n", + shu_level, shu_ack); + } + + SET32_BITFIELDS(&mtk_spm->spm_power_on_val0, + SPM_POWER_ON_VAL0_SC_PHYPLL1_SHU_EN_PCM, 0); + SET32_BITFIELDS(&mtk_spm->spm_power_on_val0, + SPM_POWER_ON_VAL0_SC_PHYPLL2_SHU_EN_PCM, 0); + SET32_BITFIELDS(&mtk_spm->spm_power_on_val0, + SPM_POWER_ON_VAL0_SC_DR_SHU_LEVEL_PCM, 0); + SET32_BITFIELDS(&mtk_spm->spm_power_on_val0, + SPM_POWER_ON_VAL0_SC_DR_SHU_LEVEL_PCM, shu_level); + + if (phy_pll_en) { + SET32_BITFIELDS(&mtk_spm->spm_power_on_val0, + SPM_POWER_ON_VAL0_SC_PHYPLL2_SHU_EN_PCM, 1); + udelay(1); + SET32_BITFIELDS(&ch[0].phy.pll2, PLL2_RG_RCLRPLL_EN, 1); + dramc_dbg("Enable CLRPLL\n"); + } else { + SET32_BITFIELDS(&mtk_spm->spm_power_on_val0, + SPM_POWER_ON_VAL0_SC_PHYPLL1_SHU_EN_PCM, 1); + udelay(1); + SET32_BITFIELDS(&ch[0].phy.pll1, PLL1_RG_RPHYPLL_EN, 1); + dramc_dbg("Enable PHYPLL\n"); + } + + SET32_BITFIELDS(&mtk_spm->spm_power_on_val0, + SPM_POWER_ON_VAL0_SC_TX_TRACKING_DIS, 3); + + udelay(20); + SET32_BITFIELDS(&mtk_spm->spm_power_on_val0, + SPM_POWER_ON_VAL0_SC_DDRPHY_FB_CK_EN_PCM, 1); + SET32_BITFIELDS(&mtk_spm->spm_power_on_val0, + SPM_POWER_ON_VAL0_SC_DPHY_RXDLY_TRACK_EN, 0); + SET32_BITFIELDS(&mtk_spm->spm_power_on_val0, + SPM_POWER_ON_VAL0_SC_DR_SHU_EN_PCM, 1); - /* CBT set vref */ - dramc_mode_reg_write_by_rank(chn, rank, 12, final_vref); - dramc_dbg("final_vref: %#x\n", final_vref); + while ((READ32_BITFIELD(&mtk_spm->dramc_dpy_clk_sw_con, + DRAMC_DPY_CLK_SW_CON_SC_DMDRAMCSHU_ACK) & shu_ack) + != shu_ack) { + dramc_dbg("wait shu_en ack.\n"); + } + SET32_BITFIELDS(&mtk_spm->spm_power_on_val0, + SPM_POWER_ON_VAL0_SC_DR_SHU_EN_PCM, 0); + + if (shu_level == 0) + SET32_BITFIELDS(&mtk_spm->spm_power_on_val0, + SPM_POWER_ON_VAL0_SC_DPHY_RXDLY_TRACK_EN, 3); + + SET32_BITFIELDS(&mtk_spm->spm_power_on_val0, + SPM_POWER_ON_VAL0_SC_TX_TRACKING_DIS, 0); + SET32_BITFIELDS(&mtk_spm->spm_power_on_val0, + SPM_POWER_ON_VAL0_SC_DDRPHY_FB_CK_EN_PCM, 0); + + if (phy_pll_en) + SET32_BITFIELDS(&ch[0].phy.pll1, PLL1_RG_RPHYPLL_EN, 0); + else + SET32_BITFIELDS(&ch[0].phy.pll2, PLL2_RG_RCLRPLL_EN, 0); + dramc_dbg("Shuffle flow complete\n"); + + phy_pll_en = !phy_pll_en; +} + +static void cbt_switch_freq(cbt_freq freq) +{ + if (freq == CBT_LOW_FREQ) + cbt_dramc_dfs_direct_jump(DRAM_DFS_SHUFFLE_MAX - 1); + else + cbt_dramc_dfs_direct_jump(DRAM_DFS_SHUFFLE_1); +} + +static void dramc_cmd_bus_training(u8 chn, u8 rank, u8 freq_group, + const struct sdram_params *params, const bool fast_calib, + struct mr_value *mr) +{ + u8 final_vref, cs_dly; + u8 fsp = get_freq_fsq(freq_group); + + cs_dly = params->cbt_cs_dly[chn][rank]; + final_vref = params->cbt_final_vref[chn][rank]; + + struct reg_value regs_bak[] = { + {&ch[chn].ao.dramc_pd_ctrl}, + {&ch[chn].ao.stbcal}, + {&ch[chn].ao.ckectrl}, + {&ch[chn].ao.write_lev}, + {&ch[chn].ao.refctrl0}, + {&ch[chn].ao.spcmdctrl}, + }; + + for (int i = 0; i < ARRAY_SIZE(regs_bak); i++) + regs_bak[i].value = read32(regs_bak[i].addr); + + dramc_auto_refresh_switch(chn, false); + if (rank == RANK_1) { + SET32_BITFIELDS(&ch[chn].ao.mrs, MRS_MRSRK, rank); + SET32_BITFIELDS(&ch[chn].ao.rkcfg, RKCFG_TXRANK, rank); + SET32_BITFIELDS(&ch[chn].ao.rkcfg, RKCFG_TXRANKFIX, 1); + SET32_BITFIELDS(&ch[chn].ao.mpc_option, MPC_OPTION_MPCRKEN, 0); + } + + cbt_set_perbit_delay_cell(chn, rank); + + if (fsp == FSP_1) + cbt_switch_freq(CBT_LOW_FREQ); + cbt_entry(chn, rank, fsp, mr); + if (fsp == FSP_1) + cbt_switch_freq(CBT_HIGH_FREQ); + + u8 new_vref = get_cbt_vref_pinmux_value(chn, final_vref); + cbt_set_vref(chn, rank, new_vref, 0); + + cbt_set_ca_clk_result(chn, rank, params); + + for (u8 rk = 0; rk < rank + 1; rk++) { + /* Set CLK and CS delay */ + SET32_BITFIELDS(&ch[chn].phy.shu[0].rk[rk].ca_cmd[9], + SHU1_R0_CA_CMD9_RG_RK0_ARPI_CS, cs_dly); + } + + if (fsp == FSP_1) + cbt_switch_freq(CBT_LOW_FREQ); + cbt_exit(chn, rank, fsp, mr); + + cbt_set_fsp(chn, rank, fsp, mr); + cbt_set_vref(chn, rank, final_vref, 1); + + if (fsp == FSP_1) + cbt_switch_freq(CBT_HIGH_FREQ); + + /* restore MRR pinmux */ + set_mrr_pinmux_mapping(); + if (rank == RANK_1) { + SET32_BITFIELDS(&ch[chn].ao.mrs, MRS_MRSRK, 0); + SET32_BITFIELDS(&ch[chn].ao.rkcfg, RKCFG_TXRANK, 0); + SET32_BITFIELDS(&ch[chn].ao.rkcfg, RKCFG_TXRANKFIX, 0); + SET32_BITFIELDS(&ch[chn].ao.mpc_option, MPC_OPTION_MPCRKEN, 0x1); + } + + for (int i = 0; i < ARRAY_SIZE(regs_bak); i++) + write32(regs_bak[i].addr, regs_bak[i].value); } static void dramc_read_dbi_onoff(size_t chn, bool on) @@ -505,7 +791,7 @@ void dramc_apply_config_after_calibration(const struct mr_value *mr) clrbits32(&ch[chn].ao.shu[shu].scintv, 0x1 << 30); clrbits32(&ch[chn].ao.dummy_rd, (0x7 << 20) | (0x1 << 7)); - dramc_cke_fix_onoff(chn, false, false); + dramc_cke_fix_onoff(CKE_DYNAMIC, chn); clrbits32(&ch[chn].ao.dramc_pd_ctrl, 0x1 << 26); clrbits32(&ch[chn].ao.eyescan, 0x7 << 8); @@ -2189,7 +2475,7 @@ static void dqsosc_auto(u8 chn, u8 rank, u8 freq_group, SET32_BITFIELDS(&ch[chn].ao.dramc_pd_ctrl, DRAMC_PD_CTRL_MIOCKCTRLOFF, 1); - dramc_cke_fix_onoff(chn, true, false); + dramc_cke_fix_onoff(CKE_FIXON, chn); start_dqsosc(chn); udelay(1); @@ -2757,8 +3043,8 @@ void get_dram_info_after_cal(u8 *density_result) *density_result = max_density; } -int dramc_calibrate_all_channels(const struct sdram_params *pams, u8 freq_group, - const struct mr_value *mr) +int dramc_calibrate_all_channels(const struct sdram_params *pams, + u8 freq_group, struct mr_value *mr) { bool fast_calib; switch (pams->source) { @@ -2782,7 +3068,7 @@ int dramc_calibrate_all_channels(const struct sdram_params *pams, u8 freq_group, dramc_dbg("Start K: freq=%d, ch=%d, rank=%d\n", freq_group, chn, rk); dramc_cmd_bus_training(chn, rk, freq_group, pams, - fast_calib); + fast_calib, mr); dramc_write_leveling(chn, rk, freq_group, pams->wr_level); dramc_auto_refresh_switch(chn, true); diff --git a/src/soc/mediatek/mt8183/emi.c b/src/soc/mediatek/mt8183/emi.c index 579bfbecbc..8afbef00d8 100644 --- a/src/soc/mediatek/mt8183/emi.c +++ b/src/soc/mediatek/mt8183/emi.c @@ -157,7 +157,7 @@ static void set_rank_info_to_conf(const struct sdram_params *params) (is_dual_rank ? 0 : 1) << 12); } -static void set_MRR_pinmux_mapping(void) +void set_mrr_pinmux_mapping(void) { for (size_t chn = 0; chn < CHANNEL_MAX; chn++) { const u8 *map = phy_mapping[chn]; @@ -182,7 +182,7 @@ static void set_MRR_pinmux_mapping(void) static void global_option_init(const struct sdram_params *params) { set_rank_info_to_conf(params); - set_MRR_pinmux_mapping(); + set_mrr_pinmux_mapping(); } static void set_vcore_voltage(u8 freq_group) diff --git a/src/soc/mediatek/mt8183/include/soc/dramc_common_mt8183.h b/src/soc/mediatek/mt8183/include/soc/dramc_common_mt8183.h index b5ae253cdf..c630b5aa90 100644 --- a/src/soc/mediatek/mt8183/include/soc/dramc_common_mt8183.h +++ b/src/soc/mediatek/mt8183/include/soc/dramc_common_mt8183.h @@ -29,6 +29,7 @@ enum dram_odt_type { }; enum { + CA_NUM_LP4 = 6, DQ_DATA_WIDTH = 16, DQS_BIT_NUMBER = 8, DQS_NUMBER = (DQ_DATA_WIDTH / DQS_BIT_NUMBER) diff --git a/src/soc/mediatek/mt8183/include/soc/dramc_param.h b/src/soc/mediatek/mt8183/include/soc/dramc_param.h index e35e4f5421..f925162e4a 100644 --- a/src/soc/mediatek/mt8183/include/soc/dramc_param.h +++ b/src/soc/mediatek/mt8183/include/soc/dramc_param.h @@ -10,7 +10,7 @@ enum { DRAMC_PARAM_HEADER_MAGIC = 0x44524d4b, - DRAMC_PARAM_HEADER_VERSION = 3, + DRAMC_PARAM_HEADER_VERSION = 4, }; enum DRAMC_PARAM_STATUS_CODES { 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 437ed3db2d..a0937d01c6 100644 --- a/src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h +++ b/src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h @@ -27,6 +27,7 @@ #define IMP_DRVN_LP4X_UNTERM_VREF_SEL 0x16 #define IMP_TRACK_LP4X_UNTERM_VREF_SEL 0x1a #define MR23_DEFAULT_VALUE 0x3f +#define CA_TRAINING_NUM 10 enum dram_te_op { TE_OP_WRITE_READ_CHECK = 0, @@ -42,6 +43,17 @@ enum { GATING_GOLDEND_DQSCNT = 0x4646 }; +enum cke_type { + CKE_FIXOFF = 0, + CKE_FIXON, + CKE_DYNAMIC +}; + +typedef enum { + CBT_LOW_FREQ = 0, + CBT_HIGH_FREQ, +} cbt_freq; + enum { IMPCAL_STAGE_DRVP = 0x1, IMPCAL_STAGE_DRVN, @@ -98,14 +110,15 @@ void dramc_sw_impedance_cal(const struct sdram_params *params, u8 term_option, void dramc_apply_config_before_calibration(u8 freq_group); void dramc_apply_config_after_calibration(const struct mr_value *mr); int dramc_calibrate_all_channels(const struct sdram_params *pams, - u8 freq_group, const struct mr_value *mr); + u8 freq_group, struct mr_value *mr); void dramc_hw_gating_onoff(u8 chn, bool onoff); void dramc_enable_phy_dcm(u8 chn, bool bEn); void dramc_mode_reg_write(u8 chn, u8 mr_idx, u8 value); -void dramc_cke_fix_onoff(u8 chn, bool fix_on, bool fix_off); u32 get_shu_freq(u8 shu); void dramc_hw_dqsosc(u8 chn); void dramc_dqs_precalculation_preset(void); void get_dram_info_after_cal(u8 *density); +void set_mrr_pinmux_mapping(void); +void dramc_cke_fix_onoff(enum cke_type option, u8 chn); #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 1e1448b923..99005a19a6 100644 --- a/src/soc/mediatek/mt8183/include/soc/dramc_register.h +++ b/src/soc/mediatek/mt8183/include/soc/dramc_register.h @@ -623,8 +623,9 @@ DEFINE_BIT(DDRCONF0_DM4TO1MODE, 22) DEFINE_BIT(DDRCONF0_RDATRST, 0) DEFINE_BIT(PERFCTL0_RWOFOEN, 4) +DEFINE_BITFIELD(RKCFG_TXRANK, 1, 0) +DEFINE_BIT(RKCFG_TXRANKFIX, 3) DEFINE_BIT(RKCFG_DQSOSC2RK, 11) -DEFINE_BIT(DRAMC_PD_CTRL_MIOCKCTRLOFF, 26) DEFINE_BIT(PADCTRL_DQIENLATEBEGIN, 3) DEFINE_BITFIELD(PADCTRL_DQIENQKEND, 1, 0) @@ -797,6 +798,7 @@ DEFINE_BITFIELD(FINE_TUNE_DQ, 13, 8) DEFINE_BITFIELD(SHU1_R0_CA_CMD9_RG_RK0_ARPI_CLK, 29, 24) DEFINE_BITFIELD(SHU1_R0_CA_CMD9_RG_RK0_ARPI_CMD, 13, 8) +DEFINE_BITFIELD(SHU1_R1_CA_CMD9_RG_RK1_ARPI_CMD, 13, 8) DEFINE_BITFIELD(SHU1_R0_CA_CMD9_RG_RK0_ARPI_CS, 5, 0) /* DRAMC_REG_ADDR(DRAMC_REG_PRE_TDQSCK1) */ @@ -908,6 +910,90 @@ DEFINE_BITFIELD(RK0_PRE_TDQSCK12_TDQSCK_UIFREQ1_P1_B3R0, 5, 0) DEFINE_BITFIELD(RK0_PRE_TDQSCK11_TDQSCK_PIFREQ3_B3R0, 12, 6) DEFINE_BITFIELD(RK0_PRE_TDQSCK11_TDQSCK_UIFREQ3_B3R0, 5, 0) +/* DRAMC_REG_MRR_BIT_MUX1 */ +DEFINE_BITFIELD(MRR_BIT_MUX1_MRR_BIT3_SEL, 28, 24) +DEFINE_BITFIELD(MRR_BIT_MUX1_MRR_BIT2_SEL, 20, 16) +DEFINE_BITFIELD(MRR_BIT_MUX1_MRR_BIT1_SEL, 12, 8) +DEFINE_BITFIELD(MRR_BIT_MUX1_MRR_BIT0_SEL, 4, 0) + +/* DRAMC_REG_SHU_SELPH_CA7 */ +DEFINE_BITFIELD(SHU_SELPH_CA7_DLY_RA5, 22, 20) +DEFINE_BITFIELD(SHU_SELPH_CA7_DLY_RA4, 18, 16) +DEFINE_BITFIELD(SHU_SELPH_CA7_DLY_RA3, 14, 12) +DEFINE_BITFIELD(SHU_SELPH_CA7_DLY_RA2, 10, 8) +DEFINE_BITFIELD(SHU_SELPH_CA7_DLY_RA1, 6, 4) +DEFINE_BITFIELD(SHU_SELPH_CA7_DLY_RA0, 2, 0) + +/* DRAMC_REG_MRR_BIT_MUX2 */ +DEFINE_BITFIELD(MRR_BIT_MUX2_MRR_BIT5_SEL, 12, 8) +DEFINE_BITFIELD(MRR_BIT_MUX2_MRR_BIT4_SEL, 4, 0) + +/* DDRPHY_SHU1_R0_CA_CMD0 */ +DEFINE_BITFIELD(SHU1_R0_CA_CMD0_RK0_TX_ARCA5_DLY, 23, 20) +DEFINE_BITFIELD(SHU1_R0_CA_CMD0_RK0_TX_ARCA4_DLY, 19, 16) +DEFINE_BITFIELD(SHU1_R0_CA_CMD0_RK0_TX_ARCA3_DLY, 15, 12) +DEFINE_BITFIELD(SHU1_R0_CA_CMD0_RK0_TX_ARCA2_DLY, 11, 8) +DEFINE_BITFIELD(SHU1_R0_CA_CMD0_RK0_TX_ARCA1_DLY, 7, 4) +DEFINE_BITFIELD(SHU1_R0_CA_CMD0_RK0_TX_ARCA0_DLY, 3, 0) + +/* DDRPHY_PLL2 */ +DEFINE_BIT(PLL2_RG_RCLRPLL_EN, 31) + +/* DDRPHY_PLL1 */ +DEFINE_BIT(PLL1_RG_RPHYPLL_EN, 31) + +/* DRAMC_REG_PADCTRL */ +DEFINE_BITFIELD(PADCTRL_FIXDQIEN, 19, 16) + +/* SPM_POWER_ON_VAL0 */ +DEFINE_BIT(SPM_POWER_ON_VAL0_SC_DR_SHU_EN_PCM, 22) +DEFINE_BIT(SPM_POWER_ON_VAL0_SC_DPHY_RXDLY_TRACK_EN, 25) +DEFINE_BIT(SPM_POWER_ON_VAL0_SC_DDRPHY_FB_CK_EN_PCM, 16) +DEFINE_BIT(SPM_POWER_ON_VAL0_SC_TX_TRACKING_DIS, 11) +DEFINE_BITFIELD(SPM_POWER_ON_VAL0_SC_DR_SHU_LEVEL_PCM, 31, 30) +DEFINE_BIT(SPM_POWER_ON_VAL0_SC_PHYPLL2_SHU_EN_PCM, 27) +DEFINE_BIT(SPM_POWER_ON_VAL0_SC_PHYPLL1_SHU_EN_PCM, 26) + +/* SPM_POWER_ON_VAL1 */ +DEFINE_BIT(SPM_POWER_ON_VAL1_SC_DR_SHORT_QUEUE_PCM, 31) + +/* SPM_DRAMC_DPY_CLK_SW_CON */ +DEFINE_BITFIELD(DRAMC_DPY_CLK_SW_CON_SC_DMDRAMCSHU_ACK, 25, 24) + +/* DRAMC_REG_DRAMC_PD_CTRL */ +DEFINE_BIT(DRAMC_PD_CTRL_DCMEN, 0) +DEFINE_BIT(DRAMC_PD_CTRL_PHYCLKDYNGEN, 30) +DEFINE_BIT(DRAMC_PD_CTRL_MIOCKCTRLOFF, 26) + +/* DRAMC_REG_WRITE_LEV */ +DEFINE_BIT(WRITE_LEV_DQS_WLEV, 7) +DEFINE_BITFIELD(WRITE_LEV_DQSBX_G, 11, 8) +DEFINE_BITFIELD(WRITE_LEV_DQS_SEL, 19, 16) +DEFINE_BITFIELD(WRITE_LEV_DMVREFCA, 27, 20) +DEFINE_BIT(WRITE_LEV_WRITE_LEVEL_EN, 0) +DEFINE_BIT(WRITE_LEV_BYTEMODECBTEN, 3) + +/* DRAMC_REG_STBCAL */ +DEFINE_BIT(STBCAL_DQSIENCG_NORMAL_EN, 29) + +/* DDRPHY_B0_DQ5 */ +DEFINE_BIT(B0_DQ5_RG_RX_ARDQ_EYE_VREF_EN_B0, 17) + +/* DDRPHY_B1_DQ5 */ +DEFINE_BIT(B1_DQ5_RG_RX_ARDQ_EYE_VREF_EN_B1, 17) + +/* DDRPHY_B0_DQ3 */ +DEFINE_BIT(B0_DQ3_RG_RX_ARDQ_SMT_EN_B0, 1) + +/* DDRPHY_B1_DQ3 */ +DEFINE_BIT(B1_DQ3_RG_RX_ARDQ_SMT_EN_B1, 1) + +/* DDRPHY_CA_CMD5 */ +DEFINE_BIT(CA_CMD5_RG_RX_ARCMD_EYE_VREF_EN, 17) + +/* DDRPHY_CA_CMD3 */ +DEFINE_BIT(CA_CMD3_RG_RX_ARCMD_SMT_EN, 1) + struct dramc_channel_regs { union { struct dramc_ddrphy_ao_regs phy; diff --git a/src/soc/mediatek/mt8183/include/soc/emi.h b/src/soc/mediatek/mt8183/include/soc/emi.h index cf794dee89..6931d5bb81 100644 --- a/src/soc/mediatek/mt8183/include/soc/emi.h +++ b/src/soc/mediatek/mt8183/include/soc/emi.h @@ -27,6 +27,7 @@ struct sdram_params { u8 cbt_clk_dly[CHANNEL_MAX][RANK_MAX]; u8 cbt_cmd_dly[CHANNEL_MAX][RANK_MAX]; u8 cbt_cs_dly[CHANNEL_MAX][RANK_MAX]; + u8 cbt_ca_perbit_delay[CHANNEL_MAX][RANK_MAX][DQS_BIT_NUMBER]; /* Gating */ u8 gating2T[CHANNEL_MAX][RANK_MAX][DQS_NUMBER]; |