[U-Boot] [PATCHv2 1/5] fsl: serdes: ensure accessing the initialized maps of serdes protocol

Zhiqiang Hou Zhiqiang.Hou at nxp.com
Tue Aug 2 13:03:22 CEST 2016


From: Hou Zhiqiang <Zhiqiang.Hou at nxp.com>

Up to now, the function is_serdes_configed() doesn't check if the map
of serdes protocol is initialized before accessing it. The function
is_serdes_configed() will get wrong result when it was called before
the serdes protocol maps initialized. As the first element of the map
isn't used for any device, so use it as the flag to indicate if the
map has been initialized.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou at nxp.com>
---
V2:
 - Check initialization-state of the serdes protocol map before serdes init.
 - Comment the element 'NONE' used as a initialization-state flag.

 arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.c          | 15 +++++++++++++--
 arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_serdes.c | 12 ++++++++++++
 arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c | 12 ++++++++++++
 .../arm/include/asm/arch-fsl-layerscape/fsl_serdes.h |  8 ++++++++
 arch/arm/include/asm/arch-ls102xa/fsl_serdes.h       |  4 ++++
 arch/powerpc/cpu/mpc85xx/bsc9132_serdes.c            |  9 +++++++++
 arch/powerpc/cpu/mpc85xx/c29x_serdes.c               |  9 +++++++++
 arch/powerpc/cpu/mpc85xx/fsl_corenet2_serdes.c       | 18 ++++++++++++++++++
 arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c        |  8 ++++++++
 arch/powerpc/cpu/mpc85xx/mpc8536_serdes.c            | 20 +++++++++++++++++++-
 arch/powerpc/cpu/mpc85xx/mpc8544_serdes.c            | 20 +++++++++++++++++++-
 arch/powerpc/cpu/mpc85xx/mpc8548_serdes.c            |  9 +++++++++
 arch/powerpc/cpu/mpc85xx/mpc8568_serdes.c            |  9 +++++++++
 arch/powerpc/cpu/mpc85xx/mpc8569_serdes.c            |  9 +++++++++
 arch/powerpc/cpu/mpc85xx/mpc8572_serdes.c            |  9 +++++++++
 arch/powerpc/cpu/mpc85xx/p1010_serdes.c              | 20 +++++++++++++++++++-
 arch/powerpc/cpu/mpc85xx/p1021_serdes.c              |  9 +++++++++
 arch/powerpc/cpu/mpc85xx/p1022_serdes.c              | 20 +++++++++++++++++++-
 arch/powerpc/cpu/mpc85xx/p1023_serdes.c              | 12 +++++++++++-
 arch/powerpc/cpu/mpc85xx/p2020_serdes.c              |  9 +++++++++
 arch/powerpc/cpu/mpc86xx/mpc8610_serdes.c            | 20 +++++++++++++++++++-
 arch/powerpc/cpu/mpc86xx/mpc8641_serdes.c            | 20 +++++++++++++++++++-
 arch/powerpc/include/asm/fsl_serdes.h                |  4 ++++
 23 files changed, 276 insertions(+), 9 deletions(-)

diff --git a/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.c b/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.c
index 9b78acb..86ace90 100644
--- a/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.c
+++ b/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.c
@@ -23,9 +23,15 @@ int is_serdes_configured(enum srds_prtcl device)
 	u64 ret = 0;
 
 #ifdef CONFIG_SYS_FSL_SRDS_1
+	if (!(serdes1_prtcl_map & (1ULL << NONE)))
+		fsl_serdes_init();
+
 	ret |= (1ULL << device) & serdes1_prtcl_map;
 #endif
 #ifdef CONFIG_SYS_FSL_SRDS_2
+	if (!(serdes2_prtcl_map & (1ULL << NONE)))
+		fsl_serdes_init();
+
 	ret |= (1ULL << device) & serdes2_prtcl_map;
 #endif
 
