[U-Boot] [PATCH] Powerpc: Make pcie link state judge more specific
Mingkai Hu
mingkai.hu at nxp.com
Tue Oct 10 10:30:07 UTC 2017
> -----Original Message-----
> From: Bao Xiaowei [mailto:xiaowei.bao at nxp.com]
> Sent: Monday, September 25, 2017 11:27 AM
> To: M.h. Lian <minghuan.lian at nxp.com>; Z.q. Hou <zhiqiang.hou at nxp.com>;
> Mingkai Hu <mingkai.hu at nxp.com>; York Sun <york.sun at nxp.com>;
> hamish.martin at alliedtelesis.co.nz; wd at denx.de;
> tony.obrien at alliedtelesis.co.nz; u-boot at lists.denx.de
> Cc: Xiaowei Bao <xiaowei.bao at 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.bao at 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
More information about the U-Boot
mailing list