diff mbox

[U-Boot,12/18] arm: mx6: add support for Compulab cm-fx6 CoM

Message ID 1407051288-17324-13-git-send-email-nikita@compulab.co.il
State Changes Requested
Delegated to: Stefano Babic
Headers show

Commit Message

Nikita Kiryanov Aug. 3, 2014, 7:34 a.m. UTC
Add initial support for Compulab CM-FX6 CoM.
Support includes MMC, SPI flash, and SPL with dynamic DRAM detection.

Cc: Igor Grinberg <grinberg@compulab.co.il>
Cc: Stefano Babic <sbabic@denx.de>
Cc: Tom Rini <trini@ti.com>
Signed-off-by: Nikita Kiryanov <nikita@compulab.co.il>
---
 arch/arm/cpu/armv7/mx6/ddr.c       |   1 -
 board/compulab/cm_fx6/Makefile     |  12 ++
 board/compulab/cm_fx6/cm_fx6.c     | 108 ++++++++++
 board/compulab/cm_fx6/common.c     |  83 ++++++++
 board/compulab/cm_fx6/common.h     |  36 ++++
 board/compulab/cm_fx6/imximage.cfg |   8 +
 board/compulab/cm_fx6/spl.c        | 400 +++++++++++++++++++++++++++++++++++++
 boards.cfg                         |   2 +
 include/configs/cm_fx6.h           | 227 +++++++++++++++++++++
 9 files changed, 876 insertions(+), 1 deletion(-)
 create mode 100644 board/compulab/cm_fx6/Makefile
 create mode 100644 board/compulab/cm_fx6/cm_fx6.c
 create mode 100644 board/compulab/cm_fx6/common.c
 create mode 100644 board/compulab/cm_fx6/common.h
 create mode 100644 board/compulab/cm_fx6/imximage.cfg
 create mode 100644 board/compulab/cm_fx6/spl.c
 create mode 100644 include/configs/cm_fx6.h

Comments

Marek Vasut Aug. 3, 2014, 2:09 p.m. UTC | #1
On Sunday, August 03, 2014 at 09:34:42 AM, Nikita Kiryanov wrote:
> Add initial support for Compulab CM-FX6 CoM.
> Support includes MMC, SPI flash, and SPL with dynamic DRAM detection.
> 
> Cc: Igor Grinberg <grinberg@compulab.co.il>
> Cc: Stefano Babic <sbabic@denx.de>
> Cc: Tom Rini <trini@ti.com>
> Signed-off-by: Nikita Kiryanov <nikita@compulab.co.il>
> ---
>  arch/arm/cpu/armv7/mx6/ddr.c       |   1 -
>  board/compulab/cm_fx6/Makefile     |  12 ++
>  board/compulab/cm_fx6/cm_fx6.c     | 108 ++++++++++
>  board/compulab/cm_fx6/common.c     |  83 ++++++++
>  board/compulab/cm_fx6/common.h     |  36 ++++
>  board/compulab/cm_fx6/imximage.cfg |   8 +
>  board/compulab/cm_fx6/spl.c        | 400
> +++++++++++++++++++++++++++++++++++++ boards.cfg                         |
>   2 +
>  include/configs/cm_fx6.h           | 227 +++++++++++++++++++++
>  9 files changed, 876 insertions(+), 1 deletion(-)
>  create mode 100644 board/compulab/cm_fx6/Makefile
>  create mode 100644 board/compulab/cm_fx6/cm_fx6.c
>  create mode 100644 board/compulab/cm_fx6/common.c
>  create mode 100644 board/compulab/cm_fx6/common.h
>  create mode 100644 board/compulab/cm_fx6/imximage.cfg
>  create mode 100644 board/compulab/cm_fx6/spl.c
>  create mode 100644 include/configs/cm_fx6.h
> 
> diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c
> index d3891dc..219263a 100644
> --- a/arch/arm/cpu/armv7/mx6/ddr.c
> +++ b/arch/arm/cpu/armv7/mx6/ddr.c
> @@ -4,7 +4,6 @@
>   *
>   * SPDX-License-Identifier:     GPL-2.0+
>   */
> -
>  #include <common.h>
>  #include <linux/types.h>
>  #include <asm/arch/mx6-ddr.h>

Drop this piece ;-)

[...]
> +++ b/board/compulab/cm_fx6/cm_fx6.c

[...]

