diff --git a/drivers/rkflash/sfc.c b/drivers/rkflash/sfc.c index f913112e96..e0d61446a1 100644 --- a/drivers/rkflash/sfc.c +++ b/drivers/rkflash/sfc.c @@ -11,6 +11,9 @@ #include "sfc.h" +#define SFC_MAX_IOSIZE_VER3 (1024 * 8) +#define SFC_MAX_IOSIZE_VER4 (0xFFFFFFFF) + static void __iomem *g_sfc_reg; static void sfc_reset(void) @@ -30,11 +33,21 @@ u16 sfc_get_version(void) return (u32)(readl(g_sfc_reg + SFC_VER) & 0xffff); } +u32 sfc_get_max_iosize(void) +{ + if (sfc_get_version() >= SFC_VER_4) + return SFC_MAX_IOSIZE_VER4; + else + return SFC_MAX_IOSIZE_VER3; +} + int sfc_init(void __iomem *reg_addr) { g_sfc_reg = reg_addr; sfc_reset(); writel(0, g_sfc_reg + SFC_CTRL); + if (sfc_get_version() >= SFC_VER_4) + writel(1, g_sfc_reg + SFC_LEN_CTRL); return SFC_OK; } @@ -45,7 +58,7 @@ void sfc_clean_irq(void) writel(0xFFFFFFFF, g_sfc_reg + SFC_IMR); } -int sfc_request(u32 sfcmd, u32 sfctrl, u32 addr, void *data) +int sfc_request(struct rk_sfc_op *op, u32 addr, void *data, u32 size) { int ret = SFC_OK; union SFCCMD_DATA cmd; @@ -57,26 +70,31 @@ int sfc_request(u32 sfcmd, u32 sfctrl, u32 addr, void *data) (readl(g_sfc_reg + SFC_SR) & SFC_BUSY)) sfc_reset(); - cmd.d32 = sfcmd; + cmd.d32 = op->sfcmd.d32; if (cmd.b.addrbits == SFC_ADDR_XBITS) { union SFCCTRL_DATA ctrl; - ctrl.d32 = sfctrl; + ctrl.d32 = op->sfctrl.d32; if (!ctrl.b.addrbits) return SFC_PARAM_ERR; /* Controller plus 1 automatically */ writel(ctrl.b.addrbits - 1, g_sfc_reg + SFC_ABIT); } /* shift in the data at negedge sclk_out */ - sfctrl |= 0x2; + op->sfctrl.d32 |= 0x2; + cmd.b.datasize = size; + if (sfc_get_version() >= SFC_VER_4) + writel(size, g_sfc_reg + SFC_LEN_EXT); + else + cmd.b.datasize = size; - writel(sfctrl, g_sfc_reg + SFC_CTRL); - writel(sfcmd, g_sfc_reg + SFC_CMD); + writel(op->sfctrl.d32, g_sfc_reg + SFC_CTRL); + writel(cmd.d32, g_sfc_reg + SFC_CMD); if (cmd.b.addrbits) writel(addr, g_sfc_reg + SFC_ADDR); - if (!cmd.b.datasize) + if (!size) goto exit_wait; - if (SFC_ENABLE_DMA & sfctrl) { + if (op->sfctrl.b.enbledma) { struct bounce_buffer bb; unsigned int bb_flags; @@ -85,16 +103,16 @@ int sfc_request(u32 sfcmd, u32 sfctrl, u32 addr, void *data) else bb_flags = GEN_BB_WRITE; - ret = bounce_buffer_start(&bb, data, cmd.b.datasize, bb_flags); + ret = bounce_buffer_start(&bb, data, size, bb_flags); if (ret) return ret; writel(0xFFFFFFFF, g_sfc_reg + SFC_ICLR); - writel(~((u32)FINISH_INT), g_sfc_reg + SFC_IMR); + writel(~((u32)DMA_INT), g_sfc_reg + SFC_IMR); writel((unsigned long)bb.bounce_buffer, g_sfc_reg + SFC_DMA_ADDR); writel(SFC_DMA_START, g_sfc_reg + SFC_DMA_TRIGGER); - timeout = cmd.b.datasize * 10; + timeout = size * 10; while ((readl(g_sfc_reg + SFC_SR) & SFC_BUSY) && (timeout-- > 0)) sfc_delay(1); @@ -108,7 +126,7 @@ int sfc_request(u32 sfcmd, u32 sfctrl, u32 addr, void *data) u32 *p_data = (u32 *)data; if (cmd.b.rw == SFC_WRITE) { - words = (cmd.b.datasize + 3) >> 2; + words = (size + 3) >> 2; while (words) { fifostat.d32 = readl(g_sfc_reg + SFC_FSR); if (fifostat.b.txlevel > 0) { @@ -132,8 +150,8 @@ int sfc_request(u32 sfcmd, u32 sfctrl, u32 addr, void *data) } } else { /* SFC_READ == cmd.b.rw */ - bytes = cmd.b.datasize & 0x3; - words = cmd.b.datasize >> 2; + bytes = size & 0x3; + words = size >> 2; while (words) { fifostat.d32 = readl(g_sfc_reg + SFC_FSR); if (fifostat.b.rxlevel > 0) { @@ -183,7 +201,7 @@ int sfc_request(u32 sfcmd, u32 sfctrl, u32 addr, void *data) exit_wait: timeout = 0; /* wait cmd or data send complete */ - while (!(readl(g_sfc_reg + SFC_FSR) & SFC_TXEMPTY)) { + while (readl(g_sfc_reg + SFC_SR) & SFC_BUSY) { sfc_delay(1); if (timeout++ > 100000) { /* wait 100ms */ ret = SFC_TX_TIMEOUT; diff --git a/drivers/rkflash/sfc.h b/drivers/rkflash/sfc.h index 4ad808f856..bcbbcc3a9f 100644 --- a/drivers/rkflash/sfc.h +++ b/drivers/rkflash/sfc.h @@ -7,9 +7,9 @@ #ifndef _SFC_H #define _SFC_H -#define SFC_VER_3 0x3 /* ver 3, else ver 1 */ +#define SFC_VER_3 0x3 +#define SFC_VER_4 0x4 -#define SFC_MAX_IOSIZE (1024 * 8) /* 8K byte */ #define SFC_EN_INT (0) /* enable interrupt */ #define SFC_EN_DMA (1) /* enable dma */ #define SFC_FIFO_DEPTH (0x10) /* 16 words */ @@ -90,6 +90,8 @@ #define SFC_QOP 0x30 #define SFC_DMA_TRIGGER 0x80 #define SFC_DMA_ADDR 0x84 +#define SFC_LEN_CTRL 0x88 +#define SFC_LEN_EXT 0x8C #define SFC_CMD 0x100 #define SFC_ADDR 0x104 #define SFC_DATA 0x108 @@ -182,10 +184,16 @@ union SFCCMD_DATA { } b; }; +struct rk_sfc_op { + union SFCCMD_DATA sfcmd; + union SFCCTRL_DATA sfctrl; +}; + int sfc_init(void __iomem *reg_addr); -int sfc_request(u32 sfcmd, u32 sfctrl, u32 addr, void *data); +int sfc_request(struct rk_sfc_op *op, u32 addr, void *data, u32 size); u16 sfc_get_version(void); void sfc_clean_irq(void); +u32 sfc_get_max_iosize(void); int rksfc_get_reg_addr(unsigned long *p_sfc_addr); #endif diff --git a/drivers/rkflash/sfc_nand.c b/drivers/rkflash/sfc_nand.c index d8b8ff9b42..01f9e8b142 100644 --- a/drivers/rkflash/sfc_nand.c +++ b/drivers/rkflash/sfc_nand.c @@ -16,76 +16,86 @@ static struct nand_info spi_nand_tbl[] = { /* TC58CVG0S0HxAIx */ - {0x98C2, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x02, 0xD8, 0x00, 18, 8, 0xFF, 0xFF, 4, 8, NULL}, + {0x98C2, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x02, 0xD8, 0x00, 18, 8, 0xFF, 0xFF, {4, 8, 0xff, 0xff}, NULL}, /* TC58CVG1S0HxAIx */ - {0x98CB, 4, 64, 2, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x02, 0xD8, 0x00, 19, 8, 0xFF, 0xFF, 4, 8, NULL}, + {0x98CB, 4, 64, 2, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x02, 0xD8, 0x00, 19, 8, 0xFF, 0xFF, {4, 8, 0xff, 0xff}, NULL}, /* MX35LF1GE4AB */ - {0xC212, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 4, 0xB0, 0, 4, 8, &sfc_nand_ecc_status_sp1}, + {0xC212, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 4, 0xB0, 0, {4, 8, 0xff, 0xff}, &sfc_nand_ecc_status_sp1}, /* MX35LF2GE4AB */ - {0xC222, 4, 64, 2, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 19, 4, 0xB0, 0, 4, 8, &sfc_nand_ecc_status_sp1}, + {0xC222, 4, 64, 2, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 19, 4, 0xB0, 0, {4, 8, 0xff, 0xff}, &sfc_nand_ecc_status_sp1}, /* GD5F1GQ4UAYIG */ - {0xC8F1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 8, 0xB0, 0, 4, 8, NULL}, + {0xC8F1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 8, 0xB0, 0, {4, 8, 0xff, 0xff}, NULL}, /* MT29F1G01ZAC */ - {0x2C12, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x00, 18, 1, 0xB0, 0, 4, 8, &sfc_nand_ecc_status_sp1}, + {0x2C12, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x00, 18, 1, 0xB0, 0, {4, 8, 0xff, 0xff}, &sfc_nand_ecc_status_sp1}, /* GD5F2GQ40BY2GR */ - {0xC8D2, 4, 64, 2, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 19, 8, 0xB0, 0, 4, 8, &sfc_nand_ecc_status_sp3}, - /* GD5F1GQ4U */ - {0xC8D1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 8, 0xB0, 0, 4, 8, &sfc_nand_ecc_status_sp3}, + {0xC8D2, 4, 64, 2, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 19, 8, 0xB0, 0, {4, 8, 0xff, 0xff}, &sfc_nand_ecc_status_sp3}, + /* GD5F1GQ4RB9IGR */ + {0xC8D1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 8, 0xB0, 0, {4, 8, 0xff, 0xff}, &sfc_nand_ecc_status_sp3}, /* IS37SML01G1 */ - {0xC821, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x00, 18, 1, 0xFF, 0xFF, 8, 12, &sfc_nand_ecc_status_sp1}, + {0xC821, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x00, 18, 1, 0xFF, 0xFF, {8, 12, 0xff, 0xff}, &sfc_nand_ecc_status_sp1}, /* W25N01GV */ - {0xEFAA, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 18, 1, 0xFF, 0xFF, 4, 20, &sfc_nand_ecc_status_sp1}, + {0xEFAA, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 18, 1, 0xFF, 0xFF, {4, 20, 36, 0xff}, &sfc_nand_ecc_status_sp1}, /* HYF2GQ4UAACAE */ - {0xC952, 4, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 19, 14, 0xB0, 0, 4, 36, NULL}, + {0xC952, 4, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 19, 14, 0xB0, 0, {4, 36, 0xff, 0xff}, NULL}, /* HYF2GQ4UDACAE */ - {0xC922, 4, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 19, 4, 0xB0, 0, 4, 20, NULL}, + {0xC922, 4, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 19, 4, 0xB0, 0, {4, 20, 0xff, 0xff}, NULL}, /* HYF2GQ4UHCCAE */ - {0xC95A, 4, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 19, 14, 0xB0, 0, 4, 36, NULL}, + {0xC95A, 4, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 19, 14, 0xB0, 0, {4, 36, 0xff, 0xff}, NULL}, /* HYF1GQ4UDACAE */ - {0xC921, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 18, 4, 0xB0, 0, 4, 20, NULL}, + {0xC921, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 18, 4, 0xB0, 0, {4, 20, 0xff, 0xff}, NULL}, /* F50L1G41LB */ - {0xC801, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 18, 1, 0xFF, 0xFF, 20, 36, &sfc_nand_ecc_status_sp1}, + {0xC801, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 18, 1, 0xFF, 0xFF, {20, 36, 0xff, 0xff}, &sfc_nand_ecc_status_sp1}, /* XT26G02A */ - {0x0BE2, 4, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 19, 1, 0xB0, 0x0, 8, 12, &sfc_nand_ecc_status_sp4}, + {0x0BE2, 4, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 19, 1, 0xB0, 0x0, {8, 12, 0xff, 0xff}, &sfc_nand_ecc_status_sp4}, /* XT26G01A */ - {0x0BE1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 18, 1, 0xB0, 0x0, 8, 12, &sfc_nand_ecc_status_sp4}, + {0x0BE1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 18, 1, 0xB0, 0x0, {8, 12, 0xff, 0xff}, &sfc_nand_ecc_status_sp4}, /* FS35ND01G-S1 */ - {0xCDB1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 4, 0xB0, 0x0, 16, 20, &sfc_nand_ecc_status_sp5}, + {0xCDB1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 4, 0xB0, 0x0, {16, 20, 0xff, 0xff}, &sfc_nand_ecc_status_sp5}, /* FS35ND02G-S2 */ - {0xCDA2, 4, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x03, 0x02, 0xD8, 0x00, 19, 4, 0xFF, 0xFF, 16, 20, &sfc_nand_ecc_status_sp5}, + {0xCDA2, 4, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x03, 0x02, 0xD8, 0x00, 19, 4, 0xFF, 0xFF, {16, 20, 0xff, 0xff}, &sfc_nand_ecc_status_sp5}, /* DS35Q1GA-1B */ - {0xE571, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 4, 0xB0, 0x0, 4, 20, &sfc_nand_ecc_status_sp1}, + {0xE571, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 4, 0xB0, 0x0, {4, 20, 0xff, 0xff}, &sfc_nand_ecc_status_sp1}, /* DS35Q2GA-1B */ - {0xE572, 4, 64, 2, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 19, 4, 0xB0, 0x0, 4, 20, &sfc_nand_ecc_status_sp1}, + {0xE572, 4, 64, 2, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 19, 4, 0xB0, 0x0, {4, 20, 0xff, 0xff}, &sfc_nand_ecc_status_sp1}, /* EM73C044SNC-G */ - {0xD522, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 8, 0xB0, 0x0, 4, 20, NULL}, + {0xD522, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 8, 0xB0, 0x0, {4, 20, 0xff, 0xff}, NULL}, /* EM73D044SNB-G */ - {0xD520, 4, 64, 1, 2048, 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, 0xff, 0xff}, 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}, + {0x9B12, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x40, 18, 1, 0xB0, 0x0, {20, 36, 0xff, 0xff}, &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}, + {0x0BF2, 4, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 19, 1, 0xB0, 0x0, {8, 12, 0xff, 0xff}, &sfc_nand_ecc_status_sp5}, /* 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}, + {0x0BF1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 18, 1, 0xB0, 0x0, {8, 12, 0xff, 0xff}, &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}, + {0xC9D4, 8, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 20, 4, 0xB0, 0, {32, 64, 36, 68}, NULL}, /* FM25S01 */ - {0xA1A1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 18, 1, 0xB0, 0, 0, 4, &sfc_nand_ecc_status_sp1}, + {0xA1A1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 18, 1, 0xB0, 0, {0, 4, 0xff, 0xff}, &sfc_nand_ecc_status_sp1}, /* HYF1GQ4UPACAE */ - {0xC9A1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 18, 4, 0xB0, 0, 4, 20, &sfc_nand_ecc_status_sp1}, + {0xC9A1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 18, 4, 0xB0, 0, {4, 20, 0xff, 0xff}, &sfc_nand_ecc_status_sp1}, /* EM73E044SNA-G */ - {0xD503, 8, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 20, 8, 0xB0, 0, 4, 40, NULL}, + {0xD503, 8, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 20, 8, 0xB0, 0, {4, 40, 8, 44}, NULL}, /* GD5F2GQ5UEYIG */ - {0xC852, 4, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 19, 4, 0xB0, 0, 4, 20, &sfc_nand_ecc_status_sp2}, + {0xC852, 4, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 19, 4, 0xB0, 0, {4, 20, 0xff, 0xff}, &sfc_nand_ecc_status_sp2}, /* GD5F1GQ4R */ - {0xC8C1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 8, 0xB0, 0, 4, 8, &sfc_nand_ecc_status_sp3}, + {0xC8C1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 8, 0xB0, 0, {4, 8, 0xff, 0xff}, &sfc_nand_ecc_status_sp3}, + /* TC58CVG2S0HRAIJ */ + {0x98ED, 8, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 20, 8, 0xFF, 0xFF, {4, 12, 8, 16}, NULL}, + /* TC58CVG1S3HRAIJ */ + {0x98EB, 4, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 19, 8, 0xFF, 0xFF, {4, 8, 0xff, 0xff}, NULL}, + /* TC58CVG0S3HRAIJ */ + {0x98E2, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 8, 0xFF, 0xFF, {4, 8, 0xff, 0xff}, NULL}, + /* XT26G04A */ + {0x0BE3, 4, 128, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 20, 1, 0xB0, 0x0, {8, 12, 0xff, 0xff}, &sfc_nand_ecc_status_sp4}, + /* FS35ND01G-S1Y2 */ + {0xCDEA, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 18, 4, 0xFF, 0xFF, {4, 8, 12, 16}, &sfc_nand_ecc_status_sp1}, }; static struct nand_info *p_nand_info; static u32 gp_page_buf[SFC_NAND_PAGE_MAX_SIZE / 4]; static struct SFNAND_DEV sfc_nand_dev; -static struct nand_info *spi_nand_get_info(u8 *nand_id) +static struct nand_info *sfc_nand_get_info(u8 *nand_id) { u32 i; u32 id = (nand_id[0] << 8) | (nand_id[1] << 0); @@ -100,43 +110,49 @@ static struct nand_info *spi_nand_get_info(u8 *nand_id) static int sfc_nand_write_en(void) { int ret; - union SFCCMD_DATA sfcmd; + struct rk_sfc_op op; - sfcmd.d32 = 0; - sfcmd.b.cmd = CMD_WRITE_EN; - ret = sfc_request(sfcmd.d32, 0, 0, NULL); + op.sfcmd.d32 = 0; + op.sfcmd.b.cmd = CMD_WRITE_EN; + + op.sfctrl.d32 = 0; + + ret = sfc_request(&op, 0, NULL, 0); return ret; } static int sfc_nand_rw_preset(void) { int ret; - union SFCCTRL_DATA sfctrl; - union SFCCMD_DATA sfcmd; + struct rk_sfc_op op; u8 status = 0xFF; - sfcmd.d32 = 0; - sfcmd.b.cmd = 0; - sfcmd.b.datasize = 1; - sfcmd.b.rw = SFC_WRITE; + op.sfcmd.d32 = 0; + op.sfcmd.b.cmd = 0; + op.sfcmd.b.rw = SFC_WRITE; - sfctrl.b.datalines = 2; - ret = sfc_request(sfcmd.d32, sfctrl.d32, 0, &status); + op.sfctrl.d32 = 0; + op.sfctrl.b.datalines = 2; + + ret = sfc_request(&op, 0, &status, 1); return ret; } static int sfc_nand_read_feature(u8 addr, u8 *data) { int ret; - union SFCCMD_DATA sfcmd; + struct rk_sfc_op op; + + op.sfcmd.d32 = 0; + op.sfcmd.b.cmd = 0x0F; + op.sfcmd.b.addrbits = SFC_ADDR_XBITS; + + op.sfctrl.d32 = 0; + op.sfctrl.b.addrbits = 8; - sfcmd.d32 = 0; - sfcmd.b.cmd = 0x0F; - sfcmd.b.datasize = 1; - sfcmd.b.addrbits = SFC_ADDR_XBITS; *data = 0; - ret = sfc_request(sfcmd.d32, 0x8 << 16, addr, data); + ret = sfc_request(&op, addr, data, 1); if (ret != SFC_OK) return ret; return SFC_OK; @@ -145,17 +161,19 @@ static int sfc_nand_read_feature(u8 addr, u8 *data) static int sfc_nand_write_feature(u32 addr, u8 status) { int ret; - union SFCCMD_DATA sfcmd; + struct rk_sfc_op op; sfc_nand_write_en(); - sfcmd.d32 = 0; - sfcmd.b.cmd = 0x1F; - sfcmd.b.datasize = 1; - sfcmd.b.addrbits = SFC_ADDR_XBITS; - sfcmd.b.rw = SFC_WRITE; + op.sfcmd.d32 = 0; + op.sfcmd.b.cmd = 0x1F; + op.sfcmd.b.addrbits = SFC_ADDR_XBITS; + op.sfcmd.b.rw = SFC_WRITE; - ret = sfc_request(sfcmd.d32, 0x8 << 16, addr, &status); + op.sfctrl.d32 = 0; + op.sfctrl.b.addrbits = 8; + + ret = sfc_request(&op, addr, &status, 1); if (ret != SFC_OK) return ret; return ret; @@ -182,6 +200,7 @@ static int sfc_nand_wait_busy(u8 *data, int timeout) /* * ecc default: + * ecc bits: 0xC0[4,5] * 0x00, No bit errors were detected * 0x01, Bit errors were detected and corrected. * 0x10, Multiple bit errors were detected and not corrected. @@ -190,7 +209,7 @@ static int sfc_nand_wait_busy(u8 *data, int timeout) */ static u32 sfc_nand_ecc_status(void) { - int ret; + u32 ret; u32 i; u8 ecc; u8 status; @@ -210,7 +229,7 @@ static u32 sfc_nand_ecc_status(void) if (ecc <= 1) ret = SFC_NAND_ECC_OK; else if (ecc == 2) - ret = SFC_NAND_ECC_ERROR; + ret = (u32)SFC_NAND_ECC_ERROR; else ret = SFC_NAND_ECC_REFRESH; @@ -219,6 +238,7 @@ static u32 sfc_nand_ecc_status(void) /* * ecc spectial type1: + * ecc bits: 0xC0[4,5] * 0x00, No bit errors were detected; * 0x01, Bits errors were detected and corrected, bit error count * may reach the bit flip detection threshold; @@ -227,7 +247,7 @@ static u32 sfc_nand_ecc_status(void) */ u32 sfc_nand_ecc_status_sp1(void) { - int ret; + u32 ret; u32 i; u8 ecc; u8 status; @@ -249,13 +269,14 @@ u32 sfc_nand_ecc_status_sp1(void) else if (ecc == 1) ret = SFC_NAND_ECC_REFRESH; else - ret = SFC_NAND_ECC_ERROR; + ret = (u32)SFC_NAND_ECC_ERROR; return ret; } /* * ecc spectial type2: + * ecc bits: 0xC0[4,5] 0xF0[4,5] * [0x0000, 0x0011], No bit errors were detected; * [0x0100, 0x0111], Bit errors were detected and corrected. Not * reach Flipping Bits; @@ -265,7 +286,7 @@ u32 sfc_nand_ecc_status_sp1(void) */ u32 sfc_nand_ecc_status_sp2(void) { - int ret; + u32 ret; u32 i; u8 ecc; u8 status, status1; @@ -290,24 +311,25 @@ u32 sfc_nand_ecc_status_sp2(void) else if (ecc == 7) ret = SFC_NAND_ECC_REFRESH; else - ret = SFC_NAND_ECC_ERROR; + ret = (u32)SFC_NAND_ECC_ERROR; return ret; } /* * ecc spectial type3: + * ecc bits: 0xC0[4,5] 0xF0[4,5] * [0x0000, 0x0011], No bit errors were detected; * [0x0100, 0x0111], Bit errors were detected and corrected. Not * reach Flipping Bits; * [0x1000, 0x1011], Multiple bit errors were detected and * not corrected. * [0x1100, 0x1111], Bit error count equals the bit flip - * detectionthreshold + * detectio nthreshold */ u32 sfc_nand_ecc_status_sp3(void) { - int ret; + u32 ret; u32 i; u8 ecc; u8 status, status1; @@ -332,13 +354,14 @@ u32 sfc_nand_ecc_status_sp3(void) else if (ecc == 7 || ecc >= 12) ret = SFC_NAND_ECC_REFRESH; else - ret = SFC_NAND_ECC_ERROR; + ret = (u32)SFC_NAND_ECC_ERROR; return ret; } /* * ecc spectial type4: + * ecc bits: 0xC0[2,5] * [0x0000], No bit errors were detected; * [0x0001, 0x0111], Bit errors were detected and corrected. Not * reach Flipping Bits; @@ -350,7 +373,7 @@ u32 sfc_nand_ecc_status_sp3(void) */ u32 sfc_nand_ecc_status_sp4(void) { - int ret; + u32 ret; u32 i; u8 ecc; u8 status; @@ -371,13 +394,14 @@ u32 sfc_nand_ecc_status_sp4(void) else if (ecc == 7 || ecc == 12) ret = SFC_NAND_ECC_REFRESH; else - ret = SFC_NAND_ECC_ERROR; + ret = (u32)SFC_NAND_ECC_ERROR; return ret; } /* * ecc spectial type5: + * ecc bits: 0xC0[4,6] * [0x0], No bit errors were detected; * [0x001, 0x011], Bit errors were detected and corrected. Not * reach Flipping Bits; @@ -389,7 +413,7 @@ u32 sfc_nand_ecc_status_sp4(void) */ u32 sfc_nand_ecc_status_sp5(void) { - int ret; + u32 ret; u32 i; u8 ecc; u8 status; @@ -410,7 +434,7 @@ u32 sfc_nand_ecc_status_sp5(void) else if (ecc == 4) ret = SFC_NAND_ECC_REFRESH; else - ret = SFC_NAND_ECC_ERROR; + ret = (u32)SFC_NAND_ECC_ERROR; return ret; } @@ -418,15 +442,19 @@ u32 sfc_nand_ecc_status_sp5(void) u32 sfc_nand_erase_block(u8 cs, u32 addr) { int ret; - union SFCCMD_DATA sfcmd; + struct rk_sfc_op op; u8 status; rkflash_print_dio("%s %x\n", __func__, addr); - sfcmd.d32 = 0; - sfcmd.b.cmd = p_nand_info->block_erase_cmd; - sfcmd.b.addrbits = SFC_ADDR_24BITS; + op.sfcmd.d32 = 0; + op.sfcmd.b.cmd = p_nand_info->block_erase_cmd; + op.sfcmd.b.addrbits = SFC_ADDR_24BITS; + op.sfcmd.b.rw = SFC_WRITE; + + op.sfctrl.d32 = 0; + sfc_nand_write_en(); - ret = sfc_request(sfcmd.d32, 0, addr, NULL); + ret = sfc_request(&op, addr, NULL, 0); if (ret != SFC_OK) return ret; ret = sfc_nand_wait_busy(&status, 1000 * 1000); @@ -440,10 +468,9 @@ static u32 sfc_nand_prog_page_raw(u8 cs, u32 addr, u32 *p_page_buf) { int ret; u32 plane; - union SFCCMD_DATA sfcmd; - union SFCCTRL_DATA sfctrl; + struct rk_sfc_op op; u8 status; - u32 sec_per_page = p_nand_info->sec_per_page; + u32 page_size = SFC_NAND_SECTOR_FULL_SIZE * p_nand_info->sec_per_page; rkflash_print_dio("%s %x %x\n", __func__, addr, p_page_buf[0]); sfc_nand_write_en(); @@ -452,24 +479,24 @@ static u32 sfc_nand_prog_page_raw(u8 cs, u32 addr, u32 *p_page_buf) sfc_get_version() < SFC_VER_3) sfc_nand_rw_preset(); - sfcmd.d32 = 0; - sfcmd.b.cmd = sfc_nand_dev.page_prog_cmd; - sfcmd.b.addrbits = SFC_ADDR_XBITS; - sfcmd.b.datasize = SFC_NAND_SECTOR_FULL_SIZE * sec_per_page; - sfcmd.b.rw = SFC_WRITE; + op.sfcmd.d32 = 0; + op.sfcmd.b.cmd = sfc_nand_dev.page_prog_cmd; + op.sfcmd.b.addrbits = SFC_ADDR_XBITS; + op.sfcmd.b.rw = SFC_WRITE; - sfctrl.d32 = 0; - sfctrl.b.datalines = sfc_nand_dev.prog_lines; - sfctrl.b.addrbits = 16; + op.sfctrl.d32 = 0; + op.sfctrl.b.datalines = sfc_nand_dev.prog_lines; + op.sfctrl.b.addrbits = 16; plane = p_nand_info->plane_per_die == 2 ? ((addr >> 6) & 0x1) << 12 : 0; - sfc_request(sfcmd.d32, sfctrl.d32, plane, p_page_buf); + sfc_request(&op, plane, p_page_buf, page_size); - sfcmd.d32 = 0; - sfcmd.b.cmd = p_nand_info->page_prog_cmd; - sfcmd.b.addrbits = SFC_ADDR_24BITS; - sfcmd.b.datasize = 0; - sfcmd.b.rw = SFC_WRITE; - ret = sfc_request(sfcmd.d32, 0, addr, p_page_buf); + op.sfcmd.d32 = 0; + op.sfcmd.b.cmd = p_nand_info->page_prog_cmd; + op.sfcmd.b.addrbits = SFC_ADDR_24BITS; + op.sfcmd.b.rw = SFC_WRITE; + + op.sfctrl.d32 = 0; + ret = sfc_request(&op, addr, p_page_buf, 0); if (ret != SFC_OK) return ret; ret = sfc_nand_wait_busy(&status, 1000 * 1000); @@ -484,16 +511,15 @@ u32 sfc_nand_prog_page(u8 cs, u32 addr, u32 *p_data, u32 *p_spare) int ret; u32 sec_per_page = p_nand_info->sec_per_page; u32 data_size = sec_per_page * SFC_NAND_SECTOR_SIZE; - u32 spare_offs_1 = p_nand_info->spare_offs_1; - u32 spare_offs_2 = p_nand_info->spare_offs_2; + struct nand_mega_area *meta = &p_nand_info->meta; memcpy(gp_page_buf, p_data, data_size); 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]; + gp_page_buf[(data_size + meta->off0) / 4] = p_spare[0]; + gp_page_buf[(data_size + meta->off1) / 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]; + gp_page_buf[(data_size + meta->off2) / 4] = p_spare[2]; + gp_page_buf[(data_size + meta->off3) / 4] = p_spare[3]; } ret = sfc_nand_prog_page_raw(cs, addr, gp_page_buf); @@ -504,59 +530,61 @@ static u32 sfc_nand_read_page_raw(u8 cs, u32 addr, u32 *p_page_buf) { int ret; u32 plane; - union SFCCMD_DATA sfcmd; - union SFCCTRL_DATA sfctrl; + struct rk_sfc_op op; u32 ecc_result; - u32 sec_per_page = p_nand_info->sec_per_page; + u32 page_size = SFC_NAND_SECTOR_FULL_SIZE * p_nand_info->sec_per_page; + u8 status; - sfcmd.d32 = 0; - sfcmd.b.cmd = p_nand_info->page_read_cmd; - sfcmd.b.datasize = 0; - sfcmd.b.addrbits = SFC_ADDR_24BITS; - sfc_request(sfcmd.d32, 0, addr, p_page_buf); + op.sfcmd.d32 = 0; + op.sfcmd.b.cmd = p_nand_info->page_read_cmd; + op.sfcmd.b.rw = SFC_WRITE; + op.sfcmd.b.addrbits = SFC_ADDR_24BITS; - if (p_nand_info->ecc_status) - ecc_result = p_nand_info->ecc_status(); - else - ecc_result = sfc_nand_ecc_status(); + op.sfctrl.d32 = 0; + sfc_request(&op, addr, p_page_buf, 0); if (sfc_nand_dev.read_lines == DATA_LINES_X4 && p_nand_info->feature & FEA_SOFT_QOP_BIT && sfc_get_version() < SFC_VER_3) sfc_nand_rw_preset(); - sfcmd.d32 = 0; - sfcmd.b.cmd = sfc_nand_dev.page_read_cmd; - 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; + sfc_nand_wait_busy(&status, 1000 * 1000); + if (p_nand_info->ecc_status) + ecc_result = p_nand_info->ecc_status(); + else + ecc_result = sfc_nand_ecc_status(); + + op.sfcmd.d32 = 0; + op.sfcmd.b.cmd = sfc_nand_dev.page_read_cmd; + op.sfcmd.b.addrbits = SFC_ADDR_24BITS; + + op.sfctrl.d32 = 0; + op.sfctrl.b.datalines = sfc_nand_dev.read_lines; plane = p_nand_info->plane_per_die == 2 ? ((addr >> 6) & 0x1) << 12 : 0; - ret = sfc_request(sfcmd.d32, sfctrl.d32, plane << 8, p_page_buf); + ret = sfc_request(&op, plane << 8, p_page_buf, page_size); rkflash_print_dio("%s %x %x\n", __func__, addr, p_page_buf[0]); if (ret != SFC_OK) - return SFC_NAND_HW_ERROR; + return SFC_NAND_ECC_ERROR; return ecc_result; } u32 sfc_nand_read_page(u8 cs, u32 addr, u32 *p_data, u32 *p_spare) { - int ret; + u32 ret; u32 sec_per_page = p_nand_info->sec_per_page; u32 data_size = sec_per_page * SFC_NAND_SECTOR_SIZE; - u32 spare_offs_1 = p_nand_info->spare_offs_1; - u32 spare_offs_2 = p_nand_info->spare_offs_2; + struct nand_mega_area *meta = &p_nand_info->meta; ret = sfc_nand_read_page_raw(cs, addr, gp_page_buf); 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]; + p_spare[0] = gp_page_buf[(data_size + meta->off0) / 4]; + p_spare[1] = gp_page_buf[(data_size + meta->off1) / 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]; + p_spare[2] = gp_page_buf[(data_size + meta->off2) / 4]; + p_spare[3] = gp_page_buf[(data_size + meta->off3) / 4]; } if (ret != SFC_NAND_ECC_OK) { @@ -576,7 +604,7 @@ u32 sfc_nand_check_bad_block(u8 cs, u32 addr) u32 data_size = p_nand_info->sec_per_page * SFC_NAND_SECTOR_SIZE; ret = sfc_nand_read_page_raw(cs, addr, gp_page_buf); - if (ret) + if (ret == SFC_NAND_ECC_ERROR) return true; /* Original bad block */ if ((gp_page_buf[data_size / 4] & 0xFF) != 0xFF) @@ -604,14 +632,16 @@ u32 sfc_nand_mark_bad_block(u8 cs, u32 addr) int sfc_nand_read_id(u8 *data) { int ret; - union SFCCMD_DATA sfcmd; + struct rk_sfc_op op; - sfcmd.d32 = 0; - sfcmd.b.cmd = CMD_READ_JEDECID; - sfcmd.b.datasize = 3; - sfcmd.b.addrbits = SFC_ADDR_XBITS; + op.sfcmd.d32 = 0; + op.sfcmd.b.cmd = CMD_READ_JEDECID; + op.sfcmd.b.addrbits = SFC_ADDR_XBITS; - ret = sfc_request(sfcmd.d32, 0x8 << 16, 0, data); + op.sfctrl.d32 = 0; + op.sfctrl.b.addrbits = 8; + + ret = sfc_request(&op, 0, data, 3); return ret; } @@ -683,7 +713,7 @@ void sfc_nand_ftl_ops_init(void) g_nand_ops.bch_sel = NULL; } -static int spi_nand_enable_QE(void) +static int sfc_nand_enable_QE(void) { int ret = SFC_OK; u8 status; @@ -713,11 +743,11 @@ u32 sfc_nand_init(void) rkflash_print_error("sfc_nand id: %x %x %x\n", id_byte[0], id_byte[1], id_byte[2]); if (id_byte[0] == 0xFF || id_byte[0] == 0x00) - return FTL_NO_FLASH; + return (u32)FTL_NO_FLASH; - p_nand_info = spi_nand_get_info(id_byte); + p_nand_info = sfc_nand_get_info(id_byte); if (!p_nand_info) - return FTL_UNSUPPORTED_FLASH; + return (u32)FTL_UNSUPPORTED_FLASH; sfc_nand_dev.manufacturer = id_byte[0]; sfc_nand_dev.mem_type = id_byte[1]; @@ -732,7 +762,7 @@ u32 sfc_nand_init(void) sfc_nand_dev.page_read_cmd = p_nand_info->read_cache_cmd_1; sfc_nand_dev.page_prog_cmd = p_nand_info->prog_cache_cmd_1; if (p_nand_info->feature & FEA_4BIT_READ) { - if (spi_nand_enable_QE() == SFC_OK) { + if (sfc_nand_enable_QE() == SFC_OK) { sfc_nand_dev.read_lines = DATA_LINES_X4; sfc_nand_dev.page_read_cmd = p_nand_info->read_cache_cmd_4; diff --git a/drivers/rkflash/sfc_nand.h b/drivers/rkflash/sfc_nand.h index 289834f777..1cb537ed52 100644 --- a/drivers/rkflash/sfc_nand.h +++ b/drivers/rkflash/sfc_nand.h @@ -84,6 +84,13 @@ struct SFNAND_DEV { u8 page_prog_cmd; }; +struct nand_mega_area { + u8 off0; + u8 off1; + u8 off2; + u8 off3; +}; + struct nand_info { u32 id; @@ -107,8 +114,7 @@ struct nand_info { u8 QE_address; u8 QE_bits; - u8 spare_offs_1; - u8 spare_offs_2; + struct nand_mega_area meta; u32 (*ecc_status)(void); }; diff --git a/drivers/rkflash/sfc_nor.c b/drivers/rkflash/sfc_nor.c index 8da0acee86..d55d891212 100644 --- a/drivers/rkflash/sfc_nor.c +++ b/drivers/rkflash/sfc_nor.c @@ -28,6 +28,8 @@ static struct flash_info spi_flash_tbl[] = { { 0xef4018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 15, 9, 0 }, /* 25Q256F/J */ { 0xef4019, 128, 8, 0x13, 0x02, 0x6C, 0x32, 0x20, 0xD8, 0x3C, 16, 9, 0 }, + /* 25Q256JWEQ*/ + { 0xef6019, 128, 8, 0x13, 0x02, 0x6C, 0x32, 0x20, 0xD8, 0x3C, 16, 9, 0 }, /* 25Q64FWSSIG */ { 0xef6017, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 14, 9, 0 }, /* MX25L6433F */ @@ -85,56 +87,64 @@ static struct flash_info spi_flash_tbl[] = { static int snor_write_en(void) { int ret; - union SFCCMD_DATA sfcmd; + struct rk_sfc_op op; - sfcmd.d32 = 0; - sfcmd.b.cmd = CMD_WRITE_EN; + op.sfcmd.d32 = 0; + op.sfcmd.b.cmd = CMD_WRITE_EN; - ret = sfc_request(sfcmd.d32, 0, 0, NULL); + op.sfctrl.d32 = 0; + + ret = sfc_request(&op, 0, NULL, 0); return ret; } int snor_reset_device(void) { - int ret; - union SFCCMD_DATA sfcmd; + struct rk_sfc_op op; - sfcmd.d32 = 0; - sfcmd.b.cmd = CMD_ENABLE_RESER; - sfc_request(sfcmd.d32, 0, 0, NULL); + op.sfcmd.d32 = 0; + op.sfcmd.b.cmd = CMD_ENABLE_RESER; - sfcmd.d32 = 0; - sfcmd.b.cmd = CMD_RESET_DEVICE; - ret = sfc_request(sfcmd.d32, 0, 0, NULL); + op.sfctrl.d32 = 0; + sfc_request(&op, 0, NULL, 0); + + op.sfcmd.d32 = 0; + op.sfcmd.b.cmd = CMD_RESET_DEVICE; + + op.sfctrl.d32 = 0; + sfc_request(&op, 0, NULL, 0); /* tRST=30us , delay 1ms here */ - mdelay(1); - return ret; + sfc_delay(1000); + + return SFC_OK; } static int snor_enter_4byte_mode(void) { int ret; - union SFCCMD_DATA sfcmd; + struct rk_sfc_op op; - sfcmd.d32 = 0; - sfcmd.b.cmd = CMD_ENTER_4BYTE_MODE; + op.sfcmd.d32 = 0; + op.sfcmd.b.cmd = CMD_ENTER_4BYTE_MODE; - ret = sfc_request(sfcmd.d32, 0, 0, NULL); + op.sfctrl.d32 = 0; + + ret = sfc_request(&op, 0, NULL, 0); return ret; } static int snor_read_status(u32 reg_index, u8 *status) { int ret; - union SFCCMD_DATA sfcmd; + struct rk_sfc_op op; u8 read_stat_cmd[] = {CMD_READ_STATUS, CMD_READ_STATUS2, CMD_READ_STATUS3}; - sfcmd.d32 = 0; - sfcmd.b.cmd = read_stat_cmd[reg_index]; - sfcmd.b.datasize = 1; + op.sfcmd.d32 = 0; + op.sfcmd.b.cmd = read_stat_cmd[reg_index]; - ret = sfc_request(sfcmd.d32, 0, 0, status); + op.sfctrl.d32 = 0; + ret = sfc_request(&op, 0, status, 1); return ret; } @@ -142,16 +152,17 @@ static int snor_read_status(u32 reg_index, u8 *status) static int snor_wait_busy(int timeout) { int ret; - union SFCCMD_DATA sfcmd; + struct rk_sfc_op op; int i; u32 status; - sfcmd.d32 = 0; - sfcmd.b.cmd = CMD_READ_STATUS; - sfcmd.b.datasize = 1; + op.sfcmd.d32 = 0; + op.sfcmd.b.cmd = CMD_READ_STATUS; + + op.sfctrl.d32 = 0; for (i = 0; i < timeout; i++) { - ret = sfc_request(sfcmd.d32, 0, 0, &status); + ret = sfc_request(&op, 0, &status, 1); if (ret != SFC_OK) return ret; @@ -168,24 +179,26 @@ static int snor_wait_busy(int timeout) static int snor_write_status2(u32 reg_index, u8 status) { int ret; - union SFCCMD_DATA sfcmd; + struct rk_sfc_op op; u8 status2[2]; - u8 read_index; status2[reg_index] = status; - read_index = (reg_index == 0) ? 2 : 0; - ret = snor_read_status(read_index, &status2[read_index]); + if (reg_index == 0) + ret = snor_read_status(2, &status2[1]); + else + ret = snor_read_status(0, &status2[0]); if (ret != SFC_OK) return ret; snor_write_en(); - sfcmd.d32 = 0; - sfcmd.b.cmd = CMD_WRITE_STATUS; - sfcmd.b.datasize = 2; - sfcmd.b.rw = SFC_WRITE; + op.sfcmd.d32 = 0; + op.sfcmd.b.cmd = CMD_WRITE_STATUS; + op.sfcmd.b.rw = SFC_WRITE; - ret = sfc_request(sfcmd.d32, 0, 0, &status2[0]); + op.sfctrl.d32 = 0; + + ret = sfc_request(&op, 0, &status2[0], 2); if (ret != SFC_OK) return ret; @@ -197,7 +210,7 @@ static int snor_write_status2(u32 reg_index, u8 status) static int snor_write_status1(u32 reg_index, u8 status) { int ret; - union SFCCMD_DATA sfcmd; + struct rk_sfc_op op; u8 status2[2]; u8 read_index; @@ -209,12 +222,13 @@ static int snor_write_status1(u32 reg_index, u8 status) snor_write_en(); - sfcmd.d32 = 0; - sfcmd.b.cmd = CMD_WRITE_STATUS; - sfcmd.b.datasize = 2; - sfcmd.b.rw = SFC_WRITE; + op.sfcmd.d32 = 0; + op.sfcmd.b.cmd = CMD_WRITE_STATUS; + op.sfcmd.b.rw = SFC_WRITE; - ret = sfc_request(sfcmd.d32, 0, 0, &status2[0]); + op.sfctrl.d32 = 0; + + ret = sfc_request(&op, 0, &status2[0], 2); if (ret != SFC_OK) return ret; @@ -226,16 +240,17 @@ static int snor_write_status1(u32 reg_index, u8 status) static int snor_write_status(u32 reg_index, u8 status) { int ret; - union SFCCMD_DATA sfcmd; + struct rk_sfc_op op; u8 write_stat_cmd[] = {CMD_WRITE_STATUS, CMD_WRITE_STATUS2, CMD_WRITE_STATUS3}; snor_write_en(); - sfcmd.d32 = 0; - sfcmd.b.cmd = write_stat_cmd[reg_index]; - sfcmd.b.datasize = 1; - sfcmd.b.rw = SFC_WRITE; + op.sfcmd.d32 = 0; + op.sfcmd.b.cmd = write_stat_cmd[reg_index]; + op.sfcmd.b.rw = SFC_WRITE; - ret = sfc_request(sfcmd.d32, 0, 0, &status); + op.sfctrl.d32 = 0; + + ret = sfc_request(&op, 0, &status, 1); if (ret != SFC_OK) return ret; @@ -249,30 +264,32 @@ int snor_erase(struct SFNOR_DEV *p_dev, enum NOR_ERASE_TYPE erase_type) { int ret; - union SFCCMD_DATA sfcmd; + struct rk_sfc_op op; int timeout[] = {400, 2000, 40000}; /* ms */ - rkflash_print_dio("%s %x\n", __func__, addr); + rkflash_print_dio("%s %x %x\n", __func__, addr, erase_type); if (erase_type > ERASE_CHIP) return SFC_PARAM_ERR; - sfcmd.d32 = 0; + op.sfcmd.d32 = 0; if (erase_type == ERASE_BLOCK64K) - sfcmd.b.cmd = p_dev->blk_erase_cmd; + op.sfcmd.b.cmd = p_dev->blk_erase_cmd; else if (erase_type == ERASE_SECTOR) - sfcmd.b.cmd = p_dev->sec_erase_cmd; + op.sfcmd.b.cmd = p_dev->sec_erase_cmd; else - sfcmd.b.cmd = CMD_CHIP_ERASE; + op.sfcmd.b.cmd = CMD_CHIP_ERASE; - sfcmd.b.addrbits = (erase_type != ERASE_CHIP) ? + op.sfcmd.b.addrbits = (erase_type != ERASE_CHIP) ? SFC_ADDR_24BITS : SFC_ADDR_0BITS; if (p_dev->addr_mode == ADDR_MODE_4BYTE && erase_type != ERASE_CHIP) - sfcmd.b.addrbits = SFC_ADDR_32BITS; + op.sfcmd.b.addrbits = SFC_ADDR_32BITS; + + op.sfctrl.d32 = 0; snor_write_en(); - ret = sfc_request(sfcmd.d32, 0, addr, NULL); + ret = sfc_request(&op, addr, NULL, 0); if (ret != SFC_OK) return ret; @@ -286,29 +303,27 @@ int snor_prog_page(struct SFNOR_DEV *p_dev, u32 size) { int ret; - union SFCCMD_DATA sfcmd; - union SFCCTRL_DATA sfctrl; + struct rk_sfc_op op; rkflash_print_dio("%s %x %x\n", __func__, addr, *(u32 *)(p_data)); - sfcmd.d32 = 0; - sfcmd.b.cmd = p_dev->prog_cmd; - sfcmd.b.addrbits = SFC_ADDR_24BITS; - sfcmd.b.datasize = size; - sfcmd.b.rw = SFC_WRITE; + op.sfcmd.d32 = 0; + op.sfcmd.b.cmd = p_dev->prog_cmd; + op.sfcmd.b.addrbits = SFC_ADDR_24BITS; + op.sfcmd.b.rw = SFC_WRITE; - sfctrl.d32 = 0; - sfctrl.b.datalines = p_dev->prog_lines; - sfctrl.b.enbledma = 0; + op.sfctrl.d32 = 0; + op.sfctrl.b.datalines = p_dev->prog_lines; + op.sfctrl.b.enbledma = 1; if (p_dev->prog_cmd == CMD_PAGE_PROG_A4) - sfctrl.b.addrlines = SFC_4BITS_LINE; + op.sfctrl.b.addrlines = SFC_4BITS_LINE; if (p_dev->addr_mode == ADDR_MODE_4BYTE) - sfcmd.b.addrbits = SFC_ADDR_32BITS; + op.sfcmd.b.addrbits = SFC_ADDR_32BITS; snor_write_en(); - ret = sfc_request(sfcmd.d32, sfctrl.d32, addr, p_data); + ret = sfc_request(&op, addr, p_data, size); if (ret != SFC_OK) return ret; @@ -386,35 +401,33 @@ int snor_read_data(struct SFNOR_DEV *p_dev, u32 size) { int ret; - union SFCCMD_DATA sfcmd; - union SFCCTRL_DATA sfctrl; + struct rk_sfc_op op; - sfcmd.d32 = 0; - sfcmd.b.cmd = p_dev->read_cmd; - sfcmd.b.datasize = size; - sfcmd.b.addrbits = SFC_ADDR_24BITS; + op.sfcmd.d32 = 0; + op.sfcmd.b.cmd = p_dev->read_cmd; + op.sfcmd.b.addrbits = SFC_ADDR_24BITS; - sfctrl.d32 = 0; - sfctrl.b.datalines = p_dev->read_lines; + op.sfctrl.d32 = 0; + op.sfctrl.b.datalines = p_dev->read_lines; if (!(size & 0x3) && size >= 4) - sfctrl.b.enbledma = 0; + op.sfctrl.b.enbledma = 1; if (p_dev->read_cmd == CMD_FAST_READ_X1 || p_dev->read_cmd == CMD_FAST_READ_X4 || p_dev->read_cmd == CMD_FAST_READ_X2 || p_dev->read_cmd == CMD_FAST_4READ_X4) { - sfcmd.b.dummybits = 8; + op.sfcmd.b.dummybits = 8; } else if (p_dev->read_cmd == CMD_FAST_READ_A4) { - sfcmd.b.addrbits = SFC_ADDR_32BITS; + op.sfcmd.b.addrbits = SFC_ADDR_32BITS; addr = (addr << 8) | 0xFF; /* Set M[7:0] = 0xFF */ - sfcmd.b.dummybits = 4; - sfctrl.b.addrlines = SFC_4BITS_LINE; + op.sfcmd.b.dummybits = 4; + op.sfctrl.b.addrlines = SFC_4BITS_LINE; } if (p_dev->addr_mode == ADDR_MODE_4BYTE) - sfcmd.b.addrbits = SFC_ADDR_32BITS; + op.sfcmd.b.addrbits = SFC_ADDR_32BITS; - ret = sfc_request(sfcmd.d32, sfctrl.d32, addr, p_data); + ret = sfc_request(&op, addr, p_data, size); rkflash_print_dio("%s %x %x\n", __func__, addr, *(u32 *)(p_data)); return ret; @@ -434,7 +447,7 @@ int snor_read(struct SFNOR_DEV *p_dev, u32 sec, u32 n_sec, void *p_data) addr = sec << 9; size = n_sec << 9; while (size) { - len = size < SFC_MAX_IOSIZE ? size : SFC_MAX_IOSIZE; + len = size < p_dev->max_iosize ? size : p_dev->max_iosize; ret = snor_read_data(p_dev, addr, p_buf, len); if (ret != SFC_OK) { rkflash_print_error("snor_read_data %x ret= %x\n", @@ -502,13 +515,14 @@ out: int snor_read_id(u8 *data) { int ret; - union SFCCMD_DATA sfcmd; + struct rk_sfc_op op; - sfcmd.d32 = 0; - sfcmd.b.cmd = CMD_READ_JEDECID; - sfcmd.b.datasize = 3; + op.sfcmd.d32 = 0; + op.sfcmd.b.cmd = CMD_READ_JEDECID; - ret = sfc_request(sfcmd.d32, 0, 0, data); + op.sfctrl.d32 = 0; + + ret = sfc_request(&op, 0, data, 3); return ret; } @@ -516,15 +530,16 @@ int snor_read_id(u8 *data) static int snor_read_parameter(u32 addr, u8 *data) { int ret; - union SFCCMD_DATA sfcmd; + struct rk_sfc_op op; - sfcmd.d32 = 0; - sfcmd.b.cmd = CMD_READ_PARAMETER; - sfcmd.b.datasize = 1; - sfcmd.b.addrbits = SFC_ADDR_24BITS; - sfcmd.b.dummybits = 8; + op.sfcmd.d32 = 0; + op.sfcmd.b.cmd = CMD_READ_PARAMETER; + op.sfcmd.b.addrbits = SFC_ADDR_24BITS; + op.sfcmd.b.dummybits = 8; - ret = sfc_request(sfcmd.d32, 0, addr, data); + op.sfctrl.d32 = 0; + + ret = sfc_request(&op, addr, data, 1); return ret; } @@ -572,7 +587,8 @@ int snor_init(struct SFNOR_DEV *p_dev) if (!p_dev) return SFC_PARAM_ERR; - memset(p_dev, 0, sizeof(struct SFNOR_DEV)); + memset((void *)p_dev, 0, sizeof(struct SFNOR_DEV)); + p_dev->max_iosize = sfc_get_max_iosize(); snor_read_id(id_byte); rkflash_print_error("sfc nor id: %x %x %x\n", id_byte[0], id_byte[1], id_byte[2]); @@ -625,7 +641,7 @@ int snor_init(struct SFNOR_DEV *p_dev) if ((g_spi_flash_info->feature & FEA_4BYTE_ADDR_MODE)) snor_enter_4byte_mode(); } else { - p_dev->capacity = 1 << id_byte[2] >> 3; + p_dev->capacity = 1 << (id_byte[2] - 9); p_dev->QE_bits = 0; p_dev->blk_size = NOR_SECS_BLK; p_dev->page_size = NOR_SECS_PAGE; diff --git a/drivers/rkflash/sfc_nor.h b/drivers/rkflash/sfc_nor.h index 0b4e369826..6c91bb2eaf 100644 --- a/drivers/rkflash/sfc_nor.h +++ b/drivers/rkflash/sfc_nor.h @@ -112,6 +112,7 @@ struct SFNOR_DEV { enum SFC_DATA_LINES prog_lines; SNOR_WRITE_STATUS write_status; + u32 max_iosize; }; struct flash_info { diff --git a/make.sh b/make.sh index 2ba1dcc73b..9f39218396 100755 --- a/make.sh +++ b/make.sh @@ -640,7 +640,7 @@ function pack_arm32_trust_image() else ./scripts/fit-vboot-uboot.sh --no-vboot --no-rebuild ls uboot.img trust*.img >/dev/null 2>&1 && rm uboot.img trust*.img -rf - echo "pack uboot.fit (with uboot trust) okay! Input: $ini" + echo "pack uboot.img (with uboot trust) okay! Input: $ini" fi } diff --git a/scripts/fit-base.sh b/scripts/fit-base.sh index e0f95e94b7..d524198a9c 100755 --- a/scripts/fit-base.sh +++ b/scripts/fit-base.sh @@ -46,14 +46,7 @@ function usage_pack() echo " $0 [args]" echo echo "args:" - if [[ "$0" = *boot.sh ]]; then - echo " --rollback-index-boot " - elif [[ "$0" = *uboot.sh ]]; then - echo " --rollback-index-uboot " - else - echo " --rollback-index-boot " - echo " --rollback-index-uboot " - fi + echo " --rollback-index " echo " --no-vboot" echo } @@ -95,13 +88,15 @@ function fit_process_args() ARG_NO_REBUILD="y" shift 1 ;; - --rollback-index-boot) - ARG_ROLLBACK_IDX_BOOT=$2 - arg_check_decimal $2 - shift 2 - ;; - --rollback-index-uboot) - ARG_ROLLBACK_IDX_UBOOT=$2 + --rollback-index) + if [[ "$0" = *fit-vboot-uboot.sh ]]; then + ARG_ROLLBACK_IDX_UBOOT=$2 + elif [[ "$0" = *fit-vboot-boot.sh ]]; then + ARG_ROLLBACK_IDX_BOOT=$2 + else + usage_pack + exit 1 + fi arg_check_decimal $2 shift 2 ;; @@ -355,7 +350,9 @@ function fit_boot_make_img() ITB_FILE=$FIT_ITB_BOOT fi - cp $ITB_FILE $FIT_IMG_BOOT + if [ "$ITB_FILE" != "$FIT_IMG_BOOT" ]; then + cp $ITB_FILE $FIT_IMG_BOOT -f + fi } function fit_resign()