@@ -87,19 +93,24 @@ u64 serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift)
 		serdes_prtcl_map |= (1ULL << lane_prtcl);
 	}
 
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes_prtcl_map |= (1ULL << NONE);
+
 	return serdes_prtcl_map;
 }
 
 void fsl_serdes_init(void)
 {
 #ifdef CONFIG_SYS_FSL_SRDS_1
-	serdes1_prtcl_map = serdes_init(FSL_SRDS_1,
+	if (!(serdes1_prtcl_map & (1ULL << NONE)))
+		serdes1_prtcl_map = serdes_init(FSL_SRDS_1,
 					CONFIG_SYS_FSL_SERDES_ADDR,
 					RCWSR4_SRDS1_PRTCL_MASK,
 					RCWSR4_SRDS1_PRTCL_SHIFT);
 #endif
 #ifdef CONFIG_SYS_FSL_SRDS_2
-	serdes2_prtcl_map = serdes_init(FSL_SRDS_2,
+	if (!(serdes2_prtcl_map & (1ULL << NONE)))
+		serdes2_prtcl_map = serdes_init(FSL_SRDS_2,
 					CONFIG_SYS_FSL_SERDES_ADDR +
 					FSL_SRDS_2 * 0x1000,
 					RCWSR4_SRDS2_PRTCL_MASK,
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_serdes.c b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_serdes.c
index f73092a..29cd28e 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_serdes.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_serdes.c
@@ -22,9 +22,15 @@ int is_serdes_configured(enum srds_prtcl device)
 	int ret = 0;
 
 #ifdef CONFIG_SYS_FSL_SRDS_1
+	if (!serdes1_prtcl_map[NONE])
+		fsl_serdes_init();
+
 	ret |= serdes1_prtcl_map[device];
 #endif
 #ifdef CONFIG_SYS_FSL_SRDS_2
+	if (!serdes2_prtcl_map[NONE])
+		fsl_serdes_init();
+
 	ret |= serdes2_prtcl_map[device];
 #endif
 
@@ -98,6 +104,9 @@ void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift,
 	u32 cfg;
 	int lane;
 
+	if (serdes_prtcl_map[NONE])
+		return;
+
 	memset(serdes_prtcl_map, 0, sizeof(u8) * SERDES_PRCTL_COUNT);
 
 	cfg = gur_in32(&gur->rcwsr[4]) & sd_prctl_mask;
@@ -115,6 +124,9 @@ void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift,
 		else
 			serdes_prtcl_map[lane_prtcl] = 1;
 	}
+
+	/* Set the first element to indicate serdes has been initialized */
+	serdes_prtcl_map[NONE] = 1;
 }
 
 void fsl_serdes_init(void)
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c
index be6acc6..9110d7a 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c
@@ -28,9 +28,15 @@ int is_serdes_configured(enum srds_prtcl device)
 	int ret = 0;
 
 #ifdef CONFIG_SYS_FSL_SRDS_1
+	if (!serdes1_prtcl_map[NONE])
+		fsl_serdes_init();
+
 	ret |= serdes1_prtcl_map[device];
 #endif
 #ifdef CONFIG_SYS_FSL_SRDS_2
+	if (!serdes2_prtcl_map[NONE])
+		fsl_serdes_init();
+
 	ret |= serdes2_prtcl_map[device];
 #endif
 
@@ -79,6 +85,9 @@ void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift,
 	u32 cfg;
 	int lane;
 
+	if (serdes_prtcl_map[NONE])
+		return;
+
 	memset(serdes_prtcl_map, 0, sizeof(u8) * SERDES_PRCTL_COUNT);
 
 	cfg = gur_in32(&gur->rcwsr[28]) & sd_prctl_mask;
@@ -136,6 +145,9 @@ void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift,
 #endif
 		}
 	}
+
+	/* Set the first element to indicate serdes has been initialized */
+	serdes_prtcl_map[NONE] = 1;
 }
 
 void fsl_serdes_init(void)
