soc/mediatek/mt8183: Set CA and DQ vref range to correct value
The CA vref should alway select range[1]. But in fast calibration flow, we missed the range selection and caused the CA vref to use the range[0] value. The DQ vref should select correct range that corresponds to current frequency, that is for 1600Mbps, 2400Mbps to select range[1], for 3200Mbps and 3600Mbps to select range[0]. Refer to the 'JESD209-4 - Low Power Double Data Rate 4X(LPDDR4X).pdf', used MR12 to set Vref(CA) levels, used MR14 to set VREF(DQ) levels. MR12 range[0] values from 15.0% to 44.9%, range[1] values from 32.9% to 62.9%, MR14 range[0] and range[1] values same as MR12. BUG=b:153614919 BRANCH=kukui TEST=Boots correctly on Kukui Change-Id: Ie7680b1bf0c29c946d18e3b27626ce6f31c4216b Signed-off-by: Huayang Duan <huayang.duan@mediatek.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/40525 Reviewed-by: Hung-Te Lin <hungte@chromium.org> Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
efaf1b32ba
commit
062646670f
|
@ -1218,8 +1218,8 @@ static void dramc_setting(const struct sdram_params *params, u8 freq_group,
|
||||||
(0x7 << 0) | (0x7 << 4) | (0x7 << 8) | (0x7 << 12) |
|
(0x7 << 0) | (0x7 << 4) | (0x7 << 8) | (0x7 << 12) |
|
||||||
(0x7 << 16) | (0x7 << 20) | (0x7 << 24) | (0x7 << 28));
|
(0x7 << 16) | (0x7 << 20) | (0x7 << 24) | (0x7 << 28));
|
||||||
clrbits32(&ch[0].ao.shu[0].selph_ca5, 0x7 << 8);
|
clrbits32(&ch[0].ao.shu[0].selph_ca5, 0x7 << 8);
|
||||||
clrsetbits32(&ch[0].ao.shu[0].selph_dqs0, 0x77777777, SELPH_DQS0);
|
clrsetbits32(&ch[0].ao.shu[0].selph_dqs0, 0x77777777, SELPH_DQS0_3200);
|
||||||
clrsetbits32(&ch[0].ao.shu[0].selph_dqs1, 0x77777777, SELPH_DQS1);
|
clrsetbits32(&ch[0].ao.shu[0].selph_dqs1, 0x77777777, SELPH_DQS1_3200);
|
||||||
|
|
||||||
for (size_t rank = 0; rank < 2; rank++) {
|
for (size_t rank = 0; rank < 2; rank++) {
|
||||||
clrsetbits32(&ch[0].ao.shu[0].rk[rank].selph_dq[0],
|
clrsetbits32(&ch[0].ao.shu[0].rk[rank].selph_dq[0],
|
||||||
|
@ -1373,6 +1373,9 @@ static void dramc_setting(const struct sdram_params *params, u8 freq_group,
|
||||||
setbits32(&ch[0].phy.shu[0].b[1].dq[7], (0x1 << 12) | (0x1 << 13));
|
setbits32(&ch[0].phy.shu[0].b[1].dq[7], (0x1 << 12) | (0x1 << 13));
|
||||||
clrbits32(&ch[0].ao.shu[0].dqs2dq_tx, 0x1f << 0);
|
clrbits32(&ch[0].ao.shu[0].dqs2dq_tx, 0x1f << 0);
|
||||||
|
|
||||||
|
/* The default dramc init settings were tuned at frequency of 3200Mbps.
|
||||||
|
For other frequencies uses dramc_setting_DDRxxx() to overwrite
|
||||||
|
the default settings. */
|
||||||
switch (freq_group) {
|
switch (freq_group) {
|
||||||
case LP4X_DDR1600:
|
case LP4X_DDR1600:
|
||||||
dramc_setting_DDR1600();
|
dramc_setting_DDR1600();
|
||||||
|
|
|
@ -220,9 +220,7 @@ static void dramc_write_leveling(u8 chn, u8 rank, u8 freq_group,
|
||||||
{
|
{
|
||||||
dramc_auto_refresh_switch(chn, false);
|
dramc_auto_refresh_switch(chn, false);
|
||||||
|
|
||||||
if (rank == RANK_0 && (freq_group == LP4X_DDR3600 ||
|
if (rank == RANK_0)
|
||||||
freq_group == LP4X_DDR1600 ||
|
|
||||||
freq_group == LP4X_DDR2400))
|
|
||||||
write_leveling_move_dqs_instead_of_clk(chn);
|
write_leveling_move_dqs_instead_of_clk(chn);
|
||||||
|
|
||||||
SET32_BITFIELDS(&ch[chn].phy.shu[0].rk[rank].ca_cmd[9],
|
SET32_BITFIELDS(&ch[chn].phy.shu[0].rk[rank].ca_cmd[9],
|
||||||
|
@ -265,8 +263,11 @@ static void dramc_cmd_bus_training(u8 chn, u8 rank, u8 freq_group,
|
||||||
SET32_BITFIELDS(&ch[chn].phy.shu[0].rk[rank].ca_cmd[9],
|
SET32_BITFIELDS(&ch[chn].phy.shu[0].rk[rank].ca_cmd[9],
|
||||||
SHU1_R0_CA_CMD9_RG_RK0_ARPI_CS, cs_dly);
|
SHU1_R0_CA_CMD9_RG_RK0_ARPI_CS, cs_dly);
|
||||||
|
|
||||||
|
final_vref |= (1 << 6);
|
||||||
|
|
||||||
/* CBT set vref */
|
/* CBT set vref */
|
||||||
dramc_mode_reg_write_by_rank(chn, rank, 12, final_vref);
|
dramc_mode_reg_write_by_rank(chn, rank, 12, final_vref);
|
||||||
|
dramc_dbg("final_vref: %#x\n", final_vref);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dramc_read_dbi_onoff(size_t chn, bool on)
|
static void dramc_read_dbi_onoff(size_t chn, bool on)
|
||||||
|
@ -1822,7 +1823,7 @@ static u8 dramc_window_perbit_cal(u8 chn, u8 rank, u8 freq_group,
|
||||||
vref_end = vref_begin + 1;
|
vref_end = vref_begin + 1;
|
||||||
dramc_dbg("bypass RX vref: %d\n", vref_begin);
|
dramc_dbg("bypass RX vref: %d\n", vref_begin);
|
||||||
} else if (type == TX_WIN_DQ_ONLY) {
|
} else if (type == TX_WIN_DQ_ONLY) {
|
||||||
vref_begin = params->tx_vref[chn][rank];
|
vref_begin = params->tx_vref[chn][rank] | (vref_range << 6);
|
||||||
vref_end = vref_begin + 1;
|
vref_end = vref_begin + 1;
|
||||||
dramc_dbg("bypass TX vref: %d\n", vref_begin);
|
dramc_dbg("bypass TX vref: %d\n", vref_begin);
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,12 +74,12 @@ enum {
|
||||||
DQ_DIV_MASK = BIT(DQ_DIV_SHIFT) - 1,
|
DQ_DIV_MASK = BIT(DQ_DIV_SHIFT) - 1,
|
||||||
OEN_SHIFT = 16,
|
OEN_SHIFT = 16,
|
||||||
|
|
||||||
SELPH_DQS0 = _SELPH_DQS_BITS(0x3, 0x3),
|
|
||||||
SELPH_DQS1 = _SELPH_DQS_BITS(0x4, 0x1),
|
|
||||||
SELPH_DQS0_1600 = _SELPH_DQS_BITS(0x2, 0x1),
|
SELPH_DQS0_1600 = _SELPH_DQS_BITS(0x2, 0x1),
|
||||||
SELPH_DQS1_1600 = _SELPH_DQS_BITS(0x1, 0x6),
|
SELPH_DQS1_1600 = _SELPH_DQS_BITS(0x1, 0x6),
|
||||||
SELPH_DQS0_2400 = _SELPH_DQS_BITS(0x3, 0x2),
|
SELPH_DQS0_2400 = _SELPH_DQS_BITS(0x3, 0x2),
|
||||||
SELPH_DQS1_2400 = _SELPH_DQS_BITS(0x1, 0x6),
|
SELPH_DQS1_2400 = _SELPH_DQS_BITS(0x1, 0x6),
|
||||||
|
SELPH_DQS0_3200 = _SELPH_DQS_BITS(0x3, 0x3),
|
||||||
|
SELPH_DQS1_3200 = _SELPH_DQS_BITS(0x5, 0x2),
|
||||||
SELPH_DQS0_3600 = _SELPH_DQS_BITS(0x4, 0x3),
|
SELPH_DQS0_3600 = _SELPH_DQS_BITS(0x4, 0x3),
|
||||||
SELPH_DQS1_3600 = _SELPH_DQS_BITS(0x1, 0x6),
|
SELPH_DQS1_3600 = _SELPH_DQS_BITS(0x1, 0x6),
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue