Exemple #1
0
/*
 * check block is bad?
 * return 1 if it's a bad block, 0 if it's good.
 */
int K9F2G08_Check_badblk(u32 block)
{
    u8 data;
    u32 _page;/* frist page in block */
    
    _page = block*PAGES_PER_BLOCK;	/* For 2'nd cycle I/O[7:5] */
    
    nand_cs_en();
	    
    nand_write_cmd(NAND_CMD_READ0);		  	/* Spare array read command	*/
    nand_write_addr(PAGE_DATA_SIZE&0xff); 	/* Read the mark of bad block in spare array(M addr=5) */
	nand_write_addr((PAGE_DATA_SIZE>>8)&0xff); 
    nand_write_addr(_page&0xff);		  	/* The mark of bad block is in 0 page */
    nand_write_addr((_page>>8)&0xff);   	/* For block number A[24:17] */
    nand_write_addr((_page>>16)&0xff);  	/* For block number A[25] */
	nand_write_cmd(NAND_CMD_READSTART);

    nand_wait();	/* Wait tR(max 12us) */
    
    data=nand_read();
    nand_cs_ds();    
    if(data==0x00)
    	return 1;/* bad */
    else
    	return 0;/* good */
}
Exemple #2
0
int K9F2G08_ReadChunk(u32 chunk, u8 *data, u8 *tags)
{
    int i;

    nand_cs_en(); 
	   
    nand_write_cmd(NAND_CMD_READ0);
	nand_write_addr(0x00);
	nand_write_addr(0x00);
    nand_write_addr(chunk & 0xff);
    nand_write_addr((chunk >> 8) & 0xff);
    nand_write_addr((chunk >> 16) & 0xff);  //
	/* nand_Init_ECC(); */
	nand_write_cmd(NAND_CMD_READ30);

    nand_wait();    /* Wait tR(max 12us) */

    for(i = 0; i < PAGE_DATA_SIZE; i++)
	{	
    	data[i] = nand_read();	/* Read page data */
	}
    for(i = 0; i < PAGE_SPARE_SIZE; i++)
	{	
    	tags[i] = nand_read();	/* Read spare array	*/
    }

    nand_cs_ds();    

	return 1;
}
Exemple #3
0
/*
 * write one page data
 * return 0,successful
 * return 1,error
 */
int K9F2G08_WritePage(u32 block, u32 page, const u8 *buffer, int len, const u8 *ecc)
{
    int i,stat;

	u32 _page = block*PAGES_PER_BLOCK + page;

    /* nand_Init_ECC(); */  /* nitialize ECC */
    
    nand_cs_en(); 

    nand_write_cmd(NAND_CMD_SEQIN);
	for(i=0;i<10;i++); 
    nand_write_addr(0x00);			    /* Column 0	*/
	nand_write_addr(0x00);
    nand_write_addr(_page&0xff);
    nand_write_addr((_page>>8)&0xff);
    nand_write_addr((_page>>16)&0xff);

    for(i=0;i<len;i++)
    {
		nand_write(*buffer++);
    }  
    nand_write_cmd(NAND_CMD_PAGEPROG);

    nand_wait();    /* wait tPROG 200~500us; */
 
	stat = read_nand_stats();
    nand_cs_ds();

	return stat;
}
Exemple #4
0
int K9F2G08_ReadTags(u32 block, u32 page, u8 *spare, int ofs, int len)
{
    int i;

	u32 _page = block*PAGES_PER_BLOCK + page;

	/* NF_RSTECC(); */ /* Initialize ECC */
    
    nand_cs_en(); 
	   
    nand_write_cmd(NAND_CMD_READ0);
    nand_write_addr((PAGE_DATA_SIZE+ofs)&0xff);
	nand_write_addr(((PAGE_DATA_SIZE+ofs)>>8)&0xff);
    nand_write_addr(_page&0xff);
    nand_write_addr((_page>>8)&0xff); 
    nand_write_addr((_page>>16)&0xff);

	nand_write_cmd(NAND_CMD_READSTART);
    
    nand_wait();    /* Wait tR(max 12us) */
    for(i=0;i<len;i++)
    {
    	spare[i] = nand_read();	/* Read one page */
    }

    nand_cs_ds();    
   	
	return 1;
}
Exemple #5
0
int K9F2G08_ReadPage(u32 block, u32 page, u8 *buffer, int len, u8 *ecc)
{
    int i;
    u32 _page = block*PAGES_PER_BLOCK + page;
    
	/* NF_RSTECC(); */ /* Initialize ECC*/
    
    nand_cs_en(); 
	   
    nand_write_cmd(NAND_CMD_READ0);   	/* Read command */
    nand_write_addr(0x00);				/* Column = 0 */
	nand_write_addr(0x00);
    nand_write_addr(_page&0xff);
    nand_write_addr((_page>>8)&0xff);
    nand_write_addr((_page>>16)&0xff); 

	nand_write_cmd(NAND_CMD_READSTART);
    
    nand_wait();    /* Wait tR(max 12us) */
    for(i=0;i<len;i++)
    {
    	buffer[i] = nand_read();	/* Read one page */
    }

    nand_cs_ds();    
   	
	return 1;
}
Exemple #6
0
/*
 * mark a block is bad
 * return 0 if ok, 1:fail
 */
