فهرست منبع

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>
Yuanquan Chen 12 سال پیش
والد
کامیت
c0a4e6b889
3فایلهای تغییر یافته به همراه26 افزوده شده و 0 حذف شده
  1. 3 0
      arch/powerpc/cpu/mpc85xx/cmd_errata.c
  2. 1 0
      arch/powerpc/include/asm/config_mpc85xx.h
  3. 22 0
      drivers/pci/fsl_pci_init.c

+ 3 - 0
arch/powerpc/cpu/mpc85xx/cmd_errata.c

@@ -247,6 +247,9 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 #ifdef CONFIG_SYS_FSL_ERRATUM_A004580
 	/* 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;
 }

+ 1 - 0
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 */

+ 22 - 0
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);