]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
driver/ifc: Add 64KB page support
authorJaiprakash Singh <b44839@freescale.com>
Sat, 21 Mar 2015 02:28:27 +0000 (19:28 -0700)
committerLothar Waßmann <LW@KARO-electronics.de>
Tue, 8 Sep 2015 20:31:12 +0000 (22:31 +0200)
IFC has two register pages.Till IFC version 1.4 each
register page is 4KB each.But IFC ver 2.0 register page
size is 64KB each.IFC regiters structure is break into
two viz FCM and RUNTIME.FCM(Flash control machine) registers
are defined in PAGE0 and controls IFC generic functionality.
RUNTIME registers are defined in PAGE1 and controls NAND and
GPCM funcinality.

FCM and RUNTIME structures defination is common for IFC
version 1.4 and 2.0.

Signed-off-by: Jaiprakash Singh <b44839@freescale.com>
Signed-off-by: York Sun <yorksun@freescale.com>
arch/arm/cpu/armv7/ls102xa/clock.c
arch/arm/cpu/armv8/fsl-lsch3/speed.c
arch/powerpc/cpu/mpc85xx/cpu_init_early.c
arch/powerpc/cpu/mpc85xx/speed.c
board/freescale/bsc9132qds/bsc9132qds.c
board/freescale/c29xpcie/c29xpcie.c
board/freescale/p1010rdb/p1010rdb.c
board/freescale/p1010rdb/spl.c
drivers/mtd/nand/fsl_ifc_nand.c
drivers/mtd/nand/fsl_ifc_spl.c
include/fsl_ifc.h

index 8f80c6175f6a3472bb705a28f4adc30fe7b6e508..7a337e1c5bc434c86ed8ff2dff7a0d935b397d5b 100644 (file)
@@ -20,7 +20,7 @@ void get_sys_info(struct sys_info *sys_info)
 {
        struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
 #ifdef CONFIG_FSL_IFC
-       struct fsl_ifc *ifc_regs = (void *)CONFIG_SYS_IFC_ADDR;
+       struct fsl_ifc ifc_regs = {(void *)CONFIG_SYS_IFC_ADDR, (void *)NULL};
        u32 ccr;
 #endif
        struct ccsr_clk *clk = (void *)(CONFIG_SYS_FSL_LS1_CLK_ADDR);
@@ -74,7 +74,7 @@ void get_sys_info(struct sys_info *sys_info)
        }
 
 #if defined(CONFIG_FSL_IFC)
-       ccr = in_be32(&ifc_regs->ifc_ccr);
+       ccr = in_be32(&ifc_regs.gregs->ifc_ccr);
        ccr = ((ccr & IFC_CCR_CLK_DIV_MASK) >> IFC_CCR_CLK_DIV_SHIFT) + 1;
 
        sys_info->freq_localbus = sys_info->freq_systembus / ccr;
