19f3183d2SMingkai Hu /*
29f3183d2SMingkai Hu * Copyright 2014-2015 Freescale Semiconductor, Inc.
39f3183d2SMingkai Hu *
49f3183d2SMingkai Hu * SPDX-License-Identifier: GPL-2.0+
59f3183d2SMingkai Hu */
69f3183d2SMingkai Hu
79f3183d2SMingkai Hu #include <common.h>
89f3183d2SMingkai Hu #include <asm/io.h>
91221ce45SMasahiro Yamada #include <linux/errno.h>
109f3183d2SMingkai Hu #include <asm/arch/fsl_serdes.h>
119f3183d2SMingkai Hu #include <asm/arch/soc.h>
129f3183d2SMingkai Hu #include <fsl-mc/ldpaa_wriop.h>
139f3183d2SMingkai Hu
149f3183d2SMingkai Hu #ifdef CONFIG_SYS_FSL_SRDS_1
159f3183d2SMingkai Hu static u8 serdes1_prtcl_map[SERDES_PRCTL_COUNT];
169f3183d2SMingkai Hu #endif
179f3183d2SMingkai Hu #ifdef CONFIG_SYS_FSL_SRDS_2
189f3183d2SMingkai Hu static u8 serdes2_prtcl_map[SERDES_PRCTL_COUNT];
199f3183d2SMingkai Hu #endif
209f3183d2SMingkai Hu
21*1f55a938SSantan Kumar #if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD)
2299e904c1SPrabhakar Kushwaha int xfi_dpmac[XFI8 + 1];
2399e904c1SPrabhakar Kushwaha int sgmii_dpmac[SGMII16 + 1];
2499e904c1SPrabhakar Kushwaha #endif
2599e904c1SPrabhakar Kushwaha
wriop_init_dpmac_qsgmii(int sd,int lane_prtcl)261b7dba99SPrabhakar Kushwaha __weak void wriop_init_dpmac_qsgmii(int sd, int lane_prtcl)
271b7dba99SPrabhakar Kushwaha {
281b7dba99SPrabhakar Kushwaha return;
291b7dba99SPrabhakar Kushwaha }
301b7dba99SPrabhakar Kushwaha
is_serdes_configured(enum srds_prtcl device)319f3183d2SMingkai Hu int is_serdes_configured(enum srds_prtcl device)
329f3183d2SMingkai Hu {
339f3183d2SMingkai Hu int ret = 0;
349f3183d2SMingkai Hu
359f3183d2SMingkai Hu #ifdef CONFIG_SYS_FSL_SRDS_1
3671fe2225SHou Zhiqiang if (!serdes1_prtcl_map[NONE])
3771fe2225SHou Zhiqiang fsl_serdes_init();
3871fe2225SHou Zhiqiang
399f3183d2SMingkai Hu ret |= serdes1_prtcl_map[device];
409f3183d2SMingkai Hu #endif
419f3183d2SMingkai Hu #ifdef CONFIG_SYS_FSL_SRDS_2
4271fe2225SHou Zhiqiang if (!serdes2_prtcl_map[NONE])
4371fe2225SHou Zhiqiang fsl_serdes_init();
4471fe2225SHou Zhiqiang
459f3183d2SMingkai Hu ret |= serdes2_prtcl_map[device];
469f3183d2SMingkai Hu #endif
479f3183d2SMingkai Hu
489f3183d2SMingkai Hu return !!ret;
499f3183d2SMingkai Hu }
509f3183d2SMingkai Hu
serdes_get_first_lane(u32 sd,enum srds_prtcl device)519f3183d2SMingkai Hu int serdes_get_first_lane(u32 sd, enum srds_prtcl device)
529f3183d2SMingkai Hu {
539f3183d2SMingkai Hu struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
547b45b383SPrabhakar Kushwaha u32 cfg = 0;
559f3183d2SMingkai Hu int i;
569f3183d2SMingkai Hu
579f3183d2SMingkai Hu switch (sd) {
589f3183d2SMingkai Hu #ifdef CONFIG_SYS_FSL_SRDS_1
599f3183d2SMingkai Hu case FSL_SRDS_1:
607b45b383SPrabhakar Kushwaha cfg = gur_in32(&gur->rcwsr[FSL_CHASSIS3_SRDS1_REGSR - 1]);
617b45b383SPrabhakar Kushwaha cfg &= FSL_CHASSIS3_SRDS1_PRTCL_MASK;
627b45b383SPrabhakar Kushwaha cfg >>= FSL_CHASSIS3_SRDS1_PRTCL_SHIFT;
639f3183d2SMingkai Hu break;
649f3183d2SMingkai Hu #endif
659f3183d2SMingkai Hu #ifdef CONFIG_SYS_FSL_SRDS_2
669f3183d2SMingkai Hu case FSL_SRDS_2:
677b45b383SPrabhakar Kushwaha cfg = gur_in32(&gur->rcwsr[FSL_CHASSIS3_SRDS2_REGSR - 1]);
687b45b383SPrabhakar Kushwaha cfg &= FSL_CHASSIS3_SRDS2_PRTCL_MASK;
697b45b383SPrabhakar Kushwaha cfg >>= FSL_CHASSIS3_SRDS2_PRTCL_SHIFT;
709f3183d2SMingkai Hu break;
719f3183d2SMingkai Hu #endif
729f3183d2SMingkai Hu default:
739f3183d2SMingkai Hu printf("invalid SerDes%d\n", sd);
749f3183d2SMingkai Hu break;
759f3183d2SMingkai Hu }
769f3183d2SMingkai Hu /* Is serdes enabled at all? */
779f3183d2SMingkai Hu if (cfg == 0)
789f3183d2SMingkai Hu return -ENODEV;
799f3183d2SMingkai Hu
809f3183d2SMingkai Hu for (i = 0; i < SRDS_MAX_LANES; i++) {
819f3183d2SMingkai Hu if (serdes_get_prtcl(sd, cfg, i) == device)
829f3183d2SMingkai Hu return i;
839f3183d2SMingkai Hu }
849f3183d2SMingkai Hu
859f3183d2SMingkai Hu return -ENODEV;
869f3183d2SMingkai Hu }
879f3183d2SMingkai Hu
serdes_init(u32 sd,u32 sd_addr,u32 rcwsr,u32 sd_prctl_mask,u32 sd_prctl_shift,u8 serdes_prtcl_map[SERDES_PRCTL_COUNT])887b45b383SPrabhakar Kushwaha void serdes_init(u32 sd, u32 sd_addr, u32 rcwsr, u32 sd_prctl_mask,
897b45b383SPrabhakar Kushwaha u32 sd_prctl_shift, u8 serdes_prtcl_map[SERDES_PRCTL_COUNT])
909f3183d2SMingkai Hu {
919f3183d2SMingkai Hu struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
929f3183d2SMingkai Hu u32 cfg;
939f3183d2SMingkai Hu int lane;
949f3183d2SMingkai Hu
9571fe2225SHou Zhiqiang if (serdes_prtcl_map[NONE])
9671fe2225SHou Zhiqiang return;
9771fe2225SHou Zhiqiang
981a338921STom Rini memset(serdes_prtcl_map, 0, sizeof(u8) * SERDES_PRCTL_COUNT);
999f3183d2SMingkai Hu
1007b45b383SPrabhakar Kushwaha cfg = gur_in32(&gur->rcwsr[rcwsr - 1]) & sd_prctl_mask;
1019f3183d2SMingkai Hu cfg >>= sd_prctl_shift;
1029f3183d2SMingkai Hu printf("Using SERDES%d Protocol: %d (0x%x)\n", sd + 1, cfg, cfg);
1039f3183d2SMingkai Hu
1049f3183d2SMingkai Hu if (!is_serdes_prtcl_valid(sd, cfg))
1059f3183d2SMingkai Hu printf("SERDES%d[PRTCL] = 0x%x is not valid\n", sd + 1, cfg);
1069f3183d2SMingkai Hu
1079f3183d2SMingkai Hu for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
1089f3183d2SMingkai Hu enum srds_prtcl lane_prtcl = serdes_get_prtcl(sd, cfg, lane);
1099f3183d2SMingkai Hu if (unlikely(lane_prtcl >= SERDES_PRCTL_COUNT))
1109f3183d2SMingkai Hu debug("Unknown SerDes lane protocol %d\n", lane_prtcl);
1119f3183d2SMingkai Hu else {
1129f3183d2SMingkai Hu serdes_prtcl_map[lane_prtcl] = 1;
113*1f55a938SSantan Kumar #if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD)
1149f3183d2SMingkai Hu switch (lane_prtcl) {
1159f3183d2SMingkai Hu case QSGMII_A:
1169f3183d2SMingkai Hu case QSGMII_B:
1179f3183d2SMingkai Hu case QSGMII_C:
1189f3183d2SMingkai Hu case QSGMII_D:
1191b7dba99SPrabhakar Kushwaha wriop_init_dpmac_qsgmii(sd, (int)lane_prtcl);
1209f3183d2SMingkai Hu break;
1219f3183d2SMingkai Hu default:
12299e904c1SPrabhakar Kushwaha if (lane_prtcl >= XFI1 && lane_prtcl <= XFI8)
12399e904c1SPrabhakar Kushwaha wriop_init_dpmac(sd,
12499e904c1SPrabhakar Kushwaha xfi_dpmac[lane_prtcl],
12599e904c1SPrabhakar Kushwaha (int)lane_prtcl);
12699e904c1SPrabhakar Kushwaha
1279f3183d2SMingkai Hu if (lane_prtcl >= SGMII1 &&
1289f3183d2SMingkai Hu lane_prtcl <= SGMII16)
12999e904c1SPrabhakar Kushwaha wriop_init_dpmac(sd, sgmii_dpmac[
13099e904c1SPrabhakar Kushwaha lane_prtcl],
1319f3183d2SMingkai Hu (int)lane_prtcl);
1329f3183d2SMingkai Hu break;
1339f3183d2SMingkai Hu }
1349f3183d2SMingkai Hu #endif
1359f3183d2SMingkai Hu }
1369f3183d2SMingkai Hu }
13771fe2225SHou Zhiqiang
13871fe2225SHou Zhiqiang /* Set the first element to indicate serdes has been initialized */
13971fe2225SHou Zhiqiang serdes_prtcl_map[NONE] = 1;
1409f3183d2SMingkai Hu }
1419f3183d2SMingkai Hu
fsl_serdes_init(void)1429f3183d2SMingkai Hu void fsl_serdes_init(void)
1439f3183d2SMingkai Hu {
144*1f55a938SSantan Kumar #if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD)
14599e904c1SPrabhakar Kushwaha int i , j;
14699e904c1SPrabhakar Kushwaha
14799e904c1SPrabhakar Kushwaha for (i = XFI1, j = 1; i <= XFI8; i++, j++)
14899e904c1SPrabhakar Kushwaha xfi_dpmac[i] = j;
14999e904c1SPrabhakar Kushwaha
15099e904c1SPrabhakar Kushwaha for (i = SGMII1, j = 1; i <= SGMII16; i++, j++)
15199e904c1SPrabhakar Kushwaha sgmii_dpmac[i] = j;
15299e904c1SPrabhakar Kushwaha #endif
15399e904c1SPrabhakar Kushwaha
1549f3183d2SMingkai Hu #ifdef CONFIG_SYS_FSL_SRDS_1
1559f3183d2SMingkai Hu serdes_init(FSL_SRDS_1,
1569f3183d2SMingkai Hu CONFIG_SYS_FSL_LSCH3_SERDES_ADDR,
1577b45b383SPrabhakar Kushwaha FSL_CHASSIS3_SRDS1_REGSR,
1587b45b383SPrabhakar Kushwaha FSL_CHASSIS3_SRDS1_PRTCL_MASK,
1597b45b383SPrabhakar Kushwaha FSL_CHASSIS3_SRDS1_PRTCL_SHIFT,
1609f3183d2SMingkai Hu serdes1_prtcl_map);
1619f3183d2SMingkai Hu #endif
1629f3183d2SMingkai Hu #ifdef CONFIG_SYS_FSL_SRDS_2
1639f3183d2SMingkai Hu serdes_init(FSL_SRDS_2,
1649f3183d2SMingkai Hu CONFIG_SYS_FSL_LSCH3_SERDES_ADDR + FSL_SRDS_2 * 0x10000,
1657b45b383SPrabhakar Kushwaha FSL_CHASSIS3_SRDS2_REGSR,
1667b45b383SPrabhakar Kushwaha FSL_CHASSIS3_SRDS2_PRTCL_MASK,
1677b45b383SPrabhakar Kushwaha FSL_CHASSIS3_SRDS2_PRTCL_SHIFT,
1689f3183d2SMingkai Hu serdes2_prtcl_map);
1699f3183d2SMingkai Hu #endif
1709f3183d2SMingkai Hu }
171