10a9b73a1SSimon Glass /* 20a9b73a1SSimon Glass * Copyright (C) 2011 OMICRON electronics GmbH 30a9b73a1SSimon Glass * 40a9b73a1SSimon Glass * based on drivers/mtd/nand/nand_spl_load.c 50a9b73a1SSimon Glass * 60a9b73a1SSimon Glass * Copyright (C) 2011 70a9b73a1SSimon Glass * Heiko Schocher, DENX Software Engineering, hs@denx.de. 80a9b73a1SSimon Glass * 90a9b73a1SSimon Glass * SPDX-License-Identifier: GPL-2.0+ 100a9b73a1SSimon Glass */ 110a9b73a1SSimon Glass 120a9b73a1SSimon Glass #include <common.h> 130a9b73a1SSimon Glass #include <spi.h> 140a9b73a1SSimon Glass #include <spi_flash.h> 150a9b73a1SSimon Glass #include <errno.h> 160a9b73a1SSimon Glass #include <spl.h> 170a9b73a1SSimon Glass 180a9b73a1SSimon Glass #ifdef CONFIG_SPL_OS_BOOT 190a9b73a1SSimon Glass /* 200a9b73a1SSimon Glass * Load the kernel, check for a valid header we can parse, and if found load 210a9b73a1SSimon Glass * the kernel and then device tree. 220a9b73a1SSimon Glass */ 232a2ee2acSSimon Glass static int spi_load_image_os(struct spl_image_info *spl_image, 242a2ee2acSSimon Glass struct spi_flash *flash, 250a9b73a1SSimon Glass struct image_header *header) 260a9b73a1SSimon Glass { 270a9b73a1SSimon Glass int err; 280a9b73a1SSimon Glass 290a9b73a1SSimon Glass /* Read for a header, parse or error out. */ 300a9b73a1SSimon Glass spi_flash_read(flash, CONFIG_SYS_SPI_KERNEL_OFFS, 0x40, 310a9b73a1SSimon Glass (void *)header); 320a9b73a1SSimon Glass 330a9b73a1SSimon Glass if (image_get_magic(header) != IH_MAGIC) 340a9b73a1SSimon Glass return -1; 350a9b73a1SSimon Glass 362a2ee2acSSimon Glass err = spl_parse_image_header(spl_image, header); 370a9b73a1SSimon Glass if (err) 380a9b73a1SSimon Glass return err; 390a9b73a1SSimon Glass 400a9b73a1SSimon Glass spi_flash_read(flash, CONFIG_SYS_SPI_KERNEL_OFFS, 412a2ee2acSSimon Glass spl_image->size, (void *)spl_image->load_addr); 420a9b73a1SSimon Glass 430a9b73a1SSimon Glass /* Read device tree. */ 440a9b73a1SSimon Glass spi_flash_read(flash, CONFIG_SYS_SPI_ARGS_OFFS, 450a9b73a1SSimon Glass CONFIG_SYS_SPI_ARGS_SIZE, 460a9b73a1SSimon Glass (void *)CONFIG_SYS_SPL_ARGS_ADDR); 470a9b73a1SSimon Glass 480a9b73a1SSimon Glass return 0; 490a9b73a1SSimon Glass } 500a9b73a1SSimon Glass #endif 510a9b73a1SSimon Glass 520a9b73a1SSimon Glass static ulong spl_spi_fit_read(struct spl_load_info *load, ulong sector, 530a9b73a1SSimon Glass ulong count, void *buf) 540a9b73a1SSimon Glass { 550a9b73a1SSimon Glass struct spi_flash *flash = load->dev; 560a9b73a1SSimon Glass ulong ret; 570a9b73a1SSimon Glass 580a9b73a1SSimon Glass ret = spi_flash_read(flash, sector, count, buf); 590a9b73a1SSimon Glass if (!ret) 600a9b73a1SSimon Glass return count; 610a9b73a1SSimon Glass else 620a9b73a1SSimon Glass return 0; 630a9b73a1SSimon Glass } 640a9b73a1SSimon Glass /* 650a9b73a1SSimon Glass * The main entry for SPI booting. It's necessary that SDRAM is already 660a9b73a1SSimon Glass * configured and available since this code loads the main U-Boot image 670a9b73a1SSimon Glass * from SPI into SDRAM and starts it from there. 680a9b73a1SSimon Glass */ 692a2ee2acSSimon Glass static int spl_spi_load_image(struct spl_image_info *spl_image, 702a2ee2acSSimon Glass struct spl_boot_device *bootdev) 710a9b73a1SSimon Glass { 720a9b73a1SSimon Glass int err = 0; 730a9b73a1SSimon Glass struct spi_flash *flash; 740a9b73a1SSimon Glass struct image_header *header; 750a9b73a1SSimon Glass 760a9b73a1SSimon Glass /* 770a9b73a1SSimon Glass * Load U-Boot image from SPI flash into RAM 780a9b73a1SSimon Glass */ 790a9b73a1SSimon Glass 800a9b73a1SSimon Glass flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS, 810a9b73a1SSimon Glass CONFIG_SF_DEFAULT_CS, 820a9b73a1SSimon Glass CONFIG_SF_DEFAULT_SPEED, 830a9b73a1SSimon Glass CONFIG_SF_DEFAULT_MODE); 840a9b73a1SSimon Glass if (!flash) { 850a9b73a1SSimon Glass puts("SPI probe failed.\n"); 860a9b73a1SSimon Glass return -ENODEV; 870a9b73a1SSimon Glass } 880a9b73a1SSimon Glass 890a9b73a1SSimon Glass /* use CONFIG_SYS_TEXT_BASE as temporary storage area */ 900a9b73a1SSimon Glass header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); 910a9b73a1SSimon Glass 920a9b73a1SSimon Glass #ifdef CONFIG_SPL_OS_BOOT 932a2ee2acSSimon Glass if (spl_start_uboot() || spi_load_image_os(spl_image, flash, header)) 940a9b73a1SSimon Glass #endif 950a9b73a1SSimon Glass { 960a9b73a1SSimon Glass /* Load u-boot, mkimage header is 64 bytes. */ 970a9b73a1SSimon Glass err = spi_flash_read(flash, CONFIG_SYS_SPI_U_BOOT_OFFS, 0x40, 980a9b73a1SSimon Glass (void *)header); 990a9b73a1SSimon Glass if (err) 1000a9b73a1SSimon Glass return err; 1010a9b73a1SSimon Glass 1020a9b73a1SSimon Glass if (IS_ENABLED(CONFIG_SPL_LOAD_FIT)) { 1030a9b73a1SSimon Glass struct spl_load_info load; 1040a9b73a1SSimon Glass 1050a9b73a1SSimon Glass debug("Found FIT\n"); 1060a9b73a1SSimon Glass load.dev = flash; 1070a9b73a1SSimon Glass load.priv = NULL; 1080a9b73a1SSimon Glass load.filename = NULL; 1090a9b73a1SSimon Glass load.bl_len = 1; 1100a9b73a1SSimon Glass load.read = spl_spi_fit_read; 111*f4d7d859SSimon Glass err = spl_load_simple_fit(spl_image, &load, 1120a9b73a1SSimon Glass CONFIG_SYS_SPI_U_BOOT_OFFS, 1130a9b73a1SSimon Glass header); 1140a9b73a1SSimon Glass } else { 1152a2ee2acSSimon Glass err = spl_parse_image_header(spl_image, header); 1160a9b73a1SSimon Glass if (err) 1170a9b73a1SSimon Glass return err; 1180a9b73a1SSimon Glass err = spi_flash_read(flash, CONFIG_SYS_SPI_U_BOOT_OFFS, 1192a2ee2acSSimon Glass spl_image->size, 1202a2ee2acSSimon Glass (void *)spl_image->load_addr); 1210a9b73a1SSimon Glass } 1220a9b73a1SSimon Glass } 1230a9b73a1SSimon Glass 1240a9b73a1SSimon Glass return err; 1250a9b73a1SSimon Glass } 126139db7afSSimon Glass /* Use priorty 1 so that boards can override this */ 127139db7afSSimon Glass SPL_LOAD_IMAGE_METHOD(1, BOOT_DEVICE_SPI, spl_spi_load_image); 128