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