#ifdef CONFIG_SYS_FSL_DDR4
        /* tXP=max(4nCK, 6ns) */
        int txp = max((int)mclk_ps * 4, 6000); /* unit=ps */
-       trwt_mclk = 2;
+       unsigned int data_rate = get_ddr_freq(ctrl_num);
+
+       /* for faster clock, need more time for data setup */
+       trwt_mclk = (data_rate/1000000 > 1900) ? 3 : 2;
        twrt_mclk = 1;
        act_pd_exit_mclk = picos_to_mclk(ctrl_num, txp);
        pre_pd_exit_mclk = act_pd_exit_mclk;
         */
        txp = max((int)mclk_ps * 3, (mclk_ps > 1540 ? 7500 : 6000));
 
-       ip_rev = fsl_ddr_get_version();
+       ip_rev = fsl_ddr_get_version(ctrl_num);
        if (ip_rev >= 0x40700) {
                /*
                 * MRS_CYC = max(tMRD, tMOD)
         * we need set extend bit for it at
         * TIMING_CFG_3[EXT_CASLAT]
         */
-       if (fsl_ddr_get_version() <= 0x40400)
+       if (fsl_ddr_get_version(ctrl_num) <= 0x40400)
                caslat_ctrl = 2 * cas_latency - 1;
        else
                caslat_ctrl = (cas_latency - 1) << 1;
        unsigned short esdmode4 = 0;    /* Extended SDRAM mode 4 */
        unsigned short esdmode5;        /* Extended SDRAM mode 5 */
 
-       esdmode5 = 0x00000400;          /* Data mask enabled */
+       esdmode5 = 0x00000500;          /* Data mask enabled */
 
        ddr->ddr_sdram_mode_9 = (0
                                 | ((esdmode4 & 0xffff) << 16)
                                 | ((esdmode5 & 0xffff) << 0)
                                );
+
+       /* only mode_9 use 0x500, others use 0x400 */
+       esdmode5 = 0x00000400;          /* Data mask enabled */
+
        debug("FSLDDR: ddr_sdram_mode_9) = 0x%08x\n", ddr->ddr_sdram_mode_9);
        if (unq_mrs_en) {       /* unique mode registers are supported */
                for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
        set_ddr_cdr1(ddr, popts);
        set_ddr_cdr2(ddr, popts);
        set_ddr_sdram_cfg(ddr, popts, common_dimm);
-       ip_rev = fsl_ddr_get_version();
+       ip_rev = fsl_ddr_get_version(ctrl_num);
        if (ip_rev > 0x40400)
                unq_mrs_en = 1;
 
 
 
 #define DIMM_PARM(x) {#x, offsetof(dimm_params_t, x), \
        sizeof((dimm_params_t *)0)->x, 0}
+#define DIMM_PARM_HEX(x) {#x, offsetof(dimm_params_t, x), \
+       sizeof((dimm_params_t *)0)->x, 1}
 
 static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo,
                                   unsigned int ctrl_num,
                DIMM_PARM(primary_sdram_width),
                DIMM_PARM(ec_sdram_width),
                DIMM_PARM(registered_dimm),
+               DIMM_PARM(mirrored_dimm),
                DIMM_PARM(device_width),
 
                DIMM_PARM(n_row_addr),
                DIMM_PARM(tdqsq_max_ps),
                DIMM_PARM(tqhs_ps),
 #endif
-
+#ifdef CONFIG_SYS_FSL_DDR4
+               DIMM_PARM_HEX(dq_mapping[0]),
+               DIMM_PARM_HEX(dq_mapping[1]),
+               DIMM_PARM_HEX(dq_mapping[2]),
+               DIMM_PARM_HEX(dq_mapping[3]),
+               DIMM_PARM_HEX(dq_mapping[4]),
+               DIMM_PARM_HEX(dq_mapping[5]),
+               DIMM_PARM_HEX(dq_mapping[6]),
+               DIMM_PARM_HEX(dq_mapping[7]),
+               DIMM_PARM_HEX(dq_mapping[8]),
+               DIMM_PARM_HEX(dq_mapping[9]),
+               DIMM_PARM_HEX(dq_mapping[10]),
+               DIMM_PARM_HEX(dq_mapping[11]),
+               DIMM_PARM_HEX(dq_mapping[12]),
+               DIMM_PARM_HEX(dq_mapping[13]),
+               DIMM_PARM_HEX(dq_mapping[14]),
+               DIMM_PARM_HEX(dq_mapping[15]),
+               DIMM_PARM_HEX(dq_mapping[16]),
+               DIMM_PARM_HEX(dq_mapping[17]),
+               DIMM_PARM(dq_mapping_ors),
+#endif
                DIMM_PARM(rank_density),
                DIMM_PARM(capacity),
                DIMM_PARM(base_address),
                DIMM_PARM(primary_sdram_width),
                DIMM_PARM(ec_sdram_width),
                DIMM_PARM(registered_dimm),
