Skip to contentSkip to conversation

imx:mx6 spl support for mx6sxsabresd

PATCH New Peng Fan 4 participants 11 messages Dec 30, 2014 – Feb 6, 2015

Subsystems (2)
lore
Share & tools
lore

Peng Fan

author
#0 lore raw

cover imx:mx6 spl support for mx6sxsabresd

This patch set is to make mx6sxsabresd spl boot capable from USDHC. SPL image is burned to sector 2 of SD card. u-boot.img is burned to sector 138.

Since i.MX 6SoloX chip only supports one mmdc channel, in order to reuse mx6_dram_cfg, define a new macro MMDC1. To i.MX 6SoloX, MMDC1 does nothing; to others, MMDC1 effects as the original "mmdc1->entry = value".

Peng Fan (6):
imx:mx6sxsabresd add spl config file
imx:mx6sxsabresd select SUPPORT_SPL
imx:mx6sxsabresd spl support in header file
imx:mx6sx add dram io configure for mx6sx
imx:mx6 add mx6sx in imx spl header file
imx:mx6sxsabresd board spl support

 arch/arm/Kconfig                            |   1 +
 arch/arm/cpu/armv7/mx6/ddr.c                |  96 +++++++++++++---
 arch/arm/include/asm/arch-mx6/mx6-ddr.h     |  46 ++++++++
 board/freescale/mx6sxsabresd/MAINTAINERS    |   1 +
 board/freescale/mx6sxsabresd/mx6sxsabresd.c | 168 ++++++++++++++++++++++++++++
 configs/mx6sxsabresd_spl_defconfig          |   4 +
 include/configs/imx6_spl.h                  |   8 ++
 include/configs/mx6sxsabresd.h              |   6 +
 8 files changed, 316 insertions(+), 14 deletions(-)
 create mode 100644 configs/mx6sxsabresd_spl_defconfig
Signature · 1 line
1.8.4
author
#1 lore raw

PATCH 1/6 imx:mx6sxsabresd add spl config file

Add a SPL default configuration file for mx6sxsabresd board.

---
 configs/mx6sxsabresd_spl_defconfig | 4 ++++
 1 file changed, 4 insertions(+)
 create mode 100644 configs/mx6sxsabresd_spl_defconfig
configs/mx6sxsabresd_spl_defconfig new file +4 -0
new file mode 100644
index 0000000..6b36e06
@@ -0,0 +1,4 @@
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,MX6SX"
++S:CONFIG_ARM=y
++S:CONFIG_TARGET_MX6SXSABRESD=y
Signature · 1 line
1.8.4
author
#2 lore raw

PATCH 2/6 imx:mx6sxsabresd select SUPPORT_SPL

In reply to Peng Fan

select SUPPORT_SPL for mx6sxsabresd.

---
 arch/arm/Kconfig | 1 +
 1 file changed, 1 insertion(+)
arch/arm/Kconfig +1 -0
index 5eb1d03..46e708f 100644
@@ -637,6 +637,7 @@ config TARGET_MX6SLEVK
 config TARGET_MX6SXSABRESD
 	bool "Support mx6sxsabresd"
 	select CPU_V7
+	select SUPPORT_SPL
 
 config TARGET_GW_VENTANA
 	bool "Support gw_ventana"
Signature · 1 line
1.8.4
author
#3 lore raw

PATCH 3/6 imx:mx6sxsabresd spl support in header file

In reply to Peng Fan

Add SPL support in mx6sxsabresd header file.

---
 include/configs/mx6sxsabresd.h | 6 ++++++
 1 file changed, 6 insertions(+)
include/configs/mx6sxsabresd.h +6 -0
index 61a7a7a..19ac3dc 100644
@@ -18,6 +18,12 @@
 #define CONFIG_DISPLAY_CPUINFO
 #define CONFIG_DISPLAY_BOARDINFO
 
+#ifdef CONFIG_SPL
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_MMC_SUPPORT
+#include "imx6_spl.h"
+#endif
+
 #define CONFIG_CMDLINE_TAG
 #define CONFIG_SETUP_MEMORY_TAGS
 #define CONFIG_INITRD_TAG
Signature · 1 line
1.8.4
author
#4 lore raw

PATCH 4/6 imx:mx6sx add dram io configure for mx6sx

In reply to Peng Fan

Define two structure mx6sx_iomux_ddr_regs and mx6sx_iomux_grp_regs. Add a new function mx6sx_dram_iocfg to configure dram io.

Since mx6sx only have one channel mmdc0, define a new empty macro MMDC1 to replace mmdc1->entry=value for mx6sx. And to other mx6 soc, MMDC1 effects as "mmdc1->entry=value".

---
 arch/arm/cpu/armv7/mx6/ddr.c            | 96 ++++++++++++++++++++++++++++-----
 arch/arm/include/asm/arch-mx6/mx6-ddr.h | 46 ++++++++++++++++
 2 files changed, 128 insertions(+), 14 deletions(-)
arch/arm/cpu/armv7/mx6/ddr.c +82 -14
index 7a9b03a..fef2231 100644
@@ -12,6 +12,65 @@
 #include <asm/io.h>
 #include <asm/types.h>
 