diff --git a/arch/arm/include/asm/arch-fsl-layerscape/fsl_serdes.h b/arch/arm/include/asm/arch-fsl-layerscape/fsl_serdes.h
index e1b3f44..7847bf4 100644
--- a/arch/arm/include/asm/arch-fsl-layerscape/fsl_serdes.h
+++ b/arch/arm/include/asm/arch-fsl-layerscape/fsl_serdes.h
@@ -11,6 +11,10 @@
 
 #ifdef CONFIG_LS2080A
 enum srds_prtcl {
+	/*
+	 * Nobody will check whether the device 'NONE' has been configured,
+	 * So use it to indicate if the serdes_prtcl_map has been initialized.
+	 */
 	NONE = 0,
 	PCIE1,
 	PCIE2,
@@ -57,6 +61,10 @@ enum srds {
 };
 #elif defined(CONFIG_FSL_LSCH2)
 enum srds_prtcl {
+	/*
+	 * Nobody will check whether the device 'NONE' has been configured,
+	 * So use it to indicate if the serdes_prtcl_map has been initialized.
+	 */
 	NONE = 0,
 	PCIE1,
 	PCIE2,
diff --git a/arch/arm/include/asm/arch-ls102xa/fsl_serdes.h b/arch/arm/include/asm/arch-ls102xa/fsl_serdes.h
index 3a92f5a..22a4275 100644
--- a/arch/arm/include/asm/arch-ls102xa/fsl_serdes.h
+++ b/arch/arm/include/asm/arch-ls102xa/fsl_serdes.h
@@ -10,6 +10,10 @@
 #include <config.h>
 
 enum srds_prtcl {
+	/*
+	 * Nobody will check whether the device 'NONE' has been configured,
+	 * So use it to indicate if the serdes_prtcl_map has been initialized.
+	 */
 	NONE = 0,
 	PCIE1,
 	PCIE2,
diff --git a/arch/powerpc/cpu/mpc85xx/bsc9132_serdes.c b/arch/powerpc/cpu/mpc85xx/bsc9132_serdes.c
index 399b208..4b5cd99 100644
--- a/arch/powerpc/cpu/mpc85xx/bsc9132_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/bsc9132_serdes.c
@@ -68,6 +68,9 @@ static u8 serdes1_cfg_tbl[][SRDS1_MAX_LANES] = {
 
 int is_serdes_configured(enum srds_prtcl prtcl)
 {
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << prtcl) & serdes1_prtcl_map;
 }
 
@@ -79,6 +82,9 @@ void fsl_serdes_init(void)
 				MPC85xx_PORDEVSR_IO_SEL_SHIFT;
 	int lane;
 
+	if (serdes1_prtcl_map & (1 << NONE))
+		return;
+
 	debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
 	if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
@@ -90,4 +96,7 @@ void fsl_serdes_init(void)
 		enum srds_prtcl lane_prtcl = serdes1_cfg_tbl[srds_cfg][lane];
 		serdes1_prtcl_map |= (1 << lane_prtcl);
 	}
+
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
 }
diff --git a/arch/powerpc/cpu/mpc85xx/c29x_serdes.c b/arch/powerpc/cpu/mpc85xx/c29x_serdes.c
index 51972cb..74d27b9 100644
--- a/arch/powerpc/cpu/mpc85xx/c29x_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/c29x_serdes.c
@@ -32,6 +32,9 @@ static const struct serdes_config serdes1_cfg_tbl[] = {
 
 int is_serdes_configured(enum srds_prtcl device)
 {
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << device) & serdes1_prtcl_map;
 }
 
@@ -44,6 +47,9 @@ void fsl_serdes_init(void)
 	const struct serdes_config *ptr;
 	int lane;
 
+	if (serdes1_prtcl_map & (1 << NONE))
+		return;
+
 	debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
 	if (srds_cfg > ARRAY_SIZE(serdes1_cfg_tbl)) {
@@ -59,4 +65,7 @@ void fsl_serdes_init(void)
 		enum srds_prtcl lane_prtcl = ptr->lanes[lane];
 		serdes1_prtcl_map |= (1 << lane_prtcl);
 	}
+
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
 }
diff --git a/arch/powerpc/cpu/mpc85xx/fsl_corenet2_serdes.c b/arch/powerpc/cpu/mpc85xx/fsl_corenet2_serdes.c
index 9920839..ebc9b81 100644
--- a/arch/powerpc/cpu/mpc85xx/fsl_corenet2_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/fsl_corenet2_serdes.c
@@ -92,15 +92,27 @@ int is_serdes_configured(enum srds_prtcl device)
 	int ret = 0;
 
 #ifdef CONFIG_SYS_FSL_SRDS_1
+	if (!serdes1_prtcl_map[NONE])
+		fsl_serdes_init();
+
 	ret |= serdes1_prtcl_map[device];
 #endif
 #ifdef CONFIG_SYS_FSL_SRDS_2
+	if (!serdes2_prtcl_map[NONE])
+		fsl_serdes_init();
+
 	ret |= serdes2_prtcl_map[device];
 #endif
 #ifdef CONFIG_SYS_FSL_SRDS_3
+	if (!serdes3_prtcl_map[NONE])
+		fsl_serdes_init();
+
 	ret |= serdes3_prtcl_map[device];
 #endif
 #ifdef CONFIG_SYS_FSL_SRDS_4