> +static ulong bank1_size;
> +static ulong bank2_size;
> +
> +#define MMDC1_MDCTL 0x21B0000
> +static int probe_mmdc_config(void)
> +{
> +	u32 val = readl(0x21B0000);
> +	switch (val) {
> +	case 0x83180000: /* DDR_16BIT_256MB */
> +		gd->ram_size	= 0x10000000;
> +		bank1_size	= 0x10000000;
> +		bank2_size	= 0;
> +		break;
> +	case 0x83190000: /* DDR_32BIT_512MB */
> +		gd->ram_size	= 0x20000000;
> +		bank1_size	= 0x20000000;
> +		bank2_size	= 0;
> +		break;

imx_ddr_size() won't cut it here ?

[...]
Tim Harvey Aug. 4, 2014, 4:45 a.m. UTC | #2
On Sun, Aug 3, 2014 at 12:34 AM, Nikita Kiryanov <nikita@compulab.co.il> wrote:
> Add initial support for Compulab CM-FX6 CoM.
> Support includes MMC, SPI flash, and SPL with dynamic DRAM detection.
>
<snip>
> +
> +static void spl_mx6s_dram_init(enum ddr_config dram_config, int reset)
> +{
> +       struct mx6_mmdc_calibration calib;
> +       struct mx6_ddr_sysinfo sysinfo;
> +       struct mx6_ddr3_cfg ddr3_cfg;
> +
> +       if (reset)
> +               ((struct mmdc_p_regs *)MX6_MMDC_P0_MDCTL)->mdmisc = 2;
> +
> +       calib.p0_mpwldectrl0    = 0x005B0061;
> +       calib.p0_mpwldectrl1    = 0x004F0055;
> +       calib.p0_mpdgctrl0      = 0x0314030C;
> +       calib.p0_mpdgctrl1      = 0x025C0268;
> +       calib.p0_mprddlctl      = 0x42464646;
> +       calib.p0_mpwrdlctl      = 0x36322C34;
> +       ddr3_cfg.mem_speed      = 800;
> +       ddr3_cfg.density        = 4;
> +       ddr3_cfg.rowaddr        = 14;
> +       ddr3_cfg.coladdr        = 10;
> +       ddr3_cfg.pagesz         = 2;
> +       ddr3_cfg.trcd           = 1800;
> +       ddr3_cfg.trcmin         = 5200;
> +       ddr3_cfg.trasmin        = 3600;
> +       ddr3_cfg.SRT            = 0;
> +       sysinfo.cs1_mirror      = 1;
> +       sysinfo.cs_density      = 16;
> +       sysinfo.bi_on           = 1;
> +       sysinfo.rtt_nom         = 1;
> +       sysinfo.rtt_wr          = 0;
> +       sysinfo.ralat           = 5;
> +       sysinfo.walat           = 1;
> +       sysinfo.mif3_mode       = 3;
> +       sysinfo.rst_to_cke      = 0x23;
> +       sysinfo.sde_to_rst      = 0x10;
> +       switch (dram_config) {
> +       case DDR_16BIT_256MB:
> +               sysinfo.dsize = 0;
> +               sysinfo.ncs = 1;
> +               break;
> +       case DDR_32BIT_512MB:
> +               sysinfo.dsize = 1;
> +               sysinfo.ncs = 1;
> +               break;
> +       case DDR_32BIT_1GB:
> +               sysinfo.dsize = 1;
> +               sysinfo.ncs = 2;
> +               break;
> +       default:
> +               puts("Tried to setup invalid DDR configuration\n");
> +               hang();
> +       }
> +
> +       mx6_dram_cfg(&sysinfo, &calib, &ddr3_cfg);
> +       udelay(100);
> +}

Nikita,

I'm curious why you add an extra udelay(100) here? There is an
mdelay(1) before the return of mx6_dram_cfg() to wait for auto-ZQ
calibration to complete (I never found a way to determine when it was
complete via registers).

Regards,

Tim
Tim Harvey Aug. 4, 2014, 6:02 a.m. UTC | #3
On Sun, Aug 3, 2014 at 12:34 AM, Nikita Kiryanov <nikita@compulab.co.il> wrote:
> Add initial support for Compulab CM-FX6 CoM.
> Support includes MMC, SPI flash, and SPL with dynamic DRAM detection.
>
<snip>
> diff --git a/include/configs/cm_fx6.h b/include/configs/cm_fx6.h
> new file mode 100644
> index 0000000..285af33
> --- /dev/null
> +++ b/include/configs/cm_fx6.h
> @@ -0,0 +1,227 @@
> +/*
> + * Config file for Compulab CM-FX6 board
> + *
> + * Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/
> + *
> + * Author: Nikita Kiryanov <nikita@compulab.co.il>
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#ifndef __CONFIG_CM_FX6_H
> +#define __CONFIG_CM_FX6_H
> +
> +#include <asm/arch/imx-regs.h>
> +#include <config_distro_defaults.h>
> +
> +#define CONFIG_SYS_L2CACHE_OFF
> +#include "mx6_common.h"
> +
> +/* Machine config */
> +#define CONFIG_MX6
> +#define CONFIG_MX6QDL
> +#define CONFIG_CM_FX6
> +#define CONFIG_SYS_LITTLE_ENDIAN
> +#define CONFIG_MACH_TYPE               4273
> +#define CONFIG_SYS_HZ                  1000
> +
> +/* Display information on boot */
> +#define CONFIG_DISPLAY_CPUINFO
> +#define CONFIG_DISPLAY_BOARDINFO
> +#define CONFIG_TIMESTAMP
> +
> +/* CMD */
> +#include <config_cmd_default.h>
> +#define CONFIG_CMD_GREPENV
> +#undef CONFIG_CMD_FLASH
> +#undef CONFIG_CMD_LOADB
> +#undef CONFIG_CMD_LOADS
> +#undef CONFIG_CMD_XIMG
> +#undef CONFIG_CMD_FPGA
> +#undef CONFIG_CMD_IMLS
> +#undef CONFIG_CMD_NET
> +#undef CONFIG_CMD_NFS
> +
> +/* MMC */
> +#define CONFIG_MMC
> +#define CONFIG_CMD_MMC
> +#define CONFIG_GENERIC_MMC
> +#define CONFIG_FSL_ESDHC
> +#define CONFIG_FSL_USDHC
> +#define CONFIG_SYS_FSL_USDHC_NUM       3
> +#define CONFIG_SYS_FSL_ESDHC_ADDR      USDHC2_BASE_ADDR
> +
> +/* RAM */
> +#define PHYS_SDRAM_1                   MMDC0_ARB_BASE_ADDR
> +#define PHYS_SDRAM_2                   MMDC1_ARB_BASE_ADDR
> +#define CONFIG_SYS_SDRAM_BASE          PHYS_SDRAM_1
> +#define CONFIG_NR_DRAM_BANKS           2
> +#define CONFIG_SYS_MEMTEST_START       0x10000000
> +#define CONFIG_SYS_MEMTEST_END         0x10010000
> +#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)
> +
> +/* Serial console */
> +#define CONFIG_MXC_UART
> +#define CONFIG_MXC_UART_BASE           UART4_BASE
> +#define CONFIG_BAUDRATE                        115200
> +#define CONFIG_SYS_BAUDRATE_TABLE      {9600, 19200, 38400, 57600, 115200}
> +
> +/* Shell */
> +#define CONFIG_SYS_PROMPT      "CM-FX6 # "
> +#define CONFIG_SYS_CBSIZE      1024
> +#define CONFIG_SYS_MAXARGS     16
> +#define CONFIG_SYS_BARGSIZE    CONFIG_SYS_CBSIZE
> +#define CONFIG_SYS_PBSIZE      (CONFIG_SYS_CBSIZE + \
> +                                       sizeof(CONFIG_SYS_PROMPT) + 16)
> +#define CONFIG_SYS_MONITOR_LEN (CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS / 2 * 1024)
> +
> +/* SPI flash */
> +#define CONFIG_SYS_NO_FLASH
> +#define CONFIG_CMD_SF
> +#define CONFIG_SF_DEFAULT_BUS          0
> +#define CONFIG_SF_DEFAULT_CS           0
> +#define CONFIG_SF_DEFAULT_SPEED                25000000
> +#define CONFIG_SF_DEFAULT_MODE         (SPI_MODE_0)
> +
> +/* Environment */
> +#define CONFIG_ENV_OVERWRITE
> +#define CONFIG_ENV_IS_IN_SPI_FLASH
> +#define CONFIG_ENV_SPI_MAX_HZ          CONFIG_SF_DEFAULT_SPEED
> +#define CONFIG_ENV_SPI_MODE            CONFIG_SF_DEFAULT_MODE
> +#define CONFIG_ENV_SPI_BUS             CONFIG_SF_DEFAULT_BUS
> +#define CONFIG_ENV_SPI_CS              CONFIG_SF_DEFAULT_CS
> +#define CONFIG_ENV_SECT_SIZE           (64 * 1024)
> +#define CONFIG_ENV_SIZE                        (8 * 1024)
> +#define CONFIG_ENV_OFFSET              (768 * 1024)
> +
> +#define CONFIG_EXTRA_ENV_SETTINGS \
> +       "kernel=uImage-cm-fx6\0" \
> +       "autoload=no\0" \
> +       "loadaddr=0x10800000\0" \
> +       "fdtaddr=0x11000000\0" \
> +       "console=ttymxc3,115200\0" \
> +       "ethprime=FEC0\0" \
> +       "bootscr=boot.scr\0" \
> +       "bootm_low=18000000\0" \
> +       "video_hdmi=mxcfb0:dev=hdmi,1920x1080M-32@50,if=RGB32\0" \
> +       "video_dvi=mxcfb0:dev=dvi,1280x800M-32@50,if=RGB32\0" \
> +       "fdtfile=cm-fx6.dtb\0" \
> +       "doboot=bootm ${loadaddr}\0" \
> +       "loadfdt=false\0" \
> +       "setboottypez=setenv kernel zImage-cm-fx6;" \
> +               "setenv doboot bootz ${loadaddr} - ${fdtaddr};" \
> +               "setenv loadfdt true;\0" \
> +       "setboottypem=setenv kernel uImage-cm-fx6;" \
> +               "setenv doboot bootm ${loadaddr};" \
> +               "setenv loadfdt false;\0"\
> +       "run_eboot=echo Starting EBOOT ...; "\
> +               "mmc dev ${mmcdev} && " \
> +               "mmc rescan && mmc read 10042000 a 400 && go 10042000\0" \
> +       "mmcdev=2\0" \
> +       "mmcroot=/dev/mmcblk0p2 rw rootwait\0" \
> +       "loadmmcbootscript=fatload mmc ${mmcdev} ${loadaddr} ${bootscr}\0" \
> +       "mmcbootscript=echo Running bootscript from mmc ...; "\
> +               "source ${loadaddr}\0" \
> +       "mmcargs=setenv bootargs console=${console} " \
> +               "root=${mmcroot} " \
> +               "${video}\0" \
> +       "mmcloadkernel=fatload mmc ${mmcdev} ${loadaddr} ${kernel}\0" \
> +       "mmcloadfdt=fatload mmc ${mmcdev} ${fdtaddr} ${fdtfile}\0" \
> +       "mmcboot=echo Booting from mmc ...; " \
> +               "run mmcargs; " \
> +               "run doboot\0" \
> +       "nandroot=/dev/mtdblock4 rw\0" \
> +       "nandrootfstype=ubifs\0" \
> +       "nandargs=setenv bootargs console=${console} " \
> +               "root=${nandroot} " \
> +               "rootfstype=${nandrootfstype} " \
> +               "${video}\0" \
> +       "nandloadfdt=nand read ${fdtaddr} 780000 80000;\0" \
> +       "nandboot=echo Booting from nand ...; " \
> +               "run nandargs; " \
> +               "nand read ${loadaddr} 0 780000; " \
> +               "if ${loadfdt}; then " \
> +                       "run nandloadfdt;" \
> +               "fi; " \
> +               "run doboot\0" \
> +       "boot=mmc dev ${mmcdev}; " \
> +               "if mmc rescan; then " \
> +                       "if run loadmmcbootscript; then " \
> +                               "run mmcbootscript;" \
> +                       "else " \
> +                               "if run mmcloadkernel; then " \
> +                                       "if ${loadfdt}; then " \
> +                                               "run mmcloadfdt;" \
> +                                       "fi;" \
> +                                       "run mmcboot;" \
> +                               "fi;" \
> +                       "fi;" \
> +               "fi;"
> +
> +#define CONFIG_BOOTCOMMAND \
> +       "run setboottypem; run boot"
> +
> +/* SPI */
> +#define CONFIG_SPI
> +#define CONFIG_MXC_SPI
> +#define CONFIG_SPI_FLASH
> +#define CONFIG_SPI_FLASH_ATMEL
> +#define CONFIG_SPI_FLASH_EON
> +#define CONFIG_SPI_FLASH_GIGADEVICE
> +#define CONFIG_SPI_FLASH_MACRONIX
> +#define CONFIG_SPI_FLASH_SPANSION
> +#define CONFIG_SPI_FLASH_STMICRO
> +#define CONFIG_SPI_FLASH_SST
> +#define CONFIG_SPI_FLASH_WINBOND
> +
> +/* GPIO */
> +#define CONFIG_MXC_GPIO
> +
> +/* Boot */
> +#define CONFIG_ZERO_BOOTDELAY_CHECK
> +#define CONFIG_LOADADDR                        0x10800000
> +#define CONFIG_SYS_LOAD_ADDR           CONFIG_LOADADDR
> +#define CONFIG_SYS_TEXT_BASE           0x10800000
> +#define CONFIG_CMDLINE_TAG             /* enable passing of ATAGs */
> +#define CONFIG_SYS_BOOTMAPSZ           (8 << 20)
> +#define CONFIG_SETUP_MEMORY_TAGS
> +#define CONFIG_INITRD_TAG
> +
> +/* misc */
> +#define CONFIG_SYS_GENERIC_BOARD
> +#define CONFIG_STACKSIZE                       (128 * 1024)
> +#define CONFIG_SYS_MALLOC_LEN                  (2 * 1024 * 1024)
> +#define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS     800 /* 400 KB */
> +
> +/* SPL */
> +#define CONFIG_SPL
> +#define CONFIG_SPL_FRAMEWORK
> +#define CONFIG_SPL_BOARD_INIT
> +#define CONFIG_SPL_STACK               0x0091FFB8
> +#define CONFIG_SPL_TEXT_BASE           0x00908000
> +#define CONFIG_SPL_BSS_START_ADDR      0x18200000
> +#define CONFIG_SPL_BSS_MAX_SIZE                0x00100000
> +#define CONFIG_SYS_SPL_MALLOC_START    0x18300000
> +#define CONFIG_SYS_SPL_MALLOC_SIZE     0x03200000
> +#define CONFIG_SPL_MAX_SIZE            (62 * 1024)
> +#define CONFIG_SPL_LIBDISK_SUPPORT
> +#define CONFIG_SPL_LIBGENERIC_SUPPORT
> +#define CONFIG_SPL_LIBCOMMON_SUPPORT
> +#define CONFIG_SPL_GPIO_SUPPORT
> +#define CONFIG_SPL_SERIAL_SUPPORT
> +#define CONFIG_SPL_MMC_SUPPORT
> +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR        0x80 /* offset 64 kb */
> +#define CONFIG_SPL_SPI_SUPPORT
> +#define CONFIG_SPL_SPI_FLASH_SUPPORT
> +#define CONFIG_SPL_SPI_BUS             CONFIG_SF_DEFAULT_BUS
> +#define CONFIG_SPL_SPI_CS              CONFIG_SF_DEFAULT_CS
> +#define CONFIG_SPL_SPI_MODE            CONFIG_SF_DEFAULT_MODE
> +#define CONFIG_SYS_SPI_U_BOOT_OFFS     (64 * 1024)
> +#define CONFIG_SPL_SPI_LOAD

Nikita,

Are the values in include/configs/imx6_spl.h too inflexible to use? If
so, I can submit a patch in the future to remove that file and pull
them all in my board config files as I'm the only user of it.

Regards,

Tim
Nikita Kiryanov Aug. 4, 2014, 1:36 p.m. UTC | #4
On 04/08/14 07:45, Tim Harvey wrote:
> On Sun, Aug 3, 2014 at 12:34 AM, Nikita Kiryanov <nikita@compulab.co.il> wrote:
>> Add initial support for Compulab CM-FX6 CoM.
>> Support includes MMC, SPI flash, and SPL with dynamic DRAM detection.
>>
> <snip>
>> +
>> +static void spl_mx6s_dram_init(enum ddr_config dram_config, int reset)
>> +{
>> +       struct mx6_mmdc_calibration calib;
>> +       struct mx6_ddr_sysinfo sysinfo;
>> +       struct mx6_ddr3_cfg ddr3_cfg;
>> +
>> +       if (reset)
>> +               ((struct mmdc_p_regs *)MX6_MMDC_P0_MDCTL)->mdmisc = 2;
>> +
>> +       calib.p0_mpwldectrl0    = 0x005B0061;
>> +       calib.p0_mpwldectrl1    = 0x004F0055;
>> +       calib.p0_mpdgctrl0      = 0x0314030C;
>> +       calib.p0_mpdgctrl1      = 0x025C0268;
>> +       calib.p0_mprddlctl      = 0x42464646;
>> +       calib.p0_mpwrdlctl      = 0x36322C34;
>> +       ddr3_cfg.mem_speed      = 800;
>> +       ddr3_cfg.density        = 4;
>> +       ddr3_cfg.rowaddr        = 14;
>> +       ddr3_cfg.coladdr        = 10;
>> +       ddr3_cfg.pagesz         = 2;
>> +       ddr3_cfg.trcd           = 1800;
>> +       ddr3_cfg.trcmin         = 5200;
>> +       ddr3_cfg.trasmin        = 3600;
>> +       ddr3_cfg.SRT            = 0;
>> +       sysinfo.cs1_mirror      = 1;
>> +       sysinfo.cs_density      = 16;
>> +       sysinfo.bi_on           = 1;
>> +       sysinfo.rtt_nom         = 1;
>> +       sysinfo.rtt_wr          = 0;
>> +       sysinfo.ralat           = 5;
>> +       sysinfo.walat           = 1;
>> +       sysinfo.mif3_mode       = 3;
>> +       sysinfo.rst_to_cke      = 0x23;
>> +       sysinfo.sde_to_rst      = 0x10;
>> +       switch (dram_config) {
>> +       case DDR_16BIT_256MB:
>> +               sysinfo.dsize = 0;
>> +               sysinfo.ncs = 1;
>> +               break;
>> +       case DDR_32BIT_512MB:
>> +               sysinfo.dsize = 1;
>> +               sysinfo.ncs = 1;
>> +               break;
>> +       case DDR_32BIT_1GB:
>> +               sysinfo.dsize = 1;
>> +               sysinfo.ncs = 2;
>> +               break;
>> +       default:
>> +               puts("Tried to setup invalid DDR configuration\n");
>> +               hang();
>> +       }
>> +
>> +       mx6_dram_cfg(&sysinfo, &calib, &ddr3_cfg);
>> +       udelay(100);
>> +}
>
> Nikita,
>
> I'm curious why you add an extra udelay(100) here? There is an
> mdelay(1) before the return of mx6_dram_cfg() to wait for auto-ZQ
> calibration to complete (I never found a way to determine when it was
> complete via registers).

Yes you're right. This udelay can probably be removed (unless I catch
the board misbehaving during multiple resets).

