[U-Boot] [PATCH 0/8] *** iMX6 SabreSD SPL Support ***

This patch is for SPL support for iMX6 SabreSD. The said patches has been tested to work on SD2 and SD3 port of the said board.
After applying the following patches, it will produces SPL and u-boot.img binary images. You should run the two commands below to store it in your SD or eMMC.
sudo dd if=SPL of=/dev/xxx bs=1K seek=1; sync sudo dd if=u-boot.img of=/dev/xxx bs=1K seek=69
John Tobias (8): kconfig: add SUPPORT_SPL imx: add file in makefile imx6: add spl on board configuration imx6: add flexibility for defining stack address mmc: imx: add spl_board_mmc_init mx6: add SPL support in the header imx: add configuration file for SPL imx: SPL support for iMX6 SabreSD
arch/arm/Kconfig | 1 + board/freescale/mx6sabresd/Makefile | 2 +- board/freescale/mx6sabresd/mx6sabresd_spl.c | 277 ++++++++++++++++++++++++++ board/freescale/mx6sabresd/mx6sabresd_spl.cfg | 54 +++++ configs/mx6qsabresd_defconfig | 8 +- drivers/mmc/mmc.c | 5 +- include/configs/imx6_spl.h | 2 + include/configs/mx6sabresd.h | 7 + 8 files changed, 351 insertions(+), 5 deletions(-) create mode 100644 board/freescale/mx6sabresd/mx6sabresd_spl.c create mode 100644 board/freescale/mx6sabresd/mx6sabresd_spl.cfg

add SUPPORT_SPL for iMX6 SabreSD by default --- arch/arm/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index bd774d4..6eafc20 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -609,6 +609,7 @@ config TARGET_MX6QSABREAUTO config TARGET_MX6SABRESD bool "Support mx6sabresd" select CPU_V7 + select SUPPORT_SPL
config TARGET_MX6SLEVK bool "Support mx6slevk"

On Fri, Nov 7, 2014 at 8:12 PM, John Tobias john.tobias.ph@gmail.com wrote:
add SUPPORT_SPL for iMX6 SabreSD by default
This should be the last patch from the serie or it will break bisect.

mx6sabresd_spl is the support file to enable SPL in iMX6 SabreSD --- board/freescale/mx6sabresd/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/board/freescale/mx6sabresd/Makefile b/board/freescale/mx6sabresd/Makefile index cfca2ef..b8d0297 100644 --- a/board/freescale/mx6sabresd/Makefile +++ b/board/freescale/mx6sabresd/Makefile @@ -6,4 +6,4 @@ # SPDX-License-Identifier: GPL-2.0+ #
-obj-y := mx6sabresd.o +obj-y := mx6sabresd.o mx6sabresd_spl.o

add the spl on build configuration of iMX6 SabreSD --- configs/mx6qsabresd_defconfig | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/configs/mx6qsabresd_defconfig b/configs/mx6qsabresd_defconfig index 67c1b77..b7b26df 100644 --- a/configs/mx6qsabresd_defconfig +++ b/configs/mx6qsabresd_defconfig @@ -1,3 +1,5 @@ -CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6sabresd/mx6q_4x_mt41j128.cfg,MX6Q" -CONFIG_ARM=y -CONFIG_TARGET_MX6SABRESD=y +CONFIG_SPL=y +CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6sabresd/mx6sabresd_spl.cfg,SPL,MX6Q" ++S:CONFIG_ARM=y ++S:CONFIG_TARGET_MX6SABRESD=y +

iMX6 SabreSD has different stack address compare to the default stack address defined on the file. --- include/configs/imx6_spl.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/configs/imx6_spl.h b/include/configs/imx6_spl.h index 308e520..003dfe7 100644 --- a/include/configs/imx6_spl.h +++ b/include/configs/imx6_spl.h @@ -29,7 +29,9 @@ #define CONFIG_SPL_TEXT_BASE 0x00908000 #define CONFIG_SPL_MAX_SIZE (64 * 1024) #define CONFIG_SPL_START_S_PATH "arch/arm/cpu/armv7" +#ifndef CONFIG_SPL_STACK #define CONFIG_SPL_STACK 0x0091FFB8 +#endif #define CONFIG_SPL_LIBCOMMON_SUPPORT #define CONFIG_SPL_LIBGENERIC_SUPPORT #define CONFIG_SPL_SERIAL_SUPPORT

When CONFIG_SPL_MMC_SUPPORT is defined, by default the mmc_initialize function will call board_mmc_init. But, the said function is not link to the spl image. --- drivers/mmc/mmc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 44a4feb..8b68e3e 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -1441,10 +1441,13 @@ int mmc_initialize(bd_t *bis) INIT_LIST_HEAD (&mmc_devices); cur_dev_num = 0;
+#ifdef CONFIG_SPL_BUILD + if (spl_board_mmc_init(bis) < 0) + cpu_mmc_init(bis); +#else if (board_mmc_init(bis) < 0) cpu_mmc_init(bis);
-#ifndef CONFIG_SPL_BUILD print_mmc_devices(','); #endif

