mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 11:50:43 +09:00
drivers: rkflash: support NANDC ver 9
1.RK3326 will apply slc NAND Flash devices. Change-Id: If5865c4934bf399bc79cc51d8924f17602b3be23 Signed-off-by: Dingqiang Lin <jon.lin@rock-chips.com>
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
#define NANDC_MASTER_EN
|
||||
|
||||
void __iomem *nandc_base;
|
||||
static u8 g_nandc_ver;
|
||||
|
||||
static u32 g_nandc_ecc_bits;
|
||||
#ifdef NANDC_MASTER_EN
|
||||
@@ -29,9 +30,21 @@ void nandc_init(void __iomem *nandc_addr)
|
||||
nandc_base = nandc_addr;
|
||||
|
||||
ctl_reg.d32 = 0;
|
||||
ctl_reg.V6.wp = 1;
|
||||
nandc_writel(ctl_reg.d32, NANDC_FMCTL);
|
||||
nandc_writel(0, NANDC_RANDMZ_CFG);
|
||||
g_nandc_ver = 6;
|
||||
if (nandc_readl(NANDC_V9_NANDC_VER) == RK3326_NANDC_VER)
|
||||
g_nandc_ver = 9;
|
||||
if (g_nandc_ver == 9) {
|
||||
ctl_reg.V9.wp = 1;
|
||||
ctl_reg.V9.sif_read_delay = 2;
|
||||
nandc_writel(ctl_reg.d32, NANDC_V9_FMCTL);
|
||||
nandc_writel(0, NANDC_V9_RANDMZ_CFG);
|
||||
nandc_writel(0x1041, NANDC_V9_FMWAIT);
|
||||
} else {
|
||||
ctl_reg.V6.wp = 1;
|
||||
nandc_writel(ctl_reg.d32, NANDC_FMCTL);
|
||||
nandc_writel(0, NANDC_RANDMZ_CFG);
|
||||
nandc_writel(0x1061, NANDC_FMWAIT);
|
||||
}
|
||||
nandc_time_cfg(40);
|
||||
|
||||
#ifdef NANDC_MASTER_EN
|
||||
@@ -95,125 +108,244 @@ void nandc_randmz_sel(u8 chip_sel, u32 randmz_seed)
|
||||
|
||||
void nandc_time_cfg(u32 ns)
|
||||
{
|
||||
if (ns < 36)
|
||||
nandc_writel(0x1061, NANDC_FMWAIT);
|
||||
else if (ns >= 100)
|
||||
nandc_writel(0x2082, NANDC_FMWAIT);
|
||||
else
|
||||
nandc_writel(0x1081, NANDC_FMWAIT);
|
||||
if (g_nandc_ver == 9) {
|
||||
if (ns < 36)
|
||||
nandc_writel(0x1041, NANDC_V9_FMWAIT);
|
||||
else if (ns >= 100)
|
||||
nandc_writel(0x2082, NANDC_V9_FMWAIT);
|
||||
else
|
||||
nandc_writel(0x1061, NANDC_V9_FMWAIT);
|
||||
} else {
|
||||
if (ns < 36)
|
||||
nandc_writel(0x1061, NANDC_FMWAIT);
|
||||
else if (ns >= 100)
|
||||
nandc_writel(0x2082, NANDC_FMWAIT);
|
||||
else
|
||||
nandc_writel(0x1081, NANDC_FMWAIT);
|
||||
}
|
||||
}
|
||||
|
||||
void nandc_bch_sel(u8 bits)
|
||||
{
|
||||
union BCH_CTL_T tmp;
|
||||
union FL_CTL_T fl_reg;
|
||||
u8 bch_config;
|
||||
|
||||
fl_reg.d32 = 0;
|
||||
fl_reg.V6.rst = 1;
|
||||
nandc_writel(fl_reg.d32, NANDC_FLCTL);
|
||||
g_nandc_ecc_bits = bits;
|
||||
tmp.d32 = 0;
|
||||
tmp.V6.addr = 0x10;
|
||||
tmp.V6.bch_mode1 = 0;
|
||||
if (bits == 16) {
|
||||
tmp.V6.bch_mode = 0;
|
||||
} else if (bits == 24) {
|
||||
tmp.V6.bch_mode = 1;
|
||||
if (g_nandc_ver == 9) {
|
||||
nandc_writel(fl_reg.d32, NANDC_V9_FLCTL);
|
||||
if (bits == 70)
|
||||
bch_config = 0;
|
||||
else if (bits == 60)
|
||||
bch_config = 3;
|
||||
else if (bits == 40)
|
||||
bch_config = 2;
|
||||
else
|
||||
bch_config = 1;
|
||||
tmp.d32 = 0;
|
||||
tmp.V9.bchmode = bch_config;
|
||||
tmp.V9.bchrst = 1;
|
||||
nandc_writel(tmp.d32, NANDC_V9_BCHCTL);
|
||||
} else {
|
||||
tmp.V6.bch_mode1 = 1;
|
||||
tmp.V6.bch_mode = 1;
|
||||
if (bits == 40)
|
||||
nandc_writel(fl_reg.d32, NANDC_FLCTL);
|
||||
tmp.d32 = 0;
|
||||
tmp.V6.addr = 0x10;
|
||||
tmp.V6.bch_mode1 = 0;
|
||||
if (bits == 16) {
|
||||
tmp.V6.bch_mode = 0;
|
||||
} else if (bits == 24) {
|
||||
tmp.V6.bch_mode = 1;
|
||||
} else {
|
||||
tmp.V6.bch_mode1 = 1;
|
||||
tmp.V6.bch_mode = 1;
|
||||
if (bits == 40)
|
||||
tmp.V6.bch_mode = 0;
|
||||
}
|
||||
tmp.V6.rst = 1;
|
||||
nandc_writel(tmp.d32, NANDC_BCHCTL);
|
||||
}
|
||||
tmp.V6.rst = 1;
|
||||
nandc_writel(tmp.d32, NANDC_BCHCTL);
|
||||
}
|
||||
|
||||
static void nandc_xfer_start(u8 chip_sel,
|
||||
u8 dir,
|
||||
u8 sector_count,
|
||||
u8 st_buf,
|
||||
u32 *p_data,
|
||||
u32 *p_spare)
|
||||
/*
|
||||
*Nandc xfer data transmission
|
||||
*1. set bch register except nandc version equals 9
|
||||
*2. set internal transfer control register
|
||||
*3. set bus transfer
|
||||
* a. target memory data address
|
||||
* b. ahb setting
|
||||
*4. configure register orderly and start transmission
|
||||
*/
|
||||
static void nandc_xfer_start(u8 dir, u8 n_sec, u32 *data, u32 *spare)
|
||||
{
|
||||
union BCH_CTL_T bch_reg;
|
||||
union FL_CTL_T fl_reg;
|
||||
u32 i;
|
||||
union MTRANS_CFG_T master_reg;
|
||||
u16 *p_spare_tmp = (u16 *)p_spare;
|
||||
u16 *p_spare_tmp = (u16 *)spare;
|
||||
|
||||
fl_reg.d32 = 0;
|
||||
bch_reg.d32 = nandc_readl(NANDC_BCHCTL);
|
||||
bch_reg.V6.addr = 0x10;
|
||||
bch_reg.V6.power_down = 0;
|
||||
bch_reg.V6.region = chip_sel;
|
||||
if (g_nandc_ver == 9) {
|
||||
fl_reg.V9.flash_rdn = dir;
|
||||
fl_reg.V9.bypass = 1;
|
||||
fl_reg.V9.tr_count = 1;
|
||||
fl_reg.V9.async_tog_mix = 1;
|
||||
fl_reg.V9.cor_able = 1;
|
||||
fl_reg.V9.st_addr = 0;
|
||||
fl_reg.V9.page_num = (n_sec + 1) / 2;
|
||||
/* dma start transfer data do care flash rdy */
|
||||
fl_reg.V9.flash_st_mod = 1;
|
||||
|
||||
fl_reg.V6.rdn = dir;
|
||||
fl_reg.V6.dma = 1;
|
||||
fl_reg.V6.tr_count = 1;
|
||||
fl_reg.V6.async_tog_mix = 1;
|
||||
fl_reg.V6.cor_en = 1;
|
||||
fl_reg.V6.st_addr = st_buf / 2;
|
||||
|
||||
master_reg.d32 = nandc_readl(NANDC_MTRANS_CFG);
|
||||
master_reg.V6.bus_mode = 0;
|
||||
#ifdef NANDC_MASTER_EN
|
||||
if (dir != 0) {
|
||||
u32 spare_sz = 64;
|
||||
|
||||
for (i = 0; i < sector_count / 2; i++) {
|
||||
if (p_spare) {
|
||||
master.spare_buf[i * spare_sz / 4] =
|
||||
(p_spare_tmp[0]) | ((u32)p_spare_tmp[1] << 16);
|
||||
p_spare_tmp += 2;
|
||||
} else{
|
||||
master.spare_buf[i * spare_sz / 4] =
|
||||
0xffffffff;
|
||||
if (dir != 0) {
|
||||
for (i = 0; i < n_sec / 2; i++) {
|
||||
if (spare) {
|
||||
master.spare_buf[i] =
|
||||
(p_spare_tmp[0]) |
|
||||
((u32)p_spare_tmp[1] << 16);
|
||||
p_spare_tmp += 2;
|
||||
} else {
|
||||
master.spare_buf[i] = 0xffffffff;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
master.spare_buf[0] = 1;
|
||||
}
|
||||
}
|
||||
fl_reg.V6.page_num = (sector_count + 1) / 2;
|
||||
master.page_vir = (u32 *)((p_data == (u32 *)NULL) ?
|
||||
master.page_buf :
|
||||
(u32 *)p_data);
|
||||
master.spare_vir = (u32 *)master.spare_buf;
|
||||
master.page_phy =
|
||||
(u32)rknandc_dma_map_single((unsigned long)master.page_vir,
|
||||
master.page_vir = (u32 *)((data == (u32 *)NULL) ?
|
||||
master.page_buf :
|
||||
(u32 *)data);
|
||||
master.spare_vir = (u32 *)master.spare_buf;
|
||||
master.page_phy =
|
||||
(u32)rknandc_dma_map_single((unsigned long)master.page_vir,
|
||||
fl_reg.V6.page_num * 1024,
|
||||
dir);
|
||||
master.spare_phy =
|
||||
(u32)rknandc_dma_map_single((unsigned long)master.spare_vir,
|
||||
master.spare_phy =
|
||||
(u32)rknandc_dma_map_single((unsigned long)master.spare_vir,
|
||||
fl_reg.V6.page_num * 64,
|
||||
dir);
|
||||
master.mapped = 1;
|
||||
nandc_writel(master.page_phy, NANDC_MTRANS_SADDR0);
|
||||
nandc_writel(master.spare_phy, NANDC_MTRANS_SADDR1);
|
||||
master_reg.d32 = 0;
|
||||
master_reg.V6.incr_num = 16;
|
||||
master_reg.V6.burst = 7;
|
||||
if ((((unsigned long)p_data) & 0x03) == 0)
|
||||
master_reg.V6.hsize = 2;
|
||||
master_reg.V6.bus_mode = 1;
|
||||
master_reg.V6.ahb_wr = !dir;
|
||||
master_reg.V6.ahb_wr_st = 1;
|
||||
#endif
|
||||
master.mapped = 1;
|
||||
nandc_writel(master.page_phy, NANDC_V9_MTRANS_SADDR0);
|
||||
nandc_writel(master.spare_phy, NANDC_V9_MTRANS_SADDR1);
|
||||
|
||||
nandc_writel(master_reg.d32, NANDC_MTRANS_CFG);
|
||||
nandc_writel(bch_reg.d32, NANDC_BCHCTL);
|
||||
nandc_writel(fl_reg.d32, NANDC_FLCTL);
|
||||
fl_reg.V6.start = 1;
|
||||
nandc_writel(fl_reg.d32, NANDC_FLCTL);
|
||||
master_reg.d32 = nandc_readl(NANDC_V9_MTRANS_CFG);
|
||||
master_reg.V9.incr_num = 16;
|
||||
master_reg.V9.burst = 7;
|
||||
master_reg.V9.hsize = 2;
|
||||
master_reg.V9.bus_mode = 1;
|
||||
master_reg.V9.ahb_wr = !dir;
|
||||
master_reg.V9.ahb_wr_st = 1;
|
||||
master_reg.V9.redundance_size = 0;
|
||||
|
||||
nandc_writel(master_reg.d32, NANDC_V9_MTRANS_CFG);
|
||||
nandc_writel(fl_reg.d32, NANDC_V9_FLCTL);
|
||||
fl_reg.V9.flash_st = 1;
|
||||
nandc_writel(fl_reg.d32, NANDC_V9_FLCTL);
|
||||
} else {
|
||||
bch_reg.d32 = nandc_readl(NANDC_BCHCTL);
|
||||
bch_reg.V6.addr = 0x10;
|
||||
bch_reg.V6.power_down = 0;
|
||||
bch_reg.V6.region = 0;
|
||||
|
||||
fl_reg.V6.rdn = dir;
|
||||
fl_reg.V6.dma = 1;
|
||||
fl_reg.V6.tr_count = 1;
|
||||
fl_reg.V6.async_tog_mix = 1;
|
||||
fl_reg.V6.cor_en = 1;
|
||||
fl_reg.V6.st_addr = 0;
|
||||
|
||||
master_reg.d32 = nandc_readl(NANDC_MTRANS_CFG);
|
||||
master_reg.V6.bus_mode = 0;
|
||||
if (dir != 0) {
|
||||
u32 spare_sz = 64;
|
||||
|
||||
for (i = 0; i < n_sec / 2; i++) {
|
||||
if (spare) {
|
||||
master.spare_buf[i * spare_sz / 4] =
|
||||
(p_spare_tmp[0]) |
|
||||
((u32)p_spare_tmp[1] << 16);
|
||||
p_spare_tmp += 2;
|
||||
} else {
|
||||
master.spare_buf[i * spare_sz / 4] =
|
||||
0xffffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
fl_reg.V6.page_num = (n_sec + 1) / 2;
|
||||
master.page_vir = (u32 *)((data == (u32 *)NULL) ?
|
||||
master.page_buf :
|
||||
(u32 *)data);
|
||||
master.spare_vir = (u32 *)master.spare_buf;
|
||||
master.page_phy =
|
||||
(u32)rknandc_dma_map_single((unsigned long)master.page_vir,
|
||||
fl_reg.V6.page_num * 1024,
|
||||
dir);
|
||||
master.spare_phy =
|
||||
(u32)rknandc_dma_map_single((unsigned long)master.spare_vir,
|
||||
fl_reg.V6.page_num * 64,
|
||||
dir);
|
||||
master.mapped = 1;
|
||||
nandc_writel(master.page_phy, NANDC_MTRANS_SADDR0);
|
||||
nandc_writel(master.spare_phy, NANDC_MTRANS_SADDR1);
|
||||
master_reg.d32 = 0;
|
||||
master_reg.V6.incr_num = 16;
|
||||
master_reg.V6.burst = 7;
|
||||
master_reg.V6.hsize = 2;
|
||||
master_reg.V6.bus_mode = 1;
|
||||
master_reg.V6.ahb_wr = !dir;
|
||||
master_reg.V6.ahb_wr_st = 1;
|
||||
|
||||
nandc_writel(master_reg.d32, NANDC_MTRANS_CFG);
|
||||
nandc_writel(bch_reg.d32, NANDC_BCHCTL);
|
||||
nandc_writel(fl_reg.d32, NANDC_FLCTL);
|
||||
fl_reg.V6.start = 1;
|
||||
nandc_writel(fl_reg.d32, NANDC_FLCTL);
|
||||
}
|
||||
}
|
||||
|
||||
static void nandc_xfer_comp(u8 chip_sel)
|
||||
/*
|
||||
* Wait for the end of data transmission
|
||||
*/
|
||||
static void nandc_xfer_done(void)
|
||||
{
|
||||
union FL_CTL_T fl_reg;
|
||||
union MTRANS_CFG_T master_reg;
|
||||
|
||||
master_reg.d32 = nandc_readl(NANDC_MTRANS_CFG);
|
||||
if (master_reg.V6.bus_mode != 0) {
|
||||
if (g_nandc_ver == 9) {
|
||||
union MTRANS_STAT_T stat_reg;
|
||||
|
||||
master_reg.d32 = nandc_readl(NANDC_V9_MTRANS_CFG);
|
||||
if (master_reg.V9.ahb_wr != 0) {
|
||||
do {
|
||||
fl_reg.d32 = nandc_readl(NANDC_V9_FLCTL);
|
||||
stat_reg.d32 = nandc_readl(NANDC_V9_MTRANS_STAT);
|
||||
} while (stat_reg.V9.mtrans_cnt < fl_reg.V9.page_num ||
|
||||
fl_reg.V9.tr_rdy == 0);
|
||||
if (master.mapped) {
|
||||
rknandc_dma_unmap_single((u64)master.page_phy,
|
||||
fl_reg.V6.page_num * 1024,
|
||||
0);
|
||||
rknandc_dma_unmap_single((u64)master.spare_phy,
|
||||
fl_reg.V6.page_num * 64,
|
||||
0);
|
||||
}
|
||||
} else {
|
||||
do {
|
||||
fl_reg.d32 = nandc_readl(NANDC_V9_FLCTL);
|
||||
} while (fl_reg.V9.tr_rdy == 0);
|
||||
if (master.mapped) {
|
||||
rknandc_dma_unmap_single((u64)master.page_phy,
|
||||
fl_reg.V6.page_num * 1024,
|
||||
1);
|
||||
rknandc_dma_unmap_single((u64)master.spare_phy,
|
||||
fl_reg.V6.page_num * 64,
|
||||
1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
master_reg.d32 = nandc_readl(NANDC_MTRANS_CFG);
|
||||
if (master_reg.V6.bus_mode != 0) {
|
||||
union MTRANS_STAT_T stat_reg;
|
||||
|
||||
if (master_reg.V6.ahb_wr != 0) {
|
||||
do {
|
||||
fl_reg.d32 = nandc_readl(NANDC_FLCTL);
|
||||
@@ -222,12 +354,14 @@ static void nandc_xfer_comp(u8 chip_sel)
|
||||
fl_reg.V6.tr_rdy == 0);
|
||||
|
||||
if (master.mapped) {
|
||||
rknandc_dma_unmap_single((u64)master.page_phy,
|
||||
fl_reg.V6.page_num * 1024,
|
||||
0);
|
||||
rknandc_dma_unmap_single((u64)master.spare_phy,
|
||||
fl_reg.V6.page_num * 64,
|
||||
0);
|
||||
rknandc_dma_unmap_single(
|
||||
(unsigned long)(master.page_phy),
|
||||
fl_reg.V6.page_num * 1024,
|
||||
0);
|
||||
rknandc_dma_unmap_single(
|
||||
(unsigned long)(master.spare_phy),
|
||||
fl_reg.V6.page_num * 64,
|
||||
0);
|
||||
}
|
||||
} else {
|
||||
do {
|
||||
@@ -243,14 +377,15 @@ static void nandc_xfer_comp(u8 chip_sel)
|
||||
}
|
||||
}
|
||||
master.mapped = 0;
|
||||
} else {
|
||||
do {
|
||||
fl_reg.d32 = nandc_readl(NANDC_FLCTL);
|
||||
} while ((fl_reg.V6.tr_rdy == 0));
|
||||
} else {
|
||||
do {
|
||||
fl_reg.d32 = nandc_readl(NANDC_FLCTL);
|
||||
} while ((fl_reg.V6.tr_rdy == 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u32 nandc_xfer_data(u8 chip_sel, u8 dir, u8 sector_count,
|
||||
u32 nandc_xfer_data(u8 chip_sel, u8 dir, u8 n_sec,
|
||||
u32 *p_data, u32 *p_spare)
|
||||
{
|
||||
u32 status = NAND_STS_OK;
|
||||
@@ -262,39 +397,63 @@ u32 nandc_xfer_data(u8 chip_sel, u8 dir, u8 sector_count,
|
||||
p_spare = (u32 *)spare;
|
||||
memset(spare, 0xFF, sizeof(spare));
|
||||
}
|
||||
nandc_xfer_start(chip_sel, dir, sector_count, 0, p_data, p_spare);
|
||||
nandc_xfer_comp(chip_sel);
|
||||
nandc_xfer_start(dir, n_sec, p_data, p_spare);
|
||||
nandc_xfer_done();
|
||||
if (dir == NANDC_READ) {
|
||||
for (i = 0; i < sector_count / 4 ; i++) {
|
||||
bch_st_reg.d32 = nandc_readl(NANDC_BCHST(i));
|
||||
if (bch_st_reg.V6.fail0 || bch_st_reg.V6.fail1) {
|
||||
status = NAND_STS_ECC_ERR;
|
||||
} else {
|
||||
u32 tmp = 0;
|
||||
|
||||
tmp =
|
||||
max(bch_st_reg.V6.err_bits0 |
|
||||
((u32)bch_st_reg.V6.err_bits0_5 << 5),
|
||||
bch_st_reg.V6.err_bits1 |
|
||||
((u32)bch_st_reg.V6.err_bits1_5 << 5));
|
||||
status = max(tmp, status);
|
||||
if (g_nandc_ver == 9) {
|
||||
for (i = 0; i < n_sec / 4; i++) {
|
||||
bch_st_reg.d32 = nandc_readl(NANDC_V9_BCHST(i));
|
||||
if (n_sec > 2) {
|
||||
if (bch_st_reg.V9.fail0 || bch_st_reg.V9.fail1) {
|
||||
status = NAND_STS_ECC_ERR;
|
||||
} else {
|
||||
u32 tmp = max((u32)bch_st_reg.V9.err_bits0,
|
||||
(u32)bch_st_reg.V9.err_bits1);
|
||||
status = max(tmp, status);
|
||||
}
|
||||
} else {
|
||||
if (bch_st_reg.V9.fail0)
|
||||
status = NAND_STS_ECC_ERR;
|
||||
else
|
||||
status = bch_st_reg.V9.err_bits0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (p_spare) {
|
||||
u32 spare_sz = 64;
|
||||
u32 temp_data;
|
||||
u8 *p_spare_temp = (u8 *)p_spare;
|
||||
|
||||
for (i = 0; i < sector_count / 2; i++) {
|
||||
temp_data = master.spare_buf[i * spare_sz / 4];
|
||||
*p_spare_temp++ = (u8)temp_data;
|
||||
*p_spare_temp++ = (u8)(temp_data >> 8);
|
||||
*p_spare_temp++ = (u8)(temp_data >> 16);
|
||||
*p_spare_temp++ = (u8)(temp_data >> 24);
|
||||
if (p_spare) {
|
||||
for (i = 0; i < n_sec / 2; i++)
|
||||
p_spare[i] = master.spare_buf[i];
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < n_sec / 4 ; i++) {
|
||||
bch_st_reg.d32 = nandc_readl(NANDC_BCHST(i));
|
||||
if (bch_st_reg.V6.fail0 || bch_st_reg.V6.fail1) {
|
||||
status = NAND_STS_ECC_ERR;
|
||||
} else {
|
||||
u32 tmp = 0;
|
||||
|
||||
tmp =
|
||||
max(bch_st_reg.V6.err_bits0 |
|
||||
((u32)bch_st_reg.V6.err_bits0_5 << 5),
|
||||
bch_st_reg.V6.err_bits1 |
|
||||
((u32)bch_st_reg.V6.err_bits1_5 << 5));
|
||||
status = max(tmp, status);
|
||||
}
|
||||
}
|
||||
if (p_spare) {
|
||||
u32 spare_sz = 64;
|
||||
u32 temp_data;
|
||||
u8 *p_spare_temp = (u8 *)p_spare;
|
||||
|
||||
for (i = 0; i < n_sec / 2; i++) {
|
||||
temp_data = master.spare_buf[i * spare_sz / 4];
|
||||
*p_spare_temp++ = (u8)temp_data;
|
||||
*p_spare_temp++ = (u8)(temp_data >> 8);
|
||||
*p_spare_temp++ = (u8)(temp_data >> 16);
|
||||
*p_spare_temp++ = (u8)(temp_data >> 24);
|
||||
}
|
||||
}
|
||||
nandc_writel(0, NANDC_MTRANS_CFG);
|
||||
}
|
||||
}
|
||||
nandc_writel(0, NANDC_MTRANS_CFG);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#define NANDC_READ 0
|
||||
#define NANDC_WRITE 1
|
||||
#define RK3326_NANDC_VER 0x56393030
|
||||
|
||||
/* INT ID */
|
||||
enum NANDC_IRQ_NUM_T {
|
||||
@@ -22,6 +23,13 @@ enum NANDC_IRQ_NUM_T {
|
||||
NC_IRQ_LLP
|
||||
};
|
||||
|
||||
enum ENUM_NANDC_BCH_CFG {
|
||||
NC_BCH_70 = 0,
|
||||
NC_BCH_24,
|
||||
NC_BCH_40,
|
||||
NC_BCH_60,
|
||||
};
|
||||
|
||||
union FM_CTL_T {
|
||||
u32 d32;
|
||||
struct {
|
||||
@@ -40,6 +48,21 @@ union FM_CTL_T {
|
||||
unsigned read_delay : 3; /* bits[24:26] */
|
||||
unsigned reserved27_31 : 5; /* bits[27:31] */
|
||||
} V6;
|
||||
struct {
|
||||
unsigned cs : 8;
|
||||
unsigned wp : 1;
|
||||
unsigned frdy : 1;
|
||||
unsigned fifo_empth_flash : 1;
|
||||
unsigned reserved11_12 : 2;
|
||||
unsigned tm : 1;
|
||||
unsigned syn_clken : 1;
|
||||
unsigned syn_mode : 1;
|
||||
unsigned flash_abort_en : 1;
|
||||
unsigned flash_abort_clear : 1;
|
||||
unsigned sif_read_delay : 3;
|
||||
unsigned io_mux : 3;
|
||||
unsigned reserved24_31 : 8;
|
||||
} V9;
|
||||
};
|
||||
|
||||
union FM_WAIT_T {
|
||||
@@ -54,6 +77,17 @@ union FM_WAIT_T {
|
||||
unsigned fmw_dly_en : 1;
|
||||
unsigned reserved31_31 : 1;
|
||||
} V6;
|
||||
struct {
|
||||
unsigned rwcs : 5;
|
||||
unsigned rwpw : 6;
|
||||
unsigned hard_rdy : 1;
|
||||
unsigned csrw : 6;
|
||||
unsigned wait_frdy_dly : 5;
|
||||
unsigned reserved23_23 : 1;
|
||||
unsigned fmw_dly : 6;
|
||||
unsigned fmw_dly_en : 1;
|
||||
unsigned reserved31_31 : 1;
|
||||
} V9;
|
||||
};
|
||||
|
||||
union FL_CTL_T {
|
||||
@@ -80,6 +114,29 @@ union FL_CTL_T {
|
||||
unsigned async_tog_mix : 1;
|
||||
unsigned reserved30_31 : 2;
|
||||
} V6;
|
||||
struct {
|
||||
unsigned flash_rst : 1;
|
||||
unsigned flash_rdn : 1;
|
||||
unsigned flash_st : 1;
|
||||
unsigned bypass : 1;
|
||||
unsigned st_addr : 1;
|
||||
unsigned tr_count : 2;
|
||||
unsigned flash_st_mod : 1;
|
||||
unsigned not_tran_data : 1;
|
||||
unsigned tran_seed : 1;
|
||||
unsigned cor_able : 1;
|
||||
unsigned lba_en : 1;
|
||||
unsigned lba_spare_sel : 1;
|
||||
unsigned reserved13_18 : 6;
|
||||
unsigned bchst_trans : 1;
|
||||
unsigned tr_rdy : 1;
|
||||
unsigned page_size : 1;
|
||||
unsigned page_num : 6;
|
||||
unsigned low_power : 1;
|
||||
unsigned async_tog_mix : 1;
|
||||
unsigned bypass_fifo_mode : 1;
|
||||
unsigned reserved31_31 : 1;
|
||||
} V9;
|
||||
};
|
||||
|
||||
union BCH_CTL_T {
|
||||
@@ -98,6 +155,17 @@ union BCH_CTL_T {
|
||||
unsigned thres : 8;
|
||||
unsigned reserved27_31 : 5;
|
||||
} V6;
|
||||
struct {
|
||||
unsigned bchrst : 1;
|
||||
unsigned wcnt_clear : 1;
|
||||
unsigned reserved2 : 1;
|
||||
unsigned bchepd : 1;
|
||||
unsigned reserved4_15 : 12;
|
||||
unsigned bchpage : 1;
|
||||
unsigned bchthre : 8;
|
||||
unsigned bchmode : 3;
|
||||
unsigned reserved28_31 : 4;
|
||||
} V9;
|
||||
};
|
||||
|
||||
union BCH_ST_T {
|
||||
@@ -121,6 +189,21 @@ union BCH_ST_T {
|
||||
unsigned err_bits_low1_5 : 1;
|
||||
unsigned reserved31_31 : 1;
|
||||
} V6;
|
||||
struct {
|
||||
unsigned errf0 : 1;
|
||||
unsigned done0 : 1;
|
||||
unsigned fail0 : 1;
|
||||
unsigned err_bits0 : 7;
|
||||
unsigned all_f_flag0 : 1;
|
||||
unsigned reserved11_15 : 5;
|
||||
unsigned errf1 : 1;
|
||||
unsigned done1 : 1;
|
||||
unsigned fail1 : 1;
|
||||
unsigned err_bits1 : 7;
|
||||
unsigned all_f_flag1 : 1;
|
||||
unsigned reserved27_30 : 4;
|
||||
unsigned bch_ready_flag: 1;
|
||||
} V9;
|
||||
};
|
||||
|
||||
union MTRANS_CFG_T {
|
||||
@@ -136,6 +219,18 @@ union MTRANS_CFG_T {
|
||||
unsigned ahb_rst : 1;
|
||||
unsigned reserved16_31 : 16;
|
||||
} V6;
|
||||
struct {
|
||||
unsigned ahb_wr_st : 1;
|
||||
unsigned ahb_wr : 1;
|
||||
unsigned bus_mode : 1;
|
||||
unsigned hsize : 3;
|
||||
unsigned burst : 3;
|
||||
unsigned incr_num : 5;
|
||||
unsigned fl_pwd : 1;
|
||||
unsigned ahb_rst : 1;
|
||||
unsigned redundance_size : 11;
|
||||
unsigned reserved27_31 : 5;
|
||||
} V9;
|
||||
};
|
||||
|
||||
union MTRANS_STAT_T {
|
||||
@@ -145,6 +240,11 @@ union MTRANS_STAT_T {
|
||||
unsigned mtrans_cnt : 5;
|
||||
unsigned reserved21_31 : 11;
|
||||
} V6;
|
||||
struct {
|
||||
unsigned bus_err : 16;
|
||||
unsigned mtrans_cnt : 6;
|
||||
unsigned reserved22_31 : 10;
|
||||
} V9;
|
||||
};
|
||||
|
||||
/* NANDC Registers */
|
||||
@@ -180,6 +280,29 @@ union MTRANS_STAT_T {
|
||||
#define NANDC_CHIP_ADDR(id) (0x800 + (id) * 0x100 + 0x4)
|
||||
#define NANDC_CHIP_CMD(id) (0x800 + (id) * 0x100 + 0x8)
|
||||
|
||||
#define NANDC_V9_FMCTL 0x0
|
||||
#define NANDC_V9_FMWAIT 0x4
|
||||
#define NANDC_V9_FLCTL 0x10
|
||||
#define NANDC_V9_BCHCTL 0x20
|
||||
#define NANDC_V9_MTRANS_CFG 0x30
|
||||
#define NANDC_V9_MTRANS_SADDR0 0x34
|
||||
#define NANDC_V9_MTRANS_SADDR1 0x38
|
||||
#define NANDC_V9_MTRANS_STAT 0x40
|
||||
#define NANDC_V9_MTRANS_STAT2 0x44
|
||||
#define NANDC_V9_NANDC_VER 0x80
|
||||
|
||||
#define NANDC_V9_INTEN 0x120
|
||||
#define NANDC_V9_INTCLR 0x124
|
||||
#define NANDC_V9_INTST 0x128
|
||||
#define NANDC_V9_SPARE0 0x200
|
||||
#define NANDC_V9_SPARE1 0x204
|
||||
#define NANDC_V9_RANDMZ_CFG 0x208
|
||||
#define NANDC_V9_BCHST(i) (0x150 + (i) * 4)
|
||||
|
||||
#define NANDC_V9_CHIP_DATA(id) (0x800 + (id) * 0x100)
|
||||
#define NANDC_V9_CHIP_ADDR(id) (0x800 + (id) * 0x100 + 0x4)
|
||||
#define NANDC_V9_CHIP_CMD(id) (0x800 + (id) * 0x100 + 0x8)
|
||||
|
||||
struct MASTER_INFO_T {
|
||||
u32 *page_buf; /* [DATA_LEN]; */
|
||||
u32 *spare_buf; /* [DATA_LEN / (1024/128)]; */
|
||||
|
||||
Reference in New Issue
Block a user