+	if (!serdes4_prtcl_map[NONE])
+		fsl_serdes_init();
+
 	ret |= serdes4_prtcl_map[device];
 #endif
 
@@ -184,6 +196,9 @@ void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift,
 	u32 cfg;
 	int lane;
 
+	if (serdes_prtcl_map[NONE])
+		return;
+
 	memset(serdes_prtcl_map, 0, sizeof(u8) * SERDES_PRCTL_COUNT);
 #ifdef CONFIG_SYS_FSL_ERRATUM_A007186
 	struct ccsr_sfp_regs  __iomem *sfp_regs =
@@ -325,6 +340,9 @@ void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift,
 		else
 			serdes_prtcl_map[lane_prtcl] = 1;
 	}
+
+	/* Set the first element to indicate serdes has been initialized */
+	serdes_prtcl_map[NONE] = 1;
 }
 
 void fsl_serdes_init(void)
diff --git a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c
index ba22f90..85739e9 100644
--- a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c
@@ -136,6 +136,9 @@ int is_serdes_configured(enum srds_prtcl device)
 	if (!(in_be32(&gur->rcwsr[5]) & FSL_CORENET_RCWSR5_SRDS_EN))
 		return 0;
 
+	if (!(serdes_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << device) & serdes_prtcl_map;
 }
 
@@ -514,6 +517,8 @@ void fsl_serdes_init(void)
 	if (getenv_f("hwconfig", buffer, sizeof(buffer)) > 0)
 		buf = buffer;
 #endif
+	if (serdes_prtcl_map & (1 << NONE))
+		return;
 
 	/* Is serdes enabled at all? */
 	if (!(in_be32(&gur->rcwsr[5]) & FSL_CORENET_RCWSR5_SRDS_EN))
@@ -857,6 +862,9 @@ void fsl_serdes_init(void)
 			     SRDS_RSTCTL_SDPD);
 	}
 #endif
+
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes_prtcl_map |= (1 << NONE);
 }
 
 const char *serdes_clock_to_string(u32 clock)
diff --git a/arch/powerpc/cpu/mpc85xx/mpc8536_serdes.c b/arch/powerpc/cpu/mpc85xx/mpc8536_serdes.c
index baf52d5..8c075f1 100644
--- a/arch/powerpc/cpu/mpc85xx/mpc8536_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/mpc8536_serdes.c
@@ -71,11 +71,19 @@ static u8 serdes2_cfg_tbl[][SRDS2_MAX_LANES] = {
 
 int is_serdes_configured(enum srds_prtcl device)
 {
-	int ret = (1 << device) & serdes1_prtcl_map;
+	int ret;
+
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
+	ret = (1 << device) & serdes1_prtcl_map;
 
 	if (ret)
 		return ret;
 
+	if (!(serdes2_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << device) & serdes2_prtcl_map;
 }
 
@@ -88,6 +96,10 @@ void fsl_serdes_init(void)
 	u32 tmp;
 	int lane;
 
+	if (serdes1_prtcl_map & (1 << NONE) &&
+	    serdes2_prtcl_map & (1 << NONE))
+		return;
+
 	srds1_io_sel = (pordevsr & MPC85xx_PORDEVSR_IO_SEL) >>
 				MPC85xx_PORDEVSR_IO_SEL_SHIFT;
 
@@ -221,6 +233,9 @@ void fsl_serdes_init(void)
 		serdes1_prtcl_map |= (1 << lane_prtcl);
 	}
 
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
+
 	if (srds2_io_sel >= ARRAY_SIZE(serdes2_cfg_tbl)) {
 		printf("Invalid PORDEVSR[SRDS2_IO_SEL] = %d\n", srds2_io_sel);
 		return;
@@ -230,4 +245,7 @@ void fsl_serdes_init(void)
 		enum srds_prtcl lane_prtcl = serdes2_cfg_tbl[srds2_io_sel][lane];
 		serdes2_prtcl_map |= (1 << lane_prtcl);
 	}
+
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes2_prtcl_map |= (1 << NONE);
 }
