rkflash: change to use rk_sfc_op for request

Change-Id: I20cc6b3cf4b49a9ca96af5170af8b7b554071a6f
Signed-off-by: Jon Lin <jon.lin@rock-chips.com>
This commit is contained in:
Jon Lin 2020-04-10 21:18:18 +08:00 committed by Jianhong Chen
parent a6fcac41dc
commit 58463f4dec
4 changed files with 240 additions and 204 deletions

View File

@ -45,7 +45,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 +57,27 @@ 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) {
struct bounce_buffer bb;
unsigned int bb_flags;
@ -85,17 +86,17 @@ 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;
while ((readl(g_sfc_reg + SFC_SR) & SFC_BUSY) &&
timeout = size * 10;
while (!((readl(g_sfc_reg + SFC_RAWISR) & DMA_INT)) &&
(timeout-- > 0))
sfc_delay(1);
writel(0xFFFFFFFF, g_sfc_reg + SFC_ICLR);
@ -108,7 +109,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 +133,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 +184,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;

View File

@ -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,8 +184,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);
int rksfc_get_reg_addr(unsigned long *p_sfc_addr);

View File

@ -34,7 +34,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 */
@ -87,6 +87,8 @@ static struct nand_info spi_nand_tbl[] = {
{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;
@ -108,43 +110,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;
@ -153,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;
@ -199,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;
@ -219,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;
@ -237,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;
@ -259,7 +269,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;
}
@ -276,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;
@ -301,7 +311,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;
}
@ -319,7 +329,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;
@ -344,7 +354,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;
}
@ -363,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;
@ -384,7 +394,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;
}
@ -403,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;
@ -424,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;
}
@ -432,16 +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;
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);
@ -455,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();
@ -467,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);
@ -518,18 +530,19 @@ 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;
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)
@ -541,15 +554,15 @@ static u32 sfc_nand_read_page_raw(u8 cs, u32 addr, u32 *p_page_buf)
else
ecc_result = sfc_nand_ecc_status();
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;
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)
@ -560,7 +573,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;
@ -619,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;
}
@ -728,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 = 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];

View File

@ -85,56 +85,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 +150,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 +177,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 +208,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 +220,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 +238,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 +262,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 +301,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 = 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;
@ -386,35 +399,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 = 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;
@ -502,13 +513,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 +528,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 +585,7 @@ 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));
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 +638,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;