soc/mediatek/mt8183: Support byte mode and single rank DDR
1. Add emi setting to support byte mode and single rank ddr sample 2. Modify initial setting for DDR with different architecture BUG=b:165768895 BRANCH=kukui TEST=DDR boot up correctly on Kukui Signed-off-by: Shaoming Chen <shaoming.chen@mediatek.corp-partner.google.com> Change-Id: Id2845b2b60e2c447486ee25259dc6a05a0bb619b Reviewed-on: https://review.coreboot.org/c/coreboot/+/48300 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Yu-Ping Wu <yupingso@google.com>
This commit is contained in:
committed by
Patrick Georgi
parent
f296273692
commit
5ff588dbc1
@@ -735,7 +735,8 @@ static u8 dramc_zq_calibration(u8 chn, u8 rank)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dramc_mode_reg_init(u8 freq_group, struct mr_value *mr)
|
||||
static void dramc_mode_reg_init(u8 freq_group, struct mr_value *mr,
|
||||
const struct sdram_params *params)
|
||||
{
|
||||
u8 *MR01Value = mr->MR01Value;
|
||||
u8 MR02Value[FSP_MAX] = {0x12, 0x12};
|
||||
@@ -744,12 +745,13 @@ static void dramc_mode_reg_init(u8 freq_group, struct mr_value *mr)
|
||||
u8 MR12Value[CHANNEL_MAX][RANK_MAX][FSP_MAX] = {
|
||||
{{0x5d, 0x5d}, {0x5d, 0x5d} }, {{0x5d, 0x5d}, {0x5d, 0x5d} },
|
||||
};
|
||||
u8 MR13Value;
|
||||
u8 MR13Value = 0x18;
|
||||
u8 MR14Value[CHANNEL_MAX][RANK_MAX][FSP_MAX] = {
|
||||
{{0x5d, 0x10}, {0x5d, 0x10} }, {{0x5d, 0x10}, {0x5d, 0x10} },
|
||||
};
|
||||
|
||||
u8 MR22Value[FSP_MAX] = {0x38, 0x34};
|
||||
u32 cbt_mode = params->cbt_mode_extern;
|
||||
|
||||
MR01Value[FSP_0] = 0x6;
|
||||
MR01Value[FSP_1] = 0x6;
|
||||
@@ -767,7 +769,7 @@ static void dramc_mode_reg_init(u8 freq_group, struct mr_value *mr)
|
||||
MR01Value[FSP_0] |= (0x5 << 4);
|
||||
MR01Value[FSP_1] |= (0x5 << 4);
|
||||
} else if (freq_group == LP4X_DDR3200) {
|
||||
MR02Value[0] = 0x12;
|
||||
MR02Value[0] = 0x1a;
|
||||
MR02Value[1] = 0x2d;
|
||||
|
||||
MR01Value[FSP_0] |= (0x5 << 4);
|
||||
@@ -780,6 +782,9 @@ static void dramc_mode_reg_init(u8 freq_group, struct mr_value *mr)
|
||||
MR01Value[FSP_1] |= (0x6 << 4);
|
||||
}
|
||||
|
||||
if (cbt_mode)
|
||||
MR11Value[FSP_1] = 0x13;
|
||||
|
||||
u8 operate_fsp = get_freq_fsq(freq_group);
|
||||
dramc_dbg("%s operate_fsp:%d, freq:%d\n", __func__, operate_fsp, freq_group);
|
||||
|
||||
@@ -789,7 +794,7 @@ static void dramc_mode_reg_init(u8 freq_group, struct mr_value *mr)
|
||||
dramc_power_on_sequence();
|
||||
|
||||
for (chn = 0; chn < CHANNEL_MAX; chn++) {
|
||||
for (rank = 0; rank < 2; rank++) {
|
||||
for (rank = 0; rank < params->rank_num; rank++) {
|
||||
clrsetbits32(&ch[chn].ao.mrs, 0x3 << 24, rank << 24);
|
||||
|
||||
dramc_zq_calibration(chn, rank);
|
||||
@@ -808,6 +813,15 @@ static void dramc_mode_reg_init(u8 freq_group, struct mr_value *mr)
|
||||
dramc_mode_reg_write(chn, 0x2, MR02Value[fsp]);
|
||||
dramc_mode_reg_write(chn, 0xb, MR11Value[fsp]);
|
||||
|
||||
if (cbt_mode == CBT_R0_NORMAL_R1_BYTE) {
|
||||
if (rank == 0)
|
||||
MR22Value[FSP_1] = 0x3c;
|
||||
else
|
||||
MR22Value[FSP_1] = 0x34;
|
||||
} else {
|
||||
MR22Value[FSP_1] = 0x34;
|
||||
}
|
||||
|
||||
dramc_mode_reg_write(chn, 0x16, MR22Value[fsp]);
|
||||
dramc_mode_reg_write(chn, 0xe,
|
||||
MR14Value[chn][rank][fsp]);
|
||||
@@ -856,7 +870,7 @@ static void auto_refresh_cke_off(void)
|
||||
dramc_set_broadcast(broadcast_bak);
|
||||
}
|
||||
|
||||
static void dramc_setting_DDR1600(void)
|
||||
static void dramc_setting_DDR1600(u32 cbt_mode)
|
||||
{
|
||||
clrsetbits32(&ch[0].ao.shu[0].rankctl,
|
||||
(0xf << 20) | (0xf << 24) | (0xf << 28),
|
||||
@@ -869,8 +883,13 @@ static void dramc_setting_DDR1600(void)
|
||||
|
||||
clrsetbits32(&ch[0].ao.shu[0].selph_dqs0, 0x77777777, SELPH_DQS0_1600);
|
||||
clrsetbits32(&ch[0].ao.shu[0].selph_dqs1, 0x77777777, SELPH_DQS1_1600);
|
||||
|
||||
if (cbt_mode)
|
||||
clrsetbits32(&ch[0].ao.shu[0].wodt, (0x1 << 31), (0x1 << 31));
|
||||
else
|
||||
clrsetbits32(&ch[0].ao.shu[0].wodt, (0x1 << 29) | (0x1 << 31),
|
||||
(0x0 << 29) | (0x1 << 31));
|
||||
|
||||
clrsetbits32(&ch[0].ao.shu[0].dqs2dq_tx, 0x1f << 0, 0x4 << 0);
|
||||
|
||||
for (size_t rank = 0; rank < 2; rank++) {
|
||||
@@ -880,16 +899,21 @@ static void dramc_setting_DDR1600(void)
|
||||
(0x3f << 0) | (0x3f << 8) | (0x3f << 16) | (0x3f << 24),
|
||||
(value << 0) | (value << 8) | (value << 16) | (value << 24));
|
||||
|
||||
clrsetbits32(&ch[0].ao.shu[0].rk[rank].selph_dq[0],
|
||||
(0x7 << 8) | (0x7 << 12) |
|
||||
(0x7 << 16) | (0x7 << 20) | (0x7 << 24) | (0x7 << 28),
|
||||
(0x2 << 8) | (0x2 << 12) |
|
||||
(0x1 << 16) | (0x1 << 20) | (0x1 << 24) | (0x1 << 28));
|
||||
clrsetbits32(&ch[0].ao.shu[0].rk[rank].selph_dq[1],
|
||||
for (size_t b = 0; b < 2; b++) {
|
||||
if (cbt_mode) {
|
||||
clrsetbits32(&ch[0].ao.shu[0].rk[rank].selph_dq[b],
|
||||
(0x7 << 0) | (0x7 << 4) | (0x7 << 8) | (0x7 << 12) |
|
||||
(0x7 << 16) | (0x7 << 20) | (0x7 << 24) | (0x7 << 28),
|
||||
(0x2 << 0) | (0x2 << 4) | (0x2 << 8) | (0x2 << 12) |
|
||||
(0x1 << 16) | (0x1 << 20) | (0x1 << 24) | (0x1 << 28));
|
||||
} else {
|
||||
clrsetbits32(&ch[0].ao.shu[0].rk[rank].selph_dq[b],
|
||||
(0x7 << 8) | (0x7 << 12) |
|
||||
(0x7 << 16) | (0x7 << 20) | (0x7 << 24) | (0x7 << 28),
|
||||
(0x2 << 8) | (0x2 << 12) |
|
||||
(0x1 << 16) | (0x1 << 20) | (0x1 << 24) | (0x1 << 28));
|
||||
}
|
||||
}
|
||||
clrsetbits32(&ch[0].ao.shu[0].rk[rank].selph_dq[2],
|
||||
0x77777777, _SELPH_DQS_BITS(0x1, 0x7));
|
||||
clrsetbits32(&ch[0].ao.shu[0].rk[rank].selph_dq[3],
|
||||
@@ -899,11 +923,20 @@ static void dramc_setting_DDR1600(void)
|
||||
clrsetbits32(&ch[0].ao.shu[0].dqsg_retry, (0x1 << 2) | (0xf << 8),
|
||||
(0x0 << 2) | (0x3 << 8));
|
||||
clrsetbits32(&ch[0].phy.shu[0].b[0].dq[5], 0x7 << 20, 0x4 << 20);
|
||||
|
||||
if (cbt_mode)
|
||||
clrsetbits32(&ch[0].phy.shu[0].b[0].dq[7], (0x3 << 4),
|
||||
(0x2 << 4));
|
||||
else
|
||||
clrsetbits32(&ch[0].phy.shu[0].b[0].dq[7],
|
||||
(0x3 << 4) | (0x1 << 7) | (0x1 << 13),
|
||||
(0x2 << 4) | (0x0 << 7) | (0x0 << 13));
|
||||
|
||||
clrsetbits32(&ch[0].phy.shu[0].b[1].dq[5], 0x7 << 20, 0x4 << 20);
|
||||
clrbits32(&ch[0].phy.shu[0].b[1].dq[7], (0x1 << 7) | (0x1 << 13));
|
||||
|
||||
if (cbt_mode == 0)
|
||||
clrbits32(&ch[0].phy.shu[0].b[1].dq[7],
|
||||
(0x1 << 7) | (0x1 << 13));
|
||||
|
||||
for (size_t r = 0; r < 2; r++) {
|
||||
int value = ((r == 0) ? 0x1a : 0x26);
|
||||
@@ -914,7 +947,7 @@ static void dramc_setting_DDR1600(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void dramc_setting_DDR2400(void)
|
||||
static void dramc_setting_DDR2400(u32 cbt_mode)
|
||||
{
|
||||
clrsetbits32(&ch[0].ao.shu[0].rankctl,
|
||||
(0xf << 20) | (0xf << 24) | (0xf << 28),
|
||||
@@ -927,8 +960,13 @@ static void dramc_setting_DDR2400(void)
|
||||
|
||||
clrsetbits32(&ch[0].ao.shu[0].selph_dqs0, 0x77777777, SELPH_DQS0_2400);
|
||||
clrsetbits32(&ch[0].ao.shu[0].selph_dqs1, 0x77777777, SELPH_DQS1_2400);
|
||||
|
||||
if (cbt_mode)
|
||||
clrsetbits32(&ch[0].ao.shu[0].wodt, (0x1 << 31), (0x0 << 31));
|
||||
else
|
||||
clrsetbits32(&ch[0].ao.shu[0].wodt,
|
||||
(0x1 << 29) | (0x1 << 31), (0x1 << 29) | (0x0 << 31));
|
||||
|
||||
clrsetbits32(&ch[0].ao.shu[0].dqs2dq_tx, 0x1f << 0, 0x7 << 0);
|
||||
|
||||
for (size_t rank = 0; rank < 2; rank++) {
|
||||
@@ -939,16 +977,21 @@ static void dramc_setting_DDR2400(void)
|
||||
(0x3f << 0) | (0x3f << 8) | (0x3f << 16) | (0x3f << 24),
|
||||
(0x14 << 0) | (0x14 << 8) | (0x14 << 16) | (0x14 << 24));
|
||||
|
||||
clrsetbits32(&ch[0].ao.shu[0].rk[rank].selph_dq[0],
|
||||
(0x7 << 8) | (0x7 << 12) |
|
||||
(0x7 << 16) | (0x7 << 20) | (0x7 << 24) | (0x7 << 28),
|
||||
(0x3 << 8) | (0x3 << 12) |
|
||||
(0x3 << 16) | (0x3 << 20) | (0x3 << 24) | (0x3 << 28));
|
||||
clrsetbits32(&ch[0].ao.shu[0].rk[rank].selph_dq[1],
|
||||
for (size_t b = 0; b < 2; b++) {
|
||||
if (cbt_mode) {
|
||||
clrsetbits32(&ch[0].ao.shu[0].rk[rank].selph_dq[b],
|
||||
(0x7 << 0) | (0x7 << 4) | (0x7 << 8) | (0x7 << 12) |
|
||||
(0x7 << 16) | (0x7 << 20) | (0x7 << 24) | (0x7 << 28),
|
||||
(0x3 << 0) | (0x3 << 4) | (0x3 << 8) | (0x3 << 12) |
|
||||
(0x3 << 16) | (0x3 << 20) | (0x3 << 24) | (0x3 << 28));
|
||||
} else {
|
||||
clrsetbits32(&ch[0].ao.shu[0].rk[rank].selph_dq[b],
|
||||
(0x7 << 8) | (0x7 << 12) |
|
||||
(0x7 << 16) | (0x7 << 20) | (0x7 << 24) | (0x7 << 28),
|
||||
(0x3 << 8) | (0x3 << 12) |
|
||||
(0x3 << 16) | (0x3 << 20) | (0x3 << 24) | (0x3 << 28));
|
||||
}
|
||||
}
|
||||
clrsetbits32(&ch[0].ao.shu[0].rk[rank].selph_dq[2],
|
||||
0x77777777, _SELPH_DQS_BITS(0x2, 0x0));
|
||||
clrsetbits32(&ch[0].ao.shu[0].rk[rank].selph_dq[3],
|
||||
@@ -958,12 +1001,19 @@ static void dramc_setting_DDR2400(void)
|
||||
clrsetbits32(&ch[0].ao.shu[0].dqsg_retry,
|
||||
(0x1 << 2) | (0xf << 8), (0x1 << 2) | (0x4 << 8));
|
||||
clrsetbits32(&ch[0].phy.shu[0].b[0].dq[5], 0x7 << 20, 0x3 << 20);
|
||||
|
||||
if (cbt_mode)
|
||||
clrsetbits32(&ch[0].phy.shu[0].b[0].dq[7],
|
||||
(0x3 << 4), (0x1 << 4));
|
||||
else
|
||||
clrsetbits32(&ch[0].phy.shu[0].b[0].dq[7],
|
||||
(0x3 << 4) | (0x1 << 7) | (0x1 << 13),
|
||||
(0x1 << 4) | (0x1 << 7) | (0x1 << 13));
|
||||
|
||||
clrsetbits32(&ch[0].phy.shu[0].b[1].dq[5], 0x7 << 20, 0x3 << 20);
|
||||
clrsetbits32(&ch[0].phy.shu[0].b[1].dq[7],
|
||||
(0x1 << 7) | (0x1 << 13), (0x1 << 7) | (0x1 << 13));
|
||||
|
||||
if (cbt_mode == 0)
|
||||
setbits32(&ch[0].phy.shu[0].b[1].dq[7], (0x1 << 7) | (0x1 << 13));
|
||||
|
||||
for (size_t r = 0; r < 2; r++) {
|
||||
for (size_t b = 0; b < 2; b++)
|
||||
@@ -1288,11 +1338,13 @@ static void dramc_setting(const struct sdram_params *params, u8 freq_group,
|
||||
(0x4 << 20) | (0x4 << 24) | (0x6 << 28));
|
||||
udelay(2);
|
||||
|
||||
if (params->cbt_mode_extern == CBT_R0_R1_NORMAL) {
|
||||
clrsetbits32(&ch[0].ao.shu[0].rk[0].dqsien,
|
||||
(0x7f << 0) | (0x7f << 8), (0x19 << 0) | (0x19 << 8));
|
||||
clrsetbits32(&ch[0].ao.shu[0].rk[1].dqsien,
|
||||
(0x7f << 0) | (0x7f << 8) | (0x7f << 16) | (0x7f << 24),
|
||||
(0x1b << 0) | (0x1b << 8) | (0x0 << 16) | (0x0 << 24));
|
||||
}
|
||||
|
||||
setbits32(&ch[0].ao.dramctrl, 0x1 << 19);
|
||||
clrsetbits32(&ch[0].ao.zqcs, 0xff << 0, 0x56 << 0);
|
||||
@@ -1317,6 +1369,15 @@ static void dramc_setting(const struct sdram_params *params, u8 freq_group,
|
||||
udelay(1);
|
||||
clrsetbits32(&ch[0].ao.hw_mrr_fun, (0xf << 0) | (0xf << 4), (0x8 << 0) | (0x6 << 4));
|
||||
|
||||
if (params->cbt_mode_extern != CBT_R0_R1_NORMAL) {
|
||||
clrsetbits32(&ch[0].ao.perfctl0,
|
||||
(0x1 << 18) | (0x1 << 19) | (0x1 << 27),
|
||||
(0x0 << 18) | (0x1 << 19) | (0x1 << 27));
|
||||
clrbits32(&ch[0].ao.rstmask, 0x1 << 28);
|
||||
setbits32(&ch[0].ao.rkcfg, 0x1 << 11);
|
||||
setbits32(&ch[0].ao.spcmdctrl, 0x1 << 28);
|
||||
setbits32(&ch[0].ao.eyescan, 0x1 << 2);
|
||||
} else {
|
||||
clrbits32(&ch[0].ao.dramctrl, 0x1 << 0);
|
||||
clrsetbits32(&ch[0].ao.perfctl0,
|
||||
(0x1 << 18) | (0x1 << 19), (0x0 << 18) | (0x1 << 19));
|
||||
@@ -1330,12 +1391,12 @@ static void dramc_setting(const struct sdram_params *params, u8 freq_group,
|
||||
setbits32(&ch[0].phy.shu[0].b[1].dq[7], 0x1 << 7);
|
||||
clrsetbits32(&ch[0].ao.shu[0].rankctl, 0xf << 20, 0x4 << 20);
|
||||
|
||||
for (size_t r = 0; r < 2; r++) {
|
||||
clrsetbits32(&ch[0].ao.shu[0].rk[r].selph_dq[0],
|
||||
(0x7 << 0) | (0x7 << 4), (0x2 << 0) | (0x2 << 4));
|
||||
clrsetbits32(&ch[0].ao.shu[0].rk[r].selph_dq[1],
|
||||
for (size_t r = 0; r < 2; r++)
|
||||
for (size_t b = 0; b < 2; b++)
|
||||
clrsetbits32(&ch[0].ao.shu[0].rk[r].selph_dq[b],
|
||||
(0x7 << 0) | (0x7 << 4), (0x2 << 0) | (0x2 << 4));
|
||||
}
|
||||
|
||||
udelay(5);
|
||||
|
||||
clrsetbits32(&ch[0].ao.stbcal1, 0xffff << 16, 0x3 << 16);
|
||||
@@ -1363,9 +1424,26 @@ static void dramc_setting(const struct sdram_params *params, u8 freq_group,
|
||||
clrsetbits32(&ch[0].ao.rkcfg, 0x7 << 4, 0x1 << 4);
|
||||
udelay(12);
|
||||
|
||||
if (params->cbt_mode_extern != CBT_R0_R1_NORMAL)
|
||||
clrsetbits32(&ch[0].ao.shu[0].rankctl,
|
||||
(0xf << 24) | (0xf << 28), (0x4 << 24) | 0x6 << 28);
|
||||
(0xf << 20) | (0xf << 24) | (0xf << 28),
|
||||
(0x3 << 20) | (0x3 << 24) | (0x5 << 28));
|
||||
else
|
||||
clrsetbits32(&ch[0].ao.shu[0].rankctl,
|
||||
(0xf << 24) | (0xf << 28),
|
||||
(0x4 << 24) | (0x6 << 28));
|
||||
|
||||
clrbits32(&ch[0].ao.shu[0].wodt, 0x1 << 31);
|
||||
|
||||
if (params->cbt_mode_extern != CBT_R0_R1_NORMAL) {
|
||||
clrsetbits32(&ch[0].ao.shu[0].rk[0].dqsien,
|
||||
(0x7f << 0) | (0x7f << 8),
|
||||
(0x19 << 0) | (0x19 << 8));
|
||||
clrsetbits32(&ch[0].ao.shu[0].rk[1].dqsien,
|
||||
(0x7f << 0) | (0x7f << 8) | (0x7f << 16) | (0x7f << 24),
|
||||
(0x1b << 0) | (0x1b << 8) | (0x0 << 16) | (0x0 << 24));
|
||||
}
|
||||
|
||||
clrsetbits32(&ch[0].ao.shu[0].rk[0].fine_tune,
|
||||
(0x3f << 0) | (0x3f << 8) | (0x3f << 16) | (0x3f << 24),
|
||||
(0x1a << 0) | (0x1a << 8) | (0x1a << 16) | (0x1a << 24));
|
||||
@@ -1383,8 +1461,16 @@ static void dramc_setting(const struct sdram_params *params, u8 freq_group,
|
||||
clrsetbits32(&ch[0].ao.shu[0].dqsg_retry,
|
||||
(0x1 << 2) | (0xf << 8) | (0x1 << 14) | (0x3 << 24),
|
||||
(0x1 << 2) | (0x5 << 8) | (0x0 << 14) | (0x1 << 24));
|
||||
setbits32(&ch[0].phy.shu[0].b[0].dq[7], (0x1 << 12) | (0x1 << 13));
|
||||
setbits32(&ch[0].phy.shu[0].b[1].dq[7], (0x1 << 12) | (0x1 << 13));
|
||||
|
||||
if (params->cbt_mode_extern != CBT_R0_R1_NORMAL) {
|
||||
setbits32(&ch[0].phy.shu[0].b[0].dq[7], (0x1 << 12));
|
||||
setbits32(&ch[0].phy.shu[0].b[1].dq[7], (0x1 << 12));
|
||||
} else {
|
||||
setbits32(&ch[0].phy.shu[0].b[0].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);
|
||||
|
||||
/* The default dramc init settings were tuned at frequency of 3200Mbps.
|
||||
@@ -1392,10 +1478,10 @@ static void dramc_setting(const struct sdram_params *params, u8 freq_group,
|
||||
the default settings. */
|
||||
switch (freq_group) {
|
||||
case LP4X_DDR1600:
|
||||
dramc_setting_DDR1600();
|
||||
dramc_setting_DDR1600(params->cbt_mode_extern);
|
||||
break;
|
||||
case LP4X_DDR2400:
|
||||
dramc_setting_DDR2400();
|
||||
dramc_setting_DDR2400(params->cbt_mode_extern);
|
||||
break;
|
||||
case LP4X_DDR3200:
|
||||
/* Do nothing */
|
||||
@@ -1423,7 +1509,7 @@ static void dramc_setting(const struct sdram_params *params, u8 freq_group,
|
||||
(0x1 << 4) | (0x1 << 11) | (0x1 << 13) |
|
||||
(0x1 << 14) | (0x3 << 16) | (0x1 << 22),
|
||||
(0x1 << 4) | (0x1 << 11) | (0x1 << 13) |
|
||||
(0x1 << 14) | (0x2 << 16) | (0x1 << 22));
|
||||
(0x1 << 14) | (params->rank_num << 16) | (0x1 << 22));
|
||||
clrsetbits32(&ch[0].ao.test2_4, 0x7 << 28, 0x4 << 28);
|
||||
clrbits32(&ch[0].ao.dramctrl, 0x1 << 0);
|
||||
udelay(1);
|
||||
@@ -1630,7 +1716,150 @@ static const struct ac_time ac_timing_tbl[LP4X_DDRFREQ_MAX] = {
|
||||
},
|
||||
};
|
||||
|
||||
static void ddr_update_ac_timing(u8 freq_group)
|
||||
static const struct ac_time ac_timing_cbt_tbl[LP4X_DDRFREQ_MAX] = {
|
||||
/* LP4x-1600, 800MHz, RDBI_OFF, byte mode */
|
||||
[LP4X_DDR1600] = {
|
||||
.tras = 0, .tras_05T = 0,
|
||||
.trp = 2, .trp_05T = 0,
|
||||
.trpab = 0, .trpab_05T = 1,
|
||||
.trc = 4, .trc_05T = 0,
|
||||
.trfc = 44, .trfc_05T = 0,
|
||||
.trfcpb = 16, .trfcpb_05T = 0,
|
||||
.txp = 0, .txp_05T = 0,
|
||||
.trtp = 1, .trtp_05T = 1,
|
||||
.trcd = 3, .trcd_05T = 0,
|
||||
.twr = 7, .twr_05T = 0,
|
||||
.twtr = 4, .twtr_05T = 0,
|
||||
.trrd = 0, .trrd_05T = 0,
|
||||
.tfaw = 0, .tfaw_05T = 0,
|
||||
.trtw_odt_on = 4, .trtw_odt_on_05T = 0,
|
||||
.refcnt = 48,
|
||||
.refcnt_fr_clk = 101,
|
||||
.txrefcnt = 62,
|
||||
.tzqcs = 16,
|
||||
.xrtw2w = 5,
|
||||
.xrtw2r = 3,
|
||||
.xrtr2w = 3,
|
||||
.xrtr2r = 8,
|
||||
.r_dmcatrain_intv = 8,
|
||||
.r_dmmrw_intv = 0xf,
|
||||
.r_dmfspchg_prdcnt = 50,
|
||||
.trtpd = 7, .trtpd_05T = 0,
|
||||
.twtpd = 7, .twtpd_05T = 1,
|
||||
.tmrr2w_odt_on = 6,
|
||||
.ckeprd = 1,
|
||||
.ckelckcnt = 0,
|
||||
.zqlat2 = 6,
|
||||
.dqsinctl = 2, .datlat = 11,
|
||||
},
|
||||
/* LP4x-2400, 1200MHz, RDBI_OFF, byte mode */
|
||||
[LP4X_DDR2400] = {
|
||||
.tras = 4, .tras_05T = 1,
|
||||
.trp = 3, .trp_05T = 1,
|
||||
.trpab = 1, .trpab_05T = 0,
|
||||
.trc = 10, .trc_05T = 0,
|
||||
.trfc = 72, .trfc_05T = 0,
|
||||
.trfcpb = 30, .trfcpb_05T = 0,
|
||||
.txp = 0, .txp_05T = 1,
|
||||
.trtp = 1, .trtp_05T = 0,
|
||||
.trcd = 4, .trcd_05T = 1,
|
||||
.twr = 10, .twr_05T = 1,
|
||||
.twtr = 6, .twtr_05T = 1,
|
||||
.trrd = 1, .trrd_05T = 0,
|
||||
.tfaw = 3, .tfaw_05T = 0,
|
||||
.trtw_odt_on = 7, .trtw_odt_on_05T = 0,
|
||||
.refcnt = 73,
|
||||
.refcnt_fr_clk = 101,
|
||||
.txrefcnt = 91,
|
||||
.tzqcs = 25,
|
||||
.xrtw2w = 5,
|
||||
.xrtw2r = 3,
|
||||
.xrtr2w = 6,
|
||||
.xrtr2r = 8,
|
||||
.r_dmcatrain_intv = 9,
|
||||
.r_dmmrw_intv = 0xf,
|
||||
.r_dmfspchg_prdcnt = 75,
|
||||
.trtpd = 10, .trtpd_05T = 0,
|
||||
.twtpd = 10, .twtpd_05T = 0,
|
||||
.tmrr2w_odt_on = 9,
|
||||
.ckeprd = 2,
|
||||
.ckelckcnt = 0,
|
||||
.zqlat2 = 9,
|
||||
.dqsinctl = 4, .datlat = 14,
|
||||
},
|
||||
/* LP4x-3200, 1600MHz, RDBI_OFF, byte mode */
|
||||
[LP4X_DDR3200] = {
|
||||
.tras = 8, .tras_05T = 1,
|
||||
.trp = 5, .trp_05T = 1,
|
||||
.trpab = 1, .trpab_05T = 0,
|
||||
.trc = 16, .trc_05T = 1,
|
||||
.trfc = 100, .trfc_05T = 0,
|
||||
.trfcpb = 44, .trfcpb_05T = 0,
|
||||
.txp = 1, .txp_05T = 0,
|
||||
.trtp = 2, .trtp_05T = 1,
|
||||
.trcd = 6, .trcd_05T = 1,
|
||||
.twr = 13, .twr_05T = 1,
|
||||
.twtr = 8, .twtr_05T = 0,
|
||||
.trrd = 2, .trrd_05T = 0,
|
||||
.tfaw = 7, .tfaw_05T = 0,
|
||||
.trtw_odt_on = 8, .trtw_odt_on_05T = 0,
|
||||
.refcnt = 97,
|
||||
.refcnt_fr_clk = 101,
|
||||
.txrefcnt = 119,
|
||||
.tzqcs = 34,
|
||||
.xrtw2w = 5,
|
||||
.xrtw2r = 3,
|
||||
.xrtr2w = 7,
|
||||
.xrtr2r = 9,
|
||||
.r_dmcatrain_intv = 11,
|
||||
.r_dmmrw_intv = 0xf,
|
||||
.r_dmfspchg_prdcnt = 100,
|
||||
.trtpd = 12, .trtpd_05T = 0,
|
||||
.twtpd = 12, .twtpd_05T = 0,
|
||||
.tmrr2w_odt_on = 11,
|
||||
.ckeprd = 2,
|
||||
.ckelckcnt = 0,
|
||||
.zqlat2 = 12,
|
||||
.dqsinctl = 5, .datlat = 16,
|
||||
},
|
||||
/* LP4x-3600, 1800MHz, RDBI_OFF, byte mode */
|
||||
[LP4X_DDR3600] = {
|
||||
.tras = 11, .tras_05T = 1,
|
||||
.trp = 6, .trp_05T = 1,
|
||||
.trpab = 1, .trpab_05T = 1,
|
||||
.trc = 20, .trc_05T = 1,
|
||||
.trfc = 118, .trfc_05T = 1,
|
||||
.trfcpb = 53, .trfcpb_05T = 1,
|
||||
.txp = 1, .txp_05T = 1,
|
||||
.trtp = 2, .trtp_05T = 0,
|
||||
.trcd = 7, .trcd_05T = 1,
|
||||
.twr = 15, .twr_05T = 1,
|
||||
.twtr = 9, .twtr_05T = 0,
|
||||
.trrd = 3, .trrd_05T = 0,
|
||||
.tfaw = 10, .tfaw_05T = 0,
|
||||
.trtw_odt_on = 9, .trtw_odt_on_05T = 0,
|
||||
.refcnt = 113,
|
||||
.refcnt_fr_clk = 101,
|
||||
.txrefcnt = 138,
|
||||
.tzqcs = 40,
|
||||
.xrtw2w = 5,
|
||||
.xrtw2r = 3,
|
||||
.xrtr2w = 8,
|
||||
.xrtr2r = 9,
|
||||
.r_dmcatrain_intv = 13,
|
||||
.r_dmmrw_intv = 0xf,
|
||||
.r_dmfspchg_prdcnt = 117,
|
||||
.trtpd = 13, .trtpd_05T = 0,
|
||||
.twtpd = 14, .twtpd_05T = 0,
|
||||
.tmrr2w_odt_on = 10,
|
||||
.ckeprd = 3,
|
||||
.ckelckcnt = 0,
|
||||
.zqlat2 = 14,
|
||||
.dqsinctl = 7, .datlat = 17,
|
||||
},
|
||||
};
|
||||
|
||||
static void ddr_update_ac_timing(u8 freq_group, u32 cbt_mode)
|
||||
{
|
||||
struct ac_time ac_t;
|
||||
u32 temp, r2w_odt_onoff = ODT_ON;
|
||||
@@ -1638,8 +1867,12 @@ static void ddr_update_ac_timing(u8 freq_group)
|
||||
u8 root = 0, tx_rank_inctl = 0, tx_dly = 0;
|
||||
u8 trtw = 0, trtw_05t = 0, tmrr2w = 0;
|
||||
|
||||
if (cbt_mode)
|
||||
memcpy(&ac_t, &ac_timing_cbt_tbl[freq_group], sizeof(struct ac_time));
|
||||
else
|
||||
memcpy(&ac_t, &ac_timing_tbl[freq_group], sizeof(struct ac_time));
|
||||
new_datlat = ac_timing_tbl[freq_group].datlat - 2;
|
||||
|
||||
new_datlat = ac_t.datlat - 2;
|
||||
|
||||
if (freq_group == LP4X_DDR1600) {
|
||||
root = 0; tx_rank_inctl = 0; tx_dly = 1;
|
||||
@@ -1729,10 +1962,13 @@ static void ddr_update_ac_timing(u8 freq_group)
|
||||
(root << 16) | (tx_rank_inctl << 12) | (tx_dly << 8));
|
||||
}
|
||||
|
||||
u8 dram_cbt_mode = 0;
|
||||
clrsetbits32(&ch[0].ao.arbctl, 0x7 << 10, 0x3 << 10);
|
||||
clrsetbits32(&ch[0].ao.rstmask, 0x3 << 13, dram_cbt_mode);
|
||||
clrsetbits32(&ch[0].ao.arbctl, 0x1 << 13, dram_cbt_mode);
|
||||
clrsetbits32(&ch[0].ao.rstmask, 0x3 << 13, cbt_mode << 13);
|
||||
|
||||
if (cbt_mode == 0)
|
||||
clrsetbits32(&ch[0].ao.arbctl, 0x1 << 13, 0 << 13);
|
||||
else
|
||||
clrsetbits32(&ch[0].ao.arbctl, 0x1 << 13, 1 << 13);
|
||||
}
|
||||
|
||||
void dramc_init(const struct sdram_params *params, u8 freq_group,
|
||||
@@ -1743,6 +1979,6 @@ void dramc_init(const struct sdram_params *params, u8 freq_group,
|
||||
dramc_duty_calibration(params, freq_group);
|
||||
dvfs_settings(freq_group);
|
||||
|
||||
dramc_mode_reg_init(freq_group, &shared->mr);
|
||||
ddr_update_ac_timing(freq_group);
|
||||
dramc_mode_reg_init(freq_group, &shared->mr, params);
|
||||
ddr_update_ac_timing(freq_group, params->cbt_mode_extern);
|
||||
}
|
||||
|
@@ -347,9 +347,9 @@ static void dramc_phy_low_power_enable(u8 chn)
|
||||
(chn == CHANNEL_A) ? 0xba000 : 0x3a000);
|
||||
}
|
||||
|
||||
static void dramc_dummy_read_for_tracking_enable(u8 chn)
|
||||
static void dramc_dummy_read_for_tracking_enable(u8 chn, u32 rk_num)
|
||||
{
|
||||
setbits32(&ch[chn].ao.dummy_rd, 0x3 << 16);
|
||||
setbits32(&ch[chn].ao.dummy_rd, rk_num << 16);
|
||||
|
||||
for (size_t r = 0; r < 2; r++)
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
@@ -403,7 +403,7 @@ static void dramc_enable_dramc_dcm(void)
|
||||
}
|
||||
}
|
||||
|
||||
void dramc_runtime_config(void)
|
||||
void dramc_runtime_config(u32 rk_num)
|
||||
{
|
||||
for (u8 chn = 0; chn < CHANNEL_MAX; chn++)
|
||||
clrbits32(&ch[chn].ao.refctrl0, 0x1 << 29);
|
||||
@@ -412,7 +412,7 @@ void dramc_runtime_config(void)
|
||||
setbits32(&mtk_spm->spm_power_on_val0, 0x1 << 25);
|
||||
|
||||
for (u8 chn = 0; chn < CHANNEL_MAX; chn++) {
|
||||
dramc_hw_dqsosc(chn);
|
||||
dramc_hw_dqsosc(chn, rk_num);
|
||||
|
||||
/* RX_TRACKING: ON */
|
||||
dramc_rx_input_delay_tracking(chn);
|
||||
@@ -426,7 +426,7 @@ void dramc_runtime_config(void)
|
||||
(0x3 << 4) | (0x3 << 8) | (0x1 << 28));
|
||||
|
||||
/* DUMMY_READ_FOR_TRACKING: ON */
|
||||
dramc_dummy_read_for_tracking_enable(chn);
|
||||
dramc_dummy_read_for_tracking_enable(chn, rk_num);
|
||||
|
||||
/* ZQCS_ENABLE_LP4: ON */
|
||||
clrbits32(&ch[chn].ao.spcmdctrl, 0x1 << 30);
|
||||
|
@@ -266,7 +266,7 @@ static void cbt_set_perbit_delay_cell(u8 chn, u8 rank)
|
||||
}
|
||||
|
||||
static void set_dram_mr_cbt_on_off(u8 chn, u8 rank, u8 fsp,
|
||||
u8 cbt_on, struct mr_value *mr)
|
||||
bool cbt_on, struct mr_value *mr, u32 cbt_mode)
|
||||
{
|
||||
u8 MR13Value = mr->MR13Value;
|
||||
|
||||
@@ -276,6 +276,9 @@ static void set_dram_mr_cbt_on_off(u8 chn, u8 rank, u8 fsp,
|
||||
MR13Value &= 0x7f;
|
||||
else
|
||||
MR13Value |= 0x80;
|
||||
|
||||
if (cbt_mode)
|
||||
SET32_BITFIELDS(&ch[chn].ao.write_lev, WRITE_LEV_BYTEMODECBTEN, 1);
|
||||
} else {
|
||||
MR13Value &= 0xfe;
|
||||
if (fsp == FSP_1)
|
||||
@@ -322,7 +325,7 @@ static void o1_path_on_off(u8 cbt_on)
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
static void cbt_entry(u8 chn, u8 rank, u8 fsp, struct mr_value *mr)
|
||||
static void cbt_entry(u8 chn, u8 rank, u8 fsp, struct mr_value *mr, u32 cbt_mode)
|
||||
{
|
||||
SET32_BITFIELDS(&ch[chn].ao.dramc_pd_ctrl,
|
||||
DRAMC_PD_CTRL_PHYCLKDYNGEN, 0,
|
||||
@@ -331,7 +334,9 @@ 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_MIOCKCTRLOFF, 1);
|
||||
|
||||
dramc_cke_fix_onoff(CKE_FIXON, chn);
|
||||
set_dram_mr_cbt_on_off(chn, rank, fsp, 1, mr);
|
||||
set_dram_mr_cbt_on_off(chn, rank, fsp, true, mr, cbt_mode);
|
||||
|
||||
if (cbt_mode == 0)
|
||||
SET32_BITFIELDS(&ch[chn].ao.write_lev, WRITE_LEV_WRITE_LEVEL_EN, 1);
|
||||
|
||||
udelay(1);
|
||||
@@ -339,18 +344,21 @@ static void cbt_entry(u8 chn, u8 rank, u8 fsp, struct mr_value *mr)
|
||||
o1_path_on_off(1);
|
||||
}
|
||||
|
||||
static void cbt_exit(u8 chn, u8 rank, u8 fsp, struct mr_value *mr)
|
||||
static void cbt_exit(u8 chn, u8 rank, u8 fsp, struct mr_value *mr, u32 cbt_mode)
|
||||
{
|
||||
dramc_cke_fix_onoff(CKE_FIXON, chn);
|
||||
|
||||
udelay(1);
|
||||
set_dram_mr_cbt_on_off(chn, rank, fsp, 0, mr);
|
||||
set_dram_mr_cbt_on_off(chn, rank, fsp, false, mr, cbt_mode);
|
||||
o1_path_on_off(0);
|
||||
|
||||
if (cbt_mode)
|
||||
SET32_BITFIELDS(&ch[chn].ao.write_lev, WRITE_LEV_BYTEMODECBTEN, 0);
|
||||
}
|
||||
|
||||
static void cbt_set_vref(u8 chn, u8 rank, u8 vref, bool is_final)
|
||||
static void cbt_set_vref(u8 chn, u8 rank, u8 vref, bool is_final, u32 cbt_mode)
|
||||
{
|
||||
if (!is_final) {
|
||||
if (cbt_mode == 0 && !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);
|
||||
@@ -394,12 +402,18 @@ static void cbt_set_ca_clk_result(u8 chn, u8 rank,
|
||||
}
|
||||
}
|
||||
|
||||
static u8 get_cbt_vref_pinmux_value(u8 chn, u8 vref_level)
|
||||
static u8 get_cbt_vref_pinmux_value(u8 chn, u8 vref_level, u32 cbt_mode)
|
||||
{
|
||||
u8 vref_bit, vref_new, vref_org;
|
||||
|
||||
vref_new = 0;
|
||||
vref_org = BIT(6) | (vref_level & 0x3f);
|
||||
|
||||
if (cbt_mode) {
|
||||
dramc_dbg("vref_org: %#x for byte mode\n", vref_org);
|
||||
|
||||
return vref_org;
|
||||
}
|
||||
for (vref_bit = 0; vref_bit < 8; vref_bit++) {
|
||||
if (vref_org & (1 << vref_bit))
|
||||
vref_new |= (1 << phy_mapping[chn][vref_bit]);
|
||||
@@ -410,11 +424,14 @@ static u8 get_cbt_vref_pinmux_value(u8 chn, u8 vref_level)
|
||||
return vref_new;
|
||||
}
|
||||
|
||||
static void cbt_dramc_dfs_direct_jump(u8 shu_level)
|
||||
static void cbt_dramc_dfs_direct_jump(u8 shu_level, bool run_dvfs)
|
||||
{
|
||||
u8 shu_ack = 0;
|
||||
static bool phy_pll_en = true;
|
||||
|
||||
if (!run_dvfs)
|
||||
return;
|
||||
|
||||
for (u8 chn = 0; chn < CHANNEL_MAX; chn++)
|
||||
shu_ack |= (0x1 << chn);
|
||||
|
||||
@@ -490,20 +507,21 @@ static void cbt_dramc_dfs_direct_jump(u8 shu_level)
|
||||
phy_pll_en = !phy_pll_en;
|
||||
}
|
||||
|
||||
static void cbt_switch_freq(cbt_freq freq)
|
||||
static void cbt_switch_freq(cbt_freq freq, bool run_dvfs)
|
||||
{
|
||||
if (freq == CBT_LOW_FREQ)
|
||||
cbt_dramc_dfs_direct_jump(DRAM_DFS_SHUFFLE_MAX - 1);
|
||||
cbt_dramc_dfs_direct_jump(DRAM_DFS_SHUFFLE_MAX - 1, run_dvfs);
|
||||
else
|
||||
cbt_dramc_dfs_direct_jump(DRAM_DFS_SHUFFLE_1);
|
||||
cbt_dramc_dfs_direct_jump(DRAM_DFS_SHUFFLE_1, run_dvfs);
|
||||
}
|
||||
|
||||
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)
|
||||
const struct sdram_params *params, struct mr_value *mr,
|
||||
bool run_dvfs)
|
||||
{
|
||||
u8 final_vref, cs_dly;
|
||||
u8 fsp = get_freq_fsq(freq_group);
|
||||
u32 cbt_mode = params->cbt_mode_extern;
|
||||
|
||||
cs_dly = params->cbt_cs_dly[chn][rank];
|
||||
final_vref = params->cbt_final_vref[chn][rank];
|
||||
@@ -521,6 +539,7 @@ static void dramc_cmd_bus_training(u8 chn, u8 rank, u8 freq_group,
|
||||
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);
|
||||
@@ -530,16 +549,35 @@ static void dramc_cmd_bus_training(u8 chn, u8 rank, u8 freq_group,
|
||||
|
||||
cbt_set_perbit_delay_cell(chn, rank);
|
||||
|
||||
if (cbt_mode == 0) {
|
||||
cbt_mrr_pinmux_mapping();
|
||||
if (fsp == FSP_1)
|
||||
cbt_switch_freq(CBT_LOW_FREQ);
|
||||
cbt_entry(chn, rank, fsp, mr);
|
||||
cbt_switch_freq(CBT_LOW_FREQ, run_dvfs);
|
||||
cbt_entry(chn, rank, fsp, mr, cbt_mode);
|
||||
udelay(1);
|
||||
if (fsp == FSP_1)
|
||||
cbt_switch_freq(CBT_HIGH_FREQ);
|
||||
cbt_switch_freq(CBT_HIGH_FREQ, run_dvfs);
|
||||
}
|
||||
|
||||
u8 new_vref = get_cbt_vref_pinmux_value(chn, final_vref);
|
||||
cbt_set_vref(chn, rank, new_vref, 0);
|
||||
u8 new_vref = get_cbt_vref_pinmux_value(chn, final_vref, cbt_mode);
|
||||
|
||||
if (cbt_mode) {
|
||||
if (fsp == FSP_1)
|
||||
cbt_switch_freq(CBT_LOW_FREQ, run_dvfs);
|
||||
|
||||
cbt_set_fsp(chn, rank, fsp, mr);
|
||||
cbt_set_vref(chn, rank, new_vref, true, cbt_mode);
|
||||
cbt_entry(chn, rank, fsp, mr, cbt_mode);
|
||||
udelay(1);
|
||||
|
||||
if (fsp == FSP_1)
|
||||
cbt_switch_freq(CBT_HIGH_FREQ, run_dvfs);
|
||||
} else {
|
||||
cbt_set_vref(chn, rank, new_vref, false, cbt_mode);
|
||||
}
|
||||
|
||||
cbt_set_ca_clk_result(chn, rank, params);
|
||||
udelay(1);
|
||||
|
||||
for (u8 rk = 0; rk < rank + 1; rk++) {
|
||||
/* Set CLK and CS delay */
|
||||
@@ -548,14 +586,16 @@ static void dramc_cmd_bus_training(u8 chn, u8 rank, u8 freq_group,
|
||||
}
|
||||
|
||||
if (fsp == FSP_1)
|
||||
cbt_switch_freq(CBT_LOW_FREQ);
|
||||
cbt_exit(chn, rank, fsp, mr);
|
||||
cbt_switch_freq(CBT_LOW_FREQ, run_dvfs);
|
||||
cbt_exit(chn, rank, fsp, mr, cbt_mode);
|
||||
|
||||
if (cbt_mode == 0) {
|
||||
cbt_set_fsp(chn, rank, fsp, mr);
|
||||
cbt_set_vref(chn, rank, final_vref, 1);
|
||||
cbt_set_vref(chn, rank, final_vref, true, cbt_mode);
|
||||
}
|
||||
|
||||
if (fsp == FSP_1)
|
||||
cbt_switch_freq(CBT_HIGH_FREQ);
|
||||
cbt_switch_freq(CBT_HIGH_FREQ, run_dvfs);
|
||||
|
||||
/* restore MRR pinmux */
|
||||
set_mrr_pinmux_mapping();
|
||||
@@ -693,7 +733,7 @@ static void dramc_rx_input_delay_tracking_init_by_freq(u8 chn, u8 freq_group)
|
||||
clrbits32(&shu->b[1].dq[7], (0x1 << 12) | (0x1 << 13));
|
||||
}
|
||||
|
||||
void dramc_apply_config_before_calibration(u8 freq_group)
|
||||
void dramc_apply_config_before_calibration(u8 freq_group, u32 cbt_mode)
|
||||
{
|
||||
for (u8 chn = 0; chn < CHANNEL_MAX; chn++) {
|
||||
dramc_enable_phy_dcm(chn, false);
|
||||
@@ -710,8 +750,20 @@ void dramc_apply_config_before_calibration(u8 freq_group)
|
||||
clrbits32(&ch[chn].ao.dramctrl, 0x1 << 18);
|
||||
clrbits32(&ch[chn].ao.spcmdctrl, 0x1 << 31);
|
||||
clrbits32(&ch[chn].ao.spcmdctrl, 0x1 << 30);
|
||||
|
||||
if (cbt_mode == CBT_R0_R1_NORMAL) {
|
||||
clrbits32(&ch[chn].ao.dqsoscr, 0x1 << 26);
|
||||
clrbits32(&ch[chn].ao.dqsoscr, 0x1 << 25);
|
||||
} else if (cbt_mode == CBT_R0_R1_BYTE) {
|
||||
setbits32(&ch[chn].ao.dqsoscr, 0x1 << 26);
|
||||
setbits32(&ch[chn].ao.dqsoscr, 0x1 << 25);
|
||||
} else if (cbt_mode == CBT_R0_NORMAL_R1_BYTE) {
|
||||
clrbits32(&ch[chn].ao.dqsoscr, 0x1 << 26);
|
||||
setbits32(&ch[chn].ao.dqsoscr, 0x1 << 25);
|
||||
} else if (cbt_mode == CBT_R0_BYTE_R1_NORMAL) {
|
||||
setbits32(&ch[chn].ao.dqsoscr, 0x1 << 26);
|
||||
clrbits32(&ch[chn].ao.dqsoscr, 0x1 << 25);
|
||||
}
|
||||
|
||||
dramc_write_dbi_onoff(chn, false);
|
||||
dramc_read_dbi_onoff(chn, false);
|
||||
@@ -751,9 +803,9 @@ void dramc_apply_config_before_calibration(u8 freq_group)
|
||||
}
|
||||
}
|
||||
|
||||
static void dramc_set_mr13_vrcg_to_Normal(u8 chn, const struct mr_value *mr)
|
||||
static void dramc_set_mr13_vrcg_to_normal(u8 chn, const struct mr_value *mr, u32 rk_num)
|
||||
{
|
||||
for (u8 rank = 0; rank < RANK_MAX; rank++)
|
||||
for (u8 rank = 0; rank < rk_num; rank++)
|
||||
dramc_mode_reg_write_by_rank(chn, rank, 13,
|
||||
mr->MR13Value & ~(0x1 << 3));
|
||||
|
||||
@@ -761,14 +813,14 @@ static void dramc_set_mr13_vrcg_to_Normal(u8 chn, const struct mr_value *mr)
|
||||
clrbits32(&ch[chn].ao.shu[shu].hwset_vrcg, 0x1 << 19);
|
||||
}
|
||||
|
||||
void dramc_apply_config_after_calibration(const struct mr_value *mr)
|
||||
void dramc_apply_config_after_calibration(const struct mr_value *mr, u32 rk_num)
|
||||
{
|
||||
for (size_t chn = 0; chn < CHANNEL_MAX; chn++) {
|
||||
write32(&ch[chn].phy.misc_cg_ctrl4, 0x11400000);
|
||||
clrbits32(&ch[chn].ao.refctrl1, 0x1 << 7);
|
||||
clrbits32(&ch[chn].ao.shuctrl, 0x1 << 2);
|
||||
clrbits32(&ch[chn].phy.ca_cmd[6], 0x1 << 6);
|
||||
dramc_set_mr13_vrcg_to_Normal(chn, mr);
|
||||
dramc_set_mr13_vrcg_to_normal(chn, mr, rk_num);
|
||||
|
||||
clrbits32(&ch[chn].phy.b[0].dq[6], 0x3);
|
||||
clrbits32(&ch[chn].phy.b[1].dq[6], 0x3);
|
||||
@@ -2358,7 +2410,7 @@ static void dramc_dual_rank_rx_datlat_cal(u8 chn, u8 freq_group, u8 datlat0, u8
|
||||
dramc_dle_factor_handler(chn, final_datlat, freq_group);
|
||||
}
|
||||
|
||||
static void dramc_rx_dqs_gating_post_process(u8 chn, u8 freq_group)
|
||||
static void dramc_rx_dqs_gating_post_process(u8 chn, u8 freq_group, u32 rk_num)
|
||||
{
|
||||
s8 dqsinctl;
|
||||
u32 read_dqsinctl, rankinctl_root, reg_tx_dly_dqsgated_min = 3;
|
||||
@@ -2372,7 +2424,7 @@ static void dramc_rx_dqs_gating_post_process(u8 chn, u8 freq_group)
|
||||
reg_tx_dly_dqsgated_min = 1;
|
||||
|
||||
/* get TXDLY_Cal_min and TXDLY_Cal_max value */
|
||||
for (size_t rank = 0; rank < RANK_MAX; rank++) {
|
||||
for (size_t rank = 0; rank < rk_num; rank++) {
|
||||
u32 dqsg0 = read32(&ch[chn].ao.shu[0].rk[rank].selph_dqsg0);
|
||||
for (size_t dqs = 0; dqs < DQS_NUMBER; dqs++) {
|
||||
best_coarse_tune2t[rank][dqs] = (dqsg0 >> (dqs * 8)) & 0x7;
|
||||
@@ -2397,7 +2449,7 @@ static void dramc_rx_dqs_gating_post_process(u8 chn, u8 freq_group)
|
||||
txdly_cal_min += dqsinctl;
|
||||
txdly_cal_max += dqsinctl;
|
||||
|
||||
for (size_t rank = 0; rank < RANK_MAX; rank++) {
|
||||
for (size_t rank = 0; rank < rk_num; rank++) {
|
||||
dramc_dbg("Rank: %zd\n", rank);
|
||||
for (size_t dqs = 0; dqs < DQS_NUMBER; dqs++) {
|
||||
best_coarse_tune2t[rank][dqs] += dqsinctl;
|
||||
@@ -2515,7 +2567,7 @@ static void dqsosc_auto(u8 chn, u8 rank, u8 freq_group,
|
||||
SHU1RK0_DQSOSC_DQSOSC_BASE_RK0_B1, dqsosc_cnt[1]);
|
||||
}
|
||||
|
||||
void dramc_hw_dqsosc(u8 chn)
|
||||
void dramc_hw_dqsosc(u8 chn, u32 rk_num)
|
||||
{
|
||||
u32 freq_shu1 = get_shu_freq(DRAM_DFS_SHUFFLE_1);
|
||||
u32 freq_shu2 = get_shu_freq(DRAM_DFS_SHUFFLE_2);
|
||||
@@ -2544,7 +2596,10 @@ void dramc_hw_dqsosc(u8 chn)
|
||||
SET32_BITFIELDS(&ch[chn].ao.dqsoscr, DQSOSCR_DQSOSCRDIS, 1);
|
||||
|
||||
SET32_BITFIELDS(&ch[chn].ao.rk[0].dqsosc, RK0_DQSOSC_DQSOSCR_RK0EN, 1);
|
||||
|
||||
if (rk_num == RANK_MAX)
|
||||
SET32_BITFIELDS(&ch[chn].ao.rk[1].dqsosc, RK1_DQSOSC_DQSOSCR_RK1EN, 1);
|
||||
|
||||
SET32_BITFIELDS(&ch[chn].ao.dqsoscr, DQSOSCR_DQSOSC_CALEN, 1);
|
||||
|
||||
for (u8 shu = 0; shu < DRAM_DFS_SHUFFLE_MAX; shu++)
|
||||
@@ -2994,7 +3049,7 @@ void dramc_dqs_precalculation_preset(void)
|
||||
}
|
||||
}
|
||||
|
||||
void get_dram_info_after_cal(u8 *density_result)
|
||||
void get_dram_info_after_cal(u8 *density_result, u32 rk_num)
|
||||
{
|
||||
u8 vendor_id, density, max_density = 0;
|
||||
u32 ddr_size, max_size = 0;
|
||||
@@ -3002,7 +3057,7 @@ void get_dram_info_after_cal(u8 *density_result)
|
||||
vendor_id = dramc_mode_reg_read_by_rank(CHANNEL_A, RANK_0, 5);
|
||||
dramc_show("Vendor id is %#x\n", vendor_id);
|
||||
|
||||
for (u8 rk = RANK_0; rk < RANK_MAX; rk++) {
|
||||
for (u8 rk = RANK_0; rk < rk_num; rk++) {
|
||||
density = dramc_mode_reg_read_by_rank(CHANNEL_A, rk, 8);
|
||||
dramc_dbg("MR8 %#x\n", density);
|
||||
density = (density >> 2) & 0xf;
|
||||
@@ -3044,7 +3099,7 @@ void get_dram_info_after_cal(u8 *density_result)
|
||||
}
|
||||
|
||||
int dramc_calibrate_all_channels(const struct sdram_params *pams,
|
||||
u8 freq_group, struct mr_value *mr)
|
||||
u8 freq_group, struct mr_value *mr, bool run_dvfs)
|
||||
{
|
||||
bool fast_calib;
|
||||
switch (pams->source) {
|
||||
@@ -3064,11 +3119,11 @@ int dramc_calibrate_all_channels(const struct sdram_params *pams,
|
||||
u16 osc_thrd_inc[RANK_MAX];
|
||||
u16 osc_thrd_dec[RANK_MAX];
|
||||
for (u8 chn = 0; chn < CHANNEL_MAX; chn++) {
|
||||
for (u8 rk = RANK_0; rk < RANK_MAX; rk++) {
|
||||
for (u8 rk = RANK_0; rk < pams->rank_num; rk++) {
|
||||
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, mr);
|
||||
mr, run_dvfs);
|
||||
dramc_write_leveling(chn, rk, freq_group, pams->wr_level);
|
||||
dramc_auto_refresh_switch(chn, true);
|
||||
|
||||
@@ -3092,7 +3147,7 @@ int dramc_calibrate_all_channels(const struct sdram_params *pams,
|
||||
}
|
||||
|
||||
dqsosc_shu_settings(chn, freq_group, osc_thrd_inc, osc_thrd_dec);
|
||||
dramc_rx_dqs_gating_post_process(chn, freq_group);
|
||||
dramc_rx_dqs_gating_post_process(chn, freq_group, pams->rank_num);
|
||||
dramc_dual_rank_rx_datlat_cal(chn, freq_group, rx_datlat[0], rx_datlat[1]);
|
||||
}
|
||||
return 0;
|
||||
|
@@ -157,6 +157,19 @@ static void set_rank_info_to_conf(const struct sdram_params *params)
|
||||
(is_dual_rank ? 0 : 1) << 12);
|
||||
}
|
||||
|
||||
void cbt_mrr_pinmux_mapping(void)
|
||||
{
|
||||
for (size_t chn = 0; chn < CHANNEL_MAX; chn++) {
|
||||
const u8 *map = phy_mapping[chn];
|
||||
write32(&ch[chn].ao.mrr_bit_mux1,
|
||||
(map[8] << 0) | (map[9] << 8) |
|
||||
(map[10] << 16) | (map[11] << 24));
|
||||
|
||||
write32(&ch[chn].ao.mrr_bit_mux2,
|
||||
(map[12] << 0) | (map[13] << 8));
|
||||
}
|
||||
}
|
||||
|
||||
void set_mrr_pinmux_mapping(void)
|
||||
{
|
||||
for (size_t chn = 0; chn < CHANNEL_MAX; chn++) {
|
||||
@@ -432,7 +445,7 @@ static void dfs_init_for_calibration(const struct sdram_params *params,
|
||||
struct dram_shared_data *shared)
|
||||
{
|
||||
dramc_init(params, freq_group, shared);
|
||||
dramc_apply_config_before_calibration(freq_group);
|
||||
dramc_apply_config_before_calibration(freq_group, params->cbt_mode_extern);
|
||||
}
|
||||
|
||||
static void init_dram(const struct sdram_params *params, u8 freq_group,
|
||||
@@ -449,7 +462,7 @@ static void init_dram(const struct sdram_params *params, u8 freq_group,
|
||||
dramc_sw_impedance_cal(params, ODT_ON, &shared->impedance);
|
||||
|
||||
dramc_init(params, freq_group, shared);
|
||||
dramc_apply_config_before_calibration(freq_group);
|
||||
dramc_apply_config_before_calibration(freq_group, params->cbt_mode_extern);
|
||||
emi_init2(params);
|
||||
}
|
||||
|
||||
@@ -589,9 +602,10 @@ static int run_calib(const struct dramc_param *dparam,
|
||||
*first_run = false;
|
||||
|
||||
dramc_dbg("Start K (current clock: %u\n", params->frequency);
|
||||
if (dramc_calibrate_all_channels(params, freq_group, &shared->mr) != 0)
|
||||
if (dramc_calibrate_all_channels(params, freq_group, &shared->mr,
|
||||
!!(dparam->header.config & DRAMC_CONFIG_DVFS)) != 0)
|
||||
return -1;
|
||||
get_dram_info_after_cal(&density);
|
||||
get_dram_info_after_cal(&density, params->rank_num);
|
||||
dramc_ac_timing_optimize(freq_group, density);
|
||||
dramc_dbg("K finished (current clock: %u\n", params->frequency);
|
||||
|
||||
@@ -599,10 +613,10 @@ static int run_calib(const struct dramc_param *dparam,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void after_calib(const struct mr_value *mr)
|
||||
static void after_calib(const struct mr_value *mr, u32 rk_num)
|
||||
{
|
||||
dramc_apply_config_after_calibration(mr);
|
||||
dramc_runtime_config();
|
||||
dramc_apply_config_after_calibration(mr, rk_num);
|
||||
dramc_runtime_config(rk_num);
|
||||
}
|
||||
|
||||
int mt_set_emi(const struct dramc_param *dparam)
|
||||
@@ -623,6 +637,6 @@ int mt_set_emi(const struct dramc_param *dparam)
|
||||
if (run_calib(dparam, &shared, DRAM_DFS_SHUFFLE_1, &first_run) != 0)
|
||||
return -1;
|
||||
|
||||
after_calib(&shared.mr);
|
||||
after_calib(&shared.mr, dparam->freq_params[DRAM_DFS_SHUFFLE_1].rank_num);
|
||||
return 0;
|
||||
}
|
||||
|
@@ -47,6 +47,13 @@ enum {
|
||||
CBT_BYTE_MODE1
|
||||
};
|
||||
|
||||
enum {
|
||||
CBT_R0_R1_NORMAL = 0, /* Normal mode */
|
||||
CBT_R0_R1_BYTE, /* Byte mode */
|
||||
CBT_R0_NORMAL_R1_BYTE, /* Mixed mode R0: Normal R1: Byte */
|
||||
CBT_R0_BYTE_R1_NORMAL /* Mixed mode R0: Byte R1: Normal */
|
||||
};
|
||||
|
||||
enum {
|
||||
FSP_0 = 0,
|
||||
FSP_1,
|
||||
|
@@ -10,7 +10,7 @@
|
||||
|
||||
enum {
|
||||
DRAMC_PARAM_HEADER_MAGIC = 0x44524d4b,
|
||||
DRAMC_PARAM_HEADER_VERSION = 4,
|
||||
DRAMC_PARAM_HEADER_VERSION = 5,
|
||||
};
|
||||
|
||||
enum DRAMC_PARAM_STATUS_CODES {
|
||||
@@ -38,9 +38,13 @@ enum DRAMC_PARAM_FLAGS {
|
||||
};
|
||||
|
||||
enum DRAMC_PARAM_GEOMETRY_TYPE {
|
||||
DDR_TYPE_2CH_1RK_4GB_4,
|
||||
DDR_TYPE_2CH_2RK_4GB_2_2,
|
||||
DDR_TYPE_2CH_2RK_6GB_3_3,
|
||||
DDR_TYPE_2CH_2RK_8GB_4_4,
|
||||
DDR_TYPE_2CH_RK0_RK1_BYTE_8GB_4_4,
|
||||
DDR_TYPE_2CH_RK0_NORMAL_RK1_BYTE_8GB_4_4,
|
||||
DDR_TYPE_2CH_RK0_BYTE_RK1_NORMAL_8GB_4_4,
|
||||
};
|
||||
|
||||
struct dramc_param_header {
|
||||
|
@@ -97,7 +97,7 @@ enum {
|
||||
};
|
||||
|
||||
void dramc_get_rank_size(u64 *dram_rank_size);
|
||||
void dramc_runtime_config(void);
|
||||
void dramc_runtime_config(u32 rk_num);
|
||||
void dramc_set_broadcast(u32 onoff);
|
||||
u32 dramc_get_broadcast(void);
|
||||
u8 get_freq_fsq(u8 freq_group);
|
||||
@@ -107,18 +107,19 @@ void dramc_sw_impedance_save_reg(u8 freq_group,
|
||||
const struct dram_impedance *impedance);
|
||||
void dramc_sw_impedance_cal(const struct sdram_params *params, u8 term_option,
|
||||
struct dram_impedance *impedance);
|
||||
void dramc_apply_config_before_calibration(u8 freq_group);
|
||||
void dramc_apply_config_after_calibration(const struct mr_value *mr);
|
||||
void dramc_apply_config_before_calibration(u8 freq_group, u32 cbt_mode);
|
||||
void dramc_apply_config_after_calibration(const struct mr_value *mr, u32 rk_num);
|
||||
int dramc_calibrate_all_channels(const struct sdram_params *pams,
|
||||
u8 freq_group, struct mr_value *mr);
|
||||
u8 freq_group, struct mr_value *mr, bool run_dvfs);
|
||||
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);
|
||||
u32 get_shu_freq(u8 shu);
|
||||
void dramc_hw_dqsosc(u8 chn);
|
||||
void dramc_hw_dqsosc(u8 chn, u32 rk_num);
|
||||
void dramc_dqs_precalculation_preset(void);
|
||||
void get_dram_info_after_cal(u8 *density);
|
||||
void get_dram_info_after_cal(u8 *density, u32 rk_num);
|
||||
void set_mrr_pinmux_mapping(void);
|
||||
void dramc_cke_fix_onoff(enum cke_type option, u8 chn);
|
||||
void cbt_mrr_pinmux_mapping(void);
|
||||
|
||||
#endif /* _DRAMC_PI_API_MT8183_H */
|
||||
|
@@ -15,6 +15,7 @@ enum DRAMC_PARAM_SOURCE {
|
||||
struct sdram_params {
|
||||
u16 source; /* DRAMC_PARAM_SOURCE */
|
||||
u16 frequency;
|
||||
u32 rank_num;
|
||||
u32 ddr_geometry; /* DRAMC_PARAM_GEOMETRY_TYPE */
|
||||
u8 wr_level[CHANNEL_MAX][RANK_MAX][DQS_NUMBER];
|
||||
|
||||
|
Reference in New Issue
Block a user