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