1 // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause 2 /* 3 * Copyright (C) 2016 4 * Ladislav Michl <ladis@linux-mips.org> 5 */ 6 7 #include <common.h> 8 #include <config.h> 9 #include <nand.h> 10 #include <onenand_uboot.h> 11 #include <ubispl.h> 12 #include <spl.h> 13 14 int spl_ubi_load_image(struct spl_image_info *spl_image, 15 struct spl_boot_device *bootdev) 16 { 17 struct image_header *header; 18 struct ubispl_info info; 19 struct ubispl_load volumes[2]; 20 int ret = 1; 21 22 switch (bootdev->boot_device) { 23 #ifdef CONFIG_SPL_NAND_SUPPORT 24 case BOOT_DEVICE_NAND: 25 nand_init(); 26 info.read = nand_spl_read_block; 27 info.peb_size = CONFIG_SYS_NAND_BLOCK_SIZE; 28 break; 29 #endif 30 #ifdef CONFIG_SPL_ONENAND_SUPPORT 31 case BOOT_DEVICE_ONENAND: 32 info.read = onenand_spl_read_block; 33 info.peb_size = CONFIG_SYS_ONENAND_BLOCK_SIZE; 34 break; 35 #endif 36 default: 37 goto out; 38 } 39 info.ubi = (struct ubi_scan_info *)CONFIG_SPL_UBI_INFO_ADDR; 40 info.fastmap = IS_ENABLED(CONFIG_MTD_UBI_FASTMAP); 41 42 info.peb_offset = CONFIG_SPL_UBI_PEB_OFFSET; 43 info.vid_offset = CONFIG_SPL_UBI_VID_OFFSET; 44 info.leb_start = CONFIG_SPL_UBI_LEB_START; 45 info.peb_count = CONFIG_SPL_UBI_MAX_PEBS - info.peb_offset; 46 47 #ifdef CONFIG_SPL_OS_BOOT 48 if (!spl_start_uboot()) { 49 volumes[0].vol_id = CONFIG_SPL_UBI_LOAD_KERNEL_ID; 50 volumes[0].load_addr = (void *)CONFIG_SYS_LOAD_ADDR; 51 volumes[1].vol_id = CONFIG_SPL_UBI_LOAD_ARGS_ID; 52 volumes[1].load_addr = (void *)CONFIG_SYS_SPL_ARGS_ADDR; 53 54 ret = ubispl_load_volumes(&info, volumes, 2); 55 if (!ret) { 56 header = (struct image_header *)volumes[0].load_addr; 57 spl_parse_image_header(spl_image, header); 58 puts("Linux loaded.\n"); 59 goto out; 60 } 61 puts("Loading Linux failed, falling back to U-Boot.\n"); 62 } 63 #endif 64 header = (struct image_header *) 65 (CONFIG_SYS_TEXT_BASE - sizeof(struct image_header)); 66 volumes[0].vol_id = CONFIG_SPL_UBI_LOAD_MONITOR_ID; 67 volumes[0].load_addr = (void *)header; 68 69 ret = ubispl_load_volumes(&info, volumes, 1); 70 if (!ret) 71 spl_parse_image_header(spl_image, header); 72 out: 73 #ifdef CONFIG_SPL_NAND_SUPPORT 74 if (bootdev->boot_device == BOOT_DEVICE_NAND) 75 nand_deselect(); 76 #endif 77 return ret; 78 } 79 /* Use priorty 0 so that Ubi will override NAND and ONENAND methods */ 80 SPL_LOAD_IMAGE_METHOD("NAND", 0, BOOT_DEVICE_NAND, spl_ubi_load_image); 81 SPL_LOAD_IMAGE_METHOD("OneNAND", 0, BOOT_DEVICE_ONENAND, spl_ubi_load_image); 82