Tiny210 (s5pv210) Port U-boot (based on version 2014.4) -- NAND 8-bit hardware ECC

Source: Internet
Author: User

In this section, we implement the nand ecc and save the environment variables to the NAND Flash. Then, we will write the previous LED light into NAND Flash and start it on. In tiny210.h, we will define macro config_s5pv210_nand_hwecc, config_sys_nand_eccsize, config_sys_nand_eccbytes


Config_sys_nand_eccsize defines the message length, that is, the number of bytes per ECC verification
Config_sys_nand_eccbytes is defined as 13 bytes. Replace config_s3c2410_nand_hwecc in drivers/MTD/NAND/s5pv210_nand.c with handler. We only perform ECC verification writes. ECC verification reads the functions provided by Samsung, we must store the ECC verification code in the storage format of the spare field specified in the Samsung manual.


Therefore, we need to customize the nand_ecclayout struct. This struct describes how to store ECC data and assigns this struct to NAND> ECC. layout.



For other code, see the source code:

/** (C) Copyright 2006 openmoko, Inc. * Author: Harald welte <[email protected]> ** spdx-license-identifier: GPL-2.0 + */# include <Common. h> # include <NAND. h> # include <ASM/ARCH/nand_reg.h> # include <ASM/Io. h> # define mp0_1con (* (volatile u32 *) con) # definemp0_3con (* (volatile u32 *) 0xe0200320) # define (* (volatile u32 *) 0xe0200380) /* modied by SHL */static void s5pv210_hwcontrol (struct MTD _ INFO * MTD, int cmd, unsigned int CTRL) {struct nand_chip * chip = MTD-> priv; struct s5pv210_nand * NAND = (struct s5pv210_nand *) samsung_get_base_nand (); debug ("hwcontrol (): 0x % 02x 0x % 02x \ n", CMD, CTRL); ulong io_addr_w = (ulong) nand; If (CTRL & nand_ctrl_change) {If (CTRL & nand_cle) io_addr_w = io_addr_w | 0x8;/* command register */else if (CTRL & nand_ale) io_addr_w = io_addr_w | 0xc;/* address registe R */chip-> io_addr_w = (void *) io_addr_w; If (CTRL & nand_nce)/* select */writel (readl (& NAND-> nfcont )&~ (1 <1), & NAND-> nfcont); else/* deselect */writel (readl (& NAND-> nfcont) | (1 <1 ), & NAND-> nfcont);} If (CMD! = Nand_assist_none) writeb (CMD, chip-> io_addr_w); elsechip-> io_addr_w = & NAND-> nfdata;} static int s5pv210_dev_ready (struct mtd_info * MTD) {struct s5pv210_nand * NAND = (struct s5pv210_nand *) samsung_get_base_nand (); debug ("dev_ready \ n"); Return readl (& NAND-> nfstat) & 0x01 ;} # ifdef config_s5pv210_nand_hweccvoid s5pv210_nand_enable_hwecc (struct mtd_info * MTD, int mode) {struct s5pv210_nand * NAND = (struct s5pv2 10_nand *) samsung_get_base_nand (); debug ("s5pv210_nand_enable_hwecc (% P, % d) \ n", MTD, mode); writel (readl (& NAND-> nfconf) | (0x3 <23), & NAND-> nfconf); If (mode = nand_ecc_read) {} else if (mode = nand_ecc_write) {/* set 8/12/16bit ECC ction to encoding */writel (readl (& NAND-> nfecccont) | (0x1 <16), & NAND-> nfecccont ); /* clear 8/12/16bit ECC encode done */writel (readl (& NAND-> nfeccstat) | (0x1 <25 ), & NAND-> nfeccstat);}/* initialize main area ECC Decoder/encoder */writel (readl (& NAND-> nfcont) | (0x1 <5), & NAND-> nfcont);/* the ECC Message Size (for 512-byte message, you shoshould set 511) * 8-bit ECC/512b */writel (511 <16) | 0x3, & NAND-> nfeccconf); writel (readl (& NAND-> nfstat) | (0x1 <4) | (0x1 <5), & NAND-> nfstat ); /* initialize main area ECC Decoder/encoder */writel (readl (& NAND-> nfecccont) | (0x1 <2), & NAND-> nfecccont);/* unlock main area ECC */writel (readl (& NAND-> nfcont )&~ (0x1 <7), & NAND-> nfcont);}/* modied by SHL */static int s5pv210_nand_calculate_ecc (struct mtd_info * MTD, const u_char * dat, u_char * ecc_code) {struct s5pv210_nand * NAND = (struct s5pv210_nand *) Forward (); u32 nfeccprgecc0 = 0, forward = 0, nfeccprgecc2 = 0, nfeccprgecc3 = 0; /* Lock main area ECC */writel (readl (& NAND-> nfcont) | (1 <7), & NAND-> nfcont ); /* read 13 bytes of ECC Code */NFEC Cprgecc0 = readl (& NAND> nfeccprgecc0); nfeccprgecc1 = readl (& NAND-> nfeccprgecc1); nfeccprgecc2 = readl (& NAND-> nfeccprgecc2 ); nfeccprgecc3 = readl (& NAND-> nfeccprgecc3); ecc_code [0] = nfeccprgecc0 & 0xff; ecc_code [1] = (nfeccprgecc0> 8) & 0xff; ecc_code [2] = (nfeccprgecc0> 16) & 0xff; ecc_code [3] = (nfeccprgecc0> 24) & 0xff; ecc_code [4] = nfeccprgecc1 & 0xff; ecc_code [5] = (nfeccprgecc1> 8) & 0xff; EC C_code [6] = (nfeccprgecc1> 16) & 0xff; ecc_code [7] = (nfeccprgecc1> 24) & 0xff; ecc_code [8] = nfeccprgecc2 & 0xff; ecc_code [9] = (nfeccprgecc2> 8) & 0xff; ecc_code [10] = (nfeccprgecc2> 16) & 0xff; ecc_code [11] = (nfeccprgecc2> 24) & 0xff; ecc_code [12] = nfeccprgecc3 & 0xff; debug ("s5pv210_nand_calculate_hwecc (% P ,): \ n "" 0x % 02x 0x % 02x 0x % 02x 0x % 02x 0x % 02x 0x % 02x 0x % 02x 0x % 02x 0x % 02x 0x % 02x \ n "0x % 0 2x 0x % 02x 0x % 02x \ n ", MTD, ecc_code [0], ecc_code [1], ecc_code [2], ecc_code [3], ecc_code [4], ecc_code [5], ecc_code [6], ecc_code [7], ecc_code [8], ecc_code [9], ecc_code [10], ecc_code [11], ecc_code [12]); Return 0;}/* Add by SHL */# define nf8_readpage_adv (A, B, C) (INT (*) (u32, u32, u8 *) (* (u32 *) 0xd0037f90) (a, B, c) Static int s5pv210_nand_read_page_hwecc (struct mtd_info * MTD, struct nand_chip * chip, UI Nt8_t * Buf, int oob_required, int page) {/* One block 64 pages of NAND Flash used by tiny210 */return nf8_readpage_adv (page/64, Page % 64, Buf );} static int s5pv210_nand_correct_data (struct mtd_info * MTD, u_char * dat, u_char * read_ecc, u_char * calc_ecc) {If (read_ecc [0] = calc_ecc [0] & read_ecc [1] = calc_ecc [1] & read_ecc [2] = calc_ecc [2]) return 0; printf ("s5pv210_nand_correct_data: not implemented \ n"); Return-1 ;}# E Ndif/** add by SHL * nand_select_chip * @ MTD: MTD device structure * @ CTL: 0 to select,-1 for deselect ** default select function for 1 chip devices. */static void s5pv210_nand_select_chip (struct mtd_info * MTD, int CTL) {struct nand_chip * chip = MTD-> priv; Switch (CTL) {Case-1: /* deselect the chip */chip-> 1__ctrl (MTD, nand_1__none, 0 | nand_ctrl_change); break; Case 0:/* select the chip */chip-> Export _ctrl (MTD, nand_assist_none, nand_nce | nand_ctrl_change); break; default: Bug () ;}/ * Add by SHL */static struct nand_ecclayout nand_oob_64 = {. eccbytes = 52,/* 2048/512*13 */. eccpos = {12, 13, 14, 15, 16, 17, 18, 19, 20, 21,22, 23, 24, 25, 26, 27, 28, 29, 30,, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 53, 54, 55, 56, 57, 58, 59, 60, 63},/* 0 and 1 are used for warranty Bad Block mark, 12 ~ 63 save ECC, 2 ~ remaining ~ 11 is free */. oobfree = {{. offset = 2 ,. length = 10 }};/* modied by SHL */INT board_nand_init (struct nand_chip * NAND) {u32 CFG = 0; struct s5pv210_nand * nand_reg = (struct s5pv210_nand *) (struct s5pv210_nand *) samsung_get_base_nand (); debug ("board_nand_init () \ n");/* initialize hardware * // * hclk_psys = 133 MHz (7.5ns) */CFG = (0x1 <23) |/* disable 1-bit and 4-bit ECC * // The following three time parameters are slightly greater than the calculated values (I will add 1 here ), otherwise, the read and write operations are unstable. */(0x3 <12) |/* 7.5ns * 2> 12ns TALs tcls */(0x2 <8) |/* (1 + 1) * 7.5ns> 12ns (TWP) */(0x1 <4) |/* (0 + 1) * 7.5> 5ns (tclh/talh) */(0x0 <3) |/* slc nand Flash */(0x0 <2) |/* 2 Kbytes/page */(0x1 <1);/* 5 address cycle */writel (CFG, & nand_reg-> nfconf ); writel (0x1 <1) | (0x1 <0), & nand_reg-> nfcont ); /* disable chip select and enable NAND Flash Controller * // * config gpio */mp0_1con & = ~ (0 xFFFF <8); mp0_1con | = (0x3333 <8); mp0_3con = 0x22222222; mp0_6con = 0x22222222; /* initialize nand_chip Data Structure */NAND-> io_addr_r = (void *) & nand_reg-> nfdata; NAND-> io_addr_w = (void *) & nand_reg-> nfdata; nand-> select_chip = s5pv210_nand_select_chip; /* read_buf and write_buf are default * // * read_byte and write_byte are default * // * hwcontrol always must be implemented */NAND-> export _ctrl = s5pv210_hwcontrol; nand-> dev_ready = s5pv210_dev_ready; # ifdef config_s5pv210_nand_hweccnand-> ECC. hwctl = s5pv210_nand_enable_hwecc; NAND-> ECC. calculate = s5pv210_nand_calculate_ecc; NAND-> ECC. correct = s5pv210_nand_correct_data; NAND-> ECC. mode = nand_ecc_hw; NAND-> ECC. size = config_sys_nand_eccsize; NAND-> ECC. bytes = config_sys_nand_eccbytes; NAND-> ECC. strength = 1;/* Add by SHL */NAND-> ECC. layout = & nand_oob_64; NAND-> ECC. read_page = s5pv210_nand_read_page_hwecc; # elsenand-> ECC. mode = nand_ecc_soft; # endif # ifdef config_s3c2410_nand_bbtnand-> bbt_options | = nand_bbt_use_flash; # endifdebug ("End of nand_init \ n"); Return 0 ;}

Re-compile, successfully generate u-boot.bin, burn it to SD card sector 32, start the development board from SD card:


Next we will conduct the NAND startup test, burn the previous led program to nand, and then start from NAND to see the effect of full LEDs. First, compile led. C to generate led. Bin, add the header information of 16b to generate 210.bin, and then copy 210.bin to the TFTP Server Directory.


Run the latest U-boot command to write 210.bin to page 0th of NAND, and then start



From the NAND start, we can see that all four LEDs are on.


Tiny210 (s5pv210) Port U-boot (based on version 2014.4) -- NAND 8-bit hardware ECC

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.