[U-Boot] [PATCH] Powerpc: Make pcie link state judge more specific
York Sun
york.sun at nxp.com
Tue Oct 3 15:31:53 UTC 2017
On 09/24/2017 08:44 PM, Bao Xiaowei wrote:
> 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
Mingkai,
Please ack if you agree with this change.
Xiaowei,
Please see some inline comments.
>
> 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 */
> +#define PCIE_GEN3_LTSSM_L0 0x11 /* L0 state */
> +#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
You don't need the "else" here.
> + return 0;
> +}
> +
> +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;
Add blank line above "return".
> +}
You don't have to send an update unless you have something else to fix.
I can make cosmetic fix when I merge it.
York
More information about the U-Boot
mailing list