|
|
|
@ -177,6 +177,34 @@ static void mctl_set_master_priority_a64(void) |
|
|
|
|
writel(0x81000004, &mctl_com->mdfs_bwlr[2]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void mctl_set_master_priority_h5(void) |
|
|
|
|
{ |
|
|
|
|
struct sunxi_mctl_com_reg * const mctl_com = |
|
|
|
|
(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE; |
|
|
|
|
|
|
|
|
|
/* enable bandwidth limit windows and set windows size 1us */ |
|
|
|
|
writel(399, &mctl_com->tmr); |
|
|
|
|
writel((1 << 16), &mctl_com->bwcr); |
|
|
|
|
|
|
|
|
|
/* set cpu high priority */ |
|
|
|
|
writel(0x00000001, &mctl_com->mapr); |
|
|
|
|
|
|
|
|
|
/* Port 2 is reserved per Allwinner's linux-3.10 source, yet
|
|
|
|
|
* they initialise it */ |
|
|
|
|
MBUS_CONF( CPU, true, HIGHEST, 0, 300, 260, 150); |
|
|
|
|
MBUS_CONF( GPU, true, HIGHEST, 0, 600, 400, 200); |
|
|
|
|
MBUS_CONF(UNUSED, true, HIGHEST, 0, 512, 256, 96); |
|
|
|
|
MBUS_CONF( DMA, true, HIGHEST, 0, 256, 128, 32); |
|
|
|
|
MBUS_CONF( VE, true, HIGHEST, 0, 1900, 1500, 1000); |
|
|
|
|
MBUS_CONF( CSI, true, HIGHEST, 0, 150, 120, 100); |
|
|
|
|
MBUS_CONF( NAND, true, HIGH, 0, 256, 128, 64); |
|
|
|
|
MBUS_CONF( SS, true, HIGHEST, 0, 256, 128, 64); |
|
|
|
|
MBUS_CONF( TS, true, HIGHEST, 0, 256, 128, 64); |
|
|
|
|
MBUS_CONF( DI, true, HIGH, 0, 1024, 256, 64); |
|
|
|
|
MBUS_CONF( DE, true, HIGHEST, 3, 3400, 2400, 1024); |
|
|
|
|
MBUS_CONF(DE_CFD, true, HIGHEST, 0, 600, 400, 200); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void mctl_set_master_priority(uint16_t socid) |
|
|
|
|
{ |
|
|
|
|
switch (socid) { |
|
|
|
@ -186,6 +214,9 @@ static void mctl_set_master_priority(uint16_t socid) |
|
|
|
|
case SOCID_A64: |
|
|
|
|
mctl_set_master_priority_a64(); |
|
|
|
|
return; |
|
|
|
|
case SOCID_H5: |
|
|
|
|
mctl_set_master_priority_h5(); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -256,7 +287,7 @@ static void mctl_set_timing_params(uint16_t socid, struct dram_para *para) |
|
|
|
|
|
|
|
|
|
/* set two rank timing */ |
|
|
|
|
clrsetbits_le32(&mctl_ctl->dramtmg[8], (0xff << 8) | (0xff << 0), |
|
|
|
|
(0x66 << 8) | (0x10 << 0)); |
|
|
|
|
((socid == SOCID_H5 ? 0x33 : 0x66) << 8) | (0x10 << 0)); |
|
|
|
|
|
|
|
|
|
/* set PHY interface timing, write latency and read latency configure */ |
|
|
|
|
writel((0x2 << 24) | (t_rdata_en << 16) | (0x1 << 8) | |
|
|
|
@ -391,7 +422,7 @@ static void mctl_sys_init(uint16_t socid, struct dram_para *para) |
|
|
|
|
CCM_DRAMCLK_CFG_DIV(1) | |
|
|
|
|
CCM_DRAMCLK_CFG_SRC_PLL11 | |
|
|
|
|
CCM_DRAMCLK_CFG_UPD); |
|
|
|
|
} else if (socid == SOCID_H3) { |
|
|
|
|
} else if (socid == SOCID_H3 || socid == SOCID_H5) { |
|
|
|
|
clock_set_pll5(CONFIG_DRAM_CLK * 2 * 1000000, false); |
|
|
|
|
clrsetbits_le32(&ccm->dram_clk_cfg, |
|
|
|
|
CCM_DRAMCLK_CFG_DIV_MASK | |
|
|
|
@ -410,7 +441,7 @@ static void mctl_sys_init(uint16_t socid, struct dram_para *para) |
|
|
|
|
setbits_le32(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_RST); |
|
|
|
|
udelay(10); |
|
|
|
|
|
|
|
|
|
writel(0xc00e, &mctl_ctl->clken); |
|
|
|
|
writel(socid == SOCID_H5 ? 0x8000 : 0xc00e, &mctl_ctl->clken); |
|
|
|
|
udelay(500); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -434,7 +465,10 @@ static int mctl_channel_init(uint16_t socid, struct dram_para *para) |
|
|
|
|
|
|
|
|
|
/* setting VTC, default disable all VT */ |
|
|
|
|
clrbits_le32(&mctl_ctl->pgcr[0], (1 << 30) | 0x3f); |
|
|
|
|
clrsetbits_le32(&mctl_ctl->pgcr[1], 1 << 24, 1 << 26); |
|
|
|
|
if (socid == SOCID_H5) |
|
|
|
|
setbits_le32(&mctl_ctl->pgcr[1], (1 << 24) | (1 << 26)); |
|
|
|
|
else |
|
|
|
|
clrsetbits_le32(&mctl_ctl->pgcr[1], 1 << 24, 1 << 26); |
|
|
|
|
|
|
|
|
|
/* increase DFI_PHY_UPD clock */ |
|
|
|
|
writel(PROTECT_MAGIC, &mctl_com->protect); |
|
|
|
@ -444,15 +478,22 @@ static int mctl_channel_init(uint16_t socid, struct dram_para *para) |
|
|
|
|
udelay(100); |
|
|
|
|
|
|
|
|
|
/* set dramc odt */ |
|
|
|
|
for (i = 0; i < 4; i++) |
|
|
|
|
clrsetbits_le32(&mctl_ctl->dx[i].gcr, (0x3 << 4) | |
|
|
|
|
(0x1 << 1) | (0x3 << 2) | (0x3 << 12) | |
|
|
|
|
(0x3 << 14), |
|
|
|
|
IS_ENABLED(CONFIG_DRAM_ODT_EN) ? |
|
|
|
|
DX_GCR_ODT_DYNAMIC : DX_GCR_ODT_OFF); |
|
|
|
|
for (i = 0; i < 4; i++) { |
|
|
|
|
u32 clearmask = (0x3 << 4) | (0x1 << 1) | (0x3 << 2) | |
|
|
|
|
(0x3 << 12) | (0x3 << 14); |
|
|
|
|
u32 setmask = IS_ENABLED(CONFIG_DRAM_ODT_EN) ? |
|
|
|
|
DX_GCR_ODT_DYNAMIC : DX_GCR_ODT_OFF; |
|
|
|
|
|
|
|
|
|
if (socid == SOCID_H5) { |
|
|
|
|
clearmask |= 0x2 << 8; |
|
|
|
|
setmask |= 0x4 << 8; |
|
|
|
|
} |
|
|
|
|
clrsetbits_le32(&mctl_ctl->dx[i].gcr, clearmask, setmask); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* AC PDR should always ON */ |
|
|
|
|
setbits_le32(&mctl_ctl->aciocr, 0x1 << 1); |
|
|
|
|
clrsetbits_le32(&mctl_ctl->aciocr, socid == SOCID_H5 ? (0x1 << 11) : 0, |
|
|
|
|
0x1 << 1); |
|
|
|
|
|
|
|
|
|
/* set DQS auto gating PD mode */ |
|
|
|
|
setbits_le32(&mctl_ctl->pgcr[2], 0x3 << 6); |
|
|
|
@ -464,7 +505,7 @@ static int mctl_channel_init(uint16_t socid, struct dram_para *para) |
|
|
|
|
/* dphy & aphy phase select 270 degree */ |
|
|
|
|
clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8), |
|
|
|
|
(0x1 << 10) | (0x2 << 8)); |
|
|
|
|
} else if (socid == SOCID_A64) { |
|
|
|
|
} else if (socid == SOCID_A64 || socid == SOCID_H5) { |
|
|
|
|
/* dphy & aphy phase select ? */ |
|
|
|
|
clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8), |
|
|
|
|
(0x0 << 10) | (0x3 << 8)); |
|
|
|
@ -488,11 +529,12 @@ static int mctl_channel_init(uint16_t socid, struct dram_para *para) |
|
|
|
|
|
|
|
|
|
mctl_phy_init(PIR_PLLINIT | PIR_DCAL | PIR_PHYRST | |
|
|
|
|
PIR_DRAMRST | PIR_DRAMINIT | PIR_QSGATE); |
|
|
|
|
} else if (socid == SOCID_A64) { |
|
|
|
|
} else if (socid == SOCID_A64 || socid == SOCID_H5) { |
|
|
|
|
clrsetbits_le32(&mctl_ctl->zqcr, 0xffffff, CONFIG_DRAM_ZQ); |
|
|
|
|
|
|
|
|
|
mctl_phy_init(PIR_ZCAL | PIR_PLLINIT | PIR_DCAL | PIR_PHYRST | |
|
|
|
|
PIR_DRAMRST | PIR_DRAMINIT | PIR_QSGATE); |
|
|
|
|
/* no PIR_QSGATE for H5 ???? */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* detect ranks and bus width */ |
|
|
|
@ -533,7 +575,7 @@ static int mctl_channel_init(uint16_t socid, struct dram_para *para) |
|
|
|
|
/* set PGCR3, CKE polarity */ |
|
|
|
|
if (socid == SOCID_H3) |
|
|
|
|
writel(0x00aa0060, &mctl_ctl->pgcr[3]); |
|
|
|
|
else if (socid == SOCID_A64) |
|
|
|
|
else if (socid == SOCID_A64 || socid == SOCID_H5) |
|
|
|
|
writel(0xc0aa0060, &mctl_ctl->pgcr[3]); |
|
|
|
|
|
|
|
|
|
/* power down zq calibration module for power save */ |
|
|
|
@ -604,6 +646,22 @@ static void mctl_auto_detect_dram_size(struct dram_para *para) |
|
|
|
|
3, 4, 0, 3, 4, 1, 4, 0, \
|
|
|
|
|
1, 1, 0, 1, 13, 5, 4 } |
|
|
|
|
|
|
|
|
|
#define SUN8I_H5_DX_READ_DELAYS \ |
|
|
|
|
{{ 14, 15, 17, 17, 17, 17, 17, 18, 17, 3, 3 }, \
|
|
|
|
|
{ 21, 21, 12, 22, 21, 21, 21, 21, 21, 3, 3 }, \
|
|
|
|
|
{ 16, 19, 19, 17, 22, 22, 21, 22, 19, 3, 3 }, \
|
|
|
|
|
{ 21, 21, 22, 22, 20, 21, 19, 19, 19, 3, 3 } } |
|
|
|
|
#define SUN8I_H5_DX_WRITE_DELAYS \ |
|
|
|
|
{{ 1, 2, 3, 4, 3, 4, 4, 4, 6, 6, 6 }, \
|
|
|
|
|
{ 6, 6, 6, 5, 5, 5, 5, 5, 6, 6, 6 }, \
|
|
|
|
|
{ 0, 2, 4, 2, 6, 5, 5, 5, 6, 6, 6 }, \
|
|
|
|
|
{ 3, 3, 3, 2, 2, 1, 1, 1, 4, 4, 4 } } |
|
|
|
|
#define SUN8I_H5_AC_DELAYS \ |
|
|
|
|
{ 0, 0, 5, 5, 0, 0, 0, 0, \
|
|
|
|
|
0, 0, 0, 0, 3, 3, 3, 3, \
|
|
|
|
|
3, 3, 3, 3, 3, 3, 3, 3, \
|
|
|
|
|
3, 3, 3, 3, 2, 0, 0 } |
|
|
|
|
|
|
|
|
|
unsigned long sunxi_dram_init(void) |
|
|
|
|
{ |
|
|
|
|
struct sunxi_mctl_com_reg * const mctl_com = |
|
|
|
@ -625,6 +683,10 @@ unsigned long sunxi_dram_init(void) |
|
|
|
|
.dx_read_delays = SUN50I_A64_DX_READ_DELAYS, |
|
|
|
|
.dx_write_delays = SUN50I_A64_DX_WRITE_DELAYS, |
|
|
|
|
.ac_delays = SUN50I_A64_AC_DELAYS, |
|
|
|
|
#elif defined(CONFIG_MACH_SUN50I_H5) |
|
|
|
|
.dx_read_delays = SUN8I_H5_DX_READ_DELAYS, |
|
|
|
|
.dx_write_delays = SUN8I_H5_DX_WRITE_DELAYS, |
|
|
|
|
.ac_delays = SUN8I_H5_AC_DELAYS, |
|
|
|
|
#endif |
|
|
|
|
}; |
|
|
|
|
/*
|
|
|
|
@ -636,6 +698,8 @@ unsigned long sunxi_dram_init(void) |
|
|
|
|
uint16_t socid = SOCID_H3; |
|
|
|
|
#elif defined(CONFIG_MACH_SUN50I) |
|
|
|
|
uint16_t socid = SOCID_A64; |
|
|
|
|
#elif defined(CONFIG_MACH_SUN50I_H5) |
|
|
|
|
uint16_t socid = SOCID_H5; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
mctl_sys_init(socid, ¶); |
|
|
|
@ -652,8 +716,9 @@ unsigned long sunxi_dram_init(void) |
|
|
|
|
if (socid == SOCID_H3) |
|
|
|
|
writel(0x0c000400, &mctl_ctl->odtcfg); |
|
|
|
|
|
|
|
|
|
if (socid == SOCID_A64) { |
|
|
|
|
setbits_le32(&mctl_ctl->vtfcr, 2 << 8); |
|
|
|
|
if (socid == SOCID_A64 || socid == SOCID_H5) { |
|
|
|
|
setbits_le32(&mctl_ctl->vtfcr, |
|
|
|
|
(socid == SOCID_H5 ? 3 : 2) << 8); |
|
|
|
|
clrbits_le32(&mctl_ctl->pgcr[2], (1 << 13)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|