fsl: serdes: ensure accessing the initialized maps of serdes protocol
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@nxp.com>
Reviewed-by: York Sun <york.sun@nxp.com>
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 @@
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 @@
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 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 @@
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 @@
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 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 @@
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 @@
#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..9f94b45 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 @@
};
#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..fafc44b 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,