>
> Regards,
>
> Tim
>
Nikita Kiryanov Aug. 4, 2014, 2:24 p.m. UTC | #5
On 04/08/14 09:02, Tim Harvey wrote:
> On Sun, Aug 3, 2014 at 12:34 AM, Nikita Kiryanov <nikita@compulab.co.il> wrote:
>> Add initial support for Compulab CM-FX6 CoM.
>> Support includes MMC, SPI flash, and SPL with dynamic DRAM detection.
>>
> <snip>
>> diff --git a/include/configs/cm_fx6.h b/include/configs/cm_fx6.h
>> new file mode 100644
>> index 0000000..285af33
>> --- /dev/null
>> +++ b/include/configs/cm_fx6.h
>> @@ -0,0 +1,227 @@
>> +/*
>> + * Config file for Compulab CM-FX6 board
>> + *
>> + * Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/
>> + *
>> + * Author: Nikita Kiryanov <nikita@compulab.co.il>
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> + */
>> +
>> +#ifndef __CONFIG_CM_FX6_H
>> +#define __CONFIG_CM_FX6_H
>> +
>> +#include <asm/arch/imx-regs.h>
>> +#include <config_distro_defaults.h>
>> +
>> +#define CONFIG_SYS_L2CACHE_OFF
>> +#include "mx6_common.h"
>> +
>> +/* Machine config */
>> +#define CONFIG_MX6
>> +#define CONFIG_MX6QDL
>> +#define CONFIG_CM_FX6
>> +#define CONFIG_SYS_LITTLE_ENDIAN
>> +#define CONFIG_MACH_TYPE               4273
>> +#define CONFIG_SYS_HZ                  1000
>> +
>> +/* Display information on boot */
>> +#define CONFIG_DISPLAY_CPUINFO
>> +#define CONFIG_DISPLAY_BOARDINFO
>> +#define CONFIG_TIMESTAMP
>> +
>> +/* CMD */
>> +#include <config_cmd_default.h>
>> +#define CONFIG_CMD_GREPENV
>> +#undef CONFIG_CMD_FLASH
>> +#undef CONFIG_CMD_LOADB
>> +#undef CONFIG_CMD_LOADS
>> +#undef CONFIG_CMD_XIMG
>> +#undef CONFIG_CMD_FPGA
>> +#undef CONFIG_CMD_IMLS
>> +#undef CONFIG_CMD_NET
>> +#undef CONFIG_CMD_NFS
>> +
>> +/* MMC */
>> +#define CONFIG_MMC
>> +#define CONFIG_CMD_MMC
>> +#define CONFIG_GENERIC_MMC
>> +#define CONFIG_FSL_ESDHC
>> +#define CONFIG_FSL_USDHC
>> +#define CONFIG_SYS_FSL_USDHC_NUM       3
>> +#define CONFIG_SYS_FSL_ESDHC_ADDR      USDHC2_BASE_ADDR
>> +
>> +/* RAM */
>> +#define PHYS_SDRAM_1                   MMDC0_ARB_BASE_ADDR
>> +#define PHYS_SDRAM_2                   MMDC1_ARB_BASE_ADDR
>> +#define CONFIG_SYS_SDRAM_BASE          PHYS_SDRAM_1
>> +#define CONFIG_NR_DRAM_BANKS           2
>> +#define CONFIG_SYS_MEMTEST_START       0x10000000
>> +#define CONFIG_SYS_MEMTEST_END         0x10010000
>> +#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)
>> +
>> +/* Serial console */
>> +#define CONFIG_MXC_UART
>> +#define CONFIG_MXC_UART_BASE           UART4_BASE
>> +#define CONFIG_BAUDRATE                        115200
>> +#define CONFIG_SYS_BAUDRATE_TABLE      {9600, 19200, 38400, 57600, 115200}
>> +
>> +/* Shell */
>> +#define CONFIG_SYS_PROMPT      "CM-FX6 # "
>> +#define CONFIG_SYS_CBSIZE      1024
>> +#define CONFIG_SYS_MAXARGS     16
>> +#define CONFIG_SYS_BARGSIZE    CONFIG_SYS_CBSIZE
>> +#define CONFIG_SYS_PBSIZE      (CONFIG_SYS_CBSIZE + \
>> +                                       sizeof(CONFIG_SYS_PROMPT) + 16)
>> +#define CONFIG_SYS_MONITOR_LEN (CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS / 2 * 1024)
>> +
>> +/* SPI flash */
>> +#define CONFIG_SYS_NO_FLASH
>> +#define CONFIG_CMD_SF
>> +#define CONFIG_SF_DEFAULT_BUS          0
>> +#define CONFIG_SF_DEFAULT_CS           0
>> +#define CONFIG_SF_DEFAULT_SPEED                25000000
>> +#define CONFIG_SF_DEFAULT_MODE         (SPI_MODE_0)
>> +
>> +/* Environment */
>> +#define CONFIG_ENV_OVERWRITE
>> +#define CONFIG_ENV_IS_IN_SPI_FLASH
>> +#define CONFIG_ENV_SPI_MAX_HZ          CONFIG_SF_DEFAULT_SPEED
>> +#define CONFIG_ENV_SPI_MODE            CONFIG_SF_DEFAULT_MODE
>> +#define CONFIG_ENV_SPI_BUS             CONFIG_SF_DEFAULT_BUS
>> +#define CONFIG_ENV_SPI_CS              CONFIG_SF_DEFAULT_CS
>> +#define CONFIG_ENV_SECT_SIZE           (64 * 1024)
>> +#define CONFIG_ENV_SIZE                        (8 * 1024)
>> +#define CONFIG_ENV_OFFSET              (768 * 1024)
>> +
>> +#define CONFIG_EXTRA_ENV_SETTINGS \
>> +       "kernel=uImage-cm-fx6\0" \
>> +       "autoload=no\0" \
>> +       "loadaddr=0x10800000\0" \
>> +       "fdtaddr=0x11000000\0" \
>> +       "console=ttymxc3,115200\0" \
>> +       "ethprime=FEC0\0" \
>> +       "bootscr=boot.scr\0" \
>> +       "bootm_low=18000000\0" \
>> +       "video_hdmi=mxcfb0:dev=hdmi,1920x1080M-32@50,if=RGB32\0" \
>> +       "video_dvi=mxcfb0:dev=dvi,1280x800M-32@50,if=RGB32\0" \
>> +       "fdtfile=cm-fx6.dtb\0" \
>> +       "doboot=bootm ${loadaddr}\0" \
>> +       "loadfdt=false\0" \
>> +       "setboottypez=setenv kernel zImage-cm-fx6;" \
>> +               "setenv doboot bootz ${loadaddr} - ${fdtaddr};" \
>> +               "setenv loadfdt true;\0" \
>> +       "setboottypem=setenv kernel uImage-cm-fx6;" \
>> +               "setenv doboot bootm ${loadaddr};" \
>> +               "setenv loadfdt false;\0"\
>> +       "run_eboot=echo Starting EBOOT ...; "\
>> +               "mmc dev ${mmcdev} && " \
>> +               "mmc rescan && mmc read 10042000 a 400 && go 10042000\0" \
>> +       "mmcdev=2\0" \
>> +       "mmcroot=/dev/mmcblk0p2 rw rootwait\0" \
>> +       "loadmmcbootscript=fatload mmc ${mmcdev} ${loadaddr} ${bootscr}\0" \
>> +       "mmcbootscript=echo Running bootscript from mmc ...; "\
>> +               "source ${loadaddr}\0" \
>> +       "mmcargs=setenv bootargs console=${console} " \
>> +               "root=${mmcroot} " \
>> +               "${video}\0" \
>> +       "mmcloadkernel=fatload mmc ${mmcdev} ${loadaddr} ${kernel}\0" \
>> +       "mmcloadfdt=fatload mmc ${mmcdev} ${fdtaddr} ${fdtfile}\0" \
>> +       "mmcboot=echo Booting from mmc ...; " \
>> +               "run mmcargs; " \
>> +               "run doboot\0" \
>> +       "nandroot=/dev/mtdblock4 rw\0" \
>> +       "nandrootfstype=ubifs\0" \
>> +       "nandargs=setenv bootargs console=${console} " \
>> +               "root=${nandroot} " \
>> +               "rootfstype=${nandrootfstype} " \
>> +               "${video}\0" \
>> +       "nandloadfdt=nand read ${fdtaddr} 780000 80000;\0" \
>> +       "nandboot=echo Booting from nand ...; " \
>> +               "run nandargs; " \
>> +               "nand read ${loadaddr} 0 780000; " \
>> +               "if ${loadfdt}; then " \
>> +                       "run nandloadfdt;" \
>> +               "fi; " \
>> +               "run doboot\0" \
>> +       "boot=mmc dev ${mmcdev}; " \
>> +               "if mmc rescan; then " \
>> +                       "if run loadmmcbootscript; then " \
>> +                               "run mmcbootscript;" \
>> +                       "else " \
>> +                               "if run mmcloadkernel; then " \
>> +                                       "if ${loadfdt}; then " \
>> +                                               "run mmcloadfdt;" \
>> +                                       "fi;" \
>> +                                       "run mmcboot;" \
>> +                               "fi;" \
>> +                       "fi;" \
>> +               "fi;"
>> +
>> +#define CONFIG_BOOTCOMMAND \
>> +       "run setboottypem; run boot"
>> +
>> +/* SPI */
>> +#define CONFIG_SPI
>> +#define CONFIG_MXC_SPI
>> +#define CONFIG_SPI_FLASH
>> +#define CONFIG_SPI_FLASH_ATMEL
>> +#define CONFIG_SPI_FLASH_EON
>> +#define CONFIG_SPI_FLASH_GIGADEVICE
>> +#define CONFIG_SPI_FLASH_MACRONIX
>> +#define CONFIG_SPI_FLASH_SPANSION
>> +#define CONFIG_SPI_FLASH_STMICRO
>> +#define CONFIG_SPI_FLASH_SST
>> +#define CONFIG_SPI_FLASH_WINBOND
>> +
>> +/* GPIO */
>> +#define CONFIG_MXC_GPIO
>> +
>> +/* Boot */
>> +#define CONFIG_ZERO_BOOTDELAY_CHECK
>> +#define CONFIG_LOADADDR                        0x10800000
>> +#define CONFIG_SYS_LOAD_ADDR           CONFIG_LOADADDR
>> +#define CONFIG_SYS_TEXT_BASE           0x10800000
>> +#define CONFIG_CMDLINE_TAG             /* enable passing of ATAGs */
>> +#define CONFIG_SYS_BOOTMAPSZ           (8 << 20)
>> +#define CONFIG_SETUP_MEMORY_TAGS
>> +#define CONFIG_INITRD_TAG
>> +
>> +/* misc */
>> +#define CONFIG_SYS_GENERIC_BOARD
>> +#define CONFIG_STACKSIZE                       (128 * 1024)
>> +#define CONFIG_SYS_MALLOC_LEN                  (2 * 1024 * 1024)
>> +#define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS     800 /* 400 KB */
>> +
>> +/* SPL */
>> +#define CONFIG_SPL
>> +#define CONFIG_SPL_FRAMEWORK
>> +#define CONFIG_SPL_BOARD_INIT
>> +#define CONFIG_SPL_STACK               0x0091FFB8
>> +#define CONFIG_SPL_TEXT_BASE           0x00908000
>> +#define CONFIG_SPL_BSS_START_ADDR      0x18200000
>> +#define CONFIG_SPL_BSS_MAX_SIZE                0x00100000
>> +#define CONFIG_SYS_SPL_MALLOC_START    0x18300000
>> +#define CONFIG_SYS_SPL_MALLOC_SIZE     0x03200000
>> +#define CONFIG_SPL_MAX_SIZE            (62 * 1024)
>> +#define CONFIG_SPL_LIBDISK_SUPPORT
>> +#define CONFIG_SPL_LIBGENERIC_SUPPORT
>> +#define CONFIG_SPL_LIBCOMMON_SUPPORT
>> +#define CONFIG_SPL_GPIO_SUPPORT
>> +#define CONFIG_SPL_SERIAL_SUPPORT
>> +#define CONFIG_SPL_MMC_SUPPORT
>> +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR        0x80 /* offset 64 kb */
>> +#define CONFIG_SPL_SPI_SUPPORT
>> +#define CONFIG_SPL_SPI_FLASH_SUPPORT
>> +#define CONFIG_SPL_SPI_BUS             CONFIG_SF_DEFAULT_BUS
>> +#define CONFIG_SPL_SPI_CS              CONFIG_SF_DEFAULT_CS
>> +#define CONFIG_SPL_SPI_MODE            CONFIG_SF_DEFAULT_MODE
>> +#define CONFIG_SYS_SPI_U_BOOT_OFFS     (64 * 1024)
>> +#define CONFIG_SPL_SPI_LOAD
>
> Nikita,
>
> Are the values in include/configs/imx6_spl.h too inflexible to use? If
> so, I can submit a patch in the future to remove that file and pull
> them all in my board config files as I'm the only user of it.

This is actually something I forgot to make use of when I was rebasing
the code over mainline. I'll try to use it in a v2.

>
> Regards,
>
> Tim
>
Nikita Kiryanov Aug. 4, 2014, 2:41 p.m. UTC | #6
On 03/08/14 17:09, Marek Vasut wrote:
> On Sunday, August 03, 2014 at 09:34:42 AM, Nikita Kiryanov wrote:
>> Add initial support for Compulab CM-FX6 CoM.
>> Support includes MMC, SPI flash, and SPL with dynamic DRAM detection.
>>
>> Cc: Igor Grinberg <grinberg@compulab.co.il>
>> Cc: Stefano Babic <sbabic@denx.de>
>> Cc: Tom Rini <trini@ti.com>
>> Signed-off-by: Nikita Kiryanov <nikita@compulab.co.il>
>> ---
>>   arch/arm/cpu/armv7/mx6/ddr.c       |   1 -
>>   board/compulab/cm_fx6/Makefile     |  12 ++
>>   board/compulab/cm_fx6/cm_fx6.c     | 108 ++++++++++
>>   board/compulab/cm_fx6/common.c     |  83 ++++++++
>>   board/compulab/cm_fx6/common.h     |  36 ++++
>>   board/compulab/cm_fx6/imximage.cfg |   8 +
>>   board/compulab/cm_fx6/spl.c        | 400
>> +++++++++++++++++++++++++++++++++++++ boards.cfg                         |
>>    2 +
>>   include/configs/cm_fx6.h           | 227 +++++++++++++++++++++
>>   9 files changed, 876 insertions(+), 1 deletion(-)
>>   create mode 100644 board/compulab/cm_fx6/Makefile
>>   create mode 100644 board/compulab/cm_fx6/cm_fx6.c
>>   create mode 100644 board/compulab/cm_fx6/common.c
>>   create mode 100644 board/compulab/cm_fx6/common.h
>>   create mode 100644 board/compulab/cm_fx6/imximage.cfg
>>   create mode 100644 board/compulab/cm_fx6/spl.c
>>   create mode 100644 include/configs/cm_fx6.h
>>
>> diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c
>> index d3891dc..219263a 100644
>> --- a/arch/arm/cpu/armv7/mx6/ddr.c
>> +++ b/arch/arm/cpu/armv7/mx6/ddr.c
>> @@ -4,7 +4,6 @@
>>    *
>>    * SPDX-License-Identifier:     GPL-2.0+
>>    */
>> -
>>   #include <common.h>
>>   #include <linux/types.h>
>>   #include <asm/arch/mx6-ddr.h>
>
> Drop this piece ;-)

Yep...

