diff options
author | Siarhei Siamashka <siarhei.siamashka@gmail.com> | 2014-08-03 05:32:40 +0300 |
---|---|---|
committer | Hans de Goede <hdegoede@redhat.com> | 2014-08-12 08:42:32 +0200 |
commit | f2577967738f923571b7156ad46ef91d9fa8d9f8 (patch) | |
tree | bd3294c579c93cd06d2f1bb03b776d0605ddeaee /arch/arm/cpu/armv7/sunxi | |
parent | 34759d74a386ec82af946c2858935af9327a9f8a (diff) | |
download | u-boot-imx-f2577967738f923571b7156ad46ef91d9fa8d9f8.zip u-boot-imx-f2577967738f923571b7156ad46ef91d9fa8d9f8.tar.gz u-boot-imx-f2577967738f923571b7156ad46ef91d9fa8d9f8.tar.bz2 |
sunxi: dram: Remove broken super-standby remnants
If the dram->ppwrsctl (SDR_DPCR) register has the lowest bit set to 1,
this means that DRAM is currently in self-refresh mode and retaining the
old data. Since we have no idea what to do in this situation yet, just
set this register to 0 and initialize DRAM in the same way as on any
normal reboot (discarding whatever was stored there).
This part of code was apparently used by the Allwinner boot0 bootloader
to handle resume from the so-called super-standby mode. But this
particular code got somehow mangled on the way from the boot0 bootloader
to the u-boot-sunxi bootloader and has no chance of doing anything even
remotely sane. For example:
1. in the original boot0 code we had "mctl_write_w(SDR_DPCR,
0x16510000)" (write to the register) and in the u-boot it now looks
like "setbits_le32(&dram->ppwrsctl, 0x16510000)" (set bits in the
register)
2. in the original boot0 code it was issuing three commands "0x12, 0x17,
0x13" (Self-Refresh entry, Self-Refresh exit, Refresh), but in the
u-boot they have become "0x12, 0x12, 0x13" (Self-Refresh entry,
Self-Refresh entry, Refresh)
Signed-off-by: Siarhei Siamashka <siarhei.siamashka@gmail.com>
Acked-by: Ian Campbell <ijc@hellion.org.uk>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Diffstat (limited to 'arch/arm/cpu/armv7/sunxi')
-rw-r--r-- | arch/arm/cpu/armv7/sunxi/dram.c | 66 |
1 files changed, 20 insertions, 46 deletions
diff --git a/arch/arm/cpu/armv7/sunxi/dram.c b/arch/arm/cpu/armv7/sunxi/dram.c index 236eed7..dc79d1c 100644 --- a/arch/arm/cpu/armv7/sunxi/dram.c +++ b/arch/arm/cpu/armv7/sunxi/dram.c @@ -359,6 +359,24 @@ static void dramc_set_autorefresh_cycle(u32 clk, u32 type, u32 density) writel(DRAM_DRR_TREFI(tREFI) | DRAM_DRR_TRFC(tRFC), &dram->drr); } +/* + * If the dram->ppwrsctl (SDR_DPCR) register has the lowest bit set to 1, this + * means that DRAM is currently in self-refresh mode and retaining the old + * data. Since we have no idea what to do in this situation yet, just set this + * register to 0 and initialize DRAM in the same way as on any normal reboot + * (discarding whatever was stored there). + * + * Note: on sun7i hardware, the highest 16 bits need to be set to 0x1651 magic + * value for this write operation to have any effect. On sun5i hadware this + * magic value is not necessary. And on sun4i hardware the writes to this + * register seem to have no effect at all. + */ +static void mctl_disable_power_save(void) +{ + struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; + writel(0x16510000, &dram->ppwrsctl); +} + unsigned long dramc_init(struct dram_para *para) { struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; @@ -373,10 +391,8 @@ unsigned long dramc_init(struct dram_para *para) /* setup DRAM relative clock */ mctl_setup_dram_clock(para->clock); -#ifdef CONFIG_SUN5I /* Disable any pad power save control */ - writel(0, &dram->ppwrsctl); -#endif + mctl_disable_power_save(); /* reset external DRAM */ #ifndef CONFIG_SUN7I @@ -444,10 +460,7 @@ unsigned long dramc_init(struct dram_para *para) #endif #ifdef CONFIG_SUN7I - if ((readl(&dram->ppwrsctl) & 0x1) != 0x1) - mctl_ddr3_reset(); - else - setbits_le32(&dram->mcr, DRAM_MCR_RESET); + mctl_ddr3_reset(); #else /* dram clock on */ dramc_clock_output_en(1); @@ -513,45 +526,6 @@ unsigned long dramc_init(struct dram_para *para) setbits_le32(&dram->ccr, DRAM_CCR_INIT); await_completion(&dram->ccr, DRAM_CCR_INIT); -#ifdef CONFIG_SUN7I - /* setup zq calibration manual */ - reg_val = readl(&dram->ppwrsctl); - if ((reg_val & 0x1) == 1) { - /* super_standby_flag = 1 */ - - reg_val = readl(0x01c20c00 + 0x120); /* rtc */ - reg_val &= 0x000fffff; - reg_val |= 0x17b00000; - writel(reg_val, &dram->zqcr0); - - /* exit self-refresh state */ - clrsetbits_le32(&dram->dcr, 0x1f << 27, 0x12 << 27); - /* check whether command has been executed */ - await_completion(&dram->dcr, 0x1 << 31); - - udelay(2); - - /* dram pad hold off */ - setbits_le32(&dram->ppwrsctl, 0x16510000); - - await_completion(&dram->ppwrsctl, 0x1); - - /* exit self-refresh state */ - clrsetbits_le32(&dram->dcr, 0x1f << 27, 0x12 << 27); - - /* check whether command has been executed */ - await_completion(&dram->dcr, 0x1 << 31); - - udelay(2); - - /* issue a refresh command */ - clrsetbits_le32(&dram->dcr, 0x1f << 27, 0x13 << 27); - await_completion(&dram->dcr, 0x1 << 31); - - udelay(2); - } -#endif - /* scan read pipe value */ mctl_itm_enable(); ret_val = dramc_scan_readpipe(); |