+#if defined(CONFIG_MX6SX)
+/* Configure MX6SX mmdc iomux */
+void mx6sx_dram_iocfg(unsigned width,
+		      const struct mx6sx_iomux_ddr_regs *ddr,
+		      const struct mx6sx_iomux_grp_regs *grp)
+{
+	struct mx6sx_iomux_ddr_regs *mx6_ddr_iomux;
+	struct mx6sx_iomux_grp_regs *mx6_grp_iomux;
+
+	mx6_ddr_iomux = (struct mx6sx_iomux_ddr_regs *)MX6SX_IOM_DDR_BASE;
+	mx6_grp_iomux = (struct mx6sx_iomux_grp_regs *)MX6SX_IOM_GRP_BASE;
+
+	/* DDR IO TYPE */
+	writel(grp->grp_ddr_type, &mx6_grp_iomux->grp_ddr_type);
+	writel(grp->grp_ddrpke, &mx6_grp_iomux->grp_ddrpke);
+
+	/* CLOCK */
+	writel(ddr->dram_sdclk_0, &mx6_ddr_iomux->dram_sdclk_0);
+
+	/* ADDRESS */
+	writel(ddr->dram_cas, &mx6_ddr_iomux->dram_cas);
+	writel(ddr->dram_ras, &mx6_ddr_iomux->dram_ras);
+	writel(grp->grp_addds, &mx6_grp_iomux->grp_addds);
+
+	/* Control */
+	writel(ddr->dram_reset, &mx6_ddr_iomux->dram_reset);
+	writel(ddr->dram_sdba2, &mx6_ddr_iomux->dram_sdba2);
+	writel(ddr->dram_sdcke0, &mx6_ddr_iomux->dram_sdcke0);
+	writel(ddr->dram_sdcke1, &mx6_ddr_iomux->dram_sdcke1);
+	writel(ddr->dram_odt0, &mx6_ddr_iomux->dram_odt0);
+	writel(ddr->dram_odt1, &mx6_ddr_iomux->dram_odt1);
+	writel(grp->grp_ctlds, &mx6_grp_iomux->grp_ctlds);
+
+	/* Data Strobes */
+	writel(grp->grp_ddrmode_ctl, &mx6_grp_iomux->grp_ddrmode_ctl);
+	writel(ddr->dram_sdqs0, &mx6_ddr_iomux->dram_sdqs0);
+	writel(ddr->dram_sdqs1, &mx6_ddr_iomux->dram_sdqs1);
+	if (width >= 32) {
+		writel(ddr->dram_sdqs2, &mx6_ddr_iomux->dram_sdqs2);
+		writel(ddr->dram_sdqs3, &mx6_ddr_iomux->dram_sdqs3);
+	}
+
+	/* Data */
+	writel(grp->grp_ddrmode, &mx6_grp_iomux->grp_ddrmode);
+	writel(grp->grp_b0ds, &mx6_grp_iomux->grp_b0ds);
+	writel(grp->grp_b1ds, &mx6_grp_iomux->grp_b1ds);
+	if (width >= 32) {
+		writel(grp->grp_b2ds, &mx6_grp_iomux->grp_b2ds);
+		writel(grp->grp_b3ds, &mx6_grp_iomux->grp_b3ds);
+	}
+	writel(ddr->dram_dqm0, &mx6_ddr_iomux->dram_dqm0);
+	writel(ddr->dram_dqm1, &mx6_ddr_iomux->dram_dqm1);
+	if (width >= 32) {
+		writel(ddr->dram_dqm2, &mx6_ddr_iomux->dram_dqm2);
+		writel(ddr->dram_dqm3, &mx6_ddr_iomux->dram_dqm3);
+	}
+}
+#endif
+
 #if defined(CONFIG_MX6QDL) || defined(CONFIG_MX6Q) || defined(CONFIG_MX6D)
 /* Configure MX6DQ mmdc iomux */
 void mx6dq_dram_iocfg(unsigned width,
@@ -184,12 +243,19 @@ void mx6sdl_dram_iocfg(unsigned width,
  */
 #define MR(val, ba, cmd, cs1) \
 	((val << 16) | (1 << 15) | (cmd << 4) | (cs1 << 3) | ba)
+#ifdef CONFIG_MX6SX
+#define MMDC1(entry, value)	do {} while (0)
+#else
+#define MMDC1(entry, value) do { mmdc1->entry = value; } while (0)
+#endif
 void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo,
 		  const struct mx6_mmdc_calibration *calib,
 		  const struct mx6_ddr3_cfg *ddr3_cfg)
 {
 	volatile struct mmdc_p_regs *mmdc0;
+#ifndef CONFIG_MX6SX
 	volatile struct mmdc_p_regs *mmdc1;
+#endif
 	u32 val;
 	u8 tcke, tcksrx, tcksre, txpdll, taofpd, taonpd, trrd;
 	u8 todtlon, taxpd, tanpd, tcwl, txp, tfaw, tcl;
@@ -203,7 +269,9 @@ void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo,
 	int cs;
 
 	mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR;
+#ifndef CONFIG_MX6SX
 	mmdc1 = (struct mmdc_p_regs *)MMDC_P1_BASE_ADDR;
+#endif
 
 	/* MX6D/MX6Q: 1066 MHz memory clock, clkper = 1.894ns = 1894ps */
 	if (is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D)) {
@@ -362,12 +430,12 @@ void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo,
 	mmdc0->mprddlctl = calib->p0_mprddlctl;
 	mmdc0->mpwrdlctl = calib->p0_mpwrdlctl;
 	if (sysinfo->dsize > 1) {
-		mmdc1->mpwldectrl0 = calib->p1_mpwldectrl0;
-		mmdc1->mpwldectrl1 = calib->p1_mpwldectrl1;
-		mmdc1->mpdgctrl0 = calib->p1_mpdgctrl0;
-		mmdc1->mpdgctrl1 = calib->p1_mpdgctrl1;
-		mmdc1->mprddlctl = calib->p1_mprddlctl;
-		mmdc1->mpwrdlctl = calib->p1_mpwrdlctl;
+		MMDC1(mpwldectrl0, calib->p1_mpwldectrl0);
+		MMDC1(mpwldectrl1, calib->p1_mpwldectrl1);
+		MMDC1(mpdgctrl0, calib->p1_mpdgctrl0);
+		MMDC1(mpdgctrl1, calib->p1_mpdgctrl1);
+		MMDC1(mprddlctl, calib->p1_mprddlctl);
+		MMDC1(mpwrdlctl, calib->p1_mpwrdlctl);
 	}
 
 	/* Read data DQ Byte0-3 delay */
@@ -379,23 +447,23 @@ void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo,
 	}
 
 	if (sysinfo->dsize > 1) {
-		mmdc1->mprddqby0dl = 0x33333333;
-		mmdc1->mprddqby1dl = 0x33333333;
-		mmdc1->mprddqby2dl = 0x33333333;
-		mmdc1->mprddqby3dl = 0x33333333;
+		MMDC1(mprddqby0dl, 0x33333333);
+		MMDC1(mprddqby1dl, 0x33333333);
+		MMDC1(mprddqby2dl, 0x33333333);
+		MMDC1(mprddqby3dl, 0x33333333);
 	}
 
 	/* MMDC Termination: rtt_nom:2 RZQ/2(120ohm), rtt_nom:1 RZQ/4(60ohm) */
 	val = (sysinfo->rtt_nom == 2) ? 0x00011117 : 0x00022227;
 	mmdc0->mpodtctrl = val;
 	if (sysinfo->dsize > 1)
-		mmdc1->mpodtctrl = val;
+		MMDC1(mpodtctrl, val);
 
 	/* complete calibration */
 	val = (1 << 11); /* Force measurement on delay-lines */
 	mmdc0->mpmur0 = val;
 	if (sysinfo->dsize > 1)
-		mmdc1->mpmur0 = val;
+		MMDC1(mpmur0, val);
 
 	/* Step 1: configuration request */
 	mmdc0->mdscr = (u32)(1 << 15); /* config request */
@@ -435,7 +503,7 @@ void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo,
 	val = 0xa1390001; /* one-time HW ZQ calib */
 	mmdc0->mpzqhwctrl = val;
 	if (sysinfo->dsize > 1)
-		mmdc1->mpzqhwctrl = val;
+		MMDC1(mpzqhwctrl, val);
 
 	/* Step 7: Enable MMDC with desired chip select */
 	mmdc0->mdctl |= (1 << 31) |			     /* SDE_0 for CS0 */
@@ -477,7 +545,7 @@ void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo,
 	val = 0xa1390003;
 	mmdc0->mpzqhwctrl = val;
 	if (sysinfo->dsize > 1)
-		mmdc1->mpzqhwctrl = val;
+		MMDC1(mpzqhwctrl, val);
 
 	/* Step 12: Configure and activate periodic refresh */
 	mmdc0->mdref = (1 << 14) | /* REF_SEL: Periodic refresh cycle: 32kHz */
arch/arm/include/asm/arch-mx6/mx6-ddr.h +46 -0

58 lines not on this page · raw message

Signature · 1 line
1.8.4
author
#5 lore raw

PATCH 5/6 imx:mx6 add mx6sx in imx spl header file

In reply to Peng Fan

Since mx6sx's memory space is different to mx6dq, redefine the SPL related macro for mx6sx chip.

---
 include/configs/imx6_spl.h | 8 ++++++++
 1 file changed, 8 insertions(+)
include/configs/imx6_spl.h +8 -0
index 1b9c277..21c5dce 100644
@@ -61,11 +61,19 @@
 #define CONFIG_SPL_LIBDISK_SUPPORT
 #endif
 
+#if defined(CONFIG_MX6SX)
+#define CONFIG_SPL_BSS_START_ADDR      0x88200000
+#define CONFIG_SPL_BSS_MAX_SIZE        0x100000        /* 1 MB */
+#define CONFIG_SYS_SPL_MALLOC_START    0x88300000
+#define CONFIG_SYS_SPL_MALLOC_SIZE     0x3200000       /* 50 MB */
+#define CONFIG_SYS_TEXT_BASE           0x87800000
+#else
 #define CONFIG_SPL_BSS_START_ADDR	0x18200000
 #define CONFIG_SPL_BSS_MAX_SIZE		0x100000	/* 1 MB */
 #define CONFIG_SYS_SPL_MALLOC_START	0x18300000
 #define CONFIG_SYS_SPL_MALLOC_SIZE	0x3200000	/* 50 MB */
 #define CONFIG_SYS_TEXT_BASE		0x17800000
 #endif
+#endif
 
 #endif
Signature · 1 line
1.8.4
author
#6 lore raw

PATCH 6/6 imx:mx6sxsabresd board spl support

In reply to Peng Fan

Add board level spl support for mx6sxsabresd board.

---
 board/freescale/mx6sxsabresd/MAINTAINERS    |   1 +
 board/freescale/mx6sxsabresd/mx6sxsabresd.c | 168 ++++++++++++++++++++++++++++
 2 files changed, 169 insertions(+)
board/freescale/mx6sxsabresd/MAINTAINERS +1 -0
index f52f300..c0f5d9c 100644
@@ -4,3 +4,4 @@ S:	Maintained
 F:	board/freescale/mx6sxsabresd/
 F:	include/configs/mx6sxsabresd.h
 F:	configs/mx6sxsabresd_defconfig
+F:	configs/mx6sxsabresd_spl_defconfig
board/freescale/mx6sxsabresd/mx6sxsabresd.c +168 -0

183 lines not on this page · raw message

Signature · 1 line
1.8.4
#7 lore raw

PATCH 6/6 imx:mx6sxsabresd board spl support

Hi Peng,

series looks ok to me - just a small question:

Quoted 146 lines · Peng Fan

Add board level spl support for mx6sxsabresd board.

---
 board/freescale/mx6sxsabresd/MAINTAINERS    |   1 +
 board/freescale/mx6sxsabresd/mx6sxsabresd.c | 168 ++++++++++++++++++++++++++++
 2 files changed, 169 insertions(+)
board/freescale/mx6sxsabresd/MAINTAINERS +1 -0
index f52f300..c0f5d9c 100644
@@ -4,3 +4,4 @@ S:	Maintained
 F:	board/freescale/mx6sxsabresd/
 F:	include/configs/mx6sxsabresd.h
 F:	configs/mx6sxsabresd_defconfig
+F:	configs/mx6sxsabresd_spl_defconfig
board/freescale/mx6sxsabresd/mx6sxsabresd.c +107 -0
index fd8bc72..74f6d40 100644
@@ -326,6 +326,7 @@ int board_mmc_getcd(struct mmc *mmc)
 
 int board_mmc_init(bd_t *bis)
 {
+#ifndef CONFIG_SPL_BUILD
 	int i, ret;
 
 	/*
@@ -369,6 +370,47 @@ int board_mmc_init(bd_t *bis)
 	}
 
 	return 0;
+#else
+	struct src *src_regs = (struct src *)SRC_BASE_ADDR;
+	u32 val;
+	u32 port;
+
+	val = readl(&src_regs->sbmr1);
+
+	if ((val & 0xc0) != 0x40) {
+		printf("Not boot from USDHC!\n");
+		return -EINVAL;
+	}
+
+	port = (val >> 11) & 0x3;
+	printf("port %d\n", port);
+	switch (port) {
+	case 1:
+		imx_iomux_v3_setup_multiple_pads(
+			usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
+		usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
+		usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR;
+		break;
+	case 2:
+		imx_iomux_v3_setup_multiple_pads(
+			usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
+		gpio_direction_input(USDHC3_CD_GPIO);
+		gpio_direction_output(USDHC3_PWR_GPIO, 1);
+		usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
+		usdhc_cfg[0].esdhc_base = USDHC3_BASE_ADDR;
+		break;
+	case 3:
+		imx_iomux_v3_setup_multiple_pads(
+			usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
+		gpio_direction_input(USDHC4_CD_GPIO);
+		usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
+		usdhc_cfg[0].esdhc_base = USDHC4_BASE_ADDR;
+		break;
+	}
+
+	gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
+	return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
+#endif
 }
 
 int board_init(void)
@@ -394,3 +436,129 @@ int checkboard(void)
 
 	return 0;
 }
+
+#ifdef CONFIG_SPL_BUILD
+#include <libfdt.h>
+#include <spl.h>
+#include <asm/arch/mx6-ddr.h>
+
+const struct mx6sx_iomux_ddr_regs mx6_ddr_ioregs = {
+	.dram_dqm0 = 0x00000028,
+	.dram_dqm1 = 0x00000028,
+	.dram_dqm2 = 0x00000028,
+	.dram_dqm3 = 0x00000028,
+	.dram_ras = 0x00000020,
+	.dram_cas = 0x00000020,
+	.dram_odt0 = 0x00000020,
+	.dram_odt1 = 0x00000020,
+	.dram_sdba2 = 0x00000000,
+	.dram_sdcke0 = 0x00003000,
+	.dram_sdcke1 = 0x00003000,
+	.dram_sdclk_0 = 0x00000030,
+	.dram_sdqs0 = 0x00000028,
+	.dram_sdqs1 = 0x00000028,
+	.dram_sdqs2 = 0x00000028,
+	.dram_sdqs3 = 0x00000028,
+	.dram_reset = 0x00000020,
+};
+
+const struct mx6sx_iomux_grp_regs mx6_grp_ioregs = {
+	.grp_addds = 0x00000020,
+	.grp_ddrmode_ctl = 0x00020000,
+	.grp_ddrpke = 0x00000000,
+	.grp_ddrmode = 0x00020000,
+	.grp_b0ds = 0x00000028,
+	.grp_b1ds = 0x00000028,
+	.grp_ctlds = 0x00000020,
+	.grp_ddr_type = 0x000c0000,
+	.grp_b2ds = 0x00000028,
+	.grp_b3ds = 0x00000028,
+};
+
+const struct mx6_mmdc_calibration mx6_mmcd_calib = {
+	.p0_mpwldectrl0 = 0x00290025,
+	.p0_mpwldectrl1 = 0x00220022,
+	.p0_mpdgctrl0 = 0x41480144,
+	.p0_mpdgctrl1 = 0x01340130,
+	.p0_mprddlctl = 0x3C3E4244,
+	.p0_mpwrdlctl = 0x34363638,
+};
+
+static struct mx6_ddr3_cfg mem_ddr = {
+	.mem_speed = 1600,
+	.density = 4,
+	.width = 32,
+	.banks = 8,
+	.rowaddr = 15,
+	.coladdr = 10,
+	.pagesz = 2,
+	.trcd = 1375,
+	.trcmin = 4875,
+	.trasmin = 3500,
+};
+
+static void ccgr_init(void)
+{
+	struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+

board/freescale/mx6sxsabresd/mx6sxsabresd.c int checkboard(void) · line 513

Quoted 10 lines
board/freescale/mx6sxsabresd/mx6sxsabresd.c +10 -0
+	writel(0xFFFFFFFF, &ccm->CCGR0);
+	writel(0xFFFFFFFF, &ccm->CCGR1);
+	writel(0xFFFFFFFF, &ccm->CCGR2);
+	writel(0xFFFFFFFF, &ccm->CCGR3);
+	writel(0xFFFFFFFF, &ccm->CCGR4);
+	writel(0xFFFFFFFF, &ccm->CCGR5);
+	writel(0xFFFFFFFF, &ccm->CCGR6);
+	writel(0xFFFFFFFF, &ccm->CCGR7);
+}
+

Is it ok to enable all clocks ? This is quite uncommon in U-Boot and it can raise some issues when Linux is booted because it assumes that clocks are turned off. Anyway, this is only a question: if this is ok for you (I do not test on this board), it is not an issue.

Quoted 42 lines
board/freescale/mx6sxsabresd/mx6sxsabresd.c +41 -0
+static void spl_dram_init(void)
+{
+	struct mx6_ddr_sysinfo sysinfo = {
+		.dsize = mem_ddr.width/32,
+		.cs_density = 24,
+		.ncs = 1,
+		.cs1_mirror = 0,
+		.rtt_wr = 2,
+		.rtt_nom = 2,		/* RTT_Nom = RZQ/2 */
+		.walat = 1,		/* Write additional latency */
+		.ralat = 5,		/* Read additional latency */
+		.mif3_mode = 3,		/* Command prediction working mode */
+		.bi_on = 1,		/* Bank interleaving enabled */
+		.sde_to_rst = 0x10,	/* 14 cycles, 200us (JEDEC default) */
+		.rst_to_cke = 0x23,	/* 33 cycles, 500us (JEDEC default) */
+	};
+
+	mx6sx_dram_iocfg(mem_ddr.width, &mx6_ddr_ioregs, &mx6_grp_ioregs);
+	mx6_dram_cfg(&sysinfo, &mx6_mmcd_calib, &mem_ddr);
+}
+
+void board_init_f(ulong dummy)
+{
+	/* setup AIPS and disable watchdog */
+	arch_cpu_init();
+
+	ccgr_init();
+
+	/* iomux and setup of i2c */
+	board_early_init_f();
+
+	/* setup GP timer */
+	timer_init();
+
+	/* UART clocks enabled and gd valid - init serial console */
+	preloader_console_init();
+
+	/* DDR initialization */
+	spl_dram_init();
+
+	/* Clear the BSS. */

board/freescale/mx6sxsabresd/mx6sxsabresd.c int checkboard(void) · line 564

Quoted 10 lines
board/freescale/mx6sxsabresd/mx6sxsabresd.c +10 -0
+	memset(__bss_start, 0, __bss_end - __bss_start);
+
+	/* load/boot image from boot device */
+	board_init_r(NULL, 0);
+}
+
+void reset_cpu(ulong addr)
+{
+}
+#endif

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
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
=====================================================================
#8 lore raw

