soc/mediatek/mt8183: Enable CA perbit mechanism
LPDDR4x has 6 CA PINs, but for some 8GB LPDDR4X DDR, the left margin of some CA PIN window is too small than others. Need to enable the CA perbit mechanism to avoid those risks. BUG=none BRANCH=kukui TEST=Boots correctly on Kukui Change-Id: I58e29d0c91a469112b0b1292da80bcb802322d47 Signed-off-by: Huayang Duan <huayang.duan@mediatek.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/41965 Reviewed-by: Hung-Te Lin <hungte@chromium.org> Reviewed-by: Yu-Ping Wu <yupingso@google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
92c1546c01
commit
63ee16075e
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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]]);
|
||||
}
|
||||
}
|
||||
|
||||
static u8 get_cbt_vref_pinmux_value(u8 chn, u8 vref_level)
|
||||
{
|
||||
u8 vref_bit, vref_new, vref_org;
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
dramc_dbg("vref_new: %#x --> %#x\n", vref_org, vref_new);
|
||||
|
||||
final_vref |= (1 << 6);
|
||||
return vref_new;
|
||||
}
|
||||
|
||||
/* CBT set vref */
|
||||
dramc_mode_reg_write_by_rank(chn, rank, 12, final_vref);
|
||||
dramc_dbg("final_vref: %#x\n", final_vref);
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
|
|
Loading…
Reference in New Issue