From: Wang Dongsheng <dongsheng.w...@freescale.com> Root cause is pcie power management state transition need a delay. The delay time define in "PCI Bus Power Management Interface Specification".
D0, D1 or D2 --> D3 need to delay 10ms. D3 --> D0 need to delay 10ms. Signed-off-by: Wang Dongsheng <dongsheng.w...@freescale.com> diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 4bd091a..33950ad 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -1175,15 +1175,24 @@ static void send_pme_turnoff_message(struct pci_controller *hose) setbits32(&pci->pex_pmcr, PEX_PMCR_PTOMR); /* Wait trun off done */ - for (i = 0; i < 150; i++) { + /* RC will get this detect quickly */ + for (i = 0; i < 50; i++) { dr = in_be32(&pci->pex_pme_mes_dr); - if (dr) { + if (dr & ENL23_DETECT_BIT) { out_be32(&pci->pex_pme_mes_dr, dr); break; } udelay(1000); } + + /* + * "PCI Bus Power Management Interface Specification" define + * Minimum System Software Guaranteed Delays + * + * D0, D1 or D2 --> D3, need delay 10ms. + */ + mdelay(10); } static void fsl_pci_syscore_do_suspend(struct pci_controller *hose) @@ -1211,9 +1220,10 @@ static void fsl_pci_syscore_do_resume(struct pci_controller *hose) setbits32(&pci->pex_pmcr, PEX_PMCR_EXL2S); /* Wait exit done */ - for (i = 0; i < 150; i++) { + /* RC will get this detect quickly */ + for (i = 0; i < 50; i++) { dr = in_be32(&pci->pex_pme_mes_dr); - if (dr) { + if (dr & EXL23_DETECT_BIT) { out_be32(&pci->pex_pme_mes_dr, dr); break; } @@ -1221,6 +1231,14 @@ static void fsl_pci_syscore_do_resume(struct pci_controller *hose) udelay(1000); } + /* + * "PCI Bus Power Management Interface Specification" define + * Minimum System Software Guaranteed Delays + * + * D3 hot --> D0, need delay 10ms. + */ + mdelay(10); + setup_pci_atmu(hose); } diff --git a/arch/powerpc/sysdev/fsl_pci.h b/arch/powerpc/sysdev/fsl_pci.h index c1cec77..37fc644 100644 --- a/arch/powerpc/sysdev/fsl_pci.h +++ b/arch/powerpc/sysdev/fsl_pci.h @@ -39,6 +39,9 @@ struct platform_device; #define PME_DISR_EN_ENL23D 0x00002000 #define PME_DISR_EN_EXL23D 0x00001000 +#define ENL23_DETECT_BIT 0x00002000 +#define EXL23_DETECT_BIT 0x00001000 + /* PCI/PCI Express outbound window reg */ struct pci_outbound_window_regs { __be32 potar; /* 0x.0 - Outbound translation address register */ -- 1.8.5 _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev