18c2ecf20Sopenharmony_ci===================================== 28c2ecf20Sopenharmony_ciMTD NAND Driver Programming Interface 38c2ecf20Sopenharmony_ci===================================== 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci:Author: Thomas Gleixner 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ciIntroduction 88c2ecf20Sopenharmony_ci============ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ciThe generic NAND driver supports almost all NAND and AG-AND based chips 118c2ecf20Sopenharmony_ciand connects them to the Memory Technology Devices (MTD) subsystem of 128c2ecf20Sopenharmony_cithe Linux Kernel. 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ciThis documentation is provided for developers who want to implement 158c2ecf20Sopenharmony_ciboard drivers or filesystem drivers suitable for NAND devices. 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ciKnown Bugs And Assumptions 188c2ecf20Sopenharmony_ci========================== 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ciNone. 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ciDocumentation hints 238c2ecf20Sopenharmony_ci=================== 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ciThe function and structure docs are autogenerated. Each function and 268c2ecf20Sopenharmony_cistruct member has a short description which is marked with an [XXX] 278c2ecf20Sopenharmony_ciidentifier. The following chapters explain the meaning of those 288c2ecf20Sopenharmony_ciidentifiers. 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ciFunction identifiers [XXX] 318c2ecf20Sopenharmony_ci-------------------------- 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ciThe functions are marked with [XXX] identifiers in the short comment. 348c2ecf20Sopenharmony_ciThe identifiers explain the usage and scope of the functions. Following 358c2ecf20Sopenharmony_ciidentifiers are used: 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci- [MTD Interface] 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci These functions provide the interface to the MTD kernel API. They are 408c2ecf20Sopenharmony_ci not replaceable and provide functionality which is complete hardware 418c2ecf20Sopenharmony_ci independent. 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci- [NAND Interface] 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci These functions are exported and provide the interface to the NAND 468c2ecf20Sopenharmony_ci kernel API. 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci- [GENERIC] 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci Generic functions are not replaceable and provide functionality which 518c2ecf20Sopenharmony_ci is complete hardware independent. 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci- [DEFAULT] 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci Default functions provide hardware related functionality which is 568c2ecf20Sopenharmony_ci suitable for most of the implementations. These functions can be 578c2ecf20Sopenharmony_ci replaced by the board driver if necessary. Those functions are called 588c2ecf20Sopenharmony_ci via pointers in the NAND chip description structure. The board driver 598c2ecf20Sopenharmony_ci can set the functions which should be replaced by board dependent 608c2ecf20Sopenharmony_ci functions before calling nand_scan(). If the function pointer is 618c2ecf20Sopenharmony_ci NULL on entry to nand_scan() then the pointer is set to the default 628c2ecf20Sopenharmony_ci function which is suitable for the detected chip type. 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ciStruct member identifiers [XXX] 658c2ecf20Sopenharmony_ci------------------------------- 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ciThe struct members are marked with [XXX] identifiers in the comment. The 688c2ecf20Sopenharmony_ciidentifiers explain the usage and scope of the members. Following 698c2ecf20Sopenharmony_ciidentifiers are used: 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci- [INTERN] 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci These members are for NAND driver internal use only and must not be 748c2ecf20Sopenharmony_ci modified. Most of these values are calculated from the chip geometry 758c2ecf20Sopenharmony_ci information which is evaluated during nand_scan(). 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci- [REPLACEABLE] 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci Replaceable members hold hardware related functions which can be 808c2ecf20Sopenharmony_ci provided by the board driver. The board driver can set the functions 818c2ecf20Sopenharmony_ci which should be replaced by board dependent functions before calling 828c2ecf20Sopenharmony_ci nand_scan(). If the function pointer is NULL on entry to 838c2ecf20Sopenharmony_ci nand_scan() then the pointer is set to the default function which is 848c2ecf20Sopenharmony_ci suitable for the detected chip type. 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci- [BOARDSPECIFIC] 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci Board specific members hold hardware related information which must 898c2ecf20Sopenharmony_ci be provided by the board driver. The board driver must set the 908c2ecf20Sopenharmony_ci function pointers and datafields before calling nand_scan(). 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci- [OPTIONAL] 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci Optional members can hold information relevant for the board driver. 958c2ecf20Sopenharmony_ci The generic NAND driver code does not use this information. 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ciBasic board driver 988c2ecf20Sopenharmony_ci================== 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ciFor most boards it will be sufficient to provide just the basic 1018c2ecf20Sopenharmony_cifunctions and fill out some really board dependent members in the nand 1028c2ecf20Sopenharmony_cichip description structure. 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ciBasic defines 1058c2ecf20Sopenharmony_ci------------- 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ciAt least you have to provide a nand_chip structure and a storage for 1088c2ecf20Sopenharmony_cithe ioremap'ed chip address. You can allocate the nand_chip structure 1098c2ecf20Sopenharmony_ciusing kmalloc or you can allocate it statically. The NAND chip structure 1108c2ecf20Sopenharmony_ciembeds an mtd structure which will be registered to the MTD subsystem. 1118c2ecf20Sopenharmony_ciYou can extract a pointer to the mtd structure from a nand_chip pointer 1128c2ecf20Sopenharmony_ciusing the nand_to_mtd() helper. 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ciKmalloc based example 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci:: 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci static struct mtd_info *board_mtd; 1198c2ecf20Sopenharmony_ci static void __iomem *baseaddr; 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ciStatic example 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci:: 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci static struct nand_chip board_chip; 1278c2ecf20Sopenharmony_ci static void __iomem *baseaddr; 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ciPartition defines 1318c2ecf20Sopenharmony_ci----------------- 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ciIf you want to divide your device into partitions, then define a 1348c2ecf20Sopenharmony_cipartitioning scheme suitable to your board. 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci:: 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci #define NUM_PARTITIONS 2 1398c2ecf20Sopenharmony_ci static struct mtd_partition partition_info[] = { 1408c2ecf20Sopenharmony_ci { .name = "Flash partition 1", 1418c2ecf20Sopenharmony_ci .offset = 0, 1428c2ecf20Sopenharmony_ci .size = 8 * 1024 * 1024 }, 1438c2ecf20Sopenharmony_ci { .name = "Flash partition 2", 1448c2ecf20Sopenharmony_ci .offset = MTDPART_OFS_NEXT, 1458c2ecf20Sopenharmony_ci .size = MTDPART_SIZ_FULL }, 1468c2ecf20Sopenharmony_ci }; 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ciHardware control function 1508c2ecf20Sopenharmony_ci------------------------- 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ciThe hardware control function provides access to the control pins of the 1538c2ecf20Sopenharmony_ciNAND chip(s). The access can be done by GPIO pins or by address lines. 1548c2ecf20Sopenharmony_ciIf you use address lines, make sure that the timing requirements are 1558c2ecf20Sopenharmony_cimet. 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci*GPIO based example* 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci:: 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci static void board_hwcontrol(struct mtd_info *mtd, int cmd) 1628c2ecf20Sopenharmony_ci { 1638c2ecf20Sopenharmony_ci switch(cmd){ 1648c2ecf20Sopenharmony_ci case NAND_CTL_SETCLE: /* Set CLE pin high */ break; 1658c2ecf20Sopenharmony_ci case NAND_CTL_CLRCLE: /* Set CLE pin low */ break; 1668c2ecf20Sopenharmony_ci case NAND_CTL_SETALE: /* Set ALE pin high */ break; 1678c2ecf20Sopenharmony_ci case NAND_CTL_CLRALE: /* Set ALE pin low */ break; 1688c2ecf20Sopenharmony_ci case NAND_CTL_SETNCE: /* Set nCE pin low */ break; 1698c2ecf20Sopenharmony_ci case NAND_CTL_CLRNCE: /* Set nCE pin high */ break; 1708c2ecf20Sopenharmony_ci } 1718c2ecf20Sopenharmony_ci } 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci*Address lines based example.* It's assumed that the nCE pin is driven 1758c2ecf20Sopenharmony_ciby a chip select decoder. 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci:: 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci static void board_hwcontrol(struct mtd_info *mtd, int cmd) 1808c2ecf20Sopenharmony_ci { 1818c2ecf20Sopenharmony_ci struct nand_chip *this = mtd_to_nand(mtd); 1828c2ecf20Sopenharmony_ci switch(cmd){ 1838c2ecf20Sopenharmony_ci case NAND_CTL_SETCLE: this->legacy.IO_ADDR_W |= CLE_ADRR_BIT; break; 1848c2ecf20Sopenharmony_ci case NAND_CTL_CLRCLE: this->legacy.IO_ADDR_W &= ~CLE_ADRR_BIT; break; 1858c2ecf20Sopenharmony_ci case NAND_CTL_SETALE: this->legacy.IO_ADDR_W |= ALE_ADRR_BIT; break; 1868c2ecf20Sopenharmony_ci case NAND_CTL_CLRALE: this->legacy.IO_ADDR_W &= ~ALE_ADRR_BIT; break; 1878c2ecf20Sopenharmony_ci } 1888c2ecf20Sopenharmony_ci } 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ciDevice ready function 1928c2ecf20Sopenharmony_ci--------------------- 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ciIf the hardware interface has the ready busy pin of the NAND chip 1958c2ecf20Sopenharmony_ciconnected to a GPIO or other accessible I/O pin, this function is used 1968c2ecf20Sopenharmony_cito read back the state of the pin. The function has no arguments and 1978c2ecf20Sopenharmony_cishould return 0, if the device is busy (R/B pin is low) and 1, if the 1988c2ecf20Sopenharmony_cidevice is ready (R/B pin is high). If the hardware interface does not 1998c2ecf20Sopenharmony_cigive access to the ready busy pin, then the function must not be defined 2008c2ecf20Sopenharmony_ciand the function pointer this->legacy.dev_ready is set to NULL. 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_ciInit function 2038c2ecf20Sopenharmony_ci------------- 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ciThe init function allocates memory and sets up all the board specific 2068c2ecf20Sopenharmony_ciparameters and function pointers. When everything is set up nand_scan() 2078c2ecf20Sopenharmony_ciis called. This function tries to detect and identify then chip. If a 2088c2ecf20Sopenharmony_cichip is found all the internal data fields are initialized accordingly. 2098c2ecf20Sopenharmony_ciThe structure(s) have to be zeroed out first and then filled with the 2108c2ecf20Sopenharmony_cinecessary information about the device. 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci:: 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci static int __init board_init (void) 2158c2ecf20Sopenharmony_ci { 2168c2ecf20Sopenharmony_ci struct nand_chip *this; 2178c2ecf20Sopenharmony_ci int err = 0; 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci /* Allocate memory for MTD device structure and private data */ 2208c2ecf20Sopenharmony_ci this = kzalloc(sizeof(struct nand_chip), GFP_KERNEL); 2218c2ecf20Sopenharmony_ci if (!this) { 2228c2ecf20Sopenharmony_ci printk ("Unable to allocate NAND MTD device structure.\n"); 2238c2ecf20Sopenharmony_ci err = -ENOMEM; 2248c2ecf20Sopenharmony_ci goto out; 2258c2ecf20Sopenharmony_ci } 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_ci board_mtd = nand_to_mtd(this); 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci /* map physical address */ 2308c2ecf20Sopenharmony_ci baseaddr = ioremap(CHIP_PHYSICAL_ADDRESS, 1024); 2318c2ecf20Sopenharmony_ci if (!baseaddr) { 2328c2ecf20Sopenharmony_ci printk("Ioremap to access NAND chip failed\n"); 2338c2ecf20Sopenharmony_ci err = -EIO; 2348c2ecf20Sopenharmony_ci goto out_mtd; 2358c2ecf20Sopenharmony_ci } 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci /* Set address of NAND IO lines */ 2388c2ecf20Sopenharmony_ci this->legacy.IO_ADDR_R = baseaddr; 2398c2ecf20Sopenharmony_ci this->legacy.IO_ADDR_W = baseaddr; 2408c2ecf20Sopenharmony_ci /* Reference hardware control function */ 2418c2ecf20Sopenharmony_ci this->hwcontrol = board_hwcontrol; 2428c2ecf20Sopenharmony_ci /* Set command delay time, see datasheet for correct value */ 2438c2ecf20Sopenharmony_ci this->legacy.chip_delay = CHIP_DEPENDEND_COMMAND_DELAY; 2448c2ecf20Sopenharmony_ci /* Assign the device ready function, if available */ 2458c2ecf20Sopenharmony_ci this->legacy.dev_ready = board_dev_ready; 2468c2ecf20Sopenharmony_ci this->eccmode = NAND_ECC_SOFT; 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci /* Scan to find existence of the device */ 2498c2ecf20Sopenharmony_ci if (nand_scan (this, 1)) { 2508c2ecf20Sopenharmony_ci err = -ENXIO; 2518c2ecf20Sopenharmony_ci goto out_ior; 2528c2ecf20Sopenharmony_ci } 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci add_mtd_partitions(board_mtd, partition_info, NUM_PARTITIONS); 2558c2ecf20Sopenharmony_ci goto out; 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci out_ior: 2588c2ecf20Sopenharmony_ci iounmap(baseaddr); 2598c2ecf20Sopenharmony_ci out_mtd: 2608c2ecf20Sopenharmony_ci kfree (this); 2618c2ecf20Sopenharmony_ci out: 2628c2ecf20Sopenharmony_ci return err; 2638c2ecf20Sopenharmony_ci } 2648c2ecf20Sopenharmony_ci module_init(board_init); 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ciExit function 2688c2ecf20Sopenharmony_ci------------- 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ciThe exit function is only necessary if the driver is compiled as a 2718c2ecf20Sopenharmony_cimodule. It releases all resources which are held by the chip driver and 2728c2ecf20Sopenharmony_ciunregisters the partitions in the MTD layer. 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci:: 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci #ifdef MODULE 2778c2ecf20Sopenharmony_ci static void __exit board_cleanup (void) 2788c2ecf20Sopenharmony_ci { 2798c2ecf20Sopenharmony_ci /* Unregister device */ 2808c2ecf20Sopenharmony_ci WARN_ON(mtd_device_unregister(board_mtd)); 2818c2ecf20Sopenharmony_ci /* Release resources */ 2828c2ecf20Sopenharmony_ci nand_cleanup(mtd_to_nand(board_mtd)); 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_ci /* unmap physical address */ 2858c2ecf20Sopenharmony_ci iounmap(baseaddr); 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci /* Free the MTD device structure */ 2888c2ecf20Sopenharmony_ci kfree (mtd_to_nand(board_mtd)); 2898c2ecf20Sopenharmony_ci } 2908c2ecf20Sopenharmony_ci module_exit(board_cleanup); 2918c2ecf20Sopenharmony_ci #endif 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_ciAdvanced board driver functions 2958c2ecf20Sopenharmony_ci=============================== 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ciThis chapter describes the advanced functionality of the NAND driver. 2988c2ecf20Sopenharmony_ciFor a list of functions which can be overridden by the board driver see 2998c2ecf20Sopenharmony_cithe documentation of the nand_chip structure. 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ciMultiple chip control 3028c2ecf20Sopenharmony_ci--------------------- 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ciThe nand driver can control chip arrays. Therefore the board driver must 3058c2ecf20Sopenharmony_ciprovide an own select_chip function. This function must (de)select the 3068c2ecf20Sopenharmony_cirequested chip. The function pointer in the nand_chip structure must be 3078c2ecf20Sopenharmony_ciset before calling nand_scan(). The maxchip parameter of nand_scan() 3088c2ecf20Sopenharmony_cidefines the maximum number of chips to scan for. Make sure that the 3098c2ecf20Sopenharmony_ciselect_chip function can handle the requested number of chips. 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ciThe nand driver concatenates the chips to one virtual chip and provides 3128c2ecf20Sopenharmony_cithis virtual chip to the MTD layer. 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_ci*Note: The driver can only handle linear chip arrays of equally sized 3158c2ecf20Sopenharmony_cichips. There is no support for parallel arrays which extend the 3168c2ecf20Sopenharmony_cibuswidth.* 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_ci*GPIO based example* 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci:: 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_ci static void board_select_chip (struct mtd_info *mtd, int chip) 3238c2ecf20Sopenharmony_ci { 3248c2ecf20Sopenharmony_ci /* Deselect all chips, set all nCE pins high */ 3258c2ecf20Sopenharmony_ci GPIO(BOARD_NAND_NCE) |= 0xff; 3268c2ecf20Sopenharmony_ci if (chip >= 0) 3278c2ecf20Sopenharmony_ci GPIO(BOARD_NAND_NCE) &= ~ (1 << chip); 3288c2ecf20Sopenharmony_ci } 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_ci 3318c2ecf20Sopenharmony_ci*Address lines based example.* Its assumed that the nCE pins are 3328c2ecf20Sopenharmony_ciconnected to an address decoder. 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_ci:: 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_ci static void board_select_chip (struct mtd_info *mtd, int chip) 3378c2ecf20Sopenharmony_ci { 3388c2ecf20Sopenharmony_ci struct nand_chip *this = mtd_to_nand(mtd); 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_ci /* Deselect all chips */ 3418c2ecf20Sopenharmony_ci this->legacy.IO_ADDR_R &= ~BOARD_NAND_ADDR_MASK; 3428c2ecf20Sopenharmony_ci this->legacy.IO_ADDR_W &= ~BOARD_NAND_ADDR_MASK; 3438c2ecf20Sopenharmony_ci switch (chip) { 3448c2ecf20Sopenharmony_ci case 0: 3458c2ecf20Sopenharmony_ci this->legacy.IO_ADDR_R |= BOARD_NAND_ADDR_CHIP0; 3468c2ecf20Sopenharmony_ci this->legacy.IO_ADDR_W |= BOARD_NAND_ADDR_CHIP0; 3478c2ecf20Sopenharmony_ci break; 3488c2ecf20Sopenharmony_ci .... 3498c2ecf20Sopenharmony_ci case n: 3508c2ecf20Sopenharmony_ci this->legacy.IO_ADDR_R |= BOARD_NAND_ADDR_CHIPn; 3518c2ecf20Sopenharmony_ci this->legacy.IO_ADDR_W |= BOARD_NAND_ADDR_CHIPn; 3528c2ecf20Sopenharmony_ci break; 3538c2ecf20Sopenharmony_ci } 3548c2ecf20Sopenharmony_ci } 3558c2ecf20Sopenharmony_ci 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_ciHardware ECC support 3588c2ecf20Sopenharmony_ci-------------------- 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ciFunctions and constants 3618c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~ 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_ciThe nand driver supports three different types of hardware ECC. 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_ci- NAND_ECC_HW3_256 3668c2ecf20Sopenharmony_ci 3678c2ecf20Sopenharmony_ci Hardware ECC generator providing 3 bytes ECC per 256 byte. 3688c2ecf20Sopenharmony_ci 3698c2ecf20Sopenharmony_ci- NAND_ECC_HW3_512 3708c2ecf20Sopenharmony_ci 3718c2ecf20Sopenharmony_ci Hardware ECC generator providing 3 bytes ECC per 512 byte. 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_ci- NAND_ECC_HW6_512 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_ci Hardware ECC generator providing 6 bytes ECC per 512 byte. 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_ci- NAND_ECC_HW8_512 3788c2ecf20Sopenharmony_ci 3798c2ecf20Sopenharmony_ci Hardware ECC generator providing 8 bytes ECC per 512 byte. 3808c2ecf20Sopenharmony_ci 3818c2ecf20Sopenharmony_ciIf your hardware generator has a different functionality add it at the 3828c2ecf20Sopenharmony_ciappropriate place in nand_base.c 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ciThe board driver must provide following functions: 3858c2ecf20Sopenharmony_ci 3868c2ecf20Sopenharmony_ci- enable_hwecc 3878c2ecf20Sopenharmony_ci 3888c2ecf20Sopenharmony_ci This function is called before reading / writing to the chip. Reset 3898c2ecf20Sopenharmony_ci or initialize the hardware generator in this function. The function 3908c2ecf20Sopenharmony_ci is called with an argument which let you distinguish between read and 3918c2ecf20Sopenharmony_ci write operations. 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_ci- calculate_ecc 3948c2ecf20Sopenharmony_ci 3958c2ecf20Sopenharmony_ci This function is called after read / write from / to the chip. 3968c2ecf20Sopenharmony_ci Transfer the ECC from the hardware to the buffer. If the option 3978c2ecf20Sopenharmony_ci NAND_HWECC_SYNDROME is set then the function is only called on 3988c2ecf20Sopenharmony_ci write. See below. 3998c2ecf20Sopenharmony_ci 4008c2ecf20Sopenharmony_ci- correct_data 4018c2ecf20Sopenharmony_ci 4028c2ecf20Sopenharmony_ci In case of an ECC error this function is called for error detection 4038c2ecf20Sopenharmony_ci and correction. Return 1 respectively 2 in case the error can be 4048c2ecf20Sopenharmony_ci corrected. If the error is not correctable return -1. If your 4058c2ecf20Sopenharmony_ci hardware generator matches the default algorithm of the nand_ecc 4068c2ecf20Sopenharmony_ci software generator then use the correction function provided by 4078c2ecf20Sopenharmony_ci nand_ecc instead of implementing duplicated code. 4088c2ecf20Sopenharmony_ci 4098c2ecf20Sopenharmony_ciHardware ECC with syndrome calculation 4108c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4118c2ecf20Sopenharmony_ci 4128c2ecf20Sopenharmony_ciMany hardware ECC implementations provide Reed-Solomon codes and 4138c2ecf20Sopenharmony_cicalculate an error syndrome on read. The syndrome must be converted to a 4148c2ecf20Sopenharmony_cistandard Reed-Solomon syndrome before calling the error correction code 4158c2ecf20Sopenharmony_ciin the generic Reed-Solomon library. 4168c2ecf20Sopenharmony_ci 4178c2ecf20Sopenharmony_ciThe ECC bytes must be placed immediately after the data bytes in order 4188c2ecf20Sopenharmony_cito make the syndrome generator work. This is contrary to the usual 4198c2ecf20Sopenharmony_cilayout used by software ECC. The separation of data and out of band area 4208c2ecf20Sopenharmony_ciis not longer possible. The nand driver code handles this layout and the 4218c2ecf20Sopenharmony_ciremaining free bytes in the oob area are managed by the autoplacement 4228c2ecf20Sopenharmony_cicode. Provide a matching oob-layout in this case. See rts_from4.c and 4238c2ecf20Sopenharmony_cidiskonchip.c for implementation reference. In those cases we must also 4248c2ecf20Sopenharmony_ciuse bad block tables on FLASH, because the ECC layout is interfering 4258c2ecf20Sopenharmony_ciwith the bad block marker positions. See bad block table support for 4268c2ecf20Sopenharmony_cidetails. 4278c2ecf20Sopenharmony_ci 4288c2ecf20Sopenharmony_ciBad block table support 4298c2ecf20Sopenharmony_ci----------------------- 4308c2ecf20Sopenharmony_ci 4318c2ecf20Sopenharmony_ciMost NAND chips mark the bad blocks at a defined position in the spare 4328c2ecf20Sopenharmony_ciarea. Those blocks must not be erased under any circumstances as the bad 4338c2ecf20Sopenharmony_ciblock information would be lost. It is possible to check the bad block 4348c2ecf20Sopenharmony_cimark each time when the blocks are accessed by reading the spare area of 4358c2ecf20Sopenharmony_cithe first page in the block. This is time consuming so a bad block table 4368c2ecf20Sopenharmony_ciis used. 4378c2ecf20Sopenharmony_ci 4388c2ecf20Sopenharmony_ciThe nand driver supports various types of bad block tables. 4398c2ecf20Sopenharmony_ci 4408c2ecf20Sopenharmony_ci- Per device 4418c2ecf20Sopenharmony_ci 4428c2ecf20Sopenharmony_ci The bad block table contains all bad block information of the device 4438c2ecf20Sopenharmony_ci which can consist of multiple chips. 4448c2ecf20Sopenharmony_ci 4458c2ecf20Sopenharmony_ci- Per chip 4468c2ecf20Sopenharmony_ci 4478c2ecf20Sopenharmony_ci A bad block table is used per chip and contains the bad block 4488c2ecf20Sopenharmony_ci information for this particular chip. 4498c2ecf20Sopenharmony_ci 4508c2ecf20Sopenharmony_ci- Fixed offset 4518c2ecf20Sopenharmony_ci 4528c2ecf20Sopenharmony_ci The bad block table is located at a fixed offset in the chip 4538c2ecf20Sopenharmony_ci (device). This applies to various DiskOnChip devices. 4548c2ecf20Sopenharmony_ci 4558c2ecf20Sopenharmony_ci- Automatic placed 4568c2ecf20Sopenharmony_ci 4578c2ecf20Sopenharmony_ci The bad block table is automatically placed and detected either at 4588c2ecf20Sopenharmony_ci the end or at the beginning of a chip (device) 4598c2ecf20Sopenharmony_ci 4608c2ecf20Sopenharmony_ci- Mirrored tables 4618c2ecf20Sopenharmony_ci 4628c2ecf20Sopenharmony_ci The bad block table is mirrored on the chip (device) to allow updates 4638c2ecf20Sopenharmony_ci of the bad block table without data loss. 4648c2ecf20Sopenharmony_ci 4658c2ecf20Sopenharmony_cinand_scan() calls the function nand_default_bbt(). 4668c2ecf20Sopenharmony_cinand_default_bbt() selects appropriate default bad block table 4678c2ecf20Sopenharmony_cidescriptors depending on the chip information which was retrieved by 4688c2ecf20Sopenharmony_cinand_scan(). 4698c2ecf20Sopenharmony_ci 4708c2ecf20Sopenharmony_ciThe standard policy is scanning the device for bad blocks and build a 4718c2ecf20Sopenharmony_ciram based bad block table which allows faster access than always 4728c2ecf20Sopenharmony_cichecking the bad block information on the flash chip itself. 4738c2ecf20Sopenharmony_ci 4748c2ecf20Sopenharmony_ciFlash based tables 4758c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~ 4768c2ecf20Sopenharmony_ci 4778c2ecf20Sopenharmony_ciIt may be desired or necessary to keep a bad block table in FLASH. For 4788c2ecf20Sopenharmony_ciAG-AND chips this is mandatory, as they have no factory marked bad 4798c2ecf20Sopenharmony_ciblocks. They have factory marked good blocks. The marker pattern is 4808c2ecf20Sopenharmony_cierased when the block is erased to be reused. So in case of powerloss 4818c2ecf20Sopenharmony_cibefore writing the pattern back to the chip this block would be lost and 4828c2ecf20Sopenharmony_ciadded to the bad blocks. Therefore we scan the chip(s) when we detect 4838c2ecf20Sopenharmony_cithem the first time for good blocks and store this information in a bad 4848c2ecf20Sopenharmony_ciblock table before erasing any of the blocks. 4858c2ecf20Sopenharmony_ci 4868c2ecf20Sopenharmony_ciThe blocks in which the tables are stored are protected against 4878c2ecf20Sopenharmony_ciaccidental access by marking them bad in the memory bad block table. The 4888c2ecf20Sopenharmony_cibad block table management functions are allowed to circumvent this 4898c2ecf20Sopenharmony_ciprotection. 4908c2ecf20Sopenharmony_ci 4918c2ecf20Sopenharmony_ciThe simplest way to activate the FLASH based bad block table support is 4928c2ecf20Sopenharmony_cito set the option NAND_BBT_USE_FLASH in the bbt_option field of the 4938c2ecf20Sopenharmony_cinand chip structure before calling nand_scan(). For AG-AND chips is 4948c2ecf20Sopenharmony_cithis done by default. This activates the default FLASH based bad block 4958c2ecf20Sopenharmony_citable functionality of the NAND driver. The default bad block table 4968c2ecf20Sopenharmony_cioptions are 4978c2ecf20Sopenharmony_ci 4988c2ecf20Sopenharmony_ci- Store bad block table per chip 4998c2ecf20Sopenharmony_ci 5008c2ecf20Sopenharmony_ci- Use 2 bits per block 5018c2ecf20Sopenharmony_ci 5028c2ecf20Sopenharmony_ci- Automatic placement at the end of the chip 5038c2ecf20Sopenharmony_ci 5048c2ecf20Sopenharmony_ci- Use mirrored tables with version numbers 5058c2ecf20Sopenharmony_ci 5068c2ecf20Sopenharmony_ci- Reserve 4 blocks at the end of the chip 5078c2ecf20Sopenharmony_ci 5088c2ecf20Sopenharmony_ciUser defined tables 5098c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~ 5108c2ecf20Sopenharmony_ci 5118c2ecf20Sopenharmony_ciUser defined tables are created by filling out a nand_bbt_descr 5128c2ecf20Sopenharmony_cistructure and storing the pointer in the nand_chip structure member 5138c2ecf20Sopenharmony_cibbt_td before calling nand_scan(). If a mirror table is necessary a 5148c2ecf20Sopenharmony_cisecond structure must be created and a pointer to this structure must be 5158c2ecf20Sopenharmony_cistored in bbt_md inside the nand_chip structure. If the bbt_md member 5168c2ecf20Sopenharmony_ciis set to NULL then only the main table is used and no scan for the 5178c2ecf20Sopenharmony_cimirrored table is performed. 5188c2ecf20Sopenharmony_ci 5198c2ecf20Sopenharmony_ciThe most important field in the nand_bbt_descr structure is the 5208c2ecf20Sopenharmony_cioptions field. The options define most of the table properties. Use the 5218c2ecf20Sopenharmony_cipredefined constants from rawnand.h to define the options. 5228c2ecf20Sopenharmony_ci 5238c2ecf20Sopenharmony_ci- Number of bits per block 5248c2ecf20Sopenharmony_ci 5258c2ecf20Sopenharmony_ci The supported number of bits is 1, 2, 4, 8. 5268c2ecf20Sopenharmony_ci 5278c2ecf20Sopenharmony_ci- Table per chip 5288c2ecf20Sopenharmony_ci 5298c2ecf20Sopenharmony_ci Setting the constant NAND_BBT_PERCHIP selects that a bad block 5308c2ecf20Sopenharmony_ci table is managed for each chip in a chip array. If this option is not 5318c2ecf20Sopenharmony_ci set then a per device bad block table is used. 5328c2ecf20Sopenharmony_ci 5338c2ecf20Sopenharmony_ci- Table location is absolute 5348c2ecf20Sopenharmony_ci 5358c2ecf20Sopenharmony_ci Use the option constant NAND_BBT_ABSPAGE and define the absolute 5368c2ecf20Sopenharmony_ci page number where the bad block table starts in the field pages. If 5378c2ecf20Sopenharmony_ci you have selected bad block tables per chip and you have a multi chip 5388c2ecf20Sopenharmony_ci array then the start page must be given for each chip in the chip 5398c2ecf20Sopenharmony_ci array. Note: there is no scan for a table ident pattern performed, so 5408c2ecf20Sopenharmony_ci the fields pattern, veroffs, offs, len can be left uninitialized 5418c2ecf20Sopenharmony_ci 5428c2ecf20Sopenharmony_ci- Table location is automatically detected 5438c2ecf20Sopenharmony_ci 5448c2ecf20Sopenharmony_ci The table can either be located in the first or the last good blocks 5458c2ecf20Sopenharmony_ci of the chip (device). Set NAND_BBT_LASTBLOCK to place the bad block 5468c2ecf20Sopenharmony_ci table at the end of the chip (device). The bad block tables are 5478c2ecf20Sopenharmony_ci marked and identified by a pattern which is stored in the spare area 5488c2ecf20Sopenharmony_ci of the first page in the block which holds the bad block table. Store 5498c2ecf20Sopenharmony_ci a pointer to the pattern in the pattern field. Further the length of 5508c2ecf20Sopenharmony_ci the pattern has to be stored in len and the offset in the spare area 5518c2ecf20Sopenharmony_ci must be given in the offs member of the nand_bbt_descr structure. 5528c2ecf20Sopenharmony_ci For mirrored bad block tables different patterns are mandatory. 5538c2ecf20Sopenharmony_ci 5548c2ecf20Sopenharmony_ci- Table creation 5558c2ecf20Sopenharmony_ci 5568c2ecf20Sopenharmony_ci Set the option NAND_BBT_CREATE to enable the table creation if no 5578c2ecf20Sopenharmony_ci table can be found during the scan. Usually this is done only once if 5588c2ecf20Sopenharmony_ci a new chip is found. 5598c2ecf20Sopenharmony_ci 5608c2ecf20Sopenharmony_ci- Table write support 5618c2ecf20Sopenharmony_ci 5628c2ecf20Sopenharmony_ci Set the option NAND_BBT_WRITE to enable the table write support. 5638c2ecf20Sopenharmony_ci This allows the update of the bad block table(s) in case a block has 5648c2ecf20Sopenharmony_ci to be marked bad due to wear. The MTD interface function 5658c2ecf20Sopenharmony_ci block_markbad is calling the update function of the bad block table. 5668c2ecf20Sopenharmony_ci If the write support is enabled then the table is updated on FLASH. 5678c2ecf20Sopenharmony_ci 5688c2ecf20Sopenharmony_ci Note: Write support should only be enabled for mirrored tables with 5698c2ecf20Sopenharmony_ci version control. 5708c2ecf20Sopenharmony_ci 5718c2ecf20Sopenharmony_ci- Table version control 5728c2ecf20Sopenharmony_ci 5738c2ecf20Sopenharmony_ci Set the option NAND_BBT_VERSION to enable the table version 5748c2ecf20Sopenharmony_ci control. It's highly recommended to enable this for mirrored tables 5758c2ecf20Sopenharmony_ci with write support. It makes sure that the risk of losing the bad 5768c2ecf20Sopenharmony_ci block table information is reduced to the loss of the information 5778c2ecf20Sopenharmony_ci about the one worn out block which should be marked bad. The version 5788c2ecf20Sopenharmony_ci is stored in 4 consecutive bytes in the spare area of the device. The 5798c2ecf20Sopenharmony_ci position of the version number is defined by the member veroffs in 5808c2ecf20Sopenharmony_ci the bad block table descriptor. 5818c2ecf20Sopenharmony_ci 5828c2ecf20Sopenharmony_ci- Save block contents on write 5838c2ecf20Sopenharmony_ci 5848c2ecf20Sopenharmony_ci In case that the block which holds the bad block table does contain 5858c2ecf20Sopenharmony_ci other useful information, set the option NAND_BBT_SAVECONTENT. When 5868c2ecf20Sopenharmony_ci the bad block table is written then the whole block is read the bad 5878c2ecf20Sopenharmony_ci block table is updated and the block is erased and everything is 5888c2ecf20Sopenharmony_ci written back. If this option is not set only the bad block table is 5898c2ecf20Sopenharmony_ci written and everything else in the block is ignored and erased. 5908c2ecf20Sopenharmony_ci 5918c2ecf20Sopenharmony_ci- Number of reserved blocks 5928c2ecf20Sopenharmony_ci 5938c2ecf20Sopenharmony_ci For automatic placement some blocks must be reserved for bad block 5948c2ecf20Sopenharmony_ci table storage. The number of reserved blocks is defined in the 5958c2ecf20Sopenharmony_ci maxblocks member of the bad block table description structure. 5968c2ecf20Sopenharmony_ci Reserving 4 blocks for mirrored tables should be a reasonable number. 5978c2ecf20Sopenharmony_ci This also limits the number of blocks which are scanned for the bad 5988c2ecf20Sopenharmony_ci block table ident pattern. 5998c2ecf20Sopenharmony_ci 6008c2ecf20Sopenharmony_ciSpare area (auto)placement 6018c2ecf20Sopenharmony_ci-------------------------- 6028c2ecf20Sopenharmony_ci 6038c2ecf20Sopenharmony_ciThe nand driver implements different possibilities for placement of 6048c2ecf20Sopenharmony_cifilesystem data in the spare area, 6058c2ecf20Sopenharmony_ci 6068c2ecf20Sopenharmony_ci- Placement defined by fs driver 6078c2ecf20Sopenharmony_ci 6088c2ecf20Sopenharmony_ci- Automatic placement 6098c2ecf20Sopenharmony_ci 6108c2ecf20Sopenharmony_ciThe default placement function is automatic placement. The nand driver 6118c2ecf20Sopenharmony_cihas built in default placement schemes for the various chiptypes. If due 6128c2ecf20Sopenharmony_cito hardware ECC functionality the default placement does not fit then 6138c2ecf20Sopenharmony_cithe board driver can provide a own placement scheme. 6148c2ecf20Sopenharmony_ci 6158c2ecf20Sopenharmony_ciFile system drivers can provide a own placement scheme which is used 6168c2ecf20Sopenharmony_ciinstead of the default placement scheme. 6178c2ecf20Sopenharmony_ci 6188c2ecf20Sopenharmony_ciPlacement schemes are defined by a nand_oobinfo structure 6198c2ecf20Sopenharmony_ci 6208c2ecf20Sopenharmony_ci:: 6218c2ecf20Sopenharmony_ci 6228c2ecf20Sopenharmony_ci struct nand_oobinfo { 6238c2ecf20Sopenharmony_ci int useecc; 6248c2ecf20Sopenharmony_ci int eccbytes; 6258c2ecf20Sopenharmony_ci int eccpos[24]; 6268c2ecf20Sopenharmony_ci int oobfree[8][2]; 6278c2ecf20Sopenharmony_ci }; 6288c2ecf20Sopenharmony_ci 6298c2ecf20Sopenharmony_ci 6308c2ecf20Sopenharmony_ci- useecc 6318c2ecf20Sopenharmony_ci 6328c2ecf20Sopenharmony_ci The useecc member controls the ecc and placement function. The header 6338c2ecf20Sopenharmony_ci file include/mtd/mtd-abi.h contains constants to select ecc and 6348c2ecf20Sopenharmony_ci placement. MTD_NANDECC_OFF switches off the ecc complete. This is 6358c2ecf20Sopenharmony_ci not recommended and available for testing and diagnosis only. 6368c2ecf20Sopenharmony_ci MTD_NANDECC_PLACE selects caller defined placement, 6378c2ecf20Sopenharmony_ci MTD_NANDECC_AUTOPLACE selects automatic placement. 6388c2ecf20Sopenharmony_ci 6398c2ecf20Sopenharmony_ci- eccbytes 6408c2ecf20Sopenharmony_ci 6418c2ecf20Sopenharmony_ci The eccbytes member defines the number of ecc bytes per page. 6428c2ecf20Sopenharmony_ci 6438c2ecf20Sopenharmony_ci- eccpos 6448c2ecf20Sopenharmony_ci 6458c2ecf20Sopenharmony_ci The eccpos array holds the byte offsets in the spare area where the 6468c2ecf20Sopenharmony_ci ecc codes are placed. 6478c2ecf20Sopenharmony_ci 6488c2ecf20Sopenharmony_ci- oobfree 6498c2ecf20Sopenharmony_ci 6508c2ecf20Sopenharmony_ci The oobfree array defines the areas in the spare area which can be 6518c2ecf20Sopenharmony_ci used for automatic placement. The information is given in the format 6528c2ecf20Sopenharmony_ci {offset, size}. offset defines the start of the usable area, size the 6538c2ecf20Sopenharmony_ci length in bytes. More than one area can be defined. The list is 6548c2ecf20Sopenharmony_ci terminated by an {0, 0} entry. 6558c2ecf20Sopenharmony_ci 6568c2ecf20Sopenharmony_ciPlacement defined by fs driver 6578c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 6588c2ecf20Sopenharmony_ci 6598c2ecf20Sopenharmony_ciThe calling function provides a pointer to a nand_oobinfo structure 6608c2ecf20Sopenharmony_ciwhich defines the ecc placement. For writes the caller must provide a 6618c2ecf20Sopenharmony_cispare area buffer along with the data buffer. The spare area buffer size 6628c2ecf20Sopenharmony_ciis (number of pages) \* (size of spare area). For reads the buffer size 6638c2ecf20Sopenharmony_ciis (number of pages) \* ((size of spare area) + (number of ecc steps per 6648c2ecf20Sopenharmony_cipage) \* sizeof (int)). The driver stores the result of the ecc check 6658c2ecf20Sopenharmony_cifor each tuple in the spare buffer. The storage sequence is:: 6668c2ecf20Sopenharmony_ci 6678c2ecf20Sopenharmony_ci <spare data page 0><ecc result 0>...<ecc result n> 6688c2ecf20Sopenharmony_ci 6698c2ecf20Sopenharmony_ci ... 6708c2ecf20Sopenharmony_ci 6718c2ecf20Sopenharmony_ci <spare data page n><ecc result 0>...<ecc result n> 6728c2ecf20Sopenharmony_ci 6738c2ecf20Sopenharmony_ciThis is a legacy mode used by YAFFS1. 6748c2ecf20Sopenharmony_ci 6758c2ecf20Sopenharmony_ciIf the spare area buffer is NULL then only the ECC placement is done 6768c2ecf20Sopenharmony_ciaccording to the given scheme in the nand_oobinfo structure. 6778c2ecf20Sopenharmony_ci 6788c2ecf20Sopenharmony_ciAutomatic placement 6798c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~ 6808c2ecf20Sopenharmony_ci 6818c2ecf20Sopenharmony_ciAutomatic placement uses the built in defaults to place the ecc bytes in 6828c2ecf20Sopenharmony_cithe spare area. If filesystem data have to be stored / read into the 6838c2ecf20Sopenharmony_cispare area then the calling function must provide a buffer. The buffer 6848c2ecf20Sopenharmony_cisize per page is determined by the oobfree array in the nand_oobinfo 6858c2ecf20Sopenharmony_cistructure. 6868c2ecf20Sopenharmony_ci 6878c2ecf20Sopenharmony_ciIf the spare area buffer is NULL then only the ECC placement is done 6888c2ecf20Sopenharmony_ciaccording to the default builtin scheme. 6898c2ecf20Sopenharmony_ci 6908c2ecf20Sopenharmony_ciSpare area autoplacement default schemes 6918c2ecf20Sopenharmony_ci---------------------------------------- 6928c2ecf20Sopenharmony_ci 6938c2ecf20Sopenharmony_ci256 byte pagesize 6948c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~ 6958c2ecf20Sopenharmony_ci 6968c2ecf20Sopenharmony_ci======== ================== =================================================== 6978c2ecf20Sopenharmony_ciOffset Content Comment 6988c2ecf20Sopenharmony_ci======== ================== =================================================== 6998c2ecf20Sopenharmony_ci0x00 ECC byte 0 Error correction code byte 0 7008c2ecf20Sopenharmony_ci0x01 ECC byte 1 Error correction code byte 1 7018c2ecf20Sopenharmony_ci0x02 ECC byte 2 Error correction code byte 2 7028c2ecf20Sopenharmony_ci0x03 Autoplace 0 7038c2ecf20Sopenharmony_ci0x04 Autoplace 1 7048c2ecf20Sopenharmony_ci0x05 Bad block marker If any bit in this byte is zero, then this 7058c2ecf20Sopenharmony_ci block is bad. This applies only to the first 7068c2ecf20Sopenharmony_ci page in a block. In the remaining pages this 7078c2ecf20Sopenharmony_ci byte is reserved 7088c2ecf20Sopenharmony_ci0x06 Autoplace 2 7098c2ecf20Sopenharmony_ci0x07 Autoplace 3 7108c2ecf20Sopenharmony_ci======== ================== =================================================== 7118c2ecf20Sopenharmony_ci 7128c2ecf20Sopenharmony_ci512 byte pagesize 7138c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~ 7148c2ecf20Sopenharmony_ci 7158c2ecf20Sopenharmony_ci 7168c2ecf20Sopenharmony_ci============= ================== ============================================== 7178c2ecf20Sopenharmony_ciOffset Content Comment 7188c2ecf20Sopenharmony_ci============= ================== ============================================== 7198c2ecf20Sopenharmony_ci0x00 ECC byte 0 Error correction code byte 0 of the lower 7208c2ecf20Sopenharmony_ci 256 Byte data in this page 7218c2ecf20Sopenharmony_ci0x01 ECC byte 1 Error correction code byte 1 of the lower 7228c2ecf20Sopenharmony_ci 256 Bytes of data in this page 7238c2ecf20Sopenharmony_ci0x02 ECC byte 2 Error correction code byte 2 of the lower 7248c2ecf20Sopenharmony_ci 256 Bytes of data in this page 7258c2ecf20Sopenharmony_ci0x03 ECC byte 3 Error correction code byte 0 of the upper 7268c2ecf20Sopenharmony_ci 256 Bytes of data in this page 7278c2ecf20Sopenharmony_ci0x04 reserved reserved 7288c2ecf20Sopenharmony_ci0x05 Bad block marker If any bit in this byte is zero, then this 7298c2ecf20Sopenharmony_ci block is bad. This applies only to the first 7308c2ecf20Sopenharmony_ci page in a block. In the remaining pages this 7318c2ecf20Sopenharmony_ci byte is reserved 7328c2ecf20Sopenharmony_ci0x06 ECC byte 4 Error correction code byte 1 of the upper 7338c2ecf20Sopenharmony_ci 256 Bytes of data in this page 7348c2ecf20Sopenharmony_ci0x07 ECC byte 5 Error correction code byte 2 of the upper 7358c2ecf20Sopenharmony_ci 256 Bytes of data in this page 7368c2ecf20Sopenharmony_ci0x08 - 0x0F Autoplace 0 - 7 7378c2ecf20Sopenharmony_ci============= ================== ============================================== 7388c2ecf20Sopenharmony_ci 7398c2ecf20Sopenharmony_ci2048 byte pagesize 7408c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~ 7418c2ecf20Sopenharmony_ci 7428c2ecf20Sopenharmony_ci=========== ================== ================================================ 7438c2ecf20Sopenharmony_ciOffset Content Comment 7448c2ecf20Sopenharmony_ci=========== ================== ================================================ 7458c2ecf20Sopenharmony_ci0x00 Bad block marker If any bit in this byte is zero, then this block 7468c2ecf20Sopenharmony_ci is bad. This applies only to the first page in a 7478c2ecf20Sopenharmony_ci block. In the remaining pages this byte is 7488c2ecf20Sopenharmony_ci reserved 7498c2ecf20Sopenharmony_ci0x01 Reserved Reserved 7508c2ecf20Sopenharmony_ci0x02-0x27 Autoplace 0 - 37 7518c2ecf20Sopenharmony_ci0x28 ECC byte 0 Error correction code byte 0 of the first 7528c2ecf20Sopenharmony_ci 256 Byte data in this page 7538c2ecf20Sopenharmony_ci0x29 ECC byte 1 Error correction code byte 1 of the first 7548c2ecf20Sopenharmony_ci 256 Bytes of data in this page 7558c2ecf20Sopenharmony_ci0x2A ECC byte 2 Error correction code byte 2 of the first 7568c2ecf20Sopenharmony_ci 256 Bytes data in this page 7578c2ecf20Sopenharmony_ci0x2B ECC byte 3 Error correction code byte 0 of the second 7588c2ecf20Sopenharmony_ci 256 Bytes of data in this page 7598c2ecf20Sopenharmony_ci0x2C ECC byte 4 Error correction code byte 1 of the second 7608c2ecf20Sopenharmony_ci 256 Bytes of data in this page 7618c2ecf20Sopenharmony_ci0x2D ECC byte 5 Error correction code byte 2 of the second 7628c2ecf20Sopenharmony_ci 256 Bytes of data in this page 7638c2ecf20Sopenharmony_ci0x2E ECC byte 6 Error correction code byte 0 of the third 7648c2ecf20Sopenharmony_ci 256 Bytes of data in this page 7658c2ecf20Sopenharmony_ci0x2F ECC byte 7 Error correction code byte 1 of the third 7668c2ecf20Sopenharmony_ci 256 Bytes of data in this page 7678c2ecf20Sopenharmony_ci0x30 ECC byte 8 Error correction code byte 2 of the third 7688c2ecf20Sopenharmony_ci 256 Bytes of data in this page 7698c2ecf20Sopenharmony_ci0x31 ECC byte 9 Error correction code byte 0 of the fourth 7708c2ecf20Sopenharmony_ci 256 Bytes of data in this page 7718c2ecf20Sopenharmony_ci0x32 ECC byte 10 Error correction code byte 1 of the fourth 7728c2ecf20Sopenharmony_ci 256 Bytes of data in this page 7738c2ecf20Sopenharmony_ci0x33 ECC byte 11 Error correction code byte 2 of the fourth 7748c2ecf20Sopenharmony_ci 256 Bytes of data in this page 7758c2ecf20Sopenharmony_ci0x34 ECC byte 12 Error correction code byte 0 of the fifth 7768c2ecf20Sopenharmony_ci 256 Bytes of data in this page 7778c2ecf20Sopenharmony_ci0x35 ECC byte 13 Error correction code byte 1 of the fifth 7788c2ecf20Sopenharmony_ci 256 Bytes of data in this page 7798c2ecf20Sopenharmony_ci0x36 ECC byte 14 Error correction code byte 2 of the fifth 7808c2ecf20Sopenharmony_ci 256 Bytes of data in this page 7818c2ecf20Sopenharmony_ci0x37 ECC byte 15 Error correction code byte 0 of the sixth 7828c2ecf20Sopenharmony_ci 256 Bytes of data in this page 7838c2ecf20Sopenharmony_ci0x38 ECC byte 16 Error correction code byte 1 of the sixth 7848c2ecf20Sopenharmony_ci 256 Bytes of data in this page 7858c2ecf20Sopenharmony_ci0x39 ECC byte 17 Error correction code byte 2 of the sixth 7868c2ecf20Sopenharmony_ci 256 Bytes of data in this page 7878c2ecf20Sopenharmony_ci0x3A ECC byte 18 Error correction code byte 0 of the seventh 7888c2ecf20Sopenharmony_ci 256 Bytes of data in this page 7898c2ecf20Sopenharmony_ci0x3B ECC byte 19 Error correction code byte 1 of the seventh 7908c2ecf20Sopenharmony_ci 256 Bytes of data in this page 7918c2ecf20Sopenharmony_ci0x3C ECC byte 20 Error correction code byte 2 of the seventh 7928c2ecf20Sopenharmony_ci 256 Bytes of data in this page 7938c2ecf20Sopenharmony_ci0x3D ECC byte 21 Error correction code byte 0 of the eighth 7948c2ecf20Sopenharmony_ci 256 Bytes of data in this page 7958c2ecf20Sopenharmony_ci0x3E ECC byte 22 Error correction code byte 1 of the eighth 7968c2ecf20Sopenharmony_ci 256 Bytes of data in this page 7978c2ecf20Sopenharmony_ci0x3F ECC byte 23 Error correction code byte 2 of the eighth 7988c2ecf20Sopenharmony_ci 256 Bytes of data in this page 7998c2ecf20Sopenharmony_ci=========== ================== ================================================ 8008c2ecf20Sopenharmony_ci 8018c2ecf20Sopenharmony_ciFilesystem support 8028c2ecf20Sopenharmony_ci================== 8038c2ecf20Sopenharmony_ci 8048c2ecf20Sopenharmony_ciThe NAND driver provides all necessary functions for a filesystem via 8058c2ecf20Sopenharmony_cithe MTD interface. 8068c2ecf20Sopenharmony_ci 8078c2ecf20Sopenharmony_ciFilesystems must be aware of the NAND peculiarities and restrictions. 8088c2ecf20Sopenharmony_ciOne major restrictions of NAND Flash is, that you cannot write as often 8098c2ecf20Sopenharmony_cias you want to a page. The consecutive writes to a page, before erasing 8108c2ecf20Sopenharmony_ciit again, are restricted to 1-3 writes, depending on the manufacturers 8118c2ecf20Sopenharmony_cispecifications. This applies similar to the spare area. 8128c2ecf20Sopenharmony_ci 8138c2ecf20Sopenharmony_ciTherefore NAND aware filesystems must either write in page size chunks 8148c2ecf20Sopenharmony_cior hold a writebuffer to collect smaller writes until they sum up to 8158c2ecf20Sopenharmony_cipagesize. Available NAND aware filesystems: JFFS2, YAFFS. 8168c2ecf20Sopenharmony_ci 8178c2ecf20Sopenharmony_ciThe spare area usage to store filesystem data is controlled by the spare 8188c2ecf20Sopenharmony_ciarea placement functionality which is described in one of the earlier 8198c2ecf20Sopenharmony_cichapters. 8208c2ecf20Sopenharmony_ci 8218c2ecf20Sopenharmony_ciTools 8228c2ecf20Sopenharmony_ci===== 8238c2ecf20Sopenharmony_ci 8248c2ecf20Sopenharmony_ciThe MTD project provides a couple of helpful tools to handle NAND Flash. 8258c2ecf20Sopenharmony_ci 8268c2ecf20Sopenharmony_ci- flasherase, flasheraseall: Erase and format FLASH partitions 8278c2ecf20Sopenharmony_ci 8288c2ecf20Sopenharmony_ci- nandwrite: write filesystem images to NAND FLASH 8298c2ecf20Sopenharmony_ci 8308c2ecf20Sopenharmony_ci- nanddump: dump the contents of a NAND FLASH partitions 8318c2ecf20Sopenharmony_ci 8328c2ecf20Sopenharmony_ciThese tools are aware of the NAND restrictions. Please use those tools 8338c2ecf20Sopenharmony_ciinstead of complaining about errors which are caused by non NAND aware 8348c2ecf20Sopenharmony_ciaccess methods. 8358c2ecf20Sopenharmony_ci 8368c2ecf20Sopenharmony_ciConstants 8378c2ecf20Sopenharmony_ci========= 8388c2ecf20Sopenharmony_ci 8398c2ecf20Sopenharmony_ciThis chapter describes the constants which might be relevant for a 8408c2ecf20Sopenharmony_cidriver developer. 8418c2ecf20Sopenharmony_ci 8428c2ecf20Sopenharmony_ciChip option constants 8438c2ecf20Sopenharmony_ci--------------------- 8448c2ecf20Sopenharmony_ci 8458c2ecf20Sopenharmony_ciConstants for chip id table 8468c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~ 8478c2ecf20Sopenharmony_ci 8488c2ecf20Sopenharmony_ciThese constants are defined in rawnand.h. They are OR-ed together to 8498c2ecf20Sopenharmony_cidescribe the chip functionality:: 8508c2ecf20Sopenharmony_ci 8518c2ecf20Sopenharmony_ci /* Buswitdh is 16 bit */ 8528c2ecf20Sopenharmony_ci #define NAND_BUSWIDTH_16 0x00000002 8538c2ecf20Sopenharmony_ci /* Device supports partial programming without padding */ 8548c2ecf20Sopenharmony_ci #define NAND_NO_PADDING 0x00000004 8558c2ecf20Sopenharmony_ci /* Chip has cache program function */ 8568c2ecf20Sopenharmony_ci #define NAND_CACHEPRG 0x00000008 8578c2ecf20Sopenharmony_ci /* Chip has copy back function */ 8588c2ecf20Sopenharmony_ci #define NAND_COPYBACK 0x00000010 8598c2ecf20Sopenharmony_ci /* AND Chip which has 4 banks and a confusing page / block 8608c2ecf20Sopenharmony_ci * assignment. See Renesas datasheet for further information */ 8618c2ecf20Sopenharmony_ci #define NAND_IS_AND 0x00000020 8628c2ecf20Sopenharmony_ci /* Chip has a array of 4 pages which can be read without 8638c2ecf20Sopenharmony_ci * additional ready /busy waits */ 8648c2ecf20Sopenharmony_ci #define NAND_4PAGE_ARRAY 0x00000040 8658c2ecf20Sopenharmony_ci 8668c2ecf20Sopenharmony_ci 8678c2ecf20Sopenharmony_ciConstants for runtime options 8688c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 8698c2ecf20Sopenharmony_ci 8708c2ecf20Sopenharmony_ciThese constants are defined in rawnand.h. They are OR-ed together to 8718c2ecf20Sopenharmony_cidescribe the functionality:: 8728c2ecf20Sopenharmony_ci 8738c2ecf20Sopenharmony_ci /* The hw ecc generator provides a syndrome instead a ecc value on read 8748c2ecf20Sopenharmony_ci * This can only work if we have the ecc bytes directly behind the 8758c2ecf20Sopenharmony_ci * data bytes. Applies for DOC and AG-AND Renesas HW Reed Solomon generators */ 8768c2ecf20Sopenharmony_ci #define NAND_HWECC_SYNDROME 0x00020000 8778c2ecf20Sopenharmony_ci 8788c2ecf20Sopenharmony_ci 8798c2ecf20Sopenharmony_ciECC selection constants 8808c2ecf20Sopenharmony_ci----------------------- 8818c2ecf20Sopenharmony_ci 8828c2ecf20Sopenharmony_ciUse these constants to select the ECC algorithm:: 8838c2ecf20Sopenharmony_ci 8848c2ecf20Sopenharmony_ci /* No ECC. Usage is not recommended ! */ 8858c2ecf20Sopenharmony_ci #define NAND_ECC_NONE 0 8868c2ecf20Sopenharmony_ci /* Software ECC 3 byte ECC per 256 Byte data */ 8878c2ecf20Sopenharmony_ci #define NAND_ECC_SOFT 1 8888c2ecf20Sopenharmony_ci /* Hardware ECC 3 byte ECC per 256 Byte data */ 8898c2ecf20Sopenharmony_ci #define NAND_ECC_HW3_256 2 8908c2ecf20Sopenharmony_ci /* Hardware ECC 3 byte ECC per 512 Byte data */ 8918c2ecf20Sopenharmony_ci #define NAND_ECC_HW3_512 3 8928c2ecf20Sopenharmony_ci /* Hardware ECC 6 byte ECC per 512 Byte data */ 8938c2ecf20Sopenharmony_ci #define NAND_ECC_HW6_512 4 8948c2ecf20Sopenharmony_ci /* Hardware ECC 8 byte ECC per 512 Byte data */ 8958c2ecf20Sopenharmony_ci #define NAND_ECC_HW8_512 6 8968c2ecf20Sopenharmony_ci 8978c2ecf20Sopenharmony_ci 8988c2ecf20Sopenharmony_ciHardware control related constants 8998c2ecf20Sopenharmony_ci---------------------------------- 9008c2ecf20Sopenharmony_ci 9018c2ecf20Sopenharmony_ciThese constants describe the requested hardware access function when the 9028c2ecf20Sopenharmony_ciboardspecific hardware control function is called:: 9038c2ecf20Sopenharmony_ci 9048c2ecf20Sopenharmony_ci /* Select the chip by setting nCE to low */ 9058c2ecf20Sopenharmony_ci #define NAND_CTL_SETNCE 1 9068c2ecf20Sopenharmony_ci /* Deselect the chip by setting nCE to high */ 9078c2ecf20Sopenharmony_ci #define NAND_CTL_CLRNCE 2 9088c2ecf20Sopenharmony_ci /* Select the command latch by setting CLE to high */ 9098c2ecf20Sopenharmony_ci #define NAND_CTL_SETCLE 3 9108c2ecf20Sopenharmony_ci /* Deselect the command latch by setting CLE to low */ 9118c2ecf20Sopenharmony_ci #define NAND_CTL_CLRCLE 4 9128c2ecf20Sopenharmony_ci /* Select the address latch by setting ALE to high */ 9138c2ecf20Sopenharmony_ci #define NAND_CTL_SETALE 5 9148c2ecf20Sopenharmony_ci /* Deselect the address latch by setting ALE to low */ 9158c2ecf20Sopenharmony_ci #define NAND_CTL_CLRALE 6 9168c2ecf20Sopenharmony_ci /* Set write protection by setting WP to high. Not used! */ 9178c2ecf20Sopenharmony_ci #define NAND_CTL_SETWP 7 9188c2ecf20Sopenharmony_ci /* Clear write protection by setting WP to low. Not used! */ 9198c2ecf20Sopenharmony_ci #define NAND_CTL_CLRWP 8 9208c2ecf20Sopenharmony_ci 9218c2ecf20Sopenharmony_ci 9228c2ecf20Sopenharmony_ciBad block table related constants 9238c2ecf20Sopenharmony_ci--------------------------------- 9248c2ecf20Sopenharmony_ci 9258c2ecf20Sopenharmony_ciThese constants describe the options used for bad block table 9268c2ecf20Sopenharmony_cidescriptors:: 9278c2ecf20Sopenharmony_ci 9288c2ecf20Sopenharmony_ci /* Options for the bad block table descriptors */ 9298c2ecf20Sopenharmony_ci 9308c2ecf20Sopenharmony_ci /* The number of bits used per block in the bbt on the device */ 9318c2ecf20Sopenharmony_ci #define NAND_BBT_NRBITS_MSK 0x0000000F 9328c2ecf20Sopenharmony_ci #define NAND_BBT_1BIT 0x00000001 9338c2ecf20Sopenharmony_ci #define NAND_BBT_2BIT 0x00000002 9348c2ecf20Sopenharmony_ci #define NAND_BBT_4BIT 0x00000004 9358c2ecf20Sopenharmony_ci #define NAND_BBT_8BIT 0x00000008 9368c2ecf20Sopenharmony_ci /* The bad block table is in the last good block of the device */ 9378c2ecf20Sopenharmony_ci #define NAND_BBT_LASTBLOCK 0x00000010 9388c2ecf20Sopenharmony_ci /* The bbt is at the given page, else we must scan for the bbt */ 9398c2ecf20Sopenharmony_ci #define NAND_BBT_ABSPAGE 0x00000020 9408c2ecf20Sopenharmony_ci /* bbt is stored per chip on multichip devices */ 9418c2ecf20Sopenharmony_ci #define NAND_BBT_PERCHIP 0x00000080 9428c2ecf20Sopenharmony_ci /* bbt has a version counter at offset veroffs */ 9438c2ecf20Sopenharmony_ci #define NAND_BBT_VERSION 0x00000100 9448c2ecf20Sopenharmony_ci /* Create a bbt if none axists */ 9458c2ecf20Sopenharmony_ci #define NAND_BBT_CREATE 0x00000200 9468c2ecf20Sopenharmony_ci /* Write bbt if necessary */ 9478c2ecf20Sopenharmony_ci #define NAND_BBT_WRITE 0x00001000 9488c2ecf20Sopenharmony_ci /* Read and write back block contents when writing bbt */ 9498c2ecf20Sopenharmony_ci #define NAND_BBT_SAVECONTENT 0x00002000 9508c2ecf20Sopenharmony_ci 9518c2ecf20Sopenharmony_ci 9528c2ecf20Sopenharmony_ciStructures 9538c2ecf20Sopenharmony_ci========== 9548c2ecf20Sopenharmony_ci 9558c2ecf20Sopenharmony_ciThis chapter contains the autogenerated documentation of the structures 9568c2ecf20Sopenharmony_ciwhich are used in the NAND driver and might be relevant for a driver 9578c2ecf20Sopenharmony_cideveloper. Each struct member has a short description which is marked 9588c2ecf20Sopenharmony_ciwith an [XXX] identifier. See the chapter "Documentation hints" for an 9598c2ecf20Sopenharmony_ciexplanation. 9608c2ecf20Sopenharmony_ci 9618c2ecf20Sopenharmony_ci.. kernel-doc:: include/linux/mtd/rawnand.h 9628c2ecf20Sopenharmony_ci :internal: 9638c2ecf20Sopenharmony_ci 9648c2ecf20Sopenharmony_ciPublic Functions Provided 9658c2ecf20Sopenharmony_ci========================= 9668c2ecf20Sopenharmony_ci 9678c2ecf20Sopenharmony_ciThis chapter contains the autogenerated documentation of the NAND kernel 9688c2ecf20Sopenharmony_ciAPI functions which are exported. Each function has a short description 9698c2ecf20Sopenharmony_ciwhich is marked with an [XXX] identifier. See the chapter "Documentation 9708c2ecf20Sopenharmony_cihints" for an explanation. 9718c2ecf20Sopenharmony_ci 9728c2ecf20Sopenharmony_ci.. kernel-doc:: drivers/mtd/nand/raw/nand_base.c 9738c2ecf20Sopenharmony_ci :export: 9748c2ecf20Sopenharmony_ci 9758c2ecf20Sopenharmony_ci.. kernel-doc:: drivers/mtd/nand/raw/nand_ecc.c 9768c2ecf20Sopenharmony_ci :export: 9778c2ecf20Sopenharmony_ci 9788c2ecf20Sopenharmony_ciInternal Functions Provided 9798c2ecf20Sopenharmony_ci=========================== 9808c2ecf20Sopenharmony_ci 9818c2ecf20Sopenharmony_ciThis chapter contains the autogenerated documentation of the NAND driver 9828c2ecf20Sopenharmony_ciinternal functions. Each function has a short description which is 9838c2ecf20Sopenharmony_cimarked with an [XXX] identifier. See the chapter "Documentation hints" 9848c2ecf20Sopenharmony_cifor an explanation. The functions marked with [DEFAULT] might be 9858c2ecf20Sopenharmony_cirelevant for a board driver developer. 9868c2ecf20Sopenharmony_ci 9878c2ecf20Sopenharmony_ci.. kernel-doc:: drivers/mtd/nand/raw/nand_base.c 9888c2ecf20Sopenharmony_ci :internal: 9898c2ecf20Sopenharmony_ci 9908c2ecf20Sopenharmony_ci.. kernel-doc:: drivers/mtd/nand/raw/nand_bbt.c 9918c2ecf20Sopenharmony_ci :internal: 9928c2ecf20Sopenharmony_ci 9938c2ecf20Sopenharmony_ciCredits 9948c2ecf20Sopenharmony_ci======= 9958c2ecf20Sopenharmony_ci 9968c2ecf20Sopenharmony_ciThe following people have contributed to the NAND driver: 9978c2ecf20Sopenharmony_ci 9988c2ecf20Sopenharmony_ci1. Steven J. Hill\ sjhill@realitydiluted.com 9998c2ecf20Sopenharmony_ci 10008c2ecf20Sopenharmony_ci2. David Woodhouse\ dwmw2@infradead.org 10018c2ecf20Sopenharmony_ci 10028c2ecf20Sopenharmony_ci3. Thomas Gleixner\ tglx@linutronix.de 10038c2ecf20Sopenharmony_ci 10048c2ecf20Sopenharmony_ciA lot of users have provided bugfixes, improvements and helping hands 10058c2ecf20Sopenharmony_cifor testing. Thanks a lot. 10068c2ecf20Sopenharmony_ci 10078c2ecf20Sopenharmony_ciThe following people have contributed to this document: 10088c2ecf20Sopenharmony_ci 10098c2ecf20Sopenharmony_ci1. Thomas Gleixner\ tglx@linutronix.de 1010