summaryrefslogtreecommitdiff
path: root/drivers/pci
diff options
context:
space:
mode:
authorYuanquan Chen <B41889@freescale.com>2012-11-26 23:49:45 +0000
committerAndy Fleming <afleming@freescale.com>2012-11-27 18:28:07 -0600
commitc0a4e6b889a702cc2c8375619ce7b093f6b3b1de (patch)
treec707baafbb5971ca6d826e4056fc5969e1f00169 /drivers/pci
parent9760b274df8fdc5a6d124f3192535ebe281a78a6 (diff)
downloadu-boot-c0a4e6b889a702cc2c8375619ce7b093f6b3b1de.tar.gz
u-boot-c0a4e6b889a702cc2c8375619ce7b093f6b3b1de.tar.bz2
u-boot-c0a4e6b889a702cc2c8375619ce7b093f6b3b1de.zip
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>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/fsl_pci_init.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/drivers/pci/fsl_pci_init.c b/drivers/pci/fsl_pci_init.c
index 48ae16374d..77ac1f7c7b 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, &ltssm);
+ 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);