summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorMarek Vasut <marex@denx.de>2020-05-30 02:14:48 +0200
committerStefano Babic <sbabic@denx.de>2020-06-08 10:42:54 +0200
commit0e06d63d195670f5181958f43216d7106c05357f (patch)
tree2f4e9d5515b5db81a3f9a09c64a1e18d81832bda /arch
parent661d9afe1429e28adcaacd277ab9f28e3790e93f (diff)
ARM: imx: ddr: Add missing PHY reset
The iMX7D RM 9.2.4.9.3 Power removal flow Table 9-11. Re-enabling power explicitly says both the DDR controller and the PHY must be reset in the correct sequence. Currently the code only resets the controller. This leads to a misbehavior where the system brings the DRAM up after reboot, but the DRAM is unstable. Add the missing reset. The easiest way to trigger this is by triggering WDT without having the WDT assert WDOG_B signal, i.e. mw.w 0x30280000 0x25 . Signed-off-by: Marek Vasut <marex@denx.de> Cc: Fabio Estevam <festevam@gmail.com> Cc: NXP i.MX U-Boot Team <uboot-imx@nxp.com> Cc: Peng Fan <peng.fan@nxp.com> Cc: Stefano Babic <sbabic@denx.de>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/include/asm/arch-mx7/imx-regs.h1
-rw-r--r--arch/arm/mach-imx/mx7/ddr.c22
2 files changed, 20 insertions, 3 deletions
diff --git a/arch/arm/include/asm/arch-mx7/imx-regs.h b/arch/arm/include/asm/arch-mx7/imx-regs.h
index 95238dcaa8..f37419c07f 100644
--- a/arch/arm/include/asm/arch-mx7/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx7/imx-regs.h
@@ -274,6 +274,7 @@ struct src {
#define SRC_DDRC_RCR_DDRC_CORE_RST_OFFSET 1
#define SRC_DDRC_RCR_DDRC_CORE_RST_MASK (1 << 1)
+#define SRC_DDRC_RCR_DDRC_PRST_MASK (1 << 0)
/* GPR0 Bit Fields */
#define IOMUXC_GPR_GPR0_DMAREQ_MUX_SEL0_MASK 0x1u
diff --git a/arch/arm/mach-imx/mx7/ddr.c b/arch/arm/mach-imx/mx7/ddr.c
index 9713835bf2..d1e10a6788 100644
--- a/arch/arm/mach-imx/mx7/ddr.c
+++ b/arch/arm/mach-imx/mx7/ddr.c
@@ -13,6 +13,7 @@
#include <asm/arch/crm_regs.h>
#include <asm/arch/mx7-ddr.h>
#include <common.h>
+#include <linux/delay.h>
/*
* Routine: mx7_dram_cfg
@@ -37,8 +38,23 @@ void mx7_dram_cfg(struct ddrc *ddrc_regs_val, struct ddrc_mp *ddrc_mp_val,
(struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR;
int i;
- /* Assert DDR Controller preset and DDR PHY reset */
- writel(SRC_DDRC_RCR_DDRC_CORE_RST_MASK, &src_regs->ddrc_rcr);
+ /*
+ * iMX7D RM 9.2.4.9.3 Power removal flow Table 9-11. Re-enabling power
+ * row 2 says "Reset controller / PHY by driving core_ddrc_rst = 0 ,
+ * aresetn_n = 0, presetn = 0. That means reset everything.
+ */
+ writel(SRC_DDRC_RCR_DDRC_CORE_RST_MASK | SRC_DDRC_RCR_DDRC_PRST_MASK,
+ &src_regs->ddrc_rcr);
+
+ /*
+ * iMX7D RM 6.2.7.26 SRC_DDRC_RCR says wait 30 cycles (of unknown).
+ * If we assume this is 30 cycles at 100 MHz (about the rate of a
+ * DRAM bus), that's 300 nS, so waiting 10 uS is more then plenty.
+ */
+ udelay(10);
+
+ /* De-assert DDR Controller 'preset' and DDR PHY reset */
+ clrbits_le32(&src_regs->ddrc_rcr, SRC_DDRC_RCR_DDRC_PRST_MASK);
/* DDR controller configuration */
writel(ddrc_regs_val->mstr, &ddrc_regs->mstr);
@@ -71,7 +87,7 @@ void mx7_dram_cfg(struct ddrc *ddrc_regs_val, struct ddrc_mp *ddrc_mp_val,
writel(ddrc_regs_val->odtcfg, &ddrc_regs->odtcfg);
writel(ddrc_regs_val->odtmap, &ddrc_regs->odtmap);
- /* De-assert DDR Controller preset and DDR PHY reset */
+ /* De-assert DDR Controller 'core_ddrc_rstn' and 'aresetn' */
clrbits_le32(&src_regs->ddrc_rcr, SRC_DDRC_RCR_DDRC_CORE_RST_MASK);
/* PHY configuration */