All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 0/3] mx6: ddr: updates for dynamic DDR calibration
@ 2016-10-30 17:18 Eric Nelson
  2016-10-30 17:19 ` [U-Boot] [PATCH 1/3] mx6: ddr: allow 32 cycles for DQS gating calibration Eric Nelson
                   ` (2 more replies)
  0 siblings, 3 replies; 44+ messages in thread
From: Eric Nelson @ 2016-10-30 17:18 UTC (permalink / raw)
  To: u-boot

This set of patches updates the interface to the DDR calibration in 
preparation for the addition of a pseudo-board for calibration on
i.MX6.

The first patch fixes an ommission in the use of the DG_CMP_CYC flag
in register MPDGCTRL0.

The second patch cleans up the handling of bus widths by passing
the system configuration information to the calibration routines.

The third routine adds support for returning the calibration data
written to the MMDC registers.

Eric Nelson (3):
  mx6: ddr: allow 32 cycles for DQS gating calibration
  mx6: ddr: pass mx6_ddr_sysinfo to calibration routines
  mx6: ddr: add mmdc_read_calibration routine to return dynamic data

 arch/arm/cpu/armv7/mx6/ddr.c            | 128 +++++++++++++++++++++-----------
 arch/arm/include/asm/arch-mx6/mx6-ddr.h |   6 +-
 board/kosagi/novena/novena_spl.c        |   4 +-
 3 files changed, 92 insertions(+), 46 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [U-Boot] [PATCH 1/3] mx6: ddr: allow 32 cycles for DQS gating calibration
  2016-10-30 17:18 [U-Boot] [PATCH 0/3] mx6: ddr: updates for dynamic DDR calibration Eric Nelson
@ 2016-10-30 17:19 ` Eric Nelson
  2016-10-30 17:27   ` Marek Vasut
  2016-10-30 17:19 ` [U-Boot] [PATCH 2/3] mx6: ddr: pass mx6_ddr_sysinfo to calibration routines Eric Nelson
  2016-10-30 17:19 ` [U-Boot] [PATCH 3/3] mx6: ddr: add routine to return DDR calibration data Eric Nelson
  2 siblings, 1 reply; 44+ messages in thread
From: Eric Nelson @ 2016-10-30 17:19 UTC (permalink / raw)
  To: u-boot

The DDR calibration code is only setting flag DG_CMP_CYC (DQS gating sample
cycle) for the first PHY.

Set the 32-cycle flag for both PHYs and clear when done so the MPDGCTRL0
output value isn't polluted with calibration artifacts.

Signed-off-by: Eric Nelson <eric@nelint.com>
---
 arch/arm/cpu/armv7/mx6/ddr.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c
index 7beb7ea..b15f376 100644
--- a/arch/arm/cpu/armv7/mx6/ddr.c
+++ b/arch/arm/cpu/armv7/mx6/ddr.c
@@ -347,6 +347,8 @@ int mmdc_do_dqs_calibration(void)
 	 * 16 before comparing read data.
 	 */
 	setbits_le32(&mmdc0->mpdgctrl0, 1 << 30);
+	if (sysinfo->dsize == 2)
+		setbits_le32(&mmdc1->mpdgctrl0, 1 << 30);
 
 	/* Set bit 28 to start automatic read DQS gating calibration */
 	setbits_le32(&mmdc0->mpdgctrl0, 5 << 28);
@@ -365,6 +367,11 @@ int mmdc_do_dqs_calibration(void)
 	if ((bus_size == 0x2) && (readl(&mmdc1->mpdgctrl0) & 0x00001000))
 		errors |= 2;
 
+	/* now disable mpdgctrl0[DG_CMP_CYC] */
+	clrbits_le32(&mmdc0->mpdgctrl0, 1 << 30);
+	if (sysinfo->dsize == 2)
+		clrbits_le32(&mmdc1->mpdgctrl0, 1 << 30);
+
 	/*
 	 * DQS gating absolute offset should be modified from
 	 * reflecting (HW_DG_LOWx + HW_DG_UPx)/2 to
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [U-Boot] [PATCH 2/3] mx6: ddr: pass mx6_ddr_sysinfo to calibration routines
  2016-10-30 17:18 [U-Boot] [PATCH 0/3] mx6: ddr: updates for dynamic DDR calibration Eric Nelson
  2016-10-30 17:19 ` [U-Boot] [PATCH 1/3] mx6: ddr: allow 32 cycles for DQS gating calibration Eric Nelson
@ 2016-10-30 17:19 ` Eric Nelson
  2016-10-30 17:29   ` Marek Vasut
  2016-10-30 17:19 ` [U-Boot] [PATCH 3/3] mx6: ddr: add routine to return DDR calibration data Eric Nelson
  2 siblings, 1 reply; 44+ messages in thread
From: Eric Nelson @ 2016-10-30 17:19 UTC (permalink / raw)
  To: u-boot

The DDR calibration routines have scattered support for bus
widths other than 64-bits:

-- The mmdc_do_write_level_calibration() routine assumes the
presence of PHY1, and
-- The mmdc_do_dqs_calibration() routine tries to determine
whether one or two DDR PHYs are active by reading MDCTL.

Since a caller of these routines must have a valid struct mx6_ddr_sysinfo
for use in calling mx6_dram_cfg(), and the bus width is available in the
"dsize" field, use this structure to inform the calibration routines which
PHYs are active.

This allows the use of the DDR calibration routines on CPU variants
like i.MX6SL that only have a single MMDC port.

Signed-off-by: Eric Nelson <eric@nelint.com>
---
 arch/arm/cpu/armv7/mx6/ddr.c            | 98 +++++++++++++++++++--------------
 arch/arm/include/asm/arch-mx6/mx6-ddr.h |  4 +-
 board/kosagi/novena/novena_spl.c        |  4 +-
 3 files changed, 60 insertions(+), 46 deletions(-)

diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c
index b15f376..274a0ba 100644
--- a/arch/arm/cpu/armv7/mx6/ddr.c
+++ b/arch/arm/cpu/armv7/mx6/ddr.c
@@ -86,14 +86,15 @@ static void modify_dg_result(u32 *reg_st0, u32 *reg_st1, u32 *reg_ctrl)
 	writel(val_ctrl, reg_ctrl);
 }
 
-int mmdc_do_write_level_calibration(void)
+int mmdc_do_write_level_calibration(struct mx6_ddr_sysinfo const *sysinfo)
 {
 	struct mmdc_p_regs *mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR;
 	struct mmdc_p_regs *mmdc1 = (struct mmdc_p_regs *)MMDC_P1_BASE_ADDR;
 	u32 esdmisc_val, zq_val;
 	u32 errors = 0;
-	u32 ldectrl[4];
+	u32 ldectrl[4] = {0};
 	u32 ddr_mr1 = 0x4;
+	u32 rwalat_max;
 
 	/*
 	 * Stash old values in case calibration fails,
@@ -101,8 +102,10 @@ int mmdc_do_write_level_calibration(void)
 	 */
 	ldectrl[0] = readl(&mmdc0->mpwldectrl0);
 	ldectrl[1] = readl(&mmdc0->mpwldectrl1);
-	ldectrl[2] = readl(&mmdc1->mpwldectrl0);
-	ldectrl[3] = readl(&mmdc1->mpwldectrl1);
+	if (sysinfo->dsize == 2) {
+		ldectrl[2] = readl(&mmdc1->mpwldectrl0);
+		ldectrl[3] = readl(&mmdc1->mpwldectrl1);
+	}
 
 	/* disable DDR logic power down timer */
 	clrbits_le32(&mmdc0->mdpdc, 0xff00);
@@ -122,10 +125,10 @@ int mmdc_do_write_level_calibration(void)
 	writel(zq_val & ~0x3, &mmdc0->mpzqhwctrl);
 
 	/* 3. increase walat and ralat to maximum */
-	setbits_le32(&mmdc0->mdmisc,
-		     (1 << 6) | (1 << 7) | (1 << 8) | (1 << 16) | (1 << 17));
-	setbits_le32(&mmdc1->mdmisc,
-		     (1 << 6) | (1 << 7) | (1 << 8) | (1 << 16) | (1 << 17));
+	rwalat_max = (1 << 6) | (1 << 7) | (1 << 8) | (1 << 16) | (1 << 17);
+	setbits_le32(&mmdc0->mdmisc, rwalat_max);
+	if (sysinfo->dsize == 2)
+		setbits_le32(&mmdc1->mdmisc, rwalat_max);
 	/*
 	 * 4 & 5. Configure the external DDR device to enter write-leveling
 	 * mode through Load Mode Register command.
@@ -152,21 +155,25 @@ int mmdc_do_write_level_calibration(void)
 	 */
 	if (readl(&mmdc0->mpwlgcr) & 0x00000F00)
 		errors |= 1;
-	if (readl(&mmdc1->mpwlgcr) & 0x00000F00)
-		errors |= 2;
+	if (sysinfo->dsize == 2)
+		if (readl(&mmdc1->mpwlgcr) & 0x00000F00)
+			errors |= 2;
 
 	debug("Ending write leveling calibration. Error mask: 0x%x\n", errors);
 
 	/* check to see if cal failed */
 	if ((readl(&mmdc0->mpwldectrl0) == 0x001F001F) &&
 	    (readl(&mmdc0->mpwldectrl1) == 0x001F001F) &&
-	    (readl(&mmdc1->mpwldectrl0) == 0x001F001F) &&
-	    (readl(&mmdc1->mpwldectrl1) == 0x001F001F)) {
+	    ((sysinfo->dsize < 2) ||
+	     ((readl(&mmdc1->mpwldectrl0) == 0x001F001F) &&
+	      (readl(&mmdc1->mpwldectrl1) == 0x001F001F)))) {
 		debug("Cal seems to have soft-failed due to memory not supporting write leveling on all channels. Restoring original write leveling values.\n");
 		writel(ldectrl[0], &mmdc0->mpwldectrl0);
 		writel(ldectrl[1], &mmdc0->mpwldectrl1);
-		writel(ldectrl[2], &mmdc1->mpwldectrl0);
-		writel(ldectrl[3], &mmdc1->mpwldectrl1);
+		if (sysinfo->dsize == 2) {
+			writel(ldectrl[2], &mmdc1->mpwldectrl0);
+			writel(ldectrl[3], &mmdc1->mpwldectrl1);
+		}
 		errors |= 4;
 	}
 
@@ -189,16 +196,20 @@ int mmdc_do_write_level_calibration(void)
 	      readl(&mmdc0->mpwldectrl0));
 	debug("\tMMDC_MPWLDECTRL1 after write level cal: 0x%08X\n",
 	      readl(&mmdc0->mpwldectrl1));
-	debug("\tMMDC_MPWLDECTRL0 after write level cal: 0x%08X\n",
-	      readl(&mmdc1->mpwldectrl0));
-	debug("\tMMDC_MPWLDECTRL1 after write level cal: 0x%08X\n",
-	      readl(&mmdc1->mpwldectrl1));
+	if (sysinfo->dsize == 2) {
+		debug("\tMMDC_MPWLDECTRL0 after write level cal: 0x%08X\n",
+		      readl(&mmdc1->mpwldectrl0));
+		debug("\tMMDC_MPWLDECTRL1 after write level cal: 0x%08X\n",
+		      readl(&mmdc1->mpwldectrl1));
+	}
 
 	/* We must force a readback of these values, to get them to stick */
 	readl(&mmdc0->mpwldectrl0);
 	readl(&mmdc0->mpwldectrl1);
-	readl(&mmdc1->mpwldectrl0);
-	readl(&mmdc1->mpwldectrl1);
+	if (sysinfo->dsize == 2) {
+		readl(&mmdc1->mpwldectrl0);
+		readl(&mmdc1->mpwldectrl1);
+	}
 
 	/* enable DDR logic power down timer: */
 	setbits_le32(&mmdc0->mdpdc, 0x00005500);
@@ -212,7 +223,7 @@ int mmdc_do_write_level_calibration(void)
 	return errors;
 }
 
-int mmdc_do_dqs_calibration(void)
+int mmdc_do_dqs_calibration(struct mx6_ddr_sysinfo const *sysinfo)
 {
 	struct mmdc_p_regs *mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR;
 	struct mmdc_p_regs *mmdc1 = (struct mmdc_p_regs *)MMDC_P1_BASE_ADDR;
@@ -223,7 +234,6 @@ int mmdc_do_dqs_calibration(void)
 	bool cs0_enable_initial;
 	bool cs1_enable_initial;
 	u32 esdmisc_val;
-	u32 bus_size;
 	u32 temp_ref;
 	u32 pddword = 0x00ffff00; /* best so far, place into MPPDCMPR1 */
 	u32 errors = 0;
@@ -292,10 +302,6 @@ int mmdc_do_dqs_calibration(void)
 	cs0_enable = readl(&mmdc0->mdctl) & 0x80000000;
 	cs1_enable = readl(&mmdc0->mdctl) & 0x40000000;
 
-	/* Check to see what the data bus size is */
-	bus_size = (readl(&mmdc0->mdctl) & 0x30000) >> 16;
-	debug("Data bus size: %d (%d bits)\n", bus_size, 1 << (bus_size + 4));
-
 	precharge_all(cs0_enable, cs1_enable);
 
 	/* Write the pre-defined value into MPPDCMPR1 */
@@ -314,11 +320,11 @@ int mmdc_do_dqs_calibration(void)
 	 * Both PHYs for x64 configuration, if x32, do only PHY0.
 	 */
 	writel(initdelay, &mmdc0->mprddlctl);
-	if (bus_size == 0x2)
+	if (sysinfo->dsize == 0x2)
 		writel(initdelay, &mmdc1->mprddlctl);
 
 	/* Force a measurment, for previous delay setup to take effect. */
-	force_delay_measurement(bus_size);
+	force_delay_measurement(sysinfo->dsize);
 
 	/*
 	 * ***************************
@@ -364,7 +370,7 @@ int mmdc_do_dqs_calibration(void)
 	if (readl(&mmdc0->mpdgctrl0) & 0x00001000)
 		errors |= 1;
 
-	if ((bus_size == 0x2) && (readl(&mmdc1->mpdgctrl0) & 0x00001000))
+	if ((sysinfo->dsize == 0x2) && (readl(&mmdc1->mpdgctrl0) & 0x00001000))
 		errors |= 2;
 
 	/* now disable mpdgctrl0[DG_CMP_CYC] */
@@ -381,7 +387,7 @@ int mmdc_do_dqs_calibration(void)
 			 &mmdc0->mpdgctrl0);
 	modify_dg_result(&mmdc0->mpdghwst2, &mmdc0->mpdghwst3,
 			 &mmdc0->mpdgctrl1);
