{
        struct mtk_nfc *nfc = nand_get_controller_data(chip);
        const struct nand_sdr_timings *timings;
-       u32 rate, tpoecs, tprecs, tc2r, tw2r, twh, twst, trlt;
+       u32 rate, tpoecs, tprecs, tc2r, tw2r, twh, twst = 0, trlt = 0;
+       u32 thold;
 
        timings = nand_get_sdr_timings(conf);
        if (IS_ERR(timings))
        twh = DIV_ROUND_UP(twh * rate, 1000000) - 1;
        twh &= 0xf;
 
-       twst = timings->tWP_min / 1000;
+       /* Calculate real WE#/RE# hold time in nanosecond */
+       thold = (twh + 1) * 1000000 / rate;
+       /* nanosecond to picosecond */
+       thold *= 1000;
+
+       /*
+        * WE# low level time should be expaned to meet WE# pulse time
+        * and WE# cycle time at the same time.
+        */
+       if (thold < timings->tWC_min)
+               twst = timings->tWC_min - thold;
+       twst = max(timings->tWP_min, twst) / 1000;
        twst = DIV_ROUND_UP(twst * rate, 1000000) - 1;
        twst &= 0xf;
 
-       trlt = max(timings->tREA_max, timings->tRP_min) / 1000;
+       /*
+        * RE# low level time should be expaned to meet RE# pulse time,
+        * RE# access time and RE# cycle time at the same time.
+        */
+       if (thold < timings->tRC_min)
+               trlt = timings->tRC_min - thold;
+       trlt = max3(trlt, timings->tREA_max, timings->tRP_min) / 1000;
        trlt = DIV_ROUND_UP(trlt * rate, 1000000) - 1;
        trlt &= 0xf;