PATCH 6/6 imx:mx6sxsabresd board spl support

Hi Stefano,

Quoted 157 lines · Stefano Babic

Hi Peng,

series looks ok to me - just a small question:

Quoted 152 lines · Peng Fan

Add board level spl support for mx6sxsabresd board.

---
  board/freescale/mx6sxsabresd/MAINTAINERS    |   1 +
  board/freescale/mx6sxsabresd/mx6sxsabresd.c | 168 ++++++++++++++++++++++++++++
  2 files changed, 169 insertions(+)
board/freescale/mx6sxsabresd/MAINTAINERS +1 -0
index f52f300..c0f5d9c 100644
@@ -4,3 +4,4 @@ S:	Maintained
  F:	board/freescale/mx6sxsabresd/
  F:	include/configs/mx6sxsabresd.h
  F:	configs/mx6sxsabresd_defconfig
+F:	configs/mx6sxsabresd_spl_defconfig
board/freescale/mx6sxsabresd/mx6sxsabresd.c +113 -0
index fd8bc72..74f6d40 100644
@@ -326,6 +326,7 @@ int board_mmc_getcd(struct mmc *mmc)
 
  int board_mmc_init(bd_t *bis)
  {
+#ifndef CONFIG_SPL_BUILD
  	int i, ret;
 
  	/*
@@ -369,6 +370,47 @@ int board_mmc_init(bd_t *bis)
  	}
 
  	return 0;
+#else
+	struct src *src_regs = (struct src *)SRC_BASE_ADDR;
+	u32 val;
+	u32 port;
+
+	val = readl(&src_regs->sbmr1);
+
+	if ((val & 0xc0) != 0x40) {
+		printf("Not boot from USDHC!\n");
+		return -EINVAL;
+	}
+
+	port = (val >> 11) & 0x3;
+	printf("port %d\n", port);
+	switch (port) {
+	case 1:
+		imx_iomux_v3_setup_multiple_pads(
+			usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
+		usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
+		usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR;
+		break;
+	case 2:
+		imx_iomux_v3_setup_multiple_pads(
+			usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
+		gpio_direction_input(USDHC3_CD_GPIO);
+		gpio_direction_output(USDHC3_PWR_GPIO, 1);
+		usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
+		usdhc_cfg[0].esdhc_base = USDHC3_BASE_ADDR;
+		break;
+	case 3:
+		imx_iomux_v3_setup_multiple_pads(
+			usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
+		gpio_direction_input(USDHC4_CD_GPIO);
+		usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
+		usdhc_cfg[0].esdhc_base = USDHC4_BASE_ADDR;
+		break;
+	}
+
+	gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
+	return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
+#endif
  }
 
  int board_init(void)
@@ -394,3 +436,129 @@ int checkboard(void)
 
  	return 0;
  }
+
+#ifdef CONFIG_SPL_BUILD
+#include <libfdt.h>
+#include <spl.h>
+#include <asm/arch/mx6-ddr.h>
+
+const struct mx6sx_iomux_ddr_regs mx6_ddr_ioregs = {
+	.dram_dqm0 = 0x00000028,
+	.dram_dqm1 = 0x00000028,
+	.dram_dqm2 = 0x00000028,
+	.dram_dqm3 = 0x00000028,
+	.dram_ras = 0x00000020,
+	.dram_cas = 0x00000020,
+	.dram_odt0 = 0x00000020,
+	.dram_odt1 = 0x00000020,
+	.dram_sdba2 = 0x00000000,
+	.dram_sdcke0 = 0x00003000,
+	.dram_sdcke1 = 0x00003000,
+	.dram_sdclk_0 = 0x00000030,
+	.dram_sdqs0 = 0x00000028,
+	.dram_sdqs1 = 0x00000028,
+	.dram_sdqs2 = 0x00000028,
+	.dram_sdqs3 = 0x00000028,
+	.dram_reset = 0x00000020,
+};
+
+const struct mx6sx_iomux_grp_regs mx6_grp_ioregs = {
+	.grp_addds = 0x00000020,
+	.grp_ddrmode_ctl = 0x00020000,
+	.grp_ddrpke = 0x00000000,
+	.grp_ddrmode = 0x00020000,
+	.grp_b0ds = 0x00000028,
+	.grp_b1ds = 0x00000028,
+	.grp_ctlds = 0x00000020,
+	.grp_ddr_type = 0x000c0000,
+	.grp_b2ds = 0x00000028,
+	.grp_b3ds = 0x00000028,
+};
+
+const struct mx6_mmdc_calibration mx6_mmcd_calib = {
+	.p0_mpwldectrl0 = 0x00290025,
+	.p0_mpwldectrl1 = 0x00220022,
+	.p0_mpdgctrl0 = 0x41480144,
+	.p0_mpdgctrl1 = 0x01340130,
+	.p0_mprddlctl = 0x3C3E4244,
+	.p0_mpwrdlctl = 0x34363638,
+};
+
+static struct mx6_ddr3_cfg mem_ddr = {
+	.mem_speed = 1600,
+	.density = 4,
+	.width = 32,
+	.banks = 8,
+	.rowaddr = 15,
+	.coladdr = 10,
+	.pagesz = 2,
+	.trcd = 1375,
+	.trcmin = 4875,
+	.trasmin = 3500,
+};
+
+static void ccgr_init(void)
+{
+	struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+
+	writel(0xFFFFFFFF, &ccm->CCGR0);
+	writel(0xFFFFFFFF, &ccm->CCGR1);
+	writel(0xFFFFFFFF, &ccm->CCGR2);
+	writel(0xFFFFFFFF, &ccm->CCGR3);
+	writel(0xFFFFFFFF, &ccm->CCGR4);
+	writel(0xFFFFFFFF, &ccm->CCGR5);
Quoted 8 lines

board/freescale/mx6sxsabresd/mx6sxsabresd.c int checkboard(void) · line 513

Quoted 4 lines
board/freescale/mx6sxsabresd/mx6sxsabresd.c +4 -0
+	writel(0xFFFFFFFF, &ccm->CCGR6);
+	writel(0xFFFFFFFF, &ccm->CCGR7);
+}
+

Is it ok to enable all clocks ? This is quite uncommon in U-Boot and it can raise some issues when Linux is booted because it assumes that clocks are turned off. Anyway, this is only a question: if this is ok for you (I do not test on this board), it is not an issue.

In imximage.cfg DCD, all clocks is opened, so I add that in the spl to enable all clocks. This piece code is just the same thing in the DCD clock part.
I have tested this patch set on mx6sxsabresd revb board and linux can boot ok.

Quoted 46 lines
Quoted 46 lines
board/freescale/mx6sxsabresd/mx6sxsabresd.c +46 -0
+static void spl_dram_init(void)
+{
+	struct mx6_ddr_sysinfo sysinfo = {
+		.dsize = mem_ddr.width/32,
+		.cs_density = 24,
+		.ncs = 1,
+		.cs1_mirror = 0,
+		.rtt_wr = 2,
+		.rtt_nom = 2,		/* RTT_Nom = RZQ/2 */
+		.walat = 1,		/* Write additional latency */
+		.ralat = 5,		/* Read additional latency */
+		.mif3_mode = 3,		/* Command prediction working mode */
+		.bi_on = 1,		/* Bank interleaving enabled */
+		.sde_to_rst = 0x10,	/* 14 cycles, 200us (JEDEC default) */
+		.rst_to_cke = 0x23,	/* 33 cycles, 500us (JEDEC default) */
+	};
+
+	mx6sx_dram_iocfg(mem_ddr.width, &mx6_ddr_ioregs, &mx6_grp_ioregs);
+	mx6_dram_cfg(&sysinfo, &mx6_mmcd_calib, &mem_ddr);
+}
+
+void board_init_f(ulong dummy)
+{
+	/* setup AIPS and disable watchdog */
+	arch_cpu_init();
+
+	ccgr_init();
+
+	/* iomux and setup of i2c */
+	board_early_init_f();
+
+	/* setup GP timer */
+	timer_init();
+
+	/* UART clocks enabled and gd valid - init serial console */
+	preloader_console_init();
+
+	/* DDR initialization */
+	spl_dram_init();
+
+	/* Clear the BSS. */
+	memset(__bss_start, 0, __bss_end - __bss_start);
+
+	/* load/boot image from boot device */
+	board_init_r(NULL, 0);
+}
Quoted 9 lines

