#define ERR_BYTE 0xFF /* Value returned for read
bytes when read failed */ #define IFC_TIMEOUT_MSECS 1000 /* Maximum timeout to wait
for IFC NAND Machine */
struct fsl_ifc_ctrl;
/* mtd information per set */ struct fsl_ifc_mtd { struct nand_chip chip; struct fsl_ifc_ctrl *ctrl;
struct device *dev; int bank; /* Chip select bank number */ unsignedint bufnum_mask; /* bufnum = page & bufnum_mask */
u8 __iomem *vbase; /* Chip select base virtual address */
};
/* overview of the fsl ifc controller */ struct fsl_ifc_nand_ctrl { struct nand_controller controller; struct fsl_ifc_mtd *chips[FSL_IFC_BANK_COUNT];
void __iomem *addr; /* Address of assigned IFC buffer */ unsignedint page; /* Last page written to / read from */ unsignedint read_bytes;/* Number of bytes read during command */ unsignedint column; /* Saved column from SEQIN */ unsignedint index; /* Pointer to next byte to 'read' */ unsignedint oob; /* Non zero if operating on OOB data */ unsignedint eccread; /* Non zero for a full-page ECC read */ unsignedint counter; /* counter for the initializations */ unsignedint max_bitflips; /* Saved during READ0 cmd */
};
/* * Set up the IFC hardware block and page address fields, and the ifc nand * structure addr field to point to the correct IFC buffer in memory
*/ staticvoid set_addr(struct mtd_info *mtd, int column, int page_addr, int oob)
{ struct nand_chip *chip = mtd_to_nand(mtd); struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); struct fsl_ifc_ctrl *ctrl = priv->ctrl; struct fsl_ifc_runtime __iomem *ifc = ctrl->rregs; int buf_num;
/* wait for command complete flag or timeout */
wait_event_timeout(ctrl->nand_wait, ctrl->nand_stat,
msecs_to_jiffies(IFC_TIMEOUT_MSECS));
/* ctrl->nand_stat will be updated from IRQ context */ if (!ctrl->nand_stat)
dev_err(priv->dev, "Controller is not responding\n"); if (ctrl->nand_stat & IFC_NAND_EVTER_STAT_FTOER)
dev_err(priv->dev, "NAND Flash Timeout Error\n"); if (ctrl->nand_stat & IFC_NAND_EVTER_STAT_WPER)
dev_err(priv->dev, "NAND Flash Write Protect Error\n");
nctrl->max_bitflips = 0;
if (nctrl->eccread) { int errors; int bufnum = nctrl->page & priv->bufnum_mask; int sector_start = bufnum * chip->ecc.steps; int sector_end = sector_start + chip->ecc.steps - 1;
__be32 __iomem *eccstat_regs;
for (i = sector_start; i <= sector_end; i++) { if (i != sector_start && !(i % 4))
eccstat = ifc_in32(&eccstat_regs[i / 4]);
errors = check_read_ecc(mtd, ctrl, eccstat, i);
if (errors == 15) { /* * Uncorrectable error. * We'll check for blank pages later. * * We disable ECCER reporting due to... * erratum IFC-A002770 -- so report it now if we * see an uncorrectable error in ECCSTAT.
*/
ctrl->nand_stat |= IFC_NAND_EVTER_STAT_ECCER; continue;
}
/* clear the read buffer */
ifc_nand_ctrl->read_bytes = 0; if (command != NAND_CMD_PAGEPROG)
ifc_nand_ctrl->index = 0;
switch (command) { /* READ0 read the entire buffer to use hardware ECC. */ case NAND_CMD_READ0:
ifc_out32(0, &ifc->ifc_nand.nand_fbcr);
set_addr(mtd, 0, page_addr, 0);
/* READOOB reads only the OOB because no ECC is performed. */ case NAND_CMD_READOOB:
ifc_out32(mtd->oobsize - column, &ifc->ifc_nand.nand_fbcr);
set_addr(mtd, column, page_addr, 1);
case NAND_CMD_READID: case NAND_CMD_PARAM: { /* * For READID, read 8 bytes that are currently used. * For PARAM, read all 3 copies of 256-bytes pages.
*/ int len = 8; int timing = IFC_FIR_OP_RB; if (command == NAND_CMD_PARAM) {
timing = IFC_FIR_OP_RBCD;
len = 256 * 3;
}
/* SEQIN sets up the addr buffer and all registers except the length */ case NAND_CMD_SEQIN: {
u32 nand_fcr0;
ifc_nand_ctrl->column = column;
ifc_nand_ctrl->oob = 0;
/* PAGEPROG reuses all of the setup from SEQIN and adds the length */ case NAND_CMD_PAGEPROG: { if (ifc_nand_ctrl->oob) {
ifc_out32(ifc_nand_ctrl->index -
ifc_nand_ctrl->column,
&ifc->ifc_nand.nand_fbcr);
} else {
ifc_out32(0, &ifc->ifc_nand.nand_fbcr);
}
/* * The chip always seems to report that it is * write-protected, even when it is not.
*/
addr = ifc_nand_ctrl->addr; if (chip->options & NAND_BUSWIDTH_16)
ifc_out16(ifc_in16(addr) | (NAND_STATUS_WP), addr); else
ifc_out8(ifc_in8(addr) | (NAND_STATUS_WP), addr); return;
}
/* * Read a byte from either the IFC hardware buffer * read function for 8-bit buswidth
*/ static uint8_t fsl_ifc_read_byte(struct nand_chip *chip)
{ struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); unsignedint offset;
/* * If there are still bytes in the IFC buffer, then use the * next byte.
*/ if (ifc_nand_ctrl->index < ifc_nand_ctrl->read_bytes) {
offset = ifc_nand_ctrl->index++; return ifc_in8(ifc_nand_ctrl->addr + offset);
}
dev_err(priv->dev, "%s: beyond end of buffer\n", __func__); return ERR_BYTE;
}
/* * Read two bytes from the IFC hardware buffer * read function for 16-bit buswith
*/ static uint8_t fsl_ifc_read_byte16(struct nand_chip *chip)
{ struct fsl_ifc_mtd *priv = nand_get_controller_data(chip);
uint16_t data;
/* * If there are still bytes in the IFC buffer, then use the * next byte.
*/ if (ifc_nand_ctrl->index < ifc_nand_ctrl->read_bytes) {
data = ifc_in16(ifc_nand_ctrl->addr + ifc_nand_ctrl->index);
ifc_nand_ctrl->index += 2; return (uint8_t) data;
}
dev_err(priv->dev, "%s: beyond end of buffer\n", __func__); return ERR_BYTE;
}
/* * Read from the IFC Controller Data Buffer
*/ staticvoid fsl_ifc_read_buf(struct nand_chip *chip, u8 *buf, int len)
{ struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); int avail;
if (len < 0) {
dev_err(priv->dev, "%s: len %d bytes", __func__, len); return;
}
if (len > avail)
dev_err(priv->dev, "%s: beyond end of buffer (%d requested, %d available)\n",
__func__, len, avail);
}
/* * This function is called after Program and Erase Operations to * check for success or failure.
*/ staticint fsl_ifc_wait(struct nand_chip *chip)
{ struct mtd_info *mtd = nand_to_mtd(chip); struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); struct fsl_ifc_ctrl *ctrl = priv->ctrl; struct fsl_ifc_runtime __iomem *ifc = ctrl->rregs;
u32 nand_fsr; int status;
/* Use READ_STATUS command, but wait for the device to be ready */
ifc_out32((IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
(IFC_FIR_OP_RDSTAT << IFC_NAND_FIR0_OP1_SHIFT),
&ifc->ifc_nand.nand_fir0);
ifc_out32(NAND_CMD_STATUS << IFC_NAND_FCR0_CMD0_SHIFT,
&ifc->ifc_nand.nand_fcr0);
ifc_out32(1, &ifc->ifc_nand.nand_fbcr);
set_addr(mtd, 0, 0, 0);
ifc_nand_ctrl->read_bytes = 1;
fsl_ifc_run_command(mtd);
nand_fsr = ifc_in32(&ifc->ifc_nand.nand_fsr);
status = nand_fsr >> 24; /* * The chip always seems to report that it is * write-protected, even when it is not.
*/ return status | NAND_STATUS_WP;
}
/* * The controller does not check for bitflips in erased pages, * therefore software must check instead.
*/ staticint check_erased_page(struct nand_chip *chip, u8 *buf)
{ struct mtd_info *mtd = nand_to_mtd(chip);
u8 *ecc = chip->oob_poi; constint ecc_size = chip->ecc.bytes; constint pkt_size = chip->ecc.size; int i, res, bitflips = 0; struct mtd_oob_region oobregion = { };
nand_read_page_op(chip, page, 0, buf, mtd->writesize); if (oob_required)
fsl_ifc_read_buf(chip, chip->oob_poi, mtd->oobsize);
if (ctrl->nand_stat & IFC_NAND_EVTER_STAT_ECCER) { if (!oob_required)
fsl_ifc_read_buf(chip, chip->oob_poi, mtd->oobsize);
return check_erased_page(chip, buf);
}
if (ctrl->nand_stat != IFC_NAND_EVTER_STAT_OPC)
mtd->ecc_stats.failed++;
return nctrl->max_bitflips;
}
/* ECC will be calculated automatically, and errors will be detected in * waitfunc.
*/ staticint fsl_ifc_write_page(struct nand_chip *chip, const uint8_t *buf, int oob_required, int page)
{ struct mtd_info *mtd = nand_to_mtd(chip);
/* Must also set CSOR_NAND_ECC_ENC_EN if DEC_EN set */ if (csor & CSOR_NAND_ECC_DEC_EN) {
chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
mtd_set_ooblayout(mtd, &fsl_ifc_ooblayout_ops);
/* Fill in fsl_ifc_mtd structure */
mtd->dev.parent = priv->dev;
nand_set_flash_node(chip, priv->dev->of_node);
/* fill in nand_chip structure */ /* set up function call table */ if ((ifc_in32(&ifc_global->cspr_cs[priv->bank].cspr))
& CSPR_PORT_SIZE_16)
chip->legacy.read_byte = fsl_ifc_read_byte16; else
chip->legacy.read_byte = fsl_ifc_read_byte;
ret = fsl_ifc_sram_init(priv); if (ret) return ret;
/* * As IFC version 2.0.0 has 16KB of internal SRAM as compared to older * versions which had 8KB. Hence bufnum mask needs to be updated.
*/ if (ctrl->version >= FSL_IFC_VERSION_2_0_0)
priv->bufnum_mask = (priv->bufnum_mask * 2) + 1;
if (!fsl_ifc_ctrl_dev || !fsl_ifc_ctrl_dev->rregs) return -ENODEV;
ifc = fsl_ifc_ctrl_dev->rregs;
/* get, allocate and map the memory resource */
ret = of_address_to_resource(node, 0, &res); if (ret) {
dev_err(&dev->dev, "%s: failed to get resource\n", __func__); return ret;
}
/* find which chip select it is connected to */ for (bank = 0; bank < fsl_ifc_ctrl_dev->banks; bank++) { if (match_bank(fsl_ifc_ctrl_dev->gregs, bank, res.start)) break;
}
if (bank >= fsl_ifc_ctrl_dev->banks) {
dev_err(&dev->dev, "%s: address did not match any chip selects\n",
__func__); return -ENODEV;
}
priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM;
mutex_lock(&fsl_ifc_nand_mutex); if (!fsl_ifc_ctrl_dev->nand) {
ifc_nand_ctrl = kzalloc(sizeof(*ifc_nand_ctrl), GFP_KERNEL); if (!ifc_nand_ctrl) {
mutex_unlock(&fsl_ifc_nand_mutex); return -ENOMEM;
}
mtd = nand_to_mtd(&priv->chip);
mtd->name = kasprintf(GFP_KERNEL, "%llx.flash", (u64)res.start); if (!mtd->name) {
ret = -ENOMEM; goto err;
}
ret = fsl_ifc_chip_init(priv); if (ret) goto err;
priv->chip.controller->ops = &fsl_ifc_controller_ops;
ret = nand_scan(&priv->chip, 1); if (ret) goto err;
/* First look for RedBoot table or partitions on the command
* line, these take precedence over device tree information */
ret = mtd_device_parse_register(mtd, part_probe_types, NULL, NULL, 0); if (ret) goto cleanup_nand;
dev_info(priv->dev, "IFC NAND device at 0x%llx, bank %d\n",
(unsignedlonglong)res.start, priv->bank);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.