diff --git a/drivers/rkflash/nandc.c b/drivers/rkflash/nandc.c index c6bdcbc4d7e1..ce7fecaac8c1 100644 --- a/drivers/rkflash/nandc.c +++ b/drivers/rkflash/nandc.c @@ -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; } diff --git a/drivers/rkflash/nandc.h b/drivers/rkflash/nandc.h index 07f04bc6f5c7..8031c79b679b 100644 --- a/drivers/rkflash/nandc.h +++ b/drivers/rkflash/nandc.h @@ -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)]; */