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 */ 230a9b73a1SSimon Glass static int spi_load_image_os(struct spi_flash *flash, 240a9b73a1SSimon Glass struct image_header *header) 250a9b73a1SSimon Glass { 260a9b73a1SSimon Glass int err; 270a9b73a1SSimon Glass 280a9b73a1SSimon Glass /* Read for a header, parse or error out. */ 290a9b73a1SSimon Glass spi_flash_read(flash, CONFIG_SYS_SPI_KERNEL_OFFS, 0x40, 300a9b73a1SSimon Glass (void *)header); 310a9b73a1SSimon Glass 320a9b73a1SSimon Glass if (image_get_magic(header) != IH_MAGIC) 330a9b73a1SSimon Glass return -1; 340a9b73a1SSimon Glass 350a9b73a1SSimon Glass err = spl_parse_image_header(&spl_image, header); 360a9b73a1SSimon Glass if (err) 370a9b73a1SSimon Glass return err; 380a9b73a1SSimon Glass 390a9b73a1SSimon Glass spi_flash_read(flash, CONFIG_SYS_SPI_KERNEL_OFFS, 400a9b73a1SSimon Glass spl_image.size, (void *)spl_image.load_addr); 410a9b73a1SSimon Glass 420a9b73a1SSimon Glass /* Read device tree. */ 430a9b73a1SSimon Glass spi_flash_read(flash, CONFIG_SYS_SPI_ARGS_OFFS, 440a9b73a1SSimon Glass CONFIG_SYS_SPI_ARGS_SIZE, 450a9b73a1SSimon Glass (void *)CONFIG_SYS_SPL_ARGS_ADDR); 460a9b73a1SSimon Glass 470a9b73a1SSimon Glass return 0; 480a9b73a1SSimon Glass } 490a9b73a1SSimon Glass #endif 500a9b73a1SSimon Glass 510a9b73a1SSimon Glass static ulong spl_spi_fit_read(struct spl_load_info *load, ulong sector, 520a9b73a1SSimon Glass ulong count, void *buf) 530a9b73a1SSimon Glass { 540a9b73a1SSimon Glass struct spi_flash *flash = load->dev; 550a9b73a1SSimon Glass ulong ret; 560a9b73a1SSimon Glass 570a9b73a1SSimon Glass ret = spi_flash_read(flash, sector, count, buf); 580a9b73a1SSimon Glass if (!ret) 590a9b73a1SSimon Glass return count; 600a9b73a1SSimon Glass else 610a9b73a1SSimon Glass return 0; 620a9b73a1SSimon Glass } 630a9b73a1SSimon Glass /* 640a9b73a1SSimon Glass * The main entry for SPI booting. It's necessary that SDRAM is already 650a9b73a1SSimon Glass * configured and available since this code loads the main U-Boot image 660a9b73a1SSimon Glass * from SPI into SDRAM and starts it from there. 670a9b73a1SSimon Glass */ 68*139db7afSSimon Glass static int spl_spi_load_image(struct spl_boot_device *bootdev) 690a9b73a1SSimon Glass { 700a9b73a1SSimon Glass int err = 0; 710a9b73a1SSimon Glass struct spi_flash *flash; 720a9b73a1SSimon Glass struct image_header *header; 730a9b73a1SSimon Glass 740a9b73a1SSimon Glass /* 750a9b73a1SSimon Glass * Load U-Boot image from SPI flash into RAM 760a9b73a1SSimon Glass */ 770a9b73a1SSimon Glass 780a9b73a1SSimon Glass flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS, 790a9b73a1SSimon Glass CONFIG_SF_DEFAULT_CS, 800a9b73a1SSimon Glass CONFIG_SF_DEFAULT_SPEED, 810a9b73a1SSimon Glass CONFIG_SF_DEFAULT_MODE); 820a9b73a1SSimon Glass if (!flash) { 830a9b73a1SSimon Glass puts("SPI probe failed.\n"); 840a9b73a1SSimon Glass return -ENODEV; 850a9b73a1SSimon Glass } 860a9b73a1SSimon Glass 870a9b73a1SSimon Glass /* use CONFIG_SYS_TEXT_BASE as temporary storage area */ 880a9b73a1SSimon Glass header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); 890a9b73a1SSimon Glass 900a9b73a1SSimon Glass #ifdef CONFIG_SPL_OS_BOOT 910a9b73a1SSimon Glass if (spl_start_uboot() || spi_load_image_os(flash, header)) 920a9b73a1SSimon Glass #endif 930a9b73a1SSimon Glass { 940a9b73a1SSimon Glass /* Load u-boot, mkimage header is 64 bytes. */ 950a9b73a1SSimon Glass err = spi_flash_read(flash, CONFIG_SYS_SPI_U_BOOT_OFFS, 0x40, 960a9b73a1SSimon Glass (void *)header); 970a9b73a1SSimon Glass if (err) 980a9b73a1SSimon Glass return err; 990a9b73a1SSimon Glass 1000a9b73a1SSimon Glass if (IS_ENABLED(CONFIG_SPL_LOAD_FIT)) { 1010a9b73a1SSimon Glass struct spl_load_info load; 1020a9b73a1SSimon Glass 1030a9b73a1SSimon Glass debug("Found FIT\n"); 1040a9b73a1SSimon Glass load.dev = flash; 1050a9b73a1SSimon Glass load.priv = NULL; 1060a9b73a1SSimon Glass load.filename = NULL; 1070a9b73a1SSimon Glass load.bl_len = 1; 1080a9b73a1SSimon Glass load.read = spl_spi_fit_read; 1090a9b73a1SSimon Glass err = spl_load_simple_fit(&load, 1100a9b73a1SSimon Glass CONFIG_SYS_SPI_U_BOOT_OFFS, 1110a9b73a1SSimon Glass header); 1120a9b73a1SSimon Glass } else { 1130a9b73a1SSimon Glass err = spl_parse_image_header(&spl_image, header); 1140a9b73a1SSimon Glass if (err) 1150a9b73a1SSimon Glass return err; 1160a9b73a1SSimon Glass err = spi_flash_read(flash, CONFIG_SYS_SPI_U_BOOT_OFFS, 1170a9b73a1SSimon Glass spl_image.size, 1180a9b73a1SSimon Glass (void *)spl_image.load_addr); 1190a9b73a1SSimon Glass } 1200a9b73a1SSimon Glass } 1210a9b73a1SSimon Glass 1220a9b73a1SSimon Glass return err; 1230a9b73a1SSimon Glass } 124*139db7afSSimon Glass /* Use priorty 1 so that boards can override this */ 125*139db7afSSimon Glass SPL_LOAD_IMAGE_METHOD(1, BOOT_DEVICE_SPI, spl_spi_load_image); 126