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...@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 + -- 1.9.1 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot