[U-Boot] [PATCH v2] sunxi: Support booting from SPI flash

Simon Glass sjg at chromium.org
Fri Jun 10 18:44:44 CEST 2016


On 9 June 2016 at 22:28, Siarhei Siamashka <siarhei.siamashka at gmail.com> wrote:
> On Thu, 9 Jun 2016 19:42:55 -0700
> Simon Glass <sjg at chromium.org> wrote:
>
>> Hi,
>>
>> On 9 June 2016 at 18:33, Siarhei Siamashka <siarhei.siamashka at gmail.com> wrote:
>> > Hi Simon,
>> >
>> > On Thu, 9 Jun 2016 17:36:10 -0700
>> > Simon Glass <sjg at chromium.org> wrote:
>> >
>> >> Hi,
>> >>
>> >> On 7 June 2016 at 05:28, Siarhei Siamashka <siarhei.siamashka at gmail.com> wrote:
>> >> > Allwinner devices support SPI flash as one of the possible
>> >> > bootable media type. The SPI flash chip needs to be connected
>> >> > to SPI0 pins (port C) to make this work. More information is
>> >> > available at:
>> >> >
>> >> >     https://linux-sunxi.org/Bootable_SPI_flash
>> >> >
>> >> > This patch adds the initial support for booting from SPI flash.
>> >> > The existing SPI frameworks are not used in order to reduce the
>> >> > SPL code size. Right now the SPL size grows by ~370 bytes when
>> >> > CONFIG_SPL_SPI_SUNXI option is enabled.
>> >> >
>> >> > While there are no popular Allwinner devices with SPI flash at
>> >> > the moment, testing can be done using a SPI flash module (it
>> >> > can be bought for ~2$ on ebay) and jumper wires with the boards,
>> >> > which expose relevant pins on the expansion header. The SPI flash
>> >> > chips themselves are very cheap (some prices are even listed as
>> >> > low as 4 cents) and should not cost much if somebody decides to
>> >> > design a development board with an SPI flash chip soldered on
>> >> > the PCB.
>> >> >
>> >> > Another nice feature of the SPI flash is that it can be safely
>> >> > accessed in a device-independent way (since we know that the
>> >> > boot ROM is already probing these pins during the boot time).
>> >> > And if, for example, Olimex boards opted to use SPI flash instead
>> >> > of EEPROM, then they would have been able to have U-Boot installed
>> >> > in the SPI flash now and boot the rest of the system from the SATA
>> >> > hard drive. Hopefully we may see new interesting Allwinner based
>> >> > development boards in the future, now that the software support
>> >> > for the SPI flash is in a better shape :-)
>> >> >
>> >> > Testing can be done by enabling the CONFIG_SPL_SPI_SUNXI option
>> >> > in a board defconfig, then building U-Boot and finally flashing
>> >> > the resulting u-boot-sunxi-with-spl.bin binary over USB OTG with
>> >> > a help of the sunxi-fel tool:
>> >> >
>> >> >    sunxi-fel spiflash-write 0 u-boot-sunxi-with-spl.bin
>> >> >
>> >> > The device needs to be switched into FEL (USB recovery) mode first.
>> >> > The most suitable boards for testing are Orange Pi PC and Pine64.
>> >> > Because these boards are cheap, have no built-in NAND/eMMC and
>> >> > expose SPI0 pins on the Raspberry Pi compatible expansion header.
>> >> > The A13-OLinuXino-Micro board also can be used.
>> >> >
>> >> > Signed-off-by: Siarhei Siamashka <siarhei.siamashka at gmail.com>
>> >> > ---
>> >> >
>> >> > Changes in v2:
>> >> >  - Add Kconfig option (CONFIG_SPL_SPI_SUNXI) and move the SPI flash
>> >> >    support code into a separate source file
>> >> >  - Use CONFIG_SYS_SPI_U_BOOT_OFFS instead of the hardcoded constant
>> >> >  - Deinitialize the SPI controller and undo pin muxing after the job
>> >> >    is done
>> >> >  - Size reduction of the SPI transfer function
>> >> >  - Add delay after each SPI transfer to ensure that the chip select
>> >> >    deassert timing requirements (tSHSL) are always satisfied
>> >> >  - More comments in the code
>> >> >
>> >> >
>> >> >  arch/arm/include/asm/arch-sunxi/gpio.h |   3 +
>> >> >  arch/arm/mach-sunxi/board.c            |   5 +
>> >> >  common/spl/spl.c                       |   4 +-
>> >> >  drivers/mtd/spi/Kconfig                |  12 ++
>> >> >  drivers/mtd/spi/Makefile               |   1 +
>> >> >  drivers/mtd/spi/sunxi_spi_spl.c        | 283 +++++++++++++++++++++++++++++++++
>> >> >  include/configs/sunxi-common.h         |   5 +
>> >> >  7 files changed, 311 insertions(+), 2 deletions(-)
>> >> >  create mode 100644 drivers/mtd/spi/sunxi_spi_spl.c
>> >>
>> >> Shouldn't this be a normal SPI driver? Then you could put this in
>> >> common/spl/spl_spi.c.
>> >
>> > This source file contains both a sunxi SPI controller support and a
>> > basic SPI flash read functionality glued together for size reduction
>> > purposes.
>> >
>> > We are interested in implementing the "spl_spi_load_image()" function,
>> > because this is what gets called when handling the BOOT_DEVICE_SPI
>> > case.
>> >
>> > The "drivers/mtd/spi" directory contains the "spi_spl_load.c" file,
>> > which implements this particular function with the help of the generic
>> > SPI flash support code from "spi_flash.c" and the generic SPI bus
>> > support provided by the code from the "drivers/spi" directory.
>> >
>> > What I'm doing in this patch is an implementation of a size reduced
>> > sunxi-specific replacement for "spi_spl_load.c". But in U-Boot proper
>> > (where the code size is not a problem anymore) we will need a real
>> > sunxi SPI driver.
>>
>> OK I see, fair enough.
>>
>> Do you know how much space this saves? I'm actually not sure how much
>> overhead the SPI flash layer adds.
>
> I don't have a DM based SPI driver for sunxi yet. But I tried to
> disable SPI flash on some other boards and check the SPL size
> reduction. I don't remember what kind of board it was before, but
> the size was reduced by several kilobytes. Now tried it again with
> the "spring_defconfig" build:
>
> == normal build ==
>
>    text    data     bss     dec     hex filename
>   11796    1260       0   13056    3300 spl/u-boot-spl
>
> == spi flash disabled ==
>
>    text    data     bss     dec     hex filename
>    6812    1052       0    7864    1eb8 spl/u-boot-spl
>
> My changes in "include/configs/exynos5-dt-common.h" to disable SPI
> flash:
>
> -#define CONFIG_ENV_IS_IN_SPI_FLASH
> +#define CONFIG_ENV_IS_IN_MMC
> +/*
>  #define CONFIG_ENV_SPI_BASE    0x12D30000
>  #define FLASH_SIZE             (4 << 20)
>  #define CONFIG_ENV_OFFSET      (FLASH_SIZE - CONFIG_ENV_SECT_SIZE)
>  #define CONFIG_SPI_BOOTING
> +*/
>
> Yes, this was not a very clean experiment. But still ~5K looks
> significantly larger than ~400 bytes.
>
>
> For comparison, building "Cubieboard_defconfig" from the current
> master branch (6b3943f1b04be60f147ee540fbd72c4c7ea89f80) results
> in the following SPL sizes, depending on the GCC version:
>
> === GCC 4.7 ===
>    text    data     bss     dec     hex filename
>   21743     640     256   22639    586f spl/u-boot-spl
>
> === GCC 4.9 ===
>    text    data     bss     dec     hex filename
>   21667     640     256   22563    5823 spl/u-boot-spl
>
> === GCC 5.3 ===
>    text    data     bss     dec     hex filename
>   21571     640     256   22467    57c3 spl/u-boot-spl
>
> === GCC 6.1 ===
>    text    data     bss     dec     hex filename
>   18406     640     256   19302    4b66 spl/u-boot-spl
>
> Please note that NAND and FIT are still not enabled, though
> CONFIG_USE_TINY_PRINTF is not enabled either. And 24 KiB is
> the size limit for the SPL, enforced by the boot ROM.

Nice work.

Reviewed-by: Simon Glass <sjg at chromium.org>

(I'm not a fan of the *********** in comments but will leave that to
Hans to decide)


More information about the U-Boot mailing list