xref: /rk3399_rockchip-uboot/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c (revision 541f538f4ca50082f77f7f34f05950d57804b1cc)
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