--- include/configs/mx6sabresd.h | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/include/configs/mx6sabresd.h b/include/configs/mx6sabresd.h index 938030d..4d2e54a 100644 --- a/include/configs/mx6sabresd.h +++ b/include/configs/mx6sabresd.h @@ -12,6 +12,13 @@ #include <asm/arch/imx-regs.h> #include <asm/imx-common/gpio.h>
+#ifdef CONFIG_SPL +#define CONFIG_SPL_LIBCOMMON_SUPPORT +#define CONFIG_SPL_MMC_SUPPORT +#define CONFIG_SPL_STACK 0x0093FFB8 +#include "imx6_spl.h" +#endif + #define CONFIG_MACH_TYPE 3980 #define CONFIG_MXC_UART_BASE UART1_BASE #define CONFIG_CONSOLE_DEV "ttymxc0"

This file is the default DCD configuration file for SPL --- board/freescale/mx6sabresd/mx6sabresd_spl.cfg | 54 +++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 board/freescale/mx6sabresd/mx6sabresd_spl.cfg
diff --git a/board/freescale/mx6sabresd/mx6sabresd_spl.cfg b/board/freescale/mx6sabresd/mx6sabresd_spl.cfg new file mode 100644 index 0000000..2e2f850 --- /dev/null +++ b/board/freescale/mx6sabresd/mx6sabresd_spl.cfg @@ -0,0 +1,54 @@ +/* + * Maintainer : Richard Hu linuxfae@technexion.com + * + * Derived from Nitrogen6x code by Boundary Devices + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Refer doc/README.imximage for more details about how-to configure + * and create imximage boot image + * + * The syntax is taken as close as possible with the kwbimage + */ + +/* image version */ +IMAGE_VERSION 2 + +/* + * Boot Device : one of + * spi, sd (the board has no nand neither onenand) + */ +BOOT_FROM sd + +#define __ASSEMBLY__ +#include <config.h> +#include "asm/arch/iomux.h" +#include "asm/arch/crm_regs.h" + +/* set the default clock gate to save power */ +DATA 4 0x020C4068 0x00C03F3F /* CCM_CCGR0 */ +DATA 4 0x020C406c 0x0030FC03 /* CCM_CCGR1 */ +DATA 4 0x020C4070 0x0FFFC000 /* CCM_CCGR2 */ +DATA 4 0x020C4074 0x3FF00000 /* CCM_CCGR3 */ +DATA 4 0x020C4078 0xFFF300 /* CCM_CCGR4 */ +DATA 4 0x020C407c 0x0F0000F3 /* CCM_CCGR5 - enable SATA clocks */ +DATA 4 0x020C4080 0x000003FF /* CCM_CCGR6 - enable ushdc and usb clocks */ + +/* enable AXI cache for VDOA/VPU/IPU */ +DATA 4 0x020e0010 0xF00000CF /* IOMUXC_GPR4 */ +/* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */ +DATA 4 0x020e0018 0x007F007F /* IOMUXC_GPR6 */ +DATA 4 0x020e001c 0x007F007F /* IOMUXC_GPR7 */ + +/* + * Setup CCM_CCOSR register as follows: + * + * cko1_en = 1 --> CKO1 enabled + * cko1_div = 111 --> divide by 8 + * cko1_sel = 1011 --> ahb_clk_root + * + * This sets CKO1 at ahb_clk_root/8 = 132/8 = 16.5 MHz + */ +DATA 4 0x020c4060 0x000000fb /* CCM_CCOSR */ + +