diff --git a/arch/powerpc/cpu/mpc85xx/mpc8544_serdes.c b/arch/powerpc/cpu/mpc85xx/mpc8544_serdes.c
index ed78a66..b27763e 100644
--- a/arch/powerpc/cpu/mpc85xx/mpc8544_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/mpc8544_serdes.c
@@ -34,11 +34,19 @@ static u8 serdes2_cfg_tbl[][SRDS2_MAX_LANES] = {
 
 int is_serdes_configured(enum srds_prtcl device)
 {
-	int ret = (1 << device) & serdes1_prtcl_map;
+	int ret;
+
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
+	ret = (1 << device) & serdes1_prtcl_map;
 
 	if (ret)
 		return ret;
 
+	if (!(serdes2_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << device) & serdes2_prtcl_map;
 }
 
@@ -50,6 +58,10 @@ void fsl_serdes_init(void)
 				MPC85xx_PORDEVSR_IO_SEL_SHIFT;
 	int lane;
 
+	if (serdes1_prtcl_map & (1 << NONE) &&
+	    serdes2_prtcl_map & (1 << NONE))
+		return;
+
 	debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
 	if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
@@ -61,6 +73,9 @@ void fsl_serdes_init(void)
 		serdes1_prtcl_map |= (1 << lane_prtcl);
 	}
 
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
+
 	if (srds_cfg >= ARRAY_SIZE(serdes2_cfg_tbl)) {
 		printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
 		return;
@@ -76,4 +91,7 @@ void fsl_serdes_init(void)
 
 	if (pordevsr & MPC85xx_PORDEVSR_SGMII3_DIS)
 		serdes2_prtcl_map &= ~(1 << SGMII_TSEC3);
+
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes2_prtcl_map |= (1 << NONE);
 }
diff --git a/arch/powerpc/cpu/mpc85xx/mpc8548_serdes.c b/arch/powerpc/cpu/mpc85xx/mpc8548_serdes.c
index d146955..f1042d5 100644
--- a/arch/powerpc/cpu/mpc85xx/mpc8548_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/mpc8548_serdes.c
@@ -24,6 +24,9 @@ static u8 serdes1_cfg_tbl[][SRDS1_MAX_LANES] = {
 
 int is_serdes_configured(enum srds_prtcl prtcl)
 {
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << prtcl) & serdes1_prtcl_map;
 }
 
@@ -35,6 +38,9 @@ void fsl_serdes_init(void)
 				MPC85xx_PORDEVSR_IO_SEL_SHIFT;
 	int lane;
 
+	if (serdes1_prtcl_map & (1 << NONE))
+		return;
+
 	debug("PORDEVSR[IO_SEL] = %x\n", srds1_cfg);
 
 	if (srds1_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
@@ -46,4 +52,7 @@ void fsl_serdes_init(void)
 		enum srds_prtcl lane_prtcl = serdes1_cfg_tbl[srds1_cfg][lane];
 		serdes1_prtcl_map |= (1 << lane_prtcl);
 	}
+
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
 }
diff --git a/arch/powerpc/cpu/mpc85xx/mpc8568_serdes.c b/arch/powerpc/cpu/mpc85xx/mpc8568_serdes.c
index 9199f01..7c287a0 100644
--- a/arch/powerpc/cpu/mpc85xx/mpc8568_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/mpc8568_serdes.c
@@ -24,6 +24,9 @@ static u8 serdes1_cfg_tbl[][SRDS1_MAX_LANES] = {
 
 int is_serdes_configured(enum srds_prtcl prtcl)
 {
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << prtcl) & serdes1_prtcl_map;
 }
 
@@ -35,6 +38,9 @@ void fsl_serdes_init(void)
 				MPC85xx_PORDEVSR_IO_SEL_SHIFT;
 	int lane;
 
+	if (serdes1_prtcl_map & (1 << NONE))
+		return;
+
 	debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
 	if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
@@ -46,4 +52,7 @@ void fsl_serdes_init(void)
 		enum srds_prtcl lane_prtcl = serdes1_cfg_tbl[srds_cfg][lane];
 		serdes1_prtcl_map |= (1 << lane_prtcl);
 	}
+
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
 }
diff --git a/arch/powerpc/cpu/mpc85xx/mpc8569_serdes.c b/arch/powerpc/cpu/mpc85xx/mpc8569_serdes.c
index 6c80b5e..cc8ddb2 100644
--- a/arch/powerpc/cpu/mpc85xx/mpc8569_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/mpc8569_serdes.c
@@ -33,6 +33,9 @@ static u8 serdes1_cfg_tbl[][SRDS1_MAX_LANES] = {
 
 int is_serdes_configured(enum srds_prtcl prtcl)
 {
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << prtcl) & serdes1_prtcl_map;
 }
 
