diff --git a/drivers/rkflash/sfc_nand.c b/drivers/rkflash/sfc_nand.c index cf3d3e887198..d16c30349aed 100644 --- a/drivers/rkflash/sfc_nand.c +++ b/drivers/rkflash/sfc_nand.c @@ -19,6 +19,7 @@ static u32 sfc_nand_get_ecc_status4(void); static u32 sfc_nand_get_ecc_status5(void); static u32 sfc_nand_get_ecc_status6(void); static u32 sfc_nand_get_ecc_status7(void); +static u32 sfc_nand_get_ecc_status8(void); static struct nand_info spi_nand_tbl[] = { /* TC58CVG0S0HxAIx */ @@ -66,6 +67,8 @@ static struct nand_info spi_nand_tbl[] = { { 0xEF, 0xAA, 0x21, 4, 0x40, 1, 1024, 0x4C, 18, 0x1, 0, { 0x04, 0x14, 0x24, 0xFF }, &sfc_nand_get_ecc_status1 }, /* W25N02KVZEIR */ { 0xEF, 0xAA, 0x22, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 0, { 0x04, 0x14, 0x24, 0xFF }, &sfc_nand_get_ecc_status0 }, + /* W25N04KVZEIR */ + { 0xEF, 0xAA, 0x23, 4, 0x40, 1, 4096, 0x4C, 20, 0x8, 0, { 0x04, 0x14, 0x24, 0x34 }, &sfc_nand_get_ecc_status0 }, /* W25N01GW */ { 0xEF, 0xBA, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x1, 0, { 0x04, 0x14, 0x24, 0xFF }, &sfc_nand_get_ecc_status1 }, @@ -99,6 +102,8 @@ static struct nand_info spi_nand_tbl[] = { { 0xE5, 0x72, 0x00, 4, 0x40, 2, 1024, 0x0C, 19, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, /* DS35M1GA-1B */ { 0xE5, 0x21, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, + /* DS35Q2GB-IB */ + { 0xE5, 0xF2, 0x00, 4, 0x40, 2, 1024, 0x0C, 19, 0x8, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 }, /* EM73C044VCC-H */ { 0xD5, 0x22, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x8, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, @@ -106,6 +111,8 @@ static struct nand_info spi_nand_tbl[] = { { 0xD5, 0x20, 0x00, 4, 0x40, 1, 2048, 0x0C, 19, 0x8, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, /* EM73E044SNA-G */ { 0xD5, 0x03, 0x00, 8, 0x40, 1, 2048, 0x4C, 20, 0x8, 1, { 0x04, 0x28, 0x08, 0x2C }, &sfc_nand_get_ecc_status0 }, + /* EM73C044VCF-H */ + { 0xD5, 0x25, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, /* XT26G02A */ { 0x0B, 0xE2, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 1, { 0x08, 0x0C, 0xFF, 0xFF }, &sfc_nand_get_ecc_status4 }, @@ -123,9 +130,13 @@ static struct nand_info spi_nand_tbl[] = { { 0x0B, 0x12, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 1, { 0x08, 0x0C, 0xFF, 0xFF }, &sfc_nand_get_ecc_status7 }, /* XT26G04C */ { 0x0B, 0x13, 0x00, 8, 0x40, 1, 2048, 0x4C, 20, 0x8, 1, { 0x04, 0x08, 0x0C, 0x10 }, &sfc_nand_get_ecc_status7 }, + /* XT26G11C */ + { 0x0B, 0x15, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, /* MT29F2G01ABA, XT26G02E, F50L2G41XA */ - { 0x2C, 0x24, 0x00, 4, 0x40, 2, 1024, 0x4C, 19, 0x1, 1, { 0x20, 0x24, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 }, + { 0x2C, 0x24, 0x00, 4, 0x40, 2, 1024, 0x4C, 19, 0x8, 0, { 0x20, 0x24, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 }, + /* MT29F1G01ABA, F50L1G41XA */ + { 0x2C, 0x14, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 0, { 0x20, 0x24, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 }, /* FM25S01 */ { 0xA1, 0xA1, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x1, 0, { 0x00, 0x04, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, @@ -142,6 +153,8 @@ static struct nand_info spi_nand_tbl[] = { { 0x9B, 0x12, 0x00, 4, 0x40, 1, 1024, 0x40, 18, 0x1, 1, { 0x14, 0x24, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, /* BWJX08K-2Gb */ { 0xBC, 0xB3, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 1, { 0x04, 0x10, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, + /* JS28U1GQSCAHG-83 */ + { 0xBF, 0x21, 0x00, 4, 0x40, 1, 1024, 0x40, 18, 0x4, 1, { 0x08, 0x0C, 0xFF, 0xFF }, &sfc_nand_get_ecc_status8 }, }; static struct nand_info *p_nand_info; @@ -456,7 +469,7 @@ static u32 sfc_nand_get_ecc_status3(void) * [0b1000], Multiple bit errors were detected and * not corrected. * [0b1100], Bit error count equals the bit flip - * detectionthreshold + * detection threshold * else, reserved */ static u32 sfc_nand_get_ecc_status4(void) @@ -498,7 +511,7 @@ static u32 sfc_nand_get_ecc_status4(void) * [0b001, 0b011], Bit errors were detected and corrected. Not * reach Flipping Bits; * [0b100], Bit error count equals the bit flip - * detectionthreshold + * detection threshold * [0b101, 0b110], Reserved; * [0b111], Multiple bit errors were detected and * not corrected. @@ -624,6 +637,48 @@ static u32 sfc_nand_get_ecc_status7(void) return ret; } +/* + * ecc spectial type8: + * ecc bits: 0xC0[4,6] + * [0b000], No bit errors were detected; + * [0b001, 0b011], 1~3 Bit errors were detected and corrected. Not + * reach Flipping Bits; + * [0b100], Bit error count equals the bit flip + * detection threshold + * others, Reserved. + */ +static u32 sfc_nand_get_ecc_status8(void) +{ + u32 ret; + u32 i; + u8 ecc; + u8 status; + u32 timeout = 1000 * 1000; + + for (i = 0; i < timeout; i++) { + ret = sfc_nand_read_feature(0xC0, &status); + + if (ret != SFC_OK) + return SFC_NAND_ECC_ERROR; + + if (!(status & (1 << 0))) + break; + + sfc_delay(1); + } + + ecc = (status >> 4) & 0x07; + + if (ecc < 4) + ret = SFC_NAND_ECC_OK; + else if (ecc == 4) + ret = SFC_NAND_ECC_REFRESH; + else + ret = (u32)SFC_NAND_ECC_ERROR; + + return ret; +} + u32 sfc_nand_erase_block(u8 cs, u32 addr) { int ret; @@ -849,7 +904,7 @@ u32 sfc_nand_check_bad_block(u8 cs, u32 addr) ret = sfc_nand_read(addr, &marker, data_size, 2); /* unify with mtd framework */ - if (ret == SFC_NAND_ECC_ERROR) + if (ret == SFC_NAND_ECC_ERROR || (u16)marker != 0xffff) rkflash_print_error("%s page= %x ret= %x spare= %x\n", __func__, addr, ret, marker);