⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmd_nand_s3c2440a.c

📁 F:worksip2440a board可启动u-boot-like.tar.gz F:worksip2440a board可启动u-boot-like.tar.gz
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * (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 + -