/* | ECC MAIN | BAD | RES | YAFFS_TAG | | 4 | 4 | 8 | 48 | */ #include "k9f2g08_s3c.h" /* From yaffs_guts.h */ #define YAFFS_OK 1 #define YAFFS_FAIL 0 int k9f2g08_init(void) { return YAFFS_OK; } int k9f2g08_deinit(void) { return YAFFS_OK; } static unsigned char wait_busy_status(void) { unsigned char rc; for (rc=0; rc <40; rc++); bsp_nand_set_cs(0); bsp_nand_write_cmd(0x70); // read status do { rc = bsp_nand_read_data8(); } while ((rc & (1<<6)) == 0); bsp_nand_set_cs(1); return rc; } int k9f2g08_mark_block_bad(unsigned int blk_num) { int row_addr = blk_num * 64; int col_addr = 2048; unsigned char status; bsp_nand_set_cs(0); bsp_nand_write_cmd(0x80); // write command bsp_nand_write_addr((unsigned char)(col_addr >> 0)); bsp_nand_write_addr((unsigned char)(col_addr >> 8)); bsp_nand_write_addr((unsigned char)(row_addr >> 0)); bsp_nand_write_addr((unsigned char)(row_addr >> 8)); bsp_nand_write_addr((unsigned char)(row_addr >> 16)); bsp_nand_write_data32(0xFFFFFFFF); bsp_nand_write_data32(0x00000000); bsp_nand_write_data32(0xFFFFFFFF); bsp_nand_write_data32(0xFFFFFFFF); bsp_nand_write_cmd(0x10); bsp_nand_set_cs(1); status = wait_busy_status(); return (status & (1<<0)) ? YAFFS_FAIL : YAFFS_OK; } int k9f2g08_write(unsigned int chunk, const unsigned char *dat, const unsigned char *spare, unsigned int spare_size) { int i; int col_addr; unsigned char status; if (dat) { col_addr = 0; } else { col_addr = 2048; } bsp_nand_set_cs(0); bsp_nand_write_cmd(0x80); // write command bsp_nand_write_addr((unsigned char)(col_addr >> 0)); bsp_nand_write_addr((unsigned char)(col_addr >> 8)); bsp_nand_write_addr((unsigned char)(chunk >> 0)); bsp_nand_write_addr((unsigned char)(chunk >> 8)); bsp_nand_write_addr((unsigned char)(chunk >> 16)); bsp_nand_start_main_ecc(); if (dat) { for (i=0; i<2048; i++) bsp_nand_write_data8(*dat++); } bsp_nand_stop_main_ecc(); bsp_nand_write_data32(bsp_nand_read_spare_ecc0()); bsp_nand_write_data32(0xFFFFFFFF); bsp_nand_write_data32(0xFFFFFFFF); bsp_nand_write_data32(0xFFFFFFFF); if (spare) { for (i=0; i> 0)); bsp_nand_write_addr((unsigned char)(col_addr >> 8)); bsp_nand_write_addr((unsigned char)(chunk >> 0)); bsp_nand_write_addr((unsigned char)(chunk >> 8)); bsp_nand_write_addr((unsigned char)(chunk >> 16)); bsp_nand_write_cmd(0x30); // read bsp_nand_wait_busy(); if (dat) { bsp_nand_start_main_ecc(); for (i=0; i<2048; i++) *p++ = bsp_nand_read_data8(); bsp_nand_stop_main_ecc(); ecc = bsp_nand_read_data32(); bsp_nand_read_data32(); bsp_nand_read_data32(); bsp_nand_read_data32(); } if (spare) { p = spare; for (i=0; i> 0)); bsp_nand_write_addr((unsigned char)(chunk >> 8)); bsp_nand_write_addr((unsigned char)(chunk >> 16)); bsp_nand_write_cmd(0xD0); // erase bsp_nand_set_cs(1); status = wait_busy_status(); return (status & (1<<0)) ? YAFFS_FAIL : YAFFS_OK; } int k9f2g08_is_block_ok(unsigned int blk_num) { int chunk = blk_num * 64; int col_addr = 2048 + 4; bsp_nand_set_cs(0); bsp_nand_write_cmd(0x00); // read command bsp_nand_write_addr((unsigned char)(col_addr >> 0)); bsp_nand_write_addr((unsigned char)(col_addr >> 8)); bsp_nand_write_addr((unsigned char)(chunk >> 0)); bsp_nand_write_addr((unsigned char)(chunk >> 8)); bsp_nand_write_addr((unsigned char)(chunk >> 16)); bsp_nand_write_cmd(0x30); // read bsp_nand_wait_busy(); int tmp = bsp_nand_read_data32(); bsp_nand_set_cs(1); if (tmp == 0xFFFFFFFF) { return 1; } return 0; } int k9f2g08_read_id(unsigned int *id) { int rc = -1; bsp_nand_set_cs(0); bsp_nand_write_cmd(0x90); // read command bsp_nand_write_addr((unsigned char)0); do { if ((rc = bsp_nand_read_data8()) != 0xEC) break; *id = bsp_nand_read_data32(); rc = 0; } while(0); bsp_nand_set_cs(1); return rc; } int k9f2g08_read_ll(unsigned int chunk, unsigned char *dat, unsigned char *spare) { int i; int col_addr; unsigned char *p; if (dat) { col_addr = 0; } else { col_addr = 2048; } bsp_nand_set_cs(0); bsp_nand_write_cmd(0x00); // read command bsp_nand_write_addr((unsigned char)(col_addr >> 0)); bsp_nand_write_addr((unsigned char)(col_addr >> 8)); bsp_nand_write_addr((unsigned char)(chunk >> 0)); bsp_nand_write_addr((unsigned char)(chunk >> 8)); bsp_nand_write_addr((unsigned char)(chunk >> 16)); bsp_nand_write_cmd(0x30); // read bsp_nand_wait_busy(); if (dat) { p = dat; for (i=0; i<2048; i++) *p++ = bsp_nand_read_data8(); } if (spare) { p = spare; for (i=0; i<64; i++) *p++ = bsp_nand_read_data8(); } bsp_nand_set_cs(1); return 1; }