uboot/common/spl/spl_spi.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2011 OMICRON electronics GmbH
   3 *
   4 * based on drivers/mtd/nand/nand_spl_load.c
   5 *
   6 * Copyright (C) 2011
   7 * Heiko Schocher, DENX Software Engineering, hs@denx.de.
   8 *
   9 * SPDX-License-Identifier:     GPL-2.0+
  10 */
  11
  12#include <common.h>
  13#include <spi.h>
  14#include <spi_flash.h>
  15#include <errno.h>
  16#include <spl.h>
  17
  18#ifdef CONFIG_SPL_OS_BOOT
  19/*
  20 * Load the kernel, check for a valid header we can parse, and if found load
  21 * the kernel and then device tree.
  22 */
  23static int spi_load_image_os(struct spl_image_info *spl_image,
  24                             struct spi_flash *flash,
  25                             struct image_header *header)
  26{
  27        int err;
  28
  29        /* Read for a header, parse or error out. */
  30        spi_flash_read(flash, CONFIG_SYS_SPI_KERNEL_OFFS, 0x40,
  31                       (void *)header);
  32
  33        if (image_get_magic(header) != IH_MAGIC)
  34                return -1;
  35
  36        err = spl_parse_image_header(spl_image, header);
  37        if (err)
  38                return err;
  39
  40        spi_flash_read(flash, CONFIG_SYS_SPI_KERNEL_OFFS,
  41                       spl_image->size, (void *)spl_image->load_addr);
  42
  43        /* Read device tree. */
  44        spi_flash_read(flash, CONFIG_SYS_SPI_ARGS_OFFS,
  45                       CONFIG_SYS_SPI_ARGS_SIZE,
  46                       (void *)CONFIG_SYS_SPL_ARGS_ADDR);
  47
  48        return 0;
  49}
  50#endif
  51
  52static ulong spl_spi_fit_read(struct spl_load_info *load, ulong sector,
  53                              ulong count, void *buf)
  54{
  55        struct spi_flash *flash = load->dev;
  56        ulong ret;
  57
  58        ret = spi_flash_read(flash, sector, count, buf);
  59        if (!ret)
  60                return count;
  61        else
  62                return 0;
  63}
  64/*
  65 * The main entry for SPI booting. It's necessary that SDRAM is already
  66 * configured and available since this code loads the main U-Boot image
  67 * from SPI into SDRAM and starts it from there.
  68 */
  69static int spl_spi_load_image(struct spl_image_info *spl_image,
  70                              struct spl_boot_device *bootdev)
  71{
  72        int err = 0;
  73        struct spi_flash *flash;
  74        struct image_header *header;
  75
  76        /*
  77         * Load U-Boot image from SPI flash into RAM
  78         */
  79
  80        flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
  81                                CONFIG_SF_DEFAULT_CS,
  82                                CONFIG_SF_DEFAULT_SPEED,
  83                                CONFIG_SF_DEFAULT_MODE);
  84        if (!flash) {
  85                puts("SPI probe failed.\n");
  86                return -ENODEV;
  87        }
  88
  89        /* use CONFIG_SYS_TEXT_BASE as temporary storage area */
  90        header = (struct image_header *)(CONFIG_SYS_TEXT_BASE);
  91
  92#ifdef CONFIG_SPL_OS_BOOT
  93        if (spl_start_uboot() || spi_load_image_os(spl_image, flash, header))
  94#endif
  95        {
  96                /* Load u-boot, mkimage header is 64 bytes. */
  97                err = spi_flash_read(flash, CONFIG_SYS_SPI_U_BOOT_OFFS, 0x40,
  98                                     (void *)header);
  99                if (err) {
 100                        debug("%s: Failed to read from SPI flash (err=%d)\n",
 101                              __func__, err);
 102                        return err;
 103                }
 104
 105                if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
 106                        image_get_magic(header) == FDT_MAGIC) {
 107                        struct spl_load_info load;
 108
 109                        debug("Found FIT\n");
 110                        load.dev = flash;
 111                        load.priv = NULL;
 112                        load.filename = NULL;
 113                        load.bl_len = 1;
 114                        load.read = spl_spi_fit_read;
 115                        err = spl_load_simple_fit(spl_image, &load,
 116                                                  CONFIG_SYS_SPI_U_BOOT_OFFS,
 117                                                  header);
 118                } else {
 119                        err = spl_parse_image_header(spl_image, header);
 120                        if (err)
 121                                return err;
 122                        err = spi_flash_read(flash, CONFIG_SYS_SPI_U_BOOT_OFFS,
 123                                             spl_image->size,
 124                                             (void *)spl_image->load_addr);
 125                }
 126        }
 127
 128        return err;
 129}
 130/* Use priorty 1 so that boards can override this */
 131SPL_LOAD_IMAGE_METHOD("SPI", 1, BOOT_DEVICE_SPI, spl_spi_load_image);
 132