1*4882a593SmuzhiyunLightweight UBI and UBI fastmap support 2*4882a593Smuzhiyun 3*4882a593Smuzhiyun# Copyright (C) Thomas Gleixner <tglx@linutronix.de> 4*4882a593Smuzhiyun# 5*4882a593Smuzhiyun# SPDX-License-Identifier: GPL 2.0+ BSD-3-Clause 6*4882a593Smuzhiyun 7*4882a593SmuzhiyunScans the UBI information and loads the requested static volumes into 8*4882a593Smuzhiyunmemory. 9*4882a593Smuzhiyun 10*4882a593SmuzhiyunConfiguration Options: 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun CONFIG_SPL_UBI 13*4882a593Smuzhiyun Enables the SPL UBI support 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun CONFIG_SPL_UBI_MAX_VOL_LEBS 16*4882a593Smuzhiyun The maximum number of logical eraseblocks which a static volume 17*4882a593Smuzhiyun to load can contain. Used for sizing the scan data structure 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun CONFIG_SPL_UBI_MAX_PEB_SIZE 20*4882a593Smuzhiyun The maximum physical erase block size. Either a compile time 21*4882a593Smuzhiyun constant or runtime detection. Used for sizing the scan data 22*4882a593Smuzhiyun structure 23*4882a593Smuzhiyun 24*4882a593Smuzhiyun CONFIG_SPL_UBI_MAX_PEBS 25*4882a593Smuzhiyun The maximum physical erase block count. Either a compile time 26*4882a593Smuzhiyun constant or runtime detection. Used for sizing the scan data 27*4882a593Smuzhiyun structure 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun CONFIG_SPL_UBI_VOL_IDS 30*4882a593Smuzhiyun The maximum volume ids which can be loaded. Used for sizing the 31*4882a593Smuzhiyun scan data structure. 32*4882a593Smuzhiyun 33*4882a593SmuzhiyunUsage notes: 34*4882a593Smuzhiyun 35*4882a593SmuzhiyunIn the board config file define for example: 36*4882a593Smuzhiyun 37*4882a593Smuzhiyun#define CONFIG_SPL_UBI 38*4882a593Smuzhiyun#define CONFIG_SPL_UBI_MAX_VOL_LEBS 256 39*4882a593Smuzhiyun#define CONFIG_SPL_UBI_MAX_PEB_SIZE (256*1024) 40*4882a593Smuzhiyun#define CONFIG_SPL_UBI_MAX_PEBS 4096 41*4882a593Smuzhiyun#define CONFIG_SPL_UBI_VOL_IDS 8 42*4882a593Smuzhiyun 43*4882a593SmuzhiyunThe size requirement is roughly as follows: 44*4882a593Smuzhiyun 45*4882a593Smuzhiyun 2k for the basic data structure 46*4882a593Smuzhiyun + CONFIG_SPL_UBI_VOL_IDS * CONFIG_SPL_UBI_MAX_VOL_LEBS * 8 47*4882a593Smuzhiyun + CONFIG_SPL_UBI_MAX_PEBS * 64 48*4882a593Smuzhiyun + CONFIG_SPL_UBI_MAX_PEB_SIZE * UBI_FM_MAX_BLOCKS 49*4882a593Smuzhiyun 50*4882a593SmuzhiyunThe last one is big, but I really don't care in that stage. Real world 51*4882a593Smuzhiyunimplementations only use the first couple of blocks, but the code 52*4882a593Smuzhiyunhandles up to UBI_FM_MAX_BLOCKS. 53*4882a593Smuzhiyun 54*4882a593SmuzhiyunGiven the above configuration example the requirement is about 5M 55*4882a593Smuzhiyunwhich is usually not a problem to reserve in the RAM along with the 56*4882a593Smuzhiyunother areas like the kernel/dts load address. 57*4882a593Smuzhiyun 58*4882a593SmuzhiyunSo something like this will do the trick: 59*4882a593Smuzhiyun 60*4882a593Smuzhiyun#define SPL_FINFO_ADDR 0x80800000 61*4882a593Smuzhiyun#define SPL_DTB_LOAD_ADDR 0x81800000 62*4882a593Smuzhiyun#define SPL_KERNEL_LOAD_ADDR 0x82000000 63*4882a593Smuzhiyun 64*4882a593SmuzhiyunIn the board file, implement the following: 65*4882a593Smuzhiyun 66*4882a593Smuzhiyunstatic struct ubispl_load myvolumes[] = { 67*4882a593Smuzhiyun { 68*4882a593Smuzhiyun .vol_id = 0, /* kernel volume */ 69*4882a593Smuzhiyun .load_addr = (void *)SPL_KERNEL_LOAD_ADDR, 70*4882a593Smuzhiyun }, 71*4882a593Smuzhiyun { 72*4882a593Smuzhiyun .vol_id = 1, /* DT blob */ 73*4882a593Smuzhiyun .load_addr = (void *)SPL_DTB_LOAD_ADDR, 74*4882a593Smuzhiyun } 75*4882a593Smuzhiyun}; 76*4882a593Smuzhiyun 77*4882a593Smuzhiyunint spl_start_uboot(void) 78*4882a593Smuzhiyun{ 79*4882a593Smuzhiyun struct ubispl_info info; 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun info.ubi = (struct ubi_scan_info *) SPL_FINFO_ADDR; 82*4882a593Smuzhiyun info.fastmap = 1; 83*4882a593Smuzhiyun info.read = nand_spl_read_flash; 84*4882a593Smuzhiyun 85*4882a593Smuzhiyun#if COMPILE_TIME_DEFINED 86*4882a593Smuzhiyun /* 87*4882a593Smuzhiyun * MY_NAND_NR_SPL_PEBS is the number of physical erase blocks 88*4882a593Smuzhiyun * in the FLASH which are reserved for the SPL. Think about 89*4882a593Smuzhiyun * mtd partitions: 90*4882a593Smuzhiyun * 91*4882a593Smuzhiyun * part_spl { .start = 0, .end = 4 } 92*4882a593Smuzhiyun * part_ubi { .start = 4, .end = NR_PEBS } 93*4882a593Smuzhiyun */ 94*4882a593Smuzhiyun info.peb_offset = MY_NAND_NR_SPL_PEBS; 95*4882a593Smuzhiyun info.peb_size = CONFIG_SYS_NAND_BLOCK_SIZE; 96*4882a593Smuzhiyun info.vid_offset = MY_NAND_UBI_VID_OFFS; 97*4882a593Smuzhiyun info.leb_start = MY_NAND_UBI_DATA_OFFS; 98*4882a593Smuzhiyun info.peb_count = MY_NAND_UBI_NUM_PEBS; 99*4882a593Smuzhiyun#else 100*4882a593Smuzhiyun get_flash_info(&flash_info); 101*4882a593Smuzhiyun info.peb_offset = MY_NAND_NR_SPL_PEBS; 102*4882a593Smuzhiyun info.peb_size = flash_info.peb_size; 103*4882a593Smuzhiyun 104*4882a593Smuzhiyun /* 105*4882a593Smuzhiyun * The VID and Data offset depend on the capability of the 106*4882a593Smuzhiyun * FLASH chip to do subpage writes. 107*4882a593Smuzhiyun * 108*4882a593Smuzhiyun * If the flash chip supports subpage writes, then the VID 109*4882a593Smuzhiyun * header starts at the second subpage. So for 2k pages size 110*4882a593Smuzhiyun * with 4 subpages the VID offset is 512. The DATA offset is 2k. 111*4882a593Smuzhiyun * 112*4882a593Smuzhiyun * If the flash chip does not support subpage writes then the 113*4882a593Smuzhiyun * VID offset is FLASH_PAGE_SIZE and the DATA offset 114*4882a593Smuzhiyun * 2 * FLASH_PAGE_SIZE 115*4882a593Smuzhiyun */ 116*4882a593Smuzhiyun info.vid_offset = flash_info.vid_offset; 117*4882a593Smuzhiyun info.leb_start = flash_info.data_offset; 118*4882a593Smuzhiyun 119*4882a593Smuzhiyun /* 120*4882a593Smuzhiyun * The flash reports the total number of erase blocks, so 121*4882a593Smuzhiyun * we need to subtract the number of blocks which are reserved 122*4882a593Smuzhiyun * for the SPL itself and not managed by UBI. 123*4882a593Smuzhiyun */ 124*4882a593Smuzhiyun info.peb_count = flash_info.peb_count - MY_NAND_NR_SPL_PEBS; 125*4882a593Smuzhiyun#endif 126*4882a593Smuzhiyun 127*4882a593Smuzhiyun ret = ubispl_load_volumes(&info, myvolumes, ARRAY_SIZE(myvolumes); 128*4882a593Smuzhiyun 129*4882a593Smuzhiyun .... 130*4882a593Smuzhiyun 131*4882a593Smuzhiyun} 132*4882a593Smuzhiyun 133*4882a593SmuzhiyunNote: you can load any payload that way. You can even load u-boot from 134*4882a593SmuzhiyunUBI, so the only non UBI managed FLASH area is the one which is 135*4882a593Smuzhiyunreserved for the SPL itself and read from the SoC ROM. 136*4882a593Smuzhiyun 137*4882a593SmuzhiyunAnd you can do fallback scenarios: 138*4882a593Smuzhiyun 139*4882a593Smuzhiyun if (ubispl_load_volumes(&info, volumes0, ARRAY_SIZE(volumes0))) 140*4882a593Smuzhiyun if (ubispl_load_volumes(&info, volumes1, ARRAY_SIZE(volumes1))) 141*4882a593Smuzhiyun ubispl_load_volumes(&info, vol_uboot, ARRAY_SIZE(vol_uboot)); 142