diff options
author | Yuanquan Chen <B41889@freescale.com> | 2012-11-26 23:49:45 +0000 |
---|---|---|
committer | Andy Fleming <afleming@freescale.com> | 2012-11-27 18:28:07 -0600 |
commit | c0a4e6b889a702cc2c8375619ce7b093f6b3b1de (patch) | |
tree | c707baafbb5971ca6d826e4056fc5969e1f00169 | |
parent | 9760b274df8fdc5a6d124f3192535ebe281a78a6 (diff) | |
download | u-boot-imx-c0a4e6b889a702cc2c8375619ce7b093f6b3b1de.zip u-boot-imx-c0a4e6b889a702cc2c8375619ce7b093f6b3b1de.tar.gz u-boot-imx-c0a4e6b889a702cc2c8375619ce7b093f6b3b1de.tar.bz2 |
powerpc/p4080ds: fix PCI-e x8 link training down failure
Due to SerDes configuration error, if we set the PCI-e controller link width
as x8 in RCW and add a narrower width(such as x4, x2 or x1) PCI-e device to
PCI-e slot, it fails to train down to the PCI-e device's link width. According
to p4080ds errata PCIe-A003, we reset the PCI-e controller link width to x4 in
u-boot. Then it can train down to x2 or x1 width to make the PCI-e link between
RC and EP.
Signed-off-by: Yuanquan Chen <B41889@freescale.com>
Signed-off-by: Andy Fleming <afleming@freescale.com>
-rw-r--r-- | arch/powerpc/cpu/mpc85xx/cmd_errata.c | 3 | ||||
-rw-r--r-- | arch/powerpc/include/asm/config_mpc85xx.h | 1 | ||||
-rw-r--r-- | drivers/pci/fsl_pci_init.c | 22 |
3 files changed, 26 insertions, 0 deletions
diff --git a/arch/powerpc/cpu/mpc85xx/cmd_errata.c b/arch/powerpc/cpu/mpc85xx/cmd_errata.c index 7d38e1c..e5ecf5d 100644 --- a/arch/powerpc/cpu/mpc85xx/cmd_errata.c +++ b/arch/powerpc/cpu/mpc85xx/cmd_errata.c @@ -248,6 +248,9 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) /* This work-around is implemented in PBI, so just check for it */ check_erratum_a4580(svr); #endif +#ifdef CONFIG_SYS_P4080_ERRATUM_PCIE_A003 + puts("Work-around for Erratum PCIe-A003 enabled\n"); +#endif return 0; } diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h index 965d431..0b9638b 100644 --- a/arch/powerpc/include/asm/config_mpc85xx.h +++ b/arch/powerpc/include/asm/config_mpc85xx.h @@ -421,6 +421,7 @@ #define CONFIG_SYS_FSL_ERRATUM_SRIO_A004034 #define CONFIG_SYS_FSL_ERRATUM_A004849 #define CONFIG_SYS_FSL_ERRATUM_A004580 +#define CONFIG_SYS_P4080_ERRATUM_PCIE_A003 #elif defined(CONFIG_PPC_P5020) /* also supports P5010 */ #define CONFIG_SYS_PPC64 /* 64-bit core */ diff --git a/drivers/pci/fsl_pci_init.c b/drivers/pci/fsl_pci_init.c index 48ae163..77ac1f7 100644 --- a/drivers/pci/fsl_pci_init.c +++ b/drivers/pci/fsl_pci_init.c @@ -470,6 +470,28 @@ void fsl_pci_init(struct pci_controller *hose, struct fsl_pci_info *pci_info) } #endif +#ifdef CONFIG_SYS_P4080_ERRATUM_PCIE_A003 + if (enabled == 0) { + serdes_corenet_t *srds_regs = (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR; + 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; + } + } +#endif if (!enabled) { /* Let the user know there's no PCIe link */ printf("no link, regs @ 0x%lx\n", pci_info->regs); |