@@ -44,6 +47,9 @@ void fsl_serdes_init(void)
 				MPC85xx_PORDEVSR_IO_SEL_SHIFT;
 	int lane;
 
+	if (serdes1_prtcl_map & (1 << NONE))
+		return;
+
 	debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
 	if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
@@ -55,4 +61,7 @@ void fsl_serdes_init(void)
 		enum srds_prtcl lane_prtcl = serdes1_cfg_tbl[srds_cfg][lane];
 		serdes1_prtcl_map |= (1 << lane_prtcl);
 	}
+
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
 }
diff --git a/arch/powerpc/cpu/mpc85xx/mpc8572_serdes.c b/arch/powerpc/cpu/mpc85xx/mpc8572_serdes.c
index 3632eb5..1f0f474 100644
--- a/arch/powerpc/cpu/mpc85xx/mpc8572_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/mpc8572_serdes.c
@@ -28,6 +28,9 @@ static u8 serdes1_cfg_tbl[][SRDS1_MAX_LANES] = {
 
 int is_serdes_configured(enum srds_prtcl prtcl)
 {
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << prtcl) & serdes1_prtcl_map;
 }
 
@@ -39,6 +42,9 @@ void fsl_serdes_init(void)
 				MPC85xx_PORDEVSR_IO_SEL_SHIFT;
 	int lane;
 
+	if (serdes1_prtcl_map & (1 << NONE))
+		return;
+
 	debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
 	if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
@@ -62,4 +68,7 @@ void fsl_serdes_init(void)
 
 	if (!(pordevsr & MPC85xx_PORDEVSR_SGMII4_DIS))
 		serdes1_prtcl_map |= (1 << SGMII_TSEC4);
+
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
 }
diff --git a/arch/powerpc/cpu/mpc85xx/p1010_serdes.c b/arch/powerpc/cpu/mpc85xx/p1010_serdes.c
index 4b965f7..d8c0b62 100644
--- a/arch/powerpc/cpu/mpc85xx/p1010_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/p1010_serdes.c
@@ -33,11 +33,19 @@ static const u8 serdes2_cfg_tbl[][SRDS2_MAX_LANES] = {
 
 int is_serdes_configured(enum srds_prtcl device)
 {
-	int ret = (1 << device) & serdes1_prtcl_map;
+	int ret;
+
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
+	ret = (1 << device) & serdes1_prtcl_map;
 
 	if (ret)
 		return ret;
 
+	if (!(serdes2_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << device) & serdes2_prtcl_map;
 }
 
@@ -49,6 +57,10 @@ void fsl_serdes_init(void)
 				MPC85xx_PORDEVSR_IO_SEL_SHIFT;
 	int lane;
 
+	if (serdes1_prtcl_map & (1 << NONE) &&
+	    serdes2_prtcl_map & (1 << NONE))
+		return;
+
 	debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
 	if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
@@ -60,6 +72,9 @@ void fsl_serdes_init(void)
 		serdes1_prtcl_map |= (1 << lane_prtcl);
 	}
 
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
+
 	if (srds_cfg >= ARRAY_SIZE(serdes2_cfg_tbl)) {
 		printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
 		return;
@@ -69,4 +84,7 @@ void fsl_serdes_init(void)
 		enum srds_prtcl lane_prtcl = serdes2_cfg_tbl[srds_cfg][lane];
 		serdes2_prtcl_map |= (1 << lane_prtcl);
 	}
+
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes2_prtcl_map |= (1 << NONE);
 }
diff --git a/arch/powerpc/cpu/mpc85xx/p1021_serdes.c b/arch/powerpc/cpu/mpc85xx/p1021_serdes.c
index 99a77bd..77b9439 100644
--- a/arch/powerpc/cpu/mpc85xx/p1021_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/p1021_serdes.c
@@ -41,6 +41,9 @@ static u8 serdes1_cfg_tbl[][SRDS1_MAX_LANES] = {
 
 int is_serdes_configured(enum srds_prtcl prtcl)
 {
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << prtcl) & serdes1_prtcl_map;
 }
 
@@ -55,6 +58,9 @@ void fsl_serdes_init(void)
 	int lane;
 	u32 mask, val;
 
+	if (serdes1_prtcl_map & (1 << NONE))
+		return;
+
 	debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
 	if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
@@ -67,6 +73,9 @@ void fsl_serdes_init(void)
 		serdes1_prtcl_map |= (1 << lane_prtcl);
 	}
 
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
+
 	/* Init SERDES Receiver electrical idle detection control for PCIe */
 
 	/* Lane 0 is always PCIe 1 */
