[U-Boot] [PATCH v7 5/5] imx6: SPL support for iMX6 SabreSD
Stefano Babic
sbabic at denx.de
Thu Nov 13 09:22:43 CET 2014
Hi John,
On 12/11/2014 23:27, John Tobias wrote:
> This patch will enable the support for SPL on iMX6 SabreSD.
> It tested on SD2 and SD3 mmc port (Switch 1 or 2 of SW6)
>
> Signed-off-by: John Tobias <john.tobias.ph at gmail.com>
> ---
> board/freescale/mx6sabresd/mx6sabresd.c | 186 +++++++++++++++++++++++++++++++-
> 1 file changed, 184 insertions(+), 2 deletions(-)
>
> diff --git a/board/freescale/mx6sabresd/mx6sabresd.c b/board/freescale/mx6sabresd/mx6sabresd.c
> index 3d81fff..eda8497 100644
> --- a/board/freescale/mx6sabresd/mx6sabresd.c
> +++ b/board/freescale/mx6sabresd/mx6sabresd.c
> @@ -27,8 +27,12 @@
> #include <i2c.h>
> #include <power/pmic.h>
> #include <power/pfuze100_pmic.h>
> +#include <asm/arch/mx6-ddr.h>
> +
> DECLARE_GLOBAL_DATA_PTR;
>
> +#define BOOT_CFG 0x020D8004
> +
> #define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
> PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \
> PAD_CTL_SRE_FAST | PAD_CTL_HYS)
> @@ -55,8 +59,7 @@ DECLARE_GLOBAL_DATA_PTR;
>
> int dram_init(void)
> {
> - gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE);
> -
> + gd->ram_size = imx_ddr_size();
> return 0;
> }
>
> @@ -253,6 +256,7 @@ int board_mmc_getcd(struct mmc *mmc)
>
> int board_mmc_init(bd_t *bis)
> {
> +#ifndef CONFIG_SPL_BUILD
> s32 status = 0;
> int i;
>
> @@ -293,6 +297,43 @@ int board_mmc_init(bd_t *bis)
> }
>
> return status;
> +#else
> + unsigned reg = readl(BOOT_CFG) >> 11;
> + /*
> + * Upon reading BOOT_CFG register the following map is done:
> + * Bit 11 and 12 of BOOT_CFG register can determine the current
> + * mmc port
> + * 0x1 SD1
> + * 0x2 SD2
> + * 0x3 SD4
> + */
> +
> + switch (reg & 0x3) {
> + case 0x1:
> + imx_iomux_v3_setup_multiple_pads(
> + usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
> + usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR;
> + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
> + gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
> + break;
> + case 0x2:
> + imx_iomux_v3_setup_multiple_pads(
> + usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
> + usdhc_cfg[0].esdhc_base = USDHC3_BASE_ADDR;
> + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
> + gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
> + break;
> + case 0x3:
> + imx_iomux_v3_setup_multiple_pads(
> + usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
> + usdhc_cfg[0].esdhc_base = USDHC4_BASE_ADDR;
> + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
> + gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
> + break;
> + }
> +
> + return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
> +#endif
> }
> #endif
>
> @@ -607,3 +648,144 @@ int checkboard(void)
> puts("Board: MX6-SabreSD\n");
> return 0;
> }
> +
> +#ifdef CONFIG_SPL_BUILD
> +#include <spl.h>
> +#include <libfdt.h>
> +
> +const struct mx6dq_iomux_ddr_regs mx6_ddr_ioregs = {
> + .dram_sdclk_0 = 0x00020030,
> + .dram_sdclk_1 = 0x00020030,
> + .dram_cas = 0x00020030,
> + .dram_ras = 0x00020030,
> + .dram_reset = 0x00020030,
> + .dram_sdcke0 = 0x00003000,
> + .dram_sdcke1 = 0x00003000,
> + .dram_sdba2 = 0x00000000,
> + .dram_sdodt0 = 0x00003030,
> + .dram_sdodt1 = 0x00003030,
> + .dram_sdqs0 = 0x00000030,
> + .dram_sdqs1 = 0x00000030,
> + .dram_sdqs2 = 0x00000030,
> + .dram_sdqs3 = 0x00000030,
> + .dram_sdqs4 = 0x00000030,
> + .dram_sdqs5 = 0x00000030,
> + .dram_sdqs6 = 0x00000030,
> + .dram_sdqs7 = 0x00000030,
> + .dram_dqm0 = 0x00020030,
> + .dram_dqm1 = 0x00020030,
> + .dram_dqm2 = 0x00020030,
> + .dram_dqm3 = 0x00020030,
> + .dram_dqm4 = 0x00020030,
> + .dram_dqm5 = 0x00020030,
> + .dram_dqm6 = 0x00020030,
> + .dram_dqm7 = 0x00020030,
> +};
> +
> +const struct mx6dq_iomux_grp_regs mx6_grp_ioregs = {
> + .grp_ddr_type = 0x000C0000,
> + .grp_ddrmode_ctl = 0x00020000,
> + .grp_ddrpke = 0x00000000,
> + .grp_addds = 0x00000030,
> + .grp_ctlds = 0x00000030,
> + .grp_ddrmode = 0x00020000,
> + .grp_b0ds = 0x00000030,
> + .grp_b1ds = 0x00000030,
> + .grp_b2ds = 0x00000030,
> + .grp_b3ds = 0x00000030,
> + .grp_b4ds = 0x00000030,
> + .grp_b5ds = 0x00000030,
> + .grp_b6ds = 0x00000030,
> + .grp_b7ds = 0x00000030,
> +};
> +
> +const struct mx6_mmdc_calibration mx6_mmcd_calib = {
> + .p0_mpwldectrl0 = 0x001F001F,
> + .p0_mpwldectrl1 = 0x001F001F,
> + .p1_mpwldectrl0 = 0x00440044,
> + .p1_mpwldectrl1 = 0x00440044,
> + .p0_mpdgctrl0 = 0x434B0350,
> + .p0_mpdgctrl1 = 0x034C0359,
> + .p1_mpdgctrl0 = 0x434B0350,
> + .p1_mpdgctrl1 = 0x03650348,
> + .p0_mprddlctl = 0x4436383B,
> + .p1_mprddlctl = 0x39393341,
> + .p0_mpwrdlctl = 0x35373933,
> + .p1_mpwrdlctl = 0x48254A36,
> +};
> +
> +static struct mx6_ddr3_cfg mem_ddr = {
> + .mem_speed = 1600,
> + .density = 4,
> + .width = 64,
> + .banks = 8,
> + .rowaddr = 14,
> + .coladdr = 10,
> + .pagesz = 2,
> + .trcd = 1375,
> + .trcmin = 4875,
> + .trasmin = 3500,
> +};
> +
> +/*
> + * This section require the differentiation
> + * between iMX6 Sabre Families.
> + * But for now, it will configure only for
> + * SabreSD.
> + */
> +static void spl_dram_init(void)
> +{
> + struct mx6_ddr_sysinfo sysinfo = {
> + /* width of data bus:0=16,1=32,2=64 */
> + .dsize = mem_ddr.width/32,
> + /* config for full 4GB range so that get_mem_size() works */
> + .cs_density = 32, /* 32Gb per CS */
> + /* single chip select */
> + .ncs = 1,
> + .cs1_mirror = 0,
> + .rtt_wr = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Wr = RZQ/4 */
> +#ifdef RTT_NOM_120OHM
> + .rtt_nom = 2 /*DDR3_RTT_120_OHM*/, /* RTT_Nom = RZQ/2 */
> +#else
> + .rtt_nom = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Nom = RZQ/4 */
> +#endif
> + .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) */
> + };
> +
> + mx6dq_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();
> +
> + /* 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);
> +}
> +
> +void reset_cpu(ulong addr)
> +{
> +}
> +#endif
>
Acked-by: Stefano Babic <sbabic at denx.de>
Thanks for all your work !
Best regards,
Stefano Babic
--
=====================================================================
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
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
=====================================================================
More information about the U-Boot
mailing list