@@ -76,15 +76,17 @@ struct fsl_elbc_ctrl {
/* device info */
fsl_lbc_t *regs;
- u8 __iomem *addr; /* Address of assigned FCM buffer */
- unsigned int page; /* Last page written to / read from */
- unsigned int read_bytes; /* Number of bytes read during command */
- unsigned int column; /* Saved column from SEQIN */
- unsigned int index; /* Pointer to next byte to 'read' */
- unsigned int status; /* status read from LTESR after last op */
- 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 */
+ u8 __iomem *addr; /* Address of assigned FCM buffer */
+ unsigned int page; /* Last page written to / read from */
+ unsigned int read_bytes; /* Number of bytes read during command */
+ unsigned int column; /* Saved column from SEQIN */
+ unsigned int index; /* Pointer to next byte to 'read' */
+ unsigned int status; /* status read from LTESR after last op */
+ 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 */
+ uint8_t *buffer; /* Just used when pagesize is greater */
+ /* than FCM RAM 2K limitation */
};
/* These map to the positions used by the FCM hardware ECC generator */
@@ -131,6 +133,10 @@ static struct nand_bbt_descr largepage_memorybased = {
.pattern = scan_ff_pattern,
};
+static u8 migrated_pattern[] = { 0x61, 0xa1, 0x87, 0xf0 };
+#define BADBLOCK_MIGRATED_OFF 1
+#define BADBLOCK_MIGRATED_MB 3
+
/*
* ELBC may use HW ECC, so that OOB offsets, that NAND core uses for bbt,
* interfere with ECC positions, that's why we implement our own descriptors.
@@ -159,6 +165,35 @@ 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 */
+ dst = ctrl->buffer + (oob ? mtd->writesize : 0) + subpage * len;
+ 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;
+
+ src = ctrl->buffer + (oob ? mtd->writesize : 0) + subpage * len;
+ dst = ctrl->addr + (oob ? 2048 : 0);
+ memcpy_toio(dst, src, len);
+ /* See the in_8() in fsl_elbc_write_buf() */
+ in_8(ctrl->addr);
+}
+
/*=================================*/
/*
@@ -194,7 +229,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), "