193db446aSBoris Brezillon /* Freescale Enhanced Local Bus Controller NAND driver 293db446aSBoris Brezillon * 393db446aSBoris Brezillon * Copyright © 2006-2007, 2010 Freescale Semiconductor 493db446aSBoris Brezillon * 593db446aSBoris Brezillon * Authors: Nick Spence <nick.spence@freescale.com>, 693db446aSBoris Brezillon * Scott Wood <scottwood@freescale.com> 793db446aSBoris Brezillon * Jack Lan <jack.lan@freescale.com> 893db446aSBoris Brezillon * Roy Zang <tie-fei.zang@freescale.com> 993db446aSBoris Brezillon * 1093db446aSBoris Brezillon * This program is free software; you can redistribute it and/or modify 1193db446aSBoris Brezillon * it under the terms of the GNU General Public License as published by 1293db446aSBoris Brezillon * the Free Software Foundation; either version 2 of the License, or 1393db446aSBoris Brezillon * (at your option) any later version. 1493db446aSBoris Brezillon * 1593db446aSBoris Brezillon * This program is distributed in the hope that it will be useful, 1693db446aSBoris Brezillon * but WITHOUT ANY WARRANTY; without even the implied warranty of 1793db446aSBoris Brezillon * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1893db446aSBoris Brezillon * GNU General Public License for more details. 1993db446aSBoris Brezillon * 2093db446aSBoris Brezillon * You should have received a copy of the GNU General Public License 2193db446aSBoris Brezillon * along with this program; if not, write to the Free Software 2293db446aSBoris Brezillon * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 2393db446aSBoris Brezillon */ 2493db446aSBoris Brezillon 2593db446aSBoris Brezillon #include <linux/module.h> 2693db446aSBoris Brezillon #include <linux/types.h> 2793db446aSBoris Brezillon #include <linux/kernel.h> 2893db446aSBoris Brezillon #include <linux/string.h> 2993db446aSBoris Brezillon #include <linux/ioport.h> 3093db446aSBoris Brezillon #include <linux/of_address.h> 3193db446aSBoris Brezillon #include <linux/of_platform.h> 3293db446aSBoris Brezillon #include <linux/platform_device.h> 3393db446aSBoris Brezillon #include <linux/slab.h> 3493db446aSBoris Brezillon #include <linux/interrupt.h> 3593db446aSBoris Brezillon 3693db446aSBoris Brezillon #include <linux/mtd/mtd.h> 3793db446aSBoris Brezillon #include <linux/mtd/rawnand.h> 3893db446aSBoris Brezillon #include <linux/mtd/nand_ecc.h> 3993db446aSBoris Brezillon #include <linux/mtd/partitions.h> 4093db446aSBoris Brezillon 4193db446aSBoris Brezillon #include <asm/io.h> 4293db446aSBoris Brezillon #include <asm/fsl_lbc.h> 4393db446aSBoris Brezillon 4493db446aSBoris Brezillon #define MAX_BANKS 8 4593db446aSBoris Brezillon #define ERR_BYTE 0xFF /* Value returned for read bytes when read failed */ 4693db446aSBoris Brezillon #define FCM_TIMEOUT_MSECS 500 /* Maximum number of mSecs to wait for FCM */ 4793db446aSBoris Brezillon 4893db446aSBoris Brezillon /* mtd information per set */ 4993db446aSBoris Brezillon 5093db446aSBoris Brezillon struct fsl_elbc_mtd { 5193db446aSBoris Brezillon struct nand_chip chip; 5293db446aSBoris Brezillon struct fsl_lbc_ctrl *ctrl; 5393db446aSBoris Brezillon 5493db446aSBoris Brezillon struct device *dev; 5593db446aSBoris Brezillon int bank; /* Chip select bank number */ 5693db446aSBoris Brezillon u8 __iomem *vbase; /* Chip select base virtual address */ 5793db446aSBoris Brezillon int page_size; /* NAND page size (0=512, 1=2048) */ 5893db446aSBoris Brezillon unsigned int fmr; /* FCM Flash Mode Register value */ 5993db446aSBoris Brezillon }; 6093db446aSBoris Brezillon 6193db446aSBoris Brezillon /* Freescale eLBC FCM controller information */ 6293db446aSBoris Brezillon 6393db446aSBoris Brezillon struct fsl_elbc_fcm_ctrl { 647da45139SMiquel Raynal struct nand_controller controller; 6593db446aSBoris Brezillon struct fsl_elbc_mtd *chips[MAX_BANKS]; 6693db446aSBoris Brezillon 6793db446aSBoris Brezillon u8 __iomem *addr; /* Address of assigned FCM buffer */ 6893db446aSBoris Brezillon unsigned int page; /* Last page written to / read from */ 6993db446aSBoris Brezillon unsigned int read_bytes; /* Number of bytes read during command */ 7093db446aSBoris Brezillon unsigned int column; /* Saved column from SEQIN */ 7193db446aSBoris Brezillon unsigned int index; /* Pointer to next byte to 'read' */ 7293db446aSBoris Brezillon unsigned int status; /* status read from LTESR after last op */ 7393db446aSBoris Brezillon unsigned int mdr; /* UPM/FCM Data Register value */ 7493db446aSBoris Brezillon unsigned int use_mdr; /* Non zero if the MDR is to be set */ 7593db446aSBoris Brezillon unsigned int oob; /* Non zero if operating on OOB data */ 7693db446aSBoris Brezillon unsigned int counter; /* counter for the initializations */ 7793db446aSBoris Brezillon unsigned int max_bitflips; /* Saved during READ0 cmd */ 7893db446aSBoris Brezillon }; 7993db446aSBoris Brezillon 8093db446aSBoris Brezillon /* These map to the positions used by the FCM hardware ECC generator */ 8193db446aSBoris Brezillon 8293db446aSBoris Brezillon static int fsl_elbc_ooblayout_ecc(struct mtd_info *mtd, int section, 8393db446aSBoris Brezillon struct mtd_oob_region *oobregion) 8493db446aSBoris Brezillon { 8593db446aSBoris Brezillon struct nand_chip *chip = mtd_to_nand(mtd); 8693db446aSBoris Brezillon struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); 8793db446aSBoris Brezillon 8893db446aSBoris Brezillon if (section >= chip->ecc.steps) 8993db446aSBoris Brezillon return -ERANGE; 9093db446aSBoris Brezillon 9193db446aSBoris Brezillon oobregion->offset = (16 * section) + 6; 9293db446aSBoris Brezillon if (priv->fmr & FMR_ECCM) 9393db446aSBoris Brezillon oobregion->offset += 2; 9493db446aSBoris Brezillon 9593db446aSBoris Brezillon oobregion->length = chip->ecc.bytes; 9693db446aSBoris Brezillon 9793db446aSBoris Brezillon return 0; 9893db446aSBoris Brezillon } 9993db446aSBoris Brezillon 10093db446aSBoris Brezillon static int fsl_elbc_ooblayout_free(struct mtd_info *mtd, int section, 10193db446aSBoris Brezillon struct mtd_oob_region *oobregion) 10293db446aSBoris Brezillon { 10393db446aSBoris Brezillon struct nand_chip *chip = mtd_to_nand(mtd); 10493db446aSBoris Brezillon struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); 10593db446aSBoris Brezillon 10693db446aSBoris Brezillon if (section > chip->ecc.steps) 10793db446aSBoris Brezillon return -ERANGE; 10893db446aSBoris Brezillon 10993db446aSBoris Brezillon if (!section) { 11093db446aSBoris Brezillon oobregion->offset = 0; 11193db446aSBoris Brezillon if (mtd->writesize > 512) 11293db446aSBoris Brezillon oobregion->offset++; 11393db446aSBoris Brezillon oobregion->length = (priv->fmr & FMR_ECCM) ? 7 : 5; 11493db446aSBoris Brezillon } else { 11593db446aSBoris Brezillon oobregion->offset = (16 * section) - 11693db446aSBoris Brezillon ((priv->fmr & FMR_ECCM) ? 5 : 7); 11793db446aSBoris Brezillon if (section < chip->ecc.steps) 11893db446aSBoris Brezillon oobregion->length = 13; 11993db446aSBoris Brezillon else 12093db446aSBoris Brezillon oobregion->length = mtd->oobsize - oobregion->offset; 12193db446aSBoris Brezillon } 12293db446aSBoris Brezillon 12393db446aSBoris Brezillon return 0; 12493db446aSBoris Brezillon } 12593db446aSBoris Brezillon 12693db446aSBoris Brezillon static const struct mtd_ooblayout_ops fsl_elbc_ooblayout_ops = { 12793db446aSBoris Brezillon .ecc = fsl_elbc_ooblayout_ecc, 12893db446aSBoris Brezillon .free = fsl_elbc_ooblayout_free, 12993db446aSBoris Brezillon }; 13093db446aSBoris Brezillon 13193db446aSBoris Brezillon /* 13293db446aSBoris Brezillon * ELBC may use HW ECC, so that OOB offsets, that NAND core uses for bbt, 13393db446aSBoris Brezillon * interfere with ECC positions, that's why we implement our own descriptors. 13493db446aSBoris Brezillon * OOB {11, 5}, works for both SP and LP chips, with ECCM = 1 and ECCM = 0. 13593db446aSBoris Brezillon */ 13693db446aSBoris Brezillon static u8 bbt_pattern[] = {'B', 'b', 't', '0' }; 13793db446aSBoris Brezillon static u8 mirror_pattern[] = {'1', 't', 'b', 'B' }; 13893db446aSBoris Brezillon 13993db446aSBoris Brezillon static struct nand_bbt_descr bbt_main_descr = { 14093db446aSBoris Brezillon .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | 14193db446aSBoris Brezillon NAND_BBT_2BIT | NAND_BBT_VERSION, 14293db446aSBoris Brezillon .offs = 11, 14393db446aSBoris Brezillon .len = 4, 14493db446aSBoris Brezillon .veroffs = 15, 14593db446aSBoris Brezillon .maxblocks = 4, 14693db446aSBoris Brezillon .pattern = bbt_pattern, 14793db446aSBoris Brezillon }; 14893db446aSBoris Brezillon 14993db446aSBoris Brezillon static struct nand_bbt_descr bbt_mirror_descr = { 15093db446aSBoris Brezillon .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | 15193db446aSBoris Brezillon NAND_BBT_2BIT | NAND_BBT_VERSION, 15293db446aSBoris Brezillon .offs = 11, 15393db446aSBoris Brezillon .len = 4, 15493db446aSBoris Brezillon .veroffs = 15, 15593db446aSBoris Brezillon .maxblocks = 4, 15693db446aSBoris Brezillon .pattern = mirror_pattern, 15793db446aSBoris Brezillon }; 15893db446aSBoris Brezillon 15993db446aSBoris Brezillon /*=================================*/ 16093db446aSBoris Brezillon 16193db446aSBoris Brezillon /* 16293db446aSBoris Brezillon * Set up the FCM hardware block and page address fields, and the fcm 16393db446aSBoris Brezillon * structure addr field to point to the correct FCM buffer in memory 16493db446aSBoris Brezillon */ 16593db446aSBoris Brezillon static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob) 16693db446aSBoris Brezillon { 16793db446aSBoris Brezillon struct nand_chip *chip = mtd_to_nand(mtd); 16893db446aSBoris Brezillon struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); 16993db446aSBoris Brezillon struct fsl_lbc_ctrl *ctrl = priv->ctrl; 17093db446aSBoris Brezillon struct fsl_lbc_regs __iomem *lbc = ctrl->regs; 17193db446aSBoris Brezillon struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand; 17293db446aSBoris Brezillon int buf_num; 17393db446aSBoris Brezillon 17493db446aSBoris Brezillon elbc_fcm_ctrl->page = page_addr; 17593db446aSBoris Brezillon 17693db446aSBoris Brezillon if (priv->page_size) { 17793db446aSBoris Brezillon /* 17893db446aSBoris Brezillon * large page size chip : FPAR[PI] save the lowest 6 bits, 17993db446aSBoris Brezillon * FBAR[BLK] save the other bits. 18093db446aSBoris Brezillon */ 18193db446aSBoris Brezillon out_be32(&lbc->fbar, page_addr >> 6); 18293db446aSBoris Brezillon out_be32(&lbc->fpar, 18393db446aSBoris Brezillon ((page_addr << FPAR_LP_PI_SHIFT) & FPAR_LP_PI) | 18493db446aSBoris Brezillon (oob ? FPAR_LP_MS : 0) | column); 18593db446aSBoris Brezillon buf_num = (page_addr & 1) << 2; 18693db446aSBoris Brezillon } else { 18793db446aSBoris Brezillon /* 18893db446aSBoris Brezillon * small page size chip : FPAR[PI] save the lowest 5 bits, 18993db446aSBoris Brezillon * FBAR[BLK] save the other bits. 19093db446aSBoris Brezillon */ 19193db446aSBoris Brezillon out_be32(&lbc->fbar, page_addr >> 5); 19293db446aSBoris Brezillon out_be32(&lbc->fpar, 19393db446aSBoris Brezillon ((page_addr << FPAR_SP_PI_SHIFT) & FPAR_SP_PI) | 19493db446aSBoris Brezillon (oob ? FPAR_SP_MS : 0) | column); 19593db446aSBoris Brezillon buf_num = page_addr & 7; 19693db446aSBoris Brezillon } 19793db446aSBoris Brezillon 19893db446aSBoris Brezillon elbc_fcm_ctrl->addr = priv->vbase + buf_num * 1024; 19993db446aSBoris Brezillon elbc_fcm_ctrl->index = column; 20093db446aSBoris Brezillon 20193db446aSBoris Brezillon /* for OOB data point to the second half of the buffer */ 20293db446aSBoris Brezillon if (oob) 20393db446aSBoris Brezillon elbc_fcm_ctrl->index += priv->page_size ? 2048 : 512; 20493db446aSBoris Brezillon 20593db446aSBoris Brezillon dev_vdbg(priv->dev, "set_addr: bank=%d, " 20693db446aSBoris Brezillon "elbc_fcm_ctrl->addr=0x%p (0x%p), " 20793db446aSBoris Brezillon "index %x, pes %d ps %d\n", 20893db446aSBoris Brezillon buf_num, elbc_fcm_ctrl->addr, priv->vbase, 20993db446aSBoris Brezillon elbc_fcm_ctrl->index, 21093db446aSBoris Brezillon chip->phys_erase_shift, chip->page_shift); 21193db446aSBoris Brezillon } 21293db446aSBoris Brezillon 21393db446aSBoris Brezillon /* 21493db446aSBoris Brezillon * execute FCM command and wait for it to complete 21593db446aSBoris Brezillon */ 21693db446aSBoris Brezillon static int fsl_elbc_run_command(struct mtd_info *mtd) 21793db446aSBoris Brezillon { 21893db446aSBoris Brezillon struct nand_chip *chip = mtd_to_nand(mtd); 21993db446aSBoris Brezillon struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); 22093db446aSBoris Brezillon struct fsl_lbc_ctrl *ctrl = priv->ctrl; 22193db446aSBoris Brezillon struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand; 22293db446aSBoris Brezillon struct fsl_lbc_regs __iomem *lbc = ctrl->regs; 22393db446aSBoris Brezillon 22493db446aSBoris Brezillon /* Setup the FMR[OP] to execute without write protection */ 22593db446aSBoris Brezillon out_be32(&lbc->fmr, priv->fmr | 3); 22693db446aSBoris Brezillon if (elbc_fcm_ctrl->use_mdr) 22793db446aSBoris Brezillon out_be32(&lbc->mdr, elbc_fcm_ctrl->mdr); 22893db446aSBoris Brezillon 22993db446aSBoris Brezillon dev_vdbg(priv->dev, 23093db446aSBoris Brezillon "fsl_elbc_run_command: fmr=%08x fir=%08x fcr=%08x\n", 23193db446aSBoris Brezillon in_be32(&lbc->fmr), in_be32(&lbc->fir), in_be32(&lbc->fcr)); 23293db446aSBoris Brezillon dev_vdbg(priv->dev, 23393db446aSBoris Brezillon "fsl_elbc_run_command: fbar=%08x fpar=%08x " 23493db446aSBoris Brezillon "fbcr=%08x bank=%d\n", 23593db446aSBoris Brezillon in_be32(&lbc->fbar), in_be32(&lbc->fpar), 23693db446aSBoris Brezillon in_be32(&lbc->fbcr), priv->bank); 23793db446aSBoris Brezillon 23893db446aSBoris Brezillon ctrl->irq_status = 0; 23993db446aSBoris Brezillon /* execute special operation */ 24093db446aSBoris Brezillon out_be32(&lbc->lsor, priv->bank); 24193db446aSBoris Brezillon 24293db446aSBoris Brezillon /* wait for FCM complete flag or timeout */ 24393db446aSBoris Brezillon wait_event_timeout(ctrl->irq_wait, ctrl->irq_status, 24493db446aSBoris Brezillon FCM_TIMEOUT_MSECS * HZ/1000); 24593db446aSBoris Brezillon elbc_fcm_ctrl->status = ctrl->irq_status; 24693db446aSBoris Brezillon /* store mdr value in case it was needed */ 24793db446aSBoris Brezillon if (elbc_fcm_ctrl->use_mdr) 24893db446aSBoris Brezillon elbc_fcm_ctrl->mdr = in_be32(&lbc->mdr); 24993db446aSBoris Brezillon 25093db446aSBoris Brezillon elbc_fcm_ctrl->use_mdr = 0; 25193db446aSBoris Brezillon 25293db446aSBoris Brezillon if (elbc_fcm_ctrl->status != LTESR_CC) { 25393db446aSBoris Brezillon dev_info(priv->dev, 25493db446aSBoris Brezillon "command failed: fir %x fcr %x status %x mdr %x\n", 25593db446aSBoris Brezillon in_be32(&lbc->fir), in_be32(&lbc->fcr), 25693db446aSBoris Brezillon elbc_fcm_ctrl->status, elbc_fcm_ctrl->mdr); 25793db446aSBoris Brezillon return -EIO; 25893db446aSBoris Brezillon } 25993db446aSBoris Brezillon 26093db446aSBoris Brezillon if (chip->ecc.mode != NAND_ECC_HW) 26193db446aSBoris Brezillon return 0; 26293db446aSBoris Brezillon 26393db446aSBoris Brezillon elbc_fcm_ctrl->max_bitflips = 0; 26493db446aSBoris Brezillon 26593db446aSBoris Brezillon if (elbc_fcm_ctrl->read_bytes == mtd->writesize + mtd->oobsize) { 26693db446aSBoris Brezillon uint32_t lteccr = in_be32(&lbc->lteccr); 26793db446aSBoris Brezillon /* 26893db446aSBoris Brezillon * if command was a full page read and the ELBC 26993db446aSBoris Brezillon * has the LTECCR register, then bits 12-15 (ppc order) of 27093db446aSBoris Brezillon * LTECCR indicates which 512 byte sub-pages had fixed errors. 27193db446aSBoris Brezillon * bits 28-31 are uncorrectable errors, marked elsewhere. 27293db446aSBoris Brezillon * for small page nand only 1 bit is used. 27393db446aSBoris Brezillon * if the ELBC doesn't have the lteccr register it reads 0 27493db446aSBoris Brezillon * FIXME: 4 bits can be corrected on NANDs with 2k pages, so 27593db446aSBoris Brezillon * count the number of sub-pages with bitflips and update 27693db446aSBoris Brezillon * ecc_stats.corrected accordingly. 27793db446aSBoris Brezillon */ 27893db446aSBoris Brezillon if (lteccr & 0x000F000F) 27993db446aSBoris Brezillon out_be32(&lbc->lteccr, 0x000F000F); /* clear lteccr */ 28093db446aSBoris Brezillon if (lteccr & 0x000F0000) { 28193db446aSBoris Brezillon mtd->ecc_stats.corrected++; 28293db446aSBoris Brezillon elbc_fcm_ctrl->max_bitflips = 1; 28393db446aSBoris Brezillon } 28493db446aSBoris Brezillon } 28593db446aSBoris Brezillon 28693db446aSBoris Brezillon return 0; 28793db446aSBoris Brezillon } 28893db446aSBoris Brezillon 28993db446aSBoris Brezillon static void fsl_elbc_do_read(struct nand_chip *chip, int oob) 29093db446aSBoris Brezillon { 29193db446aSBoris Brezillon struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); 29293db446aSBoris Brezillon struct fsl_lbc_ctrl *ctrl = priv->ctrl; 29393db446aSBoris Brezillon struct fsl_lbc_regs __iomem *lbc = ctrl->regs; 29493db446aSBoris Brezillon 29593db446aSBoris Brezillon if (priv->page_size) { 29693db446aSBoris Brezillon out_be32(&lbc->fir, 29793db446aSBoris Brezillon (FIR_OP_CM0 << FIR_OP0_SHIFT) | 29893db446aSBoris Brezillon (FIR_OP_CA << FIR_OP1_SHIFT) | 29993db446aSBoris Brezillon (FIR_OP_PA << FIR_OP2_SHIFT) | 30093db446aSBoris Brezillon (FIR_OP_CM1 << FIR_OP3_SHIFT) | 30193db446aSBoris Brezillon (FIR_OP_RBW << FIR_OP4_SHIFT)); 30293db446aSBoris Brezillon 30393db446aSBoris Brezillon out_be32(&lbc->fcr, (NAND_CMD_READ0 << FCR_CMD0_SHIFT) | 30493db446aSBoris Brezillon (NAND_CMD_READSTART << FCR_CMD1_SHIFT)); 30593db446aSBoris Brezillon } else { 30693db446aSBoris Brezillon out_be32(&lbc->fir, 30793db446aSBoris Brezillon (FIR_OP_CM0 << FIR_OP0_SHIFT) | 30893db446aSBoris Brezillon (FIR_OP_CA << FIR_OP1_SHIFT) | 30993db446aSBoris Brezillon (FIR_OP_PA << FIR_OP2_SHIFT) | 31093db446aSBoris Brezillon (FIR_OP_RBW << FIR_OP3_SHIFT)); 31193db446aSBoris Brezillon 31293db446aSBoris Brezillon if (oob) 31393db446aSBoris Brezillon out_be32(&lbc->fcr, NAND_CMD_READOOB << FCR_CMD0_SHIFT); 31493db446aSBoris Brezillon else 31593db446aSBoris Brezillon out_be32(&lbc->fcr, NAND_CMD_READ0 << FCR_CMD0_SHIFT); 31693db446aSBoris Brezillon } 31793db446aSBoris Brezillon } 31893db446aSBoris Brezillon 31993db446aSBoris Brezillon /* cmdfunc send commands to the FCM */ 3205295cf2eSBoris Brezillon static void fsl_elbc_cmdfunc(struct nand_chip *chip, unsigned int command, 32193db446aSBoris Brezillon int column, int page_addr) 32293db446aSBoris Brezillon { 3235295cf2eSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip); 32493db446aSBoris Brezillon struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); 32593db446aSBoris Brezillon struct fsl_lbc_ctrl *ctrl = priv->ctrl; 32693db446aSBoris Brezillon struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand; 32793db446aSBoris Brezillon struct fsl_lbc_regs __iomem *lbc = ctrl->regs; 32893db446aSBoris Brezillon 32993db446aSBoris Brezillon elbc_fcm_ctrl->use_mdr = 0; 33093db446aSBoris Brezillon 33193db446aSBoris Brezillon /* clear the read buffer */ 33293db446aSBoris Brezillon elbc_fcm_ctrl->read_bytes = 0; 33393db446aSBoris Brezillon if (command != NAND_CMD_PAGEPROG) 33493db446aSBoris Brezillon elbc_fcm_ctrl->index = 0; 33593db446aSBoris Brezillon 33693db446aSBoris Brezillon switch (command) { 33793db446aSBoris Brezillon /* READ0 and READ1 read the entire buffer to use hardware ECC. */ 33893db446aSBoris Brezillon case NAND_CMD_READ1: 33993db446aSBoris Brezillon column += 256; 34093db446aSBoris Brezillon 34193db446aSBoris Brezillon /* fall-through */ 34293db446aSBoris Brezillon case NAND_CMD_READ0: 34393db446aSBoris Brezillon dev_dbg(priv->dev, 34493db446aSBoris Brezillon "fsl_elbc_cmdfunc: NAND_CMD_READ0, page_addr:" 34593db446aSBoris Brezillon " 0x%x, column: 0x%x.\n", page_addr, column); 34693db446aSBoris Brezillon 34793db446aSBoris Brezillon 34893db446aSBoris Brezillon out_be32(&lbc->fbcr, 0); /* read entire page to enable ECC */ 34993db446aSBoris Brezillon set_addr(mtd, 0, page_addr, 0); 35093db446aSBoris Brezillon 35193db446aSBoris Brezillon elbc_fcm_ctrl->read_bytes = mtd->writesize + mtd->oobsize; 35293db446aSBoris Brezillon elbc_fcm_ctrl->index += column; 35393db446aSBoris Brezillon 35493db446aSBoris Brezillon fsl_elbc_do_read(chip, 0); 35593db446aSBoris Brezillon fsl_elbc_run_command(mtd); 35693db446aSBoris Brezillon return; 35793db446aSBoris Brezillon 35893db446aSBoris Brezillon /* READOOB reads only the OOB because no ECC is performed. */ 35993db446aSBoris Brezillon case NAND_CMD_READOOB: 36093db446aSBoris Brezillon dev_vdbg(priv->dev, 36193db446aSBoris Brezillon "fsl_elbc_cmdfunc: NAND_CMD_READOOB, page_addr:" 36293db446aSBoris Brezillon " 0x%x, column: 0x%x.\n", page_addr, column); 36393db446aSBoris Brezillon 36493db446aSBoris Brezillon out_be32(&lbc->fbcr, mtd->oobsize - column); 36593db446aSBoris Brezillon set_addr(mtd, column, page_addr, 1); 36693db446aSBoris Brezillon 36793db446aSBoris Brezillon elbc_fcm_ctrl->read_bytes = mtd->writesize + mtd->oobsize; 36893db446aSBoris Brezillon 36993db446aSBoris Brezillon fsl_elbc_do_read(chip, 1); 37093db446aSBoris Brezillon fsl_elbc_run_command(mtd); 37193db446aSBoris Brezillon return; 37293db446aSBoris Brezillon 37393db446aSBoris Brezillon case NAND_CMD_READID: 37493db446aSBoris Brezillon case NAND_CMD_PARAM: 37593db446aSBoris Brezillon dev_vdbg(priv->dev, "fsl_elbc_cmdfunc: NAND_CMD %x\n", command); 37693db446aSBoris Brezillon 37793db446aSBoris Brezillon out_be32(&lbc->fir, (FIR_OP_CM0 << FIR_OP0_SHIFT) | 37893db446aSBoris Brezillon (FIR_OP_UA << FIR_OP1_SHIFT) | 37993db446aSBoris Brezillon (FIR_OP_RBW << FIR_OP2_SHIFT)); 38093db446aSBoris Brezillon out_be32(&lbc->fcr, command << FCR_CMD0_SHIFT); 38193db446aSBoris Brezillon /* 38293db446aSBoris Brezillon * although currently it's 8 bytes for READID, we always read 38393db446aSBoris Brezillon * the maximum 256 bytes(for PARAM) 38493db446aSBoris Brezillon */ 38593db446aSBoris Brezillon out_be32(&lbc->fbcr, 256); 38693db446aSBoris Brezillon elbc_fcm_ctrl->read_bytes = 256; 38793db446aSBoris Brezillon elbc_fcm_ctrl->use_mdr = 1; 38893db446aSBoris Brezillon elbc_fcm_ctrl->mdr = column; 38993db446aSBoris Brezillon set_addr(mtd, 0, 0, 0); 39093db446aSBoris Brezillon fsl_elbc_run_command(mtd); 39193db446aSBoris Brezillon return; 39293db446aSBoris Brezillon 39393db446aSBoris Brezillon /* ERASE1 stores the block and page address */ 39493db446aSBoris Brezillon case NAND_CMD_ERASE1: 39593db446aSBoris Brezillon dev_vdbg(priv->dev, 39693db446aSBoris Brezillon "fsl_elbc_cmdfunc: NAND_CMD_ERASE1, " 39793db446aSBoris Brezillon "page_addr: 0x%x.\n", page_addr); 39893db446aSBoris Brezillon set_addr(mtd, 0, page_addr, 0); 39993db446aSBoris Brezillon return; 40093db446aSBoris Brezillon 40193db446aSBoris Brezillon /* ERASE2 uses the block and page address from ERASE1 */ 40293db446aSBoris Brezillon case NAND_CMD_ERASE2: 40393db446aSBoris Brezillon dev_vdbg(priv->dev, "fsl_elbc_cmdfunc: NAND_CMD_ERASE2.\n"); 40493db446aSBoris Brezillon 40593db446aSBoris Brezillon out_be32(&lbc->fir, 40693db446aSBoris Brezillon (FIR_OP_CM0 << FIR_OP0_SHIFT) | 40793db446aSBoris Brezillon (FIR_OP_PA << FIR_OP1_SHIFT) | 40893db446aSBoris Brezillon (FIR_OP_CM2 << FIR_OP2_SHIFT) | 40993db446aSBoris Brezillon (FIR_OP_CW1 << FIR_OP3_SHIFT) | 41093db446aSBoris Brezillon (FIR_OP_RS << FIR_OP4_SHIFT)); 41193db446aSBoris Brezillon 41293db446aSBoris Brezillon out_be32(&lbc->fcr, 41393db446aSBoris Brezillon (NAND_CMD_ERASE1 << FCR_CMD0_SHIFT) | 41493db446aSBoris Brezillon (NAND_CMD_STATUS << FCR_CMD1_SHIFT) | 41593db446aSBoris Brezillon (NAND_CMD_ERASE2 << FCR_CMD2_SHIFT)); 41693db446aSBoris Brezillon 41793db446aSBoris Brezillon out_be32(&lbc->fbcr, 0); 41893db446aSBoris Brezillon elbc_fcm_ctrl->read_bytes = 0; 41993db446aSBoris Brezillon elbc_fcm_ctrl->use_mdr = 1; 42093db446aSBoris Brezillon 42193db446aSBoris Brezillon fsl_elbc_run_command(mtd); 42293db446aSBoris Brezillon return; 42393db446aSBoris Brezillon 42493db446aSBoris Brezillon /* SEQIN sets up the addr buffer and all registers except the length */ 42593db446aSBoris Brezillon case NAND_CMD_SEQIN: { 42693db446aSBoris Brezillon __be32 fcr; 42793db446aSBoris Brezillon dev_vdbg(priv->dev, 42893db446aSBoris Brezillon "fsl_elbc_cmdfunc: NAND_CMD_SEQIN/PAGE_PROG, " 42993db446aSBoris Brezillon "page_addr: 0x%x, column: 0x%x.\n", 43093db446aSBoris Brezillon page_addr, column); 43193db446aSBoris Brezillon 43293db446aSBoris Brezillon elbc_fcm_ctrl->column = column; 43393db446aSBoris Brezillon elbc_fcm_ctrl->use_mdr = 1; 43493db446aSBoris Brezillon 43593db446aSBoris Brezillon if (column >= mtd->writesize) { 43693db446aSBoris Brezillon /* OOB area */ 43793db446aSBoris Brezillon column -= mtd->writesize; 43893db446aSBoris Brezillon elbc_fcm_ctrl->oob = 1; 43993db446aSBoris Brezillon } else { 44093db446aSBoris Brezillon WARN_ON(column != 0); 44193db446aSBoris Brezillon elbc_fcm_ctrl->oob = 0; 44293db446aSBoris Brezillon } 44393db446aSBoris Brezillon 44493db446aSBoris Brezillon fcr = (NAND_CMD_STATUS << FCR_CMD1_SHIFT) | 44593db446aSBoris Brezillon (NAND_CMD_SEQIN << FCR_CMD2_SHIFT) | 44693db446aSBoris Brezillon (NAND_CMD_PAGEPROG << FCR_CMD3_SHIFT); 44793db446aSBoris Brezillon 44893db446aSBoris Brezillon if (priv->page_size) { 44993db446aSBoris Brezillon out_be32(&lbc->fir, 45093db446aSBoris Brezillon (FIR_OP_CM2 << FIR_OP0_SHIFT) | 45193db446aSBoris Brezillon (FIR_OP_CA << FIR_OP1_SHIFT) | 45293db446aSBoris Brezillon (FIR_OP_PA << FIR_OP2_SHIFT) | 45393db446aSBoris Brezillon (FIR_OP_WB << FIR_OP3_SHIFT) | 45493db446aSBoris Brezillon (FIR_OP_CM3 << FIR_OP4_SHIFT) | 45593db446aSBoris Brezillon (FIR_OP_CW1 << FIR_OP5_SHIFT) | 45693db446aSBoris Brezillon (FIR_OP_RS << FIR_OP6_SHIFT)); 45793db446aSBoris Brezillon } else { 45893db446aSBoris Brezillon out_be32(&lbc->fir, 45993db446aSBoris Brezillon (FIR_OP_CM0 << FIR_OP0_SHIFT) | 46093db446aSBoris Brezillon (FIR_OP_CM2 << FIR_OP1_SHIFT) | 46193db446aSBoris Brezillon (FIR_OP_CA << FIR_OP2_SHIFT) | 46293db446aSBoris Brezillon (FIR_OP_PA << FIR_OP3_SHIFT) | 46393db446aSBoris Brezillon (FIR_OP_WB << FIR_OP4_SHIFT) | 46493db446aSBoris Brezillon (FIR_OP_CM3 << FIR_OP5_SHIFT) | 46593db446aSBoris Brezillon (FIR_OP_CW1 << FIR_OP6_SHIFT) | 46693db446aSBoris Brezillon (FIR_OP_RS << FIR_OP7_SHIFT)); 46793db446aSBoris Brezillon 46893db446aSBoris Brezillon if (elbc_fcm_ctrl->oob) 46993db446aSBoris Brezillon /* OOB area --> READOOB */ 47093db446aSBoris Brezillon fcr |= NAND_CMD_READOOB << FCR_CMD0_SHIFT; 47193db446aSBoris Brezillon else 47293db446aSBoris Brezillon /* First 256 bytes --> READ0 */ 47393db446aSBoris Brezillon fcr |= NAND_CMD_READ0 << FCR_CMD0_SHIFT; 47493db446aSBoris Brezillon } 47593db446aSBoris Brezillon 47693db446aSBoris Brezillon out_be32(&lbc->fcr, fcr); 47793db446aSBoris Brezillon set_addr(mtd, column, page_addr, elbc_fcm_ctrl->oob); 47893db446aSBoris Brezillon return; 47993db446aSBoris Brezillon } 48093db446aSBoris Brezillon 48193db446aSBoris Brezillon /* PAGEPROG reuses all of the setup from SEQIN and adds the length */ 48293db446aSBoris Brezillon case NAND_CMD_PAGEPROG: { 48393db446aSBoris Brezillon dev_vdbg(priv->dev, 48493db446aSBoris Brezillon "fsl_elbc_cmdfunc: NAND_CMD_PAGEPROG " 48593db446aSBoris Brezillon "writing %d bytes.\n", elbc_fcm_ctrl->index); 48693db446aSBoris Brezillon 48793db446aSBoris Brezillon /* if the write did not start at 0 or is not a full page 48893db446aSBoris Brezillon * then set the exact length, otherwise use a full page 48993db446aSBoris Brezillon * write so the HW generates the ECC. 49093db446aSBoris Brezillon */ 49193db446aSBoris Brezillon if (elbc_fcm_ctrl->oob || elbc_fcm_ctrl->column != 0 || 49293db446aSBoris Brezillon elbc_fcm_ctrl->index != mtd->writesize + mtd->oobsize) 49393db446aSBoris Brezillon out_be32(&lbc->fbcr, 49493db446aSBoris Brezillon elbc_fcm_ctrl->index - elbc_fcm_ctrl->column); 49593db446aSBoris Brezillon else 49693db446aSBoris Brezillon out_be32(&lbc->fbcr, 0); 49793db446aSBoris Brezillon 49893db446aSBoris Brezillon fsl_elbc_run_command(mtd); 49993db446aSBoris Brezillon return; 50093db446aSBoris Brezillon } 50193db446aSBoris Brezillon 50293db446aSBoris Brezillon /* CMD_STATUS must read the status byte while CEB is active */ 50393db446aSBoris Brezillon /* Note - it does not wait for the ready line */ 50493db446aSBoris Brezillon case NAND_CMD_STATUS: 50593db446aSBoris Brezillon out_be32(&lbc->fir, 50693db446aSBoris Brezillon (FIR_OP_CM0 << FIR_OP0_SHIFT) | 50793db446aSBoris Brezillon (FIR_OP_RBW << FIR_OP1_SHIFT)); 50893db446aSBoris Brezillon out_be32(&lbc->fcr, NAND_CMD_STATUS << FCR_CMD0_SHIFT); 50993db446aSBoris Brezillon out_be32(&lbc->fbcr, 1); 51093db446aSBoris Brezillon set_addr(mtd, 0, 0, 0); 51193db446aSBoris Brezillon elbc_fcm_ctrl->read_bytes = 1; 51293db446aSBoris Brezillon 51393db446aSBoris Brezillon fsl_elbc_run_command(mtd); 51493db446aSBoris Brezillon 51593db446aSBoris Brezillon /* The chip always seems to report that it is 51693db446aSBoris Brezillon * write-protected, even when it is not. 51793db446aSBoris Brezillon */ 51893db446aSBoris Brezillon setbits8(elbc_fcm_ctrl->addr, NAND_STATUS_WP); 51993db446aSBoris Brezillon return; 52093db446aSBoris Brezillon 52193db446aSBoris Brezillon /* RESET without waiting for the ready line */ 52293db446aSBoris Brezillon case NAND_CMD_RESET: 52393db446aSBoris Brezillon dev_dbg(priv->dev, "fsl_elbc_cmdfunc: NAND_CMD_RESET.\n"); 52493db446aSBoris Brezillon out_be32(&lbc->fir, FIR_OP_CM0 << FIR_OP0_SHIFT); 52593db446aSBoris Brezillon out_be32(&lbc->fcr, NAND_CMD_RESET << FCR_CMD0_SHIFT); 52693db446aSBoris Brezillon fsl_elbc_run_command(mtd); 52793db446aSBoris Brezillon return; 52893db446aSBoris Brezillon 52993db446aSBoris Brezillon default: 53093db446aSBoris Brezillon dev_err(priv->dev, 53193db446aSBoris Brezillon "fsl_elbc_cmdfunc: error, unsupported command 0x%x.\n", 53293db446aSBoris Brezillon command); 53393db446aSBoris Brezillon } 53493db446aSBoris Brezillon } 53593db446aSBoris Brezillon 536758b56f5SBoris Brezillon static void fsl_elbc_select_chip(struct nand_chip *chip, int cs) 53793db446aSBoris Brezillon { 53893db446aSBoris Brezillon /* The hardware does not seem to support multiple 53993db446aSBoris Brezillon * chips per bank. 54093db446aSBoris Brezillon */ 54193db446aSBoris Brezillon } 54293db446aSBoris Brezillon 54393db446aSBoris Brezillon /* 54493db446aSBoris Brezillon * Write buf to the FCM Controller Data Buffer 54593db446aSBoris Brezillon */ 546c0739d85SBoris Brezillon static void fsl_elbc_write_buf(struct nand_chip *chip, const u8 *buf, int len) 54793db446aSBoris Brezillon { 548c0739d85SBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip); 54993db446aSBoris Brezillon struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); 55093db446aSBoris Brezillon struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; 55193db446aSBoris Brezillon unsigned int bufsize = mtd->writesize + mtd->oobsize; 55293db446aSBoris Brezillon 55393db446aSBoris Brezillon if (len <= 0) { 55493db446aSBoris Brezillon dev_err(priv->dev, "write_buf of %d bytes", len); 55593db446aSBoris Brezillon elbc_fcm_ctrl->status = 0; 55693db446aSBoris Brezillon return; 55793db446aSBoris Brezillon } 55893db446aSBoris Brezillon 55993db446aSBoris Brezillon if ((unsigned int)len > bufsize - elbc_fcm_ctrl->index) { 56093db446aSBoris Brezillon dev_err(priv->dev, 56193db446aSBoris Brezillon "write_buf beyond end of buffer " 56293db446aSBoris Brezillon "(%d requested, %u available)\n", 56393db446aSBoris Brezillon len, bufsize - elbc_fcm_ctrl->index); 56493db446aSBoris Brezillon len = bufsize - elbc_fcm_ctrl->index; 56593db446aSBoris Brezillon } 56693db446aSBoris Brezillon 56793db446aSBoris Brezillon memcpy_toio(&elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index], buf, len); 56893db446aSBoris Brezillon /* 56993db446aSBoris Brezillon * This is workaround for the weird elbc hangs during nand write, 57093db446aSBoris Brezillon * Scott Wood says: "...perhaps difference in how long it takes a 57193db446aSBoris Brezillon * write to make it through the localbus compared to a write to IMMR 57293db446aSBoris Brezillon * is causing problems, and sync isn't helping for some reason." 57393db446aSBoris Brezillon * Reading back the last byte helps though. 57493db446aSBoris Brezillon */ 57593db446aSBoris Brezillon in_8(&elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index] + len - 1); 57693db446aSBoris Brezillon 57793db446aSBoris Brezillon elbc_fcm_ctrl->index += len; 57893db446aSBoris Brezillon } 57993db446aSBoris Brezillon 58093db446aSBoris Brezillon /* 58193db446aSBoris Brezillon * read a byte from either the FCM hardware buffer if it has any data left 58293db446aSBoris Brezillon * otherwise issue a command to read a single byte. 58393db446aSBoris Brezillon */ 5847e534323SBoris Brezillon static u8 fsl_elbc_read_byte(struct nand_chip *chip) 58593db446aSBoris Brezillon { 58693db446aSBoris Brezillon struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); 58793db446aSBoris Brezillon struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; 58893db446aSBoris Brezillon 58993db446aSBoris Brezillon /* If there are still bytes in the FCM, then use the next byte. */ 59093db446aSBoris Brezillon if (elbc_fcm_ctrl->index < elbc_fcm_ctrl->read_bytes) 59193db446aSBoris Brezillon return in_8(&elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index++]); 59293db446aSBoris Brezillon 59393db446aSBoris Brezillon dev_err(priv->dev, "read_byte beyond end of buffer\n"); 59493db446aSBoris Brezillon return ERR_BYTE; 59593db446aSBoris Brezillon } 59693db446aSBoris Brezillon 59793db446aSBoris Brezillon /* 59893db446aSBoris Brezillon * Read from the FCM Controller Data Buffer 59993db446aSBoris Brezillon */ 6007e534323SBoris Brezillon static void fsl_elbc_read_buf(struct nand_chip *chip, u8 *buf, int len) 60193db446aSBoris Brezillon { 60293db446aSBoris Brezillon struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); 60393db446aSBoris Brezillon struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; 60493db446aSBoris Brezillon int avail; 60593db446aSBoris Brezillon 60693db446aSBoris Brezillon if (len < 0) 60793db446aSBoris Brezillon return; 60893db446aSBoris Brezillon 60993db446aSBoris Brezillon avail = min((unsigned int)len, 61093db446aSBoris Brezillon elbc_fcm_ctrl->read_bytes - elbc_fcm_ctrl->index); 61193db446aSBoris Brezillon memcpy_fromio(buf, &elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index], avail); 61293db446aSBoris Brezillon elbc_fcm_ctrl->index += avail; 61393db446aSBoris Brezillon 61493db446aSBoris Brezillon if (len > avail) 61593db446aSBoris Brezillon dev_err(priv->dev, 61693db446aSBoris Brezillon "read_buf beyond end of buffer " 61793db446aSBoris Brezillon "(%d requested, %d available)\n", 61893db446aSBoris Brezillon len, avail); 61993db446aSBoris Brezillon } 62093db446aSBoris Brezillon 62193db446aSBoris Brezillon /* This function is called after Program and Erase Operations to 62293db446aSBoris Brezillon * check for success or failure. 62393db446aSBoris Brezillon */ 624f1d46942SBoris Brezillon static int fsl_elbc_wait(struct nand_chip *chip) 62593db446aSBoris Brezillon { 62693db446aSBoris Brezillon struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); 62793db446aSBoris Brezillon struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; 62893db446aSBoris Brezillon 62993db446aSBoris Brezillon if (elbc_fcm_ctrl->status != LTESR_CC) 63093db446aSBoris Brezillon return NAND_STATUS_FAIL; 63193db446aSBoris Brezillon 63293db446aSBoris Brezillon /* The chip always seems to report that it is 63393db446aSBoris Brezillon * write-protected, even when it is not. 63493db446aSBoris Brezillon */ 63593db446aSBoris Brezillon return (elbc_fcm_ctrl->mdr & 0xff) | NAND_STATUS_WP; 63693db446aSBoris Brezillon } 63793db446aSBoris Brezillon 6385bf3e76bSMiquel Raynal static int fsl_elbc_attach_chip(struct nand_chip *chip) 63993db446aSBoris Brezillon { 6405bf3e76bSMiquel Raynal struct mtd_info *mtd = nand_to_mtd(chip); 64193db446aSBoris Brezillon struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); 64293db446aSBoris Brezillon struct fsl_lbc_ctrl *ctrl = priv->ctrl; 64393db446aSBoris Brezillon struct fsl_lbc_regs __iomem *lbc = ctrl->regs; 64493db446aSBoris Brezillon unsigned int al; 64593db446aSBoris Brezillon 64693db446aSBoris Brezillon /* calculate FMR Address Length field */ 64793db446aSBoris Brezillon al = 0; 64893db446aSBoris Brezillon if (chip->pagemask & 0xffff0000) 64993db446aSBoris Brezillon al++; 65093db446aSBoris Brezillon if (chip->pagemask & 0xff000000) 65193db446aSBoris Brezillon al++; 65293db446aSBoris Brezillon 65393db446aSBoris Brezillon priv->fmr |= al << FMR_AL_SHIFT; 65493db446aSBoris Brezillon 65593db446aSBoris Brezillon dev_dbg(priv->dev, "fsl_elbc_init: nand->numchips = %d\n", 65693db446aSBoris Brezillon chip->numchips); 65793db446aSBoris Brezillon dev_dbg(priv->dev, "fsl_elbc_init: nand->chipsize = %lld\n", 65893db446aSBoris Brezillon chip->chipsize); 65993db446aSBoris Brezillon dev_dbg(priv->dev, "fsl_elbc_init: nand->pagemask = %8x\n", 66093db446aSBoris Brezillon chip->pagemask); 66193db446aSBoris Brezillon dev_dbg(priv->dev, "fsl_elbc_init: nand->chip_delay = %d\n", 66293db446aSBoris Brezillon chip->chip_delay); 66393db446aSBoris Brezillon dev_dbg(priv->dev, "fsl_elbc_init: nand->badblockpos = %d\n", 66493db446aSBoris Brezillon chip->badblockpos); 66593db446aSBoris Brezillon dev_dbg(priv->dev, "fsl_elbc_init: nand->chip_shift = %d\n", 66693db446aSBoris Brezillon chip->chip_shift); 66793db446aSBoris Brezillon dev_dbg(priv->dev, "fsl_elbc_init: nand->page_shift = %d\n", 66893db446aSBoris Brezillon chip->page_shift); 66993db446aSBoris Brezillon dev_dbg(priv->dev, "fsl_elbc_init: nand->phys_erase_shift = %d\n", 67093db446aSBoris Brezillon chip->phys_erase_shift); 67193db446aSBoris Brezillon dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.mode = %d\n", 67293db446aSBoris Brezillon chip->ecc.mode); 67393db446aSBoris Brezillon dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.steps = %d\n", 67493db446aSBoris Brezillon chip->ecc.steps); 67593db446aSBoris Brezillon dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.bytes = %d\n", 67693db446aSBoris Brezillon chip->ecc.bytes); 67793db446aSBoris Brezillon dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.total = %d\n", 67893db446aSBoris Brezillon chip->ecc.total); 67993db446aSBoris Brezillon dev_dbg(priv->dev, "fsl_elbc_init: mtd->ooblayout = %p\n", 68093db446aSBoris Brezillon mtd->ooblayout); 68193db446aSBoris Brezillon dev_dbg(priv->dev, "fsl_elbc_init: mtd->flags = %08x\n", mtd->flags); 68293db446aSBoris Brezillon dev_dbg(priv->dev, "fsl_elbc_init: mtd->size = %lld\n", mtd->size); 68393db446aSBoris Brezillon dev_dbg(priv->dev, "fsl_elbc_init: mtd->erasesize = %d\n", 68493db446aSBoris Brezillon mtd->erasesize); 68593db446aSBoris Brezillon dev_dbg(priv->dev, "fsl_elbc_init: mtd->writesize = %d\n", 68693db446aSBoris Brezillon mtd->writesize); 68793db446aSBoris Brezillon dev_dbg(priv->dev, "fsl_elbc_init: mtd->oobsize = %d\n", 68893db446aSBoris Brezillon mtd->oobsize); 68993db446aSBoris Brezillon 69093db446aSBoris Brezillon /* adjust Option Register and ECC to match Flash page size */ 69193db446aSBoris Brezillon if (mtd->writesize == 512) { 69293db446aSBoris Brezillon priv->page_size = 0; 69393db446aSBoris Brezillon clrbits32(&lbc->bank[priv->bank].or, OR_FCM_PGS); 69493db446aSBoris Brezillon } else if (mtd->writesize == 2048) { 69593db446aSBoris Brezillon priv->page_size = 1; 69693db446aSBoris Brezillon setbits32(&lbc->bank[priv->bank].or, OR_FCM_PGS); 69793db446aSBoris Brezillon } else { 69893db446aSBoris Brezillon dev_err(priv->dev, 69993db446aSBoris Brezillon "fsl_elbc_init: page size %d is not supported\n", 70093db446aSBoris Brezillon mtd->writesize); 70199dc9d95SMiquel Raynal return -ENOTSUPP; 70293db446aSBoris Brezillon } 70393db446aSBoris Brezillon 70493db446aSBoris Brezillon return 0; 70593db446aSBoris Brezillon } 70693db446aSBoris Brezillon 7075bf3e76bSMiquel Raynal static const struct nand_controller_ops fsl_elbc_controller_ops = { 7085bf3e76bSMiquel Raynal .attach_chip = fsl_elbc_attach_chip, 7095bf3e76bSMiquel Raynal }; 7105bf3e76bSMiquel Raynal 711b9761687SBoris Brezillon static int fsl_elbc_read_page(struct nand_chip *chip, uint8_t *buf, 712b9761687SBoris Brezillon int oob_required, int page) 71393db446aSBoris Brezillon { 714b9761687SBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip); 71593db446aSBoris Brezillon struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); 71693db446aSBoris Brezillon struct fsl_lbc_ctrl *ctrl = priv->ctrl; 71793db446aSBoris Brezillon struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand; 71893db446aSBoris Brezillon 71993db446aSBoris Brezillon nand_read_page_op(chip, page, 0, buf, mtd->writesize); 72093db446aSBoris Brezillon if (oob_required) 7217e534323SBoris Brezillon fsl_elbc_read_buf(chip, chip->oob_poi, mtd->oobsize); 72293db446aSBoris Brezillon 723f1d46942SBoris Brezillon if (fsl_elbc_wait(chip) & NAND_STATUS_FAIL) 72493db446aSBoris Brezillon mtd->ecc_stats.failed++; 72593db446aSBoris Brezillon 72693db446aSBoris Brezillon return elbc_fcm_ctrl->max_bitflips; 72793db446aSBoris Brezillon } 72893db446aSBoris Brezillon 72993db446aSBoris Brezillon /* ECC will be calculated automatically, and errors will be detected in 73093db446aSBoris Brezillon * waitfunc. 73193db446aSBoris Brezillon */ 732767eb6fbSBoris Brezillon static int fsl_elbc_write_page(struct nand_chip *chip, const uint8_t *buf, 733767eb6fbSBoris Brezillon int oob_required, int page) 73493db446aSBoris Brezillon { 735767eb6fbSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip); 736767eb6fbSBoris Brezillon 73793db446aSBoris Brezillon nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize); 738c0739d85SBoris Brezillon fsl_elbc_write_buf(chip, chip->oob_poi, mtd->oobsize); 73993db446aSBoris Brezillon 74093db446aSBoris Brezillon return nand_prog_page_end_op(chip); 74193db446aSBoris Brezillon } 74293db446aSBoris Brezillon 74393db446aSBoris Brezillon /* ECC will be calculated automatically, and errors will be detected in 74493db446aSBoris Brezillon * waitfunc. 74593db446aSBoris Brezillon */ 746767eb6fbSBoris Brezillon static int fsl_elbc_write_subpage(struct nand_chip *chip, uint32_t offset, 747767eb6fbSBoris Brezillon uint32_t data_len, const uint8_t *buf, 748767eb6fbSBoris Brezillon int oob_required, int page) 74993db446aSBoris Brezillon { 750767eb6fbSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip); 751767eb6fbSBoris Brezillon 75293db446aSBoris Brezillon nand_prog_page_begin_op(chip, page, 0, NULL, 0); 753c0739d85SBoris Brezillon fsl_elbc_write_buf(chip, buf, mtd->writesize); 754c0739d85SBoris Brezillon fsl_elbc_write_buf(chip, chip->oob_poi, mtd->oobsize); 75593db446aSBoris Brezillon return nand_prog_page_end_op(chip); 75693db446aSBoris Brezillon } 75793db446aSBoris Brezillon 75893db446aSBoris Brezillon static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv) 75993db446aSBoris Brezillon { 76093db446aSBoris Brezillon struct fsl_lbc_ctrl *ctrl = priv->ctrl; 76193db446aSBoris Brezillon struct fsl_lbc_regs __iomem *lbc = ctrl->regs; 76293db446aSBoris Brezillon struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand; 76393db446aSBoris Brezillon struct nand_chip *chip = &priv->chip; 76493db446aSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip); 76593db446aSBoris Brezillon 76693db446aSBoris Brezillon dev_dbg(priv->dev, "eLBC Set Information for bank %d\n", priv->bank); 76793db446aSBoris Brezillon 76893db446aSBoris Brezillon /* Fill in fsl_elbc_mtd structure */ 76993db446aSBoris Brezillon mtd->dev.parent = priv->dev; 77093db446aSBoris Brezillon nand_set_flash_node(chip, priv->dev->of_node); 77193db446aSBoris Brezillon 77293db446aSBoris Brezillon /* set timeout to maximum */ 77393db446aSBoris Brezillon priv->fmr = 15 << FMR_CWTO_SHIFT; 77493db446aSBoris Brezillon if (in_be32(&lbc->bank[priv->bank].or) & OR_FCM_PGS) 77593db446aSBoris Brezillon priv->fmr |= FMR_ECCM; 77693db446aSBoris Brezillon 77793db446aSBoris Brezillon /* fill in nand_chip structure */ 77893db446aSBoris Brezillon /* set up function call table */ 779716bbbabSBoris Brezillon chip->legacy.read_byte = fsl_elbc_read_byte; 780716bbbabSBoris Brezillon chip->legacy.write_buf = fsl_elbc_write_buf; 781716bbbabSBoris Brezillon chip->legacy.read_buf = fsl_elbc_read_buf; 78293db446aSBoris Brezillon chip->select_chip = fsl_elbc_select_chip; 783bf6065c6SBoris Brezillon chip->legacy.cmdfunc = fsl_elbc_cmdfunc; 7848395b753SBoris Brezillon chip->legacy.waitfunc = fsl_elbc_wait; 785b958758eSMiquel Raynal chip->set_features = nand_get_set_features_notsupp; 786b958758eSMiquel Raynal chip->get_features = nand_get_set_features_notsupp; 78793db446aSBoris Brezillon 78893db446aSBoris Brezillon chip->bbt_td = &bbt_main_descr; 78993db446aSBoris Brezillon chip->bbt_md = &bbt_mirror_descr; 79093db446aSBoris Brezillon 79193db446aSBoris Brezillon /* set up nand options */ 79293db446aSBoris Brezillon chip->bbt_options = NAND_BBT_USE_FLASH; 79393db446aSBoris Brezillon 79493db446aSBoris Brezillon chip->controller = &elbc_fcm_ctrl->controller; 79593db446aSBoris Brezillon nand_set_controller_data(chip, priv); 79693db446aSBoris Brezillon 79793db446aSBoris Brezillon chip->ecc.read_page = fsl_elbc_read_page; 79893db446aSBoris Brezillon chip->ecc.write_page = fsl_elbc_write_page; 79993db446aSBoris Brezillon chip->ecc.write_subpage = fsl_elbc_write_subpage; 80093db446aSBoris Brezillon 80193db446aSBoris Brezillon /* If CS Base Register selects full hardware ECC then use it */ 80293db446aSBoris Brezillon if ((in_be32(&lbc->bank[priv->bank].br) & BR_DECC) == 80393db446aSBoris Brezillon BR_DECC_CHK_GEN) { 80493db446aSBoris Brezillon chip->ecc.mode = NAND_ECC_HW; 80593db446aSBoris Brezillon mtd_set_ooblayout(mtd, &fsl_elbc_ooblayout_ops); 80693db446aSBoris Brezillon chip->ecc.size = 512; 80793db446aSBoris Brezillon chip->ecc.bytes = 3; 80893db446aSBoris Brezillon chip->ecc.strength = 1; 80993db446aSBoris Brezillon } else { 81093db446aSBoris Brezillon /* otherwise fall back to default software ECC */ 81193db446aSBoris Brezillon chip->ecc.mode = NAND_ECC_SOFT; 81293db446aSBoris Brezillon chip->ecc.algo = NAND_ECC_HAMMING; 81393db446aSBoris Brezillon } 81493db446aSBoris Brezillon 81593db446aSBoris Brezillon return 0; 81693db446aSBoris Brezillon } 81793db446aSBoris Brezillon 81893db446aSBoris Brezillon static int fsl_elbc_chip_remove(struct fsl_elbc_mtd *priv) 81993db446aSBoris Brezillon { 82093db446aSBoris Brezillon struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; 82193db446aSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(&priv->chip); 82293db446aSBoris Brezillon 82393db446aSBoris Brezillon kfree(mtd->name); 82493db446aSBoris Brezillon 82593db446aSBoris Brezillon if (priv->vbase) 82693db446aSBoris Brezillon iounmap(priv->vbase); 82793db446aSBoris Brezillon 82893db446aSBoris Brezillon elbc_fcm_ctrl->chips[priv->bank] = NULL; 82993db446aSBoris Brezillon kfree(priv); 83093db446aSBoris Brezillon return 0; 83193db446aSBoris Brezillon } 83293db446aSBoris Brezillon 83393db446aSBoris Brezillon static DEFINE_MUTEX(fsl_elbc_nand_mutex); 83493db446aSBoris Brezillon 83593db446aSBoris Brezillon static int fsl_elbc_nand_probe(struct platform_device *pdev) 83693db446aSBoris Brezillon { 83793db446aSBoris Brezillon struct fsl_lbc_regs __iomem *lbc; 83893db446aSBoris Brezillon struct fsl_elbc_mtd *priv; 83993db446aSBoris Brezillon struct resource res; 84093db446aSBoris Brezillon struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl; 84193db446aSBoris Brezillon static const char *part_probe_types[] 84293db446aSBoris Brezillon = { "cmdlinepart", "RedBoot", "ofpart", NULL }; 84393db446aSBoris Brezillon int ret; 84493db446aSBoris Brezillon int bank; 84593db446aSBoris Brezillon struct device *dev; 84693db446aSBoris Brezillon struct device_node *node = pdev->dev.of_node; 84793db446aSBoris Brezillon struct mtd_info *mtd; 84893db446aSBoris Brezillon 84993db446aSBoris Brezillon if (!fsl_lbc_ctrl_dev || !fsl_lbc_ctrl_dev->regs) 85093db446aSBoris Brezillon return -ENODEV; 85193db446aSBoris Brezillon lbc = fsl_lbc_ctrl_dev->regs; 85293db446aSBoris Brezillon dev = fsl_lbc_ctrl_dev->dev; 85393db446aSBoris Brezillon 85493db446aSBoris Brezillon /* get, allocate and map the memory resource */ 85593db446aSBoris Brezillon ret = of_address_to_resource(node, 0, &res); 85693db446aSBoris Brezillon if (ret) { 85793db446aSBoris Brezillon dev_err(dev, "failed to get resource\n"); 85893db446aSBoris Brezillon return ret; 85993db446aSBoris Brezillon } 86093db446aSBoris Brezillon 86193db446aSBoris Brezillon /* find which chip select it is connected to */ 86293db446aSBoris Brezillon for (bank = 0; bank < MAX_BANKS; bank++) 86393db446aSBoris Brezillon if ((in_be32(&lbc->bank[bank].br) & BR_V) && 86493db446aSBoris Brezillon (in_be32(&lbc->bank[bank].br) & BR_MSEL) == BR_MS_FCM && 86593db446aSBoris Brezillon (in_be32(&lbc->bank[bank].br) & 86693db446aSBoris Brezillon in_be32(&lbc->bank[bank].or) & BR_BA) 86793db446aSBoris Brezillon == fsl_lbc_addr(res.start)) 86893db446aSBoris Brezillon break; 86993db446aSBoris Brezillon 87093db446aSBoris Brezillon if (bank >= MAX_BANKS) { 87193db446aSBoris Brezillon dev_err(dev, "address did not match any chip selects\n"); 87293db446aSBoris Brezillon return -ENODEV; 87393db446aSBoris Brezillon } 87493db446aSBoris Brezillon 87593db446aSBoris Brezillon priv = kzalloc(sizeof(*priv), GFP_KERNEL); 87693db446aSBoris Brezillon if (!priv) 87793db446aSBoris Brezillon return -ENOMEM; 87893db446aSBoris Brezillon 87993db446aSBoris Brezillon mutex_lock(&fsl_elbc_nand_mutex); 88093db446aSBoris Brezillon if (!fsl_lbc_ctrl_dev->nand) { 88193db446aSBoris Brezillon elbc_fcm_ctrl = kzalloc(sizeof(*elbc_fcm_ctrl), GFP_KERNEL); 88293db446aSBoris Brezillon if (!elbc_fcm_ctrl) { 88393db446aSBoris Brezillon mutex_unlock(&fsl_elbc_nand_mutex); 88493db446aSBoris Brezillon ret = -ENOMEM; 88593db446aSBoris Brezillon goto err; 88693db446aSBoris Brezillon } 88793db446aSBoris Brezillon elbc_fcm_ctrl->counter++; 88893db446aSBoris Brezillon 8897da45139SMiquel Raynal nand_controller_init(&elbc_fcm_ctrl->controller); 89093db446aSBoris Brezillon fsl_lbc_ctrl_dev->nand = elbc_fcm_ctrl; 89193db446aSBoris Brezillon } else { 89293db446aSBoris Brezillon elbc_fcm_ctrl = fsl_lbc_ctrl_dev->nand; 89393db446aSBoris Brezillon } 89493db446aSBoris Brezillon mutex_unlock(&fsl_elbc_nand_mutex); 89593db446aSBoris Brezillon 89693db446aSBoris Brezillon elbc_fcm_ctrl->chips[bank] = priv; 89793db446aSBoris Brezillon priv->bank = bank; 89893db446aSBoris Brezillon priv->ctrl = fsl_lbc_ctrl_dev; 89993db446aSBoris Brezillon priv->dev = &pdev->dev; 90093db446aSBoris Brezillon dev_set_drvdata(priv->dev, priv); 90193db446aSBoris Brezillon 90293db446aSBoris Brezillon priv->vbase = ioremap(res.start, resource_size(&res)); 90393db446aSBoris Brezillon if (!priv->vbase) { 90493db446aSBoris Brezillon dev_err(dev, "failed to map chip region\n"); 90593db446aSBoris Brezillon ret = -ENOMEM; 90693db446aSBoris Brezillon goto err; 90793db446aSBoris Brezillon } 90893db446aSBoris Brezillon 90993db446aSBoris Brezillon mtd = nand_to_mtd(&priv->chip); 91093db446aSBoris Brezillon mtd->name = kasprintf(GFP_KERNEL, "%llx.flash", (u64)res.start); 91193db446aSBoris Brezillon if (!nand_to_mtd(&priv->chip)->name) { 91293db446aSBoris Brezillon ret = -ENOMEM; 91393db446aSBoris Brezillon goto err; 91493db446aSBoris Brezillon } 91593db446aSBoris Brezillon 91693db446aSBoris Brezillon ret = fsl_elbc_chip_init(priv); 91793db446aSBoris Brezillon if (ret) 91893db446aSBoris Brezillon goto err; 91993db446aSBoris Brezillon 9205bf3e76bSMiquel Raynal priv->chip.controller->ops = &fsl_elbc_controller_ops; 92100ad378fSBoris Brezillon ret = nand_scan(&priv->chip, 1); 92293db446aSBoris Brezillon if (ret) 92393db446aSBoris Brezillon goto err; 92493db446aSBoris Brezillon 92593db446aSBoris Brezillon /* First look for RedBoot table or partitions on the command 92693db446aSBoris Brezillon * line, these take precedence over device tree information */ 92739b77c58SMiquel Raynal ret = mtd_device_parse_register(mtd, part_probe_types, NULL, NULL, 0); 92839b77c58SMiquel Raynal if (ret) 92939b77c58SMiquel Raynal goto cleanup_nand; 93093db446aSBoris Brezillon 93163fa37f0SShreeya Patel pr_info("eLBC NAND device at 0x%llx, bank %d\n", 93293db446aSBoris Brezillon (unsigned long long)res.start, priv->bank); 93339b77c58SMiquel Raynal 93493db446aSBoris Brezillon return 0; 93593db446aSBoris Brezillon 93639b77c58SMiquel Raynal cleanup_nand: 93739b77c58SMiquel Raynal nand_cleanup(&priv->chip); 93893db446aSBoris Brezillon err: 93993db446aSBoris Brezillon fsl_elbc_chip_remove(priv); 94039b77c58SMiquel Raynal 94193db446aSBoris Brezillon return ret; 94293db446aSBoris Brezillon } 94393db446aSBoris Brezillon 94493db446aSBoris Brezillon static int fsl_elbc_nand_remove(struct platform_device *pdev) 94593db446aSBoris Brezillon { 94693db446aSBoris Brezillon struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = fsl_lbc_ctrl_dev->nand; 94793db446aSBoris Brezillon struct fsl_elbc_mtd *priv = dev_get_drvdata(&pdev->dev); 94893db446aSBoris Brezillon 94959ac276fSBoris Brezillon nand_release(&priv->chip); 95093db446aSBoris Brezillon fsl_elbc_chip_remove(priv); 95193db446aSBoris Brezillon 95293db446aSBoris Brezillon mutex_lock(&fsl_elbc_nand_mutex); 95393db446aSBoris Brezillon elbc_fcm_ctrl->counter--; 95493db446aSBoris Brezillon if (!elbc_fcm_ctrl->counter) { 95593db446aSBoris Brezillon fsl_lbc_ctrl_dev->nand = NULL; 95693db446aSBoris Brezillon kfree(elbc_fcm_ctrl); 95793db446aSBoris Brezillon } 95893db446aSBoris Brezillon mutex_unlock(&fsl_elbc_nand_mutex); 95993db446aSBoris Brezillon 96093db446aSBoris Brezillon return 0; 96193db446aSBoris Brezillon 96293db446aSBoris Brezillon } 96393db446aSBoris Brezillon 96493db446aSBoris Brezillon static const struct of_device_id fsl_elbc_nand_match[] = { 96593db446aSBoris Brezillon { .compatible = "fsl,elbc-fcm-nand", }, 96693db446aSBoris Brezillon {} 96793db446aSBoris Brezillon }; 96893db446aSBoris Brezillon MODULE_DEVICE_TABLE(of, fsl_elbc_nand_match); 96993db446aSBoris Brezillon 97093db446aSBoris Brezillon static struct platform_driver fsl_elbc_nand_driver = { 97193db446aSBoris Brezillon .driver = { 97293db446aSBoris Brezillon .name = "fsl,elbc-fcm-nand", 97393db446aSBoris Brezillon .of_match_table = fsl_elbc_nand_match, 97493db446aSBoris Brezillon }, 97593db446aSBoris Brezillon .probe = fsl_elbc_nand_probe, 97693db446aSBoris Brezillon .remove = fsl_elbc_nand_remove, 97793db446aSBoris Brezillon }; 97893db446aSBoris Brezillon 97993db446aSBoris Brezillon module_platform_driver(fsl_elbc_nand_driver); 98093db446aSBoris Brezillon 98193db446aSBoris Brezillon MODULE_LICENSE("GPL"); 98293db446aSBoris Brezillon MODULE_AUTHOR("Freescale"); 98393db446aSBoris Brezillon MODULE_DESCRIPTION("Freescale Enhanced Local Bus Controller MTD NAND driver"); 984