Booting the i.MX7 Sabre board from the mikroBUS SPI flash

dsc_0199
I’ve been working with the Freescale i.MX7 Sabre board and I wanted to free up the SD card so I could do some SDIO testing. I decided to boot the board from SPI flash ( I needed to test that out anyway ) and then load a kernel and rootfs across the network.

On the i.MX7 board there is a mikroBUS connector which basically just breaks out SPI/I2C/serial and a couple of GPIOs. There is a 8Mb SPI flash that you can get for this bus called the flash click. Just what I needed so I ordered one.

The documentation the board comes with claims the flash chip is a M25P80, no problem u-boot supports that. I added the config below into “include/configs/mx7dsabresd.h” to enable the u-boot SPI flash tools.

#define CONFIG_CMD_SF
#define CONFIG_MXC_SPI

Also enable SPI flash in the defconfig “configs/mx7dsabresd_secure_defconfig”

CONFIG_SPI_FLASH=y

You also need to add some code to your machine initialisation “board/freescale/mx7dsabresd/mx7dsabresd.c” so that the pads get configured properly.

define SPI_PAD_CTRL \
  (PAD_CTL_HYS | PAD_CTL_DSE_3P3V_49OHM | PAD_CTL_SRE_FAST)

static iomux_v3_cfg_t const ecspi3_pads[] = {
  MX7D_PAD_SAI2_RX_DATA__ECSPI3_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL),
  MX7D_PAD_SAI2_TX_SYNC__ECSPI3_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL),
  MX7D_PAD_SAI2_TX_BCLK__ECSPI3_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL),
  MX7D_PAD_SAI2_TX_DATA__GPIO6_IO22 | MUX_PAD_CTRL(NO_PAD_CTRL),
};

int board_spi_cs_gpio(unsigned bus, unsigned cs)
{
       return (bus == 2 && cs == 0) ? (IMX_GPIO_NR(6, 22)) : -1;
}

static void setup_spi(void)
{
       imx_iomux_v3_setup_multiple_pads(ecspi3_pads, ARRAY_SIZE(ecspi3_pads));
}

One more edit to “board/freescale/mx7dsabresd/mx7dsabresd.c” to get the code above called. Into the function board_init add this

#ifdef CONFIG_MXC_SPI
       setup_spi();
#endif

So then I built myself a new u-boot

make mx7dsabresd_secure_defconfig         
CROSS_COMPILE=arm-linux-gnueabihf- make

Now take your newly minted u-boot, burn it to an SD card.

sudo dd if=u-boot.imx of=/dev/mmcblk0 seek=1 bs=1024

and it boots the board

U-Boot 2016.11-rc3-00044-g38cacda-dirty (Nov 09 2016 - 15:59:35 -0700)

CPU:   Freescale i.MX7D rev1.1 996 MHz (running at 792 MHz)
CPU:   Commercial temperature grade (0C to 95C) at 35C
Reset cause: POR
Board: i.MX7D SABRESD in secure mode
I2C:   ready
DRAM:  1 GiB
PMIC: PFUZE3000 DEV_ID=0x30 REV_ID=0x11
MMC:   FSL_SDHC: 0, FSL_SDHC: 1
Video: 480x272x24
In:    serial
Out:   serial
Err:   serial
switch to partitions #0, OK
mmc0 is current device
Net:   FEC0
Hit any key to stop autoboot:  0 
=>

Excellent now I want to scan for the flash chip so that I can burn my new u-boot to it.

=> sf probe 2:0
SF: Unsupported flash IDs: manuf 1c, jedec 3014, ext_jedec 1c30
Failed to initialize SPI flash at 2:0

WTF that’s not the jedec id for a N25P80. So if you go back to the link near the top of the page the mikroBUS flash click actually uses the EN25Q80B which is not in mainline u-boot. Back to the code we go.

Edit “drivers/mtd/spi/sf_params.c” and right after “#ifdef CONFIG_SPI_FLASH_EON /* EON */” add the line below.

  {"EN25Q80B",        0x1c3014, 0x0, 64 * 1024,  16, 0},

You’ll also nee to edit your config again “include/configs/mx7dsabresd.h” and add EON SPI to the configuration.

#define CONFIG_SPI_FLASH_EON

Rebuild it and burn it back to the SD card and try the probe again.

=> sf probe 2:0
SF: Detected EN25Q80B with page size 256 Bytes, erase size 64 KiB, total 1 MiB

So now u-boot can understand the flash, lets erase enough space for u-boot it and flash it.

=> sf erase 0 80000 
SF: 524288 bytes @ 0x0 Erased: OK
=> mmc read 0x80000000 2 400

MMC read: dev # 0, block # 2, count 1024 ... 1024 blocks read: OK
=> sf write 0x80000000 400 80000
device 0 offset 0x400, size 0x80000
SF: 524288 bytes @ 0x400 Written: OK

Now set the jumpers to boot from the SPI flash, remove the SD card and reset the board.dsc_0201

Here’s the mikroBUS flash click patch that should apply to mainline u-boot.