+               DIMM_PARM(mirrored_dimm),
                DIMM_PARM(device_width),
 
                DIMM_PARM(n_row_addr),
                DIMM_PARM(tckmax_ps),
 
                DIMM_PARM(caslat_x),
+               DIMM_PARM_HEX(caslat_x),
                DIMM_PARM(taa_ps),
                DIMM_PARM(caslat_x_minus_1),
                DIMM_PARM(caslat_x_minus_2),
                DIMM_PARM(trcd_ps),
                DIMM_PARM(trp_ps),
                DIMM_PARM(tras_ps),
+#if defined(CONFIG_SYS_FSL_DDR4) || defined(CONFIG_SYS_FSL_DDR3)
+               DIMM_PARM(tfaw_ps),
+#endif
 #ifdef CONFIG_SYS_FSL_DDR4
                DIMM_PARM(trfc1_ps),
                DIMM_PARM(trfc2_ps),
                DIMM_PARM(tdh_ps),
                DIMM_PARM(tdqsq_max_ps),
                DIMM_PARM(tqhs_ps),
+#endif
+#ifdef CONFIG_SYS_FSL_DDR4
+               DIMM_PARM_HEX(dq_mapping[0]),
+               DIMM_PARM_HEX(dq_mapping[1]),
+               DIMM_PARM_HEX(dq_mapping[2]),
+               DIMM_PARM_HEX(dq_mapping[3]),
+               DIMM_PARM_HEX(dq_mapping[4]),
+               DIMM_PARM_HEX(dq_mapping[5]),
+               DIMM_PARM_HEX(dq_mapping[6]),
+               DIMM_PARM_HEX(dq_mapping[7]),
+               DIMM_PARM_HEX(dq_mapping[8]),
+               DIMM_PARM_HEX(dq_mapping[9]),
+               DIMM_PARM_HEX(dq_mapping[10]),
+               DIMM_PARM_HEX(dq_mapping[11]),
+               DIMM_PARM_HEX(dq_mapping[12]),
+               DIMM_PARM_HEX(dq_mapping[13]),
+               DIMM_PARM_HEX(dq_mapping[14]),
+               DIMM_PARM_HEX(dq_mapping[15]),
+               DIMM_PARM_HEX(dq_mapping[16]),
+               DIMM_PARM_HEX(dq_mapping[17]),
+               DIMM_PARM(dq_mapping_ors),
 #endif
        };
        static const unsigned int n_opts = ARRAY_SIZE(options);
 
 
 #define ULL_8FS 0xFFFFFFFFULL
 
-u32 fsl_ddr_get_version(void)
+u32 fsl_ddr_get_version(unsigned int ctrl_num)
 {
        struct ccsr_ddr __iomem *ddr;
        u32 ver_major_minor_errata;
 
-       ddr = (void *)_DDR_ADDR;
+       switch (ctrl_num) {
+       case 0:
+               ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
+               break;
+#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
+       case 1:
+               ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR;
+               break;
+#endif
+#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
+       case 2:
+               ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR;
+               break;
+#endif
+#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
+       case 3:
+               ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR;
+               break;
+#endif
+       default:
+               printf("%s unexpected ctrl_num = %u\n", __func__, ctrl_num);
+               return 0;
+       }
        ver_major_minor_errata = (ddr_in32(&ddr->ip_rev1) & 0xFFFF) << 8;
        ver_major_minor_errata |= (ddr_in32(&ddr->ip_rev2) & 0xFF00) >> 8;
 
 
        /* Calculate CAS latency based on timing cfg values */
        cas_lat = ((ddr_in32(&ddr->timing_cfg_1) >> 16) & 0xf);
-       if (fsl_ddr_get_version() <= 0x40400)
+       if (fsl_ddr_get_version(0) <= 0x40400)
                cas_lat += 1;
        else
                cas_lat += 2;