rkflash: support transfer large size data
Change-Id: I36c5daabb952215bbc4d2cb2cffb82df3fa7085a Signed-off-by: Jon Lin <jon.lin@rock-chips.com>
This commit is contained in:
parent
58463f4dec
commit
534d4d2fe4
|
|
@ -11,6 +11,9 @@
|
||||||
|
|
||||||
#include "sfc.h"
|
#include "sfc.h"
|
||||||
|
|
||||||
|
#define SFC_MAX_IOSIZE_VER3 (1024 * 8)
|
||||||
|
#define SFC_MAX_IOSIZE_VER4 (0xFFFFFFFF)
|
||||||
|
|
||||||
static void __iomem *g_sfc_reg;
|
static void __iomem *g_sfc_reg;
|
||||||
|
|
||||||
static void sfc_reset(void)
|
static void sfc_reset(void)
|
||||||
|
|
@ -30,11 +33,21 @@ u16 sfc_get_version(void)
|
||||||
return (u32)(readl(g_sfc_reg + SFC_VER) & 0xffff);
|
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)
|
int sfc_init(void __iomem *reg_addr)
|
||||||
{
|
{
|
||||||
g_sfc_reg = reg_addr;
|
g_sfc_reg = reg_addr;
|
||||||
sfc_reset();
|
sfc_reset();
|
||||||
writel(0, g_sfc_reg + SFC_CTRL);
|
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;
|
return SFC_OK;
|
||||||
}
|
}
|
||||||
|
|
@ -70,6 +83,10 @@ int sfc_request(struct rk_sfc_op *op, u32 addr, void *data, u32 size)
|
||||||
/* shift in the data at negedge sclk_out */
|
/* shift in the data at negedge sclk_out */
|
||||||
op->sfctrl.d32 |= 0x2;
|
op->sfctrl.d32 |= 0x2;
|
||||||
cmd.b.datasize = size;
|
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(op->sfctrl.d32, g_sfc_reg + SFC_CTRL);
|
writel(op->sfctrl.d32, g_sfc_reg + SFC_CTRL);
|
||||||
writel(cmd.d32, g_sfc_reg + SFC_CMD);
|
writel(cmd.d32, g_sfc_reg + SFC_CMD);
|
||||||
|
|
@ -96,7 +113,7 @@ int sfc_request(struct rk_sfc_op *op, u32 addr, void *data, u32 size)
|
||||||
writel(SFC_DMA_START, g_sfc_reg + SFC_DMA_TRIGGER);
|
writel(SFC_DMA_START, g_sfc_reg + SFC_DMA_TRIGGER);
|
||||||
|
|
||||||
timeout = size * 10;
|
timeout = size * 10;
|
||||||
while (!((readl(g_sfc_reg + SFC_RAWISR) & DMA_INT)) &&
|
while ((readl(g_sfc_reg + SFC_SR) & SFC_BUSY) &&
|
||||||
(timeout-- > 0))
|
(timeout-- > 0))
|
||||||
sfc_delay(1);
|
sfc_delay(1);
|
||||||
writel(0xFFFFFFFF, g_sfc_reg + SFC_ICLR);
|
writel(0xFFFFFFFF, g_sfc_reg + SFC_ICLR);
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,9 @@
|
||||||
#ifndef _SFC_H
|
#ifndef _SFC_H
|
||||||
#define _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_INT (0) /* enable interrupt */
|
||||||
#define SFC_EN_DMA (1) /* enable dma */
|
#define SFC_EN_DMA (1) /* enable dma */
|
||||||
#define SFC_FIFO_DEPTH (0x10) /* 16 words */
|
#define SFC_FIFO_DEPTH (0x10) /* 16 words */
|
||||||
|
|
@ -193,6 +193,7 @@ int sfc_init(void __iomem *reg_addr);
|
||||||
int sfc_request(struct rk_sfc_op *op, u32 addr, void *data, u32 size);
|
int sfc_request(struct rk_sfc_op *op, u32 addr, void *data, u32 size);
|
||||||
u16 sfc_get_version(void);
|
u16 sfc_get_version(void);
|
||||||
void sfc_clean_irq(void);
|
void sfc_clean_irq(void);
|
||||||
|
u32 sfc_get_max_iosize(void);
|
||||||
int rksfc_get_reg_addr(unsigned long *p_sfc_addr);
|
int rksfc_get_reg_addr(unsigned long *p_sfc_addr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -312,7 +312,7 @@ int snor_prog_page(struct SFNOR_DEV *p_dev,
|
||||||
|
|
||||||
op.sfctrl.d32 = 0;
|
op.sfctrl.d32 = 0;
|
||||||
op.sfctrl.b.datalines = p_dev->prog_lines;
|
op.sfctrl.b.datalines = p_dev->prog_lines;
|
||||||
op.sfctrl.b.enbledma = 0;
|
op.sfctrl.b.enbledma = 1;
|
||||||
if (p_dev->prog_cmd == CMD_PAGE_PROG_A4)
|
if (p_dev->prog_cmd == CMD_PAGE_PROG_A4)
|
||||||
op.sfctrl.b.addrlines = SFC_4BITS_LINE;
|
op.sfctrl.b.addrlines = SFC_4BITS_LINE;
|
||||||
|
|
||||||
|
|
@ -408,7 +408,7 @@ int snor_read_data(struct SFNOR_DEV *p_dev,
|
||||||
op.sfctrl.d32 = 0;
|
op.sfctrl.d32 = 0;
|
||||||
op.sfctrl.b.datalines = p_dev->read_lines;
|
op.sfctrl.b.datalines = p_dev->read_lines;
|
||||||
if (!(size & 0x3) && size >= 4)
|
if (!(size & 0x3) && size >= 4)
|
||||||
op.sfctrl.b.enbledma = 0;
|
op.sfctrl.b.enbledma = 1;
|
||||||
|
|
||||||
if (p_dev->read_cmd == CMD_FAST_READ_X1 ||
|
if (p_dev->read_cmd == CMD_FAST_READ_X1 ||
|
||||||
p_dev->read_cmd == CMD_FAST_READ_X4 ||
|
p_dev->read_cmd == CMD_FAST_READ_X4 ||
|
||||||
|
|
@ -445,7 +445,7 @@ int snor_read(struct SFNOR_DEV *p_dev, u32 sec, u32 n_sec, void *p_data)
|
||||||
addr = sec << 9;
|
addr = sec << 9;
|
||||||
size = n_sec << 9;
|
size = n_sec << 9;
|
||||||
while (size) {
|
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);
|
ret = snor_read_data(p_dev, addr, p_buf, len);
|
||||||
if (ret != SFC_OK) {
|
if (ret != SFC_OK) {
|
||||||
rkflash_print_error("snor_read_data %x ret= %x\n",
|
rkflash_print_error("snor_read_data %x ret= %x\n",
|
||||||
|
|
@ -586,6 +586,7 @@ int snor_init(struct SFNOR_DEV *p_dev)
|
||||||
return SFC_PARAM_ERR;
|
return SFC_PARAM_ERR;
|
||||||
|
|
||||||
memset((void *)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);
|
snor_read_id(id_byte);
|
||||||
rkflash_print_error("sfc nor id: %x %x %x\n",
|
rkflash_print_error("sfc nor id: %x %x %x\n",
|
||||||
id_byte[0], id_byte[1], id_byte[2]);
|
id_byte[0], id_byte[1], id_byte[2]);
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,7 @@ struct SFNOR_DEV {
|
||||||
enum SFC_DATA_LINES prog_lines;
|
enum SFC_DATA_LINES prog_lines;
|
||||||
|
|
||||||
SNOR_WRITE_STATUS write_status;
|
SNOR_WRITE_STATUS write_status;
|
||||||
|
u32 max_iosize;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct flash_info {
|
struct flash_info {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue