rkflash: support 4KB page size spi nand

1.support 4KB page size spi nand
2.add new spi nand: ATO25D1GA, XT26G02B, XT26G01B, HYF4GQ4UAACBE

Change-Id: I331c98341e9aa5f2e15cd7a4a5c6aeb2136d65dd
Signed-off-by: Jon Lin <jon.lin@rock-chips.com>
This commit is contained in:
Jon Lin 2019-04-19 09:34:17 +08:00 committed by Dingqiang Lin
parent 12bc9cd8e1
commit f25e3caf73
4 changed files with 5512 additions and 5470 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -60,7 +60,15 @@ static struct nand_info spi_nand_tbl[] = {
/* EM73C044SNC-G */
{0xD522, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 8, 0xB0, 0x0, 4, 20, NULL},
/* EM73D044SNB-G */
{0xD520, 4, 64, 2, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 19, 8, 0xB0, 0x0, 4, 20, NULL}
{0xD520, 4, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 19, 8, 0xB0, 0x0, 4, 20, NULL},
/* ATO25D1GA */
{0x9B12, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x40, 18, 1, 0xB0, 0x0, 20, 36, &sfc_nand_ecc_status_sp1},
/* XT26G02B */
{0x0BF2, 4, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 19, 1, 0xB0, 0x0, 8, 12, &sfc_nand_ecc_status_sp4},
/* XT26G01B */
{0x0BF1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 18, 1, 0xB0, 0x0, 8, 12, &sfc_nand_ecc_status_sp4},
/* HYF4GQ4UAACBE */
{0xC9D4, 8, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 20, 4, 0xB0, 0, 32, 64, NULL},
};
static u8 id_byte[8];
@ -383,15 +391,20 @@ static u32 sfc_nand_prog_page(u8 cs, u32 addr, u32 *p_data, u32 *p_spare)
union SFCCMD_DATA sfcmd;
union SFCCTRL_DATA sfctrl;
u8 status;
u32 data_sz = 2048;
u32 sec_per_page = p_nand_info->sec_per_page;
u32 spare_offs_1 = p_nand_info->spare_offs_1;
u32 spare_offs_2 = p_nand_info->spare_offs_2;
u32 data_size = sec_per_page * 512;
memcpy(gp_page_buf, p_data, data_sz);
ftl_memset(&gp_page_buf[data_sz / 4], 0xff, 64);
gp_page_buf[(data_sz + spare_offs_1) / 4] = p_spare[0];
gp_page_buf[(data_sz + spare_offs_2) / 4] = p_spare[1];
PRINT_SFC_I("%s %x %x %x\n", __func__, addr, p_data[0], p_spare[0]);
memcpy(gp_page_buf, p_data, data_size);
ftl_memset(&gp_page_buf[data_size / 4], 0xff, sec_per_page * 16);
gp_page_buf[(data_size + spare_offs_1) / 4] = p_spare[0];
gp_page_buf[(data_size + spare_offs_2) / 4] = p_spare[1];
if (sec_per_page == 8) {
gp_page_buf[(data_size + spare_offs_1) / 4 + 1] = p_spare[2];
gp_page_buf[(data_size + spare_offs_2) / 4 + 1] = p_spare[3];
}
sfc_nand_write_en();
if (sfc_nand_dev.prog_lines == DATA_LINES_X4 &&
p_nand_info->feature & FEA_SOFT_QOP_BIT &&
@ -401,7 +414,7 @@ static u32 sfc_nand_prog_page(u8 cs, u32 addr, u32 *p_data, u32 *p_spare)
sfcmd.d32 = 0;
sfcmd.b.cmd = sfc_nand_dev.page_prog_cmd;
sfcmd.b.addrbits = SFC_ADDR_XBITS;
sfcmd.b.datasize = SFC_NAND_PAGE_MAX_SIZE;
sfcmd.b.datasize = SFC_NAND_SECTOR_FULL_SIZE * sec_per_page;
sfcmd.b.rw = SFC_WRITE;
sfctrl.d32 = 0;
@ -431,10 +444,12 @@ static u32 sfc_nand_read_page(u8 cs, u32 addr, u32 *p_data, u32 *p_spare)
union SFCCMD_DATA sfcmd;
union SFCCTRL_DATA sfctrl;
u32 ecc_result;
u32 data_sz = 2048;
u32 spare_offs_1 = p_nand_info->spare_offs_1;
u32 spare_offs_2 = p_nand_info->spare_offs_2;
u32 sec_per_page = p_nand_info->sec_per_page;
u32 data_size = sec_per_page * 512;
PRINT_SFC_I("%s %x %x %x\n", __func__, addr, p_data[0], p_spare[0]);
sfcmd.d32 = 0;
sfcmd.b.cmd = p_nand_info->page_read_cmd;
sfcmd.b.datasize = 0;
@ -453,18 +468,20 @@ static u32 sfc_nand_read_page(u8 cs, u32 addr, u32 *p_data, u32 *p_spare)
sfcmd.d32 = 0;
sfcmd.b.cmd = sfc_nand_dev.page_read_cmd;
sfcmd.b.datasize = SFC_NAND_PAGE_MAX_SIZE;
sfcmd.b.datasize = SFC_NAND_SECTOR_FULL_SIZE * sec_per_page;
sfcmd.b.addrbits = SFC_ADDR_24BITS;
sfctrl.d32 = 0;
sfctrl.b.datalines = sfc_nand_dev.read_lines;
plane = p_nand_info->plane_per_die == 2 ? ((addr >> 6) & 0x1) << 12 : 0;
memset(gp_page_buf, 0, SFC_NAND_PAGE_MAX_SIZE);
ret = sfc_request(sfcmd.d32, sfctrl.d32, plane << 8, gp_page_buf);
memcpy(p_data, gp_page_buf, data_sz);
p_spare[0] = gp_page_buf[(data_sz + spare_offs_1) / 4];
p_spare[1] = gp_page_buf[(data_sz + spare_offs_2) / 4];
memcpy(p_data, gp_page_buf, data_size);
p_spare[0] = gp_page_buf[(data_size + spare_offs_1) / 4];
p_spare[1] = gp_page_buf[(data_size + spare_offs_2) / 4];
if (p_nand_info->sec_per_page == 8) {
p_spare[2] = gp_page_buf[(data_size + spare_offs_1) / 4 + 1];
p_spare[3] = gp_page_buf[(data_size + spare_offs_2) / 4 + 1];
}
if (ret != SFC_OK)
return SFC_NAND_ECC_ERROR;
@ -475,6 +492,7 @@ static u32 sfc_nand_read_page(u8 cs, u32 addr, u32 *p_data, u32 *p_spare)
if (p_spare)
PRINT_SFC_HEX("spare:", p_spare, 4, 2);
}
return ecc_result;
}

View File

@ -15,7 +15,8 @@
#define SFC_NAND_ECC_REFRESH NAND_STS_REFRESH
#define SFC_NAND_ECC_OK NAND_STS_OK
#define SFC_NAND_PAGE_MAX_SIZE 2112
#define SFC_NAND_PAGE_MAX_SIZE 4224
#define SFC_NAND_SECTOR_FULL_SIZE 528
#define FEA_READ_STATUE_MASK (0x3 << 0)
#define FEA_STATUE_MODE1 0
@ -113,8 +114,8 @@ struct nand_info {
u8 QE_address;
u8 QE_bits;
u8 spare_offs_1;
u8 spare_offs_2;
u8 spare_offs_1; /* 4/8 bytes for 2KB/4KB page size flash */
u8 spare_offs_2; /* 4/8 bytes for 2KB/4KB page size flash */
u32 (*ecc_status)(void);
};