[U-Boot] [PATCH 1/2]powerpc/usb: Workaround for erratum-A006918

Ramneek Mehresh ramneek.mehresh at freescale.com
Mon Aug 5 12:43:18 CEST 2013


Erratum-A006918 prevents internal UTMI dual phy pll inside T4240
rev 1.0 from starting sometimes. Workaround involves restarting
phy pll maximum seven times with 1ms delay in each loop

Signed-off-by: Ramneek Mehresh <ramneek.mehresh at freescale.com>
Signed-off-by: Suresh Gupta <suresh.gupta at freescale.com>
---
Applies on git://git.denx.de/u-boot.git
(branch master)

 arch/powerpc/cpu/mpc85xx/cmd_errata.c     |  4 +++
 arch/powerpc/cpu/mpc85xx/cpu_init.c       | 55 +++++++++++++++++++++++++++++++
 arch/powerpc/include/asm/config_mpc85xx.h |  1 +
 include/fsl_usb.h                         |  7 ++++
 4 files changed, 67 insertions(+)

diff --git a/arch/powerpc/cpu/mpc85xx/cmd_errata.c b/arch/powerpc/cpu/mpc85xx/cmd_errata.c
index 5cd02cc..779b352 100644
--- a/arch/powerpc/cpu/mpc85xx/cmd_errata.c
+++ b/arch/powerpc/cpu/mpc85xx/cmd_errata.c
@@ -195,6 +195,10 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	puts("Work-around for Erratum DDR111 enabled\n");
 	puts("Work-around for Erratum DDR134 enabled\n");
 #endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_A006918
+	if (IS_SVR_REV(svr, 1, 0))
+		puts("Work-around for Erratum A006918 enabled\n");
+#endif
 #ifdef CONFIG_SYS_FSL_ERRATUM_IFC_A002769
 	puts("Work-around for Erratum IFC-A002769 enabled\n");
 #endif
diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init.c b/arch/powerpc/cpu/mpc85xx/cpu_init.c
index 5aa09c1..6024768 100644
--- a/arch/powerpc/cpu/mpc85xx/cpu_init.c
+++ b/arch/powerpc/cpu/mpc85xx/cpu_init.c
@@ -35,6 +35,10 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#ifdef CONFIG_SYS_FSL_ERRATUM_A006918
+bool	has_fsl_erratum_a006918;
+#endif
+
 #ifdef CONFIG_QE
 extern qe_iop_conf_t qe_iop_conf_tab[];
 extern void qe_config_iopin(u8 port, u8 pin, int dir,
@@ -211,6 +215,47 @@ static void corenet_tb_init(void)
 }
 #endif
 