>
> [...]
>> +++ b/board/compulab/cm_fx6/cm_fx6.c
>
> [...]
>
>> +static ulong bank1_size;
>> +static ulong bank2_size;
>> +
>> +#define MMDC1_MDCTL 0x21B0000
>> +static int probe_mmdc_config(void)
>> +{
>> +	u32 val = readl(0x21B0000);
>> +	switch (val) {
>> +	case 0x83180000: /* DDR_16BIT_256MB */
>> +		gd->ram_size	= 0x10000000;
>> +		bank1_size	= 0x10000000;
>> +		bank2_size	= 0;
>> +		break;
>> +	case 0x83190000: /* DDR_32BIT_512MB */
>> +		gd->ram_size	= 0x20000000;
>> +		bank1_size	= 0x20000000;
>> +		bank2_size	= 0;
>> +		break;
>
> imx_ddr_size() won't cut it here ?

It doesn't handle 4GB correctly (returns 0). I suppose
I can make a patch which caps the return value of
imx_ddr_size() for MX6 socs to 3840MB.
What do you think?

>
> [...]
>
Marek Vasut Aug. 4, 2014, 3:12 p.m. UTC | #7
On Monday, August 04, 2014 at 04:41:03 PM, Nikita Kiryanov wrote:
> On 03/08/14 17:09, Marek Vasut wrote:
> > On Sunday, August 03, 2014 at 09:34:42 AM, Nikita Kiryanov wrote:
> >> Add initial support for Compulab CM-FX6 CoM.
> >> Support includes MMC, SPI flash, and SPL with dynamic DRAM detection.
> >> 
> >> Cc: Igor Grinberg <grinberg@compulab.co.il>
> >> Cc: Stefano Babic <sbabic@denx.de>
> >> Cc: Tom Rini <trini@ti.com>
> >> Signed-off-by: Nikita Kiryanov <nikita@compulab.co.il>
> >> ---
> >> 
> >>   arch/arm/cpu/armv7/mx6/ddr.c       |   1 -
> >>   board/compulab/cm_fx6/Makefile     |  12 ++
> >>   board/compulab/cm_fx6/cm_fx6.c     | 108 ++++++++++
> >>   board/compulab/cm_fx6/common.c     |  83 ++++++++
> >>   board/compulab/cm_fx6/common.h     |  36 ++++
> >>   board/compulab/cm_fx6/imximage.cfg |   8 +
> >>   board/compulab/cm_fx6/spl.c        | 400
> >> 
> >> +++++++++++++++++++++++++++++++++++++ boards.cfg                        
> >> |
> >> 
> >>    2 +
> >>   
> >>   include/configs/cm_fx6.h           | 227 +++++++++++++++++++++
> >>   9 files changed, 876 insertions(+), 1 deletion(-)
> >>   create mode 100644 board/compulab/cm_fx6/Makefile
> >>   create mode 100644 board/compulab/cm_fx6/cm_fx6.c
> >>   create mode 100644 board/compulab/cm_fx6/common.c
> >>   create mode 100644 board/compulab/cm_fx6/common.h
> >>   create mode 100644 board/compulab/cm_fx6/imximage.cfg
> >>   create mode 100644 board/compulab/cm_fx6/spl.c
> >>   create mode 100644 include/configs/cm_fx6.h
> >> 
> >> diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c
> >> index d3891dc..219263a 100644
> >> --- a/arch/arm/cpu/armv7/mx6/ddr.c
> >> +++ b/arch/arm/cpu/armv7/mx6/ddr.c
> >> @@ -4,7 +4,6 @@
> >> 
> >>    *
> >>    * SPDX-License-Identifier:     GPL-2.0+
> >>    */
> >> 
> >> -
> >> 
> >>   #include <common.h>
> >>   #include <linux/types.h>
> >>   #include <asm/arch/mx6-ddr.h>
> > 
> > Drop this piece ;-)
> 
> Yep...
> 
> > [...]
> > 
> >> +++ b/board/compulab/cm_fx6/cm_fx6.c
> > 
> > [...]
> > 
> >> +static ulong bank1_size;
> >> +static ulong bank2_size;
> >> +
> >> +#define MMDC1_MDCTL 0x21B0000
> >> +static int probe_mmdc_config(void)
> >> +{
> >> +	u32 val = readl(0x21B0000);
> >> +	switch (val) {
> >> +	case 0x83180000: /* DDR_16BIT_256MB */
> >> +		gd->ram_size	= 0x10000000;
> >> +		bank1_size	= 0x10000000;
> >> +		bank2_size	= 0;
> >> +		break;
> >> +	case 0x83190000: /* DDR_32BIT_512MB */
> >> +		gd->ram_size	= 0x20000000;
> >> +		bank1_size	= 0x20000000;
> >> +		bank2_size	= 0;
> >> +		break;
> > 
> > imx_ddr_size() won't cut it here ?
> 
> It doesn't handle 4GB correctly (returns 0). I suppose
> I can make a patch which caps the return value of
> imx_ddr_size() for MX6 socs to 3840MB.
> What do you think?

That you should check the U-Boot ML, since that's what I did yesterday ;-) But 
still, this is rather sad practice -- instead of fixing a bug in code which you 
do know about, you implement such a workaround :-(
Nikita Kiryanov Aug. 5, 2014, 7:36 a.m. UTC | #8
On 04/08/14 18:12, Marek Vasut wrote:
> On Monday, August 04, 2014 at 04:41:03 PM, Nikita Kiryanov wrote:
>> On 03/08/14 17:09, Marek Vasut wrote:
>>> On Sunday, August 03, 2014 at 09:34:42 AM, Nikita Kiryanov wrote:
>>>> Add initial support for Compulab CM-FX6 CoM.
>>>> Support includes MMC, SPI flash, and SPL with dynamic DRAM detection.
>>>>
>>>> Cc: Igor Grinberg <grinberg@compulab.co.il>
>>>> Cc: Stefano Babic <sbabic@denx.de>
>>>> Cc: Tom Rini <trini@ti.com>
>>>> Signed-off-by: Nikita Kiryanov <nikita@compulab.co.il>
>>>> ---
>>>>
>>>>    arch/arm/cpu/armv7/mx6/ddr.c       |   1 -
>>>>    board/compulab/cm_fx6/Makefile     |  12 ++
>>>>    board/compulab/cm_fx6/cm_fx6.c     | 108 ++++++++++
>>>>    board/compulab/cm_fx6/common.c     |  83 ++++++++
>>>>    board/compulab/cm_fx6/common.h     |  36 ++++
>>>>    board/compulab/cm_fx6/imximage.cfg |   8 +
>>>>    board/compulab/cm_fx6/spl.c        | 400
>>>>
>>>> +++++++++++++++++++++++++++++++++++++ boards.cfg
>>>> |
>>>>
>>>>     2 +
>>>>
>>>>    include/configs/cm_fx6.h           | 227 +++++++++++++++++++++
>>>>    9 files changed, 876 insertions(+), 1 deletion(-)
>>>>    create mode 100644 board/compulab/cm_fx6/Makefile
>>>>    create mode 100644 board/compulab/cm_fx6/cm_fx6.c
>>>>    create mode 100644 board/compulab/cm_fx6/common.c
>>>>    create mode 100644 board/compulab/cm_fx6/common.h
>>>>    create mode 100644 board/compulab/cm_fx6/imximage.cfg
>>>>    create mode 100644 board/compulab/cm_fx6/spl.c
>>>>    create mode 100644 include/configs/cm_fx6.h
>>>>
>>>> diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c
>>>> index d3891dc..219263a 100644
>>>> --- a/arch/arm/cpu/armv7/mx6/ddr.c
>>>> +++ b/arch/arm/cpu/armv7/mx6/ddr.c
>>>> @@ -4,7 +4,6 @@
>>>>
>>>>     *
>>>>     * SPDX-License-Identifier:     GPL-2.0+
>>>>     */
>>>>
>>>> -
>>>>
>>>>    #include <common.h>
>>>>    #include <linux/types.h>
>>>>    #include <asm/arch/mx6-ddr.h>
>>>
>>> Drop this piece ;-)
>>
>> Yep...
>>
>>> [...]
>>>
>>>> +++ b/board/compulab/cm_fx6/cm_fx6.c
>>>
>>> [...]
>>>
>>>> +static ulong bank1_size;
>>>> +static ulong bank2_size;
>>>> +
>>>> +#define MMDC1_MDCTL 0x21B0000
>>>> +static int probe_mmdc_config(void)
>>>> +{
>>>> +	u32 val = readl(0x21B0000);
>>>> +	switch (val) {
>>>> +	case 0x83180000: /* DDR_16BIT_256MB */
>>>> +		gd->ram_size	= 0x10000000;
>>>> +		bank1_size	= 0x10000000;
>>>> +		bank2_size	= 0;
>>>> +		break;
>>>> +	case 0x83190000: /* DDR_32BIT_512MB */
>>>> +		gd->ram_size	= 0x20000000;
>>>> +		bank1_size	= 0x20000000;
>>>> +		bank2_size	= 0;
>>>> +		break;
>>>
>>> imx_ddr_size() won't cut it here ?
>>
>> It doesn't handle 4GB correctly (returns 0). I suppose
>> I can make a patch which caps the return value of
>> imx_ddr_size() for MX6 socs to 3840MB.
>> What do you think?
>
> That you should check the U-Boot ML, since that's what I did yesterday ;-) But
> still, this is rather sad practice -- instead of fixing a bug in code which you
> do know about, you implement such a workaround :-(

Actually, I only learned of this bug yesterday after you asked about
imx_ddr_size(). Glad to hear you already fixed it; I'll look at it for
the v2.
Marek Vasut Aug. 5, 2014, 7:58 a.m. UTC | #9
On Tuesday, August 05, 2014 at 09:36:27 AM, Nikita Kiryanov wrote:

[...]

> >>> imx_ddr_size() won't cut it here ?
> >> 
> >> It doesn't handle 4GB correctly (returns 0). I suppose
> >> I can make a patch which caps the return value of
> >> imx_ddr_size() for MX6 socs to 3840MB.
> >> What do you think?
> > 
> > That you should check the U-Boot ML, since that's what I did yesterday
> > ;-) But still, this is rather sad practice -- instead of fixing a bug in
> > code which you do know about, you implement such a workaround :-(
> 
> Actually, I only learned of this bug yesterday after you asked about
> imx_ddr_size(). Glad to hear you already fixed it; I'll look at it for
> the v2.

I did the capping, yep. HTH :)

Best regards,
Marek Vasut
Nikita Kiryanov Aug. 6, 2014, 5:29 p.m. UTC | #10
On 04/08/14 16:36, Nikita Kiryanov wrote:
>
>
> On 04/08/14 07:45, Tim Harvey wrote:
>> On Sun, Aug 3, 2014 at 12:34 AM, Nikita Kiryanov
>> <nikita@compulab.co.il> wrote:
>>> Add initial support for Compulab CM-FX6 CoM.
>>> Support includes MMC, SPI flash, and SPL with dynamic DRAM detection.
>>>
>> <snip>
>>> +
>>> +static void spl_mx6s_dram_init(enum ddr_config dram_config, int reset)
>>> +{
>>> +       struct mx6_mmdc_calibration calib;
>>> +       struct mx6_ddr_sysinfo sysinfo;
>>> +       struct mx6_ddr3_cfg ddr3_cfg;
>>> +
>>> +       if (reset)
>>> +               ((struct mmdc_p_regs *)MX6_MMDC_P0_MDCTL)->mdmisc = 2;
>>> +
>>> +       calib.p0_mpwldectrl0    = 0x005B0061;
>>> +       calib.p0_mpwldectrl1    = 0x004F0055;
>>> +       calib.p0_mpdgctrl0      = 0x0314030C;
>>> +       calib.p0_mpdgctrl1      = 0x025C0268;
>>> +       calib.p0_mprddlctl      = 0x42464646;
>>> +       calib.p0_mpwrdlctl      = 0x36322C34;
>>> +       ddr3_cfg.mem_speed      = 800;
>>> +       ddr3_cfg.density        = 4;
>>> +       ddr3_cfg.rowaddr        = 14;
>>> +       ddr3_cfg.coladdr        = 10;
>>> +       ddr3_cfg.pagesz         = 2;
>>> +       ddr3_cfg.trcd           = 1800;
>>> +       ddr3_cfg.trcmin         = 5200;
>>> +       ddr3_cfg.trasmin        = 3600;
>>> +       ddr3_cfg.SRT            = 0;
>>> +       sysinfo.cs1_mirror      = 1;
>>> +       sysinfo.cs_density      = 16;
>>> +       sysinfo.bi_on           = 1;
>>> +       sysinfo.rtt_nom         = 1;
>>> +       sysinfo.rtt_wr          = 0;
>>> +       sysinfo.ralat           = 5;
>>> +       sysinfo.walat           = 1;
>>> +       sysinfo.mif3_mode       = 3;
>>> +       sysinfo.rst_to_cke      = 0x23;
>>> +       sysinfo.sde_to_rst      = 0x10;
>>> +       switch (dram_config) {
>>> +       case DDR_16BIT_256MB:
>>> +               sysinfo.dsize = 0;
>>> +               sysinfo.ncs = 1;
>>> +               break;
>>> +       case DDR_32BIT_512MB:
>>> +               sysinfo.dsize = 1;
>>> +               sysinfo.ncs = 1;
>>> +               break;
>>> +       case DDR_32BIT_1GB:
>>> +               sysinfo.dsize = 1;
>>> +               sysinfo.ncs = 2;
>>> +               break;
>>> +       default:
>>> +               puts("Tried to setup invalid DDR configuration\n");
>>> +               hang();
>>> +       }
>>> +
>>> +       mx6_dram_cfg(&sysinfo, &calib, &ddr3_cfg);
>>> +       udelay(100);
>>> +}
>>
>> Nikita,
>>
>> I'm curious why you add an extra udelay(100) here? There is an
>> mdelay(1) before the return of mx6_dram_cfg() to wait for auto-ZQ
>> calibration to complete (I never found a way to determine when it was
>> complete via registers).
>
> Yes you're right. This udelay can probably be removed (unless I catch
> the board misbehaving during multiple resets).

Caught the DRAM config failing during multiple resets when udelay(100)
is removed, so I guess they stay..

>
>>
>> Regards,
>>
>> Tim
>>
> _______________________________________________
> U-Boot mailing list
> U-Boot@lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
Nikita Kiryanov Aug. 7, 2014, 11:27 a.m. UTC | #11
On 04/08/14 17:24, Nikita Kiryanov wrote:
>
>
> On 04/08/14 09:02, Tim Harvey wrote:
>> Nikita,
>>
>> Are the values in include/configs/imx6_spl.h too inflexible to use? If
>> so, I can submit a patch in the future to remove that file and pull
>> them all in my board config files as I'm the only user of it.
>
> This is actually something I forgot to make use of when I was rebasing
> the code over mainline. I'll try to use it in a v2.
>

I came across an unexpected problem when using imx6_spl.h. Due to the
way the makefile is written, it is impossible to redefine imx6_spl.h's
definition of CONFIG_SYS_TEXT_BASE using standard #undef/#define pair.

This happens because the makefile passes the CONFIG_SYS_TEXT_BASE
define using the -D option to the compiler, and it clashes with the
contents of common.h. For example:

The relevant code from Makefile:
ifneq ($(CONFIG_SYS_TEXT_BASE),)
KBUILD_CPPFLAGS += -DCONFIG_SYS_TEXT_BASE=$(CONFIG_SYS_TEXT_BASE)
endif

The include hierarchy and contents of include/configs/someboard.h:
include/common.h
  |---> include/config.h
           |---> include/configs/someboard.h
                 #include "imx6_spl.h"
                 #undef CONFIG_SYS_TEXT_BASE
                 #define CONFIG_SYS_TEXT_BASE <NEW_VALUE>

During build:
Makefile obtains CONFIG_SYS_TEXT_BASE <NEW_VALUE> and passes it
to the compiler using: -DCONFIG_SYS_TEXT_BASE=$(CONFIG_SYS_TEXT_BASE)

For every file that #includes common.h we get this:

  #define CONFIG_SYS_TEXT_BASE <NEW_VALUE> <-- from compiler
  #define CONFIG_SYS_TEXT_BASE 0x17800000  <-- from imx6_spl.h 
(redefinition!)
  #undef CONFIG_SYS_TEXT_BASE              <-- from someboard.h
  #define CONFIG_SYS_TEXT_BASE <NEW_VALUE>

Sample output during compilation:
include/configs/imx6_spl.h:68:0: warning: "CONFIG_SYS_TEXT_BASE" 
redefined [enabled by default]
  #define CONFIG_SYS_TEXT_BASE  0x17800000
  ^
<command-line>:0:0: note: this is the location of the previous definition
   LD      arch/arm/cpu/armv7/mx6/built-in.o
   CC      arch/arm/lib/reset.o
In file included from include/configs/cm_fx6.h:273:0,
                  from include/config.h:10,
                  from include/common.h:18,
                  from arch/arm/lib/interrupts.c:22:

This goes on and on for quite a lot of files, and I wonder if passing
-DCONFIG_SYS_TEXT_BASE to the compiler is even necessary. It looks like
the includes already take care of bringing this value where it is
needed.

I tried to remove
KBUILD_CPPFLAGS += -DCONFIG_SYS_TEXT_BASE=$(CONFIG_SYS_TEXT_BASE)
and run MAKEALL for arm boards, and most of them compiled without 
problems. Only these two boards failed: cam_enc_4xx, hawkboard.

Tom, any insight as to the necessity of this practice?
Tim Harvey Aug. 8, 2014, 7:19 a.m. UTC | #12
On Wed, Aug 6, 2014 at 10:29 AM, Nikita Kiryanov <nikita@compulab.co.il> wrote:
>
>
> On 04/08/14 16:36, Nikita Kiryanov wrote:
>>
>>
>>
>> On 04/08/14 07:45, Tim Harvey wrote:
>>>
>>> On Sun, Aug 3, 2014 at 12:34 AM, Nikita Kiryanov
>>> <nikita@compulab.co.il> wrote:
>>>>
>>>> Add initial support for Compulab CM-FX6 CoM.
>>>> Support includes MMC, SPI flash, and SPL with dynamic DRAM detection.
>>>>
>>> <snip>
>>>>
>>>> +
>>>> +static void spl_mx6s_dram_init(enum ddr_config dram_config, int reset)
>>>> +{
>>>> +       struct mx6_mmdc_calibration calib;
>>>> +       struct mx6_ddr_sysinfo sysinfo;
>>>> +       struct mx6_ddr3_cfg ddr3_cfg;
>>>> +
>>>> +       if (reset)
>>>> +               ((struct mmdc_p_regs *)MX6_MMDC_P0_MDCTL)->mdmisc = 2;
>>>> +
>>>> +       calib.p0_mpwldectrl0    = 0x005B0061;
>>>> +       calib.p0_mpwldectrl1    = 0x004F0055;
>>>> +       calib.p0_mpdgctrl0      = 0x0314030C;
>>>> +       calib.p0_mpdgctrl1      = 0x025C0268;
>>>> +       calib.p0_mprddlctl      = 0x42464646;
>>>> +       calib.p0_mpwrdlctl      = 0x36322C34;
>>>> +       ddr3_cfg.mem_speed      = 800;
>>>> +       ddr3_cfg.density        = 4;
>>>> +       ddr3_cfg.rowaddr        = 14;
>>>> +       ddr3_cfg.coladdr        = 10;
>>>> +       ddr3_cfg.pagesz         = 2;
>>>> +       ddr3_cfg.trcd           = 1800;
>>>> +       ddr3_cfg.trcmin         = 5200;
>>>> +       ddr3_cfg.trasmin        = 3600;
>>>> +       ddr3_cfg.SRT            = 0;
>>>> +       sysinfo.cs1_mirror      = 1;
>>>> +       sysinfo.cs_density      = 16;
>>>> +       sysinfo.bi_on           = 1;
>>>> +       sysinfo.rtt_nom         = 1;
>>>> +       sysinfo.rtt_wr          = 0;
>>>> +       sysinfo.ralat           = 5;
>>>> +       sysinfo.walat           = 1;
>>>> +       sysinfo.mif3_mode       = 3;
>>>> +       sysinfo.rst_to_cke      = 0x23;
>>>> +       sysinfo.sde_to_rst      = 0x10;
>>>> +       switch (dram_config) {
>>>> +       case DDR_16BIT_256MB:
>>>> +               sysinfo.dsize = 0;
>>>> +               sysinfo.ncs = 1;
>>>> +               break;
>>>> +       case DDR_32BIT_512MB:
>>>> +               sysinfo.dsize = 1;
>>>> +               sysinfo.ncs = 1;
>>>> +               break;
>>>> +       case DDR_32BIT_1GB:
>>>> +               sysinfo.dsize = 1;
>>>> +               sysinfo.ncs = 2;
>>>> +               break;
>>>> +       default:
>>>> +               puts("Tried to setup invalid DDR configuration\n");
>>>> +               hang();
>>>> +       }
>>>> +
>>>> +       mx6_dram_cfg(&sysinfo, &calib, &ddr3_cfg);
>>>> +       udelay(100);
>>>> +}
>>>
>>>
>>> Nikita,
>>>
>>> I'm curious why you add an extra udelay(100) here? There is an
>>> mdelay(1) before the return of mx6_dram_cfg() to wait for auto-ZQ
>>> calibration to complete (I never found a way to determine when it was
>>> complete via registers).
>>
>>
>> Yes you're right. This udelay can probably be removed (unless I catch
>> the board misbehaving during multiple resets).
>
>
> Caught the DRAM config failing during multiple resets when udelay(100)
> is removed, so I guess they stay..
>

Nikita,

What exactly was failing? Was the subsequent to get_ram_size()
failing? If the extra delay is really needed we should add it to the
mx6_dram_cfg() function. The issue I ran into before I added the
mdelay(1) there to wait for auto-ZQ calib to complete was that SDRAM
operations immediately following the call to mx6_dram_cfg() would be
un-reliable, specifically a memset to 0 would fail to clear memory
where GD was which caused some interesting failures down the line.

Maybe I'll open up an issue with Freescale and ask them if there is a
way to know when auto-ZQ calibration is complete because it isn't
clear to me how to do that. The 1ms delay was because the 0 value we
set to MPZQHWCTRL ZQ_HW_PER configures it for a 1ms ZQ calibration
cycle.... maybe we simply need a little more headroom.

Tim
Nikita Kiryanov Aug. 10, 2014, 4:20 p.m. UTC | #13
On 08/08/14 10:19, Tim Harvey wrote:
> On Wed, Aug 6, 2014 at 10:29 AM, Nikita Kiryanov <nikita@compulab.co.il> wrote:
>>
>>
>> On 04/08/14 16:36, Nikita Kiryanov wrote:
>>>
>>>
>>>
>>> On 04/08/14 07:45, Tim Harvey wrote:
>>>>
>>>> On Sun, Aug 3, 2014 at 12:34 AM, Nikita Kiryanov
>>>> <nikita@compulab.co.il> wrote:
>>>>>
>>>>> Add initial support for Compulab CM-FX6 CoM.
>>>>> Support includes MMC, SPI flash, and SPL with dynamic DRAM detection.
>>>>>
>>>> <snip>
>>>>>
>>>>> +
>>>>> +static void spl_mx6s_dram_init(enum ddr_config dram_config, int reset)
>>>>> +{
>>>>> +       struct mx6_mmdc_calibration calib;
>>>>> +       struct mx6_ddr_sysinfo sysinfo;
>>>>> +       struct mx6_ddr3_cfg ddr3_cfg;
>>>>> +
>>>>> +       if (reset)
>>>>> +               ((struct mmdc_p_regs *)MX6_MMDC_P0_MDCTL)->mdmisc = 2;
>>>>> +
>>>>> +       calib.p0_mpwldectrl0    = 0x005B0061;
>>>>> +       calib.p0_mpwldectrl1    = 0x004F0055;
>>>>> +       calib.p0_mpdgctrl0      = 0x0314030C;
>>>>> +       calib.p0_mpdgctrl1      = 0x025C0268;
>>>>> +       calib.p0_mprddlctl      = 0x42464646;
>>>>> +       calib.p0_mpwrdlctl      = 0x36322C34;
>>>>> +       ddr3_cfg.mem_speed      = 800;
>>>>> +       ddr3_cfg.density        = 4;
>>>>> +       ddr3_cfg.rowaddr        = 14;
>>>>> +       ddr3_cfg.coladdr        = 10;
>>>>> +       ddr3_cfg.pagesz         = 2;
>>>>> +       ddr3_cfg.trcd           = 1800;
>>>>> +       ddr3_cfg.trcmin         = 5200;
>>>>> +       ddr3_cfg.trasmin        = 3600;
>>>>> +       ddr3_cfg.SRT            = 0;
>>>>> +       sysinfo.cs1_mirror      = 1;
>>>>> +       sysinfo.cs_density      = 16;
>>>>> +       sysinfo.bi_on           = 1;
>>>>> +       sysinfo.rtt_nom         = 1;
>>>>> +       sysinfo.rtt_wr          = 0;
>>>>> +       sysinfo.ralat           = 5;
>>>>> +       sysinfo.walat           = 1;
>>>>> +       sysinfo.mif3_mode       = 3;
>>>>> +       sysinfo.rst_to_cke      = 0x23;
>>>>> +       sysinfo.sde_to_rst      = 0x10;
>>>>> +       switch (dram_config) {
>>>>> +       case DDR_16BIT_256MB:
>>>>> +               sysinfo.dsize = 0;
>>>>> +               sysinfo.ncs = 1;
>>>>> +               break;
>>>>> +       case DDR_32BIT_512MB:
>>>>> +               sysinfo.dsize = 1;
>>>>> +               sysinfo.ncs = 1;
>>>>> +               break;
>>>>> +       case DDR_32BIT_1GB:
>>>>> +               sysinfo.dsize = 1;
>>>>> +               sysinfo.ncs = 2;
>>>>> +               break;
>>>>> +       default:
>>>>> +               puts("Tried to setup invalid DDR configuration\n");
>>>>> +               hang();
>>>>> +       }
>>>>> +
>>>>> +       mx6_dram_cfg(&sysinfo, &calib, &ddr3_cfg);
>>>>> +       udelay(100);
>>>>> +}
>>>>
>>>>
>>>> Nikita,
>>>>
>>>> I'm curious why you add an extra udelay(100) here? There is an
>>>> mdelay(1) before the return of mx6_dram_cfg() to wait for auto-ZQ
>>>> calibration to complete (I never found a way to determine when it was
>>>> complete via registers).
>>>
>>>
>>> Yes you're right. This udelay can probably be removed (unless I catch
>>> the board misbehaving during multiple resets).
>>
>>
>> Caught the DRAM config failing during multiple resets when udelay(100)
>> is removed, so I guess they stay..
>>
>
> Nikita,
>
> What exactly was failing? Was the subsequent to get_ram_size()
> failing?

Yes.

> If the extra delay is really needed we should add it to the
> mx6_dram_cfg() function. The issue I ran into before I added the
> mdelay(1) there to wait for auto-ZQ calib to complete was that SDRAM
> operations immediately following the call to mx6_dram_cfg() would be
> un-reliable, specifically a memset to 0 would fail to clear memory
> where GD was which caused some interesting failures down the line.

In my case the failures appeared after the board had been operational
long enough for the soc to heat up. I'm curious to hear what kind of
temperatures you tested your board under. If a warm temperature that is
within reasonable limits can cause failures on your board as well, that
would be a clear indication that the 1 msec delay is a borderline value
and needs to be increased.

>
> Maybe I'll open up an issue with Freescale and ask them if there is a
> way to know when auto-ZQ calibration is complete because it isn't
> clear to me how to do that. The 1ms delay was because the 0 value we
> set to MPZQHWCTRL ZQ_HW_PER configures it for a 1ms ZQ calibration
> cycle.... maybe we simply need a little more headroom.

Maybe. If a Freescale representative can provide an analytical reason
like the one you're proposing, that would be great. The question is what
to do if a good explanation is not given. We can simply increase the
mdelay tentatively in mx6_dram_cfg(), or we can keep the udelay() for
cm_fx6 and wait to see if someone else complains. I'm fine with both
options.

>
> Tim
>
diff mbox

Patch

diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c
index d3891dc..219263a 100644
--- a/arch/arm/cpu/armv7/mx6/ddr.c
+++ b/arch/arm/cpu/armv7/mx6/ddr.c
@@ -4,7 +4,6 @@ 
  *
  * SPDX-License-Identifier:     GPL-2.0+
  */
-
 #include <common.h>
 #include <linux/types.h>
 #include <asm/arch/mx6-ddr.h>
diff --git a/board/compulab/cm_fx6/Makefile b/board/compulab/cm_fx6/Makefile
new file mode 100644
index 0000000..3e5c903
--- /dev/null
+++ b/board/compulab/cm_fx6/Makefile
@@ -0,0 +1,12 @@ 
+#
+# (C) Copyright 2014 CompuLab, Ltd. <www.compulab.co.il>
+#
+# Authors: Nikita Kiryanov <nikita@compulab.co.il>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+ifdef CONFIG_SPL_BUILD
+obj-y = common.o spl.o
+else
+obj-y = common.o cm_fx6.o
+endif
diff --git a/board/compulab/cm_fx6/cm_fx6.c b/board/compulab/cm_fx6/cm_fx6.c
new file mode 100644
index 0000000..b55b99e
--- /dev/null
+++ b/board/compulab/cm_fx6/cm_fx6.c
@@ -0,0 +1,108 @@ 
+/*
+ * Board functions for Compulab CM-FX6 board
+ *
+ * Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/
+ *
+ * Author: Nikita Kiryanov <nikita@compulab.co.il>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include "common.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_FSL_ESDHC
+int board_mmc_init(bd_t *bis)
+{
+	int i;
+
+	cm_fx6_set_usdhc_iomux();
+	for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
+		usdhc_cfg[i].sdhc_clk = mxc_get_clock(usdhc_clk[i]);
+		usdhc_cfg[i].max_bus_width = 4;
+		fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
+		enable_usdhc_clk(1, i);
+	}
+
+	return 0;
+}
+#endif
+
+int board_init(void)
+{
+	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
+	return 0;
+}
+
+int checkboard(void)
+{
+	puts("Board: CM-FX6\n");
+	return 0;
+}
+
+static ulong bank1_size;
+static ulong bank2_size;
+
+#define MMDC1_MDCTL 0x21B0000
+static int probe_mmdc_config(void)
+{
+	u32 val = readl(0x21B0000);
+	switch (val) {
+	case 0x83180000: /* DDR_16BIT_256MB */
+		gd->ram_size	= 0x10000000;
+		bank1_size	= 0x10000000;
+		bank2_size	= 0;
+		break;
+	case 0x83190000: /* DDR_32BIT_512MB */
+		gd->ram_size	= 0x20000000;
+		bank1_size	= 0x20000000;
+		bank2_size	= 0;
+		break;
+	case 0xC3190000: /* DDR_32BIT_1GB */
+		gd->ram_size	= 0x40000000;
+		bank1_size	= 0x20000000;
+		bank2_size	= 0x20000000;
+		break;
+	case 0x831A0000: /* DDR_64BIT_1GB */
+		gd->ram_size	= 0x40000000;
+		bank1_size	= 0x40000000;
+		bank2_size	= 0;
+		break;
+	case 0xC31A0000: /* DDR_64BIT_2GB */
+		gd->ram_size	= 0x80000000;
+		bank1_size	= 0x40000000;
+		bank2_size	= 0x40000000;
+		break;
+	case 0xC41A0000: /* DDR_64BIT_4GB */
+		gd->ram_size	= 0xEFF00000;
+		bank1_size	= 0x70000000;
+		bank2_size	= 0x7FF00000;
+		break;
+	default:
+		printf("!!!ERROR!!! Unsupported DRAM configuration: 0x%x\n",
+		       val);
+		return -1;
+	}
+
+	return 0;
+}
+
+void dram_init_banksize(void)
+{
+	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+	gd->bd->bi_dram[0].size = bank1_size;
+	gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
+	gd->bd->bi_dram[1].size = bank2_size;
+}
+
+int dram_init(void)
+{
+	return probe_mmdc_config();
+}
+
+u32 get_board_rev(void)
+{
+	return 100;
+}
diff --git a/board/compulab/cm_fx6/common.c b/board/compulab/cm_fx6/common.c
new file mode 100644
index 0000000..a2d9ca4
--- /dev/null
+++ b/board/compulab/cm_fx6/common.c
@@ -0,0 +1,83 @@ 
+/*
+ * Code used by both U-Boot and SPL for Compulab CM-FX6
+ *
+ * Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/
+ *
+ * Author: Nikita Kiryanov <nikita@compulab.co.il>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/gpio.h>
+#include "common.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_FSL_ESDHC
+#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP |			\
+	PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm |			\
+	PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
+
+static iomux_v3_cfg_t const usdhc_pads[] = {
+	IOMUX_PADS(PAD_SD1_CLK__SD1_CLK    | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD1_CMD__SD1_CMD    | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD1_DAT0__SD1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD1_DAT1__SD1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD1_DAT2__SD1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD1_DAT3__SD1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+
+	IOMUX_PADS(PAD_SD2_CLK__SD2_CLK    | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD2_CMD__SD2_CMD    | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+
+	IOMUX_PADS(PAD_SD3_CLK__SD3_CLK    | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD3_CMD__SD3_CMD    | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD3_DAT4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+	IOMUX_PADS(PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+};
+
+void cm_fx6_set_usdhc_iomux(void)
+{
+	SETUP_IOMUX_PADS(usdhc_pads);
+}
+
+/* CINS bit doesn't work, so always try to access the MMC card */
+int board_mmc_getcd(struct mmc *mmc)
+{
+	return 1;
+}
+#endif
+
+#ifdef CONFIG_MXC_SPI
+#define ECSPI_PAD_CTRL (PAD_CTL_SRE_FAST | PAD_CTL_SPEED_MED | \
+		PAD_CTL_PUS_100K_DOWN | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+
+static iomux_v3_cfg_t const ecspi_pads[] = {
+	IOMUX_PADS(PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(ECSPI_PAD_CTRL)),
+	IOMUX_PADS(PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(ECSPI_PAD_CTRL)),
+	IOMUX_PADS(PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(ECSPI_PAD_CTRL)),
+	IOMUX_PADS(PAD_EIM_EB2__GPIO2_IO30  | MUX_PAD_CTRL(ECSPI_PAD_CTRL)),
+	IOMUX_PADS(PAD_EIM_D19__ECSPI1_SS1  | MUX_PAD_CTRL(ECSPI_PAD_CTRL)),
+};
+
+void cm_fx6_set_ecspi_iomux(void)
+{
+	SETUP_IOMUX_PADS(ecspi_pads);
+}
+
+int board_spi_cs_gpio(unsigned bus, unsigned cs)
+{
+	return (bus == 0 && cs == 0) ? (CM_FX6_ECSPI_BUS0_CS0) : -1;
+}
+#endif
diff --git a/board/compulab/cm_fx6/common.h b/board/compulab/cm_fx6/common.h
new file mode 100644
index 0000000..05eab34
--- /dev/null
+++ b/board/compulab/cm_fx6/common.h
@@ -0,0 +1,36 @@ 
+/*
+ * Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/
+ *
+ * Author: Nikita Kiryanov <nikita@compulab.co.il>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <asm/arch/mx6-pins.h>
+#include <asm/arch/clock.h>
+
+#define UART_PAD_CTRL  (PAD_CTL_PUS_100K_UP |	\
+			PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm |	\
+			PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
+
+#define CM_FX6_ECSPI_BUS0_CS0	IMX_GPIO_NR(2, 30)
+#define CM_FX6_GREEN_LED	IMX_GPIO_NR(2, 31)
+
+#if defined(CONFIG_FSL_ESDHC)
+#include <fsl_esdhc.h>
+
+static __maybe_unused struct fsl_esdhc_cfg usdhc_cfg[3] = {
+	{USDHC1_BASE_ADDR},
+	{USDHC2_BASE_ADDR},
+	{USDHC3_BASE_ADDR},
+};
+
+static __maybe_unused enum mxc_clock usdhc_clk[3] = {
+	MXC_ESDHC_CLK,
+	MXC_ESDHC2_CLK,
+	MXC_ESDHC3_CLK,
+};
+#endif
+
+void cm_fx6_set_usdhc_iomux(void);
+void cm_fx6_set_ecspi_iomux(void);
diff --git a/board/compulab/cm_fx6/imximage.cfg b/board/compulab/cm_fx6/imximage.cfg
new file mode 100644
index 0000000..8e7ec91
--- /dev/null
+++ b/board/compulab/cm_fx6/imximage.cfg
@@ -0,0 +1,8 @@ 
+#
+# Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+IMAGE_VERSION 2
+BOOT_FROM	sd
diff --git a/board/compulab/cm_fx6/spl.c b/board/compulab/cm_fx6/spl.c
new file mode 100644
index 0000000..9f9e5f8
--- /dev/null
+++ b/board/compulab/cm_fx6/spl.c
@@ -0,0 +1,400 @@ 
+/*
+ * SPL specific code for Compulab CM-FX6 board
+ *
+ * Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/
+ *
+ * Author: Nikita Kiryanov <nikita@compulab.co.il>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <asm/arch/mx6-ddr.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/imx-common/iomux-v3.h>
+#include <fsl_esdhc.h>
+#include "common.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum ddr_config {
+	DDR_16BIT_256MB,
+	DDR_32BIT_512MB,
+	DDR_32BIT_1GB,
+	DDR_64BIT_1GB,
+	DDR_64BIT_2GB,
+	DDR_64BIT_4GB,
+	DDR_UNKNOWN,
+};
+
+static void spl_mx6s_dram_setup_iomux(void)
+{
+	struct mx6sdl_iomux_ddr_regs ddr_iomux;
+	struct mx6sdl_iomux_grp_regs grp_iomux;
+
+	ddr_iomux.dram_sdqs0	= 0x00000038;
+	ddr_iomux.dram_sdqs1	= 0x00000038;
+	ddr_iomux.dram_sdqs2	= 0x00000038;
+	ddr_iomux.dram_sdqs3	= 0x00000038;
+	ddr_iomux.dram_sdqs4	= 0x00000038;
+	ddr_iomux.dram_sdqs5	= 0x00000038;
+	ddr_iomux.dram_sdqs6	= 0x00000038;
+	ddr_iomux.dram_sdqs7	= 0x00000038;
+	ddr_iomux.dram_dqm0	= 0x00000038;
+	ddr_iomux.dram_dqm1	= 0x00000038;
+	ddr_iomux.dram_dqm2	= 0x00000038;
+	ddr_iomux.dram_dqm3	= 0x00000038;
+	ddr_iomux.dram_dqm4	= 0x00000038;
+	ddr_iomux.dram_dqm5	= 0x00000038;
+	ddr_iomux.dram_dqm6	= 0x00000038;
+	ddr_iomux.dram_dqm7	= 0x00000038;
+	ddr_iomux.dram_cas	= 0x00000038;
+	ddr_iomux.dram_ras	= 0x00000038;
+	ddr_iomux.dram_sdclk_0	= 0x00000038;
+	ddr_iomux.dram_sdclk_1	= 0x00000038;
+	ddr_iomux.dram_sdcke0	= 0x00003000;
+	ddr_iomux.dram_sdcke1	= 0x00003000;
+	/*
+	 * Below DRAM_RESET[DDR_SEL] = 0 which is incorrect according to
+	 * Freescale QRM, but this is exactly the value used by the automatic
+	 * calibration script and it works also in all our tests, so we leave
+	 * it as is at this point.
+	 */
+	ddr_iomux.dram_reset	= 0x00000038;
+	ddr_iomux.dram_sdba2	= 0x00000000;
+	ddr_iomux.dram_sdodt0	= 0x00000038;
+	ddr_iomux.dram_sdodt1	= 0x00000038;
+	grp_iomux.grp_b0ds	= 0x00000038;
+	grp_iomux.grp_b1ds	= 0x00000038;
+	grp_iomux.grp_b2ds	= 0x00000038;
+	grp_iomux.grp_b3ds	= 0x00000038;
+	grp_iomux.grp_b4ds	= 0x00000038;
+	grp_iomux.grp_b5ds	= 0x00000038;
+	grp_iomux.grp_b6ds	= 0x00000038;
+	grp_iomux.grp_b7ds	= 0x00000038;
+	grp_iomux.grp_addds	= 0x00000038;
+	grp_iomux.grp_ddrmode_ctl = 0x00020000;
+	grp_iomux.grp_ddrpke	= 0x00000000;
+	grp_iomux.grp_ddrmode	= 0x00020000;
+	grp_iomux.grp_ctlds	= 0x00000038;
+	grp_iomux.grp_ddr_type	= 0x000C0000;
+	mx6sdl_dram_iocfg(64, &ddr_iomux, &grp_iomux);
+}
+
+static void spl_mx6q_dram_setup_iomux(void)
+{
+	struct mx6dq_iomux_ddr_regs ddr_iomux;
+	struct mx6dq_iomux_grp_regs grp_iomux;
+
+	ddr_iomux.dram_sdqs0	= 0x00000038;
+	ddr_iomux.dram_sdqs1	= 0x00000038;
+	ddr_iomux.dram_sdqs2	= 0x00000038;
+	ddr_iomux.dram_sdqs3	= 0x00000038;
+	ddr_iomux.dram_sdqs4	= 0x00000038;
+	ddr_iomux.dram_sdqs5	= 0x00000038;
+	ddr_iomux.dram_sdqs6	= 0x00000038;
+	ddr_iomux.dram_sdqs7	= 0x00000038;
+	ddr_iomux.dram_dqm0	= 0x00000038;
+	ddr_iomux.dram_dqm1	= 0x00000038;
+	ddr_iomux.dram_dqm2	= 0x00000038;
+	ddr_iomux.dram_dqm3	= 0x00000038;
+	ddr_iomux.dram_dqm4	= 0x00000038;
+	ddr_iomux.dram_dqm5	= 0x00000038;
+	ddr_iomux.dram_dqm6	= 0x00000038;
+	ddr_iomux.dram_dqm7	= 0x00000038;
+	ddr_iomux.dram_cas	= 0x00000038;
+	ddr_iomux.dram_ras	= 0x00000038;
+	ddr_iomux.dram_sdclk_0	= 0x00000038;
+	ddr_iomux.dram_sdclk_1	= 0x00000038;
+	ddr_iomux.dram_sdcke0	= 0x00003000;
+	ddr_iomux.dram_sdcke1	= 0x00003000;
+	/*
+	 * Below DRAM_RESET[DDR_SEL] = 0 which is incorrect according to
+	 * Freescale QRM, but this is exactly the value used by the automatic
+	 * calibration script and it works also in all our tests, so we leave
+	 * it as is at this point.
+	 */
+	ddr_iomux.dram_reset	= 0x00000038;
+	ddr_iomux.dram_sdba2	= 0x00000000;
+	ddr_iomux.dram_sdodt0	= 0x00000038;
+	ddr_iomux.dram_sdodt1	= 0x00000038;
+	grp_iomux.grp_b0ds	= 0x00000038;
+	grp_iomux.grp_b1ds	= 0x00000038;
+	grp_iomux.grp_b2ds	= 0x00000038;
+	grp_iomux.grp_b3ds	= 0x00000038;
+	grp_iomux.grp_b4ds	= 0x00000038;
+	grp_iomux.grp_b5ds	= 0x00000038;
+	grp_iomux.grp_b6ds	= 0x00000038;
+	grp_iomux.grp_b7ds	= 0x00000038;
+	grp_iomux.grp_addds	= 0x00000038;
+	grp_iomux.grp_ddrmode_ctl = 0x00020000;
+	grp_iomux.grp_ddrpke	= 0x00000000;
+	grp_iomux.grp_ddrmode	= 0x00020000;
+	grp_iomux.grp_ctlds	= 0x00000038;
+	grp_iomux.grp_ddr_type	= 0x000C0000;
+	mx6dq_dram_iocfg(64, &ddr_iomux, &grp_iomux);
+}
+
+static void spl_mx6s_dram_init(enum ddr_config dram_config, int reset)
+{
+	struct mx6_mmdc_calibration calib;
+	struct mx6_ddr_sysinfo sysinfo;
+	struct mx6_ddr3_cfg ddr3_cfg;
+
+	if (reset)
+		((struct mmdc_p_regs *)MX6_MMDC_P0_MDCTL)->mdmisc = 2;
+
+	calib.p0_mpwldectrl0	= 0x005B0061;
+	calib.p0_mpwldectrl1	= 0x004F0055;
+	calib.p0_mpdgctrl0	= 0x0314030C;
+	calib.p0_mpdgctrl1	= 0x025C0268;
+	calib.p0_mprddlctl	= 0x42464646;
+	calib.p0_mpwrdlctl	= 0x36322C34;
+	ddr3_cfg.mem_speed	= 800;
+	ddr3_cfg.density	= 4;
+	ddr3_cfg.rowaddr	= 14;
+	ddr3_cfg.coladdr	= 10;
+	ddr3_cfg.pagesz		= 2;
+	ddr3_cfg.trcd		= 1800;
+	ddr3_cfg.trcmin		= 5200;
+	ddr3_cfg.trasmin	= 3600;
+	ddr3_cfg.SRT		= 0;
+	sysinfo.cs1_mirror	= 1;
+	sysinfo.cs_density	= 16;
+	sysinfo.bi_on		= 1;
+	sysinfo.rtt_nom		= 1;
+	sysinfo.rtt_wr		= 0;
+	sysinfo.ralat		= 5;
+	sysinfo.walat		= 1;
+	sysinfo.mif3_mode	= 3;
+	sysinfo.rst_to_cke	= 0x23;
+	sysinfo.sde_to_rst	= 0x10;
+	switch (dram_config) {
+	case DDR_16BIT_256MB:
+		sysinfo.dsize = 0;
+		sysinfo.ncs = 1;
+		break;
+	case DDR_32BIT_512MB:
+		sysinfo.dsize = 1;
+		sysinfo.ncs = 1;
+		break;
+	case DDR_32BIT_1GB:
+		sysinfo.dsize = 1;
+		sysinfo.ncs = 2;
+		break;
+	default:
+		puts("Tried to setup invalid DDR configuration\n");
+		hang();
+	}
+
+	mx6_dram_cfg(&sysinfo, &calib, &ddr3_cfg);
+	udelay(100);
+}
+
+static void spl_mx6q_dram_init(enum ddr_config dram_config, int reset)
+{
+	struct mx6_mmdc_calibration calib;
+	struct mx6_ddr_sysinfo sysinfo;
+	struct mx6_ddr3_cfg ddr3_cfg;
+
+	if (reset)
+		((struct mmdc_p_regs *)MX6_MMDC_P0_MDCTL)->mdmisc = 2;
+
+	calib.p0_mpwldectrl0	= 0x00630068;
+	calib.p0_mpwldectrl1	= 0x0068005D;
+	calib.p0_mpdgctrl0	= 0x04140428;
+	calib.p0_mpdgctrl1	= 0x037C037C;
+	calib.p0_mprddlctl	= 0x3C30303A;
+	calib.p0_mpwrdlctl	= 0x3A344038;
+	calib.p1_mpwldectrl0	= 0x0035004C;
+	calib.p1_mpwldectrl1	= 0x00170026;
+	calib.p1_mpdgctrl0	= 0x0374037C;
+	calib.p1_mpdgctrl1	= 0x0350032C;
+	calib.p1_mprddlctl	= 0x30322A3C;
+	calib.p1_mpwrdlctl	= 0x48304A3E;
+	ddr3_cfg.mem_speed	= 1066;
+	ddr3_cfg.density	= 4;
+	ddr3_cfg.rowaddr	= 14;
+	ddr3_cfg.coladdr	= 10;
+	ddr3_cfg.pagesz		= 2;
+	ddr3_cfg.trcd		= 1324;
+	ddr3_cfg.trcmin		= 59500;
+	ddr3_cfg.trasmin	= 9750;
+	ddr3_cfg.SRT		= 0;
+	sysinfo.cs_density	= 16;
+	sysinfo.cs1_mirror	= 1;
+	sysinfo.bi_on		= 1;
+	sysinfo.rtt_nom		= 1;
+	sysinfo.rtt_wr		= 0;
+	sysinfo.ralat		= 5;
+	sysinfo.walat		= 1;
+	sysinfo.mif3_mode	= 3;
+	sysinfo.rst_to_cke	= 0x23;
+	sysinfo.sde_to_rst	= 0x10;
+	switch (dram_config) {
+	case DDR_16BIT_256MB:
+		sysinfo.dsize = 0;
+		sysinfo.ncs = 1;
+		break;
+	case DDR_32BIT_512MB:
+		sysinfo.dsize = 1;
+		sysinfo.ncs = 1;
+		break;
+	case DDR_64BIT_1GB:
+		sysinfo.dsize = 2;
+		sysinfo.ncs = 1;
+		break;
+	case DDR_64BIT_2GB:
+		sysinfo.dsize = 2;
+		sysinfo.ncs = 2;
+		break;
+	case DDR_64BIT_4GB:
+		sysinfo.dsize = 2;
+		sysinfo.ncs = 2;
+		ddr3_cfg.rowaddr = 15;
+		break;
+	default:
+		puts("Tried to setup invalid DDR configuration\n");
+		hang();
+	}
+
+	mx6_dram_cfg(&sysinfo, &calib, &ddr3_cfg);
+	udelay(100);
+}
+
+static int cm_fx6_spl_dram_init(void)
+{
+	u32 cpurev, imxtype;
+	unsigned long bank1_size, bank2_size;
+
+	cpurev = get_cpu_rev();
+	imxtype = (cpurev & 0xFF000) >> 12;
+
+	switch (imxtype) {
+	case MXC_CPU_MX6SOLO:
+		spl_mx6s_dram_setup_iomux();
+
+		spl_mx6s_dram_init(DDR_32BIT_1GB, 0);
+		bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000);
+		if (bank1_size == 0x40000000)
+			return 0;
+
+		if (bank1_size == 0x20000000) {
+			spl_mx6s_dram_init(DDR_32BIT_512MB, 1);
+			return 0;
+		}
+
+		spl_mx6s_dram_init(DDR_16BIT_256MB, 1);
+		bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000);
+		if (bank1_size == 0x10000000)
+			return 0;
+
+		break;
+	case MXC_CPU_MX6D:
+	case MXC_CPU_MX6Q:
+		spl_mx6q_dram_setup_iomux();
+
+		spl_mx6q_dram_init(DDR_64BIT_4GB, 0);
+		bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000);
+		if (bank1_size == 0x80000000)
+			return 0;
+
+		if (bank1_size == 0x40000000) {
+			bank2_size = get_ram_size((long int *)PHYS_SDRAM_2,
+								0x80000000);
+			if (bank2_size == 0x40000000) {
+				/* Don't do a full reset here */
+				spl_mx6q_dram_init(DDR_64BIT_2GB, 0);
+			} else {
+				spl_mx6q_dram_init(DDR_64BIT_1GB, 1);
+			}
+
+			return 0;
+		}
+
+		spl_mx6q_dram_init(DDR_32BIT_512MB, 1);
+		bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000);
+		if (bank1_size == 0x20000000)
+			return 0;
+
+		spl_mx6q_dram_init(DDR_16BIT_256MB, 1);
+		bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000);
+		if (bank1_size == 0x10000000)
+			return 0;
+
+		break;
+	}
+
+	return -1;
+}
+
+static iomux_v3_cfg_t const uart4_pads[] = {
+	IOMUX_PADS(PAD_KEY_COL0__UART4_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
+	IOMUX_PADS(PAD_KEY_ROW0__UART4_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
+};
+
+static void cm_fx6_setup_uart(void)
+{
+	SETUP_IOMUX_PADS(uart4_pads);
+	enable_uart_clk(1);
+}
+
+#ifdef CONFIG_SPL_SPI_SUPPORT
+static void cm_fx6_setup_ecspi(void)
+{
+	enable_cspi_clock(1, 0);
+	cm_fx6_set_ecspi_iomux();
+}
+#else
+static void cm_fx6_setup_ecspi(void) { }
+#endif
+
+void board_init_f(ulong dummy)
+{
+	gd = &gdata;
+	enable_usdhc_clk(1, 2);
+	arch_cpu_init();
+	timer_init();
+	cm_fx6_setup_ecspi();
+	cm_fx6_setup_uart();
+	get_clocks();
+	preloader_console_init();
+	gpio_direction_output(CM_FX6_GREEN_LED, 1);
+	if (cm_fx6_spl_dram_init()) {
+		puts("!!!ERROR!!! DRAM detection failed!!!\n");
+		hang();
+	}
+
+	memset(__bss_start, 0, __bss_end - __bss_start);
+	board_init_r(NULL, 0);
+}
+
+void spl_board_init(void)
+{
+	uint soc_sbmr = readl(SRC_BASE_ADDR + 0x4);
+	uint bt_mem_ctl = (soc_sbmr & 0x000000FF) >> 4;
+	uint bt_mem_type = (soc_sbmr & 0x00000008) >> 3;
+
+	if (bt_mem_ctl == 0x3 && !bt_mem_type)
+		puts("Booting from SPI flash\n");
+	else if (bt_mem_ctl == 0x4 || bt_mem_ctl == 0x5)
+		puts("Booting from MMC\n");
+	else
+		puts("Unknown boot device\n");
+}
+
+#ifdef CONFIG_SPL_MMC_SUPPORT
+int board_mmc_init(bd_t *bis)
+{
+	cm_fx6_set_usdhc_iomux();
+
+	usdhc_cfg[2].sdhc_clk = mxc_get_clock(usdhc_clk[2]);
+	usdhc_cfg[2].max_bus_width = 4;
+
+	return fsl_esdhc_initialize(bis, &usdhc_cfg[2]);
+}
+#endif
diff --git a/boards.cfg b/boards.cfg
index e3a0726..308b94e 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -334,6 +334,8 @@  Active  arm         armv7          mx6         freescale       mx6sabresd
 Active  arm         armv7          mx6         freescale       mx6slevk            mx6slevk                              mx6slevk:IMX_CONFIG=board/freescale/mx6slevk/imximage.cfg,MX6SL                                                                   Fabio Estevam <fabio.estevam@freescale.com>
 Active  arm         armv7          mx6         gateworks       gw_ventana          gwventana                             gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6QDL,SPL                                                        Tim Harvey <tharvey@gateworks.com>
 Active  arm         armv7          mx6         solidrun        hummingboard        hummingboard_solo                     hummingboard:IMX_CONFIG=board/solidrun/hummingboard/solo.cfg,MX6S,DDR_MB=512                                                      Jon Nettleton <jon.nettleton@gmail.com>
+Active  arm         armv7          mx6         compulab        cm_fx6              cm_fx6                          
+-                                                                                                                                 Nikita Kiryanov <nikita@compulab.co.il>
 Active  arm         armv7          omap3       -               overo               omap3_overo                           -                                                                                                                                 Steve Sakoman <sakoman@gmail.com>
 Active  arm         armv7          omap3       -               pandora             omap3_pandora                         -                                                                                                                                 Grazvydas Ignotas <notasas@gmail.com>
 Active  arm         armv7          omap3       8dtech          eco5pk              eco5pk                                -                                                                                                                                 Raphael Assenat <raph@8d.com>
diff --git a/include/configs/cm_fx6.h b/include/configs/cm_fx6.h
new file mode 100644
index 0000000..285af33
--- /dev/null
+++ b/include/configs/cm_fx6.h
@@ -0,0 +1,227 @@ 
+/*
+ * Config file for Compulab CM-FX6 board
+ *
+ * Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/
+ *
+ * Author: Nikita Kiryanov <nikita@compulab.co.il>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __CONFIG_CM_FX6_H
+#define __CONFIG_CM_FX6_H
+
+#include <asm/arch/imx-regs.h>
+#include <config_distro_defaults.h>
+
+#define CONFIG_SYS_L2CACHE_OFF
+#include "mx6_common.h"
+
+/* Machine config */
+#define CONFIG_MX6
+#define CONFIG_MX6QDL
+#define CONFIG_CM_FX6
+#define CONFIG_SYS_LITTLE_ENDIAN
+#define CONFIG_MACH_TYPE		4273
+#define CONFIG_SYS_HZ			1000
+
+/* Display information on boot */
+#define CONFIG_DISPLAY_CPUINFO
+#define CONFIG_DISPLAY_BOARDINFO
+#define CONFIG_TIMESTAMP
+
+/* CMD */
+#include <config_cmd_default.h>
+#define CONFIG_CMD_GREPENV
+#undef CONFIG_CMD_FLASH
+#undef CONFIG_CMD_LOADB
+#undef CONFIG_CMD_LOADS
+#undef CONFIG_CMD_XIMG
+#undef CONFIG_CMD_FPGA
+#undef CONFIG_CMD_IMLS
+#undef CONFIG_CMD_NET
+#undef CONFIG_CMD_NFS
+
+/* MMC */
+#define CONFIG_MMC
+#define CONFIG_CMD_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_FSL_ESDHC
+#define CONFIG_FSL_USDHC
+#define CONFIG_SYS_FSL_USDHC_NUM	3
+#define CONFIG_SYS_FSL_ESDHC_ADDR	USDHC2_BASE_ADDR
+
+/* RAM */
+#define PHYS_SDRAM_1			MMDC0_ARB_BASE_ADDR
+#define PHYS_SDRAM_2			MMDC1_ARB_BASE_ADDR
+#define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
+#define CONFIG_NR_DRAM_BANKS		2
+#define CONFIG_SYS_MEMTEST_START	0x10000000
+#define CONFIG_SYS_MEMTEST_END		0x10010000
+#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)
+
+/* Serial console */
+#define CONFIG_MXC_UART
+#define CONFIG_MXC_UART_BASE		UART4_BASE
+#define CONFIG_BAUDRATE			115200
+#define CONFIG_SYS_BAUDRATE_TABLE	{9600, 19200, 38400, 57600, 115200}
+
+/* Shell */
+#define CONFIG_SYS_PROMPT	"CM-FX6 # "
+#define CONFIG_SYS_CBSIZE	1024
+#define CONFIG_SYS_MAXARGS	16
+#define CONFIG_SYS_BARGSIZE	CONFIG_SYS_CBSIZE
+#define CONFIG_SYS_PBSIZE	(CONFIG_SYS_CBSIZE + \
+					sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_MONITOR_LEN	(CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS / 2 * 1024)
+
+/* SPI flash */
+#define CONFIG_SYS_NO_FLASH
+#define CONFIG_CMD_SF
+#define CONFIG_SF_DEFAULT_BUS		0
+#define CONFIG_SF_DEFAULT_CS		0
+#define CONFIG_SF_DEFAULT_SPEED		25000000
+#define CONFIG_SF_DEFAULT_MODE		(SPI_MODE_0)
+
+/* Environment */
+#define CONFIG_ENV_OVERWRITE
+#define CONFIG_ENV_IS_IN_SPI_FLASH
+#define CONFIG_ENV_SPI_MAX_HZ		CONFIG_SF_DEFAULT_SPEED
+#define CONFIG_ENV_SPI_MODE		CONFIG_SF_DEFAULT_MODE
+#define CONFIG_ENV_SPI_BUS		CONFIG_SF_DEFAULT_BUS
+#define CONFIG_ENV_SPI_CS		CONFIG_SF_DEFAULT_CS
+#define CONFIG_ENV_SECT_SIZE		(64 * 1024)
+#define CONFIG_ENV_SIZE			(8 * 1024)
+#define CONFIG_ENV_OFFSET		(768 * 1024)
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"kernel=uImage-cm-fx6\0" \
+	"autoload=no\0" \
+	"loadaddr=0x10800000\0" \
+	"fdtaddr=0x11000000\0" \
+	"console=ttymxc3,115200\0" \
+	"ethprime=FEC0\0" \
+	"bootscr=boot.scr\0" \
+	"bootm_low=18000000\0" \
+	"video_hdmi=mxcfb0:dev=hdmi,1920x1080M-32@50,if=RGB32\0" \
+	"video_dvi=mxcfb0:dev=dvi,1280x800M-32@50,if=RGB32\0" \
+	"fdtfile=cm-fx6.dtb\0" \
+	"doboot=bootm ${loadaddr}\0" \
+	"loadfdt=false\0" \
+	"setboottypez=setenv kernel zImage-cm-fx6;" \
+		"setenv doboot bootz ${loadaddr} - ${fdtaddr};" \
+		"setenv loadfdt true;\0" \
+	"setboottypem=setenv kernel uImage-cm-fx6;" \
+		"setenv doboot bootm ${loadaddr};" \
+		"setenv loadfdt false;\0"\
+	"run_eboot=echo Starting EBOOT ...; "\
+		"mmc dev ${mmcdev} && " \
+		"mmc rescan && mmc read 10042000 a 400 && go 10042000\0" \
+	"mmcdev=2\0" \
+	"mmcroot=/dev/mmcblk0p2 rw rootwait\0" \
+	"loadmmcbootscript=fatload mmc ${mmcdev} ${loadaddr} ${bootscr}\0" \
+	"mmcbootscript=echo Running bootscript from mmc ...; "\
+		"source ${loadaddr}\0" \
+	"mmcargs=setenv bootargs console=${console} " \
+		"root=${mmcroot} " \
+		"${video}\0" \
+	"mmcloadkernel=fatload mmc ${mmcdev} ${loadaddr} ${kernel}\0" \
+	"mmcloadfdt=fatload mmc ${mmcdev} ${fdtaddr} ${fdtfile}\0" \
+	"mmcboot=echo Booting from mmc ...; " \
+		"run mmcargs; " \
+		"run doboot\0" \
+	"nandroot=/dev/mtdblock4 rw\0" \
+	"nandrootfstype=ubifs\0" \
+	"nandargs=setenv bootargs console=${console} " \
+		"root=${nandroot} " \
+		"rootfstype=${nandrootfstype} " \
+		"${video}\0" \
+	"nandloadfdt=nand read ${fdtaddr} 780000 80000;\0" \
+	"nandboot=echo Booting from nand ...; " \
+		"run nandargs; " \
+		"nand read ${loadaddr} 0 780000; " \
+		"if ${loadfdt}; then " \
+			"run nandloadfdt;" \
+		"fi; " \
+		"run doboot\0" \
+	"boot=mmc dev ${mmcdev}; " \
+		"if mmc rescan; then " \
+			"if run loadmmcbootscript; then " \
+				"run mmcbootscript;" \
+			"else " \
+				"if run mmcloadkernel; then " \
+					"if ${loadfdt}; then " \
+						"run mmcloadfdt;" \
+					"fi;" \
+					"run mmcboot;" \
+				"fi;" \
+			"fi;" \
+		"fi;"
+
+#define CONFIG_BOOTCOMMAND \
+	"run setboottypem; run boot"
+
+/* SPI */
+#define CONFIG_SPI
+#define CONFIG_MXC_SPI
+#define CONFIG_SPI_FLASH
+#define CONFIG_SPI_FLASH_ATMEL
+#define CONFIG_SPI_FLASH_EON
+#define CONFIG_SPI_FLASH_GIGADEVICE
+#define CONFIG_SPI_FLASH_MACRONIX
+#define CONFIG_SPI_FLASH_SPANSION
+#define CONFIG_SPI_FLASH_STMICRO
+#define CONFIG_SPI_FLASH_SST
+#define CONFIG_SPI_FLASH_WINBOND
+
+/* GPIO */
+#define CONFIG_MXC_GPIO
+
+/* Boot */
+#define CONFIG_ZERO_BOOTDELAY_CHECK
+#define CONFIG_LOADADDR			0x10800000
+#define CONFIG_SYS_LOAD_ADDR		CONFIG_LOADADDR
+#define CONFIG_SYS_TEXT_BASE		0x10800000
+#define CONFIG_CMDLINE_TAG		/* enable passing of ATAGs */
+#define CONFIG_SYS_BOOTMAPSZ	        (8 << 20)
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_INITRD_TAG
+
+/* misc */
+#define CONFIG_SYS_GENERIC_BOARD
+#define CONFIG_STACKSIZE			(128 * 1024)
+#define CONFIG_SYS_MALLOC_LEN			(2 * 1024 * 1024)
+#define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS	800 /* 400 KB */
+
+/* SPL */
+#define CONFIG_SPL
+#define CONFIG_SPL_FRAMEWORK
+#define CONFIG_SPL_BOARD_INIT
+#define CONFIG_SPL_STACK		0x0091FFB8
+#define CONFIG_SPL_TEXT_BASE		0x00908000
+#define CONFIG_SPL_BSS_START_ADDR	0x18200000
+#define CONFIG_SPL_BSS_MAX_SIZE		0x00100000
+#define CONFIG_SYS_SPL_MALLOC_START	0x18300000
+#define CONFIG_SYS_SPL_MALLOC_SIZE	0x03200000
+#define CONFIG_SPL_MAX_SIZE		(62 * 1024)
+#define CONFIG_SPL_LIBDISK_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_GPIO_SUPPORT
+#define CONFIG_SPL_SERIAL_SUPPORT
+#define CONFIG_SPL_MMC_SUPPORT
+#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR	0x80 /* offset 64 kb */
+#define CONFIG_SPL_SPI_SUPPORT
+#define CONFIG_SPL_SPI_FLASH_SUPPORT
+#define CONFIG_SPL_SPI_BUS		CONFIG_SF_DEFAULT_BUS
+#define CONFIG_SPL_SPI_CS		CONFIG_SF_DEFAULT_CS
+#define CONFIG_SPL_SPI_MODE		CONFIG_SF_DEFAULT_MODE
+#define CONFIG_SYS_SPI_U_BOOT_OFFS	(64 * 1024)
+#define CONFIG_SPL_SPI_LOAD
+
+#endif	/* __CONFIG_CM_FX6_H */