#include <asm/errno.h>
#include <fsl_ifc.h>
-#define FSL_IFC_V1_1_0 0x01010000
-#define MAX_BANKS 4
+#ifndef CONFIG_SYS_FSL_IFC_BANK_COUNT
+#define CONFIG_SYS_FSL_IFC_BANK_COUNT 4
+#endif
+
+#define MAX_BANKS CONFIG_SYS_FSL_IFC_BANK_COUNT
#define ERR_BYTE 0xFF /* Value returned for read bytes
when read failed */
-#define IFC_TIMEOUT_MSECS 10 /* Maximum number of mSecs to wait for IFC
- NAND Machine */
struct fsl_ifc_ctrl;
struct fsl_ifc_mtd *priv = chip->priv;
struct fsl_ifc_ctrl *ctrl = priv->ctrl;
struct fsl_ifc *ifc = ctrl->regs;
- long long end_tick;
- u32 eccstat[4];
+ u32 timeo = (CONFIG_SYS_HZ * 10) / 1000;
+ u32 time_start;
+ u32 eccstat[4] = {0};
int i;
/* set the chip select for NAND Transaction */
IFC_NAND_SEQ_STRT_FIR_STRT);
/* wait for NAND Machine complete flag or timeout */
- end_tick = usec2ticks(IFC_TIMEOUT_MSECS * 1000) + get_ticks();
+ time_start = get_timer(0);
- while (end_tick > get_ticks()) {
+ while (get_timer(time_start) < timeo) {
ctrl->status = ifc_in32(&ifc->ifc_nand.nand_evter_stat);
if (ctrl->status & IFC_NAND_EVTER_STAT_OPC)
__func__, len, avail);
}
+#if defined(CONFIG_MTD_NAND_VERIFY_WRITE)
/*
* Verify buffer against the IFC Controller Data Buffer
*/
ctrl->index += len;
return i == len && ctrl->status == IFC_NAND_EVTER_STAT_OPC ? 0 : -EIO;
}
+#endif
/* This function is called after Program and Erase Operations to
* check for success or failure.
{
}
-static void fsl_ifc_sram_init(void)
+static int fsl_ifc_sram_init(uint32_t ver)
{
struct fsl_ifc *ifc = ifc_ctrl->regs;
uint32_t cs = 0, csor = 0, csor_8k = 0, csor_ext = 0;
- long long end_tick;
+ uint32_t ncfgr = 0;
+ u32 timeo = (CONFIG_SYS_HZ * 10) / 1000;
+ u32 time_start;
+
+ if (ver > FSL_IFC_V1_1_0) {
+ ncfgr = ifc_in32(&ifc->ifc_nand.ncfgr);
+ ifc_out32(&ifc->ifc_nand.ncfgr, ncfgr | IFC_NAND_SRAM_INIT_EN);
+
+ /* wait for SRAM_INIT bit to be clear or timeout */
+ time_start = get_timer(0);
+ while (get_timer(time_start) < timeo) {
+ ifc_ctrl->status =
+ ifc_in32(&ifc->ifc_nand.nand_evter_stat);
+
+ if (!(ifc_ctrl->status & IFC_NAND_SRAM_INIT_EN))
+ return 0;
+ }
+ printf("fsl-ifc: Failed to Initialise SRAM\n");
+ return 1;
+ }
cs = ifc_ctrl->cs_nand >> IFC_NAND_CSEL_SHIFT;
/* start read seq */
ifc_out32(&ifc->ifc_nand.nandseq_strt, IFC_NAND_SEQ_STRT_FIR_STRT);
- /* wait for NAND Machine complete flag or timeout */
- end_tick = usec2ticks(IFC_TIMEOUT_MSECS * 1000) + get_ticks();
+ time_start = get_timer(0);
- while (end_tick > get_ticks()) {
+ while (get_timer(time_start) < timeo) {
ifc_ctrl->status = ifc_in32(&ifc->ifc_nand.nand_evter_stat);
if (ifc_ctrl->status & IFC_NAND_EVTER_STAT_OPC)
break;
}
+ if (ifc_ctrl->status != IFC_NAND_EVTER_STAT_OPC) {
+ printf("fsl-ifc: Failed to Initialise SRAM\n");
+ return 1;
+ }
+
ifc_out32(&ifc->ifc_nand.nand_evter_stat, ifc_ctrl->status);
/* Restore CSOR and CSOR_ext */
ifc_out32(&ifc_ctrl->regs->csor_cs[cs].csor, csor);
ifc_out32(&ifc_ctrl->regs->csor_cs[cs].csor_ext, csor_ext);
+
+ return 0;
}
static int fsl_ifc_chip_init(int devnum, u8 *addr)
struct fsl_ifc_mtd *priv;
struct nand_ecclayout *layout;
uint32_t cspr = 0, csor = 0, ver = 0;
- int ret;
+ int ret = 0;
if (!ifc_ctrl) {
fsl_ifc_ctrl_init();
nand->write_buf = fsl_ifc_write_buf;
nand->read_buf = fsl_ifc_read_buf;
+#if defined(CONFIG_MTD_NAND_VERIFY_WRITE)
nand->verify_buf = fsl_ifc_verify_buf;
+#endif
nand->select_chip = fsl_ifc_select_chip;
nand->cmdfunc = fsl_ifc_cmdfunc;
nand->waitfunc = fsl_ifc_wait;
}
ver = ifc_in32(&ifc_ctrl->regs->ifc_rev);
- if (ver == FSL_IFC_V1_1_0)
- fsl_ifc_sram_init();
+ if (ver >= FSL_IFC_V1_1_0)
+ ret = fsl_ifc_sram_init(ver);
+ if (ret)
+ return ret;
+
+ if (ver >= FSL_IFC_V2_0_0)
+ priv->bufnum_mask = (priv->bufnum_mask * 2) + 1;
ret = nand_scan_ident(mtd, 1, NULL);
if (ret)