+#ifdef CONFIG_SYS_FSL_ERRATUM_A006918
+void fsl_erratum_a006918_workaround(void)
+{
+	unsigned int cnt = FSL_MAX_USBPLL_RETRY_COUNT;
+	struct ccsr_usb_phy *usb_phy =
+		(void *)CONFIG_SYS_MPC85xx_USB1_PHY_ADDR;
+
+	has_fsl_erratum_a006918 = true;
+
+	do {
+		/* 1ms delay required for PLL to be stable */
+		mdelay(1);
+		if ((in_be32(&usb_phy->port1.sts) &
+			CONFIG_SYS_FSL_USB_SYS_CLK_VALID) &&
+				(in_be32(&usb_phy->port2.sts) &
+					CONFIG_SYS_FSL_USB_SYS_CLK_VALID)) {
+			has_fsl_erratum_a006918 = false;
+			break;
+		} else {
+			clrsetbits_be32(&usb_phy->pllprg[1],
+					CONFIG_SYS_FSL_USB_PLLPRG2_PLL_EN,
+					CONFIG_SYS_FSL_USB_PLLPRG2_PHY2_CLK_EN |
+					CONFIG_SYS_FSL_USB_PLLPRG2_PHY1_CLK_EN |
+					CONFIG_SYS_FSL_USB_PLLPRG2_FRAC_LPF_EN |
+					CONFIG_SYS_FSL_USB_PLLPRG2_REF_DIV |
+					CONFIG_SYS_FSL_USB_PLLPRG2_MFI);
+			setbits_be32(&usb_phy->pllprg[1],
+				     CONFIG_SYS_FSL_USB_PLLPRG2_PHY2_CLK_EN |
+				     CONFIG_SYS_FSL_USB_PLLPRG2_PHY1_CLK_EN |
+				     CONFIG_SYS_FSL_USB_PLLPRG2_FRAC_LPF_EN |
+				     CONFIG_SYS_FSL_USB_PLLPRG2_REF_DIV |
+				     CONFIG_SYS_FSL_USB_PLLPRG2_MFI |
+				     CONFIG_SYS_FSL_USB_PLLPRG2_PLL_EN);
+		}
+	} while (--cnt);
+
+	if (has_fsl_erratum_a006918)
+		printf("ERROR:fsl internal utmi phy init failed\n");
+}
+#endif
+
 void cpu_init_f (void)
 {
 	extern void m8560_cpm_reset (void);
@@ -628,6 +673,8 @@ skip_l2:
 #if defined(CONFIG_SYS_FSL_USB_DUAL_PHY_ENABLE)
 		struct ccsr_usb_phy __iomem *usb_phy =
 			(void *)CONFIG_SYS_MPC85xx_USB1_PHY_ADDR;
+		setbits_be32(&usb_phy->pllprg[0],
+			     CONFIG_SYS_FSL_USB_PLLPRG1_PHY_DIV);
 		setbits_be32(&usb_phy->pllprg[1],
 			     CONFIG_SYS_FSL_USB_PLLPRG2_PHY2_CLK_EN |
 			     CONFIG_SYS_FSL_USB_PLLPRG2_PHY1_CLK_EN |
@@ -645,6 +692,14 @@ skip_l2:
 			     CONFIG_SYS_FSL_USB_DRVVBUS_CR_EN);
 		setbits_be32(&usb_phy->port2.pwrfltcfg,
 			     CONFIG_SYS_FSL_USB_PWRFLT_CR_EN);
+
+	/* Deal with USB Erratum USB-A006918
+	 * UTMI phy clk instability issue
+	 */
+#ifdef CONFIG_SYS_FSL_ERRATUM_A006918
+		if (IS_SVR_REV(svr, 1, 0))
+			fsl_erratum_a006918_workaround();
+#endif
 #endif
 
 #ifdef CONFIG_FMAN_ENET
diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h
index 7ed93ac..f7926ef 100644
--- a/arch/powerpc/include/asm/config_mpc85xx.h
+++ b/arch/powerpc/include/asm/config_mpc85xx.h
@@ -542,6 +542,7 @@
 #define CONFIG_SYS_FSL_ERRATUM_A_004934
 #define CONFIG_SYS_FSL_ERRATUM_A005871
 #define CONFIG_SYS_FSL_ERRATUM_A006593
+#define CONFIG_SYS_FSL_ERRATUM_A006918
 #define CONFIG_SYS_CCSRBAR_DEFAULT	0xfe000000
 #define CONFIG_SYS_FSL_PCI_VER_3_X
 
diff --git a/include/fsl_usb.h b/include/fsl_usb.h
index 88d6a1f..a3e681b 100644
--- a/include/fsl_usb.h
+++ b/include/fsl_usb.h
@@ -25,6 +25,8 @@
 #ifndef _ASM_FSL_USB_H_
 #define _ASM_FSL_USB_H_
 
+#include <stdbool.h>
+
 #ifdef CONFIG_SYS_FSL_USB_DUAL_PHY_ENABLE
 struct ccsr_usb_port_ctrl {
 	u32	ctrl;
@@ -68,6 +70,11 @@ struct ccsr_usb_phy {
 #define CONFIG_SYS_FSL_USB_PLLPRG2_MFI (5 << 16)
 #define CONFIG_SYS_FSL_USB_PLLPRG2_PLL_EN (1 << 21)
 #define CONFIG_SYS_FSL_USB_SYS_CLK_VALID (1 << 0)
+
+#ifdef CONFIG_SYS_FSL_ERRATUM_A006918
+extern bool	has_fsl_erratum_a006918;
+#define	FSL_MAX_USBPLL_RETRY_COUNT	7
+#endif
 #else
 struct ccsr_usb_phy {
 	u8	res0[0x18];
-- 
1.7.11.7





More information about the U-Boot mailing list