]> git.sur5r.net Git - u-boot/blobdiff - arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c
Merge git://git.denx.de/u-boot-fdt
[u-boot] / arch / arm / cpu / armv8 / fsl-layerscape / fsl_lsch3_serdes.c
index 2ab8da64030763fd87055b1c5f5f5f0fdab52959..7faa86c3fdf41587052d19a2a3d957004cc3df50 100644 (file)
@@ -6,7 +6,7 @@
 
 #include <common.h>
 #include <asm/io.h>
-#include <asm/errno.h>
+#include <linux/errno.h>
 #include <asm/arch/fsl_serdes.h>
 #include <asm/arch/soc.h>
 #include <fsl-mc/ldpaa_wriop.h>
@@ -18,14 +18,25 @@ static u8 serdes1_prtcl_map[SERDES_PRCTL_COUNT];
 static u8 serdes2_prtcl_map[SERDES_PRCTL_COUNT];
 #endif
 
+#ifdef CONFIG_FSL_MC_ENET
+int xfi_dpmac[XFI8 + 1];
+int sgmii_dpmac[SGMII16 + 1];
+#endif
+
 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
 
@@ -74,7 +85,10 @@ void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift,
        u32 cfg;
        int lane;
 
-       memset(serdes_prtcl_map, 0, sizeof(serdes_prtcl_map));
+       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;
        cfg >>= sd_prctl_shift;
@@ -116,19 +130,38 @@ void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift,
                                wriop_init_dpmac(sd, 12, (int)lane_prtcl);
                                break;
                        default:
+                               if (lane_prtcl >= XFI1 && lane_prtcl <= XFI8)
+                                       wriop_init_dpmac(sd,
+                                                        xfi_dpmac[lane_prtcl],
+                                                        (int)lane_prtcl);
+
                                 if (lane_prtcl >= SGMII1 &&
-                                          lane_prtcl <= SGMII16)
-                                       wriop_init_dpmac(sd, lane + 1,
+                                    lane_prtcl <= SGMII16)
+                                       wriop_init_dpmac(sd, sgmii_dpmac[
+                                                        lane_prtcl],
                                                         (int)lane_prtcl);
                                break;
                        }
 #endif
                }
        }
+
+       /* Set the first element to indicate serdes has been initialized */
+       serdes_prtcl_map[NONE] = 1;
 }
 
 void fsl_serdes_init(void)
 {
+#ifdef CONFIG_FSL_MC_ENET
+       int i , j;
+
+       for (i = XFI1, j = 1; i <= XFI8; i++, j++)
+               xfi_dpmac[i] = j;
+
+       for (i = SGMII1, j = 1; i <= SGMII16; i++, j++)
+               sgmii_dpmac[i] = j;
+#endif
+
 #ifdef CONFIG_SYS_FSL_SRDS_1
        serdes_init(FSL_SRDS_1,
                    CONFIG_SYS_FSL_LSCH3_SERDES_ADDR,