mirror of
https://github.com/AsahiLinux/u-boot
synced 2025-03-16 23:07:00 +00:00
sunxi: Add TPR2 parameter for H616 DRAM driver
It turns out that some H616 and related SoCs (like H313) need TPR2 parameter for proper working. Add it. Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com> Reviewed-by: Andre Przywara <andre.przywara@arm.com> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
This commit is contained in:
parent
4a967cb95f
commit
deb77f18bf
4 changed files with 75 additions and 24 deletions
|
@ -157,6 +157,7 @@ struct dram_para {
|
|||
u32 ca_dri;
|
||||
u32 odt_en;
|
||||
u32 tpr0;
|
||||
u32 tpr2;
|
||||
u32 tpr10;
|
||||
u32 tpr11;
|
||||
u32 tpr12;
|
||||
|
|
|
@ -79,6 +79,12 @@ config DRAM_SUN50I_H616_TPR0
|
|||
help
|
||||
TPR0 value from vendor DRAM settings.
|
||||
|
||||
config DRAM_SUN50I_H616_TPR2
|
||||
hex "H616 DRAM TPR2 parameter"
|
||||
default 0x0
|
||||
help
|
||||
TPR2 value from vendor DRAM settings.
|
||||
|
||||
config DRAM_SUN50I_H616_TPR10
|
||||
hex "H616 DRAM TPR10 parameter"
|
||||
help
|
||||
|
|
|
@ -788,21 +788,37 @@ static void mctl_phy_ca_bit_delay_compensation(struct dram_para *para)
|
|||
writel(val, &ptr[i]);
|
||||
|
||||
val = (para->tpr10 << 1) & 0x1e;
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x7d8);
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x7dc);
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x7e0);
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x7f4);
|
||||
|
||||
/* following configuration is DDR3 specific */
|
||||
val = (para->tpr10 >> 7) & 0x1e;
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x7d4);
|
||||
if (para->ranks == 2) {
|
||||
val = (para->tpr10 >> 11) & 0x1e;
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x79c);
|
||||
}
|
||||
if (para->tpr0 & BIT(31)) {
|
||||
val = (para->tpr0 << 1) & 0x3e;
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x78c);
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x7a4);
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x7b8);
|
||||
if (para->tpr2 & 1) {
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x794);
|
||||
if (para->ranks == 2) {
|
||||
val = (para->tpr10 >> 11) & 0x1e;
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x7e4);
|
||||
}
|
||||
if (para->tpr0 & BIT(31)) {
|
||||
val = (para->tpr0 << 1) & 0x3e;
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x790);
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x7b8);
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x7cc);
|
||||
}
|
||||
} else {
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x7d4);
|
||||
if (para->ranks == 2) {
|
||||
val = (para->tpr10 >> 11) & 0x1e;
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x79c);
|
||||
}
|
||||
if (para->tpr0 & BIT(31)) {
|
||||
val = (para->tpr0 << 1) & 0x3e;
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x78c);
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x7a4);
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x7b8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -812,7 +828,7 @@ static bool mctl_phy_init(struct dram_para *para)
|
|||
(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
|
||||
struct sunxi_mctl_ctl_reg * const mctl_ctl =
|
||||
(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
|
||||
u32 val, *ptr;
|
||||
u32 val, val2, *ptr, mr0, mr2;
|
||||
int i;
|
||||
|
||||
if (para->bus_full_width)
|
||||
|
@ -821,20 +837,28 @@ static bool mctl_phy_init(struct dram_para *para)
|
|||
val = 3;
|
||||
clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x3c, 0xf, val);
|
||||
|
||||
writel(0xd, SUNXI_DRAM_PHY0_BASE + 0x14);
|
||||
writel(0xd, SUNXI_DRAM_PHY0_BASE + 0x35c);
|
||||
writel(0xd, SUNXI_DRAM_PHY0_BASE + 0x368);
|
||||
writel(0xd, SUNXI_DRAM_PHY0_BASE + 0x374);
|
||||
if (para->tpr2 & 0x100) {
|
||||
val = 9;
|
||||
val2 = 7;
|
||||
} else {
|
||||
val = 13;
|
||||
val2 = 9;
|
||||
}
|
||||
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x14);
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x35c);
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x368);
|
||||
writel(val, SUNXI_DRAM_PHY0_BASE + 0x374);
|
||||
|
||||
writel(0, SUNXI_DRAM_PHY0_BASE + 0x18);
|
||||
writel(0, SUNXI_DRAM_PHY0_BASE + 0x360);
|
||||
writel(0, SUNXI_DRAM_PHY0_BASE + 0x36c);
|
||||
writel(0, SUNXI_DRAM_PHY0_BASE + 0x378);
|
||||
|
||||
writel(9, SUNXI_DRAM_PHY0_BASE + 0x1c);
|
||||
writel(9, SUNXI_DRAM_PHY0_BASE + 0x364);
|
||||
writel(9, SUNXI_DRAM_PHY0_BASE + 0x370);
|
||||
writel(9, SUNXI_DRAM_PHY0_BASE + 0x37c);
|
||||
writel(val2, SUNXI_DRAM_PHY0_BASE + 0x1c);
|
||||
writel(val2, SUNXI_DRAM_PHY0_BASE + 0x364);
|
||||
writel(val2, SUNXI_DRAM_PHY0_BASE + 0x370);
|
||||
writel(val2, SUNXI_DRAM_PHY0_BASE + 0x37c);
|
||||
|
||||
ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xc0);
|
||||
for (i = 0; i < ARRAY_SIZE(phy_init); i++)
|
||||
|
@ -890,7 +914,15 @@ static bool mctl_phy_init(struct dram_para *para)
|
|||
writel(1, &mctl_ctl->swctl);
|
||||
mctl_await_completion(&mctl_ctl->swstat, 1, 1);
|
||||
|
||||
writel(0x1f14, &mctl_ctl->mrctrl1);
|
||||
if (para->tpr2 & 0x100) {
|
||||
mr0 = 0x1b50;
|
||||
mr2 = 0x10;
|
||||
} else {
|
||||
mr0 = 0x1f14;
|
||||
mr2 = 0x20;
|
||||
}
|
||||
|
||||
writel(mr0, &mctl_ctl->mrctrl1);
|
||||
writel(0x80000030, &mctl_ctl->mrctrl0);
|
||||
mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
|
||||
|
||||
|
@ -898,7 +930,7 @@ static bool mctl_phy_init(struct dram_para *para)
|
|||
writel(0x80001030, &mctl_ctl->mrctrl0);
|
||||
mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
|
||||
|
||||
writel(0x20, &mctl_ctl->mrctrl1);
|
||||
writel(mr2, &mctl_ctl->mrctrl1);
|
||||
writel(0x80002030, &mctl_ctl->mrctrl0);
|
||||
mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
|
||||
|
||||
|
@ -1135,6 +1167,7 @@ unsigned long sunxi_dram_init(void)
|
|||
.ca_dri = CONFIG_DRAM_SUN50I_H616_CA_DRI,
|
||||
.odt_en = CONFIG_DRAM_SUN50I_H616_ODT_EN,
|
||||
.tpr0 = CONFIG_DRAM_SUN50I_H616_TPR0,
|
||||
.tpr2 = CONFIG_DRAM_SUN50I_H616_TPR2,
|
||||
.tpr10 = CONFIG_DRAM_SUN50I_H616_TPR10,
|
||||
.tpr11 = CONFIG_DRAM_SUN50I_H616_TPR11,
|
||||
.tpr12 = CONFIG_DRAM_SUN50I_H616_TPR12,
|
||||
|
|
|
@ -50,9 +50,20 @@ void mctl_set_timing_params(struct dram_para *para)
|
|||
u8 t_rdata_en = 9; /* ? */
|
||||
u8 t_wr_lat = 5; /* ? */
|
||||
|
||||
u8 twtp = tcl + 2 + tcwl; /* (WL + BL / 2 + tWR) / 2 */
|
||||
u8 twr2rd = trtp + 2 + tcwl; /* (WL + BL / 2 + tWTR) / 2 */
|
||||
u8 trd2wr = tcl + 3 - tcwl; /* (RL + BL / 2 + 2 - WL) / 2 */
|
||||
u8 twtp; /* (WL + BL / 2 + tWR) / 2 */
|
||||
u8 twr2rd; /* (WL + BL / 2 + tWTR) / 2 */
|
||||
u8 trd2wr; /* (RL + BL / 2 + 2 - WL) / 2 */
|
||||
|
||||
if (para->tpr2 & 0x100) {
|
||||
tcl = 5;
|
||||
tcwl = 4;
|
||||
t_rdata_en = 5;
|
||||
t_wr_lat = 3;
|
||||
}
|
||||
|
||||
twtp = tcl + 2 + tcwl;
|
||||
twr2rd = trtp + 2 + tcwl;
|
||||
trd2wr = tcl + 3 - tcwl;
|
||||
|
||||
/* set DRAM timing */
|
||||
writel((twtp << 24) | (tfaw << 16) | (trasmax << 8) | tras,
|
||||
|
|
Loading…
Add table
Reference in a new issue