board/freescale/mx6sxsabresd/mx6sxsabresd.c int checkboard(void) · line 564

Quoted 6 lines
board/freescale/mx6sxsabresd/mx6sxsabresd.c +5 -0
+
+void reset_cpu(ulong addr)
+{
+}
+#endif

Best regards,
Stefano Babic

Regards,
Peng.

#9 lore raw

PATCH 6/6 imx:mx6sxsabresd board spl support

Hi Peng,

Quoted 167 lines · Peng Fan

Hi Stefano,

Quoted 155 lines · Stefano Babic

Hi Peng,

series looks ok to me - just a small question:

Quoted 150 lines · Peng Fan

Add board level spl support for mx6sxsabresd board.

---
  board/freescale/mx6sxsabresd/MAINTAINERS    |   1 +
  board/freescale/mx6sxsabresd/mx6sxsabresd.c | 168
++++++++++++++++++++++++++++
  2 files changed, 169 insertions(+)
board/freescale/mx6sxsabresd/MAINTAINERS +1 -0
index f52f300..c0f5d9c 100644
@@ -4,3 +4,4 @@ S:    Maintained
  F:    board/freescale/mx6sxsabresd/
  F:    include/configs/mx6sxsabresd.h
  F:    configs/mx6sxsabresd_defconfig