This file will enable the support for SPL on iMX6 Sabrex families. It tested on SD2 and SD3 mmc port. --- board/freescale/mx6sabresd/mx6sabresd_spl.c | 277 ++++++++++++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100644 board/freescale/mx6sabresd/mx6sabresd_spl.c
diff --git a/board/freescale/mx6sabresd/mx6sabresd_spl.c b/board/freescale/mx6sabresd/mx6sabresd_spl.c new file mode 100644 index 0000000..1d9ec6e --- /dev/null +++ b/board/freescale/mx6sabresd/mx6sabresd_spl.c @@ -0,0 +1,277 @@ +/* + * Author: John Tobias john.tobias.ph@gmail.com + * + * Derived from EDM_CF_IMX6 code by TechNexion,Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#if defined(CONFIG_SPL_BUILD) +#include <asm/arch/clock.h> +#include <asm/arch/mx6-pins.h> +#include <fsl_esdhc.h> +#include <asm/imx-common/iomux-v3.h> +#include <spl.h> +#include <libfdt.h> +#include <asm/io.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define BOOT_CFG 0x20D8004 + +#define __REG(x) (*((volatile u32 *)(x))) + +#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \ + PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \ + PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +struct fsl_esdhc_cfg spl_usdhc_cfg; + +iomux_v3_cfg_t const spl_usdhc2_pads[] = { + MX6_PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_NANDF_D4__SD2_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_NANDF_D5__SD2_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_NANDF_D6__SD2_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_NANDF_D7__SD2_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_NANDF_D2__GPIO2_IO02 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */ +}; + +iomux_v3_cfg_t const spl_usdhc3_pads[] = { + MX6_PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DAT4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_NANDF_D0__GPIO2_IO00 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */ +}; + +iomux_v3_cfg_t const spl_usdhc4_pads[] = { + MX6_PAD_SD4_CLK__SD4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_CMD__SD4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT0__SD4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT4__SD4_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT5__SD4_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT6__SD4_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DAT7__SD4_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL), +}; + +/* + * Got it from mx6q_4x_mt41j128.cfg file + */ +void set_mt41j128_ddr(void) +{ + __REG(0x020e05a8) = 0x00000028; + __REG(0x020e05b0) = 0x00000028; + __REG(0x020e0524) = 0x00000028; + __REG(0x020e051c) = 0x00000028; + + __REG(0x020e0518) = 0x00000028; + __REG(0x020e050c) = 0x00000028; + __REG(0x020e05b8) = 0x00000028; + __REG(0x020e05c0) = 0x00000028; + + __REG(0x020e05ac) = 0x00000028; + __REG(0x020e05b4) = 0x00000028; + __REG(0x020e0528) = 0x00000028; + __REG(0x020e0520) = 0x00000028; + + __REG(0x020e0514) = 0x00000028; + __REG(0x020e0510) = 0x00000028; + __REG(0x020e05bc) = 0x00000028; + __REG(0x020e05c4) = 0x00000028; + + __REG(0x020e056c) = 0x00000030; + __REG(0x020e0578) = 0x00000030; + __REG(0x020e0588) = 0x00000030; + __REG(0x020e0594) = 0x00000030; + + __REG(0x020e057c) = 0x00000030; + __REG(0x020e0590) = 0x00000030; + __REG(0x020e0598) = 0x00000030; + __REG(0x020e058c) = 0x00000000; + + __REG(0x020e059c) = 0x00003030; + __REG(0x020e05a0) = 0x00003030; + __REG(0x020e0784) = 0x00000028; + __REG(0x020e0788) = 0x00000028; + + __REG(0x020e0794) = 0x00000028; + __REG(0x020e079c) = 0x00000028; + __REG(0x020e07a0) = 0x00000028; + __REG(0x020e07a4) = 0x00000028; + + __REG(0x020e07a8) = 0x00000028; + __REG(0x020e0748) = 0x00000028; + __REG(0x020e074c) = 0x00000030; + __REG(0x020e0750) = 0x00020000; + + __REG(0x020e0758) = 0x00000000; + __REG(0x020e0774) = 0x00020000; + __REG(0x020e078c) = 0x00000030; + __REG(0x020e0798) = 0x000C0000; + + __REG(0x021b081c) = 0x33333333; + __REG(0x021b0820) = 0x33333333; + __REG(0x021b0824) = 0x33333333; + __REG(0x021b0828) = 0x33333333; + + __REG(0x021b481c) = 0x33333333; + __REG(0x021b4820) = 0x33333333; + __REG(0x021b4824) = 0x33333333; + __REG(0x021b4828) = 0x33333333; + + __REG(0x021b0018) = 0x00001740; + + __REG(0x021b001c) = 0x00008000; + __REG(0x021b000c) = 0x8A8F7975; + __REG(0x021b0010) = 0xFF538E64; + __REG(0x021b0014) = 0x01FF00DB; + __REG(0x021b002c) = 0x000026D2; + + __REG(0x021b0030) = 0x008F0E21; + __REG(0x021b0008) = 0x09444040; + __REG(0x021b0004) = 0x00020036; + __REG(0x021b0040) = 0x00000047; + __REG(0x021b0000) = 0x841A0000; + + __REG(0x021b001c) = 0x04088032; + __REG(0x021b001c) = 0x00008033; + __REG(0x021b001c) = 0x00428031; + __REG(0x021b001c) = 0x09408030; + + __REG(0x021b001c) = 0x04008040; + __REG(0x021b0800) = 0xA1380003; + __REG(0x021b0020) = 0x00005800; + __REG(0x021b0818) = 0x00000007; + __REG(0x021b4818) = 0x00000007; + + /* Calibration values based on ARD and 528MHz */ + __REG(0x021b083c) = 0x434B0358; + __REG(0x021b0840) = 0x033D033C; + __REG(0x021b483c) = 0x03520362; + __REG(0x021b4840) = 0x03480318; + __REG(0x021b0848) = 0x41383A3C; + __REG(0x021b4848) = 0x3F3C374A; + __REG(0x021b0850) = 0x42434444; + __REG(0x021b4850) = 0x4932473A; + + __REG(0x021b080c) = 0x001F001F; + __REG(0x021b0810) = 0x001F001F; + + __REG(0x021b480c) = 0x001F001F; + __REG(0x021b4810) = 0x001F001F; + + __REG(0x021b08b8) = 0x00000800; + __REG(0x021b48b8) = 0x00000800; + + __REG(0x021b0404) = 0x00011006; + __REG(0x021b0004) = 0x00025576; + + __REG(0x021b001c) = 0x00000000; + + __REG(0x020c4068) = 0x00C03F3F; + __REG(0x020c406c) = 0x0030FC00; + __REG(0x020c4070) = 0x0FFFC000; + __REG(0x020c4074) = 0x3FF00000; + __REG(0x020c4078) = 0x00FFF300; + __REG(0x020c407c) = 0x0F0000C3; + __REG(0x020c4080) = 0x000003FF; +} + +/* + * This section require the differentiation + * between iMX6 Sabre Families. + * But for now, it will configure only for + * SabreSD. + */ +static u32 spl_dram_init(void) +{ + u32 ddr_size; + + set_mt41j128_ddr(); + ddr_size = 0x40000000; + + return ddr_size; +} + +int spl_board_mmc_init(bd_t *bis) +{ + unsigned reg = readl(BOOT_CFG); + /* + * Upon reading BOOT_CFG register the following map is done: + * (U-boot device node) (Physical Port) + * 0x840 SD2 + * 0x1040 SD3 + * 0x1840 eMMC + */ + switch (reg) { + case 0x840: + imx_iomux_v3_setup_multiple_pads( + spl_usdhc2_pads, ARRAY_SIZE(spl_usdhc2_pads)); + spl_usdhc_cfg.esdhc_base = USDHC2_BASE_ADDR; + spl_usdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); + gd->arch.sdhc_clk = spl_usdhc_cfg.sdhc_clk; + break; + case 0x1040: + imx_iomux_v3_setup_multiple_pads( + spl_usdhc3_pads, ARRAY_SIZE(spl_usdhc3_pads)); + spl_usdhc_cfg.esdhc_base = USDHC3_BASE_ADDR; + spl_usdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); + gd->arch.sdhc_clk = spl_usdhc_cfg.sdhc_clk; + break; + case 0x1840: + imx_iomux_v3_setup_multiple_pads( + spl_usdhc4_pads, ARRAY_SIZE(spl_usdhc4_pads)); + spl_usdhc_cfg.esdhc_base = USDHC4_BASE_ADDR; + spl_usdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK); + gd->arch.sdhc_clk = spl_usdhc_cfg.sdhc_clk; + break; + } + + return fsl_esdhc_initialize(bis, &spl_usdhc_cfg); +} + +void board_init_f(ulong dummy) +{ + u32 ram_size; + + /* Set the stack pointer. */ + asm volatile("mov sp, %0\n" : : "r"(CONFIG_SPL_STACK)); + + ram_size = spl_dram_init(); + + arch_cpu_init(); + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end - __bss_start); + + /* Set global data pointer. */ + gd = &gdata; + gd->ram_size = ram_size; + + board_early_init_f(); + + timer_init(); + + preloader_console_init(); + + board_init_r(NULL, 0); +} + +void reset_cpu(ulong addr) +{ +} +#endif +

On Fri, Nov 7, 2014 at 8:12 PM, John Tobias john.tobias.ph@gmail.com wrote:
This file will enable the support for SPL on iMX6 Sabrex families. It tested on SD2 and SD3 mmc port.
This needs to be included before we actually use it. So before the makefile inclusion. In fact I see no reason to split it so much.

Thanks for the info.
I got a 2nd revision and will send it later.
Regards,
john
On Sat, Nov 8, 2014 at 5:13 AM, Otavio Salvador otavio@ossystems.com.br wrote:
On Fri, Nov 7, 2014 at 8:12 PM, John Tobias john.tobias.ph@gmail.com wrote:
This file will enable the support for SPL on iMX6 Sabrex families. It tested on SD2 and SD3 mmc port.
This needs to be included before we actually use it. So before the makefile inclusion. In fact I see no reason to split it so much.
-- 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
participants (2)
-
John Tobias
-
Otavio Salvador