diff --git a/arch/powerpc/cpu/mpc85xx/p1022_serdes.c b/arch/powerpc/cpu/mpc85xx/p1022_serdes.c
index 14d17eb..88013d4 100644
--- a/arch/powerpc/cpu/mpc85xx/p1022_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/p1022_serdes.c
@@ -72,11 +72,19 @@ static const u8 serdes2_cfg_tbl[][SRDS2_MAX_LANES] = {
 
 int is_serdes_configured(enum srds_prtcl device)
 {
-	int ret = (1 << device) & serdes1_prtcl_map;
+	int ret;
+
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
+	ret = (1 << device) & serdes1_prtcl_map;
 
 	if (ret)
 		return ret;
 
+	if (!(serdes2_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << device) & serdes2_prtcl_map;
 }
 
@@ -88,6 +96,10 @@ void fsl_serdes_init(void)
 				MPC85xx_PORDEVSR_IO_SEL_SHIFT;
 	int lane;
 
+	if (serdes1_prtcl_map & (1 << NONE) &&
+	    serdes2_prtcl_map & (1 << NONE))
+		return;
+
 	debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
 	if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
@@ -99,6 +111,9 @@ void fsl_serdes_init(void)
 		serdes1_prtcl_map |= (1 << lane_prtcl);
 	}
 
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
+
 	if (srds_cfg >= ARRAY_SIZE(serdes2_cfg_tbl)) {
 		printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
 		return;
@@ -108,4 +123,7 @@ void fsl_serdes_init(void)
 		enum srds_prtcl lane_prtcl = serdes2_cfg_tbl[srds_cfg][lane];
 		serdes2_prtcl_map |= (1 << lane_prtcl);
 	}
+
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes2_prtcl_map |= (1 << NONE);
 }
diff --git a/arch/powerpc/cpu/mpc85xx/p1023_serdes.c b/arch/powerpc/cpu/mpc85xx/p1023_serdes.c
index e83b0a3..b2b9f95 100644
--- a/arch/powerpc/cpu/mpc85xx/p1023_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/p1023_serdes.c
@@ -24,7 +24,12 @@ static const u8 serdes1_cfg_tbl[][SRDS1_MAX_LANES] = {
 
 int is_serdes_configured(enum srds_prtcl device)
 {
-	int ret = (1 << device) & serdes1_prtcl_map;
+	int ret;
+
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
+	ret = (1 << device) & serdes1_prtcl_map;
 	return ret;
 }
 
@@ -36,6 +41,9 @@ void fsl_serdes_init(void)
 				MPC85xx_PORDEVSR_IO_SEL_SHIFT;
 	int lane;
 
+	if (serdes1_prtcl_map & (1 << NONE))
+		return;
+
 	debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
 	if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
@@ -47,4 +55,6 @@ void fsl_serdes_init(void)
 		serdes1_prtcl_map |= (1 << lane_prtcl);
 	}
 
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
 }
diff --git a/arch/powerpc/cpu/mpc85xx/p2020_serdes.c b/arch/powerpc/cpu/mpc85xx/p2020_serdes.c
index 59d402c..0890eaa 100644
--- a/arch/powerpc/cpu/mpc85xx/p2020_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/p2020_serdes.c
@@ -32,6 +32,9 @@ static u8 serdes1_cfg_tbl[][SRDS1_MAX_LANES] = {
 
 int is_serdes_configured(enum srds_prtcl prtcl)
 {
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << prtcl) & serdes1_prtcl_map;
 }
 
@@ -43,6 +46,9 @@ void fsl_serdes_init(void)
 				MPC85xx_PORDEVSR_IO_SEL_SHIFT;
 	int lane;
 
+	if (serdes1_prtcl_map & (1 << NONE))
+		return;
+
 	debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
 	if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
@@ -54,4 +60,7 @@ void fsl_serdes_init(void)
 		enum srds_prtcl lane_prtcl = serdes1_cfg_tbl[srds_cfg][lane];
 		serdes1_prtcl_map |= (1 << lane_prtcl);
 	}
+
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
 }