+F:    configs/mx6sxsabresd_spl_defconfig
board/freescale/mx6sxsabresd/mx6sxsabresd.c +113 -0
index fd8bc72..74f6d40 100644
@@ -326,6 +326,7 @@ int board_mmc_getcd(struct mmc *mmc)
  int board_mmc_init(bd_t *bis)
  {
+#ifndef CONFIG_SPL_BUILD
      int i, ret;
      /*
@@ -369,6 +370,47 @@ int board_mmc_init(bd_t *bis)
      }
      return 0;
+#else
+    struct src *src_regs = (struct src *)SRC_BASE_ADDR;
+    u32 val;
+    u32 port;
+
+    val = readl(&src_regs->sbmr1);
+
+    if ((val & 0xc0) != 0x40) {
+        printf("Not boot from USDHC!\n");
+        return -EINVAL;
+    }
+
+    port = (val >> 11) & 0x3;
+    printf("port %d\n", port);
+    switch (port) {
+    case 1:
+        imx_iomux_v3_setup_multiple_pads(
+            usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
+        usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
+        usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR;
+        break;
+    case 2:
+        imx_iomux_v3_setup_multiple_pads(
+            usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
+        gpio_direction_input(USDHC3_CD_GPIO);
+        gpio_direction_output(USDHC3_PWR_GPIO, 1);
+        usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
+        usdhc_cfg[0].esdhc_base = USDHC3_BASE_ADDR;
+        break;
+    case 3:
+        imx_iomux_v3_setup_multiple_pads(
+            usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
+        gpio_direction_input(USDHC4_CD_GPIO);
+        usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
+        usdhc_cfg[0].esdhc_base = USDHC4_BASE_ADDR;
+        break;
+    }
+
+    gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
+    return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
+#endif
  }
  int board_init(void)
@@ -394,3 +436,129 @@ int checkboard(void)
      return 0;
  }
+
+#ifdef CONFIG_SPL_BUILD
+#include <libfdt.h>
+#include <spl.h>
+#include <asm/arch/mx6-ddr.h>
+
+const struct mx6sx_iomux_ddr_regs mx6_ddr_ioregs = {
+    .dram_dqm0 = 0x00000028,
+    .dram_dqm1 = 0x00000028,
+    .dram_dqm2 = 0x00000028,
+    .dram_dqm3 = 0x00000028,
+    .dram_ras = 0x00000020,
+    .dram_cas = 0x00000020,
+    .dram_odt0 = 0x00000020,
+    .dram_odt1 = 0x00000020,
+    .dram_sdba2 = 0x00000000,
+    .dram_sdcke0 = 0x00003000,
+    .dram_sdcke1 = 0x00003000,
+    .dram_sdclk_0 = 0x00000030,
+    .dram_sdqs0 = 0x00000028,
+    .dram_sdqs1 = 0x00000028,
+    .dram_sdqs2 = 0x00000028,
+    .dram_sdqs3 = 0x00000028,
+    .dram_reset = 0x00000020,
+};
+
+const struct mx6sx_iomux_grp_regs mx6_grp_ioregs = {
+    .grp_addds = 0x00000020,
+    .grp_ddrmode_ctl = 0x00020000,
+    .grp_ddrpke = 0x00000000,
+    .grp_ddrmode = 0x00020000,
+    .grp_b0ds = 0x00000028,
+    .grp_b1ds = 0x00000028,
+    .grp_ctlds = 0x00000020,
+    .grp_ddr_type = 0x000c0000,
+    .grp_b2ds = 0x00000028,
+    .grp_b3ds = 0x00000028,
+};
+
+const struct mx6_mmdc_calibration mx6_mmcd_calib = {
+    .p0_mpwldectrl0 = 0x00290025,
+    .p0_mpwldectrl1 = 0x00220022,
+    .p0_mpdgctrl0 = 0x41480144,
+    .p0_mpdgctrl1 = 0x01340130,
+    .p0_mprddlctl = 0x3C3E4244,
+    .p0_mpwrdlctl = 0x34363638,
+};
+
+static struct mx6_ddr3_cfg mem_ddr = {
+    .mem_speed = 1600,
+    .density = 4,
+    .width = 32,
+    .banks = 8,
+    .rowaddr = 15,
+    .coladdr = 10,
+    .pagesz = 2,
+    .trcd = 1375,
+    .trcmin = 4875,
+    .trasmin = 3500,
+};
+
+static void ccgr_init(void)
+{
+    struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+
+    writel(0xFFFFFFFF, &ccm->CCGR0);
+    writel(0xFFFFFFFF, &ccm->CCGR1);
+    writel(0xFFFFFFFF, &ccm->CCGR2);
+    writel(0xFFFFFFFF, &ccm->CCGR3);
+    writel(0xFFFFFFFF, &ccm->CCGR4);
+    writel(0xFFFFFFFF, &ccm->CCGR5);
Quoted 8 lines

board/freescale/mx6sxsabresd/mx6sxsabresd.c int checkboard(void) · line 513

Quoted 4 lines
board/freescale/mx6sxsabresd/mx6sxsabresd.c +4 -0
+    writel(0xFFFFFFFF, &ccm->CCGR6);
+    writel(0xFFFFFFFF, &ccm->CCGR7);
+}
+

Is it ok to enable all clocks ? This is quite uncommon in U-Boot and it can raise some issues when Linux is booted because it assumes that clocks are turned off. Anyway, this is only a question: if this is ok for you (I do not test on this board), it is not an issue.

Quoted 5 lines

In imximage.cfg DCD, all clocks is opened, so I add that in the spl to enable all clocks. This piece code is just the same thing in the DCD clock part.
I have tested this patch set on mx6sxsabresd revb board and linux can boot ok.

Just FYI - when all the clocks are enabled, the imx6 can get uncomfortably hot. I'm not sure how it's with the imx6sx, but I tried in the past to enable all clocks on imx6d and it was not my best idea.

If this code will be running on the SabreSD development boards, your users can spend quite a bit of time hacking around in the U-Boot environment - editing env-vars, scripts, trying to guess boot args and what-not, but at the same time the CPU will be running at full steam.

Quoted 56 lines
Quoted 47 lines
Quoted 47 lines
board/freescale/mx6sxsabresd/mx6sxsabresd.c +46 -0
+static void spl_dram_init(void)
+{
+    struct mx6_ddr_sysinfo sysinfo = {
+        .dsize = mem_ddr.width/32,
+        .cs_density = 24,
+        .ncs = 1,
+        .cs1_mirror = 0,
+        .rtt_wr = 2,
+        .rtt_nom = 2,        /* RTT_Nom = RZQ/2 */
+        .walat = 1,        /* Write additional latency */
+        .ralat = 5,        /* Read additional latency */
+        .mif3_mode = 3,        /* Command prediction working mode */
+        .bi_on = 1,        /* Bank interleaving enabled */
+        .sde_to_rst = 0x10,    /* 14 cycles, 200us (JEDEC default) */
+        .rst_to_cke = 0x23,    /* 33 cycles, 500us (JEDEC default) */
+    };
+
+    mx6sx_dram_iocfg(mem_ddr.width, &mx6_ddr_ioregs, &mx6_grp_ioregs);
+    mx6_dram_cfg(&sysinfo, &mx6_mmcd_calib, &mem_ddr);
+}
+
+void board_init_f(ulong dummy)
+{
+    /* setup AIPS and disable watchdog */
+    arch_cpu_init();
+
+    ccgr_init();
+
+    /* iomux and setup of i2c */
+    board_early_init_f();
+
+    /* setup GP timer */
+    timer_init();
+
+    /* UART clocks enabled and gd valid - init serial console */
+    preloader_console_init();
+
+    /* DDR initialization */
+    spl_dram_init();
+
+    /* Clear the BSS. */
+    memset(__bss_start, 0, __bss_end - __bss_start);
+
+    /* load/boot image from boot device */
+    board_init_r(NULL, 0);
+}
Quoted 9 lines