int K9F2G08_Mark_badblk(u32 block)
{
	u8 stat;
    u32 _page = block*PAGES_PER_BLOCK; 
    
    nand_cs_en(); 

    nand_write_cmd(NAND_CMD_SEQIN);   	/* Write 1st command */
    
    nand_write_addr(PAGE_DATA_SIZE & 0xff);/* The mark of bad block	*/
	nand_write_addr((PAGE_DATA_SIZE>>8)&0xff);
    nand_write_addr(_page&0xff);	    /* marked 1th spare array */
    nand_write_addr((_page>>8)&0xff);   /* in the 1st page. */
    nand_write_addr((_page>>16)&0xff); 
    
    nand_write(0x00);	/* 0x00 is commendatory make of the bad block. */

    nand_write_cmd(NAND_CMD_PAGEPROG);   /* Write 2nd command */

    nand_wait();      /* Wait tPROG(200~500us) */
    stat = read_nand_stats();
	nand_cs_ds();

    return stat;
}
Exemple #7
0
static void nand_reset(){
   int i;

   nand_select();
   NFCMD=NAND_CMD_RESET;
   for(i=0;i<10;i++);  
   nand_wait();  
   nand_deselect();
}
Exemple #8
0
void K9F2G08_Reset(void)
{
    nand_cs_en();

    nand_write_cmd(0xFF);	/* reset command */

    nand_wait();      /* wait 200~500us */
    nand_cs_ds();

	K9F2G08_Init();
}
Exemple #9
0
/*
 *erase a block
 *return 0,successful
 *return 1,error
 */
