#define CFG_REG                                        (LMI_BASE_ADDR + 0x0)
 #define     LTSSM_SHIFT                                24
 #define     LTSSM_MASK                         0x3f
-#define     LTSSM_L0                           0x10
 #define     RC_BAR_CONFIG                      0x300
+
+/* LTSSM values in CFG_REG */
+enum {
+       LTSSM_DETECT_QUIET                      = 0x0,
+       LTSSM_DETECT_ACTIVE                     = 0x1,
+       LTSSM_POLLING_ACTIVE                    = 0x2,
+       LTSSM_POLLING_COMPLIANCE                = 0x3,
+       LTSSM_POLLING_CONFIGURATION             = 0x4,
+       LTSSM_CONFIG_LINKWIDTH_START            = 0x5,
+       LTSSM_CONFIG_LINKWIDTH_ACCEPT           = 0x6,
+       LTSSM_CONFIG_LANENUM_ACCEPT             = 0x7,
+       LTSSM_CONFIG_LANENUM_WAIT               = 0x8,
+       LTSSM_CONFIG_COMPLETE                   = 0x9,
+       LTSSM_CONFIG_IDLE                       = 0xa,
+       LTSSM_RECOVERY_RCVR_LOCK                = 0xb,
+       LTSSM_RECOVERY_SPEED                    = 0xc,
+       LTSSM_RECOVERY_RCVR_CFG                 = 0xd,
+       LTSSM_RECOVERY_IDLE                     = 0xe,
+       LTSSM_L0                                = 0x10,
+       LTSSM_RX_L0S_ENTRY                      = 0x11,
+       LTSSM_RX_L0S_IDLE                       = 0x12,
+       LTSSM_RX_L0S_FTS                        = 0x13,
+       LTSSM_TX_L0S_ENTRY                      = 0x14,
+       LTSSM_TX_L0S_IDLE                       = 0x15,
+       LTSSM_TX_L0S_FTS                        = 0x16,
+       LTSSM_L1_ENTRY                          = 0x17,
+       LTSSM_L1_IDLE                           = 0x18,
+       LTSSM_L2_IDLE                           = 0x19,
+       LTSSM_L2_TRANSMIT_WAKE                  = 0x1a,
+       LTSSM_DISABLED                          = 0x20,
+       LTSSM_LOOPBACK_ENTRY_MASTER             = 0x21,
+       LTSSM_LOOPBACK_ACTIVE_MASTER            = 0x22,
+       LTSSM_LOOPBACK_EXIT_MASTER              = 0x23,
+       LTSSM_LOOPBACK_ENTRY_SLAVE              = 0x24,
+       LTSSM_LOOPBACK_ACTIVE_SLAVE             = 0x25,
+       LTSSM_LOOPBACK_EXIT_SLAVE               = 0x26,
+       LTSSM_HOT_RESET                         = 0x27,
+       LTSSM_RECOVERY_EQUALIZATION_PHASE0      = 0x28,
+       LTSSM_RECOVERY_EQUALIZATION_PHASE1      = 0x29,
+       LTSSM_RECOVERY_EQUALIZATION_PHASE2      = 0x2a,
+       LTSSM_RECOVERY_EQUALIZATION_PHASE3      = 0x2b,
+};
+
 #define VENDOR_ID_REG                          (LMI_BASE_ADDR + 0x44)
 
 /* PCIe core controller registers */
        return readl(pcie->base + reg);
 }
 
-static int advk_pcie_link_up(struct advk_pcie *pcie)
+static u8 advk_pcie_ltssm_state(struct advk_pcie *pcie)
 {
-       u32 val, ltssm_state;
+       u32 val;
+       u8 ltssm_state;
 
        val = advk_readl(pcie, CFG_REG);
        ltssm_state = (val >> LTSSM_SHIFT) & LTSSM_MASK;
-       return ltssm_state >= LTSSM_L0;
+       return ltssm_state;
+}
+
+static inline bool advk_pcie_link_up(struct advk_pcie *pcie)
+{
+       /* check if LTSSM is in normal operation - some L* state */
+       u8 ltssm_state = advk_pcie_ltssm_state(pcie);
+       return ltssm_state >= LTSSM_L0 && ltssm_state < LTSSM_DISABLED;
+}
+
+static inline bool advk_pcie_link_training(struct advk_pcie *pcie)
+{
+       /*
+        * According to PCIe Base specification 3.0, Table 4-14: Link
+        * Status Mapped to the LTSSM is Link Training mapped to LTSSM
+        * Configuration and Recovery states.
+        */
+       u8 ltssm_state = advk_pcie_ltssm_state(pcie);
+       return ((ltssm_state >= LTSSM_CONFIG_LINKWIDTH_START &&
+                ltssm_state < LTSSM_L0) ||
+               (ltssm_state >= LTSSM_RECOVERY_EQUALIZATION_PHASE0 &&
+                ltssm_state <= LTSSM_RECOVERY_EQUALIZATION_PHASE3));
 }
 
 static int advk_pcie_wait_for_link(struct advk_pcie *pcie)
        size_t retries;
 
        for (retries = 0; retries < RETRAIN_WAIT_MAX_RETRIES; ++retries) {
-               if (!advk_pcie_link_up(pcie))
+               if (advk_pcie_link_training(pcie))
                        break;
                udelay(RETRAIN_WAIT_USLEEP_US);
        }
                /* u32 contains both PCI_EXP_LNKCTL and PCI_EXP_LNKSTA */
                u32 val = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + reg) &
                        ~(PCI_EXP_LNKSTA_LT << 16);
-               if (!advk_pcie_link_up(pcie))
+               if (advk_pcie_link_training(pcie))
                        val |= (PCI_EXP_LNKSTA_LT << 16);
                *value = val;
                return PCI_BRIDGE_EMUL_HANDLED;