board/freescale/mx6sxsabresd/mx6sxsabresd.c int checkboard(void)

Quoted 6 lines
board/freescale/mx6sxsabresd/mx6sxsabresd.c +5 -0
+
+void reset_cpu(ulong addr)
+{
+}
+#endif
 

Best regards,
Stefano Babic

Quoted 2 lines

Regards,
Peng.

Kind regards,
Nikolay

#10 lore raw

PATCH 6/6 imx:mx6sxsabresd board spl support

Hi Nikolay,

Quoted 176 lines · Nikolay Dimitrov

Hi Peng,

Quoted 167 lines · Peng Fan

Hi Stefano,

Quoted 155 lines · Stefano Babic

Hi Peng,

series looks ok to me - just a small question:

Quoted 150 lines · Peng Fan

Add board level spl support for mx6sxsabresd board.

---
  board/freescale/mx6sxsabresd/MAINTAINERS    |   1 +
  board/freescale/mx6sxsabresd/mx6sxsabresd.c | 168
++++++++++++++++++++++++++++
  2 files changed, 169 insertions(+)
board/freescale/mx6sxsabresd/MAINTAINERS +1 -0
index f52f300..c0f5d9c 100644
@@ -4,3 +4,4 @@ S:    Maintained
  F:    board/freescale/mx6sxsabresd/
  F:    include/configs/mx6sxsabresd.h
  F:    configs/mx6sxsabresd_defconfig