int K9F2G08_EraseBlock(u32 block)
{
	int stat;
	u32 _page = block*PAGES_PER_BLOCK;
    
    nand_cs_en();
    
    nand_write_cmd(NAND_CMD_ERASE1);   /* Erase one block 1st command */

    nand_write_addr(_page&0xff);	    /* Page number=0 */
    nand_write_addr((_page>>8)&0xff);   
    nand_write_addr((_page>>16)&0xff);

    nand_write_cmd(NAND_CMD_ERASE2);   /* Erase one blcok 2nd command */
    
	nand_wait();    /* Wait tBERS max 3ms. */

    stat = read_nand_stats();
	nand_cs_ds();
	return stat;
}
Exemple #10
0
int K9F2G08_WriteTags(u32 block, u32 page, const u8 *spare, int ofs, int len)
{
    int i,stat;
	u32 _page = block*PAGES_PER_BLOCK + page;

    /* nand_Init_ECC(); */  /* Initialize ECC */
    
    nand_cs_en(); 

    nand_write_cmd(NAND_CMD_SEQIN);
	for(i=0;i<10;i++); 
    nand_write_addr((PAGE_DATA_SIZE+ofs)&0xff);
	nand_write_addr(((PAGE_DATA_SIZE+ofs)>>8)&0xff);
    nand_write_addr(_page&0xff);
    nand_write_addr((_page>>8)&0xff);
    nand_write_addr((_page>>16)&0xff);

    for(i=0;i<len;i++)
    {
		nand_write(*spare++);
    }   

    nand_write_cmd(NAND_CMD_PAGEPROG);

    nand_wait();    /* wait tPROG 200~500us; */
 
	stat = read_nand_stats();
    if(!stat) /* Page write error */
    {	
    	nand_cs_ds();
		return 0;
    }
    else 
    {
    	nand_cs_ds();
		return 1;
    }
}
static void nand_load(unsigned int offs, int uboot_size, uchar *dst)
{
	fsl_lbus_t *regs = (fsl_lbus_t *)(CONFIG_SYS_IMMR + 0x5000);
	uchar *buf = (uchar *)CONFIG_SYS_NAND_BASE;
	int large = in_be32(&regs->bank[0].or) & OR_FCM_PGS;
	int block_shift = large ? 17 : 14;
	int block_size = 1 << block_shift;
	int page_size = large ? 2048 : 512;
	int bad_marker = large ? page_size + 0 : page_size + 5;
	int fmr = (15 << FMR_CWTO_SHIFT) | (2 << FMR_AL_SHIFT) | 2;
	int pos = 0;

	if (offs & (block_size - 1)) {
		puts("bad offset\n");
		for (;;);
	}

	if (large) {
		fmr |= FMR_ECCM;
		out_be32(&regs->fcr, (NAND_CMD_READ0 << FCR_CMD0_SHIFT) |
		                     (NAND_CMD_READSTART << FCR_CMD1_SHIFT));
		out_be32(&regs->fir,
		         (FIR_OP_CW0 << FIR_OP0_SHIFT) |
		         (FIR_OP_CA  << FIR_OP1_SHIFT) |
		         (FIR_OP_PA  << FIR_OP2_SHIFT) |
		         (FIR_OP_CW1 << FIR_OP3_SHIFT) |
		         (FIR_OP_RBW << FIR_OP4_SHIFT));
	} else {
		out_be32(&regs->fcr, NAND_CMD_READ0 << FCR_CMD0_SHIFT);
		out_be32(&regs->fir,
		         (FIR_OP_CW0 << FIR_OP0_SHIFT) |
		         (FIR_OP_CA  << FIR_OP1_SHIFT) |
		         (FIR_OP_PA  << FIR_OP2_SHIFT) |
		         (FIR_OP_RBW << FIR_OP3_SHIFT));
	}

	out_be32(&regs->fbcr, 0);
	clrsetbits_be32(&regs->bank[0].br, BR_DECC, BR_DECC_CHK_GEN);

	while (pos < uboot_size) {
		int i = 0;
		out_be32(&regs->fbar, offs >> block_shift);

		do {
			int j;
			unsigned int page_offs = (offs & (block_size - 1)) << 1;

			out_be32(&regs->ltesr, ~0);
			out_be32(&regs->lteatr, 0);
			out_be32(&regs->fpar, page_offs);
			out_be32(&regs->fmr, fmr);
			out_be32(&regs->lsor, 0);
			nand_wait();

			page_offs %= WINDOW_SIZE;

			/*
			 * If either of the first two pages are marked bad,
			 * continue to the next block.
			 */
			if (i++ < 2 && buf[page_offs + bad_marker] != 0xff) {
				puts("skipping\n");
				offs = (offs + block_size) & ~(block_size - 1);
				pos &= ~(block_size - 1);
				break;
			}

			for (j = 0; j < page_size; j++)
				dst[pos + j] = buf[page_offs + j];

			pos += page_size;
			offs += page_size;
		} while ((offs & (block_size - 1)) && (pos < uboot_size));
	}
}