-	if (bus_size == 0x2) {
+	if (sysinfo->dsize == 0x2) {
 		modify_dg_result(&mmdc1->mpdghwst0, &mmdc1->mpdghwst1,
 				 &mmdc1->mpdgctrl0);
 		modify_dg_result(&mmdc1->mpdghwst2, &mmdc1->mpdghwst3,
@@ -424,7 +430,8 @@ int mmdc_do_dqs_calibration(void)
 	if (readl(&mmdc0->mprddlhwctl) & 0x0000000f)
 		errors |= 4;
 
-	if ((bus_size == 0x2) && (readl(&mmdc1->mprddlhwctl) & 0x0000000f))
+	if ((sysinfo->dsize == 0x2) &&
+	    (readl(&mmdc1->mprddlhwctl) & 0x0000000f))
 		errors |= 8;
 
 	debug("Ending Read Delay calibration. Error mask: 0x%x\n", errors);
@@ -450,14 +457,14 @@ int mmdc_do_dqs_calibration(void)
 	 * Both PHYs for x64 configuration, if x32, do only PHY0.
 	 */
 	writel(initdelay, &mmdc0->mpwrdlctl);
-	if (bus_size == 0x2)
+	if (sysinfo->dsize == 0x2)
 		writel(initdelay, &mmdc1->mpwrdlctl);
 
 	/*
 	 * XXX This isn't in the manual. Force a measurement,
 	 * for previous delay setup to effect.
 	 */
-	force_delay_measurement(bus_size);
+	force_delay_measurement(sysinfo->dsize);
 
 	/*
 	 * 9. 10. Start the automatic write calibration process
@@ -477,7 +484,8 @@ int mmdc_do_dqs_calibration(void)
 	if (readl(&mmdc0->mpwrdlhwctl) & 0x0000000f)
 		errors |= 16;
 
-	if ((bus_size == 0x2) && (readl(&mmdc1->mpwrdlhwctl) & 0x0000000f))
+	if ((sysinfo->dsize == 0x2) &&
+	    (readl(&mmdc1->mpwrdlhwctl) & 0x0000000f))
 		errors |= 32;
 
 	debug("Ending Write Delay calibration. Error mask: 0x%x\n", errors);
@@ -529,14 +537,18 @@ int mmdc_do_dqs_calibration(void)
 	debug("Read DQS gating calibration:\n");
 	debug("\tMPDGCTRL0 PHY0 = 0x%08X\n", readl(&mmdc0->mpdgctrl0));
 	debug("\tMPDGCTRL1 PHY0 = 0x%08X\n", readl(&mmdc0->mpdgctrl1));
-	debug("\tMPDGCTRL0 PHY1 = 0x%08X\n", readl(&mmdc1->mpdgctrl0));
-	debug("\tMPDGCTRL1 PHY1 = 0x%08X\n", readl(&mmdc1->mpdgctrl1));
+	if (sysinfo->dsize == 2) {
+		debug("\tMPDGCTRL0 PHY1 = 0x%08X\n", readl(&mmdc1->mpdgctrl0));
+		debug("\tMPDGCTRL1 PHY1 = 0x%08X\n", readl(&mmdc1->mpdgctrl1));
+	}
 	debug("Read calibration:\n");
 	debug("\tMPRDDLCTL PHY0 = 0x%08X\n", readl(&mmdc0->mprddlctl));
-	debug("\tMPRDDLCTL PHY1 = 0x%08X\n", readl(&mmdc1->mprddlctl));
+	if (sysinfo->dsize == 2)
+		debug("\tMPRDDLCTL PHY1 = 0x%08X\n", readl(&mmdc1->mprddlctl));
 	debug("Write calibration:\n");
 	debug("\tMPWRDLCTL PHY0 = 0x%08X\n", readl(&mmdc0->mpwrdlctl));
-	debug("\tMPWRDLCTL PHY1 = 0x%08X\n", readl(&mmdc1->mpwrdlctl));
+	if (sysinfo->dsize == 2)
+		debug("\tMPWRDLCTL PHY1 = 0x%08X\n", readl(&mmdc1->mpwrdlctl));
 
 	/*
 	 * Registers below are for debugging purposes.  These print out
@@ -548,10 +560,12 @@ int mmdc_do_dqs_calibration(void)
 	debug("\tMPDGHWST1 PHY0 = 0x%08x\n", readl(&mmdc0->mpdghwst1));
 	debug("\tMPDGHWST2 PHY0 = 0x%08x\n", readl(&mmdc0->mpdghwst2));
 	debug("\tMPDGHWST3 PHY0 = 0x%08x\n", readl(&mmdc0->mpdghwst3));
-	debug("\tMPDGHWST0 PHY1 = 0x%08x\n", readl(&mmdc1->mpdghwst0));
-	debug("\tMPDGHWST1 PHY1 = 0x%08x\n", readl(&mmdc1->mpdghwst1));
-	debug("\tMPDGHWST2 PHY1 = 0x%08x\n", readl(&mmdc1->mpdghwst2));
-	debug("\tMPDGHWST3 PHY1 = 0x%08x\n", readl(&mmdc1->mpdghwst3));
+	if (sysinfo->dsize == 2) {
+		debug("\tMPDGHWST0 PHY1 = 0x%08x\n", readl(&mmdc1->mpdghwst0));
+		debug("\tMPDGHWST1 PHY1 = 0x%08x\n", readl(&mmdc1->mpdghwst1));
+		debug("\tMPDGHWST2 PHY1 = 0x%08x\n", readl(&mmdc1->mpdghwst2));
+		debug("\tMPDGHWST3 PHY1 = 0x%08x\n", readl(&mmdc1->mpdghwst3));
+	}
 
 	debug("Final do_dqs_calibration error mask: 0x%x\n", errors);
 
diff --git a/arch/arm/include/asm/arch-mx6/mx6-ddr.h b/arch/arm/include/asm/arch-mx6/mx6-ddr.h
index 53eb5fa..cd5bc97 100644
--- a/arch/arm/include/asm/arch-mx6/mx6-ddr.h
+++ b/arch/arm/include/asm/arch-mx6/mx6-ddr.h
@@ -459,8 +459,8 @@ void mx6sl_dram_iocfg(unsigned width,
 		      const struct mx6sl_iomux_grp_regs *);
 
 #if defined(CONFIG_MX6QDL) || defined(CONFIG_MX6Q) || defined(CONFIG_MX6D)
-int mmdc_do_write_level_calibration(void);
-int mmdc_do_dqs_calibration(void);
+int mmdc_do_write_level_calibration(struct mx6_ddr_sysinfo const *sysinfo);
+int mmdc_do_dqs_calibration(struct mx6_ddr_sysinfo const *sysinfo);
 #endif
 
 /* configure mx6 mmdc registers */
diff --git a/board/kosagi/novena/novena_spl.c b/board/kosagi/novena/novena_spl.c
index 92c61ae..b934d36 100644
--- a/board/kosagi/novena/novena_spl.c
+++ b/board/kosagi/novena/novena_spl.c
@@ -605,8 +605,8 @@ void board_init_f(ulong dummy)
 
 	/* Perform DDR DRAM calibration */
 	udelay(100);
-	mmdc_do_write_level_calibration();
-	mmdc_do_dqs_calibration();
+	mmdc_do_write_level_calibration(&novena_ddr_info);
+	mmdc_do_dqs_calibration(&novena_ddr_info);
 
 	/* Clear the BSS. */
 	memset(__bss_start, 0, __bss_end - __bss_start);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [U-Boot] [PATCH 3/3] mx6: ddr: add routine to return DDR calibration data
  2016-10-30 17:18 [U-Boot] [PATCH 0/3] mx6: ddr: updates for dynamic DDR calibration Eric Nelson
  2016-10-30 17:19 ` [U-Boot] [PATCH 1/3] mx6: ddr: allow 32 cycles for DQS gating calibration Eric Nelson
  2016-10-30 17:19 ` [U-Boot] [PATCH 2/3] mx6: ddr: pass mx6_ddr_sysinfo to calibration routines Eric Nelson
@ 2016-10-30 17:19 ` Eric Nelson
  2016-10-30 17:30   ` Marek Vasut
  2016-10-30 19:20   ` [U-Boot] [PATCH] ARM: mx6: ddr: use Kconfig for inclusion of DDR calibration routines Eric Nelson
  2 siblings, 2 replies; 44+ messages in thread
From: Eric Nelson @ 2016-10-30 17:19 UTC (permalink / raw)
  To: u-boot

Add routine mmdc_read_calibration() to return the output of DDR
calibration. This can be used for debugging or to aid in construction
of static memory configuration.

Signed-off-by: Eric Nelson <eric@nelint.com>
---
 arch/arm/cpu/armv7/mx6/ddr.c            | 23 +++++++++++++++++++++++
 arch/arm/include/asm/arch-mx6/mx6-ddr.h |  2 ++
 2 files changed, 25 insertions(+)

diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c
index 274a0ba..b12fb64 100644
--- a/arch/arm/cpu/armv7/mx6/ddr.c
+++ b/arch/arm/cpu/armv7/mx6/ddr.c
@@ -1501,6 +1501,29 @@ void mx6_ddr3_cfg(const struct mx6_ddr_sysinfo *sysinfo,
 	mdelay(1);
 }
 
+void mmdc_read_calibration(struct mx6_ddr_sysinfo const *sysinfo,
+                           struct mx6_mmdc_calibration *calib)
+{
+	struct mmdc_p_regs *mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR;
+	struct mmdc_p_regs *mmdc1 = (struct mmdc_p_regs *)MMDC_P1_BASE_ADDR;
+
+	calib->p0_mpwldectrl0 = readl(&mmdc0->mpwldectrl0);
+	calib->p0_mpwldectrl1 = readl(&mmdc0->mpwldectrl1);
+	calib->p0_mpdgctrl0 = readl(&mmdc0->mpdgctrl0);
+	calib->p0_mpdgctrl1 = readl(&mmdc0->mpdgctrl1);
+	calib->p0_mprddlctl = readl(&mmdc0->mprddlctl);
+	calib->p0_mpwrdlctl = readl(&mmdc0->mpwrdlctl);
+
+	if (sysinfo->dsize == 2) {
+		calib->p1_mpwldectrl0 = readl(&mmdc1->mpwldectrl0);
+		calib->p1_mpwldectrl1 = readl(&mmdc1->mpwldectrl1);
+		calib->p1_mpdgctrl0 = readl(&mmdc1->mpdgctrl0);
+		calib->p1_mpdgctrl1 = readl(&mmdc1->mpdgctrl1);
+		calib->p1_mprddlctl = readl(&mmdc1->mprddlctl);
+		calib->p1_mpwrdlctl = readl(&mmdc1->mpwrdlctl);
+	}
+}
+
 void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo,
 		  const struct mx6_mmdc_calibration *calib,
 		  const void *ddr_cfg)
diff --git a/arch/arm/include/asm/arch-mx6/mx6-ddr.h b/arch/arm/include/asm/arch-mx6/mx6-ddr.h
index cd5bc97..12454fa 100644
--- a/arch/arm/include/asm/arch-mx6/mx6-ddr.h
+++ b/arch/arm/include/asm/arch-mx6/mx6-ddr.h
@@ -461,6 +461,8 @@ void mx6sl_dram_iocfg(unsigned width,
 #if defined(CONFIG_MX6QDL) || defined(CONFIG_MX6Q) || defined(CONFIG_MX6D)
 int mmdc_do_write_level_calibration(struct mx6_ddr_sysinfo const *sysinfo);
 int mmdc_do_dqs_calibration(struct mx6_ddr_sysinfo const *sysinfo);
+void mmdc_read_calibration(struct mx6_ddr_sysinfo const *sysinfo,
+                           struct mx6_mmdc_calibration *calib);
 #endif
 
 /* configure mx6 mmdc registers */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [U-Boot] [PATCH 1/3] mx6: ddr: allow 32 cycles for DQS gating calibration
  2016-10-30 17:19 ` [U-Boot] [PATCH 1/3] mx6: ddr: allow 32 cycles for DQS gating calibration Eric Nelson
@ 2016-10-30 17:27   ` Marek Vasut
  0 siblings, 0 replies; 44+ messages in thread
From: Marek Vasut @ 2016-10-30 17:27 UTC (permalink / raw)
  To: u-boot

On 10/30/2016 06:19 PM, Eric Nelson wrote:
> The DDR calibration code is only setting flag DG_CMP_CYC (DQS gating sample
> cycle) for the first PHY.
> 
> Set the 32-cycle flag for both PHYs and clear when done so the MPDGCTRL0
> output value isn't polluted with calibration artifacts.
> 
> Signed-off-by: Eric Nelson <eric@nelint.com>

Reviewed-by: Marek Vasut <marex@denx.de>

> ---
>  arch/arm/cpu/armv7/mx6/ddr.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c
> index 7beb7ea..b15f376 100644
> --- a/arch/arm/cpu/armv7/mx6/ddr.c
> +++ b/arch/arm/cpu/armv7/mx6/ddr.c
> @@ -347,6 +347,8 @@ int mmdc_do_dqs_calibration(void)
>  	 * 16 before comparing read data.
>  	 */
>  	setbits_le32(&mmdc0->mpdgctrl0, 1 << 30);
> +	if (sysinfo->dsize == 2)
> +		setbits_le32(&mmdc1->mpdgctrl0, 1 << 30);
>  
>  	/* Set bit 28 to start automatic read DQS gating calibration */
>  	setbits_le32(&mmdc0->mpdgctrl0, 5 << 28);
> @@ -365,6 +367,11 @@ int mmdc_do_dqs_calibration(void)
>  	if ((bus_size == 0x2) && (readl(&mmdc1->mpdgctrl0) & 0x00001000))
>  		errors |= 2;
>  
> +	/* now disable mpdgctrl0[DG_CMP_CYC] */
> +	clrbits_le32(&mmdc0->mpdgctrl0, 1 << 30);
> +	if (sysinfo->dsize == 2)
> +		clrbits_le32(&mmdc1->mpdgctrl0, 1 << 30);
> +
>  	/*
>  	 * DQS gating absolute offset should be modified from
>  	 * reflecting (HW_DG_LOWx + HW_DG_UPx)/2 to
> 


-- 
Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [U-Boot] [PATCH 2/3] mx6: ddr: pass mx6_ddr_sysinfo to calibration routines
  2016-10-30 17:19 ` [U-Boot] [PATCH 2/3] mx6: ddr: pass mx6_ddr_sysinfo to calibration routines Eric Nelson
@ 2016-10-30 17:29   ` Marek Vasut
  0 siblings, 0 replies; 44+ messages in thread
From: Marek Vasut @ 2016-10-30 17:29 UTC (permalink / raw)
  To: u-boot

On 10/30/2016 06:19 PM, Eric Nelson wrote:
> The DDR calibration routines have scattered support for bus
> widths other than 64-bits:
> 
> -- The mmdc_do_write_level_calibration() routine assumes the
> presence of PHY1, and
> -- The mmdc_do_dqs_calibration() routine tries to determine
> whether one or two DDR PHYs are active by reading MDCTL.
> 
> Since a caller of these routines must have a valid struct mx6_ddr_sysinfo
> for use in calling mx6_dram_cfg(), and the bus width is available in the
> "dsize" field, use this structure to inform the calibration routines which
> PHYs are active.
> 
> This allows the use of the DDR calibration routines on CPU variants
> like i.MX6SL that only have a single MMDC port.
> 
> Signed-off-by: Eric Nelson <eric@nelint.com>

Reviewed-by: Marek Vasut <marex@denx.de>

-- 
Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [U-Boot] [PATCH 3/3] mx6: ddr: add routine to return DDR calibration data
  2016-10-30 17:19 ` [U-Boot] [PATCH 3/3] mx6: ddr: add routine to return DDR calibration data Eric Nelson
@ 2016-10-30 17:30   ` Marek Vasut
  2016-10-30 19:14     ` Eric Nelson
  2016-10-30 19:20   ` [U-Boot] [PATCH] ARM: mx6: ddr: use Kconfig for inclusion of DDR calibration routines Eric Nelson
  1 sibling, 1 reply; 44+ messages in thread
From: Marek Vasut @ 2016-10-30 17:30 UTC (permalink / raw)
  To: u-boot

On 10/30/2016 06:19 PM, Eric Nelson wrote:
> Add routine mmdc_read_calibration() to return the output of DDR
> calibration. This can be used for debugging or to aid in construction
> of static memory configuration.
> 
> Signed-off-by: Eric Nelson <eric@nelint.com>

Do you plan to use it or will this be mostly dead code ?

> ---
>  arch/arm/cpu/armv7/mx6/ddr.c            | 23 +++++++++++++++++++++++
>  arch/arm/include/asm/arch-mx6/mx6-ddr.h |  2 ++
>  2 files changed, 25 insertions(+)
> 
> diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c
> index 274a0ba..b12fb64 100644
> --- a/arch/arm/cpu/armv7/mx6/ddr.c
> +++ b/arch/arm/cpu/armv7/mx6/ddr.c
> @@ -1501,6 +1501,29 @@ void mx6_ddr3_cfg(const struct mx6_ddr_sysinfo *sysinfo,
>  	mdelay(1);
>  }
>  
> +void mmdc_read_calibration(struct mx6_ddr_sysinfo const *sysinfo,
> +                           struct mx6_mmdc_calibration *calib)
> +{
> +	struct mmdc_p_regs *mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR;
> +	struct mmdc_p_regs *mmdc1 = (struct mmdc_p_regs *)MMDC_P1_BASE_ADDR;
> +
> +	calib->p0_mpwldectrl0 = readl(&mmdc0->mpwldectrl0);
> +	calib->p0_mpwldectrl1 = readl(&mmdc0->mpwldectrl1);
> +	calib->p0_mpdgctrl0 = readl(&mmdc0->mpdgctrl0);
> +	calib->p0_mpdgctrl1 = readl(&mmdc0->mpdgctrl1);
> +	calib->p0_mprddlctl = readl(&mmdc0->mprddlctl);
> +	calib->p0_mpwrdlctl = readl(&mmdc0->mpwrdlctl);
> +
> +	if (sysinfo->dsize == 2) {
> +		calib->p1_mpwldectrl0 = readl(&mmdc1->mpwldectrl0);
> +		calib->p1_mpwldectrl1 = readl(&mmdc1->mpwldectrl1);
> +		calib->p1_mpdgctrl0 = readl(&mmdc1->mpdgctrl0);
> +		calib->p1_mpdgctrl1 = readl(&mmdc1->mpdgctrl1);
> +		calib->p1_mprddlctl = readl(&mmdc1->mprddlctl);
> +		calib->p1_mpwrdlctl = readl(&mmdc1->mpwrdlctl);
> +	}
> +}
> +
>  void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo,
>  		  const struct mx6_mmdc_calibration *calib,
>  		  const void *ddr_cfg)
> diff --git a/arch/arm/include/asm/arch-mx6/mx6-ddr.h b/arch/arm/include/asm/arch-mx6/mx6-ddr.h
> index cd5bc97..12454fa 100644
> --- a/arch/arm/include/asm/arch-mx6/mx6-ddr.h
> +++ b/arch/arm/include/asm/arch-mx6/mx6-ddr.h
> @@ -461,6 +461,8 @@ void mx6sl_dram_iocfg(unsigned width,
>  #if defined(CONFIG_MX6QDL) || defined(CONFIG_MX6Q) || defined(CONFIG_MX6D)
>  int mmdc_do_write_level_calibration(struct mx6_ddr_sysinfo const *sysinfo);
>  int mmdc_do_dqs_calibration(struct mx6_ddr_sysinfo const *sysinfo);
> +void mmdc_read_calibration(struct mx6_ddr_sysinfo const *sysinfo,
> +                           struct mx6_mmdc_calibration *calib);
>  #endif
>  
>  /* configure mx6 mmdc registers */
> 


-- 
Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [U-Boot] [PATCH 3/3] mx6: ddr: add routine to return DDR calibration data
  2016-10-30 17:30   ` Marek Vasut
@ 2016-10-30 19:14     ` Eric Nelson
  2016-10-30 20:02       ` Marek Vasut
  0 siblings, 1 reply; 44+ messages in thread
From: Eric Nelson @ 2016-10-30 19:14 UTC (permalink / raw)
  To: u-boot

Hi Marek,

On 10/30/2016 10:30 AM, Marek Vasut wrote:
> On 10/30/2016 06:19 PM, Eric Nelson wrote:
>> Add routine mmdc_read_calibration() to return the output of DDR
>> calibration. This can be used for debugging or to aid in construction
>> of static memory configuration.
>>
>> Signed-off-by: Eric Nelson <eric@nelint.com>
> 
> Do you plan to use it or will this be mostly dead code ?
> 

I plan to use it.

I'm cleaning things up before (re)sending a patch adding the
virtual "mx6memcal" board and wanted to push the supporting
changes in a separate set.

I have one more independent patch (4/3?) to send before
the new board.

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [U-Boot] [PATCH] ARM: mx6: ddr: use Kconfig for inclusion of DDR calibration routines
  2016-10-30 17:19 ` [U-Boot] [PATCH 3/3] mx6: ddr: add routine to return DDR calibration data Eric Nelson
  2016-10-30 17:30   ` Marek Vasut
@ 2016-10-30 19:20   ` Eric Nelson
  2016-10-30 20:03     ` Marek Vasut
  1 sibling, 1 reply; 44+ messages in thread
From: Eric Nelson @ 2016-10-30 19:20 UTC (permalink / raw)
  To: u-boot

The DDR calibration routines are gated by conditionals for the
i.MX6DQ SOCs, but with the use of the sysinfo parameter, these
are usable on at least i.MX6SDL and i.MX6SL variants with DDR3.

Also, since only the Novena board currently uses the dynamic
DDR calibration routines, these routines waste space on other
boards using SPL.

Add a KConfig entry to allow boards to selectively include the
DDR calibration routines.

Signed-off-by: Eric Nelson <eric@nelint.com>
---
 arch/arm/cpu/armv7/mx6/Kconfig          | 5 +++++
 arch/arm/cpu/armv7/mx6/ddr.c            | 3 +--
 arch/arm/include/asm/arch-mx6/mx6-ddr.h | 2 +-
 configs/novena_defconfig                | 1 +
 4 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/arch/arm/cpu/armv7/mx6/Kconfig b/arch/arm/cpu/armv7/mx6/Kconfig
index 762a581..32536c0 100644
--- a/arch/arm/cpu/armv7/mx6/Kconfig
+++ b/arch/arm/cpu/armv7/mx6/Kconfig
@@ -35,6 +35,11 @@ config MX6ULL
 	bool
 	select MX6UL
 
+config MX6_DDRCAL
+	bool "Include dynamic DDR calibration routines"
+	depends on SPL
+	default n
+
 choice
 	prompt "MX6 board select"
 	optional
diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c
index b12fb64..0cf391e 100644
--- a/arch/arm/cpu/armv7/mx6/ddr.c
+++ b/arch/arm/cpu/armv7/mx6/ddr.c
@@ -14,8 +14,7 @@
 #include <asm/types.h>
 #include <wait_bit.h>
 
-#if defined(CONFIG_MX6QDL) || defined(CONFIG_MX6Q) || defined(CONFIG_MX6D)
-
+#if defined(CONFIG_MX6_DDRCAL)
 static void reset_read_data_fifos(void)
 {
 	struct mmdc_p_regs *mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR;
diff --git a/arch/arm/include/asm/arch-mx6/mx6-ddr.h b/arch/arm/include/asm/arch-mx6/mx6-ddr.h
index 12454fa..2a8d443 100644
--- a/arch/arm/include/asm/arch-mx6/mx6-ddr.h
+++ b/arch/arm/include/asm/arch-mx6/mx6-ddr.h
@@ -458,7 +458,7 @@ void mx6sl_dram_iocfg(unsigned width,
 		      const struct mx6sl_iomux_ddr_regs *,
 		      const struct mx6sl_iomux_grp_regs *);
 
-#if defined(CONFIG_MX6QDL) || defined(CONFIG_MX6Q) || defined(CONFIG_MX6D)
+#if defined(CONFIG_MX6_DDRCAL)
 int mmdc_do_write_level_calibration(struct mx6_ddr_sysinfo const *sysinfo);
 int mmdc_do_dqs_calibration(struct mx6_ddr_sysinfo const *sysinfo);
 void mmdc_read_calibration(struct mx6_ddr_sysinfo const *sysinfo,
diff --git a/configs/novena_defconfig b/configs/novena_defconfig
index 1ffdddc..9d47d5b 100644
--- a/configs/novena_defconfig
+++ b/configs/novena_defconfig
@@ -3,6 +3,7 @@ CONFIG_ARCH_MX6=y
 CONFIG_SPL_GPIO_SUPPORT=y
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_MX6_DDRCAL=y
 CONFIG_TARGET_KOSAGI_NOVENA=y
 CONFIG_SPL_EXT_SUPPORT=y
 CONFIG_SPL_FAT_SUPPORT=y
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [U-Boot] [PATCH 3/3] mx6: ddr: add routine to return DDR calibration data
  2016-10-30 19:14     ` Eric Nelson
@ 2016-10-30 20:02       ` Marek Vasut
  0 siblings, 0 replies; 44+ messages in thread
From: Marek Vasut @ 2016-10-30 20:02 UTC (permalink / raw)
  To: u-boot

On 10/30/2016 08:14 PM, Eric Nelson wrote:
> Hi Marek,

Hi!

> On 10/30/2016 10:30 AM, Marek Vasut wrote:
>> On 10/30/2016 06:19 PM, Eric Nelson wrote:
>>> Add routine mmdc_read_calibration() to return the output of DDR
>>> calibration. This can be used for debugging or to aid in construction
>>> of static memory configuration.
>>>
>>> Signed-off-by: Eric Nelson <eric@nelint.com>
>>
>> Do you plan to use it or will this be mostly dead code ?
>>
> 
> I plan to use it.
> 
> I'm cleaning things up before (re)sending a patch adding the
> virtual "mx6memcal" board and wanted to push the supporting
> changes in a separate set.

Oh cool, all right.

> I have one more independent patch (4/3?) to send before
> the new board.
> 


-- 
Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [U-Boot] [PATCH] ARM: mx6: ddr: use Kconfig for inclusion of DDR calibration routines
  2016-10-30 19:20   ` [U-Boot] [PATCH] ARM: mx6: ddr: use Kconfig for inclusion of DDR calibration routines Eric Nelson
@ 2016-10-30 20:03     ` Marek Vasut
  2016-10-30 23:10       ` Eric Nelson
  0 siblings, 1 reply; 44+ messages in thread
From: Marek Vasut @ 2016-10-30 20:03 UTC (permalink / raw)
  To: u-boot

On 10/30/2016 08:20 PM, Eric Nelson wrote:
> The DDR calibration routines are gated by conditionals for the
> i.MX6DQ SOCs, but with the use of the sysinfo parameter, these
> are usable on at least i.MX6SDL and i.MX6SL variants with DDR3.
> 
> Also, since only the Novena board currently uses the dynamic
> DDR calibration routines, these routines waste space on other
> boards using SPL.
> 
> Add a KConfig entry to allow boards to selectively include the
> DDR calibration routines.
> 
> Signed-off-by: Eric Nelson <eric@nelint.com>
> ---
>  arch/arm/cpu/armv7/mx6/Kconfig          | 5 +++++
>  arch/arm/cpu/armv7/mx6/ddr.c            | 3 +--
>  arch/arm/include/asm/arch-mx6/mx6-ddr.h | 2 +-
>  configs/novena_defconfig                | 1 +
>  4 files changed, 8 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/cpu/armv7/mx6/Kconfig b/arch/arm/cpu/armv7/mx6/Kconfig
> index 762a581..32536c0 100644
> --- a/arch/arm/cpu/armv7/mx6/Kconfig
> +++ b/arch/arm/cpu/armv7/mx6/Kconfig
> @@ -35,6 +35,11 @@ config MX6ULL
>  	bool
>  	select MX6UL
>  
> +config MX6_DDRCAL
> +	bool "Include dynamic DDR calibration routines"
> +	depends on SPL
> +	default n

Help text would really be helpful ;)

>  choice
>  	prompt "MX6 board select"
>  	optional
> diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c
> index b12fb64..0cf391e 100644
> --- a/arch/arm/cpu/armv7/mx6/ddr.c
> +++ b/arch/arm/cpu/armv7/mx6/ddr.c
> @@ -14,8 +14,7 @@
>  #include <asm/types.h>
>  #include <wait_bit.h>
>  
> -#if defined(CONFIG_MX6QDL) || defined(CONFIG_MX6Q) || defined(CONFIG_MX6D)
> -
> +#if defined(CONFIG_MX6_DDRCAL)
>  static void reset_read_data_fifos(void)
>  {
>  	struct mmdc_p_regs *mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR;
> diff --git a/arch/arm/include/asm/arch-mx6/mx6-ddr.h b/arch/arm/include/asm/arch-mx6/mx6-ddr.h
> index 12454fa..2a8d443 100644
> --- a/arch/arm/include/asm/arch-mx6/mx6-ddr.h
> +++ b/arch/arm/include/asm/arch-mx6/mx6-ddr.h
> @@ -458,7 +458,7 @@ void mx6sl_dram_iocfg(unsigned width,
>  		      const struct mx6sl_iomux_ddr_regs *,
>  		      const struct mx6sl_iomux_grp_regs *);
>  
> -#if defined(CONFIG_MX6QDL) || defined(CONFIG_MX6Q) || defined(CONFIG_MX6D)
> +#if defined(CONFIG_MX6_DDRCAL)
>  int mmdc_do_write_level_calibration(struct mx6_ddr_sysinfo const *sysinfo);
>  int mmdc_do_dqs_calibration(struct mx6_ddr_sysinfo const *sysinfo);
>  void mmdc_read_calibration(struct mx6_ddr_sysinfo const *sysinfo,
> diff --git a/configs/novena_defconfig b/configs/novena_defconfig
> index 1ffdddc..9d47d5b 100644
> --- a/configs/novena_defconfig
> +++ b/configs/novena_defconfig
> @@ -3,6 +3,7 @@ CONFIG_ARCH_MX6=y
>  CONFIG_SPL_GPIO_SUPPORT=y
>  CONFIG_SPL_LIBCOMMON_SUPPORT=y
>  CONFIG_SPL_LIBGENERIC_SUPPORT=y
> +CONFIG_MX6_DDRCAL=y
>  CONFIG_TARGET_KOSAGI_NOVENA=y
>  CONFIG_SPL_EXT_SUPPORT=y
>  CONFIG_SPL_FAT_SUPPORT=y
> 


-- 
Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [U-Boot] [PATCH] ARM: mx6: ddr: use Kconfig for inclusion of DDR calibration routines
  2016-10-30 20:03     ` Marek Vasut
@ 2016-10-30 23:10       ` Eric Nelson
  2016-10-30 23:33         ` [U-Boot] [PATCH V2 0/4] mx6: ddr: updates for dynamic DDR calibration Eric Nelson
  2016-11-01 20:13         ` [U-Boot] [RFC PATCH 0/9] ARM: imx: mx6: Add virtual mx6memcal board Eric Nelson
  0 siblings, 2 replies; 44+ messages in thread
From: Eric Nelson @ 2016-10-30 23:10 UTC (permalink / raw)
  To: u-boot

Thanks Marek,

On 10/30/2016 01:03 PM, Marek Vasut wrote:
> On 10/30/2016 08:20 PM, Eric Nelson wrote:
>> The DDR calibration routines are gated by conditionals for the
>> i.MX6DQ SOCs, but with the use of the sysinfo parameter, these
>> are usable on at least i.MX6SDL and i.MX6SL variants with DDR3.
>>
>> Also, since only the Novena board currently uses the dynamic
>> DDR calibration routines, these routines waste space on other
>> boards using SPL.
>>
>> Add a KConfig entry to allow boards to selectively include the
>> DDR calibration routines.
>>
>> Signed-off-by: Eric Nelson <eric@nelint.com>
>> ---
>>  arch/arm/cpu/armv7/mx6/Kconfig          | 5 +++++
>>  arch/arm/cpu/armv7/mx6/ddr.c            | 3 +--
>>  arch/arm/include/asm/arch-mx6/mx6-ddr.h | 2 +-
>>  configs/novena_defconfig                | 1 +
>>  4 files changed, 8 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/arm/cpu/armv7/mx6/Kconfig b/arch/arm/cpu/armv7/mx6/Kconfig
>> index 762a581..32536c0 100644
>> --- a/arch/arm/cpu/armv7/mx6/Kconfig
>> +++ b/arch/arm/cpu/armv7/mx6/Kconfig
>> @@ -35,6 +35,11 @@ config MX6ULL
>>  	bool
>>  	select MX6UL
>>  
>> +config MX6_DDRCAL
>> +	bool "Include dynamic DDR calibration routines"
>> +	depends on SPL
>> +	default n
> 
> Help text would really be helpful ;)
> 

Cool.

I'll fix this and re-send the series as V2 (with the fourth patch).

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [U-Boot] [PATCH V2 0/4] mx6: ddr: updates for dynamic DDR calibration
  2016-10-30 23:10       ` Eric Nelson
@ 2016-10-30 23:33         ` Eric Nelson
  2016-10-30 23:33           ` [U-Boot] [PATCH V2 1/4] mx6: ddr: allow 32 cycles for DQS gating calibration Eric Nelson
                             ` (5 more replies)
  2016-11-01 20:13         ` [U-Boot] [RFC PATCH 0/9] ARM: imx: mx6: Add virtual mx6memcal board Eric Nelson
  1 sibling, 6 replies; 44+ messages in thread
From: Eric Nelson @ 2016-10-30 23:33 UTC (permalink / raw)
  To: u-boot

This set of patches updates the interface to the DDR calibration in 
preparation for the addition of a pseudo-board for calibration on
i.MX6.

The first patch fixes an ommission in the use of the DG_CMP_CYC flag
in register MPDGCTRL0.

The second patch cleans up the handling of bus widths by passing
the system configuration information to the calibration routines.

The third patch adds support for returning the calibration data
written to the MMDC registers.

The fourth patch adds a Kconfig selection to inclut the DDR calibration
routines.

Eric Nelson (4):
  mx6: ddr: allow 32 cycles for DQS gating calibration
  mx6: ddr: pass mx6_ddr_sysinfo to calibration routines
  mx6: ddr: add routine to return DDR calibration data
  ARM: mx6: ddr: use Kconfig for inclusion of DDR calibration routines

 arch/arm/cpu/armv7/mx6/Kconfig          |   5 ++
 arch/arm/cpu/armv7/mx6/ddr.c            | 131 +++++++++++++++++++++-----------
 arch/arm/include/asm/arch-mx6/mx6-ddr.h |   8 +-
 board/kosagi/novena/novena_spl.c        |   4 +-
 configs/novena_defconfig                |   1 +
 5 files changed, 100 insertions(+), 49 deletions(-)

-- 
V2 adds patch 4
2.7.4

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [U-Boot] [PATCH V2 1/4] mx6: ddr: allow 32 cycles for DQS gating calibration
  2016-10-30 23:33         ` [U-Boot] [PATCH V2 0/4] mx6: ddr: updates for dynamic DDR calibration Eric Nelson
@ 2016-10-30 23:33           ` Eric Nelson
  2016-10-30 23:33           ` [U-Boot] [PATCH V2 2/4] mx6: ddr: pass mx6_ddr_sysinfo to calibration routines Eric Nelson
                             ` (4 subsequent siblings)
  5 siblings, 0 replies; 44+ messages in thread
From: Eric Nelson @ 2016-10-30 23:33 UTC (permalink / raw)
  To: u-boot

The DDR calibration code is only setting flag DG_CMP_CYC (DQS gating sample
cycle) for the first PHY.

Set the 32-cycle flag for both PHYs and clear when done so the MPDGCTRL0
output value isn't polluted with calibration artifacts.

Signed-off-by: Eric Nelson <eric@nelint.com>
Reviewed-by: Marek Vasut <marex@denx.de>
---
No change in V2.
 arch/arm/cpu/armv7/mx6/ddr.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c
index 7beb7ea..b15f376 100644
--- a/arch/arm/cpu/armv7/mx6/ddr.c
+++ b/arch/arm/cpu/armv7/mx6/ddr.c
@@ -347,6 +347,8 @@ int mmdc_do_dqs_calibration(void)
 	 * 16 before comparing read data.
 	 */
 	setbits_le32(&mmdc0->mpdgctrl0, 1 << 30);
+	if (sysinfo->dsize == 2)
+		setbits_le32(&mmdc1->mpdgctrl0, 1 << 30);
 
 	/* Set bit 28 to start automatic read DQS gating calibration */
 	setbits_le32(&mmdc0->mpdgctrl0, 5 << 28);
@@ -365,6 +367,11 @@ int mmdc_do_dqs_calibration(void)
 	if ((bus_size == 0x2) && (readl(&mmdc1->mpdgctrl0) & 0x00001000))
 		errors |= 2;
 
+	/* now disable mpdgctrl0[DG_CMP_CYC] */
+	clrbits_le32(&mmdc0->mpdgctrl0, 1 << 30);
+	if (sysinfo->dsize == 2)
+		clrbits_le32(&mmdc1->mpdgctrl0, 1 << 30);
+
 	/*
 	 * DQS gating absolute offset should be modified from
 	 * reflecting (HW_DG_LOWx + HW_DG_UPx)/2 to
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [U-Boot] [PATCH V2 2/4] mx6: ddr: pass mx6_ddr_sysinfo to calibration routines
  2016-10-30 23:33         ` [U-Boot] [PATCH V2 0/4] mx6: ddr: updates for dynamic DDR calibration Eric Nelson
  2016-10-30 23:33           ` [U-Boot] [PATCH V2 1/4] mx6: ddr: allow 32 cycles for DQS gating calibration Eric Nelson
@ 2016-10-30 23:33           ` Eric Nelson
  2016-10-30 23:33           ` [U-Boot] [PATCH V2 3/4] mx6: ddr: add routine to return DDR calibration data Eric Nelson
                             ` (3 subsequent siblings)
  5 siblings, 0 replies; 44+ messages in thread
From: Eric Nelson @ 2016-10-30 23:33 UTC (permalink / raw)
  To: u-boot

The DDR calibration routines have scattered support for bus
widths other than 64-bits:

-- The mmdc_do_write_level_calibration() routine assumes the
presence of PHY1, and
-- The mmdc_do_dqs_calibration() routine tries to determine
whether one or two DDR PHYs are active by reading MDCTL.

Since a caller of these routines must have a valid struct mx6_ddr_sysinfo
for use in calling mx6_dram_cfg(), and the bus width is available in the
"dsize" field, use this structure to inform the calibration routines which
PHYs are active.

This allows the use of the DDR calibration routines on CPU variants
like i.MX6SL that only have a single MMDC port.

Signed-off-by: Eric Nelson <eric@nelint.com>
Reviewed-by: Marek Vasut <marex@denx.de>
---
No change in V2
 arch/arm/cpu/armv7/mx6/ddr.c            | 98 +++++++++++++++++++--------------
 arch/arm/include/asm/arch-mx6/mx6-ddr.h |  4 +-
 board/kosagi/novena/novena_spl.c        |  4 +-
 3 files changed, 60 insertions(+), 46 deletions(-)

diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c
index b15f376..274a0ba 100644
--- a/arch/arm/cpu/armv7/mx6/ddr.c
+++ b/arch/arm/cpu/armv7/mx6/ddr.c
@@ -86,14 +86,15 @@ static void modify_dg_result(u32 *reg_st0, u32 *reg_st1, u32 *reg_ctrl)
 	writel(val_ctrl, reg_ctrl);
 }
 
-int mmdc_do_write_level_calibration(void)
+int mmdc_do_write_level_calibration(struct mx6_ddr_sysinfo const *sysinfo)
 {
 	struct mmdc_p_regs *mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR;
 	struct mmdc_p_regs *mmdc1 = (struct mmdc_p_regs *)MMDC_P1_BASE_ADDR;
 	u32 esdmisc_val, zq_val;
 	u32 errors = 0;
-	u32 ldectrl[4];
+	u32 ldectrl[4] = {0};
 	u32 ddr_mr1 = 0x4;
+	u32 rwalat_max;
 
 	/*
 	 * Stash old values in case calibration fails,
@@ -101,8 +102,10 @@ int mmdc_do_write_level_calibration(void)
 	 */
 	ldectrl[0] = readl(&mmdc0->mpwldectrl0);
 	ldectrl[1] = readl(&mmdc0->mpwldectrl1);
-	ldectrl[2] = readl(&mmdc1->mpwldectrl0);
-	ldectrl[3] = readl(&mmdc1->mpwldectrl1);
+	if (sysinfo->dsize == 2) {
+		ldectrl[2] = readl(&mmdc1->mpwldectrl0);
+		ldectrl[3] = readl(&mmdc1->mpwldectrl1);
+	}
 
 	/* disable DDR logic power down timer */
 	clrbits_le32(&mmdc0->mdpdc, 0xff00);
@@ -122,10 +125,10 @@ int mmdc_do_write_level_calibration(void)
 	writel(zq_val & ~0x3, &mmdc0->mpzqhwctrl);
 
 	/* 3. increase walat and ralat to maximum */
-	setbits_le32(&mmdc0->mdmisc,
-		     (1 << 6) | (1 << 7) | (1 << 8) | (1 << 16) | (1 << 17));
-	setbits_le32(&mmdc1->mdmisc,
-		     (1 << 6) | (1 << 7) | (1 << 8) | (1 << 16) | (1 << 17));
+	rwalat_max = (1 << 6) | (1 << 7) | (1 << 8) | (1 << 16) | (1 << 17);
+	setbits_le32(&mmdc0->mdmisc, rwalat_max);
+	if (sysinfo->dsize == 2)
+		setbits_le32(&mmdc1->mdmisc, rwalat_max);
 	/*
 	 * 4 & 5. Configure the external DDR device to enter write-leveling
 	 * mode through Load Mode Register command.
@@ -152,21 +155,25 @@ int mmdc_do_write_level_calibration(void)
 	 */
 	if (readl(&mmdc0->mpwlgcr) & 0x00000F00)
 		errors |= 1;
-	if (readl(&mmdc1->mpwlgcr) & 0x00000F00)
-		errors |= 2;
+	if (sysinfo->dsize == 2)
+		if (readl(&mmdc1->mpwlgcr) & 0x00000F00)
+			errors |= 2;
 
 	debug("Ending write leveling calibration. Error mask: 0x%x\n", errors);
 
 	/* check to see if cal failed */
 	if ((readl(&mmdc0->mpwldectrl0) == 0x001F001F) &&
 	    (readl(&mmdc0->mpwldectrl1) == 0x001F001F) &&
-	    (readl(&mmdc1->mpwldectrl0) == 0x001F001F) &&
-	    (readl(&mmdc1->mpwldectrl1) == 0x001F001F)) {
+	    ((sysinfo->dsize < 2) ||
+	     ((readl(&mmdc1->mpwldectrl0) == 0x001F001F) &&
+	      (readl(&mmdc1->mpwldectrl1) == 0x001F001F)))) {
 		debug("Cal seems to have soft-failed due to memory not supporting write leveling on all channels. Restoring original write leveling values.\n");
 		writel(ldectrl[0], &mmdc0->mpwldectrl0);
 		writel(ldectrl[1], &mmdc0->mpwldectrl1);
-		writel(ldectrl[2], &mmdc1->mpwldectrl0);
-		writel(ldectrl[3], &mmdc1->mpwldectrl1);
+		if (sysinfo->dsize == 2) {
+			writel(ldectrl[2], &mmdc1->mpwldectrl0);
+			writel(ldectrl[3], &mmdc1->mpwldectrl1);
+		}
 		errors |= 4;
 	}
 
@@ -189,16 +196,20 @@ int mmdc_do_write_level_calibration(void)
 	      readl(&mmdc0->mpwldectrl0));
 	debug("\tMMDC_MPWLDECTRL1 after write level cal: 0x%08X\n",
 	      readl(&mmdc0->mpwldectrl1));
-	debug("\tMMDC_MPWLDECTRL0 after write level cal: 0x%08X\n",
-	      readl(&mmdc1->mpwldectrl0));
-	debug("\tMMDC_MPWLDECTRL1 after write level cal: 0x%08X\n",
-	      readl(&mmdc1->mpwldectrl1));
+	if (sysinfo->dsize == 2) {
+		debug("\tMMDC_MPWLDECTRL0 after write level cal: 0x%08X\n",
+		      readl(&mmdc1->mpwldectrl0));
+		debug("\tMMDC_MPWLDECTRL1 after write level cal: 0x%08X\n",
+		      readl(&mmdc1->mpwldectrl1));
+	}
 
 	/* We must force a readback of these values, to get them to stick */
 	readl(&mmdc0->mpwldectrl0);
 	readl(&mmdc0->mpwldectrl1);
-	readl(&mmdc1->mpwldectrl0);
-	readl(&mmdc1->mpwldectrl1);
+	if (sysinfo->dsize == 2) {
+		readl(&mmdc1->mpwldectrl0);
+		readl(&mmdc1->mpwldectrl1);
+	}
 
 	/* enable DDR logic power down timer: */
 	setbits_le32(&mmdc0->mdpdc, 0x00005500);
@@ -212,7 +223,7 @@ int mmdc_do_write_level_calibration(void)
 	return errors;
 }
 
-int mmdc_do_dqs_calibration(void)
+int mmdc_do_dqs_calibration(struct mx6_ddr_sysinfo const *sysinfo)
 {
 	struct mmdc_p_regs *mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR;
 	struct mmdc_p_regs *mmdc1 = (struct mmdc_p_regs *)MMDC_P1_BASE_ADDR;
@@ -223,7 +234,6 @@ int mmdc_do_dqs_calibration(void)
 	bool cs0_enable_initial;
 	bool cs1_enable_initial;
 	u32 esdmisc_val;
-	u32 bus_size;
 	u32 temp_ref;
 	u32 pddword = 0x00ffff00; /* best so far, place into MPPDCMPR1 */
 	u32 errors = 0;
@@ -292,10 +302,6 @@ int mmdc_do_dqs_calibration(void)
 	cs0_enable = readl(&mmdc0->mdctl) & 0x80000000;
 	cs1_enable = readl(&mmdc0->mdctl) & 0x40000000;
 
-	/* Check to see what the data bus size is */
-	bus_size = (readl(&mmdc0->mdctl) & 0x30000) >> 16;
-	debug("Data bus size: %d (%d bits)\n", bus_size, 1 << (bus_size + 4));
-
 	precharge_all(cs0_enable, cs1_enable);
 
 	/* Write the pre-defined value into MPPDCMPR1 */
@@ -314,11 +320,11 @@ int mmdc_do_dqs_calibration(void)
 	 * Both PHYs for x64 configuration, if x32, do only PHY0.
 	 */
 	writel(initdelay, &mmdc0->mprddlctl);
-	if (bus_size == 0x2)
+	if (sysinfo->dsize == 0x2)
 		writel(initdelay, &mmdc1->mprddlctl);
 
 	/* Force a measurment, for previous delay setup to take effect. */
-	force_delay_measurement(bus_size);
+	force_delay_measurement(sysinfo->dsize);
 
 	/*
 	 * ***************************
@@ -364,7 +370,7 @@ int mmdc_do_dqs_calibration(void)
 	if (readl(&mmdc0->mpdgctrl0) & 0x00001000)
 		errors |= 1;
 
-	if ((bus_size == 0x2) && (readl(&mmdc1->mpdgctrl0) & 0x00001000))
+	if ((sysinfo->dsize == 0x2) && (readl(&mmdc1->mpdgctrl0) & 0x00001000))
 		errors |= 2;
 
 	/* now disable mpdgctrl0[DG_CMP_CYC] */
@@ -381,7 +387,7 @@ int mmdc_do_dqs_calibration(void)
 			 &mmdc0->mpdgctrl0);
 	modify_dg_result(&mmdc0->mpdghwst2, &mmdc0->mpdghwst3,
 			 &mmdc0->mpdgctrl1);
-	if (bus_size == 0x2) {
+	if (sysinfo->dsize == 0x2) {
 		modify_dg_result(&mmdc1->mpdghwst0, &mmdc1->mpdghwst1,
 				 &mmdc1->mpdgctrl0);
 		modify_dg_result(&mmdc1->mpdghwst2, &mmdc1->mpdghwst3,
@@ -424,7 +430,8 @@ int mmdc_do_dqs_calibration(void)
 	if (readl(&mmdc0->mprddlhwctl) & 0x0000000f)
 		errors |= 4;
 
-	if ((bus_size == 0x2) && (readl(&mmdc1->mprddlhwctl) & 0x0000000f))
+	if ((sysinfo->dsize == 0x2) &&
+	    (readl(&mmdc1->mprddlhwctl) & 0x0000000f))
 		errors |= 8;
 
 	debug("Ending Read Delay calibration. Error mask: 0x%x\n", errors);
@@ -450,14 +457,14 @@ int mmdc_do_dqs_calibration(void)
 	 * Both PHYs for x64 configuration, if x32, do only PHY0.
 	 */
 	writel(initdelay, &mmdc0->mpwrdlctl);
-	if (bus_size == 0x2)
+	if (sysinfo->dsize == 0x2)
 		writel(initdelay, &mmdc1->mpwrdlctl);
 
 	/*
 	 * XXX This isn't in the manual. Force a measurement,
 	 * for previous delay setup to effect.
 	 */
-	force_delay_measurement(bus_size);
+	force_delay_measurement(sysinfo->dsize);
 
 	/*
 	 * 9. 10. Start the automatic write calibration process
@@ -477,7 +484,8 @@ int mmdc_do_dqs_calibration(void)
 	if (readl(&mmdc0->mpwrdlhwctl) & 0x0000000f)
 		errors |= 16;
 
-	if ((bus_size == 0x2) && (readl(&mmdc1->mpwrdlhwctl) & 0x0000000f))
+	if ((sysinfo->dsize == 0x2) &&
+	    (readl(&mmdc1->mpwrdlhwctl) & 0x0000000f))
 		errors |= 32;
 
 	debug("Ending Write Delay calibration. Error mask: 0x%x\n", errors);
@@ -529,14 +537,18 @@ int mmdc_do_dqs_calibration(void)
 	debug("Read DQS gating calibration:\n");
 	debug("\tMPDGCTRL0 PHY0 = 0x%08X\n", readl(&mmdc0->mpdgctrl0));
 	debug("\tMPDGCTRL1 PHY0 = 0x%08X\n", readl(&mmdc0->mpdgctrl1));
-	debug("\tMPDGCTRL0 PHY1 = 0x%08X\n", readl(&mmdc1->mpdgctrl0));
-	debug("\tMPDGCTRL1 PHY1 = 0x%08X\n", readl(&mmdc1->mpdgctrl1));
+	if (sysinfo->dsize == 2) {
+		debug("\tMPDGCTRL0 PHY1 = 0x%08X\n", readl(&mmdc1->mpdgctrl0));
+		debug("\tMPDGCTRL1 PHY1 = 0x%08X\n", readl(&mmdc1->mpdgctrl1));
+	}
 	debug("Read calibration:\n");
 	debug("\tMPRDDLCTL PHY0 = 0x%08X\n", readl(&mmdc0->mprddlctl));
-	debug("\tMPRDDLCTL PHY1 = 0x%08X\n", readl(&mmdc1->mprddlctl));
+	if (sysinfo->dsize == 2)
+		debug("\tMPRDDLCTL PHY1 = 0x%08X\n", readl(&mmdc1->mprddlctl));
 	debug("Write calibration:\n");
 	debug("\tMPWRDLCTL PHY0 = 0x%08X\n", readl(&mmdc0->mpwrdlctl));
-	debug("\tMPWRDLCTL PHY1 = 0x%08X\n", readl(&mmdc1->mpwrdlctl));
+	if (sysinfo->dsize == 2)
+		debug("\tMPWRDLCTL PHY1 = 0x%08X\n", readl(&mmdc1->mpwrdlctl));
 
 	/*
 	 * Registers below are for debugging purposes.  These print out
@@ -548,10 +560,12 @@ int mmdc_do_dqs_calibration(void)
 	debug("\tMPDGHWST1 PHY0 = 0x%08x\n", readl(&mmdc0->mpdghwst1));
 	debug("\tMPDGHWST2 PHY0 = 0x%08x\n", readl(&mmdc0->mpdghwst2));
 	debug("\tMPDGHWST3 PHY0 = 0x%08x\n", readl(&mmdc0->mpdghwst3));
-	debug("\tMPDGHWST0 PHY1 = 0x%08x\n", readl(&mmdc1->mpdghwst0));
-	debug("\tMPDGHWST1 PHY1 = 0x%08x\n", readl(&mmdc1->mpdghwst1));
-	debug("\tMPDGHWST2 PHY1 = 0x%08x\n", readl(&mmdc1->mpdghwst2));
-	debug("\tMPDGHWST3 PHY1 = 0x%08x\n", readl(&mmdc1->mpdghwst3));
+	if (sysinfo->dsize == 2) {
+		debug("\tMPDGHWST0 PHY1 = 0x%08x\n", readl(&mmdc1->mpdghwst0));
+		debug("\tMPDGHWST1 PHY1 = 0x%08x\n", readl(&mmdc1->mpdghwst1));
+		debug("\tMPDGHWST2 PHY1 = 0x%08x\n", readl(&mmdc1->mpdghwst2));
+		debug("\tMPDGHWST3 PHY1 = 0x%08x\n", readl(&mmdc1->mpdghwst3));
+	}
 
 	debug("Final do_dqs_calibration error mask: 0x%x\n", errors);
 
diff --git a/arch/arm/include/asm/arch-mx6/mx6-ddr.h b/arch/arm/include/asm/arch-mx6/mx6-ddr.h
index 53eb5fa..cd5bc97 100644
--- a/arch/arm/include/asm/arch-mx6/mx6-ddr.h
+++ b/arch/arm/include/asm/arch-mx6/mx6-ddr.h
@@ -459,8 +459,8 @@ void mx6sl_dram_iocfg(unsigned width,
 		      const struct mx6sl_iomux_grp_regs *);
 
 #if defined(CONFIG_MX6QDL) || defined(CONFIG_MX6Q) || defined(CONFIG_MX6D)
-int mmdc_do_write_level_calibration(void);
-int mmdc_do_dqs_calibration(void);
+int mmdc_do_write_level_calibration(struct mx6_ddr_sysinfo const *sysinfo);
+int mmdc_do_dqs_calibration(struct mx6_ddr_sysinfo const *sysinfo);
 #endif
 
 /* configure mx6 mmdc registers */
diff --git a/board/kosagi/novena/novena_spl.c b/board/kosagi/novena/novena_spl.c
index 92c61ae..b934d36 100644
--- a/board/kosagi/novena/novena_spl.c
+++ b/board/kosagi/novena/novena_spl.c
@@ -605,8 +605,8 @@ void board_init_f(ulong dummy)
 
 	/* Perform DDR DRAM calibration */
 	udelay(100);
-	mmdc_do_write_level_calibration();
-	mmdc_do_dqs_calibration();
+	mmdc_do_write_level_calibration(&novena_ddr_info);
+	mmdc_do_dqs_calibration(&novena_ddr_info);
 
 	/* Clear the BSS. */
 	memset(__bss_start, 0, __bss_end - __bss_start);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [U-Boot] [PATCH V2 3/4] mx6: ddr: add routine to return DDR calibration data
  2016-10-30 23:33         ` [U-Boot] [PATCH V2 0/4] mx6: ddr: updates for dynamic DDR calibration Eric Nelson
  2016-10-30 23:33           ` [U-Boot] [PATCH V2 1/4] mx6: ddr: allow 32 cycles for DQS gating calibration Eric Nelson
  2016-10-30 23:33           ` [U-Boot] [PATCH V2 2/4] mx6: ddr: pass mx6_ddr_sysinfo to calibration routines Eric Nelson
@ 2016-10-30 23:33           ` Eric Nelson
  2016-10-30 23:33           ` [U-Boot] [PATCH V2 4/4] ARM: mx6: ddr: use Kconfig for inclusion of DDR calibration routines Eric Nelson
                             ` (2 subsequent siblings)
  5 siblings, 0 replies; 44+ messages in thread
From: Eric Nelson @ 2016-10-30 23:33 UTC (permalink / raw)
  To: u-boot

Add routine mmdc_read_calibration() to return the output of DDR
calibration. This can be used for debugging or to aid in construction
of static memory configuration.

This routine will be used in a subsequent patch set adding a virtual
"mx6memcal" board, but could also be useful when gathering statistics
during an initial production run.

Signed-off-by: Eric Nelson <eric@nelint.com>
---
Commit message expanded in V2

 arch/arm/cpu/armv7/mx6/ddr.c            | 23 +++++++++++++++++++++++
 arch/arm/include/asm/arch-mx6/mx6-ddr.h |  2 ++
 2 files changed, 25 insertions(+)

diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c
index 274a0ba..b12fb64 100644
--- a/arch/arm/cpu/armv7/mx6/ddr.c
+++ b/arch/arm/cpu/armv7/mx6/ddr.c
@@ -1501,6 +1501,29 @@ void mx6_ddr3_cfg(const struct mx6_ddr_sysinfo *sysinfo,
 	mdelay(1);
 }
 
+void mmdc_read_calibration(struct mx6_ddr_sysinfo const *sysinfo,
+                           struct mx6_mmdc_calibration *calib)
+{
+	struct mmdc_p_regs *mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR;
+	struct mmdc_p_regs *mmdc1 = (struct mmdc_p_regs *)MMDC_P1_BASE_ADDR;
+
+	calib->p0_mpwldectrl0 = readl(&mmdc0->mpwldectrl0);
+	calib->p0_mpwldectrl1 = readl(&mmdc0->mpwldectrl1);
+	calib->p0_mpdgctrl0 = readl(&mmdc0->mpdgctrl0);
+	calib->p0_mpdgctrl1 = readl(&mmdc0->mpdgctrl1);
+	calib->p0_mprddlctl = readl(&mmdc0->mprddlctl);
+	calib->p0_mpwrdlctl = readl(&mmdc0->mpwrdlctl);
+
+	if (sysinfo->dsize == 2) {
+		calib->p1_mpwldectrl0 = readl(&mmdc1->mpwldectrl0);
+		calib->p1_mpwldectrl1 = readl(&mmdc1->mpwldectrl1);
+		calib->p1_mpdgctrl0 = readl(&mmdc1->mpdgctrl0);
+		calib->p1_mpdgctrl1 = readl(&mmdc1->mpdgctrl1);
+		calib->p1_mprddlctl = readl(&mmdc1->mprddlctl);
+		calib->p1_mpwrdlctl = readl(&mmdc1->mpwrdlctl);
+	}
+}
+
 void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo,
 		  const struct mx6_mmdc_calibration *calib,
 		  const void *ddr_cfg)
diff --git a/arch/arm/include/asm/arch-mx6/mx6-ddr.h b/arch/arm/include/asm/arch-mx6/mx6-ddr.h
index cd5bc97..12454fa 100644
--- a/arch/arm/include/asm/arch-mx6/mx6-ddr.h
+++ b/arch/arm/include/asm/arch-mx6/mx6-ddr.h
@@ -461,6 +461,8 @@ void mx6sl_dram_iocfg(unsigned width,
 #if defined(CONFIG_MX6QDL) || defined(CONFIG_MX6Q) || defined(CONFIG_MX6D)
 int mmdc_do_write_level_calibration(struct mx6_ddr_sysinfo const *sysinfo);
 int mmdc_do_dqs_calibration(struct mx6_ddr_sysinfo const *sysinfo);
+void mmdc_read_calibration(struct mx6_ddr_sysinfo const *sysinfo,
+                           struct mx6_mmdc_calibration *calib);
 #endif
 
 /* configure mx6 mmdc registers */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [U-Boot] [PATCH V2 4/4] ARM: mx6: ddr: use Kconfig for inclusion of DDR calibration routines
  2016-10-30 23:33         ` [U-Boot] [PATCH V2 0/4] mx6: ddr: updates for dynamic DDR calibration Eric Nelson
                             ` (2 preceding siblings ...)
  2016-10-30 23:33           ` [U-Boot] [PATCH V2 3/4] mx6: ddr: add routine to return DDR calibration data Eric Nelson
@ 2016-10-30 23:33           ` Eric Nelson
  2016-11-22 10:59           ` [U-Boot] [PATCH V2 0/4] mx6: ddr: updates for dynamic DDR calibration Christoph Fritz
  2016-11-29 16:28           ` Stefano Babic
  5 siblings, 0 replies; 44+ messages in thread
From: Eric Nelson @ 2016-10-30 23:33 UTC (permalink / raw)
  To: u-boot

The DDR calibration routines are gated by conditionals for the
i.MX6DQ SOCs, but with the use of the sysinfo parameter, these
are usable on at least i.MX6SDL and i.MX6SL variants with DDR3.

Also, since only the Novena board currently uses the dynamic
DDR calibration routines, these routines waste space on other
boards using SPL.

Add a KConfig entry to allow boards to selectively include the
DDR calibration routines.

Signed-off-by: Eric Nelson <eric@nelint.com>
---
 arch/arm/cpu/armv7/mx6/Kconfig          | 8 ++++++++
 arch/arm/cpu/armv7/mx6/ddr.c            | 3 +--
 arch/arm/include/asm/arch-mx6/mx6-ddr.h | 2 +-
 configs/novena_defconfig                | 1 +
 4 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/arch/arm/cpu/armv7/mx6/Kconfig b/arch/arm/cpu/armv7/mx6/Kconfig
index 762a581..8b2217e 100644
--- a/arch/arm/cpu/armv7/mx6/Kconfig
+++ b/arch/arm/cpu/armv7/mx6/Kconfig
@@ -35,6 +35,14 @@ config MX6ULL
 	bool
 	select MX6UL
 
+config MX6_DDRCAL
+	bool "Include dynamic DDR calibration routines"
+	depends on SPL
+	default n
+	help
+	  Say "Y" if your board uses dynamic (per-boot) DDR calibration.
+	  If unsure, say N.
+
 choice
 	prompt "MX6 board select"
 	optional
diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c
index b12fb64..0cf391e 100644
--- a/arch/arm/cpu/armv7/mx6/ddr.c
+++ b/arch/arm/cpu/armv7/mx6/ddr.c
@@ -14,8 +14,7 @@
 #include <asm/types.h>
 #include <wait_bit.h>
 
-#if defined(CONFIG_MX6QDL) || defined(CONFIG_MX6Q) || defined(CONFIG_MX6D)
-
+#if defined(CONFIG_MX6_DDRCAL)
 static void reset_read_data_fifos(void)
 {
 	struct mmdc_p_regs *mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR;
diff --git a/arch/arm/include/asm/arch-mx6/mx6-ddr.h b/arch/arm/include/asm/arch-mx6/mx6-ddr.h
index 12454fa..2a8d443 100644
--- a/arch/arm/include/asm/arch-mx6/mx6-ddr.h
+++ b/arch/arm/include/asm/arch-mx6/mx6-ddr.h
@@ -458,7 +458,7 @@ void mx6sl_dram_iocfg(unsigned width,
 		      const struct mx6sl_iomux_ddr_regs *,
 		      const struct mx6sl_iomux_grp_regs *);
 
-#if defined(CONFIG_MX6QDL) || defined(CONFIG_MX6Q) || defined(CONFIG_MX6D)
+#if defined(CONFIG_MX6_DDRCAL)
 int mmdc_do_write_level_calibration(struct mx6_ddr_sysinfo const *sysinfo);
 int mmdc_do_dqs_calibration(struct mx6_ddr_sysinfo const *sysinfo);
 void mmdc_read_calibration(struct mx6_ddr_sysinfo const *sysinfo,
diff --git a/configs/novena_defconfig b/configs/novena_defconfig
index 1ffdddc..9d47d5b 100644
--- a/configs/novena_defconfig
+++ b/configs/novena_defconfig
@@ -3,6 +3,7 @@ CONFIG_ARCH_MX6=y
 CONFIG_SPL_GPIO_SUPPORT=y
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_MX6_DDRCAL=y
 CONFIG_TARGET_KOSAGI_NOVENA=y
 CONFIG_SPL_EXT_SUPPORT=y
 CONFIG_SPL_FAT_SUPPORT=y
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [U-Boot] [RFC PATCH 0/9] ARM: imx: mx6: Add virtual mx6memcal board
  2016-10-30 23:10       ` Eric Nelson
  2016-10-30 23:33         ` [U-Boot] [PATCH V2 0/4] mx6: ddr: updates for dynamic DDR calibration Eric Nelson
@ 2016-11-01 20:13         ` Eric Nelson
  2016-11-01 20:13           ` [U-Boot] [RFC PATCH 1/9] mx6: Add board mx6memcal for use in validating DDR Eric Nelson
                             ` (9 more replies)
  1 sibling, 10 replies; 44+ messages in thread
From: Eric Nelson @ 2016-11-01 20:13 UTC (permalink / raw)
  To: u-boot

This patch series adds a DDR calibration tool in the form of a
virtual i.MX6 board named "mx6memcal".

I was hoping to send this without the RFC, but found something that
needs some investigation in the process of cleanup (see ccgr_init in
patch 1) and would like to get it out so that others can experiment
and so I can get some additional feedback.

The board is added in patch 1.

The second patch is kept separate because I don't yet know why this
is needed. If the initial calibration is left as all zero, the 
calibration of the Nitrogen6_Max board will fail. Other boards don't
appear to have this problem.

The rest of the patches add configurations for use in testing.

Most of the boards are supported in main-line U-Boot, though I did
add the Nitrogen6_max board as a test of a 4GiB DDR arrangement.

The 'tr1x' board is a custom design that uses i.MX6SL and DDR3 that
I've been testing against and it works fine.

The mx6slevk and warp boards aren't currently supported because LPDDR2
isn't fully supported.

I did have them working in a local tree that pre-dated Marek's addition
of the calibration code into main-line:

    https://github.com/ericnelsonaz/u-boot/tree/memcal-pass1

Finally, as noted in the commit message, I saw some quirkiness with
a Wandboard Quad. For some reason, the dynamic calibration failed on
this platform when I selected 64-bit bus width and I haven't taken
time to investigate.

Eric Nelson (9):
  mx6: Add board mx6memcal for use in validating DDR
  mx6memcal: zero values for MPWRDLCTL cause read DQS calibration errors
  mx6memcal: add configuration for SABRE Lite
  mx6memcal: add configuration for Nitrogen6_max board
  mx6memcal: add configuration for tr1x board (i.MX6SL with DDR3)
  mx6memcal: add configuration for Wandboard Solo (512MiB of x32 DDR3)
  mx6memcal: add configuration for Wandboard Quad
  mx6memcal: add configuration for mx6slevk
  mx6memcal: add configuration for warp board (i.MX6SL)

 arch/arm/cpu/armv7/mx6/Kconfig             |   9 +
 board/freescale/mx6memcal/Kconfig          | 235 +++++++++++++++
 board/freescale/mx6memcal/MAINTAINERS      |   7 +
 board/freescale/mx6memcal/Makefile         |  13 +
 board/freescale/mx6memcal/README           |  49 +++
 board/freescale/mx6memcal/mx6memcal.c      |  32 ++
 board/freescale/mx6memcal/spl.c            | 462 +++++++++++++++++++++++++++++
 configs/mx6memcal_defconfig                |  32 ++
 configs/mx6memcal_mx6slevk_defconfig       |  37 +++
 configs/mx6memcal_nitrogen6_max_defconfig  |  33 +++
 configs/mx6memcal_sabrelite_defconfig      |  34 +++
 configs/mx6memcal_tr1x_defconfig           |  36 +++
 configs/mx6memcal_wandboard_quad_defconfig |  34 +++
 configs/mx6memcal_wandboard_solo_defconfig |  35 +++
 configs/mx6memcal_warpboard_defconfig      |  39 +++
 include/configs/mx6memcal.h                |  62 ++++
 scripts/config_whitelist.txt               |   5 +
 17 files changed, 1154 insertions(+)
 create mode 100644 board/freescale/mx6memcal/Kconfig
 create mode 100644 board/freescale/mx6memcal/MAINTAINERS
 create mode 100644 board/freescale/mx6memcal/Makefile
 create mode 100644 board/freescale/mx6memcal/README
 create mode 100644 board/freescale/mx6memcal/mx6memcal.c
 create mode 100644 board/freescale/mx6memcal/spl.c
 create mode 100644 configs/mx6memcal_defconfig
 create mode 100644 configs/mx6memcal_mx6slevk_defconfig
 create mode 100644 configs/mx6memcal_nitrogen6_max_defconfig
 create mode 100644 configs/mx6memcal_sabrelite_defconfig
 create mode 100644 configs/mx6memcal_tr1x_defconfig
 create mode 100644 configs/mx6memcal_wandboard_quad_defconfig
 create mode 100644 configs/mx6memcal_wandboard_solo_defconfig
 create mode 100644 configs/mx6memcal_warpboard_defconfig
 create mode 100644 include/configs/mx6memcal.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [U-Boot] [RFC PATCH 1/9] mx6: Add board mx6memcal for use in validating DDR
  2016-11-01 20:13         ` [U-Boot] [RFC PATCH 0/9] ARM: imx: mx6: Add virtual mx6memcal board Eric Nelson
@ 2016-11-01 20:13           ` Eric Nelson
  2017-07-14 14:18             ` Fabio Estevam
  2016-11-01 20:13           ` [U-Boot] [RFC PATCH 2/9] mx6memcal: zero values for MPWRDLCTL cause read DQS calibration errors Eric Nelson
                             ` (8 subsequent siblings)
  9 siblings, 1 reply; 44+ messages in thread
From: Eric Nelson @ 2016-11-01 20:13 UTC (permalink / raw)
  To: u-boot

This is a virtual "board" that uses configuration files and
Kconfig to define the memory layout used by a real board during
the board bring-up process.

It generates an SPL image that can be loaded using imx_usb or
SB_LOADER.exe.

When run, it will generate a set of calibration constants for
use in either or both a DCD configuration file for boards that
use u-boot.imx or struct mx6_mmdc_calibration for boards that
boot via SPL.

In essence, it is a configurable, open-source variant of the
Freescale ddr-stress tool.

	https://community.nxp.com/docs/DOC-105652

File mx6memcal_defconfig configures the board for use with
mx6sabresd or mx6qsabreauto.

Signed-off-by: Eric Nelson <eric@nelint.com>
---
 arch/arm/cpu/armv7/mx6/Kconfig        |   9 +
 board/freescale/mx6memcal/Kconfig     | 235 +++++++++++++++++
 board/freescale/mx6memcal/MAINTAINERS |   7 +
 board/freescale/mx6memcal/Makefile    |  13 +
 board/freescale/mx6memcal/README      |  49 ++++
 board/freescale/mx6memcal/mx6memcal.c |  32 +++
 board/freescale/mx6memcal/spl.c       | 458 ++++++++++++++++++++++++++++++++++
 configs/mx6memcal_defconfig           |  32 +++
 include/configs/mx6memcal.h           |  62 +++++
 scripts/config_whitelist.txt          |   5 +
 10 files changed, 902 insertions(+)
 create mode 100644 board/freescale/mx6memcal/Kconfig
 create mode 100644 board/freescale/mx6memcal/MAINTAINERS
 create mode 100644 board/freescale/mx6memcal/Makefile
 create mode 100644 board/freescale/mx6memcal/README
 create mode 100644 board/freescale/mx6memcal/mx6memcal.c
 create mode 100644 board/freescale/mx6memcal/spl.c
 create mode 100644 configs/mx6memcal_defconfig
 create mode 100644 include/configs/mx6memcal.h

diff --git a/arch/arm/cpu/armv7/mx6/Kconfig b/arch/arm/cpu/armv7/mx6/Kconfig
index 8b2217e..ac4b0fd 100644
--- a/arch/arm/cpu/armv7/mx6/Kconfig
+++ b/arch/arm/cpu/armv7/mx6/Kconfig
@@ -100,6 +100,14 @@ config TARGET_MX6CUBOXI
 	bool "Solid-run mx6 boards"
 	select SUPPORT_SPL
 
+config TARGET_MX6MEMCAL
+	bool "mx6memcal"
+	select SUPPORT_SPL
+	help
+	  The mx6memcal board is a virtual board that can be used to validate
+	  and characterize the memory layout of a new design during the initial
+	  development and pre-production stages.
+
 config TARGET_MX6QARM2
 	bool "mx6qarm2"
 
@@ -245,6 +253,7 @@ source "board/el/el6x/Kconfig"
 source "board/embest/mx6boards/Kconfig"
 source "board/engicam/icorem6/Kconfig"
 source "board/freescale/mx6qarm2/Kconfig"
+source "board/freescale/mx6memcal/Kconfig"
 source "board/freescale/mx6qsabreauto/Kconfig"
 source "board/freescale/mx6sabresd/Kconfig"
 source "board/freescale/mx6slevk/Kconfig"
diff --git a/board/freescale/mx6memcal/Kconfig b/board/freescale/mx6memcal/Kconfig
new file mode 100644
index 0000000..443804d
--- /dev/null
+++ b/board/freescale/mx6memcal/Kconfig
@@ -0,0 +1,235 @@
+if TARGET_MX6MEMCAL
+
+config SYS_BOARD
+	default "mx6memcal"
+
+config SYS_VENDOR
+	default "freescale"
+
+config SYS_CONFIG_NAME
+	default "mx6memcal"
+
+menu "mx6memcal specifics"
+choice
+	prompt "Serial console"
+	help
+	  Either UART1 or UART2 will be used as the console for
+	  displaying the calibration values or errors.
+
+config SERIAL_CONSOLE_UART1
+	bool "UART1"
+	help
+	  Select this if your board uses UART1 for its' console.
+
+config SERIAL_CONSOLE_UART2
+	bool "UART2"
+	help
+	  Select this if your board uses UART2 for its' console.
+
+endchoice
+
+choice
+	prompt "UART pads"
+	help
+	  Select the RX and TX pads used for your serial console.
+	  The choices below reflect the most commonly used options
+	  for your UART.
+
+	config UART2_EIM_D26_27
+		bool "UART2 on EIM_D26/27 (SabreLite, Nitrogen6x)"
+		depends on SERIAL_CONSOLE_UART2
+		help
+		  Choose this configuration if you're using pads
+		  EIM_D26 and D27 for a console on UART2.
+		  This is typical for designs that are based on the
+		  NXP SABRELite.
+
+	config UART1_CSI0_DAT10_11
+		bool "UART1 on CSI0_DAT10/11 (Wand)"
+		depends on SERIAL_CONSOLE_UART1
+		help
+		  Choose this configuration if you're using pads
+		  CSI0_DAT10 and DAT11 for a console on UART1 as
+		  is done on the i.MX6 Wand board.
+
+	config UART1_SD3_DAT6_7
+		bool "UART1 on SD3_DAT6/7 (SabreSD, SabreAuto)"
+		depends on SERIAL_CONSOLE_UART1
+		help
+		  Choose this configuration if you're using pads
+		  SD3_DAT6 and DAT7 for a console on UART1 as is
+		  done on the NXP SABRESD or SABREAUTO designs.
+
+	config UART1_UART1
+		bool "UART1 on UART1 (i.MX6SL EVK, WaRP)"
+		depends on SERIAL_CONSOLE_UART1
+		help
+		  Choose this configuration if you're using pads
+		  UART1_TXD/RXD for a console on UART1 as is done
+		  on most i.MX6SL designs.
+
+endchoice
+
+config IMXIMAGE_OUTPUT
+	bool "Include output for imximage .cfg files"
+	default y
+	help
+	  Say "Y" if you want output formatted for use in non-SPL
+	  (DCD-style) configuration files.
+
+config DDRWIDTH
+	int "DDR bus width"
+	default 64
+	help
+	  Select either 32 or 64 to reflect the DDR bus width.
+
+config DDRCS
+	int "DDR chip selects"
+	default 2
+	range 1 2
+	help
+	  Select the number of chip selects used in your board design
+
+choice
+	prompt "Memory type"
+	help
+	  Select the type of DDR (DDR3 or LPDDR2) used on your design
+
+config	DDR3
+	bool "DDR3"
+	help
+	  Select this if your board design uses DDR3.
+
+config	LPDDR2
+	bool "LPDDR2"
+	help
+	  Select this if your board design uses LPDDR2.
+
+endchoice
+
+choice
+	prompt "Memory device"
+
+config MT41K512M16TNA
+	bool "Micron MT41K512M16TNA 512Mx16 (1GiB/chip)"
+	depends on DDR3
+
+config MT41K128M16JT
+	bool "Micron MT41K128M16JT 128Mx16 (256 MiB/chip)"
+	depends on DDR3
+
+config H5TQ4G63AFR
+	bool "Hynix H5TQ4G63AFR 256Mx16 (512 MiB/chip)"
+	depends on DDR3
+
+config H5TQ2G63DFR
+	bool "Hynix H5TQ2G63DFR 128Mx16 (256 MiB/chip)"
+	depends on DDR3
+
+config MT42L256M32D2LG
+	bool "Micron MT42L256M32D2LG LPDDR2 256Mx32 (1GiB/chip)"
+	depends on LPDDR2
+
+config MT29PZZZ4D4BKESK
+	bool "Micron MT29PZZZ4D4BKESK multi-chip 512MiB LPDDR2/4GiB eMMC"
+	depends on LPDDR2
+
+endchoice
+
+config DDR_ODT
+	int "DDR On-die-termination"
+	default 2
+	range 0 7
+	help
+	  Enter the on-die termination value as an index defined for
+	  IOMUX settings for PAD_DRAM_SDCLK0_P and others.
+	  0 == Disabled
+	  1 == 120 Ohm
+	  2 == 60 Ohm
+	  3 == 40 Ohm
+	  4 == 30 Ohm
+	  5 == 24 Ohm
+	  6 == 20 Ohm
+	  7 == 17 Ohm
+	  Value will be applied to all clock and data lines
+
+
+config DRAM_DRIVE_STRENGTH
+	int "DRAM Drive strength"
+	default 6
+	range 0 7
+	help
+	  Enter drive strength as an index defined for IOMUX settings
+	  for GRP_B1DS and others.
+	  0 == Hi Z
+	  6 == 40 Ohm (default)
+	  7 == 34 Ohm
+	  Value will be applied to all clock and data lines
+
+config RTT_NOM
+	int "RTT_NOM"
+	default 1
+	range 1 2
+	help
+	  Enter the RTT_NOM selector
+	  1 == RZQ/4 (60ohm)
+	  2 == RZQ/2 (120ohm)
+
+config RTT_WR
+	int "RTT_WR"
+	default 1
+	range 0 2
+	help
+	  Enter the RTT_WR selector for MR2
+	  0 == Dynamic ODT disabled
+	  1 == RZQ/4 (60ohm)
+	  2 == RZQ/2 (120ohm)
+
+config RALAT
+	int "Read additional latency"
+	default 5
+	range 0 7
+	help
+	  Enter a latency in number of cycles. This will be added to
+	  CAS and internal delays for which the MMDC will retrieve the
+	  read data from the internal FIFO.
+	  This is used to compensate for board/chip delays.
+
+config WALAT
+	int "Write additional latency"
+	default 0
+	range 0 7
+	help
+	  Enter a latency in number of cycles. This will be added to
+	  CAS and internal delays for which the MMDC will retrieve the
+	  read data from the internal FIFO
+	  This is used to compensate for board/chip delays.
+
+config REFSEL
+	int "Refresh period"
+	range 0 3
+	default 1
+	help
+	  Select the DDR refresh period.
+	  See the description of bitfield REF_SEL in the reference manual
+	  for details.
+	  0 == disabled
+	  1 == 32 kHz
+	  2 == 64 kHz
+	  3 == fast counter
+
+config REFR
+	int "Number of refreshes"
+	range 0 7
+	default 7
+	help
+	   This selects the number of refreshes (-1) during each period.
+	   i.e.:
+	   0 == 1 refresh (tRFC)
+	   7 == 8 refreshes (tRFC*8)
+	   See the description of MDREF[REFR] in the reference manual for
+	   details.
+
+endmenu
+endif
+
diff --git a/board/freescale/mx6memcal/MAINTAINERS b/board/freescale/mx6memcal/MAINTAINERS
new file mode 100644
index 0000000..5da38f7
--- /dev/null
+++ b/board/freescale/mx6memcal/MAINTAINERS
@@ -0,0 +1,7 @@
+MX6MEMCAL BOARD
+M:	Eric Nelson <eric@nelint.com>
+S:	Maintained
+F:	board/freescale/mx6memcal/
+F:	include/configs/mx6memcal.h
+F:	configs/mx6memcal_defconfig
+
diff --git a/board/freescale/mx6memcal/Makefile b/board/freescale/mx6memcal/Makefile
new file mode 100644
index 0000000..2d7a6fa
--- /dev/null
+++ b/board/freescale/mx6memcal/Makefile
@@ -0,0 +1,13 @@
+#
+# Copyright (C) 2007, Guennadi Liakhovetski <lg@denx.de>
+#
+# (C) Copyright 2011 Freescale Semiconductor, Inc.
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+ifdef CONFIG_SPL_BUILD
+obj-y	:= spl.o
+else
+obj-y	:= mx6memcal.o
+endif
diff --git a/board/freescale/mx6memcal/README b/board/freescale/mx6memcal/README
new file mode 100644
index 0000000..9fe2fe2
--- /dev/null
+++ b/board/freescale/mx6memcal/README
@@ -0,0 +1,49 @@
+mx6memcal - a tool for calibrating DDR on i.MX6 boards.
+
+The mx6memcal board isn't a real board, but a tool for use in bring-up of
+new i.MX6 board designs.
+
+It provides a similar function to the tool from NXP([1]) with a number
+of advantages:
+
+1. It's open-source, so it's easier to change if needed.
+   Typical reasons for needing to change include the use of alternate
+   UARTs and PMIC initialization.
+2. It produces an image that's directly loadable with imx_usb [2] or
+   SB_LOADER.exe [3].
+   The NXP tool requires either a cumbersome JTAG connection that
+   makes running the DDR very slow or a working U-Boot image that
+   suffers from a chicken-and-egg problem (i.e. where do you get the
+   DDR parameters for U-Boot?).
+3. It doesn't prompt for parameters, so it's much faster to gather
+   data from multiple boards.
+4. Parameters to the calibration process can be chosen through
+   'make menuconfig'.
+
+When booted, the mx6memcal board will run the DDR calibration
+routines and display the result in a form suitable for cut and
+paste into struct mx6_mmdc_calibration. It can also optionally
+produce output in a form usable in a DCD-style .cfg file.
+
+Selections in Kconfig allow most system design settings to be chosen:
+
+1. The UART number and pad configuration for the UART. Options
+   include support for the most frequent reference designs on
+   i.MX6DQ/SDL (SABRE Lite and SABRESD designs).
+2. The memory bus width (64 and 32-bit)
+3. The number of chip-selects in use
+4. The type of DDR (DDR3 or LPDDR2). Note that LPDDR2 support
+   is incomplete as of this writing.
+5. The type of DDR chips in use. This selection allows re-use of common
+   parts and four DDR3 and two LPDDR2 parts are currently defined
+6. The On-die termination value for the DRAM lines
+7. The DRAM drive strength
+8. The RTT_NOM and RTT_WR termination settings
+9. RALAT/WALAT latency values
+
+References:
+[1] - NXP DDR Stress Test Tool - https://community.nxp.com/docs/DOC-105652
+[2] - Boundary Devices imx_usb_loader
+      https://github.com/boundarydevices/imx_usb_loader
+[3] - Use of SB_Loader.exe
+      https://boundarydevices.com/windows-users-and-unbricking
diff --git a/board/freescale/mx6memcal/mx6memcal.c b/board/freescale/mx6memcal/mx6memcal.c
new file mode 100644
index 0000000..afea0fb
--- /dev/null
+++ b/board/freescale/mx6memcal/mx6memcal.c
@@ -0,0 +1,32 @@
+/*
+ * mx6memcal board support - provides a minimal, UART-only
+ * U-Boot that's capable of running a memory test.
+ *
+ * Copyright (C) 2016 Nelson Integration, LLC
+ * Author: Eric Nelson <eric@nelint.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/sys_proto.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_init(void)
+{
+	return 0;
+}
+
+int checkboard(void)
+{
+	puts("Board: mx6memcal\n");
+	return 0;
+}
+
+int dram_init(void)
+{
+	gd->ram_size = imx_ddr_size();
+	return 0;
+}
+
diff --git a/board/freescale/mx6memcal/spl.c b/board/freescale/mx6memcal/spl.c
new file mode 100644
index 0000000..90e240f
--- /dev/null
+++ b/board/freescale/mx6memcal/spl.c
@@ -0,0 +1,458 @@
+/*
+ * Copyright (C) 2016 Nelson Integration, LLC
+ * Author: Eric Nelson <eric@nelint.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/iomux.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/crm_regs.h>
+#include <asm/arch/mx6-ddr.h>
+#include <asm/arch/mx6-pins.h>
+#include <asm/arch/sys_proto.h>
+#include <spl.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define UART_PAD_CTRL  (PAD_CTL_PUS_100K_UP |			\
+	PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm |			\
+	PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
+
+static iomux_v3_cfg_t const uart_pads[] = {
+#ifdef CONFIG_UART2_EIM_D26_27
+	IOMUX_PADS(PAD_EIM_D26__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
+	IOMUX_PADS(PAD_EIM_D27__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
+#elif defined(CONFIG_UART1_CSI0_DAT10_11)
+	IOMUX_PADS(PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
+	IOMUX_PADS(PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
+#elif defined(CONFIG_UART1_SD3_DAT6_7)
+	IOMUX_PADS(PAD_SD3_DAT6__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD3_DAT7__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
+#elif defined(CONFIG_UART1_UART1)
+	MX6_PAD_UART1_TXD__UART1_TXD | MUX_PAD_CTRL(UART_PAD_CTRL),
+	MX6_PAD_UART1_RXD__UART1_RXD | MUX_PAD_CTRL(UART_PAD_CTRL),
+#else
+#error select UART console pads
+#endif
+};
+
+#ifdef CONFIG_DDR3
+#define GRP_DDRTYPE	0x000C0000
+#else
+#define GRP_DDRTYPE	0x00080000
+#endif
+
+/* all existing designs have this disabled */
+#define DDR_PKE		0
+
+/* use Kconfig for ODT and DRIVE_STRENGTH */
+#define DDR_ODT	\
+	(CONFIG_DDR_ODT<<8)
+#define DRAM_DRIVE_STRENGTH \
+	(CONFIG_DRAM_DRIVE_STRENGTH << 3)
+
+/* configure MX6Q/DUAL mmdc DDR io registers */
+static struct mx6dq_iomux_ddr_regs const mx6dq_ddr_ioregs = {
+	/* SDCLK[0:1], CAS, RAS, Reset: Differential input, 40ohm */
+	.dram_sdclk_0 = DDR_ODT+DRAM_DRIVE_STRENGTH,
+	.dram_sdclk_1 = DDR_ODT+DRAM_DRIVE_STRENGTH,
+	.dram_cas = DDR_ODT+DRAM_DRIVE_STRENGTH,
+	.dram_ras = DDR_ODT+DRAM_DRIVE_STRENGTH,
+	.dram_reset = DDR_ODT+DRAM_DRIVE_STRENGTH,
+	/* SDCKE[0:1]: 100k pull-up */
+	.dram_sdcke0 = 0x00003000,
+	.dram_sdcke1 = 0x00003000,
+	/* SDBA2: pull-up disabled */
+	.dram_sdba2 = 0x00000000,
+	/* SDODT[0:1]: 100k pull-up, 40 ohm */
+	.dram_sdodt0 = 0x00003000+DRAM_DRIVE_STRENGTH,
+	.dram_sdodt1 = 0x00003000+DRAM_DRIVE_STRENGTH,
+	/* SDQS[0:7]: Differential input, 40 ohm */
+	.dram_sdqs0 = DRAM_DRIVE_STRENGTH,
+	.dram_sdqs1 = DRAM_DRIVE_STRENGTH,
+	.dram_sdqs2 = DRAM_DRIVE_STRENGTH,
+	.dram_sdqs3 = DRAM_DRIVE_STRENGTH,
+	.dram_sdqs4 = DRAM_DRIVE_STRENGTH,
+	.dram_sdqs5 = DRAM_DRIVE_STRENGTH,
+	.dram_sdqs6 = DRAM_DRIVE_STRENGTH,
+	.dram_sdqs7 = DRAM_DRIVE_STRENGTH,
+
+	/* DQM[0:7]: Differential input, 40 ohm */
+	.dram_dqm0 = DDR_ODT+DRAM_DRIVE_STRENGTH,
+	.dram_dqm1 = DDR_ODT+DRAM_DRIVE_STRENGTH,
+	.dram_dqm2 = DDR_ODT+DRAM_DRIVE_STRENGTH,
+	.dram_dqm3 = DDR_ODT+DRAM_DRIVE_STRENGTH,
+	.dram_dqm4 = DDR_ODT+DRAM_DRIVE_STRENGTH,
+	.dram_dqm5 = DDR_ODT+DRAM_DRIVE_STRENGTH,
+	.dram_dqm6 = DDR_ODT+DRAM_DRIVE_STRENGTH,
+	.dram_dqm7 = DDR_ODT+DRAM_DRIVE_STRENGTH,
+};
+
+/* configure MX6Q/DUAL mmdc GRP io registers */
+static struct mx6dq_iomux_grp_regs const mx6dq_grp_ioregs = {
+	/* DDR3 */
+	.grp_ddr_type = GRP_DDRTYPE,
+	.grp_ddrmode_ctl = DDR_ODT,
+	/* disable DDR pullups */
+	.grp_ddrpke = DDR_PKE,
+	/* ADDR[00:16], SDBA[0:1]: 40 ohm */
+	.grp_addds = DRAM_DRIVE_STRENGTH,
+	/* CS0/CS1/SDBA2/CKE0/CKE1/SDWE: 40 ohm */
+	.grp_ctlds = DRAM_DRIVE_STRENGTH,
+	/* DATA[00:63]: Differential input, 40 ohm */
+	.grp_ddrmode = DDR_ODT,
+	.grp_b0ds = DRAM_DRIVE_STRENGTH,
+	.grp_b1ds = DRAM_DRIVE_STRENGTH,
+	.grp_b2ds = DRAM_DRIVE_STRENGTH,
+	.grp_b3ds = DRAM_DRIVE_STRENGTH,
+	.grp_b4ds = DRAM_DRIVE_STRENGTH,
+	.grp_b5ds = DRAM_DRIVE_STRENGTH,
+	.grp_b6ds = DRAM_DRIVE_STRENGTH,
+	.grp_b7ds = DRAM_DRIVE_STRENGTH,
+};
+
+static struct mx6sdl_iomux_ddr_regs const mx6sdl_ddr_ioregs = {
+	/* SDCLK[0:1], CAS, RAS, Reset: Differential input, 40ohm */
+	.dram_sdclk_0 = DDR_ODT+DRAM_DRIVE_STRENGTH,
+	.dram_sdclk_1 = DDR_ODT+DRAM_DRIVE_STRENGTH,
+	.dram_cas = DDR_ODT+DRAM_DRIVE_STRENGTH,
+	.dram_ras = DDR_ODT+DRAM_DRIVE_STRENGTH,
+	.dram_reset = DDR_ODT+DRAM_DRIVE_STRENGTH,
+	/* SDCKE[0:1]: 100k pull-up */
+	.dram_sdcke0 = 0x00003000,
+	.dram_sdcke1 = 0x00003000,
+	/* SDBA2: pull-up disabled */
+	.dram_sdba2 = 0x00000000,
+	/* SDODT[0:1]: 100k pull-up, 40 ohm */
+	.dram_sdodt0 = 0x00003000+DRAM_DRIVE_STRENGTH,
+	.dram_sdodt1 = 0x00003000+DRAM_DRIVE_STRENGTH,
+	/* SDQS[0:7]: Differential input, 40 ohm */
+	.dram_sdqs0 = DRAM_DRIVE_STRENGTH,
+	.dram_sdqs1 = DRAM_DRIVE_STRENGTH,
+	.dram_sdqs2 = DRAM_DRIVE_STRENGTH,
+	.dram_sdqs3 = DRAM_DRIVE_STRENGTH,
+	.dram_sdqs4 = DRAM_DRIVE_STRENGTH,
+	.dram_sdqs5 = DRAM_DRIVE_STRENGTH,
+	.dram_sdqs6 = DRAM_DRIVE_STRENGTH,
+	.dram_sdqs7 = DRAM_DRIVE_STRENGTH,
+
+	/* DQM[0:7]: Differential input, 40 ohm */
+	.dram_dqm0 = DDR_ODT+DRAM_DRIVE_STRENGTH,
+	.dram_dqm1 = DDR_ODT+DRAM_DRIVE_STRENGTH,
+	.dram_dqm2 = DDR_ODT+DRAM_DRIVE_STRENGTH,
+	.dram_dqm3 = DDR_ODT+DRAM_DRIVE_STRENGTH,
+	.dram_dqm4 = DDR_ODT+DRAM_DRIVE_STRENGTH,
+	.dram_dqm5 = DDR_ODT+DRAM_DRIVE_STRENGTH,
+	.dram_dqm6 = DDR_ODT+DRAM_DRIVE_STRENGTH,
+	.dram_dqm7 = DDR_ODT+DRAM_DRIVE_STRENGTH,
+};
+
+/* configure MX6SOLO/DUALLITE mmdc GRP io registers */
+static struct mx6sdl_iomux_grp_regs const mx6sdl_grp_ioregs = {
+	/* DDR3 */
+	.grp_ddr_type = GRP_DDRTYPE,
+	/* SDQS[0:7]: Differential input, 40 ohm */
+	.grp_ddrmode_ctl = DDR_ODT,
+	/* disable DDR pullups */
+	.grp_ddrpke = DDR_PKE,
+	/* ADDR[00:16], SDBA[0:1]: 40 ohm */
+	.grp_addds = DRAM_DRIVE_STRENGTH,
+	/* CS0/CS1/SDBA2/CKE0/CKE1/SDWE: 40 ohm */
+	.grp_ctlds = DRAM_DRIVE_STRENGTH,
+	/* DATA[00:63]: Differential input, 40 ohm */
+	.grp_ddrmode = DDR_ODT,
+	.grp_b0ds = DRAM_DRIVE_STRENGTH,
+	.grp_b1ds = DRAM_DRIVE_STRENGTH,
+	.grp_b2ds = DRAM_DRIVE_STRENGTH,
+	.grp_b3ds = DRAM_DRIVE_STRENGTH,
+	.grp_b4ds = DRAM_DRIVE_STRENGTH,
+	.grp_b5ds = DRAM_DRIVE_STRENGTH,
+	.grp_b6ds = DRAM_DRIVE_STRENGTH,
+	.grp_b7ds = DRAM_DRIVE_STRENGTH,
+};
+
+const struct mx6sl_iomux_ddr_regs mx6sl_ddr_ioregs = {
+	.dram_sdqs0 = DRAM_DRIVE_STRENGTH,
+	.dram_sdqs1 = DRAM_DRIVE_STRENGTH,
+	.dram_sdqs2 = DRAM_DRIVE_STRENGTH,
+	.dram_sdqs3 = DRAM_DRIVE_STRENGTH,
+	.dram_dqm0 = DRAM_DRIVE_STRENGTH,
+	.dram_dqm1 = DRAM_DRIVE_STRENGTH,
+	.dram_dqm2 = DRAM_DRIVE_STRENGTH,
+	.dram_dqm3 = DRAM_DRIVE_STRENGTH,
+	.dram_cas  = DRAM_DRIVE_STRENGTH,
+	.dram_ras  = DRAM_DRIVE_STRENGTH,
+	.dram_sdclk_0 = DRAM_DRIVE_STRENGTH,
+	.dram_reset = DRAM_DRIVE_STRENGTH,
+	.dram_sdba2 = 0x00020000,
+	.dram_odt0 = 0x00030000+DRAM_DRIVE_STRENGTH,
+	.dram_odt1 = 0x00030000+DRAM_DRIVE_STRENGTH,
+};
+
+const struct mx6sl_iomux_grp_regs mx6sl_grp_ioregs = {
+	.grp_b0ds = DRAM_DRIVE_STRENGTH,
+	.grp_b1ds = DRAM_DRIVE_STRENGTH,
+	.grp_b2ds = DRAM_DRIVE_STRENGTH,
+	.grp_b3ds = DRAM_DRIVE_STRENGTH,
+	.grp_addds = DRAM_DRIVE_STRENGTH,
+	.grp_ctlds = DRAM_DRIVE_STRENGTH,
+	.grp_ddrmode_ctl = DDR_ODT,
+	.grp_ddrpke = DDR_PKE,
+	.grp_ddrmode = DDR_ODT,
+	.grp_ddr_type = GRP_DDRTYPE,
+};
+
+static struct mx6_ddr_sysinfo const sysinfo = {
+	/* width of data bus:0=16,1=32,2=64 */
+#if CONFIG_DDRWIDTH == 32
+	.dsize = 1,
+#elif CONFIG_DDRWIDTH == 64
+	.dsize = 2,
+#else
+#error missing CONFIG_DDRWIDTH
+#endif
+	/* config for full 4GB range so that get_mem_size() works */
+	.cs_density = 32, /* 32Gb per CS */
+
+	/* # of chip selects */
+	.ncs = CONFIG_DDRCS,
+	.cs1_mirror = 0,
+	.bi_on = 1,	/* Bank interleaving enabled */
+	.rtt_nom = CONFIG_RTT_NOM,
+	.rtt_wr = CONFIG_RTT_WR,
+	.ralat = CONFIG_RALAT,	/* Read additional latency */
+	.walat = CONFIG_WALAT,	/* Write additional latency */
+	.mif3_mode = 3,	/* Command prediction working mode */
+#ifdef CONFIG_DDR3
+	.rst_to_cke = 0x23,	/* 33 cycles, 500us (JEDEC default) */
+	.sde_to_rst = 0x10,	/* JEDEC value for LPDDR2 - 200us */
+	.pd_fast_exit = 0,	/* immaterial for calibration */
+	.ddr_type = DDR_TYPE_DDR3,
+#else
+	.rst_to_cke = 0x10,	/* JEDEC value for LPDDR2: 200us */
+	.sde_to_rst = 0,	/* LPDDR2 does not need this field */
+	.pd_fast_exit = 0,	/* immaterial for calibration */
+	.ddr_type = DDR_TYPE_LPDDR2,
+#endif
+	.refsel = CONFIG_REFSEL,
+	.refr = CONFIG_REFR,
+};
+
+#ifdef CONFIG_MT41K512M16TNA
+/* Micron MT41K512M16TNA-125 */
+static struct mx6_ddr3_cfg const ddrtype = {
+	.mem_speed = 1600,
+	.density = 8,
+	.width = 16,
+	.banks = 8,
+	.rowaddr = 15,
+	.coladdr = 10,
+	.pagesz = 1,
+	.trcd = 1375,
+	.trcmin = 5062,
+	.trasmin = 3750,
+};
+#elif defined(CONFIG_MT41K128M16JT)
+/* Micron MT41K128M16JT-125 */
+static struct mx6_ddr3_cfg const ddrtype = {
+	.mem_speed = 1600,
+	.density = 2,
+	.width = 16,
+	.banks = 8,
+	.rowaddr = 14,
+	.coladdr = 10,
+	.pagesz = 2,
+	.trcd = 1375,
+	.trcmin = 4875,
+	.trasmin = 3500,
+};
+#elif defined(CONFIG_H5TQ4G63AFR)
+/* Hynix H5TQ4G63AFR */
+static struct mx6_ddr3_cfg const ddrtype = {
+	.mem_speed = 1600,
+	.density = 4,
+	.width = 16,
+	.banks = 8,
+	.rowaddr = 15,
+	.coladdr = 10,
+	.pagesz = 2,
+	.trcd = 1375,
+	.trcmin = 4875,
+	.trasmin = 3500,
+};
+#elif defined CONFIG_H5TQ2G63DFR
+/* Hynix H5TQ2G63DFR */
+static struct mx6_ddr3_cfg const ddrtype = {
+	.mem_speed = 1333,
+	.density = 2,
+	.width = 16,
+	.banks = 8,
+	.rowaddr = 14,
+	.coladdr = 10,
+	.pagesz = 2,
+	.trcd = 1350,
+	.trcmin = 4950,
+	.trasmin = 3600,
+};
+#elif defined(CONFIG_MT42L256M32D2LG)
+/* Micron MT42L256M32D2LG */
+static struct mx6_lpddr2_cfg ddrtype = {
+	.mem_speed = 800,
+	.density = 4,
+	.width = 32,
+	.banks = 8,
+	.rowaddr = 14,
+	.coladdr = 10,
+	.trcd_lp = 2000,
+	.trppb_lp = 2000,
+	.trpab_lp = 2250,
+	.trasmin = 4200,
+};
+#elif defined(CONFIG_MT29PZZZ4D4BKESK)
+/* Micron MT29PZZZ4D4BKESK */
+static struct mx6_lpddr2_cfg ddrtype = {
+	.mem_speed = 800,
+	.density = 4,
+	.width = 32,
+	.banks = 8,
+	.rowaddr = 14,
+	.coladdr = 10,
+	.trcd_lp = 2000,
+	.trppb_lp = 2000,
+	.trpab_lp = 2250,
+	.trasmin = 4200,
+};
+#else
+#error please select DDR type using menuconfig
+#endif
+
+static void ccgr_init(void)
+{
+	struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+
+	/* FIXME: these should probably be checked, especially
+	 * for i.MX6SL, UL, ULL
+	 */
+	writel(0x00C03F3F, &ccm->CCGR0);
+	writel(0x0030FC03, &ccm->CCGR1);
+	writel(0x0FFFC000, &ccm->CCGR2);
+	writel(0x3FF00000, &ccm->CCGR3);
+	writel(0x00FFF300, &ccm->CCGR4);
+	writel(0x0F0000C3, &ccm->CCGR5);
+	writel(0x000003FF, &ccm->CCGR6);
+}
+
+static void display_calibration(struct mx6_mmdc_calibration *calib)
+{
+	printf(".p0_mpdgctrl0\t= 0x%08X\n", calib->p0_mpdgctrl0);
+	printf(".p0_mpdgctrl1\t= 0x%08X\n", calib->p0_mpdgctrl1);
+	printf(".p0_mprddlctl\t= 0x%08X\n", calib->p0_mprddlctl);
+	printf(".p0_mpwrdlctl\t= 0x%08X\n", calib->p0_mpwrdlctl);
+	printf(".p0_mpwldectrl0\t= 0x%08X\n", calib->p0_mpwldectrl0);
+	printf(".p0_mpwldectrl1\t= 0x%08X\n", calib->p0_mpwldectrl1);
+	if (sysinfo.dsize == 2) {
+		printf(".p1_mpdgctrl0\t= 0x%08X\n", calib->p1_mpdgctrl0);
+		printf(".p1_mpdgctrl1\t= 0x%08X\n", calib->p1_mpdgctrl1);
+		printf(".p1_mprddlctl\t= 0x%08X\n", calib->p1_mprddlctl);
+		printf(".p1_mpwrdlctl\t= 0x%08X\n", calib->p1_mpwrdlctl);
+		printf(".p1_mpwldectrl0\t= 0x%08X\n", calib->p1_mpwldectrl0);
+		printf(".p1_mpwldectrl1\t= 0x%08X\n", calib->p1_mpwldectrl1);
+	}
+#ifdef CONFIG_IMXIMAGE_OUTPUT
+	printf("DATA 4 MX6_MMDC_P0_MPDGCTRL0\t= 0x%08X\n", calib->p0_mpdgctrl0);
+	printf("DATA 4 MX6_MMDC_P0_MPDGCTRL1\t= 0x%08X\n", calib->p0_mpdgctrl1);
+	printf("DATA 4 MX6_MMDC_P0_MPRDDLCTL\t= 0x%08X\n", calib->p0_mprddlctl);
+	printf("DATA 4 MX6_MMDC_P0_MPWRDLCTL\t= 0x%08X\n", calib->p0_mpwrdlctl);
+	printf("DATA 4 MX6_MMDC_P0_MPWLDECTRL0\t= 0x%08X\n",
+	       calib->p0_mpwldectrl0);
+	printf("DATA 4 MX6_MMDC_P0_MPWLDECTRL1\t= 0x%08X\n",
+	       calib->p0_mpwldectrl1);
+	if (sysinfo.dsize == 2) {
+		printf("DATA 4 MX6_MMDC_P1_MPDGCTRL0\t= 0x%08X\n",
+		       calib->p1_mpdgctrl0);
+		printf("DATA 4 MX6_MMDC_P1_MPDGCTRL1\t= 0x%08X\n",
+		       calib->p1_mpdgctrl1);
+		printf("DATA 4 MX6_MMDC_P1_MPRDDLCTL\t= 0x%08X\n",
+		       calib->p1_mprddlctl);
+		printf("DATA 4 MX6_MMDC_P1_MPWRDLCTL\t= 0x%08X\n",
+		       calib->p1_mpwrdlctl);
+		printf("DATA 4 MX6_MMDC_P1_MPWLDECTRL0\t= 0x%08X\n",
+		       calib->p1_mpwldectrl0);
+		printf("DATA 4 MX6_MMDC_P1_MPWLDECTRL1\t= 0x%08X\n",
+		       calib->p1_mpwldectrl1);
+	}
+#endif
+}
+
+/*
+ * called from C runtime startup code (arch/arm/lib/crt0.S:_main)
+ * - we have a stack and a place to store GD, both in SRAM
+ * - no variable global data is available
+ */
+void board_init_f(ulong dummy)
+{
+	int errs;
+	struct mx6_mmdc_calibration calibration = {0};
+	u32 cpurev = get_cpu_rev();
+
+	memset((void *)gd, 0, sizeof(struct global_data));
+
+	/* setup AIPS and disable watchdog */
+	arch_cpu_init();
+
+	ccgr_init();
+
+	SETUP_IOMUX_PADS(uart_pads);
+
+	/* setup GP timer */
+	timer_init();
+
+	/* UART clocks enabled and gd valid - init serial console */
+	preloader_console_init();
+
+	if (sysinfo.dsize != 1) {
+		if (is_cpu_type(MXC_CPU_MX6SX) ||
+		    is_cpu_type(MXC_CPU_MX6UL) ||
+		    is_cpu_type(MXC_CPU_MX6SL)) {
+			printf("cpu type 0x%x doesn't support 64-bit bus\n",
+			       get_cpu_type());
+			reset_cpu(0);
+		}
+	}
+	printf("CPU:   NXP i.MX%s rev%d.%d at %d MHz\n",
+	       get_imx_type((cpurev & 0xFF000) >> 12),
+	       (cpurev & 0x000F0) >> 4,
+	       (cpurev & 0x0000F) >> 0,
+	       mxc_get_clock(MXC_ARM_CLK) / 1000000);
+#ifdef CONFIG_MX6SL
+	mx6sl_dram_iocfg(CONFIG_DDRWIDTH, &mx6sl_ddr_ioregs,
+			 &mx6sl_grp_ioregs);
+#else
+	if (is_cpu_type(MXC_CPU_MX6Q)) {
+		mx6dq_dram_iocfg(CONFIG_DDRWIDTH, &mx6dq_ddr_ioregs,
+				 &mx6dq_grp_ioregs);
+	} else {
+		mx6sdl_dram_iocfg(CONFIG_DDRWIDTH, &mx6sdl_ddr_ioregs,
+				  &mx6sdl_grp_ioregs);
+	}
+#endif
+	mx6_dram_cfg(&sysinfo, &calibration, &ddrtype);
+
+	errs = mmdc_do_write_level_calibration(&sysinfo);
+	if (errs) {
+		printf("error %d from write level calibration\n", errs);
+	} else {
+		errs = mmdc_do_dqs_calibration(&sysinfo);
+		if (errs) {
+			printf("error %d from write level calibration\n", errs);
+		} else {
+			printf("completed successfully\n");
+			mmdc_read_calibration(&sysinfo, &calibration);
+			display_calibration(&calibration);
+		}
+	}
+	reset_cpu(0);
+}
diff --git a/configs/mx6memcal_defconfig b/configs/mx6memcal_defconfig
new file mode 100644
index 0000000..7e07182
--- /dev/null
+++ b/configs/mx6memcal_defconfig
@@ -0,0 +1,32 @@
+CONFIG_ARM=y
+CONFIG_ARCH_MX6=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_MX6_DDRCAL=y
+CONFIG_TARGET_MX6MEMCAL=y
+CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_WATCHDOG_SUPPORT=y
+CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,SPL,MX6QDL"
+CONFIG_SPL=y
+CONFIG_HUSH_PARSER=y
+# CONFIG_CMD_BOOTD is not set
+# CONFIG_CMD_BOOTM is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+# CONFIG_CMD_EDITENV is not set
+# CONFIG_CMD_SAVEENV is not set
+# CONFIG_CMD_ENV_EXISTS is not set
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_MEMINFO=y
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_FPGA is not set
+# CONFIG_CMD_NET is not set
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_CACHE=y
+CONFIG_REGEX=y
diff --git a/include/configs/mx6memcal.h b/include/configs/mx6memcal.h
new file mode 100644
index 0000000..75125f2
--- /dev/null
+++ b/include/configs/mx6memcal.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
+ *
+ * Configuration settings for the Boundary Devices Nitrogen6X
+ * and Freescale i.MX6Q Sabre Lite boards.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/* SPL */
+
+#include "mx6_common.h"
+#include "imx6_spl.h"
+
+#undef CONFIG_FSL_ESDHC
+#undef CONFIG_MMC
+#undef CONFIG_SPL_MMC_SUPPORT
+#undef CONFIG_GENERIC_MMC
+#undef CONFIG_CMD_FUSE
+
+#define CONFIG_SYS_MEMTEST_START	0x10000000
+#define CONFIG_SYS_MEMTEST_END		0x20000000
+#define CONFIG_SYS_MALLOC_LEN		(64 * 1024 * 1024)
+
+#define CONFIG_MXC_UART
+#ifdef CONFIG_SERIAL_CONSOLE_UART1
+#if defined(CONFIG_MX6SL)
+#define CONFIG_MXC_UART_BASE		UART1_IPS_BASE_ADDR
+#else
+#define CONFIG_MXC_UART_BASE		UART1_BASE
+#endif
+#elif defined(CONFIG_SERIAL_CONSOLE_UART2)
+#define CONFIG_MXC_UART_BASE		UART2_BASE
+#else
+#error please define serial console (CONFIG_SERIAL_CONSOLE_UARTx)
+#endif
+#define CONFIG_BAUDRATE			115200
+
+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + 16)
+
+/* Physical Memory Map */
+#define CONFIG_NR_DRAM_BANKS	       1
+#define PHYS_SDRAM		       MMDC0_ARB_BASE_ADDR
+
+#define CONFIG_SYS_SDRAM_BASE	       PHYS_SDRAM
+#define CONFIG_SYS_INIT_RAM_ADDR       IRAM_BASE_ADDR
+#define CONFIG_SYS_INIT_RAM_SIZE       IRAM_SIZE
+
+#define CONFIG_SYS_INIT_SP_OFFSET \
+	(CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
+#define CONFIG_SYS_INIT_SP_ADDR \
+	(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)
+
+#define CONFIG_SYS_NO_FLASH
+
+#define CONFIG_ENV_SIZE			(8 * 1024)
+#define CONFIG_ENV_IS_NOWHERE
+
+#endif	       /* __CONFIG_H */
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index 04e9536..6b67f7c 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -781,6 +781,7 @@ CONFIG_DCACHE_OFF
 CONFIG_DCACHE_WB
 CONFIG_DCFG_ADDR
 CONFIG_DCLK_DIV
+CONFIG_DDR3
 CONFIG_DDR_
 CONFIG_DDR_2HCLK
 CONFIG_DDR_2T_TIMING
@@ -1947,6 +1948,7 @@ CONFIG_LPC32XX_SSP
 CONFIG_LPC32XX_SSP_TIMEOUT
 CONFIG_LPC_BASE
 CONFIG_LPC_IO_BASE
+CONFIG_LPDDR2
 CONFIG_LPUART
 CONFIG_LPUART_32B_REG
 CONFIG_LQ035Q1_LCD_MODE
@@ -8048,6 +8050,9 @@ CONFIG_TWR_P1025
 CONFIG_TX_DESCR_NUM
 CONFIG_TZSW_RESERVED_DRAM_SIZE
 CONFIG_T_SH7706LSR
+CONFIG_UART1_CSI0_DAT10_11
+CONFIG_UART1_UART1
+CONFIG_UART2_EIM_D26_27
 CONFIG_UART_BASE
 CONFIG_UART_BR_PRELIM
 CONFIG_UART_CONSOLE
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [U-Boot] [RFC PATCH 2/9] mx6memcal: zero values for MPWRDLCTL cause read DQS calibration errors
  2016-11-01 20:13         ` [U-Boot] [RFC PATCH 0/9] ARM: imx: mx6: Add virtual mx6memcal board Eric Nelson
  2016-11-01 20:13           ` [U-Boot] [RFC PATCH 1/9] mx6: Add board mx6memcal for use in validating DDR Eric Nelson
@ 2016-11-01 20:13           ` Eric Nelson
  2016-11-01 20:13           ` [U-Boot] [RFC PATCH 3/9] mx6memcal: add configuration for SABRE Lite Eric Nelson
                             ` (7 subsequent siblings)
  9 siblings, 0 replies; 44+ messages in thread
From: Eric Nelson @ 2016-11-01 20:13 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Eric Nelson <eric@nelint.com>
---
 board/freescale/mx6memcal/spl.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/board/freescale/mx6memcal/spl.c b/board/freescale/mx6memcal/spl.c
index 90e240f..4e63e34 100644
--- a/board/freescale/mx6memcal/spl.c
+++ b/board/freescale/mx6memcal/spl.c
@@ -400,6 +400,10 @@ void board_init_f(ulong dummy)
 
 	memset((void *)gd, 0, sizeof(struct global_data));
 
+	/* write leveling calibration defaults */
+	calibration.p0_mpwrdlctl = 0x40404040;
+	calibration.p1_mpwrdlctl = 0x40404040;
+
 	/* setup AIPS and disable watchdog */
 	arch_cpu_init();
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [U-Boot] [RFC PATCH 3/9] mx6memcal: add configuration for SABRE Lite
  2016-11-01 20:13         ` [U-Boot] [RFC PATCH 0/9] ARM: imx: mx6: Add virtual mx6memcal board Eric Nelson
  2016-11-01 20:13           ` [U-Boot] [RFC PATCH 1/9] mx6: Add board mx6memcal for use in validating DDR Eric Nelson
  2016-11-01 20:13           ` [U-Boot] [RFC PATCH 2/9] mx6memcal: zero values for MPWRDLCTL cause read DQS calibration errors Eric Nelson
@ 2016-11-01 20:13           ` Eric Nelson
  2016-11-01 20:13           ` [U-Boot] [RFC PATCH 4/9] mx6memcal: add configuration for Nitrogen6_max board Eric Nelson
                             ` (6 subsequent siblings)
  9 siblings, 0 replies; 44+ messages in thread
From: Eric Nelson @ 2016-11-01 20:13 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Eric Nelson <eric@nelint.com>
---
 configs/mx6memcal_sabrelite_defconfig | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)
 create mode 100644 configs/mx6memcal_sabrelite_defconfig

diff --git a/configs/mx6memcal_sabrelite_defconfig b/configs/mx6memcal_sabrelite_defconfig
new file mode 100644
index 0000000..f0c7148
--- /dev/null
+++ b/configs/mx6memcal_sabrelite_defconfig
@@ -0,0 +1,34 @@
+CONFIG_ARM=y
+CONFIG_ARCH_MX6=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_MX6_DDRCAL=y
+CONFIG_TARGET_MX6MEMCAL=y
+CONFIG_MT41K128M16JT=y
+CONFIG_SERIAL_CONSOLE_UART2=y
+CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_WATCHDOG_SUPPORT=y
+CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,SPL,MX6QDL"
+CONFIG_SPL=y
+CONFIG_HUSH_PARSER=y
+# CONFIG_CMD_BOOTD is not set
+# CONFIG_CMD_BOOTM is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+# CONFIG_CMD_EDITENV is not set
+# CONFIG_CMD_SAVEENV is not set
+# CONFIG_CMD_ENV_EXISTS is not set
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_MEMINFO=y
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_FPGA is not set
+# CONFIG_CMD_NET is not set
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_CACHE=y
+CONFIG_REGEX=y
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [U-Boot] [RFC PATCH 4/9] mx6memcal: add configuration for Nitrogen6_max board
  2016-11-01 20:13         ` [U-Boot] [RFC PATCH 0/9] ARM: imx: mx6: Add virtual mx6memcal board Eric Nelson
                             ` (2 preceding siblings ...)
  2016-11-01 20:13           ` [U-Boot] [RFC PATCH 3/9] mx6memcal: add configuration for SABRE Lite Eric Nelson
@ 2016-11-01 20:13           ` Eric Nelson
  2016-11-01 20:13           ` [U-Boot] [RFC PATCH 5/9] mx6memcal: add configuration for tr1x board (i.MX6SL with DDR3) Eric Nelson
                             ` (5 subsequent siblings)
  9 siblings, 0 replies; 44+ messages in thread
From: Eric Nelson @ 2016-11-01 20:13 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Eric Nelson <eric@nelint.com>
---
 configs/mx6memcal_nitrogen6_max_defconfig | 33 +++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)
 create mode 100644 configs/mx6memcal_nitrogen6_max_defconfig

diff --git a/configs/mx6memcal_nitrogen6_max_defconfig b/configs/mx6memcal_nitrogen6_max_defconfig
new file mode 100644
index 0000000..097d27d
--- /dev/null
+++ b/configs/mx6memcal_nitrogen6_max_defconfig
@@ -0,0 +1,33 @@
+CONFIG_ARM=y
+CONFIG_ARCH_MX6=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_MX6_DDRCAL=y
+CONFIG_TARGET_MX6MEMCAL=y
+CONFIG_SERIAL_CONSOLE_UART2=y
+CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_WATCHDOG_SUPPORT=y
+CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,SPL,MX6QDL"
+CONFIG_SPL=y
+CONFIG_HUSH_PARSER=y
+# CONFIG_CMD_BOOTD is not set
+# CONFIG_CMD_BOOTM is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+# CONFIG_CMD_EDITENV is not set
+# CONFIG_CMD_SAVEENV is not set
+# CONFIG_CMD_ENV_EXISTS is not set
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_MEMINFO=y
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_FPGA is not set
+# CONFIG_CMD_NET is not set
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_CACHE=y
+CONFIG_REGEX=y
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [U-Boot] [RFC PATCH 5/9] mx6memcal: add configuration for tr1x board (i.MX6SL with DDR3)
  2016-11-01 20:13         ` [U-Boot] [RFC PATCH 0/9] ARM: imx: mx6: Add virtual mx6memcal board Eric Nelson
                             ` (3 preceding siblings ...)
  2016-11-01 20:13           ` [U-Boot] [RFC PATCH 4/9] mx6memcal: add configuration for Nitrogen6_max board Eric Nelson
@ 2016-11-01 20:13           ` Eric Nelson
  2016-11-01 20:13           ` [U-Boot] [RFC PATCH 6/9] mx6memcal: add configuration for Wandboard Solo (512MiB of x32 DDR3) Eric Nelson
                             ` (4 subsequent siblings)
  9 siblings, 0 replies; 44+ messages in thread
From: Eric Nelson @ 2016-11-01 20:13 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Eric Nelson <eric@nelint.com>
---
 configs/mx6memcal_tr1x_defconfig | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)
 create mode 100644 configs/mx6memcal_tr1x_defconfig

diff --git a/configs/mx6memcal_tr1x_defconfig b/configs/mx6memcal_tr1x_defconfig
new file mode 100644
index 0000000..c79fd72
--- /dev/null
+++ b/configs/mx6memcal_tr1x_defconfig
@@ -0,0 +1,36 @@
+CONFIG_ARM=y
+CONFIG_ARCH_MX6=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_MX6_DDRCAL=y
+CONFIG_TARGET_MX6MEMCAL=y
+CONFIG_DDRWIDTH=32
+CONFIG_DDRCS=1
+CONFIG_MT41K128M16JT=y
+CONFIG_UART1_UART1=y
+CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_WATCHDOG_SUPPORT=y
+CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,SPL,MX6SL"
+CONFIG_SPL=y
+CONFIG_HUSH_PARSER=y
+# CONFIG_CMD_BOOTD is not set
+# CONFIG_CMD_BOOTM is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+# CONFIG_CMD_EDITENV is not set
+# CONFIG_CMD_SAVEENV is not set
+# CONFIG_CMD_ENV_EXISTS is not set
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_MEMINFO=y
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_FPGA is not set
+# CONFIG_CMD_NET is not set
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_CACHE=y
+CONFIG_REGEX=y
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [U-Boot] [RFC PATCH 6/9] mx6memcal: add configuration for Wandboard Solo (512MiB of x32 DDR3)
  2016-11-01 20:13         ` [U-Boot] [RFC PATCH 0/9] ARM: imx: mx6: Add virtual mx6memcal board Eric Nelson
                             ` (4 preceding siblings ...)
  2016-11-01 20:13           ` [U-Boot] [RFC PATCH 5/9] mx6memcal: add configuration for tr1x board (i.MX6SL with DDR3) Eric Nelson
@ 2016-11-01 20:13           ` Eric Nelson
  2016-11-01 20:13           ` [U-Boot] [RFC PATCH 7/9] mx6memcal: add configuration for Wandboard Quad Eric Nelson
                             ` (3 subsequent siblings)
  9 siblings, 0 replies; 44+ messages in thread
From: Eric Nelson @ 2016-11-01 20:13 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Eric Nelson <eric@nelint.com>
---
 configs/mx6memcal_wandboard_solo_defconfig | 35 ++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 configs/mx6memcal_wandboard_solo_defconfig

diff --git a/configs/mx6memcal_wandboard_solo_defconfig b/configs/mx6memcal_wandboard_solo_defconfig
new file mode 100644
index 0000000..f47ce43
--- /dev/null
+++ b/configs/mx6memcal_wandboard_solo_defconfig
@@ -0,0 +1,35 @@
+CONFIG_ARM=y
+CONFIG_ARCH_MX6=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_MX6_DDRCAL=y
+CONFIG_TARGET_MX6MEMCAL=y
+CONFIG_DDRWIDTH=32
+CONFIG_DDRCS=1
+CONFIG_H5TQ2G63DFR=y
+CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_WATCHDOG_SUPPORT=y
+CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,SPL,MX6QDL"
+CONFIG_SPL=y
+CONFIG_HUSH_PARSER=y
+# CONFIG_CMD_BOOTD is not set
+# CONFIG_CMD_BOOTM is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+# CONFIG_CMD_EDITENV is not set
+# CONFIG_CMD_SAVEENV is not set
+# CONFIG_CMD_ENV_EXISTS is not set
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_MEMINFO=y
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_FPGA is not set
+# CONFIG_CMD_NET is not set
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_CACHE=y
+CONFIG_REGEX=y
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [U-Boot] [RFC PATCH 7/9] mx6memcal: add configuration for Wandboard Quad
  2016-11-01 20:13         ` [U-Boot] [RFC PATCH 0/9] ARM: imx: mx6: Add virtual mx6memcal board Eric Nelson
                             ` (5 preceding siblings ...)
  2016-11-01 20:13           ` [U-Boot] [RFC PATCH 6/9] mx6memcal: add configuration for Wandboard Solo (512MiB of x32 DDR3) Eric Nelson
@ 2016-11-01 20:13           ` Eric Nelson
  2016-11-01 20:13           ` [U-Boot] [RFC PATCH 8/9] mx6memcal: add configuration for mx6slevk Eric Nelson
                             ` (2 subsequent siblings)
  9 siblings, 0 replies; 44+ messages in thread
From: Eric Nelson @ 2016-11-01 20:13 UTC (permalink / raw)
  To: u-boot

Note that for some reason, this is failing for me unless I
select a DDR bus width of 32 bits.

Signed-off-by: Eric Nelson <eric@nelint.com>
---
 configs/mx6memcal_wandboard_quad_defconfig | 34 ++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)
 create mode 100644 configs/mx6memcal_wandboard_quad_defconfig

diff --git a/configs/mx6memcal_wandboard_quad_defconfig b/configs/mx6memcal_wandboard_quad_defconfig
new file mode 100644
index 0000000..291c273
--- /dev/null
+++ b/configs/mx6memcal_wandboard_quad_defconfig
@@ -0,0 +1,34 @@
+CONFIG_ARM=y
+CONFIG_ARCH_MX6=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_MX6_DDRCAL=y
+CONFIG_TARGET_MX6MEMCAL=y
+CONFIG_DDRCS=1
+CONFIG_H5TQ4G63AFR=y
+CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_WATCHDOG_SUPPORT=y
+CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,SPL,MX6QDL"
+CONFIG_SPL=y
+CONFIG_HUSH_PARSER=y
+# CONFIG_CMD_BOOTD is not set
+# CONFIG_CMD_BOOTM is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+# CONFIG_CMD_EDITENV is not set
+# CONFIG_CMD_SAVEENV is not set
+# CONFIG_CMD_ENV_EXISTS is not set
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_MEMINFO=y
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_FPGA is not set
+# CONFIG_CMD_NET is not set
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_CACHE=y
+CONFIG_REGEX=y
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [U-Boot] [RFC PATCH 8/9] mx6memcal: add configuration for mx6slevk
  2016-11-01 20:13         ` [U-Boot] [RFC PATCH 0/9] ARM: imx: mx6: Add virtual mx6memcal board Eric Nelson
                             ` (6 preceding siblings ...)
  2016-11-01 20:13           ` [U-Boot] [RFC PATCH 7/9] mx6memcal: add configuration for Wandboard Quad Eric Nelson
@ 2016-11-01 20:13           ` Eric Nelson
  2016-11-01 20:13           ` [U-Boot] [RFC PATCH 9/9] mx6memcal: add configuration for warp board (i.MX6SL) Eric Nelson
  2016-11-02  2:06           ` [U-Boot] [RFC PATCH 0/3] ARM: imx: mx6: Add plugin support for SPL Eric Nelson
  9 siblings, 0 replies; 44+ messages in thread
From: Eric Nelson @ 2016-11-01 20:13 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Eric Nelson <eric@nelint.com>
---
 configs/mx6memcal_mx6slevk_defconfig | 37 ++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)
 create mode 100644 configs/mx6memcal_mx6slevk_defconfig

diff --git a/configs/mx6memcal_mx6slevk_defconfig b/configs/mx6memcal_mx6slevk_defconfig
new file mode 100644
index 0000000..aaa81bc
--- /dev/null
+++ b/configs/mx6memcal_mx6slevk_defconfig
@@ -0,0 +1,37 @@
+CONFIG_ARM=y
+CONFIG_ARCH_MX6=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_MX6_DDRCAL=y
+CONFIG_TARGET_MX6MEMCAL=y
+CONFIG_DDRWIDTH=32
+CONFIG_DDRCS=1
+CONFIG_LPDDR2=y
+CONFIG_RALAT=2
+CONFIG_UART1_UART1=y
+CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_WATCHDOG_SUPPORT=y
+CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,SPL,MX6SL"
+CONFIG_SPL=y
+CONFIG_HUSH_PARSER=y
+# CONFIG_CMD_BOOTD is not set
+# CONFIG_CMD_BOOTM is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+# CONFIG_CMD_EDITENV is not set
+# CONFIG_CMD_SAVEENV is not set
+# CONFIG_CMD_ENV_EXISTS is not set
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_MEMINFO=y
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_FPGA is not set
+# CONFIG_CMD_NET is not set
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_CACHE=y
+CONFIG_REGEX=y
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [U-Boot] [RFC PATCH 9/9] mx6memcal: add configuration for warp board (i.MX6SL)
  2016-11-01 20:13         ` [U-Boot] [RFC PATCH 0/9] ARM: imx: mx6: Add virtual mx6memcal board Eric Nelson
                             ` (7 preceding siblings ...)
  2016-11-01 20:13           ` [U-Boot] [RFC PATCH 8/9] mx6memcal: add configuration for mx6slevk Eric Nelson
@ 2016-11-01 20:13           ` Eric Nelson
  2016-11-02  2:06           ` [U-Boot] [RFC PATCH 0/3] ARM: imx: mx6: Add plugin support for SPL Eric Nelson
  9 siblings, 0 replies; 44+ messages in thread
From: Eric Nelson @ 2016-11-01 20:13 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Eric Nelson <eric@nelint.com>
---
 configs/mx6memcal_warpboard_defconfig | 39 +++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)
 create mode 100644 configs/mx6memcal_warpboard_defconfig

diff --git a/configs/mx6memcal_warpboard_defconfig b/configs/mx6memcal_warpboard_defconfig
new file mode 100644
index 0000000..1786e57
--- /dev/null
+++ b/configs/mx6memcal_warpboard_defconfig
@@ -0,0 +1,39 @@
+CONFIG_ARM=y
+CONFIG_ARCH_MX6=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_MX6_DDRCAL=y
+CONFIG_TARGET_MX6MEMCAL=y
+CONFIG_DDRWIDTH=32
+CONFIG_DDRCS=1
+CONFIG_LPDDR2=y
+CONFIG_MT29PZZZ4D4BKESK=y
+CONFIG_DRAM_DRIVE_STRENGTH=4
+CONFIG_RALAT=2
+CONFIG_UART1_UART1=y
+CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_WATCHDOG_SUPPORT=y
+CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,SPL,MX6SL"
+CONFIG_SPL=y
+CONFIG_HUSH_PARSER=y
+# CONFIG_CMD_BOOTD is not set
+# CONFIG_CMD_BOOTM is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+# CONFIG_CMD_EDITENV is not set
+# CONFIG_CMD_SAVEENV is not set
+# CONFIG_CMD_ENV_EXISTS is not set
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_MEMINFO=y
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_FPGA is not set
+# CONFIG_CMD_NET is not set
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_CACHE=y
+CONFIG_REGEX=y
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [U-Boot] [RFC PATCH 0/3] ARM: imx: mx6: Add plugin support for SPL
  2016-11-01 20:13         ` [U-Boot] [RFC PATCH 0/9] ARM: imx: mx6: Add virtual mx6memcal board Eric Nelson
                             ` (8 preceding siblings ...)
  2016-11-01 20:13           ` [U-Boot] [RFC PATCH 9/9] mx6memcal: add configuration for warp board (i.MX6SL) Eric Nelson
@ 2016-11-02  2:06           ` Eric Nelson
  2016-11-02  2:06             ` [U-Boot] [RFC PATCH 1/3] ARM: mx6: preserve Boot ROM stack in SPL Eric Nelson
                               ` (3 more replies)
  9 siblings, 4 replies; 44+ messages in thread
From: Eric Nelson @ 2016-11-02  2:06 UTC (permalink / raw)
  To: u-boot

I forgot to mention in the cover letter for the previous patch set 
that because the mx6memcal board has no implementation of storage
(it only supports a serial console and DDR), I haven't tested the
resulting U-Boot, which has very little besides "mtest" included.

I'm hoping to use this code base (mx6memcal) as a straw man for 
loading both SPL (as a plugin) and U-Boot through the serial download 
path as we've previously discussed in at least [1], [2] and [3].

Now that Peng's patch to imximage has been applied, we can start
to look at the implementation details, and I hope this patch set
can help move us toward an implementation.

The gist of what's needed to allow SPL to be loaded as a plugin
and avoid the need for removable storage or a full (non-SPL)
U-Boot is shown in patch 2.

That is, we need something akin to setjmp/longjmp to:
1. to save the early state of the machine before SPL configures
   the DDR controller, and
2. a routine that we can call to return to the boot ROM

To address #1, there's a clear precedent in the support for a
save_boot_params() routine and patch 2 adds one that simply
saves the working register set. Examining the registers used
by the ROM code shows that r0-r9 plus sp and lr are sufficient.

Experimentally, I've found that the boot ROM stack is initialized
to 0x91ffb4 and that the stack pointer is at 0x91febc (248 bytes)
on all of the machines I've tested against (MX6Q, MX6DL, MX6S and
MX6SL), so we can save the stack just by moving the SPL stack
(patch #1).

We'll also need to determine where the decision to return to the
boot ROM occurs (i.e. when we call routine #2).

The obvious place for use during development is right after
DDR initialization if loaded through the serial downloader,
but it might also be useful to invoke the serial loader as
a last resort instead of the current call to hang().

Patch 3 adds a config file which will allow a build of 
u-boot.imx with SPL as a plugin followed by u-boot.bin as
the primary payload. It highlights the issue of only having
a single IMX_CONFIG variable so it breaks the build of a
stand-alone SPL. Rather, it doesn't break the build, but 
produces SPL that is effectively the same as u-boot.imx.

This leaves only the question of what the return_to_rom code 
should look like, and I'm a bit stumped. The ROM API isn't
documented in any document I have.

In Troy's original patch ([4]), he calls a routine that he
names HAB_RVT_LOAD_DATA. On i.MX Community ([5]), I found
a reference to a plugin_download() routine and I'm not
sure where that came from. The Community post suggests
that it's used in EBOOT.

I tried a simplistic copy of the tail end of plugin start
from [6] that calls pu_irom_hwcnfg_setup() and then returns
to ROM without success. I'm not certain that this was the
right approach and am hoping for some guidance.

References:
[1] - http://lists.denx.de/pipermail/u-boot/2015-June/thread.html#215606
[2] - http://lists.denx.de/pipermail/u-boot/2016-September/thread.html#266303
[3] - http://lists.denx.de/pipermail/u-boot/2015-May/thread.html#215573
[4] - http://patchwork.ozlabs.org/patch/186054/
[5] - http://community.nxp.com/thread/303794
[6] - http://git.denx.de/?p=u-boot.git;a=blob;f=arch/arm/include/asm/arch-mx6/mx6_plugin.S

Eric Nelson (3):
  ARM: mx6: preserve Boot ROM stack in SPL
  ARM: mx6: ddr: add plugin-utils placeholder
  ARM: imx: mx6memcal: allow build of combined SPL+U-Boot

 arch/arm/cpu/armv7/mx6/Makefile         |  2 +-
 arch/arm/cpu/armv7/mx6/ddr.c            |  4 ++++
 arch/arm/cpu/armv7/mx6/plugin-utils.S   | 24 ++++++++++++++++++++++++
 arch/arm/imx-common/spl-plus-u-boot.cfg |  4 ++++
 arch/arm/include/asm/arch-mx6/mx6-ddr.h | 19 +++++++++++++++++++
 configs/mx6memcal_defconfig             |  2 +-
 include/configs/imx6_spl.h              |  2 +-
 7 files changed, 54 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/mx6/plugin-utils.S
 create mode 100644 arch/arm/imx-common/spl-plus-u-boot.cfg

-- 
2.7.4

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [U-Boot] [RFC PATCH 1/3] ARM: mx6: preserve Boot ROM stack in SPL
  2016-11-02  2:06           ` [U-Boot] [RFC PATCH 0/3] ARM: imx: mx6: Add plugin support for SPL Eric Nelson
@ 2016-11-02  2:06             ` Eric Nelson
  2016-11-02  2:06             ` [U-Boot] [RFC PATCH 2/3] ARM: mx6: ddr: add plugin-utils placeholder Eric Nelson
                               ` (2 subsequent siblings)
  3 siblings, 0 replies; 44+ messages in thread
From: Eric Nelson @ 2016-11-02  2:06 UTC (permalink / raw)
  To: u-boot

The i.MX6 Boot ROM starts its' stack at 0x091ffb4 and appears
to be a little less than 256 bytes deep when starting U-Boot.

This was determined experimentally on i.MX6DL and i.MX6SL.

Allow this stack to be preserved to simplify returning to
ROM when SPL is loaded as a plugin.

Signed-off-by: Eric Nelson <eric@nelint.com>
---
 include/configs/imx6_spl.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/configs/imx6_spl.h b/include/configs/imx6_spl.h
index 76d1ca0..fb1b237 100644
--- a/include/configs/imx6_spl.h
+++ b/include/configs/imx6_spl.h
@@ -28,7 +28,7 @@
 #define CONFIG_SPL_LDSCRIPT	"arch/arm/cpu/armv7/omap-common/u-boot-spl.lds"
 #define CONFIG_SPL_TEXT_BASE		0x00908000
 #define CONFIG_SPL_MAX_SIZE		0x10000
-#define CONFIG_SPL_STACK		0x0091FFB8
+#define CONFIG_SPL_STACK		0x0091FEB8
 
 /* NAND support */
 #if defined(CONFIG_SPL_NAND_SUPPORT)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [U-Boot] [RFC PATCH 2/3] ARM: mx6: ddr: add plugin-utils placeholder
  2016-11-02  2:06           ` [U-Boot] [RFC PATCH 0/3] ARM: imx: mx6: Add plugin support for SPL Eric Nelson
  2016-11-02  2:06             ` [U-Boot] [RFC PATCH 1/3] ARM: mx6: preserve Boot ROM stack in SPL Eric Nelson
@ 2016-11-02  2:06             ` Eric Nelson
  2016-11-02  2:06             ` [U-Boot] [RFC PATCH 3/3] ARM: imx: mx6memcal: allow build of combined SPL+U-Boot Eric Nelson
  2017-01-18  1:27             ` [U-Boot] [RFC PATCH 0/3] ARM: imx: mx6: Add plugin support for SPL Tim Harvey
  3 siblings, 0 replies; 44+ messages in thread
From: Eric Nelson @ 2016-11-02  2:06 UTC (permalink / raw)
  To: u-boot

Add entry points for saving the state of the machine at entry
from the Boot ROM and for restoring the state before a return.

Note that this needs some fixup before it's useful, so I'm
forwarding it as an RFC to solicit advice.

This placeholder is little more than a setjmp/longjmp that
saves the SP, LR and registers 0-9. Disassembling the ROM
for i.MX6DL and i.MX6SL shows that these are the only registers
used by the ROM on those SOCs.

Signed-off-by: Eric Nelson <eric@nelint.com>
---
 arch/arm/cpu/armv7/mx6/Makefile         |  2 +-
 arch/arm/cpu/armv7/mx6/ddr.c            |  4 ++++
 arch/arm/cpu/armv7/mx6/plugin-utils.S   | 24 ++++++++++++++++++++++++
 arch/arm/include/asm/arch-mx6/mx6-ddr.h | 19 +++++++++++++++++++
 4 files changed, 48 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/cpu/armv7/mx6/plugin-utils.S

diff --git a/arch/arm/cpu/armv7/mx6/Makefile b/arch/arm/cpu/armv7/mx6/Makefile
index 8af191d..d0d0103 100644
--- a/arch/arm/cpu/armv7/mx6/Makefile
+++ b/arch/arm/cpu/armv7/mx6/Makefile
@@ -8,5 +8,5 @@
 #
 
 obj-y	:= soc.o clock.o
-obj-$(CONFIG_SPL_BUILD)	     += ddr.o
+obj-$(CONFIG_SPL_BUILD)	     += ddr.o plugin-utils.o
 obj-$(CONFIG_MP)             += mp.o
diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c
index 0cf391e..7f8e30d 100644
--- a/arch/arm/cpu/armv7/mx6/ddr.c
+++ b/arch/arm/cpu/armv7/mx6/ddr.c
@@ -1536,3 +1536,7 @@ void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo,
 		hang();
 	}
 }
+
+#ifdef CONFIG_SPL_BUILD
+struct plugin_state plugin_state __attribute__((section(".data")));
+#endif
diff --git a/arch/arm/cpu/armv7/mx6/plugin-utils.S b/arch/arm/cpu/armv7/mx6/plugin-utils.S
new file mode 100644
index 0000000..c284a76
--- /dev/null
+++ b/arch/arm/cpu/armv7/mx6/plugin-utils.S
@@ -0,0 +1,24 @@
+/*
+ * Utility functions for executing as an i.MX plugin
+ *
+ * Copyright (c) 2016 Nelson Integration, LLC
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <asm/system.h>
+#include <linux/linkage.h>
+
+ENTRY(save_boot_params)
+	ldr	r10, =plugin_state
+	stmia	r10, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, fp, sp, lr}
+	b	save_boot_params_ret
+ENDPROC(save_boot_params)
+
+ENTRY(return_to_rom)
+	ldr	r10, =plugin_state
+	ldmia	r10, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, fp, sp, lr}
+	bx	lr
+ENDPROC(return_to_rom)
diff --git a/arch/arm/include/asm/arch-mx6/mx6-ddr.h b/arch/arm/include/asm/arch-mx6/mx6-ddr.h
index 2a8d443..52420da 100644
--- a/arch/arm/include/asm/arch-mx6/mx6-ddr.h
+++ b/arch/arm/include/asm/arch-mx6/mx6-ddr.h
@@ -528,4 +528,23 @@ void mx6_dram_cfg(const struct mx6_ddr_sysinfo *,
 #define MX6_MMDC_P1_MPZQLP2CTL	0x021b485C
 #define MX6_MMDC_P1_MPMUR0	0x021b48b8
 
+#ifdef CONFIG_SPL_BUILD
+struct plugin_state {
+	uint32_t r0;
+	uint32_t r1;
+	uint32_t r2;
+	uint32_t r3;
+	uint32_t r4;
+	uint32_t r5;
+	uint32_t r6;
+	uint32_t r7;
+	uint32_t r8;
+	uint32_t r9;
+	uint32_t fp;
+	uint32_t sp;
+	uint32_t lr;
+};
+void return_to_rom(void);
+#endif
+
 #endif	/*__ASM_ARCH_MX6_DDR_H__ */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [U-Boot] [RFC PATCH 3/3] ARM: imx: mx6memcal: allow build of combined SPL+U-Boot
  2016-11-02  2:06           ` [U-Boot] [RFC PATCH 0/3] ARM: imx: mx6: Add plugin support for SPL Eric Nelson
  2016-11-02  2:06             ` [U-Boot] [RFC PATCH 1/3] ARM: mx6: preserve Boot ROM stack in SPL Eric Nelson
  2016-11-02  2:06             ` [U-Boot] [RFC PATCH 2/3] ARM: mx6: ddr: add plugin-utils placeholder Eric Nelson
@ 2016-11-02  2:06             ` Eric Nelson
  2017-01-18  1:27             ` [U-Boot] [RFC PATCH 0/3] ARM: imx: mx6: Add plugin support for SPL Tim Harvey
  3 siblings, 0 replies; 44+ messages in thread
From: Eric Nelson @ 2016-11-02  2:06 UTC (permalink / raw)
  To: u-boot

Add an imximage config file to construct u-boot.imx with SPL
as a plugin and use it as a straw-man for the mx6memcal
virtual board.

Note that this breaks the build of SPL because only one value
can be listed for IMX_CONFIG.

As it stands, all imx SPL builds use an almost empty .cfg file
from arch/arm/configs/spl_sd.cfg.

This could be hard-coded for use in building SPL if we just
remove the comments from the file (copyright).

Signed-off-by: Eric Nelson <eric@nelint.com>
---
 arch/arm/imx-common/spl-plus-u-boot.cfg | 4 ++++
 configs/mx6memcal_defconfig             | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/imx-common/spl-plus-u-boot.cfg

diff --git a/arch/arm/imx-common/spl-plus-u-boot.cfg b/arch/arm/imx-common/spl-plus-u-boot.cfg
new file mode 100644
index 0000000..5940cb0
--- /dev/null
+++ b/arch/arm/imx-common/spl-plus-u-boot.cfg
@@ -0,0 +1,4 @@
+IMAGE_VERSION 2
+BOOT_FROM sd
+PLUGIN spl/u-boot-spl.bin 0x00907000
+
diff --git a/configs/mx6memcal_defconfig b/configs/mx6memcal_defconfig
index 7e07182..06aa85f 100644
--- a/configs/mx6memcal_defconfig
+++ b/configs/mx6memcal_defconfig
@@ -6,7 +6,7 @@ CONFIG_MX6_DDRCAL=y
 CONFIG_TARGET_MX6MEMCAL=y
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL_WATCHDOG_SUPPORT=y
-CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,SPL,MX6QDL"
+CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl-plus-u-boot.cfg,SPL,MX6QDL"
 CONFIG_SPL=y
 CONFIG_HUSH_PARSER=y
 # CONFIG_CMD_BOOTD is not set
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [U-Boot] [PATCH V2 0/4] mx6: ddr: updates for dynamic DDR calibration
  2016-10-30 23:33         ` [U-Boot] [PATCH V2 0/4] mx6: ddr: updates for dynamic DDR calibration Eric Nelson
                             ` (3 preceding siblings ...)
  2016-10-30 23:33           ` [U-Boot] [PATCH V2 4/4] ARM: mx6: ddr: use Kconfig for inclusion of DDR calibration routines Eric Nelson
@ 2016-11-22 10:59           ` Christoph Fritz
  2016-11-29 16:28           ` Stefano Babic
  5 siblings, 0 replies; 44+ messages in thread
From: Christoph Fritz @ 2016-11-22 10:59 UTC (permalink / raw)
  To: u-boot

On Sun, Oct 30, 2016 at 04:33:46PM -0700, Eric Nelson wrote:
> This set of patches updates the interface to the DDR calibration in 
> preparation for the addition of a pseudo-board for calibration on
> i.MX6.

What's the current state in regard of applying this patchset?

Does it also work on i.MX6SX like the sabresd board?

Thanks
  -- Christoph

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [U-Boot] [PATCH V2 0/4] mx6: ddr: updates for dynamic DDR calibration
  2016-10-30 23:33         ` [U-Boot] [PATCH V2 0/4] mx6: ddr: updates for dynamic DDR calibration Eric Nelson
                             ` (4 preceding siblings ...)
  2016-11-22 10:59           ` [U-Boot] [PATCH V2 0/4] mx6: ddr: updates for dynamic DDR calibration Christoph Fritz
@ 2016-11-29 16:28           ` Stefano Babic
  5 siblings, 0 replies; 44+ messages in thread
From: Stefano Babic @ 2016-11-29 16:28 UTC (permalink / raw)
  To: u-boot

On 31/10/2016 00:33, Eric Nelson wrote:
> This set of patches updates the interface to the DDR calibration in 
> preparation for the addition of a pseudo-board for calibration on
> i.MX6.
> 
> The first patch fixes an ommission in the use of the DG_CMP_CYC flag
> in register MPDGCTRL0.
> 
> The second patch cleans up the handling of bus widths by passing
> the system configuration information to the calibration routines.
> 
> The third patch adds support for returning the calibration data
> written to the MMDC registers.
> 
> The fourth patch adds a Kconfig selection to inclut the DDR calibration
> routines.
> 
> Eric Nelson (4):
>   mx6: ddr: allow 32 cycles for DQS gating calibration
>   mx6: ddr: pass mx6_ddr_sysinfo to calibration routines
>   mx6: ddr: add routine to return DDR calibration data
>   ARM: mx6: ddr: use Kconfig for inclusion of DDR calibration routines
> 
>  arch/arm/cpu/armv7/mx6/Kconfig          |   5 ++
>  arch/arm/cpu/armv7/mx6/ddr.c            | 131 +++++++++++++++++++++-----------
>  arch/arm/include/asm/arch-mx6/mx6-ddr.h |   8 +-
>  board/kosagi/novena/novena_spl.c        |   4 +-
>  configs/novena_defconfig                |   1 +
>  5 files changed, 100 insertions(+), 49 deletions(-)
> 

Applied to u-boot-imx, thanks !

Best regards,
Stefano Babic

-- 
=====================================================================
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [U-Boot] [RFC PATCH 0/3] ARM: imx: mx6: Add plugin support for SPL
  2016-11-02  2:06           ` [U-Boot] [RFC PATCH 0/3] ARM: imx: mx6: Add plugin support for SPL Eric Nelson
                               ` (2 preceding siblings ...)
  2016-11-02  2:06             ` [U-Boot] [RFC PATCH 3/3] ARM: imx: mx6memcal: allow build of combined SPL+U-Boot Eric Nelson
@ 2017-01-18  1:27             ` Tim Harvey
  2017-01-18 17:05               ` Eric Nelson
  3 siblings, 1 reply; 44+ messages in thread
From: Tim Harvey @ 2017-01-18  1:27 UTC (permalink / raw)
  To: u-boot

On Tue, Nov 1, 2016 at 7:06 PM, Eric Nelson <eric@nelint.com> wrote:
> I forgot to mention in the cover letter for the previous patch set
> that because the mx6memcal board has no implementation of storage
> (it only supports a serial console and DDR), I haven't tested the
> resulting U-Boot, which has very little besides "mtest" included.
>
> I'm hoping to use this code base (mx6memcal) as a straw man for
> loading both SPL (as a plugin) and U-Boot through the serial download
> path as we've previously discussed in at least [1], [2] and [3].
>
> Now that Peng's patch to imximage has been applied, we can start
> to look at the implementation details, and I hope this patch set
> can help move us toward an implementation.
>
> The gist of what's needed to allow SPL to be loaded as a plugin
> and avoid the need for removable storage or a full (non-SPL)
> U-Boot is shown in patch 2.
>
> That is, we need something akin to setjmp/longjmp to:
> 1. to save the early state of the machine before SPL configures
>    the DDR controller, and
> 2. a routine that we can call to return to the boot ROM
>
> To address #1, there's a clear precedent in the support for a
> save_boot_params() routine and patch 2 adds one that simply
> saves the working register set. Examining the registers used
> by the ROM code shows that r0-r9 plus sp and lr are sufficient.
>
> Experimentally, I've found that the boot ROM stack is initialized
> to 0x91ffb4 and that the stack pointer is at 0x91febc (248 bytes)
> on all of the machines I've tested against (MX6Q, MX6DL, MX6S and
> MX6SL), so we can save the stack just by moving the SPL stack
> (patch #1).
>
> We'll also need to determine where the decision to return to the
> boot ROM occurs (i.e. when we call routine #2).
>
> The obvious place for use during development is right after
> DDR initialization if loaded through the serial downloader,
> but it might also be useful to invoke the serial loader as
> a last resort instead of the current call to hang().
>
> Patch 3 adds a config file which will allow a build of
> u-boot.imx with SPL as a plugin followed by u-boot.bin as
> the primary payload. It highlights the issue of only having
> a single IMX_CONFIG variable so it breaks the build of a
> stand-alone SPL. Rather, it doesn't break the build, but
> produces SPL that is effectively the same as u-boot.imx.
>
> This leaves only the question of what the return_to_rom code
> should look like, and I'm a bit stumped. The ROM API isn't
> documented in any document I have.
>
> In Troy's original patch ([4]), he calls a routine that he
> names HAB_RVT_LOAD_DATA. On i.MX Community ([5]), I found
> a reference to a plugin_download() routine and I'm not
> sure where that came from. The Community post suggests
> that it's used in EBOOT.
>
> I tried a simplistic copy of the tail end of plugin start
> from [6] that calls pu_irom_hwcnfg_setup() and then returns
> to ROM without success. I'm not certain that this was the
> right approach and am hoping for some guidance.
>
> References:
> [1] - http://lists.denx.de/pipermail/u-boot/2015-June/thread.html#215606
> [2] - http://lists.denx.de/pipermail/u-boot/2016-September/thread.html#266303
> [3] - http://lists.denx.de/pipermail/u-boot/2015-May/thread.html#215573
> [4] - http://patchwork.ozlabs.org/patch/186054/
> [5] - http://community.nxp.com/thread/303794
> [6] - http://git.denx.de/?p=u-boot.git;a=blob;f=arch/arm/include/asm/arch-mx6/mx6_plugin.S
>
> Eric Nelson (3):
>   ARM: mx6: preserve Boot ROM stack in SPL
>   ARM: mx6: ddr: add plugin-utils placeholder
>   ARM: imx: mx6memcal: allow build of combined SPL+U-Boot
>
>  arch/arm/cpu/armv7/mx6/Makefile         |  2 +-
>  arch/arm/cpu/armv7/mx6/ddr.c            |  4 ++++
>  arch/arm/cpu/armv7/mx6/plugin-utils.S   | 24 ++++++++++++++++++++++++
>  arch/arm/imx-common/spl-plus-u-boot.cfg |  4 ++++
>  arch/arm/include/asm/arch-mx6/mx6-ddr.h | 19 +++++++++++++++++++
>  configs/mx6memcal_defconfig             |  2 +-
>  include/configs/imx6_spl.h              |  2 +-
>  7 files changed, 54 insertions(+), 3 deletions(-)
>  create mode 100644 arch/arm/cpu/armv7/mx6/plugin-utils.S
>  create mode 100644 arch/arm/imx-common/spl-plus-u-boot.cfg
>
> --
> 2.7.4
>

Hi Eric,

I'm interested loading U-Boot from the OTG serial downloader and this
looks like a good approach. Thanks for continuing to plug away at
this!

If I understand correctly the approach here is to use the plugin
support such that the boot ROM will execute the SPL as a plugin which
then returns and jumps to U-boot?

I've applied your mx6memcal series to master and support for one of
the Gateworks boards I'm working with and can boot that SPL (23KB)
fine (so I've got the UART and configured correctly at least). When I
adapt that to use pl-plus-u-boot.cfg on top of this patch series the
resulting SPL (85KB) image doens't appear to boot (nothing over the
serial console) but I'm thinking I'm doing something wrong as
imx_usb_loader seems like its not loading it fully or loading it too
quickly. Do I need patches to imx_usb_loader or am I doing something
obvious wrong here?

Incidentally, did anyone ever proof out the other discussed method
where an SPL is built with zmodem and allows loading u-boot.img over
that?

Regards,

Tim

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [U-Boot] [RFC PATCH 0/3] ARM: imx: mx6: Add plugin support for SPL
  2017-01-18  1:27             ` [U-Boot] [RFC PATCH 0/3] ARM: imx: mx6: Add plugin support for SPL Tim Harvey
@ 2017-01-18 17:05               ` Eric Nelson
  2017-01-18 18:49                 ` Tim Harvey
  0 siblings, 1 reply; 44+ messages in thread
From: Eric Nelson @ 2017-01-18 17:05 UTC (permalink / raw)
  To: u-boot

Hi Tim,

On 01/17/2017 06:27 PM, Tim Harvey wrote:
> On Tue, Nov 1, 2016 at 7:06 PM, Eric Nelson <eric@nelint.com> wrote:
>> I forgot to mention in the cover letter for the previous patch set
>> that because the mx6memcal board has no implementation of storage
>> (it only supports a serial console and DDR), I haven't tested the
>> resulting U-Boot, which has very little besides "mtest" included.
>>
>> I'm hoping to use this code base (mx6memcal) as a straw man for
>> loading both SPL (as a plugin) and U-Boot through the serial download
>> path as we've previously discussed in at least [1], [2] and [3].
>>
>> Now that Peng's patch to imximage has been applied, we can start
>> to look at the implementation details, and I hope this patch set
>> can help move us toward an implementation.
>>
>> The gist of what's needed to allow SPL to be loaded as a plugin
>> and avoid the need for removable storage or a full (non-SPL)
>> U-Boot is shown in patch 2.
>>
>> That is, we need something akin to setjmp/longjmp to:
>> 1. to save the early state of the machine before SPL configures
>>    the DDR controller, and
>> 2. a routine that we can call to return to the boot ROM
>>
>> To address #1, there's a clear precedent in the support for a
>> save_boot_params() routine and patch 2 adds one that simply
>> saves the working register set. Examining the registers used
>> by the ROM code shows that r0-r9 plus sp and lr are sufficient.
>>
>> Experimentally, I've found that the boot ROM stack is initialized
>> to 0x91ffb4 and that the stack pointer is at 0x91febc (248 bytes)
>> on all of the machines I've tested against (MX6Q, MX6DL, MX6S and
>> MX6SL), so we can save the stack just by moving the SPL stack
>> (patch #1).
>>
>> We'll also need to determine where the decision to return to the
>> boot ROM occurs (i.e. when we call routine #2).
>>
>> The obvious place for use during development is right after
>> DDR initialization if loaded through the serial downloader,
>> but it might also be useful to invoke the serial loader as
>> a last resort instead of the current call to hang().
>>
>> Patch 3 adds a config file which will allow a build of
>> u-boot.imx with SPL as a plugin followed by u-boot.bin as
>> the primary payload. It highlights the issue of only having
>> a single IMX_CONFIG variable so it breaks the build of a
>> stand-alone SPL. Rather, it doesn't break the build, but
>> produces SPL that is effectively the same as u-boot.imx.
>>
>> This leaves only the question of what the return_to_rom code
>> should look like, and I'm a bit stumped. The ROM API isn't
>> documented in any document I have.
>>
>> In Troy's original patch ([4]), he calls a routine that he
>> names HAB_RVT_LOAD_DATA. On i.MX Community ([5]), I found
>> a reference to a plugin_download() routine and I'm not
>> sure where that came from. The Community post suggests
>> that it's used in EBOOT.
>>
>> I tried a simplistic copy of the tail end of plugin start
>> from [6] that calls pu_irom_hwcnfg_setup() and then returns
>> to ROM without success. I'm not certain that this was the
>> right approach and am hoping for some guidance.
>>
>> References:
>> [1] - http://lists.denx.de/pipermail/u-boot/2015-June/thread.html#215606
>> [2] - http://lists.denx.de/pipermail/u-boot/2016-September/thread.html#266303
>> [3] - http://lists.denx.de/pipermail/u-boot/2015-May/thread.html#215573
>> [4] - http://patchwork.ozlabs.org/patch/186054/
>> [5] - http://community.nxp.com/thread/303794
>> [6] - http://git.denx.de/?p=u-boot.git;a=blob;f=arch/arm/include/asm/arch-mx6/mx6_plugin.S
>>
>> Eric Nelson (3):
>>   ARM: mx6: preserve Boot ROM stack in SPL
>>   ARM: mx6: ddr: add plugin-utils placeholder
>>   ARM: imx: mx6memcal: allow build of combined SPL+U-Boot
>>
>>  arch/arm/cpu/armv7/mx6/Makefile         |  2 +-
>>  arch/arm/cpu/armv7/mx6/ddr.c            |  4 ++++
>>  arch/arm/cpu/armv7/mx6/plugin-utils.S   | 24 ++++++++++++++++++++++++
>>  arch/arm/imx-common/spl-plus-u-boot.cfg |  4 ++++
>>  arch/arm/include/asm/arch-mx6/mx6-ddr.h | 19 +++++++++++++++++++
>>  configs/mx6memcal_defconfig             |  2 +-
>>  include/configs/imx6_spl.h              |  2 +-
>>  7 files changed, 54 insertions(+), 3 deletions(-)
>>  create mode 100644 arch/arm/cpu/armv7/mx6/plugin-utils.S
>>  create mode 100644 arch/arm/imx-common/spl-plus-u-boot.cfg
>>
>> --
>> 2.7.4
>>
> 
> Hi Eric,
> 
> I'm interested loading U-Boot from the OTG serial downloader and this
> looks like a good approach. Thanks for continuing to plug away at
> this!
> 

NP. It seems like the easy route if we can figure out the details of
the ROM API calls.

I was hoping to get some feedback from Peng or Troy, but it seems
that they're also overloaded.

> If I understand correctly the approach here is to use the plugin
> support such that the boot ROM will execute the SPL as a plugin which
> then returns and jumps to U-boot?
> 

That's the idea. Both SB_LOADER and imx_usb support this, so the
key is figuring out how to return to the Boot ROM.

> I've applied your mx6memcal series to master and support for one of
> the Gateworks boards I'm working with and can boot that SPL (23KB)
> fine (so I've got the UART and configured correctly at least). When I
> adapt that to use spl-plus-u-boot.cfg on top of this patch series the
> resulting SPL (85KB) image doens't appear to boot (nothing over the
> serial console) but I'm thinking I'm doing something wrong as
> imx_usb_loader seems like its not loading it fully or loading it too
> quickly. Do I need patches to imx_usb_loader or am I doing something
> obvious wrong here?
> 

I need to re-visit this. My recollection is that the SPL portion should
load and run, but the return-to-ROM portion will fail.

My next thought is to use JTAG to trace things through the return to
BOOT ROM and use an image from the Freescale fork as a working
example.

> Incidentally, did anyone ever proof out the other discussed method
> where an SPL is built with zmodem and allows loading u-boot.img over
> that?
> 
Yeah.

Stefano had that working, though I had some issues getting
microcom working. I had to stop and restart microcom and initiate
the upload.

Regards,


Eric

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [U-Boot] [RFC PATCH 0/3] ARM: imx: mx6: Add plugin support for SPL
  2017-01-18 17:05               ` Eric Nelson
@ 2017-01-18 18:49                 ` Tim Harvey
  2017-01-18 19:01                   ` Fabio Estevam
  0 siblings, 1 reply; 44+ messages in thread
From: Tim Harvey @ 2017-01-18 18:49 UTC (permalink / raw)
  To: u-boot

On Wed, Jan 18, 2017 at 9:05 AM, Eric Nelson <eric@nelint.com> wrote:
> Hi Tim,
>
> On 01/17/2017 06:27 PM, Tim Harvey wrote:
>> On Tue, Nov 1, 2016 at 7:06 PM, Eric Nelson <eric@nelint.com> wrote:
>>> I forgot to mention in the cover letter for the previous patch set
>>> that because the mx6memcal board has no implementation of storage
>>> (it only supports a serial console and DDR), I haven't tested the
>>> resulting U-Boot, which has very little besides "mtest" included.
>>>
>>> I'm hoping to use this code base (mx6memcal) as a straw man for
>>> loading both SPL (as a plugin) and U-Boot through the serial download
>>> path as we've previously discussed in at least [1], [2] and [3].
>>>
>>> Now that Peng's patch to imximage has been applied, we can start
>>> to look at the implementation details, and I hope this patch set
>>> can help move us toward an implementation.
>>>
>>> The gist of what's needed to allow SPL to be loaded as a plugin
>>> and avoid the need for removable storage or a full (non-SPL)
>>> U-Boot is shown in patch 2.
>>>
>>> That is, we need something akin to setjmp/longjmp to:
>>> 1. to save the early state of the machine before SPL configures
>>>    the DDR controller, and
>>> 2. a routine that we can call to return to the boot ROM
>>>
>>> To address #1, there's a clear precedent in the support for a
>>> save_boot_params() routine and patch 2 adds one that simply
>>> saves the working register set. Examining the registers used
>>> by the ROM code shows that r0-r9 plus sp and lr are sufficient.
>>>
>>> Experimentally, I've found that the boot ROM stack is initialized
>>> to 0x91ffb4 and that the stack pointer is at 0x91febc (248 bytes)
>>> on all of the machines I've tested against (MX6Q, MX6DL, MX6S and
>>> MX6SL), so we can save the stack just by moving the SPL stack
>>> (patch #1).
>>>
>>> We'll also need to determine where the decision to return to the
>>> boot ROM occurs (i.e. when we call routine #2).
>>>
>>> The obvious place for use during development is right after
>>> DDR initialization if loaded through the serial downloader,
>>> but it might also be useful to invoke the serial loader as
>>> a last resort instead of the current call to hang().
>>>
>>> Patch 3 adds a config file which will allow a build of
>>> u-boot.imx with SPL as a plugin followed by u-boot.bin as
>>> the primary payload. It highlights the issue of only having
>>> a single IMX_CONFIG variable so it breaks the build of a
>>> stand-alone SPL. Rather, it doesn't break the build, but
>>> produces SPL that is effectively the same as u-boot.imx.
>>>
>>> This leaves only the question of what the return_to_rom code
>>> should look like, and I'm a bit stumped. The ROM API isn't
>>> documented in any document I have.
>>>
>>> In Troy's original patch ([4]), he calls a routine that he
>>> names HAB_RVT_LOAD_DATA. On i.MX Community ([5]), I found
>>> a reference to a plugin_download() routine and I'm not
>>> sure where that came from. The Community post suggests
>>> that it's used in EBOOT.
>>>
>>> I tried a simplistic copy of the tail end of plugin start
>>> from [6] that calls pu_irom_hwcnfg_setup() and then returns
>>> to ROM without success. I'm not certain that this was the
>>> right approach and am hoping for some guidance.
>>>
>>> References:
>>> [1] - http://lists.denx.de/pipermail/u-boot/2015-June/thread.html#215606
>>> [2] - http://lists.denx.de/pipermail/u-boot/2016-September/thread.html#266303
>>> [3] - http://lists.denx.de/pipermail/u-boot/2015-May/thread.html#215573
>>> [4] - http://patchwork.ozlabs.org/patch/186054/
>>> [5] - http://community.nxp.com/thread/303794
>>> [6] - http://git.denx.de/?p=u-boot.git;a=blob;f=arch/arm/include/asm/arch-mx6/mx6_plugin.S
>>>
>>> Eric Nelson (3):
>>>   ARM: mx6: preserve Boot ROM stack in SPL
>>>   ARM: mx6: ddr: add plugin-utils placeholder
>>>   ARM: imx: mx6memcal: allow build of combined SPL+U-Boot
>>>
>>>  arch/arm/cpu/armv7/mx6/Makefile         |  2 +-
>>>  arch/arm/cpu/armv7/mx6/ddr.c            |  4 ++++
>>>  arch/arm/cpu/armv7/mx6/plugin-utils.S   | 24 ++++++++++++++++++++++++
>>>  arch/arm/imx-common/spl-plus-u-boot.cfg |  4 ++++
>>>  arch/arm/include/asm/arch-mx6/mx6-ddr.h | 19 +++++++++++++++++++
>>>  configs/mx6memcal_defconfig             |  2 +-
>>>  include/configs/imx6_spl.h              |  2 +-
>>>  7 files changed, 54 insertions(+), 3 deletions(-)
>>>  create mode 100644 arch/arm/cpu/armv7/mx6/plugin-utils.S
>>>  create mode 100644 arch/arm/imx-common/spl-plus-u-boot.cfg
>>>
>>> --
>>> 2.7.4
>>>
>>
>> Hi Eric,
>>
>> I'm interested loading U-Boot from the OTG serial downloader and this
>> looks like a good approach. Thanks for continuing to plug away at
>> this!
>>
>
> NP. It seems like the easy route if we can figure out the details of
> the ROM API calls.
>
> I was hoping to get some feedback from Peng or Troy, but it seems
> that they're also overloaded.
>
>> If I understand correctly the approach here is to use the plugin
>> support such that the boot ROM will execute the SPL as a plugin which
>> then returns and jumps to U-boot?
>>
>
> That's the idea. Both SB_LOADER and imx_usb support this, so the
> key is figuring out how to return to the Boot ROM.
>
>> I've applied your mx6memcal series to master and support for one of
>> the Gateworks boards I'm working with and can boot that SPL (23KB)
>> fine (so I've got the UART and configured correctly at least). When I
>> adapt that to use spl-plus-u-boot.cfg on top of this patch series the
>> resulting SPL (85KB) image doens't appear to boot (nothing over the
>> serial console) but I'm thinking I'm doing something wrong as
>> imx_usb_loader seems like its not loading it fully or loading it too
>> quickly. Do I need patches to imx_usb_loader or am I doing something
>> obvious wrong here?
>>
>
> I need to re-visit this. My recollection is that the SPL portion should
> load and run, but the return-to-ROM portion will fail.

ok - I thought you had it fully working, but it does sound like you at
least got further than I'm getting (you saw the SPL boot at least) so
let me know what you find when you re-visit it.

>
> My next thought is to use JTAG to trace things through the return to
> BOOT ROM and use an image from the Freescale fork as a working
> example.
>
>> Incidentally, did anyone ever proof out the other discussed method
>> where an SPL is built with zmodem and allows loading u-boot.img over
>> that?
>>
> Yeah.
>
> Stefano had that working, though I had some issues getting
> microcom working. I had to stop and restart microcom and initiate
> the upload.

Stefano,

Did you document the 'IMX6 SPL to U-Boot over serial' setup anywhere,
or can you talk me through what you did?

Thanks,

Tim

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [U-Boot] [RFC PATCH 0/3] ARM: imx: mx6: Add plugin support for SPL
  2017-01-18 18:49                 ` Tim Harvey
@ 2017-01-18 19:01                   ` Fabio Estevam
  2017-01-20 17:40                     ` Tim Harvey
  0 siblings, 1 reply; 44+ messages in thread
From: Fabio Estevam @ 2017-01-18 19:01 UTC (permalink / raw)
  To: u-boot

Hi Tim,

On Wed, Jan 18, 2017 at 4:49 PM, Tim Harvey <tharvey@gateworks.com> wrote:

> Did you document the 'IMX6 SPL to U-Boot over serial' setup anywhere,
> or can you talk me through what you did?

It is available at doc/README.imx6 (2. Using imx_usb_loader for first
install with SPL).

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [U-Boot] [RFC PATCH 0/3] ARM: imx: mx6: Add plugin support for SPL
  2017-01-18 19:01                   ` Fabio Estevam
@ 2017-01-20 17:40                     ` Tim Harvey
  2017-01-27 14:56                       ` Fabio Estevam
  0 siblings, 1 reply; 44+ messages in thread
From: Tim Harvey @ 2017-01-20 17:40 UTC (permalink / raw)
  To: u-boot

On Wed, Jan 18, 2017 at 11:01 AM, Fabio Estevam <festevam@gmail.com> wrote:
> Hi Tim,
>
> On Wed, Jan 18, 2017 at 4:49 PM, Tim Harvey <tharvey@gateworks.com> wrote:
>
>> Did you document the 'IMX6 SPL to U-Boot over serial' setup anywhere,
>> or can you talk me through what you did?
>
> It is available at doc/README.imx6 (2. Using imx_usb_loader for first
> install with SPL).

Fabio,

Thanks for pointing me in the right direction. I did manage to get
IMX6 SPL Ymodem working although I had to hack the return value of
spl_boot_device(). In my current situation with a board that has no
BOOT MODE pin strapping, and no fuses blown imx_usb_loader
spl_boot_device() returns BOOT_DEVICE_NOR which is wrong.

The SRC_SBMR register reflects the BOOT MODE pins of the chip
(strapping) but the reference manual defines SRC_GPR9 and
SRC_GPR10[28] as reserved and I don't recall the reasoning for using
these for the boot mode. Can you provide some documentation that we
can put in the code? I'm thinking there is something else missing from
this function that should be able to determine that the serial
downloader was used in my case and return BOOT_DEVICE_UART
appropriately.

Regards,

Tim

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [U-Boot] [RFC PATCH 0/3] ARM: imx: mx6: Add plugin support for SPL
  2017-01-20 17:40                     ` Tim Harvey
@ 2017-01-27 14:56                       ` Fabio Estevam
  2017-01-27 15:25                         ` Otavio Salvador
  0 siblings, 1 reply; 44+ messages in thread
From: Fabio Estevam @ 2017-01-27 14:56 UTC (permalink / raw)
  To: u-boot

Hi Tim,

On Fri, Jan 20, 2017 at 3:40 PM, Tim Harvey <tharvey@gateworks.com> wrote:

> The SRC_SBMR register reflects the BOOT MODE pins of the chip
> (strapping) but the reference manual defines SRC_GPR9 and
> SRC_GPR10[28] as reserved and I don't recall the reasoning for using
> these for the boot mode. Can you provide some documentation that we
> can put in the code? I'm thinking there is something else missing from
> this function that should be able to determine that the serial
> downloader was used in my case and return BOOT_DEVICE_UART
> appropriately.

I could also not found any documentation about SRC_GPR9 and SRC_GPR10[28].

I also find it confusing that we use such undocumented registers in
U-Boot for determining the boot mode.

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [U-Boot] [RFC PATCH 0/3] ARM: imx: mx6: Add plugin support for SPL
  2017-01-27 14:56                       ` Fabio Estevam
@ 2017-01-27 15:25                         ` Otavio Salvador
  0 siblings, 0 replies; 44+ messages in thread
From: Otavio Salvador @ 2017-01-27 15:25 UTC (permalink / raw)
  To: u-boot

On Fri, Jan 27, 2017 at 12:56 PM, Fabio Estevam <festevam@gmail.com> wrote:
> On Fri, Jan 20, 2017 at 3:40 PM, Tim Harvey <tharvey@gateworks.com> wrote:
>> The SRC_SBMR register reflects the BOOT MODE pins of the chip
>> (strapping) but the reference manual defines SRC_GPR9 and
>> SRC_GPR10[28] as reserved and I don't recall the reasoning for using
>> these for the boot mode. Can you provide some documentation that we
>> can put in the code? I'm thinking there is something else missing from
>> this function that should be able to determine that the serial
>> downloader was used in my case and return BOOT_DEVICE_UART
>> appropriately.
>
> I could also not found any documentation about SRC_GPR9 and SRC_GPR10[28].

I think the BootROM is the ultimate resource here. Did you look
internally for its source?

-- 
Otavio Salvador                             O.S. Systems
http://www.ossystems.com.br        http://code.ossystems.com.br
Mobile: +55 (53) 9981-7854            Mobile: +1 (347) 903-9750

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [U-Boot] [RFC PATCH 1/9] mx6: Add board mx6memcal for use in validating DDR
  2016-11-01 20:13           ` [U-Boot] [RFC PATCH 1/9] mx6: Add board mx6memcal for use in validating DDR Eric Nelson
@ 2017-07-14 14:18             ` Fabio Estevam
  2017-07-14 17:58               ` Eric Nelson
  0 siblings, 1 reply; 44+ messages in thread
From: Fabio Estevam @ 2017-07-14 14:18 UTC (permalink / raw)
  To: u-boot

Hi Eric,

On Tue, Nov 1, 2016 at 5:13 PM, Eric Nelson <eric@nelint.com> wrote:
> This is a virtual "board" that uses configuration files and
> Kconfig to define the memory layout used by a real board during
> the board bring-up process.
>
> It generates an SPL image that can be loaded using imx_usb or
> SB_LOADER.exe.
>
> When run, it will generate a set of calibration constants for
> use in either or both a DCD configuration file for boards that
> use u-boot.imx or struct mx6_mmdc_calibration for boards that
> boot via SPL.
>
> In essence, it is a configurable, open-source variant of the
> Freescale ddr-stress tool.
>
>         https://community.nxp.com/docs/DOC-105652
>
> File mx6memcal_defconfig configures the board for use with
> mx6sabresd or mx6qsabreauto.

Do you still have plans on refreshing this series?

It does seem very useful.

Thanks

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [U-Boot] [RFC PATCH 1/9] mx6: Add board mx6memcal for use in validating DDR
  2017-07-14 14:18             ` Fabio Estevam
@ 2017-07-14 17:58               ` Eric Nelson
  2017-07-14 19:01                 ` Fabio Estevam
  0 siblings, 1 reply; 44+ messages in thread
From: Eric Nelson @ 2017-07-14 17:58 UTC (permalink / raw)
  To: u-boot

Hi Fabio,

On 07/14/2017 07:18 AM, Fabio Estevam wrote:
> Hi Eric,
> 
> On Tue, Nov 1, 2016 at 5:13 PM, Eric Nelson <eric@nelint.com> wrote:
>> This is a virtual "board" that uses configuration files and
>> Kconfig to define the memory layout used by a real board during
>> the board bring-up process.
>>
>> It generates an SPL image that can be loaded using imx_usb or
>> SB_LOADER.exe.
>>
>> When run, it will generate a set of calibration constants for
>> use in either or both a DCD configuration file for boards that
>> use u-boot.imx or struct mx6_mmdc_calibration for boards that
>> boot via SPL.
>>
>> In essence, it is a configurable, open-source variant of the
>> Freescale ddr-stress tool.
>>
>>          https://community.nxp.com/docs/DOC-105652
>>
>> File mx6memcal_defconfig configures the board for use with
>> mx6sabresd or mx6qsabreauto.
> 
> Do you still have plans on refreshing this series?
> 

Plans is a strong word, but I certainly hope to find some time
to continue this effort.

I haven't been doing too many new board bring-ups lately though,
so it moved away from my front burner.

I set this aside because I wasn't able to get the "return to
RBL" code working and figured I'd try to reverse-engineer the API.

Any hints you have in that area would be helpful, and will solve
that other long-standing issue of how to live with SPL on i.MX.

> It does seem very useful.
> 

It is, and even the RFC patch allows very quick testing of
large numbers of boards to gather calibration data.

Regards,


Eric

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [U-Boot] [RFC PATCH 1/9] mx6: Add board mx6memcal for use in validating DDR
  2017-07-14 17:58               ` Eric Nelson
@ 2017-07-14 19:01                 ` Fabio Estevam
  2017-07-28  2:50                   ` Eric Nelson
  0 siblings, 1 reply; 44+ messages in thread
From: Fabio Estevam @ 2017-07-14 19:01 UTC (permalink / raw)
  To: u-boot

Hi Eric,

On Fri, Jul 14, 2017 at 2:58 PM, Eric Nelson <eric@nelint.com> wrote:

> I set this aside because I wasn't able to get the "return to
> RBL" code working and figured I'd try to reverse-engineer the API.
>
> Any hints you have in that area would be helpful, and will solve
> that other long-standing issue of how to live with SPL on i.MX.

Sorry, but what does "return to RBL" mean?

Regards,

Fabio Estevam

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [U-Boot] [RFC PATCH 1/9] mx6: Add board mx6memcal for use in validating DDR
  2017-07-14 19:01                 ` Fabio Estevam
@ 2017-07-28  2:50                   ` Eric Nelson
  0 siblings, 0 replies; 44+ messages in thread
From: Eric Nelson @ 2017-07-28  2:50 UTC (permalink / raw)
  To: u-boot

Hi Fabio,

On Fri, Jul 14, 2017 at 12:01 PM, Fabio Estevam <festevam@gmail.com> wrote:

> Hi Eric,
>
> On Fri, Jul 14, 2017 at 2:58 PM, Eric Nelson <eric@nelint.com> wrote:
>
> > I set this aside because I wasn't able to get the "return to
> > RBL" code working and figured I'd try to reverse-engineer the API.
> >
> > Any hints you have in that area would be helpful, and will solve
> > that other long-standing issue of how to live with SPL on i.MX.
>
> Sorry, but what does "return to RBL" mean?
>
>
I was trying to get the SPL to act as a plugin in this patch set, so we
could send
a full U-Boot with a memory test as a payload, but got stuck on the details.

https://lists.denx.de/pipermail/u-boot/2016-June/258784.html

Looking back at the patch set, the plugin support wasn't explicitly
included.

I sent some notes in November:

https://lists.denx.de/pipermail/u-boot/2016-November/271647.html

And there was some follow-up in January:

https://lists.denx.de/pipermail/u-boot/2017-January/278518.html

^ permalink raw reply	[flat|nested] 44+ messages in thread

end of thread, other threads:[~2017-07-28  2:50 UTC | newest]

Thread overview: 44+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-30 17:18 [U-Boot] [PATCH 0/3] mx6: ddr: updates for dynamic DDR calibration Eric Nelson
2016-10-30 17:19 ` [U-Boot] [PATCH 1/3] mx6: ddr: allow 32 cycles for DQS gating calibration Eric Nelson
2016-10-30 17:27   ` Marek Vasut
2016-10-30 17:19 ` [U-Boot] [PATCH 2/3] mx6: ddr: pass mx6_ddr_sysinfo to calibration routines Eric Nelson
2016-10-30 17:29   ` Marek Vasut
2016-10-30 17:19 ` [U-Boot] [PATCH 3/3] mx6: ddr: add routine to return DDR calibration data Eric Nelson
2016-10-30 17:30   ` Marek Vasut
2016-10-30 19:14     ` Eric Nelson
2016-10-30 20:02       ` Marek Vasut
2016-10-30 19:20   ` [U-Boot] [PATCH] ARM: mx6: ddr: use Kconfig for inclusion of DDR calibration routines Eric Nelson
2016-10-30 20:03     ` Marek Vasut
2016-10-30 23:10       ` Eric Nelson
2016-10-30 23:33         ` [U-Boot] [PATCH V2 0/4] mx6: ddr: updates for dynamic DDR calibration Eric Nelson
2016-10-30 23:33           ` [U-Boot] [PATCH V2 1/4] mx6: ddr: allow 32 cycles for DQS gating calibration Eric Nelson
2016-10-30 23:33           ` [U-Boot] [PATCH V2 2/4] mx6: ddr: pass mx6_ddr_sysinfo to calibration routines Eric Nelson
2016-10-30 23:33           ` [U-Boot] [PATCH V2 3/4] mx6: ddr: add routine to return DDR calibration data Eric Nelson
2016-10-30 23:33           ` [U-Boot] [PATCH V2 4/4] ARM: mx6: ddr: use Kconfig for inclusion of DDR calibration routines Eric Nelson
2016-11-22 10:59           ` [U-Boot] [PATCH V2 0/4] mx6: ddr: updates for dynamic DDR calibration Christoph Fritz
2016-11-29 16:28           ` Stefano Babic
2016-11-01 20:13         ` [U-Boot] [RFC PATCH 0/9] ARM: imx: mx6: Add virtual mx6memcal board Eric Nelson
2016-11-01 20:13           ` [U-Boot] [RFC PATCH 1/9] mx6: Add board mx6memcal for use in validating DDR Eric Nelson
2017-07-14 14:18             ` Fabio Estevam
2017-07-14 17:58               ` Eric Nelson
2017-07-14 19:01                 ` Fabio Estevam
2017-07-28  2:50                   ` Eric Nelson
2016-11-01 20:13           ` [U-Boot] [RFC PATCH 2/9] mx6memcal: zero values for MPWRDLCTL cause read DQS calibration errors Eric Nelson
2016-11-01 20:13           ` [U-Boot] [RFC PATCH 3/9] mx6memcal: add configuration for SABRE Lite Eric Nelson
2016-11-01 20:13           ` [U-Boot] [RFC PATCH 4/9] mx6memcal: add configuration for Nitrogen6_max board Eric Nelson
2016-11-01 20:13           ` [U-Boot] [RFC PATCH 5/9] mx6memcal: add configuration for tr1x board (i.MX6SL with DDR3) Eric Nelson
2016-11-01 20:13           ` [U-Boot] [RFC PATCH 6/9] mx6memcal: add configuration for Wandboard Solo (512MiB of x32 DDR3) Eric Nelson
2016-11-01 20:13           ` [U-Boot] [RFC PATCH 7/9] mx6memcal: add configuration for Wandboard Quad Eric Nelson
2016-11-01 20:13           ` [U-Boot] [RFC PATCH 8/9] mx6memcal: add configuration for mx6slevk Eric Nelson
2016-11-01 20:13           ` [U-Boot] [RFC PATCH 9/9] mx6memcal: add configuration for warp board (i.MX6SL) Eric Nelson
2016-11-02  2:06           ` [U-Boot] [RFC PATCH 0/3] ARM: imx: mx6: Add plugin support for SPL Eric Nelson
2016-11-02  2:06             ` [U-Boot] [RFC PATCH 1/3] ARM: mx6: preserve Boot ROM stack in SPL Eric Nelson
2016-11-02  2:06             ` [U-Boot] [RFC PATCH 2/3] ARM: mx6: ddr: add plugin-utils placeholder Eric Nelson
2016-11-02  2:06             ` [U-Boot] [RFC PATCH 3/3] ARM: imx: mx6memcal: allow build of combined SPL+U-Boot Eric Nelson
2017-01-18  1:27             ` [U-Boot] [RFC PATCH 0/3] ARM: imx: mx6: Add plugin support for SPL Tim Harvey
2017-01-18 17:05               ` Eric Nelson
2017-01-18 18:49                 ` Tim Harvey
2017-01-18 19:01                   ` Fabio Estevam
2017-01-20 17:40                     ` Tim Harvey
2017-01-27 14:56                       ` Fabio Estevam
2017-01-27 15:25                         ` Otavio Salvador

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.