+F:    configs/mx6sxsabresd_spl_defconfig
board/freescale/mx6sxsabresd/mx6sxsabresd.c +113 -0
index fd8bc72..74f6d40 100644
@@ -326,6 +326,7 @@ int board_mmc_getcd(struct mmc *mmc)
  int board_mmc_init(bd_t *bis)
  {
+#ifndef CONFIG_SPL_BUILD
      int i, ret;
      /*
@@ -369,6 +370,47 @@ int board_mmc_init(bd_t *bis)
      }
      return 0;
+#else
+    struct src *src_regs = (struct src *)SRC_BASE_ADDR;
+    u32 val;
+    u32 port;
+
+    val = readl(&src_regs->sbmr1);
+
+    if ((val & 0xc0) != 0x40) {
+        printf("Not boot from USDHC!\n");
+        return -EINVAL;
+    }
+
+    port = (val >> 11) & 0x3;
+    printf("port %d\n", port);
+    switch (port) {
+    case 1:
+        imx_iomux_v3_setup_multiple_pads(
+            usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
+        usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
+        usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR;
+        break;
+    case 2:
+        imx_iomux_v3_setup_multiple_pads(
+            usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
+        gpio_direction_input(USDHC3_CD_GPIO);
+        gpio_direction_output(USDHC3_PWR_GPIO, 1);
+        usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
+        usdhc_cfg[0].esdhc_base = USDHC3_BASE_ADDR;
+        break;
+    case 3:
+        imx_iomux_v3_setup_multiple_pads(
+            usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
+        gpio_direction_input(USDHC4_CD_GPIO);
+        usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
+        usdhc_cfg[0].esdhc_base = USDHC4_BASE_ADDR;
+        break;
+    }
+
+    gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
+    return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
+#endif
  }
  int board_init(void)
@@ -394,3 +436,129 @@ int checkboard(void)
      return 0;
  }
+
+#ifdef CONFIG_SPL_BUILD
+#include <libfdt.h>
+#include <spl.h>
+#include <asm/arch/mx6-ddr.h>
+
+const struct mx6sx_iomux_ddr_regs mx6_ddr_ioregs = {
+    .dram_dqm0 = 0x00000028,
+    .dram_dqm1 = 0x00000028,
+    .dram_dqm2 = 0x00000028,
+    .dram_dqm3 = 0x00000028,
+    .dram_ras = 0x00000020,
+    .dram_cas = 0x00000020,
+    .dram_odt0 = 0x00000020,
+    .dram_odt1 = 0x00000020,
+    .dram_sdba2 = 0x00000000,
+    .dram_sdcke0 = 0x00003000,
+    .dram_sdcke1 = 0x00003000,
+    .dram_sdclk_0 = 0x00000030,
+    .dram_sdqs0 = 0x00000028,
+    .dram_sdqs1 = 0x00000028,
+    .dram_sdqs2 = 0x00000028,
+    .dram_sdqs3 = 0x00000028,
+    .dram_reset = 0x00000020,
+};
+
+const struct mx6sx_iomux_grp_regs mx6_grp_ioregs = {
+    .grp_addds = 0x00000020,
+    .grp_ddrmode_ctl = 0x00020000,
+    .grp_ddrpke = 0x00000000,
+    .grp_ddrmode = 0x00020000,
+    .grp_b0ds = 0x00000028,
+    .grp_b1ds = 0x00000028,
+    .grp_ctlds = 0x00000020,
+    .grp_ddr_type = 0x000c0000,
+    .grp_b2ds = 0x00000028,
+    .grp_b3ds = 0x00000028,
+};
+
+const struct mx6_mmdc_calibration mx6_mmcd_calib = {
+    .p0_mpwldectrl0 = 0x00290025,
+    .p0_mpwldectrl1 = 0x00220022,
+    .p0_mpdgctrl0 = 0x41480144,
+    .p0_mpdgctrl1 = 0x01340130,
+    .p0_mprddlctl = 0x3C3E4244,
+    .p0_mpwrdlctl = 0x34363638,
+};
+
+static struct mx6_ddr3_cfg mem_ddr = {
+    .mem_speed = 1600,
+    .density = 4,
+    .width = 32,
+    .banks = 8,
+    .rowaddr = 15,
+    .coladdr = 10,
+    .pagesz = 2,
+    .trcd = 1375,
+    .trcmin = 4875,
+    .trasmin = 3500,
+};
+
+static void ccgr_init(void)
+{
+    struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+
+    writel(0xFFFFFFFF, &ccm->CCGR0);
+    writel(0xFFFFFFFF, &ccm->CCGR1);
+    writel(0xFFFFFFFF, &ccm->CCGR2);
+    writel(0xFFFFFFFF, &ccm->CCGR3);
+    writel(0xFFFFFFFF, &ccm->CCGR4);
+    writel(0xFFFFFFFF, &ccm->CCGR5);
Quoted 8 lines

board/freescale/mx6sxsabresd/mx6sxsabresd.c int checkboard(void) · line 513

Quoted 4 lines
board/freescale/mx6sxsabresd/mx6sxsabresd.c +4 -0
+    writel(0xFFFFFFFF, &ccm->CCGR6);
+    writel(0xFFFFFFFF, &ccm->CCGR7);
+}
+

Is it ok to enable all clocks ? This is quite uncommon in U-Boot and it can raise some issues when Linux is booted because it assumes that clocks are turned off. Anyway, this is only a question: if this is ok for you (I do not test on this board), it is not an issue.

Quoted 5 lines

In imximage.cfg DCD, all clocks is opened, so I add that in the spl to enable all clocks. This piece code is just the same thing in the DCD clock part.
I have tested this patch set on mx6sxsabresd revb board and linux can boot ok.

Quoted 9 lines

Just FYI - when all the clocks are enabled, the imx6 can get uncomfortably hot. I'm not sure how it's with the imx6sx, but I tried in the past to enable all clocks on imx6d and it was not my best idea.

If this code will be running on the SabreSD development boards, your users can spend quite a bit of time hacking around in the U-Boot environment - editing env-vars, scripts, trying to guess boot args and what-not, but at the same time the CPU will be running at full steam.

Thanks for this information. I'll send another patch to fix the CCGR setting in SPL and DCD both.

Quoted 57 lines
Quoted 57 lines
Quoted 57 lines
Quoted 44 lines
board/freescale/mx6sxsabresd/mx6sxsabresd.c +41 -0
+static void spl_dram_init(void)
+{
+    struct mx6_ddr_sysinfo sysinfo = {
+        .dsize = mem_ddr.width/32,
+        .cs_density = 24,
+        .ncs = 1,
+        .cs1_mirror = 0,
+        .rtt_wr = 2,
+        .rtt_nom = 2,        /* RTT_Nom = RZQ/2 */
+        .walat = 1,        /* Write additional latency */
+        .ralat = 5,        /* Read additional latency */
+        .mif3_mode = 3,        /* Command prediction working mode */
+        .bi_on = 1,        /* Bank interleaving enabled */
+        .sde_to_rst = 0x10,    /* 14 cycles, 200us (JEDEC default) */
+        .rst_to_cke = 0x23,    /* 33 cycles, 500us (JEDEC default) */
+    };
+
+    mx6sx_dram_iocfg(mem_ddr.width, &mx6_ddr_ioregs, 
 &mx6_grp_ioregs);
+    mx6_dram_cfg(&sysinfo, &mx6_mmcd_calib, &mem_ddr);
+}
+
+void board_init_f(ulong dummy)
+{
+    /* setup AIPS and disable watchdog */
+    arch_cpu_init();
+
+    ccgr_init();
+
+    /* iomux and setup of i2c */
+    board_early_init_f();
+
+    /* setup GP timer */
+    timer_init();
+
+    /* UART clocks enabled and gd valid - init serial console */
+    preloader_console_init();
+
+    /* DDR initialization */
+    spl_dram_init();
+
+    /* Clear the BSS. */

board/freescale/mx6sxsabresd/mx6sxsabresd.c int checkboard(void) · line 564

Quoted 10 lines
board/freescale/mx6sxsabresd/mx6sxsabresd.c +10 -0
+    memset(__bss_start, 0, __bss_end - __bss_start);
+
+    /* load/boot image from boot device */
+    board_init_r(NULL, 0);
+}
+
+void reset_cpu(ulong addr)
+{
+}
+#endif

Best regards,
Stefano Babic

Quoted 5 lines
Quoted 2 lines

Regards,
Peng.

Kind regards,
Nikolay

Thanks,
Peng.