Copy the directory or file below-RF from uboot to the corresponding directory of ppcboot
Drivers/Nand
Include/Linux/MTD
Include/NAND. h
Include/ASM-arm/IO. h
Add
# Define min (x, y )/
({Typeof (x) _ x = (x), _ y = (y );/
(_ X <_ y )? _ X: _ y ;})
# Define max (x, y )/
({Typeof (x) _ x = (x), _ y = (y );/
(_ X> _ y )? _ X: _ y ;})
# Define ipv_0000_nand 0x0000100000000000/* NAND support */
Add in include/comfigs/smdk2410.h
# Define pai_nand_base 0x4e00000c
# Define pai_max_nand_device 1
There are still some modifications that will be modified after compilation errors occur.
The main task is to add commands and modify the driver.
Temporarily add a simple command, nandinit, to initialize nandflash
Add performance_nand.h under include
# Ifndef _ assist_nand_h
# DEFINE _ assist_nand_h
# If (config_commands & cmd_cmd_nand)
# Define cmd_tbl_nandinit mk_cmd_tbl_entry (/
"Nandinit", 5, 1, 1, do_nandinit ,/
"Nandinit-init NAND Flash/N ",/
"/N nandinit-init NAND Flash/N "/
),
Int do_nandinit (cmd_tbl_t * cmdtp, int flag, int argc, char * argv []);
# Else
# Define pai_tbl_nandinit
# Endif/* 1__1__nand */
# Endif/* _ cmd_nand_h */
Then add the corresponding cmd_nand.c file in common to implement this command.
# Include <common. h>
# Include <command. h>
Extern void nand_init (void );
# If (config_commands & cmd_cmd_nand)
Int do_nandinit (cmd_tbl_t * cmdtp, int flag, int argc, char * argv [])
{
Ulong bank;
Nand_init ();
Return 0;
}
# Endif/* cfg_cmd_flash */
Modify makefile and add it to common/command. C.
# Include <cmd_nand.h>
Add cmd_tbl_nandinit to the macro array of the cmd_tbl command so that run_command can find the command.
The nandflash driver from uboot is basically the driver in the 2.6 kernel.
We only need to implement several lower-layer interface functions, and ppcboot is not used
In this way, the nandflash controller registers are operated directly.
Originally, these functions need to be placed in the Board/smdk2410 directory, but directly modify the driver for convenience.
The NAND. c file. The following is the code.
# Include <common. h>
# Include <ASM/IO. h>
# If (config_commands & cfg_assist_nand )&&! Defined (performance_nand_legacy)
# Include <NAND. h>
# Ifndef performance_nand_base_list
# Define pai_nand_base_list {pai_nand_base}
# Endif
# Define s3c2410_nfreg (x) (x + 0x4e000000)
# Define s3c2410_nfconf s3c2410_nfreg (0x00)
# Define s3c2410_nfcmd s3c2410_nfreg (0x04)
# Define s3c2410_nfaddr s3c2410_nfreg (0x08)
# Define s3c2410_nfdata s3c2410_nfreg (0x0c)
# Define s3c2410_nfstat s3c2410_nfreg (0x10)
# Define s3c2410_nfecc s3c2410_nfreg (0x14)
# Define s3c2410_nfconf_en (1 <15)
# Define s3c2410_nfconf_512byte (1 <14)
# Define s3c2410_nfconf_4step (1 <13)
# Define s3c2410_nfconf_initecc (1 <12)
# Define s3c2410_nfconf_nfce (1 <11)
# Define s3c2410_nfconf_tacls (x) <8)
# Define s3c2410_nfconf_twrph0 (x) <4)
# Define s3c2410_nfconf_twrph1 (x) <0)
# Define s3c2410_nfstat_busy (1 <0)
Void s3c2410_nand_inithw (void)
{
2010tacls, twrph0, twrph1;
2017-11-cfg = 0;
Tacls = 4;
Twrph0 = 8;
Twrph1 = 8;
CFG = s3c2410_nfconf_en;
CFG | = s3c2410_nfconf_tacls (tacls-1 );
CFG | = s3c2410_nfconf_twrph0 (twrph0-1 );
CFG | = s3c2410_nfconf_twrph1 (twrph1-1 );
Writew (CFG, s3c2410_nfconf );
}
Static void s3c2410_nand_hwcontrol (struct mtd_info * MTD, int cmd)
{
Struct nand_chip * chip = MTD-> priv;
Switch (CMD ){
Case nand_ctl_setnce:
Writew (readw (s3c2410_nfconf )&~ S3c2410_nfconf_nfce, s3c2410_nfconf );
Break;
Case nand_ctl_clrnce:
Writew (readw (s3c2410_nfconf) | s3c2410_nfconf_nfce, s3c2410_nfconf );
Break;
Case nand_ctl_setcle:
Chip-> io_addr_w = (void _ iomem *) s3c2410_nfcmd;
Break;
Case nand_ctl_setale:
Chip-> io_addr_w = (void _ iomem *) s3c2410_nfaddr;
Break;
/* Nand_ctl_clrcle :*/
/* Nand_ctl_clrale :*/
Default:
Chip-> io_addr_w = (void _ iomem *) s3c2410_nfdata;
Break;
}
}
Static int s3c2410_nand_devready (struct mtd_info * MTD)
{
Return readb (s3c2410_nfstat) & s3c2410_nfstat_busy;
}
Void board_nand_init (struct nand_chip * NAND)
{
S3c2410_nand_inithw ();
Nand-> hwcontrol = s3c2410_nand_hwcontrol;
Nand-> dev_ready = s3c2410_nand_devready;
Nand-> chip_delay = 50;
Nand-> Options = 0;
Nand-> eccmode = nand_ecc_soft;
}
Int nand_curr_device =-1;
Nand_info_t nand_info [pai_max_nand_device];
Static struct nand_chip [performance_max_nand_device];
Static ulong base_address [pai_max_nand_device] = pai_nand_base_list;
Static const char default_nand_name [] = "NAND ";
Static void nand_init_chip (struct mtd_info * MTD, struct nand_chip * nand,
Ulong base_addr)
{
MTD-> priv = NAND;
Nand-> io_addr_r = NAND-> io_addr_w = (void _ iomem *) base_addr;
Board_nand_init (NAND );
If (nand_scan (MTD, 1) = 0 ){
If (! MTD-> name)
MTD-> name = (char *) default_nand_name;
} Else
MTD-> name = NULL;
}
Void nand_init (void)
{
Int I;
Unsigned int size = 0;
For (I = 0; I <cfg_max_nand_device; I ++ ){
Nand_init_chip (& nand_info [I], & nand_chip [I], base_address [I]);
Size + = nand_info [I]. size;
If (nand_curr_device =-1)
Nand_curr_device = I;
}
Printf ("NAND Flash % DM/N", size/(1024*1024 ));
}
# Endif
It is easy to understand, and then you can add the nandflash command on this basis.
You can also add the command to start wince to implement both Linux and wince systems.