mtd/nand: Add function board_nand_init_tail() for some special NAND controllers
Subsystems (2)
PATCH 1/5 mtd/nand: Add function board_nand_init_tail() for some special NAND controllers
In some NAND controllers there is a size limitation of RAM buffer(2K bytes). To support large-page NAND chips with greater than 2K pagesize, we need a large buffer, but we don't know pagesize before calling nand_scan_ident(), for more flexible and to identify different cases of large-page greater than 2K bytes, we have a board_nand_init_tail() between nand_scan_ident() and nand_scan_tail().
--- drivers/mtd/nand/nand.c | 19 ++++++++++++++++++- 1 files changed, 18 insertions(+), 1 deletions(-)
drivers/mtd/nand/nand.c +18 -1
@@ -39,6 +39,14 @@ static ulong base_address[CONFIG_SYS_MAX_NAND_DEVICE] = CONFIG_SYS_NAND_BASE_LISstatic const char default_nand_name[] ="nand" ;static __attribute__((unused))char dev_name[CONFIG_SYS_MAX_NAND_DEVICE ][8 ]; +int __board_nand_init_tail (struct mtd_info *mtd,struct nand_chip *nand) +{ +/* Allow for init at tail in controller-specific file for some reason */ +return 0 ; +} +int board_nand_init_tail (struct mtd_info *mtd,struct nand_chip *nand) +__attribute__((weak,alias ("__board_nand_init_tail" ))); +static void nand_init_chip (struct mtd_info *mtd,struct nand_chip *nand,ulong base_addr) {
@@ -51,7 +59,16 @@ static void nand_init_chip(struct mtd_info *mtd, struct nand_chip *nand, nand->IO_ADDR_R = nand->IO_ADDR_W = (void __iomem *)base_addr;if (board_nand_init (nand) ==0 ) { -if (nand_scan (mtd, maxchips) ==0 ) { +if (!nand_scan_ident (mtd, maxchips,NULL )) { +if (board_nand_init_tail (mtd, nand)) { + mtd->name =NULL ; +return ; + } + +if (nand_scan_tail (mtd)) { + mtd->name =NULL ; +return ; + }if (!mtd->name) mtd->name = (char *)default_nand_name;#ifdef CONFIG_NEEDS_MANUAL_RELOC
Signature · 1 line
1.6.4
PATCH 2/5 mtd/nand: Fixup for support ONFI detect
In the past the ONFI never worked dut to u-boot aborted when nand device id not found in ids table. Now if not found in ids table, u-boot still continues to detect by ONFI way.
--- drivers/mtd/nand/nand_base.c | 26 ++++++++++++++++---------- 1 files changed, 16 insertions(+), 10 deletions(-)
drivers/mtd/nand/nand_base.c +16 -10
@@ -2592,10 +2592,17 @@ static const struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,if (*dev_id == type->id)break ; +if (!type->name || !type->pagesize) { +/* Check if chip is ONFI compliant */ + ret =nand_flash_detect_onfi (mtd, chip, &busw); +if (ret) + goto ident_done; + } +if (!type->name) {/* supress warning if there is no nand */ if (*maf_id !=0x00 && *maf_id !=0xff && - *dev_id !=0x00 && *dev_id !=0xff ) + *dev_id !=0x00 && *dev_id !=0xff )printk (KERN_INFO "%s: unknown NAND device: " "Manufacturer ID: 0x%02x, Chip ID: 0x%02x\n" , __func__, *maf_id, *dev_id);
@@ -2608,14 +2615,19 @@ static const struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, chip->chipsize = (uint64_t )type->chipsize <<20 ; chip->onfi_version =0 ; - ret =nand_flash_detect_onfi (mtd, chip, &busw); -if (!ret) -nand_flash_detect_non_onfi (mtd, chip, type, &busw); +nand_flash_detect_non_onfi (mtd, chip, type, &busw);/* Get chip options, preserve non chip based options */ chip->options &= ~NAND_CHIPOPTIONS_MSK ; chip->options |= type->options &NAND_CHIPOPTIONS_MSK ; +/* Check if chip is a not a samsung device. Do not clear the +* options for chips which are not having an extended id. +*/ +if (*maf_id !=NAND_MFR_SAMSUNG && !type->pagesize) + chip->options &= ~NAND_SAMSUNG_LP_OPTIONS ; + +ident_done:/* * Set chip as a default. Board drivers can override it, if necessary */
@@ -2657,12 +2669,6 @@ static const struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, chip->badblockpos = mtd->writesize >512 ?NAND_LARGE_BADBLOCK_POS :NAND_SMALL_BADBLOCK_POS ; -/* Check if chip is a not a samsung device. Do not clear the -* options for chips which are not having an extended id. -*/ -if (*maf_id !=NAND_MFR_SAMSUNG && !type->pagesize) - chip->options &= ~NAND_SAMSUNG_LP_OPTIONS ; -/* Check for AND chips with 4 page planes */ if (chip->options &NAND_4PAGE_ARRAY ) chip->erase_cmd = multi_erase_cmd;
Signature · 1 line
1.6.4
PATCH 3/5 mtd/nand: remove CONFIG_SYS_NAND_ONFI_DETECTION to enable ONFI detection
remove CONFIG_SYS_NAND_ONFI_DETECTION to enable ONFI detection.
--- drivers/mtd/nand/nand_base.c | 9 --------- include/linux/mtd/nand.h | 2 -- 2 files changed, 0 insertions(+), 11 deletions(-)
drivers/mtd/nand/nand_base.c +0 -9
@@ -2415,7 +2415,6 @@ static void nand_set_defaults(struct nand_chip *chip, int busw) chip->controller = &chip->hwcontrol; } -#ifdef CONFIG_SYS_NAND_ONFI_DETECTION static u16 onfi_crc16 (u16 crc,u8 const *p,size_t len) {int i;
@@ -2493,14 +2492,6 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd,return 1 ; } -#else -static inline int nand_flash_detect_onfi (struct mtd_info *mtd, -struct nand_chip *chip, -int *busw) -{ -return 0 ; -} -#endif static void nand_flash_detect_non_onfi(struct mtd_info *mtd, struct nand_chip *chip,
include/linux/mtd/nand.h +0 -2
@@ -472,9 +472,7 @@ struct nand_chip {uint8_t cellinfo;int badblockpos;int onfi_version; -#ifdef CONFIG_SYS_NAND_ONFI_DETECTION struct nand_onfi_params onfi_params; -#endif int state;
Signature · 1 line
1.6.4
PATCH 4/5 mtd/nand: Add ONFI support for FSL NAND controller
- fix NAND_CMD_READID command for ONFI detect.
- add NAND_CMD_PARAM command to read the ONFI parameter page.
--- drivers/mtd/nand/fsl_elbc_nand.c | 19 ++++++++++++------- 1 files changed, 12 insertions(+), 7 deletions(-)
drivers/mtd/nand/fsl_elbc_nand.c +12 -7
@@ -340,20 +340,25 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,/* READID must read all 5 possible bytes while CEB is active */ case NAND_CMD_READID : -vdbg ("fsl_elbc_cmdfunc: NAND_CMD_READID.\n" ); +case NAND_CMD_PARAM : +vdbg ("fsl_elbc_cmdfunc: NAND_CMD 0x%x.\n" , command);out_be32 (&lbc->fir, (FIR_OP_CW0 <<FIR_OP0_SHIFT ) | (FIR_OP_UA <<FIR_OP1_SHIFT ) | (FIR_OP_RBW <<FIR_OP2_SHIFT )); -out_be32 (&lbc->fcr,NAND_CMD_READID <<FCR_CMD0_SHIFT ); -/* 5 bytes for manuf, device and exts */ -out_be32 (&lbc->fbcr,5 ); - ctrl->read_bytes =5 ; +out_be32 (&lbc->fcr, command <<FCR_CMD0_SHIFT ); +/* +* although currently it's 8 bytes for READID, we always read +* the maximum 256 bytes(for PARAM) +*/ +out_be32 (&lbc->fbcr,256 ); + ctrl->read_bytes =256 ; ctrl->use_mdr =1 ; - ctrl->mdr =0 ; - + ctrl->mdr = column;set_addr (mtd,0 ,0 ,0 );fsl_elbc_run_command (mtd); +if (mtd->writesize >2048 ) +memcpy_fromio (ctrl->buffer, ctrl->addr,256 );return ;/* ERASE1 stores the block and page address */
Signature · 1 line
1.6.4
PATCH 5/5 mtd/nand: workaround for Freescale FCM to support 4k pagesize Nand chip
Freescale FCM controller has a 2K size limitation of buffer RAM. In order to support the Nand flash chip whose page size is larger than 2K bytes, we read/write 2k data repeatedly by issuing FIR_OP_RB/FIR_OP_WB and save them to a large buffer.
--- drivers/mtd/nand/fsl_elbc_nand.c | 279 +++++++++++++++++++++++++++++++++---- 1 files changed, 248 insertions(+), 31 deletions(-)
drivers/mtd/nand/fsl_elbc_nand.c +248 -31
@@ -64,7 +64,6 @@ struct fsl_elbc_mtd {struct device *dev;int bank;/* Chip select bank number */ u8 __iomem *vbase;/* Chip select base virtual address */ -int page_size;/* NAND page size (0=512, 1=2048) */ unsigned int fmr;/* FCM Flash Mode Register value */ };
@@ -85,6 +84,8 @@ struct fsl_elbc_ctrl {unsigned int mdr;/* UPM/FCM Data Register value */ unsigned int use_mdr;/* Non zero if the MDR is to be set */ unsigned int oob;/* Non zero if operating on OOB data */ +char *buffer;/* just used when pagesize is greater */ +/* than FCM RAM 2K limitation */ };/* These map to the positions used by the FCM hardware ECC generator */
@@ -159,6 +160,44 @@ static struct nand_bbt_descr bbt_mirror_descr = { .pattern = mirror_pattern, }; +static void io_to_buffer (struct mtd_info *mtd,int subpage,int oob) +{ +struct nand_chip *chip = mtd->priv; +struct fsl_elbc_mtd *priv = chip->priv; +struct fsl_elbc_ctrl *ctrl = priv->ctrl; +void *src, *dst; +int len = (oob ?64 :2048 ); + +/* for emulating 4096+ bytes NAND using 2048-byte FCM RAM */ +if (oob) + dst = ctrl->buffer + mtd->writesize + subpage *64 ; +else + dst = ctrl->buffer + subpage *2048 ; + + src = ctrl->addr + (oob ?2048 :0 ); +memcpy_fromio (dst, src, len); +} + +static void buffer_to_io (struct mtd_info *mtd,int subpage,int oob) +{ +struct nand_chip *chip = mtd->priv; +struct fsl_elbc_mtd *priv = chip->priv; +struct fsl_elbc_ctrl *ctrl = priv->ctrl; +void *src, *dst; +int len = (oob ?64 :2048 ); + +if (oob) + src = ctrl->buffer + mtd->writesize + subpage *64 ; +else + src = ctrl->buffer + subpage *2048 ; + + dst = ctrl->addr + (oob ?2048 :0 ); + +memcpy_toio (dst, src, len); +/* See the in_8() in fsl_elbc_write_buf() */ +in_8 (ctrl->addr); +} +/*=================================*/ /*
@@ -175,7 +214,7 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob) ctrl->page = page_addr; -if (priv->page_size) { +if (mtd->writesize >=2048 ) {out_be32 (&lbc->fbar, page_addr >>6 ); out_be32(&lbc->fpar, ((page_addr << FPAR_LP_PI_SHIFT) & FPAR_LP_PI) |
@@ -194,7 +233,7 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob)/* for OOB data point to the second half of the buffer */ if (oob) - ctrl->index += priv->page_size ?2048 :512 ; + ctrl->index += mtd->writesize; vdbg("set_addr: bank=%d, ctrl->addr=0x%p (0x%p), " "index %x, pes %d ps %d\n",
@@ -256,13 +295,14 @@ static int fsl_elbc_run_command(struct mtd_info *mtd)return ctrl->status ==LTESR_CC ?0 : -EIO ; } -static void fsl_elbc_do_read (struct nand_chip *chip,int oob) +static void fsl_elbc_do_read (struct mtd_info *mtd,int oob) { +struct nand_chip *chip = mtd->priv;struct fsl_elbc_mtd *priv = chip->priv;struct fsl_elbc_ctrl *ctrl = priv->ctrl;fsl_lbc_t *lbc = ctrl->regs; -if (priv->page_size) { +if (mtd->writesize >=2048 ) { out_be32(&lbc->fir, (FIR_OP_CW0 << FIR_OP0_SHIFT) | (FIR_OP_CA << FIR_OP1_SHIFT) |
@@ -295,6 +335,7 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,struct fsl_elbc_mtd *priv = chip->priv;struct fsl_elbc_ctrl *ctrl = priv->ctrl;fsl_lbc_t *lbc = ctrl->regs; +int i, nps = mtd->writesize /2048 ; ctrl->use_mdr =0 ;
@@ -319,8 +360,27 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command, ctrl->read_bytes = mtd->writesize + mtd->oobsize; ctrl->index += column; -fsl_elbc_do_read (chip,0 ); +fsl_elbc_do_read (mtd,0 );fsl_elbc_run_command (mtd); + +if (mtd->writesize <=2048 ) +return ; + +/* Continue to read the rest bytes if writesize > 2048 */ +io_to_buffer (mtd,0 ,0 ); +io_to_buffer (mtd,0 ,1 ); +/* +* Maybe there are some reasons of FCM hardware timing, +* we must insert a FIR_OP_NOP(0x00) before FIR_OP_RB. +*/ +out_be32 (&lbc->fir,FIR_OP_RB <<FIR_OP1_SHIFT ); + +for (i =1 ; i < nps; i++) { +fsl_elbc_run_command (mtd); +io_to_buffer (mtd, i,0 ); +io_to_buffer (mtd, i,1 ); + } +return ;/* READOOB reads only the OOB because no ECC is performed. */
@@ -328,14 +388,35 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,vdbg ("fsl_elbc_cmdfunc: NAND_CMD_READOOB, page_addr:" " 0x%x, column: 0x%x.\n" , page_addr, column); -out_be32 (&lbc->fbcr, mtd->oobsize - column); -set_addr (mtd, column, page_addr,1 ); +if (mtd->writesize <=2048 ) { +out_be32 (&lbc->fbcr, mtd->oobsize - column); +set_addr (mtd, column, page_addr,1 ); + }else { +out_be32 (&lbc->fbcr,64 ); +set_addr (mtd,0 , page_addr,1 ); + ctrl->index += column; + } ctrl->read_bytes = mtd->writesize + mtd->oobsize; - -fsl_elbc_do_read (chip,1 ); +fsl_elbc_do_read (mtd,1 );fsl_elbc_run_command (mtd); +if (mtd->writesize <=2048 ) +return ; + +if (column <64 ) +io_to_buffer (mtd,0 ,1 ); + +out_be32 (&lbc->fpar,in_be32 (&lbc->fpar) & ~FPAR_LP_MS ); +out_be32 (&lbc->fir,FIR_OP_RB <<FIR_OP1_SHIFT ); +out_be32 (&lbc->fbcr,2112 ); + +for (i =1 ; i < nps; i++) { +fsl_elbc_run_command (mtd); +if (column < (64 * (i +1 ))) +io_to_buffer (mtd, i,1 ); + } +return ;/* READID must read all 5 possible bytes while CEB is active */
@@ -395,9 +476,28 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command, page_addr, column); ctrl->column = column; - ctrl->oob =0 ; +if (column >= mtd->writesize) { +/* OOB area */ + column -= mtd->writesize; + ctrl->oob =1 ; + }else { + ctrl->oob =0 ; + } -if (priv->page_size) { +if (mtd->writesize >2048 ) { +/* writesize > 2048 */ + fcr = (NAND_CMD_STATUS <<FCR_CMD1_SHIFT ) | + (NAND_CMD_SEQIN <<FCR_CMD2_SHIFT ) | + (NAND_CMD_PAGEPROG <<FCR_CMD3_SHIFT ); +if (ctrl->oob) + fcr |=NAND_CMD_RNDIN <<FCR_CMD0_SHIFT ; + +out_be32 (&lbc->fir, + (FIR_OP_CM2 <<FIR_OP0_SHIFT ) | + (FIR_OP_CA <<FIR_OP1_SHIFT ) | + (FIR_OP_PA <<FIR_OP2_SHIFT ) | + (FIR_OP_WB <<FIR_OP3_SHIFT )); + }else if (mtd->writesize ==2048 ) { fcr = (NAND_CMD_SEQIN <<FCR_CMD0_SHIFT ) | (NAND_CMD_PAGEPROG <<FCR_CMD1_SHIFT );
@@ -419,11 +519,9 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command, (FIR_OP_WB <<FIR_OP4_SHIFT ) | (FIR_OP_CW1 << FIR_OP5_SHIFT)); -if (column >= mtd->writesize) { +if (ctrl->oob) {/* OOB area --> READOOB */ - column -= mtd->writesize; fcr |=NAND_CMD_READOOB <<FCR_CMD0_SHIFT ; - ctrl->oob =1 ; }else if (column <256 ) {/* First 256 bytes --> READ0 */ fcr |=NAND_CMD_READ0 <<FCR_CMD0_SHIFT ;
@@ -434,12 +532,19 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command, }out_be32 (&lbc->fcr, fcr); -set_addr (mtd, column, page_addr, ctrl->oob); +if (column >= mtd->writesize && mtd->writesize >2048 ) { +/* for write oob && writesize > 2048 */ +set_addr (mtd,0 , page_addr,0 ); + ctrl->index = column; + }else { +set_addr (mtd, column, page_addr, ctrl->oob); + }return ; }/* PAGEPROG reuses all of the setup from SEQIN and adds the length */ case NAND_CMD_PAGEPROG : { +int pos;vdbg ("fsl_elbc_cmdfunc: NAND_CMD_PAGEPROG " "writing %d bytes.\n" , ctrl->index);
@@ -447,14 +552,71 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,* then set the exact length, otherwise use a full page * write so the HW generates the ECC. */ +if (ctrl->oob || ctrl->column !=0 || - ctrl->index != mtd->writesize + mtd->oobsize) -out_be32 (&lbc->fbcr, ctrl->index); -else + ctrl->index != mtd->writesize + mtd->oobsize) { +if (ctrl->oob && mtd->writesize >2048 ) { +out_be32 (&lbc->fbcr,64 ); + }else { +out_be32 (&lbc->fbcr, ctrl->index - + ctrl->column); + } + }else {out_be32 (&lbc->fbcr,0 ); + } + +if (mtd->writesize >2048 ) { +if (!ctrl->oob) +buffer_to_io (mtd,0 ,0 ); +buffer_to_io (mtd,0 ,1 ); + }fsl_elbc_run_command (mtd); +if (mtd->writesize <=2048 ) +return ; + +if (ctrl->oob) { + pos =2048 ; +out_be32 (&lbc->fir, + (FIR_OP_CM0 <<FIR_OP0_SHIFT ) | + (FIR_OP_UA <<FIR_OP1_SHIFT ) | + (FIR_OP_UA <<FIR_OP2_SHIFT ) | + (FIR_OP_WB <<FIR_OP3_SHIFT )); + +for (i =1 ; i < nps; i++) { + pos +=2112 ; + ctrl->mdr = pos; + ctrl->use_mdr =1 ; +if (i == nps -1 ) { +out_be32 (&lbc->fir, + (FIR_OP_CM0 <<FIR_OP1_SHIFT ) | + (FIR_OP_UA <<FIR_OP2_SHIFT ) | + (FIR_OP_UA <<FIR_OP3_SHIFT ) | + (FIR_OP_WB <<FIR_OP4_SHIFT ) | + (FIR_OP_CM3 <<FIR_OP5_SHIFT ) | + (FIR_OP_CW1 <<FIR_OP6_SHIFT ) | + (FIR_OP_RS <<FIR_OP7_SHIFT )); + } +buffer_to_io (mtd, i,1 ); +fsl_elbc_run_command (mtd); + } + }else { +out_be32 (&lbc->fir,FIR_OP_WB <<FIR_OP1_SHIFT ); +for (i =1 ; i < nps; i++) { +if (i == nps -1 ) { + ctrl->use_mdr =1 ; +out_be32 (&lbc->fir, + (FIR_OP_WB <<FIR_OP1_SHIFT ) | + (FIR_OP_CM3 <<FIR_OP2_SHIFT ) | + (FIR_OP_CW1 <<FIR_OP3_SHIFT ) | + (FIR_OP_RS <<FIR_OP4_SHIFT )); + } +buffer_to_io (mtd, i,0 ); +buffer_to_io (mtd, i,1 ); +fsl_elbc_run_command (mtd); + } + }return ; }
@@ -475,6 +637,7 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,* write-protected, even when it is not. */ out_8 (ctrl->addr,in_8 (ctrl->addr) |NAND_STATUS_WP ); + ctrl->buffer[0 ] =in_8 (ctrl->addr);return ;/* RESET without waiting for the ready line */
@@ -521,7 +684,11 @@ static void fsl_elbc_write_buf(struct mtd_info *mtd, const u8 *buf, int len) len = bufsize - ctrl->index; } -memcpy_toio (&ctrl->addr[ctrl->index], buf, len); +if (mtd->writesize >2048 ) +memcpy (&ctrl->buffer[ctrl->index], buf, len); +else +memcpy_toio (&ctrl->addr[ctrl->index], buf, len); +/* * This is workaround for the weird elbc hangs during nand write, * Scott Wood says: "...perhaps difference in how long it takes a
@@ -545,8 +712,13 @@ static u8 fsl_elbc_read_byte(struct mtd_info *mtd)struct fsl_elbc_ctrl *ctrl = priv->ctrl;/* If there are still bytes in the FCM, then use the next byte. */ -if (ctrl->index < ctrl->read_bytes) -return in_8 (&ctrl->addr[ctrl->index++]); +if (ctrl->index < ctrl->read_bytes) { +int index = ctrl->index++; +if (mtd->writesize >2048 ) +return ctrl->buffer[index]; +else +return in_8 (&ctrl->addr[index]); + }printf ("read_byte beyond end of buffer\n" );return ERR_BYTE ;
@@ -566,7 +738,10 @@ static void fsl_elbc_read_buf(struct mtd_info *mtd, u8 *buf, int len)return ; avail =min ((unsigned int )len, ctrl->read_bytes - ctrl->index); -memcpy_fromio (buf, &ctrl->addr[ctrl->index], avail); +if (mtd->writesize >2048 ) +memcpy (buf, &ctrl->buffer[ctrl->index], avail); +else +memcpy_fromio (buf, &ctrl->addr[ctrl->index], avail); ctrl->index += avail;if (len > avail)
@@ -600,9 +775,17 @@ static int fsl_elbc_verify_buf(struct mtd_info *mtd,return -EINVAL ; } -for (i =0 ; i < len; i++) -if (in_8 (&ctrl->addr[ctrl->index + i]) != buf[i]) -break ; +if (mtd->writesize >2048 ) { +for (i =0 ; i < len; i++) { +if (ctrl->buffer[ctrl->index + i] != buf[i]) +break ; + } + }else { +for (i =0 ; i < len; i++) { +if (in_8 (&ctrl->addr[ctrl->index + i]) != buf[i]) +break ; + } + } ctrl->index += len;return i == len && ctrl->status ==LTESR_CC ?0 : -EIO ;
@@ -639,6 +822,7 @@ static int fsl_elbc_wait(struct mtd_info *mtd, struct nand_chip *chip)* write-protected, even when it is not. */ out_8 (ctrl->addr,in_8 (ctrl->addr) |NAND_STATUS_WP ); + ctrl->buffer[0 ] =in_8 (ctrl->addr);return fsl_elbc_read_byte (mtd); }
@@ -668,11 +852,11 @@ static void fsl_elbc_write_page(struct mtd_info *mtd,static struct fsl_elbc_ctrl *elbc_ctrl; -static void fsl_elbc_ctrl_init (void ) +static int fsl_elbc_ctrl_init (void ) { elbc_ctrl =kzalloc (sizeof (*elbc_ctrl),GFP_KERNEL );if (!elbc_ctrl) -return ; +return -ENOMEM ; elbc_ctrl->regs =LBC_BASE_ADDR ;
@@ -686,6 +870,22 @@ static void fsl_elbc_ctrl_init(void) elbc_ctrl->read_bytes =0 ; elbc_ctrl->index =0 ; elbc_ctrl->addr =NULL ; + +/* +* Freescale FCM controller has a 2K size limitation of buffer +* RAM, so elbc_fcm_ctrl->buffer have to be used if writesize +* of chip is greater than 2048. +* We kmalloc a 9 KB buffer for now (if there will be 16k pagesize, +* modify it later) at this point, because we don't know writesize +* before calling nand_scan(). We will re-malloc later if needed. +*/ + elbc_ctrl->buffer =kmalloc (1024 *8 +1024 ,GFP_KERNEL ); +if (!elbc_ctrl->buffer) { +printf ("failed to allocate memory for elbc_ctrl->buffer\n" ); +return -ENOMEM ; + } + +return 0 ; }int board_nand_init (struct nand_chip *nand)
@@ -694,8 +894,7 @@ int board_nand_init(struct nand_chip *nand)uint32_t br =0 , or =0 ;if (!elbc_ctrl) { -fsl_elbc_ctrl_init (); -if (!elbc_ctrl) +if (fsl_elbc_ctrl_init ())return -1 ; }
@@ -784,7 +983,6 @@ int board_nand_init(struct nand_chip *nand)/* Large-page-specific setup */ if (or &OR_FCM_PGS ) { - priv->page_size =1 ; nand->badblock_pattern = &largepage_memorybased;/* adjust ecc setup if needed */
@@ -798,3 +996,22 @@ int board_nand_init(struct nand_chip *nand)return 0 ; } + + +int board_nand_init_tail (struct mtd_info *mtd,struct nand_chip *nand) +{ +struct fsl_elbc_mtd *priv = nand->priv; +struct fsl_elbc_ctrl *ctrl = priv->ctrl; + +kfree (ctrl->buffer); + ctrl->buffer =NULL ; + +if (mtd->writesize >2048 ) { + ctrl->buffer =kmalloc (mtd->writesize + mtd->oobsize, +GFP_KERNEL ); +if (!ctrl->buffer) +return -ENOMEM ; + } + +return 0 ; +}
Signature · 1 line
1.6.4
PATCH 5/5 mtd/nand: workaround for Freescale FCM to support 4k pagesize Nand chip
Quoted 25 lines
Freescale FCM controller has a 2K size limitation of buffer RAM. In order to support the Nand flash chip whose page size is larger than 2K bytes, we read/write 2k data repeatedly by issuing FIR_OP_RB/FIR_OP_WB and save them to a large buffer.
Signed-off-by Shengzhou Liu <[email protected]>Signed-off-by Liu Shuo <[email protected]>--- drivers/mtd/nand/fsl_elbc_nand.c | 279+++++++++++++++++++++++++++++++++---- 1 files changed, 248 insertions(+), 31 deletions(-)
(quoted diff) +0
-0
b/drivers/mtd/nand/fsl_elbc_nand.cindex 52362b1..3983c8c 100644drivers/mtd/nand/fsl_elbc_nand.c +0
-1@@ -64,7 +64,6 @@ struct fsl_elbc_mtd {struct device *dev;int bank;/* Chip select bank number */ u8 __iomem *vbase;/* Chip select base virtual address */ -int page_size;/* NAND page size (0=512, 1=2048) */ unsigned int fmr;/* FCM Flash Mode Register value */ };
drivers/mtd/nand/fsl_elbc_nand.c struct fsl_elbc_ctrl { · line 87
Quoted 4 lines
drivers/mtd/nand/fsl_elbc_nand.c +1
-0@@ -85,6 +84,8 @@ struct fsl_elbc_ctrl {unsigned int mdr;/* UPM/FCM Data Register value */ unsigned int use_mdr;/* Non zero if the MDR is to be set */ unsigned int oob;/* Non zero if operating on OOB data */ +char *buffer;/* just used when pagesize is greater */
Start sentence with capital letter
Quoted 5 lines
drivers/mtd/nand/fsl_elbc_nand.c +1
-0+/* than FCM RAM 2K limitation */ };/* These map to the positions used by the FCM hardware ECC generator */
drivers/mtd/nand/fsl_elbc_nand.c static struct nand_bbt_descr bbt_mirror_descr = { · line 169
Quoted 10 lines
drivers/mtd/nand/fsl_elbc_nand.c +7
-0@@ -159,6 +160,44 @@ static struct nand_bbt_descr bbt_mirror_descr = { .pattern = mirror_pattern, }; +static void io_to_buffer (struct mtd_info *mtd,int subpage,int oob) +{ +struct nand_chip *chip = mtd->priv; +struct fsl_elbc_mtd *priv = chip->priv; +struct fsl_elbc_ctrl *ctrl = priv->ctrl; +void *src, *dst; +int len = (oob ?64 :2048 );
No parenthesis ...
drivers/mtd/nand/fsl_elbc_nand.c static struct nand_bbt_descr bbt_mirror_descr = { · line 175
Quoted 6 lines
drivers/mtd/nand/fsl_elbc_nand.c +6
-0+ +/* for emulating 4096+ bytes NAND using 2048-byte FCM RAM */ +if (oob) + dst = ctrl->buffer + mtd->writesize + subpage *64 ; +else + dst = ctrl->buffer + subpage *2048 ;
subpage * len ?
Quoted 7 lines
drivers/mtd/nand/fsl_elbc_nand.c +7
-0+ + src = ctrl->addr + (oob ?2048 :0 ); +memcpy_fromio (dst, src, len); +} + +static void buffer_to_io (struct mtd_info *mtd,int subpage,int oob) +{
drivers/mtd/nand/fsl_elbc_nand.c static struct nand_bbt_descr bbt_mirror_descr = { · line 192
Quoted 10 lines
drivers/mtd/nand/fsl_elbc_nand.c +10
-0+struct nand_chip *chip = mtd->priv; +struct fsl_elbc_mtd *priv = chip->priv; +struct fsl_elbc_ctrl *ctrl = priv->ctrl; +void *src, *dst; +int len = (oob ?64 :2048 ); + +if (oob) + src = ctrl->buffer + mtd->writesize + subpage *64 ; +else + src = ctrl->buffer + subpage *2048 ;
DTTO
M
PATCH 5/5 mtd/nand: workaround for Freescale FCM to support 4k pagesize Nand chip
? 2011?12?09? 00:37, Marek Vasut ??:
Quoted 48 lines
Quoted 25 lines
Freescale FCM controller has a 2K size limitation of buffer RAM. In order to support the Nand flash chip whose page size is larger than 2K bytes, we read/write 2k data repeatedly by issuing FIR_OP_RB/FIR_OP_WB and save them to a large buffer.
Signed-off-by Shengzhou Liu<[email protected]>Signed-off-by Liu Shuo<[email protected]>--- drivers/mtd/nand/fsl_elbc_nand.c | 279+++++++++++++++++++++++++++++++++---- 1 files changed, 248 insertions(+), 31 deletions(-)
(quoted diff) +0
-0
b/drivers/mtd/nand/fsl_elbc_nand.cindex 52362b1..3983c8c 100644drivers/mtd/nand/fsl_elbc_nand.c +0
-1@@ -64,7 +64,6 @@ struct fsl_elbc_mtd {struct device *dev;int bank;/* Chip select bank number */ u8 __iomem *vbase;/* Chip select base virtual address */ -int page_size;/* NAND page size (0=512, 1=2048) */ unsigned int fmr;/* FCM Flash Mode Register value */ };drivers/mtd/nand/fsl_elbc_nand.c struct fsl_elbc_ctrl { · line 87
Quoted 4 lines
drivers/mtd/nand/fsl_elbc_nand.c +1
-0@@ -85,6 +84,8 @@ struct fsl_elbc_ctrl {unsigned int mdr;/* UPM/FCM Data Register value */ unsigned int use_mdr;/* Non zero if the MDR is to be set */ unsigned int oob;/* Non zero if operating on OOB data */ +char *buffer;/* just used when pagesize is greater */ Start sentence with capital letter
Quoted 5 lines
drivers/mtd/nand/fsl_elbc_nand.c +1
-0+/* than FCM RAM 2K limitation */ };/* These map to the positions used by the FCM hardware ECC generator */ drivers/mtd/nand/fsl_elbc_nand.c static struct nand_bbt_descr bbt_mirror_descr = { · line 169
Quoted 10 lines
drivers/mtd/nand/fsl_elbc_nand.c +7
-0@@ -159,6 +160,44 @@ static struct nand_bbt_descr bbt_mirror_descr = { .pattern = mirror_pattern, }; +static void io_to_buffer (struct mtd_info *mtd,int subpage,int oob) +{ +struct nand_chip *chip = mtd->priv; +struct fsl_elbc_mtd *priv = chip->priv; +struct fsl_elbc_ctrl *ctrl = priv->ctrl; +void *src, *dst; +int len = (oob ?64 :2048 );No parenthesis ...
Quoted 7 lines
drivers/mtd/nand/fsl_elbc_nand.c static struct nand_bbt_descr bbt_mirror_descr = { · line 175
Quoted 6 lines
drivers/mtd/nand/fsl_elbc_nand.c +6
-0+ +/* for emulating 4096+ bytes NAND using 2048-byte FCM RAM */ +if (oob) + dst = ctrl->buffer + mtd->writesize + subpage *64 ; +else + dst = ctrl->buffer + subpage *2048 ;subpage * len ?
dst = ctrl->buffer + (oob ? mtd->writesize : 0) + subpage * len ? Is this important ? I think it is ok.
-LiuShuo
Quoted 22 lines
Quoted 8 lines
drivers/mtd/nand/fsl_elbc_nand.c +7
-0+ + src = ctrl->addr + (oob ?2048 :0 ); +memcpy_fromio (dst, src, len); +} + +static void buffer_to_io (struct mtd_info *mtd,int subpage,int oob) +{drivers/mtd/nand/fsl_elbc_nand.c static struct nand_bbt_descr bbt_mirror_descr = { · line 192
Quoted 10 lines
drivers/mtd/nand/fsl_elbc_nand.c +10
-0+struct nand_chip *chip = mtd->priv; +struct fsl_elbc_mtd *priv = chip->priv; +struct fsl_elbc_ctrl *ctrl = priv->ctrl; +void *src, *dst; +int len = (oob ?64 :2048 ); + +if (oob) + src = ctrl->buffer + mtd->writesize + subpage *64 ; +else + src = ctrl->buffer + subpage *2048 ;DTTO
M
PATCH 5/5 mtd/nand: workaround for Freescale FCM to support 4k pagesize Nand chip
Quoted 73 lines
? 2011?12?09? 00:37, Marek Vasut ??:
Quoted 63 lines
Quoted 31 lines
Freescale FCM controller has a 2K size limitation of buffer RAM. In order to support the Nand flash chip whose page size is larger than 2K bytes, we read/write 2k data repeatedly by issuing FIR_OP_RB/FIR_OP_WB and save them to a large buffer.
Signed-off-by Shengzhou Liu<[email protected]>Signed-off-by Liu Shuo<[email protected]>---
drivers/mtd/nand/fsl_elbc_nand.c | 279+++++++++++++++++++++++++++++++++---- 1 files changed, 248 insertions(+), 31 deletions(-)
(quoted diff) +0
-0
b/drivers/mtd/nand/fsl_elbc_nand.cindex 52362b1..3983c8c 100644drivers/mtd/nand/fsl_elbc_nand.c +0
-1@@ -64,7 +64,6 @@ struct fsl_elbc_mtd {struct device *dev;int bank;/* Chip select bank number */ u8 __iomem *vbase;/* Chip select base virtual address */ -int page_size;/* NAND page size (0=512, 1=2048) */ unsigned int fmr; /* FCM Flash Mode Register value */
};drivers/mtd/nand/fsl_elbc_nand.c struct fsl_elbc_ctrl { · line 89
Quoted 6 lines
drivers/mtd/nand/fsl_elbc_nand.c +1
-0@@ -85,6 +84,8 @@ struct fsl_elbc_ctrl {unsigned int mdr;/* UPM/FCM Data Register value */ unsigned int use_mdr;/* Non zero if the MDR is to be set */ unsigned int oob;/* Non zero if operating on OOB data */ +char *buffer;/* just used when pagesize is greater */ Start sentence with capital letter
Quoted 10 lines
drivers/mtd/nand/fsl_elbc_nand.c +1
-0+/* than FCM RAM 2K limitation */ };/* These map to the positions used by the FCM hardware ECC generator */
drivers/mtd/nand/fsl_elbc_nand.c +0
-0@@ -159,6 +160,44 @@ static struct nand_bbt_descr bbt_mirror_descr = { .pattern = mirror_pattern,drivers/mtd/nand/fsl_elbc_nand.c static struct nand_bbt_descr bbt_mirror_descr = { · line 171
Quoted 10 lines
drivers/mtd/nand/fsl_elbc_nand.c +7
-0}; +static void io_to_buffer (struct mtd_info *mtd,int subpage,int oob) +{ +struct nand_chip *chip = mtd->priv; +struct fsl_elbc_mtd *priv = chip->priv; +struct fsl_elbc_ctrl *ctrl = priv->ctrl; +void *src, *dst; +int len = (oob ?64 :2048 );No parenthesis ...
Quoted 8 lines
drivers/mtd/nand/fsl_elbc_nand.c static struct nand_bbt_descr bbt_mirror_descr = { · line 175
Quoted 6 lines
drivers/mtd/nand/fsl_elbc_nand.c +6
-0+ +/* for emulating 4096+ bytes NAND using 2048-byte FCM RAM */ +if (oob) + dst = ctrl->buffer + mtd->writesize + subpage *64 ; +else + dst = ctrl->buffer + subpage *2048 ;subpage * len ?
Quoted 2 lines
dst =
ctrl->buffer+ (oob ?mtd->writesize: 0) + subpage * len ? Is this important ? I think it is ok.
dst = ctrl->buffer + subpage * len;
if (oob)
dst += mtd->writesize;
it's important, this code looks like mess. You introduce len and don't use it anywhere then ?
M
PATCH 5/5 mtd/nand: workaround for Freescale FCM to support 4k pagesize Nand chip
? 2011?12?09? 16:27, Marek Vasut ??:
Quoted 71 lines
Quoted 69 lines
? 2011?12?09? 00:37, Marek Vasut ??:
Quoted 61 lines
Quoted 31 lines
Freescale FCM controller has a 2K size limitation of buffer RAM. In order to support the Nand flash chip whose page size is larger than 2K bytes, we read/write 2k data repeatedly by issuing FIR_OP_RB/FIR_OP_WB and save them to a large buffer.
Signed-off-by Shengzhou Liu<[email protected]>Signed-off-by Liu Shuo<[email protected]>---
drivers/mtd/nand/fsl_elbc_nand.c | 279+++++++++++++++++++++++++++++++++---- 1 files changed, 248 insertions(+), 31 deletions(-)
(quoted diff) +0
-0
b/drivers/mtd/nand/fsl_elbc_nand.cindex 52362b1..3983c8c 100644drivers/mtd/nand/fsl_elbc_nand.c +0
-1@@ -64,7 +64,6 @@ struct fsl_elbc_mtd {struct device *dev;int bank;/* Chip select bank number */ u8 __iomem *vbase;/* Chip select base virtual address */ -int page_size;/* NAND page size (0=512, 1=2048) */ unsigned int fmr; /* FCM Flash Mode Register value */
};drivers/mtd/nand/fsl_elbc_nand.c struct fsl_elbc_ctrl { · line 89
Quoted 6 lines
drivers/mtd/nand/fsl_elbc_nand.c +1
-0@@ -85,6 +84,8 @@ struct fsl_elbc_ctrl {unsigned int mdr;/* UPM/FCM Data Register value */ unsigned int use_mdr;/* Non zero if the MDR is to be set */ unsigned int oob;/* Non zero if operating on OOB data */ +char *buffer;/* just used when pagesize is greater */ Start sentence with capital letter
Quoted 10 lines
drivers/mtd/nand/fsl_elbc_nand.c +1
-0+/* than FCM RAM 2K limitation */ };/* These map to the positions used by the FCM hardware ECC generator */drivers/mtd/nand/fsl_elbc_nand.c +0
-0@@ -159,6 +160,44 @@ static struct nand_bbt_descr bbt_mirror_descr = { .pattern = mirror_pattern,drivers/mtd/nand/fsl_elbc_nand.c static struct nand_bbt_descr bbt_mirror_descr = { · line 171
Quoted 10 lines
drivers/mtd/nand/fsl_elbc_nand.c +7
-0}; +static void io_to_buffer (struct mtd_info *mtd,int subpage,int oob) +{ +struct nand_chip *chip = mtd->priv; +struct fsl_elbc_mtd *priv = chip->priv; +struct fsl_elbc_ctrl *ctrl = priv->ctrl; +void *src, *dst; +int len = (oob ?64 :2048 );No parenthesis ...
Quoted 7 lines
drivers/mtd/nand/fsl_elbc_nand.c static struct nand_bbt_descr bbt_mirror_descr = { · line 175
Quoted 6 lines
drivers/mtd/nand/fsl_elbc_nand.c +6
-0+ +/* for emulating 4096+ bytes NAND using 2048-byte FCM RAM */ +if (oob) + dst = ctrl->buffer + mtd->writesize + subpage *64 ; +else + dst = ctrl->buffer + subpage *2048 ;subpage * len ?
Quoted 2 lines
dst =
ctrl->buffer+ (oob ?mtd->writesize: 0) + subpage * len ? Is this important ? I think it is ok.
Quoted 7 lines
dst =
ctrl->buffer+ subpage * len;if (oob)
dst += mtd->writesize;it's important, this code looks like mess. You introduce len and don't use it anywhere then ?
memcpy_fromio(dst, src, len);
-Liu Shuo
Quoted 2 lines
M
PATCH 5/5 mtd/nand: workaround for Freescale FCM to support 4k pagesize Nand chip
Quoted 32 lines
? 2011?12?09? 16:27, Marek Vasut ??:
Quoted 31 lines
Quoted 31 lines
? 2011?12?09? 00:37, Marek Vasut ??:
Quoted 30 lines
Quoted 30 lines
Freescale FCM controller has a 2K size limitation of buffer RAM. In order to support the Nand flash chip whose page size is larger than 2K bytes, we read/write 2k data repeatedly by issuing FIR_OP_RB/FIR_OP_WB and save them to a large buffer.
Signed-off-by Shengzhou Liu<[email protected]>Signed-off-by Liu Shuo<[email protected]>---
drivers/mtd/nand/fsl_elbc_nand.c | 279+++++++++++++++++++++++++++++++++---- 1 files changed, 248 insertions(+), 31 deletions(-)
(quoted diff) +0
-0
b/drivers/mtd/nand/fsl_elbc_nand.cindex 52362b1..3983c8c 100644drivers/mtd/nand/fsl_elbc_nand.c +0
-1@@ -64,7 +64,6 @@ struct fsl_elbc_mtd {struct device *dev;int bank;/* Chip select bank number */ u8 __iomem *vbase;/* Chip select base virtual address */ -int page_size;/* NAND page size (0=512, 1=2048) */ unsigned int fmr; /* FCM Flash Mode Register value */
};
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/mtd/nand/fsl_elbc_nand.c struct fsl_elbc_ctrl { · line 90
Quoted 8 lines
drivers/mtd/nand/fsl_elbc_nand.c +1
-0@@ -85,6 +84,8 @@ struct fsl_elbc_ctrl {unsigned int mdr;/* UPM/FCM Data Register value */ unsigned int use_mdr;/* Non zero if the MDR is to be set */ unsigned int oob;/* Non zero if operating on OOB data */ +char *buffer;/* just used when pagesize is greater
*/
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Start sentence with capital letter
drivers/mtd/nand/fsl_elbc_nand.c struct fsl_elbc_ctrl { · line 91
Quoted 1 line
drivers/mtd/nand/fsl_elbc_nand.c +1
-0+/* than FCM RAM 2K limitation
*/
Quoted 36 lines
Quoted 36 lines
Quoted 31 lines
Quoted 22 lines
Quoted 9 lines
};/* These map to the positions used by the FCM hardware ECC generator */drivers/mtd/nand/fsl_elbc_nand.c +0
-0@@ -159,6 +160,44 @@ static struct nand_bbt_descr bbt_mirror_descr = { .pattern = mirror_pattern,drivers/mtd/nand/fsl_elbc_nand.c static struct nand_bbt_descr bbt_mirror_descr = { · line 171
Quoted 10 lines
drivers/mtd/nand/fsl_elbc_nand.c +7
-0}; +static void io_to_buffer (struct mtd_info *mtd,int subpage,int oob) +{ +struct nand_chip *chip = mtd->priv; +struct fsl_elbc_mtd *priv = chip->priv; +struct fsl_elbc_ctrl *ctrl = priv->ctrl; +void *src, *dst; +int len = (oob ?64 :2048 );No parenthesis ...
Quoted 8 lines
drivers/mtd/nand/fsl_elbc_nand.c static struct nand_bbt_descr bbt_mirror_descr = { · line 175
Quoted 6 lines
drivers/mtd/nand/fsl_elbc_nand.c +6
-0+ +/* for emulating 4096+ bytes NAND using 2048-byte FCM RAM */ +if (oob) + dst = ctrl->buffer + mtd->writesize + subpage *64 ; +else + dst = ctrl->buffer + subpage *2048 ;subpage * len ?
Quoted 2 lines
dst =
ctrl->buffer+ (oob ?mtd->writesize: 0) + subpage * len ? Is this important ? I think it is ok.dst =
ctrl->buffer+ subpage * len;
Quoted 8 lines
Quoted 6 lines
if (oob)
dst += mtd->writesize;it's important, this code looks like mess. You introduce len and don't use it anywhere then ?
memcpy_fromio(dst, src, len);
Ok, why not use it consistently then.
M
PATCH 5/5 mtd/nand: workaround for Freescale FCM to support 4k pagesize Nand chip
? 2011?12?09? 17:11, Marek Vasut ??:
Quoted 76 lines
Quoted 32 lines
? 2011?12?09? 16:27, Marek Vasut ??:
Quoted 31 lines
Quoted 31 lines
? 2011?12?09? 00:37, Marek Vasut ??:
Quoted 30 lines
Quoted 30 lines
Freescale FCM controller has a 2K size limitation of buffer RAM. In order to support the Nand flash chip whose page size is larger than 2K bytes, we read/write 2k data repeatedly by issuing FIR_OP_RB/FIR_OP_WB and save them to a large buffer.
Signed-off-by Shengzhou Liu<[email protected]>Signed-off-by Liu Shuo<[email protected]>---
drivers/mtd/nand/fsl_elbc_nand.c | 279+++++++++++++++++++++++++++++++++---- 1 files changed, 248 insertions(+), 31 deletions(-)
(quoted diff) +0
-0
b/drivers/mtd/nand/fsl_elbc_nand.cindex 52362b1..3983c8c 100644drivers/mtd/nand/fsl_elbc_nand.c +0
-1@@ -64,7 +64,6 @@ struct fsl_elbc_mtd {struct device *dev;int bank;/* Chip select bank number */ u8 __iomem *vbase;/* Chip select base virtual address */ -int page_size;/* NAND page size (0=512, 1=2048) */ unsigned int fmr; /* FCM Flash Mode Register value */
};
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/mtd/nand/fsl_elbc_nand.c struct fsl_elbc_ctrl { · line 90
Quoted 8 lines
drivers/mtd/nand/fsl_elbc_nand.c +1
-0@@ -85,6 +84,8 @@ struct fsl_elbc_ctrl {unsigned int mdr;/* UPM/FCM Data Register value */ unsigned int use_mdr;/* Non zero if the MDR is to be set */ unsigned int oob;/* Non zero if operating on OOB data */ +char *buffer;/* just used when pagesize is greater */
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Start sentence with capital letter
drivers/mtd/nand/fsl_elbc_nand.c struct fsl_elbc_ctrl { · line 91
Quoted 1 line
drivers/mtd/nand/fsl_elbc_nand.c +1
-0+/* than FCM RAM 2K limitation */
Quoted 31 lines
Quoted 31 lines
Quoted 27 lines
Quoted 20 lines
Quoted 8 lines
}; /* These map to the positions used by the FCM hardware ECC generator */drivers/mtd/nand/fsl_elbc_nand.c +0
-0@@ -159,6 +160,44 @@ static struct nand_bbt_descr bbt_mirror_descr = { .pattern = mirror_pattern,drivers/mtd/nand/fsl_elbc_nand.c static struct nand_bbt_descr bbt_mirror_descr = { · line 171
Quoted 10 lines
drivers/mtd/nand/fsl_elbc_nand.c +7
-0}; +static void io_to_buffer (struct mtd_info *mtd,int subpage,int oob) +{ +struct nand_chip *chip = mtd->priv; +struct fsl_elbc_mtd *priv = chip->priv; +struct fsl_elbc_ctrl *ctrl = priv->ctrl; +void *src, *dst; +int len = (oob ?64 :2048 );No parenthesis ...
Quoted 7 lines
drivers/mtd/nand/fsl_elbc_nand.c static struct nand_bbt_descr bbt_mirror_descr = { · line 175
Quoted 6 lines
drivers/mtd/nand/fsl_elbc_nand.c +6
-0+ +/* for emulating 4096+ bytes NAND using 2048-byte FCM RAM */ +if (oob) + dst = ctrl->buffer + mtd->writesize + subpage *64 ; +else + dst = ctrl->buffer + subpage *2048 ;subpage * len ?
Quoted 2 lines
dst =
ctrl->buffer+ (oob ?mtd->writesize: 0) + subpage * len ? Is this important ? I think it is ok.dst =
ctrl->buffer+ subpage * len;
Quoted 8 lines
Quoted 7 lines
Quoted 6 lines
if (oob)
dst += mtd->writesize;it's important, this code looks like mess. You introduce len and don't use it anywhere then ?
memcpy_fromio(dst, src, len);Ok, why not use it consistently then.
I think it is pellucid. I still don't think it is very important.
- LiuShuo
Quoted 2 lines
M
PATCH 5/5 mtd/nand: workaround for Freescale FCM to support 4k pagesize Nand chip
Quoted 92 lines
? 2011?12?09? 17:11, Marek Vasut ??:
Quoted 91 lines
Quoted 34 lines
? 2011?12?09? 16:27, Marek Vasut ??:
Quoted 33 lines
Quoted 33 lines
? 2011?12?09? 00:37, Marek Vasut ??:
Quoted 32 lines
Quoted 32 lines
Freescale FCM controller has a 2K size limitation of buffer RAM. In order to support the Nand flash chip whose page size is larger than 2K bytes, we read/write 2k data repeatedly by issuing FIR_OP_RB/FIR_OP_WB and save them to a large buffer.
Signed-off-by Shengzhou Liu<[email protected]>Signed-off-by Liu Shuo<[email protected]>---
drivers/mtd/nand/fsl_elbc_nand.c | 279+++++++++++++++++++++++++++++++++---- 1 files changed, 248 insertions(+), 31 deletions(-)
(quoted diff) +0
-0
b/drivers/mtd/nand/fsl_elbc_nand.cindex 52362b1..3983c8c 100644drivers/mtd/nand/fsl_elbc_nand.c +0
-1@@ -64,7 +64,6 @@ struct fsl_elbc_mtd {struct device *dev;int bank;/* Chip select bank number */ u8 __iomem *vbase;/* Chip select base virtual address */ -int page_size;/* NAND page size (0=512, 1=2048) */ unsigned int fmr; /* FCM Flash Mode Register value */
};
drivers/mtd/nand/fsl_elbc_nand.c +0
-0@@ -85,6 +84,8 @@ struct fsl_elbc_ctrl {Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/mtd/nand/fsl_elbc_nand.c struct fsl_elbc_ctrl {
Quoted 8 lines
drivers/mtd/nand/fsl_elbc_nand.c +1
-0unsigned int mdr;/* UPM/FCM Data Register value */ unsigned int use_mdr;/* Non zero if the MDR is to be set */ unsigned int oob;/* Non zero if operating on OOB data */ +char *buffer;/* just used when pagesize is greater */
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Start sentence with capital letter
drivers/mtd/nand/fsl_elbc_nand.c
Quoted 1 line
drivers/mtd/nand/fsl_elbc_nand.c +1
-0+/* than FCM RAM 2K limitation */
Quoted 40 lines
Quoted 40 lines
Quoted 31 lines
Quoted 22 lines
Quoted 14 lines
}; /* These map to the positions used by the FCM hardware ECC generator */drivers/mtd/nand/fsl_elbc_nand.c +1
-0@@ -159,6 +160,44 @@ static struct nand_bbt_descr bbt_mirror_descr = { .pattern = mirror_pattern, }; +static void io_to_buffer(struct mtd_info *mtd, int subpage, intoob) +{
drivers/mtd/nand/fsl_elbc_nand.c
Quoted 5 lines
drivers/mtd/nand/fsl_elbc_nand.c +5
-0+struct nand_chip *chip = mtd->priv; +struct fsl_elbc_mtd *priv = chip->priv; +struct fsl_elbc_ctrl *ctrl = priv->ctrl; +void *src, *dst; +int len = (oob ?64 :2048 );No parenthesis ...
Quoted 8 lines
drivers/mtd/nand/fsl_elbc_nand.c
Quoted 6 lines
drivers/mtd/nand/fsl_elbc_nand.c +6
-0+ +/* for emulating 4096+ bytes NAND using 2048-byte FCM RAM */ +if (oob) + dst = ctrl->buffer + mtd->writesize + subpage *64 ; +else + dst = ctrl->buffer + subpage *2048 ;subpage * len ?
Quoted 2 lines
dst =
ctrl->buffer+ (oob ?mtd->writesize: 0) + subpage * len ? Is this important ? I think it is ok.dst =
ctrl->buffer+ subpage * len;if (oob)
dst += mtd->writesize;
Quoted 8 lines
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines
it's important, this code looks like mess. You introduce len and don't use it anywhere then ?
memcpy_fromio(dst, src, len);Ok, why not use it consistently then.
I think it is pellucid. I still don't think it is very important.
Ok, enough of this stuff, apparently I'm loosing time here. Let's see what others think.
M
PATCH 4/5 mtd/nand: Add ONFI support for FSL NAND controller
In reply to Shengzhou LiuQuoted 32 lines · Shengzhou Liu
- fix
NAND_CMD_READIDcommand for ONFI detect.
- addNAND_CMD_PARAMcommand to read the ONFI parameter page.Signed-off-by Shengzhou Liu <[email protected]>--- drivers/mtd/nand/fsl_elbc_nand.c | 19 ++++++++++++------- 1 files changed, 12 insertions(+), 7 deletions(-)drivers/mtd/nand/fsl_elbc_nand.c +7
-5@@ -340,20 +340,25 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,/* READID must read all 5 possible bytes while CEB is active */ case NAND_CMD_READID : -vdbg ("fsl_elbc_cmdfunc: NAND_CMD_READID.\n" ); +case NAND_CMD_PARAM : +vdbg ("fsl_elbc_cmdfunc: NAND_CMD 0x%x.\n" , command);out_be32 (&lbc->fir, (FIR_OP_CW0 <<FIR_OP0_SHIFT ) | (FIR_OP_UA <<FIR_OP1_SHIFT ) | (FIR_OP_RBW <<FIR_OP2_SHIFT )); -out_be32 (&lbc->fcr,NAND_CMD_READID <<FCR_CMD0_SHIFT ); -/* 5 bytes for manuf, device and exts */ -out_be32 (&lbc->fbcr,5 ); - ctrl->read_bytes =5 ; +out_be32 (&lbc->fcr, command <<FCR_CMD0_SHIFT ); +/* +* although currently it's 8 bytes for READID, we always read +* the maximum 256 bytes(for PARAM) +*/
drivers/mtd/nand/fsl_elbc_nand.c static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command, · line 361
Quoted 10 lines
drivers/mtd/nand/fsl_elbc_nand.c +5
-2+out_be32 (&lbc->fbcr,256 ); + ctrl->read_bytes =256 ; ctrl->use_mdr =1 ; - ctrl->mdr =0 ; - + ctrl->mdr = column;set_addr (mtd,0 ,0 ,0 );fsl_elbc_run_command (mtd); +if (mtd->writesize >2048 ) +memcpy_fromio (ctrl->buffer, ctrl->addr,256 );
This memcpy_fromio looks like leakage from patch 5/5.
-Scott
PATCH 1/5 mtd/nand: Add function board_nand_init_tail() for some special NAND controllers
In reply to Shengzhou LiuQuoted 17 lines
In some NAND controllers there is a size limitation of RAM buffer(2K bytes). To support large-page NAND chips with greater than 2K pagesize, we need a large buffer, but we don't know pagesize before calling
nand_scan_ident(), for more flexible and to identify different cases of large-page greater than 2K bytes, we have aboard_nand_init_tail()betweennand_scan_ident()andnand_scan_tail().Signed-off-by Shengzhou Liu <[email protected]>--- drivers/mtd/nand/nand.c | 19 ++++++++++++++++++- 1 files changed, 18 insertions(+), 1 deletions(-)drivers/mtd/nand/nand.c +0
-0
drivers/mtd/nand/nand.c static ulong base_address[CONFIG_SYS_MAX_NAND_DEVICE] = · line 44
Quoted 6 lines
drivers/mtd/nand/nand.c +2
-0@@ -39,6 +39,14 @@ static ulong base_address[CONFIG_SYS_MAX_NAND_DEVICE] = CONFIG_SYS_NAND_BASE_LIS static const char default_nand_name[] = "nand";static __attribute__((unused))char dev_name[CONFIG_SYS_MAX_NAND_DEVICE ][8 ]; +int __board_nand_init_tail (struct mtd_info *mtd,struct nand_chip *nand) +{
Isn't struct nand_chip * already passed in mtd->priv ?
M
Quoted 28 lines
drivers/mtd/nand/nand.c +6
-0+/* Allow for init at tail in controller-specific file for some reason */ +return 0 ; +} +int board_nand_init_tail (struct mtd_info *mtd,struct nand_chip *nand) +__attribute__((weak,alias ("__board_nand_init_tail" ))); +static void nand_init_chip (struct mtd_info *mtd,struct nand_chip *nand,ulong base_addr){
drivers/mtd/nand/nand.c +10
-1@@ -51,7 +59,16 @@ static void nand_init_chip(struct mtd_info *mtd, struct nand_chip *nand, nand->IO_ADDR_R = nand->IO_ADDR_W = (void __iomem *)base_addr;if (board_nand_init (nand) ==0 ) { -if (nand_scan (mtd, maxchips) ==0 ) { +if (!nand_scan_ident (mtd, maxchips,NULL )) { +if (board_nand_init_tail (mtd, nand)) { + mtd->name =NULL ; +return ; + } + +if (nand_scan_tail (mtd)) { + mtd->name =NULL ; +return ; + }if (!mtd->name) mtd->name = (char *)default_nand_name;#ifdef
CONFIG_NEEDS_MANUAL_RELOC