Patchwork [U-Boot,3/3,v2] powerpc/85xx: wait for alignment before resetting SERDES RX lanes (SERDES9)

login
register
mail settings
Submitter Timur Tabi
Date Oct. 7, 2011, 8:35 p.m.
Message ID <1318019722-11095-3-git-send-email-timur@freescale.com>
Download mbox | patch
Permalink /patch/118368/
State Changes Requested
Delegated to: Kumar Gala
Headers show

Comments

Timur Tabi - Oct. 7, 2011, 8:35 p.m.
The work-around for P4080 erratum SERDES9 says that the SERDES receiver lanes
should be reset after the XAUI starts tranmitting alignment signals.

Signed-off-by: Timur Tabi <timur@freescale.com>
---
 arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c |   10 ------
 board/freescale/corenet_ds/eth_p4080.c        |   42 ++++++++++++++++++++-----
 drivers/net/phy/teranetics.h                  |    1 +
 3 files changed, 35 insertions(+), 18 deletions(-)
 create mode 100644 drivers/net/phy/teranetics.h
Kumar Gala - Oct. 14, 2011, 4:29 a.m.
On Oct 7, 2011, at 3:35 PM, Timur Tabi wrote:

> The work-around for P4080 erratum SERDES9 says that the SERDES receiver lanes
> should be reset after the XAUI starts tranmitting alignment signals.
> 
> Signed-off-by: Timur Tabi <timur@freescale.com>
> ---
> arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c |   10 ------
> board/freescale/corenet_ds/eth_p4080.c        |   42 ++++++++++++++++++++-----
> drivers/net/phy/teranetics.h                  |    1 +
> 3 files changed, 35 insertions(+), 18 deletions(-)
> create mode 100644 drivers/net/phy/teranetics.h
> 
> diff --git a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c
> index 07e58ed..89ed5b4 100644
> --- a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c
> +++ b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c
> @@ -504,9 +504,6 @@ void fsl_serdes_init(void)
> 	const char *srds_lpd_arg;
> 	size_t arglen;
> #endif
> -#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES9
> -	enum srds_prtcl device;
> -#endif
> #ifdef CONFIG_SYS_P4080_ERRATUM_SERDES_A001
> 	int need_serdes_a001;	/* TRUE == need work-around for SERDES A001 */
> #endif
> @@ -787,11 +784,4 @@ void fsl_serdes_init(void)
> 			     SRDS_RSTCTL_SDPD);
> 	}
> #endif
> -
> -#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES9
> -	for (device = XAUI_FM1; device <= XAUI_FM2; device++) {
> -		if (is_serdes_configured(device))
> -			__serdes_reset_rx(srds_regs, cfg, device);
> -	}
> -#endif
> }
> diff --git a/board/freescale/corenet_ds/eth_p4080.c b/board/freescale/corenet_ds/eth_p4080.c
> index d4657f7..1c22a4d 100644
> --- a/board/freescale/corenet_ds/eth_p4080.c
> +++ b/board/freescale/corenet_ds/eth_p4080.c
> @@ -42,6 +42,10 @@
> #include "../common/fman.h"
> #include <asm/fsl_dtsec.h>
> 
> +#if defined(CONFIG_SYS_P4080_ERRATUM_SERDES9) && defined(CONFIG_PHY_TERANETICS)
> +#include "../../../drivers/net/phy/teranetics.h" /* for tn2020_driver.uid */
> +#endif
> +
> #define EMI_NONE	0xffffffff
> #define EMI_MASK	0xf0000000
> #define EMI1_RGMII	0x0
> @@ -93,21 +97,43 @@ struct mii_dev *mii_dev_for_muxval(u32 muxval)
> 	return bus;
> }
> 
> -#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES9
> +#if defined(CONFIG_SYS_P4080_ERRATUM_SERDES9) && defined(CONFIG_PHY_TERANETICS)
> int board_phy_config(struct phy_device *phydev)
> {
> -	/*
> -	 * If this is the 10G PHY, and we switched it to fiber,
> -	 * we need to reset the serdes link for SERDES9
> -	 */
> -	if ((phydev->port == PORT_FIBRE) && (phydev->drv->uid == 0x00a19410)) {
> +	if (phydev->drv->uid == tn2020_driver.uid) {

Rather than looking at tn2020_driver.uid lets just do something like:

if ((phydev->drv->uid & phydev->drv->mask) == TN2020_UID)

And add a #define in phy.h:

#define TN2020_UID	0x00a19410

> +		unsigned long timeout = 1 * 1000; /* 1 seconds */
> 		enum srds_prtcl device;
> 
> +		/*
> +		 * Wait for the XAUI to come out of reset.  This is when it
> +		 * starts transmitting alignment signals.
> +		 */
> +		while (--timeout) {
> +			int reg = phy_read(phydev, MDIO_MMD_PHYXS, MDIO_CTRL1);
> +			if (reg < 0) {
> +				printf("TN2020: Error reading from PHY at "
> +				       "address %u\n", phydev->addr);
> +				break;
> +			}
> +			/*
> +			 * Note that we've never actually seen
> +			 * MDIO_CTRL1_RESET set to 1.
> +			 */
> +			if ((reg & MDIO_CTRL1_RESET) == 0)
> +				break;
> +			udelay(1000);
> +		}
> +
> +		if (!timeout) {
> +			printf("TN2020: Timeout waiting for PHY at address %u "
> +			       " to reset.\n", phydev->addr);
> +		}
> +
> 		switch (phydev->addr) {
> -		case 4:
> +		case CONFIG_SYS_FM1_10GEC1_PHY_ADDR:
> 			device = XAUI_FM1;
> 			break;
> -		case 0:
> +		case CONFIG_SYS_FM2_10GEC1_PHY_ADDR:
> 			device = XAUI_FM2;
> 			break;
> 		default:
> diff --git a/drivers/net/phy/teranetics.h b/drivers/net/phy/teranetics.h
> new file mode 100644
> index 0000000..1d983de
> --- /dev/null
> +++ b/drivers/net/phy/teranetics.h
> @@ -0,0 +1 @@
> +extern struct phy_driver tn2020_driver;
> -- 
> 1.7.3.4
> 
> 
> _______________________________________________
> U-Boot mailing list
> U-Boot@lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
Tabi Timur-B04825 - Oct. 14, 2011, 11:40 a.m.
Kumar Gala wrote:
> Rather than looking at tn2020_driver.uid lets just do something like:
>
> if ((phydev->drv->uid&  phydev->drv->mask) == TN2020_UID)
>
> And add a #define in phy.h:
>
> #define TN2020_UID	0x00a19410

I guess that makes more sense.  I thought my original version was cooler, 
though.

Patch

diff --git a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c
index 07e58ed..89ed5b4 100644
--- a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c
@@ -504,9 +504,6 @@  void fsl_serdes_init(void)
 	const char *srds_lpd_arg;
 	size_t arglen;
 #endif
-#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES9
-	enum srds_prtcl device;
-#endif
 #ifdef CONFIG_SYS_P4080_ERRATUM_SERDES_A001
 	int need_serdes_a001;	/* TRUE == need work-around for SERDES A001 */
 #endif
@@ -787,11 +784,4 @@  void fsl_serdes_init(void)
 			     SRDS_RSTCTL_SDPD);
 	}
 #endif
-
-#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES9
-	for (device = XAUI_FM1; device <= XAUI_FM2; device++) {
-		if (is_serdes_configured(device))
-			__serdes_reset_rx(srds_regs, cfg, device);
-	}
-#endif
 }
diff --git a/board/freescale/corenet_ds/eth_p4080.c b/board/freescale/corenet_ds/eth_p4080.c
index d4657f7..1c22a4d 100644
--- a/board/freescale/corenet_ds/eth_p4080.c
+++ b/board/freescale/corenet_ds/eth_p4080.c
@@ -42,6 +42,10 @@ 
 #include "../common/fman.h"
 #include <asm/fsl_dtsec.h>
 
+#if defined(CONFIG_SYS_P4080_ERRATUM_SERDES9) && defined(CONFIG_PHY_TERANETICS)
+#include "../../../drivers/net/phy/teranetics.h" /* for tn2020_driver.uid */
+#endif
+
 #define EMI_NONE	0xffffffff
 #define EMI_MASK	0xf0000000
 #define EMI1_RGMII	0x0
@@ -93,21 +97,43 @@  struct mii_dev *mii_dev_for_muxval(u32 muxval)
 	return bus;
 }
 
