diff mbox

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

Message ID 1375699398-14812-1-git-send-email-ramneek.mehresh@freescale.com
State Rejected
Delegated to: York Sun
Headers show

Commit Message

ramneek mehresh Aug. 5, 2013, 10:43 a.m. UTC
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@freescale.com>
Signed-off-by: Suresh Gupta <suresh.gupta@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(+)

Comments

York Sun Aug. 13, 2013, 9:54 p.m. UTC | #1
On 08/05/2013 03:43 AM, Ramneek Mehresh wrote:
> 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@freescale.com>
> Signed-off-by: Suresh Gupta <suresh.gupta@freescale.com>

Mehresh,

This patch only applies to rev 1 of T4240, doesn't it? Rev 1 part is not
available for general public. We don't submit rev 1 errata workaround.

York
diff mbox

Patch

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];