diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/pci/pcie_layerscape.c | 25 | ||||
-rw-r--r-- | drivers/pci/pcie_layerscape.h | 3 |
2 files changed, 24 insertions, 4 deletions
diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c index 610f85c..9a69107 100644 --- a/drivers/pci/pcie_layerscape.c +++ b/drivers/pci/pcie_layerscape.c @@ -69,13 +69,30 @@ static int ls_pcie_ltssm(struct ls_pcie *pcie) static int ls_pcie_link_up(struct ls_pcie *pcie) { - int ltssm; + int ltssm, i; ltssm = ls_pcie_ltssm(pcie); - if (ltssm < LTSSM_PCIE_L0) - return 0; - return 1; + /* + * For some special reset times for longer pcie devices, + * the pcie device may on polling compliance state, + * on this state, if the device can restored to the L0 state + * within 100ms considers the pcie device is link up + */ + if (ltssm == LTSSM_PCIE_DETECT_QUIET || + ltssm == LTSSM_PCIE_DETECT_ACTIVE) { + return 0; + } else if (ltssm == LTSSM_PCIE_L0) { + return 1; + } else { + for (i = 0; i < 100; i++) { + udelay(1000); + ltssm = ls_pcie_ltssm(pcie); + if (ltssm == LTSSM_PCIE_L0) + return 1; + } + return 0; + } } static void ls_pcie_cfg0_set_busdev(struct ls_pcie *pcie, u32 busdev) diff --git a/drivers/pci/pcie_layerscape.h b/drivers/pci/pcie_layerscape.h index 782e3ab..4313e85 100644 --- a/drivers/pci/pcie_layerscape.h +++ b/drivers/pci/pcie_layerscape.h @@ -70,6 +70,9 @@ #define LTSSM_STATE_MASK 0x3f #define LTSSM_PCIE_L0 0x11 /* L0 state */ +#define LTSSM_PCIE_DETECT_QUIET 0x00 /* L0 state */ +#define LTSSM_PCIE_DETECT_ACTIVE 0x01 /* L0 state */ +#define LTSSM_PCIE_L0 0x11 /* L0 state */ #define PCIE_DBI_SIZE 0x100000 /* 1M */ |