diff --git a/arch/powerpc/cpu/mpc86xx/mpc8610_serdes.c b/arch/powerpc/cpu/mpc86xx/mpc8610_serdes.c
index 2a7e3bf..ea4f4c8 100644
--- a/arch/powerpc/cpu/mpc86xx/mpc8610_serdes.c
+++ b/arch/powerpc/cpu/mpc86xx/mpc8610_serdes.c
@@ -29,11 +29,19 @@ static u8 serdes2_cfg_tbl[][SRDS2_MAX_LANES] = {
 
 int is_serdes_configured(enum srds_prtcl device)
 {
-	int ret = (1 << device) & serdes1_prtcl_map;
+	int ret;
+
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
+	ret = (1 << device) & serdes1_prtcl_map;
 
 	if (ret)
 		return ret;
 
+	if (!(serdes2_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << device) & serdes2_prtcl_map;
 }
 
@@ -46,6 +54,10 @@ void fsl_serdes_init(void)
 				MPC8610_PORDEVSR_IO_SEL_SHIFT;
 	int lane;
 
+	if (serdes1_prtcl_map & (1 << NONE) &&
+	    serdes2_prtcl_map & (1 << NONE))
+		return;
+
 	debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
 	if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
@@ -57,6 +69,9 @@ void fsl_serdes_init(void)
 		serdes1_prtcl_map |= (1 << lane_prtcl);
 	}
 
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
+
 	if (srds_cfg >= ARRAY_SIZE(serdes2_cfg_tbl)) {
 		printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
 		return;
@@ -66,4 +81,7 @@ void fsl_serdes_init(void)
 		enum srds_prtcl lane_prtcl = serdes2_cfg_tbl[srds_cfg][lane];
 		serdes2_prtcl_map |= (1 << lane_prtcl);
 	}
+
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes2_prtcl_map |= (1 << NONE);
 }
diff --git a/arch/powerpc/cpu/mpc86xx/mpc8641_serdes.c b/arch/powerpc/cpu/mpc86xx/mpc8641_serdes.c
index cc0f8e9..5b12cbd 100644
--- a/arch/powerpc/cpu/mpc86xx/mpc8641_serdes.c
+++ b/arch/powerpc/cpu/mpc86xx/mpc8641_serdes.c
@@ -38,11 +38,19 @@ static u8 serdes2_cfg_tbl[][SRDS2_MAX_LANES] = {
 
 int is_serdes_configured(enum srds_prtcl device)
 {
-	int ret = (1 << device) & serdes1_prtcl_map;
+	int ret;
+
+	if (!(serdes1_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
+	ret = (1 << device) & serdes1_prtcl_map;
 
 	if (ret)
 		return ret;
 
+	if (!(serdes2_prtcl_map & (1 << NONE)))
+		fsl_serdes_init();
+
 	return (1 << device) & serdes2_prtcl_map;
 }
 
@@ -55,6 +63,10 @@ void fsl_serdes_init(void)
 				MPC8641_PORDEVSR_IO_SEL_SHIFT;
 	int lane;
 
+	if (serdes1_prtcl_map & (1 << NONE) &&
+	    serdes2_prtcl_map & (1 << NONE))
+		return;
+
 	debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
 	if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
@@ -66,6 +78,9 @@ void fsl_serdes_init(void)
 		serdes1_prtcl_map |= (1 << lane_prtcl);
 	}
 
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes1_prtcl_map |= (1 << NONE);
+
 	if (srds_cfg >= ARRAY_SIZE(serdes2_cfg_tbl)) {
 		printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
 		return;
@@ -75,4 +90,7 @@ void fsl_serdes_init(void)
 		enum srds_prtcl lane_prtcl = serdes2_cfg_tbl[srds_cfg][lane];
 		serdes2_prtcl_map |= (1 << lane_prtcl);
 	}
+
+	/* Set the first bit to indicate serdes has been initialized */
+	serdes2_prtcl_map |= (1 << NONE);
 }
diff --git a/arch/powerpc/include/asm/fsl_serdes.h b/arch/powerpc/include/asm/fsl_serdes.h
index 45e248e..bef961c 100644
--- a/arch/powerpc/include/asm/fsl_serdes.h
+++ b/arch/powerpc/include/asm/fsl_serdes.h
@@ -10,6 +10,10 @@
 #include <config.h>
 
 enum srds_prtcl {
+	/*
+	 * Nobody will check whether the device 'NONE' has been configured,
+	 * So use it to indicate if the serdes_prtcl_map has been initialized.
+	 */
 	NONE = 0,
 	PCIE1,
 	PCIE2,
-- 
2.1.0.27.g96db324



More information about the U-Boot mailing list