-#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES9
+#if defined(CONFIG_SYS_P4080_ERRATUM_SERDES9) && defined(CONFIG_PHY_TERANETICS)
 int board_phy_config(struct phy_device *phydev)
 {
-	/*
-	 * If this is the 10G PHY, and we switched it to fiber,
-	 * we need to reset the serdes link for SERDES9
-	 */
-	if ((phydev->port == PORT_FIBRE) && (phydev->drv->uid == 0x00a19410)) {
+	if (phydev->drv->uid == tn2020_driver.uid) {
+		unsigned long timeout = 1 * 1000; /* 1 seconds */
 		enum srds_prtcl device;
 
+		/*
+		 * Wait for the XAUI to come out of reset.  This is when it
+		 * starts transmitting alignment signals.
+		 */
+		while (--timeout) {
+			int reg = phy_read(phydev, MDIO_MMD_PHYXS, MDIO_CTRL1);
+			if (reg < 0) {
+				printf("TN2020: Error reading from PHY at "
+				       "address %u\n", phydev->addr);
+				break;
+			}
+			/*
+			 * Note that we've never actually seen
+			 * MDIO_CTRL1_RESET set to 1.
+			 */
+			if ((reg & MDIO_CTRL1_RESET) == 0)
+				break;
+			udelay(1000);
+		}
+
+		if (!timeout) {
+			printf("TN2020: Timeout waiting for PHY at address %u "
+			       " to reset.\n", phydev->addr);
+		}
+
 		switch (phydev->addr) {
-		case 4:
+		case CONFIG_SYS_FM1_10GEC1_PHY_ADDR:
 			device = XAUI_FM1;
 			break;
-		case 0:
+		case CONFIG_SYS_FM2_10GEC1_PHY_ADDR:
 			device = XAUI_FM2;
 			break;
 		default:
diff --git a/drivers/net/phy/teranetics.h b/drivers/net/phy/teranetics.h
new file mode 100644
index 0000000..1d983de
--- /dev/null
+++ b/drivers/net/phy/teranetics.h
@@ -0,0 +1 @@ 
+extern struct phy_driver tn2020_driver;