index 2b140cd76f4be1e5dba2beb5f27168ea4c7ca98c..cac4f925a4ec9386f3e230f381f8d9a4769976ae 100644 (file)
@@ -26,7 +26,7 @@ void get_sys_info(struct sys_info *sys_info)
 {
        struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
 #ifdef CONFIG_FSL_IFC
-       struct fsl_ifc *ifc_regs = (void *)CONFIG_SYS_IFC_ADDR;
+       struct fsl_ifc ifc_regs = {(void *)CONFIG_SYS_IFC_ADDR, (void *)NULL};
        u32 ccr;
 #endif
        struct ccsr_clk_cluster_group __iomem *clk_grp[2] = {
@@ -118,7 +118,7 @@ void get_sys_info(struct sys_info *sys_info)
        }
 
 #if defined(CONFIG_FSL_IFC)
-       ccr = in_le32(&ifc_regs->ifc_ccr);
+       ccr = in_le32(&ifc_regs.gregs->ifc_ccr);
        ccr = ((ccr & IFC_CCR_CLK_DIV_MASK) >> IFC_CCR_CLK_DIV_SHIFT) + 1;
 
        sys_info->freq_localbus = sys_info->freq_systembus / ccr;
index 5ca9bf5ff98f53adac99d04c7a6c26fa57fb679f..235a635c22f9d42456523e6f42780c15428353b2 100644 (file)
@@ -15,7 +15,7 @@ DECLARE_GLOBAL_DATA_PTR;
 #ifdef CONFIG_A003399_NOR_WORKAROUND
 void setup_ifc(void)
 {
-       struct fsl_ifc *ifc_regs = (void *)CONFIG_SYS_IFC_ADDR;
+       struct fsl_ifc ifc_regs = {(void *)CONFIG_SYS_IFC_ADDR, (void *)NULL};
        u32 _mas0, _mas1, _mas2, _mas3, _mas7;
        phys_addr_t flash_phys = CONFIG_SYS_FLASH_BASE_PHYS;
 
@@ -70,9 +70,9 @@ void setup_ifc(void)
 #endif
 
        /* Change flash's physical address */
-       ifc_out32(&(ifc_regs->cspr_cs[0].cspr), CONFIG_SYS_CSPR0);
-       ifc_out32(&(ifc_regs->csor_cs[0].csor), CONFIG_SYS_CSOR0);
-       ifc_out32(&(ifc_regs->amask_cs[0].amask), CONFIG_SYS_AMASK0);
+       ifc_out32(&(ifc_regs.gregs->cspr_cs[0].cspr), CONFIG_SYS_CSPR0);
+       ifc_out32(&(ifc_regs.gregs->csor_cs[0].csor), CONFIG_SYS_CSOR0);
+       ifc_out32(&(ifc_regs.gregs->amask_cs[0].amask), CONFIG_SYS_AMASK0);
 
        return ;
 }
index e24b857672d7703958f6084bb93e2f21b85977cf..321ade24fe7d639f1723f2bcb8672167202167c4 100644 (file)
@@ -28,7 +28,7 @@ void get_sys_info(sys_info_t *sys_info)
 {
        volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
 #ifdef CONFIG_FSL_IFC
-       struct fsl_ifc *ifc_regs = (void *)CONFIG_SYS_IFC_ADDR;
+       struct fsl_ifc ifc_regs = {(void *)CONFIG_SYS_IFC_ADDR, (void *)NULL};
        u32 ccr;
 #endif
 #ifdef CONFIG_FSL_CORENET
@@ -597,7 +597,7 @@ void get_sys_info(sys_info_t *sys_info)
 #endif
 
 #if defined(CONFIG_FSL_IFC)
-       ccr = ifc_in32(&ifc_regs->ifc_ccr);
+       ccr = ifc_in32(&ifc_regs.gregs->ifc_ccr);
        ccr = ((ccr & IFC_CCR_CLK_DIV_MASK) >> IFC_CCR_CLK_DIV_SHIFT) + 1;
 
        sys_info->freq_localbus = sys_info->freq_systembus / ccr;
index 36a68dbc4dba95ae0990c9f3a900a4b487f5ee85..586daccb4a0ba16c5a7b04fae1876d90328b5d66 100644 (file)
@@ -36,9 +36,9 @@ DECLARE_GLOBAL_DATA_PTR;
 
 int board_early_init_f(void)
 {
-       struct fsl_ifc *ifc = (void *)CONFIG_SYS_IFC_ADDR;
+       struct fsl_ifc ifc = {(void *)CONFIG_SYS_IFC_ADDR, (void *)NULL};
 
-       setbits_be32(&ifc->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT);
+       setbits_be32(&ifc.gregs->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT);
 
        return 0;
 }
index d75770969b1891f56dea3b077a5e77377999b037..f42d373dafbbb5f6fbb57239bec8a073e204c0e4 100644 (file)
@@ -38,10 +38,10 @@ int checkboard(void)
 
 int board_early_init_f(void)
 {
-       struct fsl_ifc *ifc = (void *)CONFIG_SYS_IFC_ADDR;
+       struct fsl_ifc ifc = {(void *)CONFIG_SYS_IFC_ADDR, (void *)NULL};
 
        /* Clock configuration to access CPLD using IFC(GPCM) */
-       setbits_be32(&ifc->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT);
+       setbits_be32(&ifc.gregs->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT);
 
        return 0;
 }
index 1cf0ab78b71fe992ab454b65d3531f0a3a92a43f..ebffe9a58abca92ec8b0f145130792bbb5abd05e 100644 (file)
@@ -77,10 +77,9 @@ struct cpld_data {
 int board_early_init_f(void)
 {
        ccsr_gpio_t *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR);
-       struct fsl_ifc *ifc = (void *)CONFIG_SYS_IFC_ADDR;
-
+       struct fsl_ifc ifc = {(void *)CONFIG_SYS_IFC_ADDR, (void *)NULL};
        /* Clock configuration to access CPLD using IFC(GPCM) */
-       setbits_be32(&ifc->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT);
+       setbits_be32(&ifc.gregs->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT);
        /*
        * Reset PCIe slots via GPIO4
        */
index 11bd9cfccce6273fdc16abcee79bafe6b003a1d4..ee873b09141c1f02fc75c5131af18be927b61cbb 100644 (file)
@@ -23,12 +23,12 @@ void board_init_f(ulong bootflag)
 {
        u32 plat_ratio;
        ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
-       struct fsl_ifc *ifc = (void *)CONFIG_SYS_IFC_ADDR;
+       struct fsl_ifc ifc = {(void *)CONFIG_SYS_IFC_ADDR, (void *)NULL};
 
        console_init_f();
 
        /* Clock configuration to access CPLD using IFC(GPCM) */
-       setbits_be32(&ifc->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT);
+       setbits_be32(&ifc.gregs->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT);
 
 #ifdef CONFIG_P1010RDB_PB
        setbits_be32(&gur->pmuxcr2, MPC85xx_PMUXCR2_GPIO01_DRVVBUS);
index 28f197ed9e4c176b94107cda232e5503176639b6..79fa88b22f975082bf6edd09cedfec71f4c8ca38 100644 (file)
@@ -46,7 +46,7 @@ struct fsl_ifc_ctrl {
        struct fsl_ifc_mtd *chips[MAX_BANKS];
 
        /* device info */
-       struct fsl_ifc *regs;
+       struct fsl_ifc regs;
        uint8_t __iomem *addr;   /* Address of assigned IFC buffer        */
        unsigned int cs_nand;    /* On which chipsel NAND is connected    */
        unsigned int page;       /* Last page written to / read from      */
@@ -225,7 +225,7 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob)
        struct nand_chip *chip = mtd->priv;
        struct fsl_ifc_mtd *priv = chip->priv;
        struct fsl_ifc_ctrl *ctrl = priv->ctrl;
-       struct fsl_ifc *ifc = ctrl->regs;
+       struct fsl_ifc_runtime *ifc = ctrl->regs.rregs;
        int buf_num;
 
        ctrl->page = page_addr;
@@ -289,7 +289,7 @@ static int fsl_ifc_run_command(struct mtd_info *mtd)
        struct nand_chip *chip = mtd->priv;
        struct fsl_ifc_mtd *priv = chip->priv;
        struct fsl_ifc_ctrl *ctrl = priv->ctrl;
-       struct fsl_ifc *ifc = ctrl->regs;
+       struct fsl_ifc_runtime *ifc = ctrl->regs.rregs;
        u32 timeo = (CONFIG_SYS_HZ * 10) / 1000;
        u32 time_start;
        u32 eccstat[8] = {0};
@@ -369,7 +369,7 @@ static void fsl_ifc_do_read(struct nand_chip *chip,
 {
        struct fsl_ifc_mtd *priv = chip->priv;
        struct fsl_ifc_ctrl *ctrl = priv->ctrl;
-       struct fsl_ifc *ifc = ctrl->regs;
+       struct fsl_ifc_runtime *ifc = ctrl->regs.rregs;
 
        /* Program FIR/IFC_NAND_FCR0 for Small/Large page */
        if (mtd->writesize > 512) {
@@ -407,7 +407,7 @@ static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command,
        struct nand_chip *chip = mtd->priv;
        struct fsl_ifc_mtd *priv = chip->priv;
        struct fsl_ifc_ctrl *ctrl = priv->ctrl;
-       struct fsl_ifc *ifc = ctrl->regs;
+       struct fsl_ifc_runtime *ifc = ctrl->regs.rregs;
 
        /* clear the read buffer */
        ctrl->read_bytes = 0;
@@ -697,7 +697,7 @@ static int fsl_ifc_wait(struct mtd_info *mtd, struct nand_chip *chip)
 {
        struct fsl_ifc_mtd *priv = chip->priv;
        struct fsl_ifc_ctrl *ctrl = priv->ctrl;
-       struct fsl_ifc *ifc = ctrl->regs;
+       struct fsl_ifc_runtime *ifc = ctrl->regs.rregs;
        u32 nand_fsr;
 
        if (ctrl->status != IFC_NAND_EVTER_STAT_OPC)
@@ -754,24 +754,33 @@ static int fsl_ifc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 
 static void fsl_ifc_ctrl_init(void)
 {
+       uint32_t ver = 0;
        ifc_ctrl = kzalloc(sizeof(*ifc_ctrl), GFP_KERNEL);
        if (!ifc_ctrl)
                return;
 
-       ifc_ctrl->regs = IFC_BASE_ADDR;
+       ifc_ctrl->regs.gregs = IFC_FCM_BASE_ADDR;
+
+       ver = ifc_in32(&ifc_ctrl->regs.gregs->ifc_rev);
+       if (ver >= FSL_IFC_V2_0_0)
+               ifc_ctrl->regs.rregs =
+                       (void *)CONFIG_SYS_IFC_ADDR + IFC_RREGS_64KOFFSET;
+       else
+               ifc_ctrl->regs.rregs =
+                       (void *)CONFIG_SYS_IFC_ADDR + IFC_RREGS_4KOFFSET;
 
        /* clear event registers */
-       ifc_out32(&ifc_ctrl->regs->ifc_nand.nand_evter_stat, ~0U);
-       ifc_out32(&ifc_ctrl->regs->ifc_nand.pgrdcmpl_evt_stat, ~0U);
+       ifc_out32(&ifc_ctrl->regs.rregs->ifc_nand.nand_evter_stat, ~0U);
+       ifc_out32(&ifc_ctrl->regs.rregs->ifc_nand.pgrdcmpl_evt_stat, ~0U);
 
        /* Enable error and event for any detected errors */
-       ifc_out32(&ifc_ctrl->regs->ifc_nand.nand_evter_en,
+       ifc_out32(&ifc_ctrl->regs.rregs->ifc_nand.nand_evter_en,
                  IFC_NAND_EVTER_EN_OPC_EN |
                  IFC_NAND_EVTER_EN_PGRDCMPL_EN |
                  IFC_NAND_EVTER_EN_FTOER_EN |
                  IFC_NAND_EVTER_EN_WPER_EN);
 
-       ifc_out32(&ifc_ctrl->regs->ifc_nand.ncfgr, 0x0);
+       ifc_out32(&ifc_ctrl->regs.rregs->ifc_nand.ncfgr, 0x0);
 }
 
 static void fsl_ifc_select_chip(struct mtd_info *mtd, int chip)
@@ -780,7 +789,7 @@ static void fsl_ifc_select_chip(struct mtd_info *mtd, int chip)
 
 static int fsl_ifc_sram_init(uint32_t ver)
 {
-       struct fsl_ifc *ifc = ifc_ctrl->regs;
+       struct fsl_ifc_runtime *ifc = ifc_ctrl->regs.rregs;
        uint32_t cs = 0, csor = 0, csor_8k = 0, csor_ext = 0;
        uint32_t ncfgr = 0;
        u32 timeo = (CONFIG_SYS_HZ * 10) / 1000;
@@ -806,13 +815,13 @@ static int fsl_ifc_sram_init(uint32_t ver)
        cs = ifc_ctrl->cs_nand >> IFC_NAND_CSEL_SHIFT;
 
        /* Save CSOR and CSOR_ext */
-       csor = ifc_in32(&ifc_ctrl->regs->csor_cs[cs].csor);
-       csor_ext = ifc_in32(&ifc_ctrl->regs->csor_cs[cs].csor_ext);
+       csor = ifc_in32(&ifc_ctrl->regs.gregs->csor_cs[cs].csor);
+       csor_ext = ifc_in32(&ifc_ctrl->regs.gregs->csor_cs[cs].csor_ext);
 
        /* chage PageSize 8K and SpareSize 1K*/
        csor_8k = (csor & ~(CSOR_NAND_PGS_MASK)) | 0x0018C000;
-       ifc_out32(&ifc_ctrl->regs->csor_cs[cs].csor, csor_8k);
-       ifc_out32(&ifc_ctrl->regs->csor_cs[cs].csor_ext, 0x0000400);
+       ifc_out32(&ifc_ctrl->regs.gregs->csor_cs[cs].csor, csor_8k);
+       ifc_out32(&ifc_ctrl->regs.gregs->csor_cs[cs].csor_ext, 0x0000400);
 
        /* READID */
        ifc_out32(&ifc->ifc_nand.nand_fir0,
@@ -852,8 +861,8 @@ static int fsl_ifc_sram_init(uint32_t ver)
        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);
+       ifc_out32(&ifc_ctrl->regs.gregs->csor_cs[cs].csor, csor);
+       ifc_out32(&ifc_ctrl->regs.gregs->csor_cs[cs].csor_ext, csor_ext);
 
        return 0;
 }
@@ -864,6 +873,7 @@ static int fsl_ifc_chip_init(int devnum, u8 *addr)
        struct nand_chip *nand;
        struct fsl_ifc_mtd *priv;
        struct nand_ecclayout *layout;
+       struct fsl_ifc_fcm *gregs = NULL;
        uint32_t cspr = 0, csor = 0, ver = 0;
        int ret = 0;
 
@@ -879,14 +889,15 @@ static int fsl_ifc_chip_init(int devnum, u8 *addr)
 
        priv->ctrl = ifc_ctrl;
        priv->vbase = addr;
+       gregs = ifc_ctrl->regs.gregs;
 
        /* Find which chip select it is connected to.
         */
        for (priv->bank = 0; priv->bank < MAX_BANKS; priv->bank++) {
                phys_addr_t phys_addr = virt_to_phys(addr);
 
-               cspr = ifc_in32(&ifc_ctrl->regs->cspr_cs[priv->bank].cspr);
-               csor = ifc_in32(&ifc_ctrl->regs->csor_cs[priv->bank].csor);
+               cspr = ifc_in32(&gregs->cspr_cs[priv->bank].cspr);
+               csor = ifc_in32(&gregs->csor_cs[priv->bank].csor);
 
                if ((cspr & CSPR_V) && (cspr & CSPR_MSEL) == CSPR_MSEL_NAND &&
                    (cspr & CSPR_BA) == CSPR_PHYS_ADDR(phys_addr)) {
@@ -1005,7 +1016,7 @@ static int fsl_ifc_chip_init(int devnum, u8 *addr)
                nand->ecc.mode = NAND_ECC_SOFT;
        }
 
-       ver = ifc_in32(&ifc_ctrl->regs->ifc_rev);
+       ver = ifc_in32(&gregs->ifc_rev);
        if (ver >= FSL_IFC_V1_1_0)
                ret = fsl_ifc_sram_init(ver);
        if (ret)
index fb827c5e74e096a37f71dcbdade8a5a350be6aaf..2fb9fb12c4185adf74fd62c5fd41d15af340756f 100644 (file)
@@ -48,9 +48,23 @@ static inline int check_read_ecc(uchar *buf, u32 *eccstat,
        return 0;
 }
 
+static inline struct fsl_ifc_runtime *runtime_regs_address(void)
+{
+       struct fsl_ifc regs = {(void *)CONFIG_SYS_IFC_ADDR, NULL};
+       int ver = 0;
+
+       ver = ifc_in32(&regs.gregs->ifc_rev);
+       if (ver >= FSL_IFC_V2_0_0)
+               regs.rregs = (void *)CONFIG_SYS_IFC_ADDR + IFC_RREGS_64KOFFSET;
+       else
+               regs.rregs = (void *)CONFIG_SYS_IFC_ADDR + IFC_RREGS_4KOFFSET;
+
+       return regs.rregs;
+}
+
 static inline void nand_wait(uchar *buf, int bufnum, int page_size)
 {
-       struct fsl_ifc *ifc = IFC_BASE_ADDR;
+       struct fsl_ifc_runtime *ifc = runtime_regs_address();
        u32 status;
        u32 eccstat[4];
        int bufperpage = page_size / 512;
@@ -90,7 +104,8 @@ static inline int bad_block(uchar *marker, int port_size)
 
 int nand_spl_load_image(uint32_t offs, unsigned int uboot_size, void *vdst)
 {
-       struct fsl_ifc *ifc = IFC_BASE_ADDR;
+       struct fsl_ifc_fcm *gregs = (void *)CONFIG_SYS_IFC_ADDR;
+       struct fsl_ifc_runtime *ifc = NULL;
        uchar *buf = (uchar *)CONFIG_SYS_NAND_BASE;
        int page_size;
        int port_size;
@@ -107,6 +122,8 @@ int nand_spl_load_image(uint32_t offs, unsigned int uboot_size, void *vdst)
        int pg_no;
        uchar *dst = vdst;
 
+       ifc = runtime_regs_address();
+
        /* Get NAND Flash configuration */
        csor = CONFIG_SYS_NAND_CSOR;
        cspr = CONFIG_SYS_NAND_CSPR;
@@ -130,7 +147,7 @@ int nand_spl_load_image(uint32_t offs, unsigned int uboot_size, void *vdst)
                        bad_marker = 5;
        }
 
-       ver = ifc_in32(&ifc->ifc_rev);
+       ver = ifc_in32(&gregs->ifc_rev);
        if (ver >= FSL_IFC_V2_0_0)
                bufnum_mask = (bufnum_mask * 2) + 1;
 
index 11474b757c39e26a9b1d076e88d72c5df0585c9e..a7ddd5fc88732f45b74c0b3b0cd38a391c966a52 100644 (file)
@@ -790,24 +790,36 @@ extern void print_ifc_regs(void);
 extern void init_early_memctl_regs(void);
 void init_final_memctl_regs(void);
 
-#define IFC_BASE_ADDR ((struct fsl_ifc *)CONFIG_SYS_IFC_ADDR)
-
-#define get_ifc_cspr_ext(i) (ifc_in32(&(IFC_BASE_ADDR)->cspr_cs[i].cspr_ext))
-#define get_ifc_cspr(i) (ifc_in32(&(IFC_BASE_ADDR)->cspr_cs[i].cspr))
-#define get_ifc_csor_ext(i) (ifc_in32(&(IFC_BASE_ADDR)->csor_cs[i].csor_ext))
-#define get_ifc_csor(i) (ifc_in32(&(IFC_BASE_ADDR)->csor_cs[i].csor))
-#define get_ifc_amask(i) (ifc_in32(&(IFC_BASE_ADDR)->amask_cs[i].amask))
-#define get_ifc_ftim(i, j) (ifc_in32(&(IFC_BASE_ADDR)->ftim_cs[i].ftim[j]))
-
-#define set_ifc_cspr_ext(i, v) \
-                       (ifc_out32(&(IFC_BASE_ADDR)->cspr_cs[i].cspr_ext, v))
-#define set_ifc_cspr(i, v) (ifc_out32(&(IFC_BASE_ADDR)->cspr_cs[i].cspr, v))
-#define set_ifc_csor_ext(i, v) \
-                       (ifc_out32(&(IFC_BASE_ADDR)->csor_cs[i].csor_ext, v))
-#define set_ifc_csor(i, v) (ifc_out32(&(IFC_BASE_ADDR)->csor_cs[i].csor, v))
-#define set_ifc_amask(i, v) (ifc_out32(&(IFC_BASE_ADDR)->amask_cs[i].amask, v))
-#define set_ifc_ftim(i, j, v) \
-                       (ifc_out32(&(IFC_BASE_ADDR)->ftim_cs[i].ftim[j], v))
+#define IFC_RREGS_4KOFFSET     (4*1024)
+#define IFC_RREGS_64KOFFSET    (64*1024)
+
+#define IFC_FCM_BASE_ADDR \
+       ((struct fsl_ifc_fcm *)CONFIG_SYS_IFC_ADDR)
+
+#define get_ifc_cspr_ext(i)    \
+               (ifc_in32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr_ext))
+#define get_ifc_cspr(i)                \
+               (ifc_in32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr))
+#define get_ifc_csor_ext(i)    \
+               (ifc_in32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor_ext))
+#define get_ifc_csor(i)                \
+               (ifc_in32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor))
+#define get_ifc_amask(i)       \
+               (ifc_in32(&(IFC_FCM_BASE_ADDR)->amask_cs[i].amask))
+#define get_ifc_ftim(i, j)     \
+               (ifc_in32(&(IFC_FCM_BASE_ADDR)->ftim_cs[i].ftim[j]))
+#define set_ifc_cspr_ext(i, v) \
+               (ifc_out32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr_ext, v))
+#define set_ifc_cspr(i, v)     \
+               (ifc_out32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr, v))
+#define set_ifc_csor_ext(i, v) \
+               (ifc_out32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor_ext, v))
+#define set_ifc_csor(i, v)     \
+               (ifc_out32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor, v))
+#define set_ifc_amask(i, v)    \
+               (ifc_out32(&(IFC_FCM_BASE_ADDR)->amask_cs[i].amask, v))
+#define set_ifc_ftim(i, j, v)  \
+               (ifc_out32(&(IFC_FCM_BASE_ADDR)->ftim_cs[i].ftim[j], v))
 
 enum ifc_chip_sel {
        IFC_CS0,
@@ -869,20 +881,26 @@ struct fsl_ifc_nand {
        u32 nand_evter_en;
        u32 res17[0x2];
        u32 nand_evter_intr_en;
-       u32 res18[0x2];
+       u32 nand_vol_addr_stat;
+       u32 res18;
        u32 nand_erattr0;
        u32 nand_erattr1;
        u32 res19[0x10];
        u32 nand_fsr;
-       u32 res20;
-       u32 nand_eccstat[4];
-       u32 res21[0x20];
+       u32 res20[0x3];
+       u32 nand_eccstat[6];
+       u32 res21[0x1c];
        u32 nanndcr;
        u32 res22[0x2];
        u32 nand_autoboot_trgr;
        u32 res23;
        u32 nand_mdr;
-       u32 res24[0x5C];
+       u32 res24[0x1c];
+       u32 nand_dll_lowcfg0;
+       u32 nand_dll_lowcfg1;
+       u32 res25;
+       u32 nand_dll_lowstat;
+       u32 res26[0x3C];
 };
 
 /*
@@ -917,7 +935,6 @@ struct fsl_ifc_gpcm {
        u32 gpcm_erattr1;
        u32 gpcm_erattr2;
        u32 gpcm_stat;
-       u32 res4[0x1F3];
 };
 
 #ifdef CONFIG_SYS_FSL_IFC_BANK_COUNT
@@ -965,9 +982,11 @@ struct fsl_ifc_ftim {
 };
 
 /*
- * IFC Controller Registers
+ * IFC Controller Global Registers
+ * FCM - Flash control machine
  */
-struct fsl_ifc {
+
+struct fsl_ifc_fcm {
        u32 ifc_rev;
        u32 res1[0x2];
        struct fsl_ifc_cspr cspr_cs[CONFIG_SYS_FSL_IFC_BANK_COUNT];
@@ -979,7 +998,8 @@ struct fsl_ifc {
        struct fsl_ifc_ftim ftim_cs[CONFIG_SYS_FSL_IFC_BANK_COUNT];
        u8 res5[IFC_FTIM_REG_LEN - IFC_FTIM_USED_LEN];
        u32 rb_stat;
-       u32 res6[0x2];
+       u32 rb_map;
+       u32 wp_map;
        u32 ifc_gcr;
        u32 res7[0x2];
        u32 cm_evter_stat;
@@ -993,12 +1013,20 @@ struct fsl_ifc {
        u32 res11[0x2];
        u32 ifc_ccr;
        u32 ifc_csr;
-       u32 res12[0x2EB];
+       u32 ddr_ccr_low;
+};
+
+struct fsl_ifc_runtime {
        struct fsl_ifc_nand ifc_nand;
        struct fsl_ifc_nor ifc_nor;
        struct fsl_ifc_gpcm ifc_gpcm;
 };
 
+struct fsl_ifc {
+       struct fsl_ifc_fcm *gregs;
+       struct fsl_ifc_runtime *rregs;
+};
+
 #ifdef CONFIG_SYS_FSL_ERRATUM_IFC_A002769
 #undef CSPR_MSEL_NOR
 #define CSPR_MSEL_NOR  CSPR_MSEL_GPCM