sunxi: Add support for LPDDR3 for A83T
Banana-pi M3 has LPDDR3 DRAM. this adds support for LPDDR3 for A83T. Mostly the timing parameters are different from DDR3. Signed-off-by: Vishnu Patekar <vishnupatekar0510@gmail.com> Acked-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
committed by
Hans de Goede
parent
f5fd8caf7f
commit
f3ad64c88c
@@ -131,10 +131,42 @@ static void auto_set_timing_para(struct dram_para *para)
|
|||||||
/* Set work mode register */
|
/* Set work mode register */
|
||||||
mctl_set_cr(para);
|
mctl_set_cr(para);
|
||||||
/* Set mode register */
|
/* Set mode register */
|
||||||
writel(MCTL_MR0, &mctl_ctl->mr0);
|
if (para->dram_type == DRAM_TYPE_DDR3) {
|
||||||
writel(MCTL_MR1, &mctl_ctl->mr1);
|
writel(MCTL_MR0, &mctl_ctl->mr0);
|
||||||
writel(MCTL_MR2, &mctl_ctl->mr2);
|
writel(MCTL_MR1, &mctl_ctl->mr1);
|
||||||
writel(MCTL_MR3, &mctl_ctl->mr3);
|
writel(MCTL_MR2, &mctl_ctl->mr2);
|
||||||
|
writel(MCTL_MR3, &mctl_ctl->mr3);
|
||||||
|
} else if (para->dram_type == DRAM_TYPE_LPDDR3) {
|
||||||
|
writel(MCTL_LPDDR3_MR0, &mctl_ctl->mr0);
|
||||||
|
writel(MCTL_LPDDR3_MR1, &mctl_ctl->mr1);
|
||||||
|
writel(MCTL_LPDDR3_MR2, &mctl_ctl->mr2);
|
||||||
|
writel(MCTL_LPDDR3_MR3, &mctl_ctl->mr3);
|
||||||
|
|
||||||
|
/* timing parameters for LPDDR3 */
|
||||||
|
tfaw = max(ns_to_t(50), 4);
|
||||||
|
trrd = max(ns_to_t(10), 2);
|
||||||
|
trcd = max(ns_to_t(24), 2);
|
||||||
|
trc = ns_to_t(70);
|
||||||
|
txp = max(ns_to_t(8), 2);
|
||||||
|
twtr = max(ns_to_t(8), 2);
|
||||||
|
trtp = max(ns_to_t(8), 2);
|
||||||
|
trp = max(ns_to_t(27), 2);
|
||||||
|
tras = ns_to_t(42);
|
||||||
|
trefi = ns_to_t(3900) / 32;
|
||||||
|
trfc = ns_to_t(210);
|
||||||
|
tmrw = 5;
|
||||||
|
tmrd = 5;
|
||||||
|
tckesr = 5;
|
||||||
|
tcwl = 3; /* CWL 8 */
|
||||||
|
t_rdata_en = 5;
|
||||||
|
tdinit0 = (200 * CONFIG_DRAM_CLK) + 1; /* 200us */
|
||||||
|
tdinit1 = (100 * CONFIG_DRAM_CLK) / 1000 + 1; /* 100ns */
|
||||||
|
tdinit2 = (11 * CONFIG_DRAM_CLK) + 1; /* 200us */
|
||||||
|
tdinit3 = (1 * CONFIG_DRAM_CLK) + 1; /* 1us */
|
||||||
|
twtp = tcwl + 4 + twr + 1; /* CWL + BL/2 + tWR */
|
||||||
|
twr2rd = tcwl + 4 + 1 + twtr; /* WL + BL / 2 + tWTR */
|
||||||
|
trd2wr = tcl + 4 + 5 - tcwl + 1; /* RL + BL / 2 + 2 - WL */
|
||||||
|
}
|
||||||
/* Set dram timing */
|
/* Set dram timing */
|
||||||
reg_val = (twtp << 24) | (tfaw << 16) | (trasmax << 8) | (tras << 0);
|
reg_val = (twtp << 24) | (tfaw << 16) | (trasmax << 8) | (tras << 0);
|
||||||
writel(reg_val, &mctl_ctl->dramtmg0);
|
writel(reg_val, &mctl_ctl->dramtmg0);
|
||||||
@@ -289,6 +321,9 @@ static int mctl_channel_init(struct dram_para *para)
|
|||||||
clrbits_le32(&mctl_ctl->pgcr2, (0x3 << 6));
|
clrbits_le32(&mctl_ctl->pgcr2, (0x3 << 6));
|
||||||
clrbits_le32(&mctl_ctl->dqsgmr, (0x1 << 8) | (0x7));
|
clrbits_le32(&mctl_ctl->dqsgmr, (0x1 << 8) | (0x7));
|
||||||
|
|
||||||
|
if (para->dram_type == DRAM_TYPE_LPDDR3)
|
||||||
|
clrsetbits_le32(&mctl_ctl->dxccr, (0x1 << 27) | (0x3<<6) ,
|
||||||
|
0x1 << 31);
|
||||||
if (readl(&mctl_com->cr) & 0x1)
|
if (readl(&mctl_com->cr) & 0x1)
|
||||||
writel(0x00000303, &mctl_ctl->odtmap);
|
writel(0x00000303, &mctl_ctl->odtmap);
|
||||||
else
|
else
|
||||||
@@ -299,7 +334,11 @@ static int mctl_channel_init(struct dram_para *para)
|
|||||||
clrsetbits_le32(ZQnPR(0), 0x000000ff, CONFIG_DRAM_ZQ & 0xff);
|
clrsetbits_le32(ZQnPR(0), 0x000000ff, CONFIG_DRAM_ZQ & 0xff);
|
||||||
clrsetbits_le32(ZQnPR(1), 0x000000ff, (CONFIG_DRAM_ZQ >> 8) & 0xff);
|
clrsetbits_le32(ZQnPR(1), 0x000000ff, (CONFIG_DRAM_ZQ >> 8) & 0xff);
|
||||||
/* CA calibration */
|
/* CA calibration */
|
||||||
mctl_set_pir(0x0201f3 | 0x1<<10);
|
|
||||||
|
if (para->dram_type == DRAM_TYPE_DDR3)
|
||||||
|
mctl_set_pir(0x0201f3 | 0x1<<10);
|
||||||
|
else
|
||||||
|
mctl_set_pir(0x020173 | 0x1<<10);
|
||||||
|
|
||||||
/* DQS gate training */
|
/* DQS gate training */
|
||||||
if (mctl_train_dram(para) != 0) {
|
if (mctl_train_dram(para) != 0) {
|
||||||
@@ -359,6 +398,7 @@ static void mctl_sys_init(struct dram_para *para)
|
|||||||
clrbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL);
|
clrbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL);
|
||||||
clrbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MCTL);
|
clrbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MCTL);
|
||||||
clrbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_EN);
|
clrbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_EN);
|
||||||
|
udelay(1000);
|
||||||
clrbits_le32(&ccm->dram_clk_cfg, 0x01<<31);
|
clrbits_le32(&ccm->dram_clk_cfg, 0x01<<31);
|
||||||
|
|
||||||
clock_set_pll5(CONFIG_DRAM_CLK * 1000000 * DRAM_CLK_MUL);
|
clock_set_pll5(CONFIG_DRAM_CLK * 1000000 * DRAM_CLK_MUL);
|
||||||
@@ -373,6 +413,10 @@ static void mctl_sys_init(struct dram_para *para)
|
|||||||
setbits_le32(&ccm->mbus_reset, CCM_MBUS_RESET_RESET);
|
setbits_le32(&ccm->mbus_reset, CCM_MBUS_RESET_RESET);
|
||||||
setbits_le32(&ccm->mbus_clk_cfg, MBUS_CLK_GATE);
|
setbits_le32(&ccm->mbus_clk_cfg, MBUS_CLK_GATE);
|
||||||
|
|
||||||
|
para->rank = 2;
|
||||||
|
para->bus_width = 16;
|
||||||
|
mctl_set_cr(para);
|
||||||
|
|
||||||
/* Set dram master access priority */
|
/* Set dram master access priority */
|
||||||
writel(0x0000e00f, &mctl_ctl->clken); /* normal */
|
writel(0x0000e00f, &mctl_ctl->clken); /* normal */
|
||||||
|
|
||||||
|
|||||||
@@ -198,6 +198,11 @@ struct sunxi_mctl_ctl_reg {
|
|||||||
#define MCTL_MR2 0x18 /* CWL=8 */
|
#define MCTL_MR2 0x18 /* CWL=8 */
|
||||||
#define MCTL_MR3 0x0
|
#define MCTL_MR3 0x0
|
||||||
|
|
||||||
|
#define MCTL_LPDDR3_MR0 0x0
|
||||||
|
#define MCTL_LPDDR3_MR1 0xc3 /* twr=8, bl=8 */
|
||||||
|
#define MCTL_LPDDR3_MR2 0xa /* RL=12, CWL=6 */
|
||||||
|
#define MCTL_LPDDR3_MR3 0x0
|
||||||
|
|
||||||
#define DRAM_TYPE_DDR3 3
|
#define DRAM_TYPE_DDR3 3
|
||||||
#define DRAM_TYPE_LPDDR3 7
|
#define DRAM_TYPE_LPDDR3 7
|
||||||
#endif /* _SUNXI_DRAM_SUN8I_A83T_H */
|
#endif /* _SUNXI_DRAM_SUN8I_A83T_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user