📄 cmd_nand_s3c2440a.c
字号:
/* * (C) Samsung Electronics * SW.LEE <hitchcar@samsung.com> * - add nandE, 16Bit NAND * - delete dummy code for S3C2440A * (C) Samsung Electrocnis * getfree * * Driver for NAND support, Rick Bronson * borrowed heavily from: * (c) 1999 Machine Vision Holdings, Inc. * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> */#include <common.h>#include <command.h>#include <malloc.h>#include <asm/io.h>#include <s3c2440aa.h>#ifdef CONFIG_SHOW_BOOT_PROGRESS# include <status_led.h># define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg)#else# define SHOW_BOOT_PROGRESS(arg)#endif#if (CONFIG_COMMANDS & CFG_CMD_NAND)#include <linux/mtd/nandaa.h>#include <linux/mtd/nand_ids.h>#define BAD_CHECK (0)#define ECC_CHECK (0)#define __SMDK2440_NAND_H#define CFG_ENV_NAND_BLOCK 8#define NAND_OOB_SIZE (16)#define NAND_PAGES_IN_BLOCK (32)#define NAND_PAGE_SIZE (512)#define NAND_BLOCK_SIZE (NAND_PAGE_SIZE*NAND_PAGES_IN_BLOCK)#define NAND_BLOCK_CNT (4096)#define NAND_BLOCK_MASK (NAND_BLOCK_SIZE - 1)#define NAND_PAGE_MASK (NAND_PAGE_SIZE - 1)//#define NAND_3_ADDR_CYCLE 1//#define S3C24X0_16BIT_NAND 1/* mark bad block */#define NF_BB_ON 1#define NF_BB_OFF 0/* NAND R/W status */#define NF_RW_NORMAL 1 /* default */#define NF_RW_YAFFS 2 /* yaffs image r/w */ /* NAND R/W ECC status */#define NF_USE_ECC 1 #define NF_USE_MTD_ECC 2#define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1)))u8 NF8_Spare_Data[16];#define FAIL 0#define OK 1static u8 NF_CheckId(void);static int NF_EraseBlock(u32 blockNum);static int NF_ReadPage(u32 block, u32 page, u8 *buffer);static int NF_WritePage(u32 block, u32 page, u8 *buffer);static int NF_IsBadBlock(u32 block);static int NF_MarkBadBlock(u32 block, int mark_flag);static void NF_Reset(void);static void NF_Init(void);static int NF_WriteOob(u32 block, u32 page, u8 *buffer, int yaffs_option);int s3c24x0_nand_write(uint targetBlock,uint targetSize, uint srcAddress, int flag, int yaffs_option ){ int i; int programError=0; u8 *srcPt,*saveSrcPt; u32 blockIndex; printf("NAND Flash writing\n"); printf("Source base address =0x%x\n",srcAddress); printf("Target start block number=%d\n",targetBlock); printf("Target size (0x4000*n) =0x%x\n",targetSize); srcPt=(u8 *)srcAddress; blockIndex=targetBlock; while(1) { saveSrcPt=srcPt; #if BAD_CHECK if(NF_IsBadBlock(blockIndex)) { // 1:bad 0:good blockIndex++; // for next block continue; }#endif if(!NF_EraseBlock(blockIndex)) { blockIndex++; // for next block printf(" Error-> Erase Block %d \n",(int)blockIndex); continue; } for(i=0; i< NAND_PAGES_IN_BLOCK ;i++) { if(!NF_WritePage(blockIndex,i,srcPt)) { // block num, page num, buffer programError=1; break; }#if ECC_CHECK if ( flag != NF_RW_YAFFS ) { if(!NF_ReadPage(blockIndex,i,srcPt)) { printf("ECC Error(block=%d,page=%d!!!\n",(int)blockIndex,i); } }#endif srcPt += NAND_PAGE_SIZE; if ( flag == NF_RW_YAFFS ) { if (!NF_WriteOob(blockIndex,i,srcPt, yaffs_option)) { programError = 1; break; } srcPt += NAND_OOB_SIZE; } printf("."); if((u32)srcPt>=(srcAddress+targetSize)) // Check end of buffer break; // Exit for loop } if(programError==1) { blockIndex++; srcPt=saveSrcPt; programError=0; continue; } if((u32)srcPt>=(srcAddress+targetSize)) break; // Exit while loop blockIndex++; } printf("\n\n"); return 0;}int do_nande (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){ int startblk, size,eraseblocks,i; if ( argc != 3 ){ printf ("Usage:\n%s\n", cmdtp->usage); return 1; } startblk = simple_strtoul(argv[1], NULL, 16); size = simple_strtoul(argv[2], NULL, 16); printf("StartBlock %d (0x%x) : Size %d (0x%x) \n",startblk,startblk,size, size); eraseblocks = size / NAND_BLOCK_SIZE; printf("Total Erase Blocks %d (0x%x) \n",eraseblocks, eraseblocks); NF_Init(); NF_Reset(); for ( i=0 ; i < eraseblocks; i++) { NF_EraseBlock(startblk); NF_CheckBadNande(startblk); startblk++; } return 0;}int do_nandE (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){ int startblk, size,eraseblocks,i; if ( argc != 3 ){ printf ("Usage:\n%s\n", cmdtp->usage); return 1; } startblk = simple_strtoul(argv[1], NULL, 16); size = simple_strtoul(argv[2], NULL, 16); printf("StartBlock %d (0x%x) : Size %d (0x%x) \n",startblk,startblk,size, size); eraseblocks = size / NAND_BLOCK_SIZE; printf("Total Erase Blocks %d (0x%x) \n",eraseblocks, eraseblocks); NF_Init(); NF_Reset(); for ( i=0 ; i < eraseblocks; i++) { NF_EraseBlock(startblk); startblk++; } return 0;}int do_nandw (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){ ulong startblk,size,memadr; if (argc != 4) { printf ("Usage:\n%s\n", cmdtp->usage); return 1; } startblk = simple_strtoul(argv[1], NULL, 16); size = simple_strtoul(argv[2], NULL, 16); memadr = simple_strtoul(argv[3], NULL, 16); NF_Init(); NF_Reset(); s3c24x0_nand_write(startblk,size,memadr, NF_RW_NORMAL, 0 ); return 0;}int do_nandyw (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){ ulong startblk,size,memadr; int ecc_option; if (argc != 5) { printf ("Usage:\n%s\n", cmdtp->usage); return 1; } startblk = simple_strtoul(argv[1], NULL, 16); size = simple_strtoul(argv[2], NULL, 16); memadr = simple_strtoul(argv[3], NULL, 16); ecc_option = (argv[4][0] == 'y') ? NF_USE_ECC : NF_USE_MTD_ECC; // yaffs image don't use 1st block startblk++; NF_Init(); NF_Reset(); s3c24x0_nand_write(startblk, size, memadr, NF_RW_YAFFS, ecc_option ); return 0;}extern int nandll_read_blocks(unsigned long, unsigned long, int);int do_nandr (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){ ulong startblk,size,memadr; if (argc != 4) { printf ("Usage:\n%s\n", cmdtp->usage); return 1; } startblk = NAND_BLOCK_SIZE*simple_strtoul(argv[1], NULL, 16); size = simple_strtoul(argv[2], NULL, 16); memadr = simple_strtoul(argv[3], NULL, 16); NF_Init(); NF_Reset(); nandll_read_blocks(memadr,startblk,size); return 0;}U_BOOT_CMD( nandw, 4, 1, do_nandw, "nandw HEX: targetblock targetsize mem_addr \n", "\n - SMDK24X0 NAND Flash Write Program\n" \ "nandw targetblock 0~4096, targetsize memory addr \n" \);U_BOOT_CMD( nandyw, 5, 1, do_nandyw, "nandyw - HEX: targetblock targetsize mem_addr ecc_option(y/m)\n", "\n - SMDK24X0 NAND Flash Write Command for Yaffs\n" \ "nandyw targetblock 0~0xfff(4095), targetsize memory addr \n" \ " ecc_option : [y] : use yaffs ecc / [m] : use mtd ecc \n" \);U_BOOT_CMD( nande, 4, 1, do_nande, "nande startBlock size \n", " - delete blocks while skipping bad block \n" \);U_BOOT_CMD( nandE, 4, 1, do_nandE, "nandE startBlock size \n", " - delete all blocks in given range regardless Bad Blcok\n" \);U_BOOT_CMD( nandr, 4, 1, do_nandr, "nandr - HEX: targetblock targetsize mem_adr \n", "\n -SMDK24X0 NAND Flash Read Program\n" \ "nandw targetblock 0~4096, targetsize memory addr \n" \);#define NF_SOFT_UnLock() {NFCONT&=~(1<<12);}#define NF_MECC_UnLock() {NFCONT&=~(1<<5);}#define NF_MECC_Lock() {NFCONT|=(1<<5);}#define NF_SECC_UnLock() {NFCONT&=~(1<<6);}#define NF_SECC_Lock() {NFCONT|=(1<<6);}#define NF_nFCE_L() {NFCONT&=~(1<<1);}#define NF_nFCE_H() {NFCONT|=(1<<1);}#define NF_RSTECC() {NFCONT|=(1<<4);}#define NF_CLEAR_RB() {NFSTAT |= (1<<2);}#define NF_DETECT_RB() {while(!(NFSTAT&(1<<2)));}#define TACLS 7 // 1-clk(0ns) #define TWRPH0 7 // 3-clk(25ns)#define TWRPH1 7 // 1-clk(10ns) //TACLS+TWRPH0+TWRPH1>=50nsstatic u8 se8Buf[16]={ 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff};static u32 se16Buf[32/2]={ 0xffffffff,0xffffffff,0xffffffff,0xffffffff, 0xffffffff,0xffffffff,0xffffffff,0xffffffff, 0xffffffff,0xffffffff,0xffffffff,0xffffffff, 0xffffffff,0xffffffff,0xffffffff,0xffffffff};static u8 seBuf[16]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};static int NF_MarkBadBlock(u32 block, int mark_flag){ int i; u32 blockPage = block * NAND_PAGES_IN_BLOCK;#ifdef S3C24X0_16BIT_NAND u16 *Buf = (unsigned short *) seBuf;#endif#ifdef S3C24X0_16BIT_NAND seBuf[0]=0x00; seBuf[1]=0x00; seBuf[2]=0xff; seBuf[3]=0xff; seBuf[5]=0xff; // Bad blcok mark=0#else seBuf[0]=0xff; seBuf[1]=0xff; seBuf[2]=0xff; //seBuf[3]=0xff; seBuf[5]=0x44; // Bad blcok mark=0 if ( mark_flag == NF_BB_OFF ) seBuf[5] = 0xff;#endif // NF_CLRRnB(); NF_nFCE_L(); NFCMD = NAND_CMD_READOOB; NFCMD = NAND_CMD_SEQIN; NFADDR = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -