}
 
 #define CT2_NFC_MAX_DELAY      1000
+#define CT2_NFC_VER_VALID      0x143
+#define BFA_IOC_PLL_POLL       1000000
+
+static bfa_boolean_t
+bfa_ioc_ct2_nfc_halted(void __iomem *rb)
+{
+       u32     r32;
+
+       r32 = readl(rb + CT2_NFC_CSR_SET_REG);
+       if (r32 & __NFC_CONTROLLER_HALTED)
+               return BFA_TRUE;
+
+       return BFA_FALSE;
+}
+
+static void
+bfa_ioc_ct2_nfc_resume(void __iomem *rb)
+{
+       u32     r32;
+       int i;
+
+       writel(__HALT_NFC_CONTROLLER, rb + CT2_NFC_CSR_CLR_REG);
+       for (i = 0; i < CT2_NFC_MAX_DELAY; i++) {
+               r32 = readl(rb + CT2_NFC_CSR_SET_REG);
+               if (!(r32 & __NFC_CONTROLLER_HALTED))
+                       return;
+               udelay(1000);
+       }
+       WARN_ON(1);
+}
+
 bfa_status_t
 bfa_ioc_ct2_pll_init(void __iomem *rb, enum bfi_asic_mode mode)
 {
-       u32     wgn, r32;
-       int i;
+       u32 wgn, r32, nfc_ver, i;
 
-       /*
-        * Initialize PLL if not already done by NFC
-        */
        wgn = readl(rb + CT2_WGN_STATUS);
-       if (!(wgn & __GLBL_PF_VF_CFG_RDY)) {
+       nfc_ver = readl(rb + CT2_RSC_GPR15_REG);
+
+       if ((wgn == (__A2T_AHB_LOAD | __WGN_READY)) &&
+           (nfc_ver >= CT2_NFC_VER_VALID)) {
+               if (bfa_ioc_ct2_nfc_halted(rb))
+                       bfa_ioc_ct2_nfc_resume(rb);
+
+               writel(__RESET_AND_START_SCLK_LCLK_PLLS,
+                      rb + CT2_CSI_FW_CTL_SET_REG);
+
+               for (i = 0; i < BFA_IOC_PLL_POLL; i++) {
+                       r32 = readl(rb + CT2_APP_PLL_LCLK_CTL_REG);
+                       if (r32 & __RESET_AND_START_SCLK_LCLK_PLLS)
+                               break;
+               }
+
+               WARN_ON(!(r32 & __RESET_AND_START_SCLK_LCLK_PLLS));
+
+               for (i = 0; i < BFA_IOC_PLL_POLL; i++) {
+                       r32 = readl(rb + CT2_APP_PLL_LCLK_CTL_REG);
+                       if (!(r32 & __RESET_AND_START_SCLK_LCLK_PLLS))
+                               break;
+               }
+
+               WARN_ON(r32 & __RESET_AND_START_SCLK_LCLK_PLLS);
+               udelay(1000);
+
+               r32 = readl(rb + CT2_CSI_FW_CTL_REG);
+               WARN_ON(r32 & __RESET_AND_START_SCLK_LCLK_PLLS);
+       } else {
                writel(__HALT_NFC_CONTROLLER, rb + CT2_NFC_CSR_SET_REG);
                for (i = 0; i < CT2_NFC_MAX_DELAY; i++) {
                        r32 = readl(rb + CT2_NFC_CSR_SET_REG);
                                break;
                        udelay(1000);
                }
-       }
 
-       /*
-        * Mask the interrupts and clear any
-        * pending interrupts.
-        */
-       writel(1, (rb + CT2_LPU0_HOSTFN_MBOX0_MSK));
-       writel(1, (rb + CT2_LPU1_HOSTFN_MBOX0_MSK));
-
-       r32 = readl((rb + CT2_LPU0_HOSTFN_CMD_STAT));
-       if (r32 == 1) {
-               writel(1, (rb + CT2_LPU0_HOSTFN_CMD_STAT));
-               readl((rb + CT2_LPU0_HOSTFN_CMD_STAT));
+               bfa_ioc_ct2_mac_reset(rb);
+               bfa_ioc_ct2_sclk_init(rb);
+               bfa_ioc_ct2_lclk_init(rb);
+
+               /*
+                * release soft reset on s_clk & l_clk
+                */
+               r32 = readl(rb + CT2_APP_PLL_SCLK_CTL_REG);
+               writel(r32 & ~__APP_PLL_SCLK_LOGIC_SOFT_RESET,
+                      (rb + CT2_APP_PLL_SCLK_CTL_REG));
+
+               /*
+                * release soft reset on s_clk & l_clk
+                */
+               r32 = readl(rb + CT2_APP_PLL_LCLK_CTL_REG);
+               writel(r32 & ~__APP_PLL_LCLK_LOGIC_SOFT_RESET,
+                     (rb + CT2_APP_PLL_LCLK_CTL_REG));
        }
-       r32 = readl((rb + CT2_LPU1_HOSTFN_CMD_STAT));
-       if (r32 == 1) {
-               writel(1, (rb + CT2_LPU1_HOSTFN_CMD_STAT));
-               readl((rb + CT2_LPU1_HOSTFN_CMD_STAT));
-       }
-
-       bfa_ioc_ct2_mac_reset(rb);
-       bfa_ioc_ct2_sclk_init(rb);
-       bfa_ioc_ct2_lclk_init(rb);
-
-       /*
-        * release soft reset on s_clk & l_clk
-        */
-       r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG));
-       writel(r32 & ~__APP_PLL_SCLK_LOGIC_SOFT_RESET,
-               (rb + CT2_APP_PLL_SCLK_CTL_REG));
-
-       /*
-        * release soft reset on s_clk & l_clk
-        */
-       r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG));
-       writel(r32 & ~__APP_PLL_LCLK_LOGIC_SOFT_RESET,
-               (rb + CT2_APP_PLL_LCLK_CTL_REG));
 
        /*
         * Announce flash device presence, if flash was corrupted.
         */
        if (wgn == (__WGN_READY | __GLBL_PF_VF_CFG_RDY)) {
-               r32 = readl((rb + PSS_GPIO_OUT_REG));
+               r32 = readl(rb + PSS_GPIO_OUT_REG);
                writel(r32 & ~1, (rb + PSS_GPIO_OUT_REG));
-               r32 = readl((rb + PSS_GPIO_OE_REG));
+               r32 = readl(rb + PSS_GPIO_OE_REG);
                writel(r32 | 1, (rb + PSS_GPIO_OE_REG));
        }
 
+       /*
+        * Mask the interrupts and clear any
+        * pending interrupts.
+        */
+       writel(1, (rb + CT2_LPU0_HOSTFN_MBOX0_MSK));
+       writel(1, (rb + CT2_LPU1_HOSTFN_MBOX0_MSK));
+
+       /* For first time initialization, no need to clear interrupts */
+       r32 = readl(rb + HOST_SEM5_REG);
+       if (r32 & 0x1) {
+               r32 = readl(rb + CT2_LPU0_HOSTFN_CMD_STAT);
+               if (r32 == 1) {
+                       writel(1, rb + CT2_LPU0_HOSTFN_CMD_STAT);
+                       readl((rb + CT2_LPU0_HOSTFN_CMD_STAT));
+               }
+               r32 = readl(rb + CT2_LPU1_HOSTFN_CMD_STAT);
+               if (r32 == 1) {
+                       writel(1, rb + CT2_LPU1_HOSTFN_CMD_STAT);
+                       readl(rb + CT2_LPU1_HOSTFN_CMD_STAT);
+               }
+       }
+
        bfa_ioc_ct2_mem_init(rb);
 
-       writel(BFI_IOC_UNINIT, (rb + CT2_BFA_IOC0_STATE_REG));
-       writel(BFI_IOC_UNINIT, (rb + CT2_BFA_IOC1_STATE_REG));
+       writel(BFI_IOC_UNINIT, rb + CT2_BFA_IOC0_STATE_REG);
+       writel(BFI_IOC_UNINIT, rb + CT2_BFA_IOC1_STATE_REG);
+
        return BFA_STATUS_OK;
 }