> -----Original Message----- > From: Bao Xiaowei [mailto:xiaowei....@nxp.com] > Sent: Monday, September 25, 2017 11:27 AM > To: M.h. Lian <minghuan.l...@nxp.com>; Z.q. Hou <zhiqiang....@nxp.com>; > Mingkai Hu <mingkai...@nxp.com>; York Sun <york....@nxp.com>; > hamish.mar...@alliedtelesis.co.nz; w...@denx.de; > tony.obr...@alliedtelesis.co.nz; u-boot@lists.denx.de > Cc: Xiaowei Bao <xiaowei....@nxp.com> > Subject: [PATCH] Powerpc: Make pcie link state judge more specific > > For some special reset times for longer pcie devices, in this case, the pcie > device may on polling compliance state, the RC considers the pcie device is > link up, but the pcie device is not link up, only the L0 state is link up > state. So > add the link up status judgement mechanisms. > > Signed-off-by: Bao Xiaowei <xiaowei....@nxp.com> > --- > v2: > - Detailed function module > - Adjust the code structure >
I suggest to split this patch to two patches, one is for format change, another one is for LTSSM change. > arch/powerpc/include/asm/fsl_pci.h | 3 + > drivers/pci/fsl_pci_init.c | 151 > ++++++++++++++++++++----------------- > 2 files changed, 86 insertions(+), 68 deletions(-) > > diff --git a/arch/powerpc/include/asm/fsl_pci.h > b/arch/powerpc/include/asm/fsl_pci.h > index cad341e..9dfbf19 100644 > --- a/arch/powerpc/include/asm/fsl_pci.h > +++ b/arch/powerpc/include/asm/fsl_pci.h > @@ -24,6 +24,9 @@ > > #define PCI_LTSSM 0x404 /* PCIe Link Training, Status State Machine */ > #define PCI_LTSSM_L0 0x16 /* L0 state */ It's better to submit a patch to fix the leading space. > +#define PCIE_GEN3_LTSSM_L0 0x11 /* L0 state */ Follow the same name rule as PCI_LTSSM_L0? Like PCI_LTSSM_L0_PEX_REV3? > +#define LTSSM_PCIE_DETECT_QUIET 0x00 /* Detect state */ > +#define LTSSM_PCIE_DETECT_ACTIVE 0x01 /* Detect state */ > > int fsl_setup_hose(struct pci_controller *hose, unsigned long addr); int > fsl_is_pci_agent(struct pci_controller *hose); diff --git > a/drivers/pci/fsl_pci_init.c b/drivers/pci/fsl_pci_init.c index > af20cf0..5d697bc > 100644 > --- a/drivers/pci/fsl_pci_init.c > +++ b/drivers/pci/fsl_pci_init.c > @@ -39,6 +39,8 @@ DECLARE_GLOBAL_DATA_PTR; #if > defined(CONFIG_SYS_PCI_64BIT) > && !defined(CONFIG_SYS_PCI64_MEMORY_BUS) > #define CONFIG_SYS_PCI64_MEMORY_BUS (64ull*1024*1024*1024) #endif > +#define PEX_CSR0_LTSSM_MASK 0xFC > +#define PEX_CSR0_LTSSM_SHIFT 2 > > /* Setup one inbound ATMU window. > * > @@ -290,6 +292,81 @@ static void fsl_pcie_boot_master_release_slave(int > port) } #endif > > +static int is_pcie_gen3(struct fsl_pci_info *pci_info) { > + u32 cfg_addr = (u32)&((ccsr_fsl_pci_t *)pci_info->regs)->cfg_addr; > + volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *)cfg_addr; > + u32 block_rev; > + > + block_rev = in_be32(&pci->block_rev1); > + if (block_rev >= PEX_IP_BLK_REV_3_0) > + return 1; > + else > + return 0; > +} > + As discussed, it's not related to gen3. It's related to PEX block version. Please use The PCIe controller version here. > +static int get_ltssm_val(struct pci_controller *hose, > + struct fsl_pci_info *pci_info) > +{ > + u16 ltssm = 0; > + pci_dev_t dev = PCI_BDF(hose->first_busno, 0, 0); > + u32 cfg_addr = (u32)&((ccsr_fsl_pci_t *)pci_info->regs)->cfg_addr; > + volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *)cfg_addr; > + > + if (is_pcie_gen3(pci_info)) > + ltssm = (in_be32(&pci->pex_csr0) > + & PEX_CSR0_LTSSM_MASK) >> > PEX_CSR0_LTSSM_SHIFT; > + else > + pci_hose_read_config_word(hose, dev, PCI_LTSSM, <ssm); > + > + return ltssm; > +} > + > +static int pci_link_up(struct pci_controller *hose, > + struct fsl_pci_info *pci_info) > +{ > + int enabled = 0; > + u16 ltssm; > + int i, pcie_ltssm_l0; > + > + if (is_pcie_gen3(pci_info)) > + pcie_ltssm_l0 = PCIE_GEN3_LTSSM_L0; > + else > + pcie_ltssm_l0 = PCI_LTSSM_L0; > + > + ltssm = get_ltssm_val(hose, pci_info); > + if (ltssm == LTSSM_PCIE_DETECT_QUIET || > + ltssm == LTSSM_PCIE_DETECT_ACTIVE) > + enabled = 0; > + else if (ltssm == PCIE_GEN3_LTSSM_L0) > + enabled = 1; > + else { > + for (i = 0; i < 100 && ltssm != pcie_ltssm_l0; i++) { > + ltssm = get_ltssm_val(hose, pci_info); > + udelay(1000); > + } > + enabled = (ltssm == pcie_ltssm_l0) ? 1 : 0; > + } > + return enabled; > +} > + > +#if defined(CONFIG_FSL_PCIE_RESET) || \ > + defined(CONFIG_SYS_P4080_ERRATUM_PCIE_A003) > +static void do_pcie_reset(struct fsl_pci_info *pci_info) { > + u32 cfg_addr = (u32)&((ccsr_fsl_pci_t *)pci_info->regs)->cfg_addr; > + volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *)cfg_addr; > + > + /* assert PCIe reset */ > + setbits_be32(&pci->pdb_stat, 0x08000000); > + (void) in_be32(&pci->pdb_stat); > + udelay(1000); > + /* clear PCIe reset */ > + clrbits_be32(&pci->pdb_stat, 0x08000000); > + asm("sync;isync"); > +} > +#endif > + > void fsl_pci_init(struct pci_controller *hose, struct fsl_pci_info > *pci_info) { > u32 cfg_addr = (u32)&((ccsr_fsl_pci_t *)pci_info->regs)->cfg_addr; > @@ -298,7 +375,6 @@ void fsl_pci_init(struct pci_controller *hose, struct > fsl_pci_info *pci_info) > u32 temp32; > u32 block_rev; > int enabled, r, inbound = 0; > - u16 ltssm; > u8 temp8, pcie_cap; > int pcie_cap_pos; > int pci_dcr; > @@ -438,63 +514,12 @@ void fsl_pci_init(struct pci_controller *hose, struct > fsl_pci_info *pci_info) > udelay(1); > #endif > if (pcie_cap == PCI_CAP_ID_EXP) { > - if (block_rev >= PEX_IP_BLK_REV_3_0) { > -#define PEX_CSR0_LTSSM_MASK 0xFC > -#define PEX_CSR0_LTSSM_SHIFT 2 > - ltssm = (in_be32(&pci->pex_csr0) > - & PEX_CSR0_LTSSM_MASK) >> > PEX_CSR0_LTSSM_SHIFT; > - enabled = (ltssm == 0x11) ? 1 : 0; > #ifdef CONFIG_FSL_PCIE_RESET > - int i; > - /* assert PCIe reset */ > - setbits_be32(&pci->pdb_stat, 0x08000000); > - (void) in_be32(&pci->pdb_stat); > - udelay(1000); > - /* clear PCIe reset */ > - clrbits_be32(&pci->pdb_stat, 0x08000000); > - asm("sync;isync"); > - for (i = 0; i < 100 && ltssm < PCI_LTSSM_L0; i++) { > - pci_hose_read_config_word(hose, dev, > PCI_LTSSM, > - <ssm); > - udelay(1000); > - } > + do_pcie_reset(pci_info); > + pci_hose_write_config_dword(hose, dev, > + PCI_BASE_ADDRESS_0, > pcicsrbar); > #endif > - } else { > - /* pci_hose_read_config_word(hose, dev, PCI_LTSSM, > <ssm); */ > - /* enabled = ltssm >= PCI_LTSSM_L0; */ > - pci_hose_read_config_word(hose, dev, PCI_LTSSM, <ssm); > - enabled = ltssm >= PCI_LTSSM_L0; > - > -#ifdef CONFIG_FSL_PCIE_RESET > - if (ltssm == 1) { > - int i; > - debug("....PCIe link error. " "LTSSM=0x%02x.", ltssm); > - /* assert PCIe reset */ > - setbits_be32(&pci->pdb_stat, 0x08000000); > - (void) in_be32(&pci->pdb_stat); > - udelay(100); > - debug(" Asserting PCIe reset @%p = %x\n", > - &pci->pdb_stat, in_be32(&pci->pdb_stat)); > - /* clear PCIe reset */ > - clrbits_be32(&pci->pdb_stat, 0x08000000); > - asm("sync;isync"); > - for (i=0; i<100 && ltssm < PCI_LTSSM_L0; i++) { > - pci_hose_read_config_word(hose, dev, > PCI_LTSSM, > - <ssm); > - udelay(1000); > - debug("....PCIe link error. " > - "LTSSM=0x%02x.\n", ltssm); > - } > - enabled = ltssm >= PCI_LTSSM_L0; > - > - /* we need to re-write the bar0 since a reset will > - * clear it > - */ > - pci_hose_write_config_dword(hose, dev, > - PCI_BASE_ADDRESS_0, pcicsrbar); > - } > -#endif > - } > + enabled = pci_link_up(hose, pci_info); > > #ifdef CONFIG_SYS_P4080_ERRATUM_PCIE_A003 > if (enabled == 0) { > @@ -502,19 +527,9 @@ void fsl_pci_init(struct pci_controller *hose, struct > fsl_pci_info *pci_info) > temp32 = in_be32(&srds_regs->srdspccr0); > > if ((temp32 >> 28) == 3) { > - int i; > - > out_be32(&srds_regs->srdspccr0, 2 << 28); > - setbits_be32(&pci->pdb_stat, 0x08000000); > - in_be32(&pci->pdb_stat); > - udelay(100); > - clrbits_be32(&pci->pdb_stat, 0x08000000); > - asm("sync;isync"); > - for (i=0; i < 100 && ltssm < PCI_LTSSM_L0; i++) > { > - pci_hose_read_config_word(hose, > dev, PCI_LTSSM, <ssm); > - udelay(1000); > - } > - enabled = ltssm >= PCI_LTSSM_L0; > + do_pcie_reset(pci_info); > + enabled = pci_link_up(hose, pci_info); > } > } > #endif > -- > 2.7.4 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot