From cd76ab1868559dfc9831ef737e5ddf30d17145e0 Mon Sep 17 00:00:00 2001 From: Jon Lin Date: Fri, 10 Apr 2020 21:32:59 +0800 Subject: [PATCH] drivers: rkflash: change to use rk_sfc_op for request Change-Id: I5c82c8178c7641eb1f32b207a2afb0c30a5ef871 Signed-off-by: Jon Lin --- drivers/rkflash/flash_com.h | 2 +- drivers/rkflash/sfc.c | 35 ++--- drivers/rkflash/sfc.h | 9 +- drivers/rkflash/sfc_nand.c | 196 +++++++++++++------------ drivers/rkflash/sfc_nor.c | 276 ++++++++++++++++++------------------ 5 files changed, 272 insertions(+), 246 deletions(-) diff --git a/drivers/rkflash/flash_com.h b/drivers/rkflash/flash_com.h index dd87effe2447..da6eb29968a1 100644 --- a/drivers/rkflash/flash_com.h +++ b/drivers/rkflash/flash_com.h @@ -18,7 +18,7 @@ #define NAND_IDB_START 64 /* 32 KB*/ #define NAND_IDB_SIZE 512 /* 256 KB*/ #define NAND_IDB_END (NAND_IDB_START + NAND_IDB_SIZE - 1) -#define DEFAULT_IDB_RESERVED_BLOCK 16 +#define DEFAULT_IDB_RESERVED_BLOCK 8 #define FULL_SLC 0 #define SLC 1 diff --git a/drivers/rkflash/sfc.c b/drivers/rkflash/sfc.c index 1b9fc71cdfab..cb3e1453f6e2 100644 --- a/drivers/rkflash/sfc.c +++ b/drivers/rkflash/sfc.c @@ -42,7 +42,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; @@ -54,41 +54,42 @@ 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; - 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) { unsigned long dma_addr; u8 direction = (cmd.b.rw == SFC_WRITE) ? 1 : 0; dma_addr = rksfc_dma_map_single((unsigned long)data, - cmd.b.datasize, + size, direction); rksfc_irq_flag_init(); writel(0xFFFFFFFF, g_sfc_reg + SFC_ICLR); - writel(~(FINISH_INT), g_sfc_reg + SFC_IMR); + writel(~((u32)DMA_INT), g_sfc_reg + SFC_IMR); writel((u32)dma_addr, g_sfc_reg + SFC_DMA_ADDR); writel(SFC_DMA_START, g_sfc_reg + SFC_DMA_TRIGGER); - timeout = cmd.b.datasize * 10; + timeout = size * 10; rksfc_wait_for_irq_completed(); - while ((readl(g_sfc_reg + SFC_SR) & SFC_BUSY) && + while (!((readl(g_sfc_reg + SFC_RAWISR) & DMA_INT)) && (timeout-- > 0)) sfc_delay(1); writel(0xFFFFFFFF, g_sfc_reg + SFC_ICLR); @@ -96,7 +97,7 @@ int sfc_request(u32 sfcmd, u32 sfctrl, u32 addr, void *data) ret = SFC_WAIT_TIMEOUT; direction = (cmd.b.rw == SFC_WRITE) ? 1 : 0; rksfc_dma_unmap_single(dma_addr, - cmd.b.datasize, + size, direction); } else { u32 i, words, count, bytes; @@ -104,7 +105,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) { @@ -128,8 +129,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) { @@ -179,7 +180,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 777836812428..6cb1f4865343 100644 --- a/drivers/rkflash/sfc.h +++ b/drivers/rkflash/sfc.h @@ -88,6 +88,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 @@ -180,8 +182,13 @@ 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); void sfc_handle_irq(void); diff --git a/drivers/rkflash/sfc_nand.c b/drivers/rkflash/sfc_nand.c index 8ef079032fd7..934041ed0fd3 100644 --- a/drivers/rkflash/sfc_nand.c +++ b/drivers/rkflash/sfc_nand.c @@ -30,7 +30,7 @@ static struct nand_info spi_nand_tbl[] = { /* IS37SML01G1 */ {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, 0xff, 0xff}, &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, 0xff, 0xff}, NULL}, /* HYF2GQ4UDACAE */ @@ -104,43 +104,49 @@ static struct nand_info *sfc_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; @@ -149,17 +155,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; @@ -195,7 +203,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; @@ -215,7 +223,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; @@ -233,7 +241,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; @@ -255,7 +263,7 @@ 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; } @@ -272,7 +280,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; @@ -297,7 +305,7 @@ 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; } @@ -315,7 +323,7 @@ u32 sfc_nand_ecc_status_sp2(void) */ u32 sfc_nand_ecc_status_sp3(void) { - int ret; + u32 ret; u32 i; u8 ecc; u8 status, status1; @@ -340,7 +348,7 @@ 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; } @@ -359,7 +367,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; @@ -380,7 +388,7 @@ 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; } @@ -399,7 +407,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; @@ -420,7 +428,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; } @@ -428,16 +436,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; - sfcmd.b.rw = SFC_WRITE; + 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); @@ -451,10 +462,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(); @@ -463,24 +473,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); @@ -514,37 +524,39 @@ 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.rw = SFC_WRITE; - 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) @@ -555,7 +567,7 @@ static u32 sfc_nand_read_page_raw(u8 cs, u32 addr, u32 *p_page_buf) 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; struct nand_mega_area *meta = &p_nand_info->meta; @@ -614,14 +626,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; } @@ -723,11 +737,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 = 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]; diff --git a/drivers/rkflash/sfc_nor.c b/drivers/rkflash/sfc_nor.c index 4ba09f9eb1b5..9b7b9a0985a2 100644 --- a/drivers/rkflash/sfc_nor.c +++ b/drivers/rkflash/sfc_nor.c @@ -74,56 +74,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; } @@ -131,16 +139,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; @@ -157,7 +166,7 @@ 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; @@ -169,12 +178,13 @@ static int snor_write_status2(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; @@ -186,7 +196,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; @@ -198,12 +208,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; @@ -215,16 +226,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; @@ -238,28 +250,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 %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; @@ -273,27 +289,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; - 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; + rkflash_print_dio("%s %x %x\n", __func__, addr, *(u32 *)(p_data)); - sfctrl.d32 = 0; - sfctrl.b.datalines = p_dev->prog_lines; - sfctrl.b.enbledma = 0; + 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; + + op.sfctrl.d32 = 0; + op.sfctrl.b.datalines = p_dev->prog_lines; + op.sfctrl.b.enbledma = 0; 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; @@ -330,28 +346,18 @@ static int snor_enable_QE(struct SFNOR_DEV *p_dev) int bit_offset; u8 status; - if (p_dev->manufacturer == MID_GIGADEV || - p_dev->manufacturer == MID_WINBOND || - p_dev->manufacturer == MID_XTX || - p_dev->manufacturer == MID_MACRONIX || - p_dev->manufacturer == MID_PUYA || - p_dev->manufacturer == MID_XMC || - p_dev->manufacturer == MID_DOSILICON || - p_dev->manufacturer == MID_ZBIT) { - reg_index = p_dev->QE_bits >> 3; - bit_offset = p_dev->QE_bits & 0x7; - ret = snor_read_status(reg_index, &status); - if (ret != SFC_OK) - return ret; + reg_index = p_dev->QE_bits >> 3; + bit_offset = p_dev->QE_bits & 0x7; + ret = snor_read_status(reg_index, &status); + if (ret != SFC_OK) + return ret; - if (status & (1 << bit_offset)) /* is QE bit set */ - return SFC_OK; + if (status & (1 << bit_offset)) /* is QE bit set */ + return SFC_OK; - status |= (1 << bit_offset); - return p_dev->write_status(reg_index, status); - } + status |= (1 << bit_offset); - return ret; + return p_dev->write_status(reg_index, status); } int snor_disable_QE(struct SFNOR_DEV *p_dev) @@ -361,28 +367,18 @@ int snor_disable_QE(struct SFNOR_DEV *p_dev) int bit_offset; u8 status; - if (p_dev->manufacturer == MID_GIGADEV || - p_dev->manufacturer == MID_WINBOND || - p_dev->manufacturer == MID_XTX || - p_dev->manufacturer == MID_MACRONIX || - p_dev->manufacturer == MID_PUYA || - p_dev->manufacturer == MID_XMC || - p_dev->manufacturer == MID_DOSILICON || - p_dev->manufacturer == MID_ZBIT) { - reg_index = p_dev->QE_bits >> 3; - bit_offset = p_dev->QE_bits & 0x7; - ret = snor_read_status(reg_index, &status); - if (ret != SFC_OK) - return ret; + reg_index = p_dev->QE_bits >> 3; + bit_offset = p_dev->QE_bits & 0x7; + ret = snor_read_status(reg_index, &status); + if (ret != SFC_OK) + return ret; - if (!(status & (1 << bit_offset))) - return SFC_OK; + if (!(status & (1 << bit_offset))) + return SFC_OK; - status &= ~(1 << bit_offset); - return p_dev->write_status(reg_index, status); - } + status &= ~(1 << bit_offset); - return ret; + return p_dev->write_status(reg_index, status); } int snor_read_data(struct SFNOR_DEV *p_dev, @@ -391,35 +387,34 @@ 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 = 0; 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; } @@ -430,6 +425,8 @@ int snor_read(struct SFNOR_DEV *p_dev, u32 sec, u32 n_sec, void *p_data) u32 addr, size, len; u8 *p_buf = (u8 *)p_data; + rkflash_print_dio("%s %x %x\n", __func__, sec, n_sec); + if ((sec + n_sec) > p_dev->capacity) return SFC_PARAM_ERR; @@ -462,6 +459,8 @@ int snor_write(struct SFNOR_DEV *p_dev, u32 sec, u32 n_sec, void *p_data) u8 *p_buf = (u8 *)p_data; u32 total_sec = n_sec; + rkflash_print_dio("%s %x %x\n", __func__, sec, n_sec); + if ((sec + n_sec) > p_dev->capacity) return SFC_PARAM_ERR; @@ -502,13 +501,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 +516,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; } @@ -566,13 +567,13 @@ static void *snor_flash_info_adjust(struct flash_info *spi_flash_info) int snor_init(struct SFNOR_DEV *p_dev) { struct flash_info *g_spi_flash_info; - u32 i; + u32 i, ret; u8 id_byte[5]; if (!p_dev) return SFC_PARAM_ERR; - memset(p_dev, 0, sizeof(struct SFNOR_DEV)); + memset((void *)p_dev, 0, sizeof(struct SFNOR_DEV)); snor_read_id(id_byte); rkflash_print_error("sfc nor id: %x %x %x\n", id_byte[0], id_byte[1], id_byte[2]); @@ -605,7 +606,10 @@ int snor_init(struct SFNOR_DEV *p_dev) else if (i == 2) p_dev->write_status = snor_write_status2; if (g_spi_flash_info->feature & FEA_4BIT_READ) { - if (snor_enable_QE(p_dev) == SFC_OK) { + ret = SFC_OK; + if (g_spi_flash_info->QE_bits) + ret = snor_enable_QE(p_dev); + if (ret == SFC_OK) { p_dev->read_lines = DATA_LINES_X4; p_dev->read_cmd = g_spi_flash_info->read_cmd_4; } @@ -622,7 +626,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;