18281c58fSMingkai Hu /*
28281c58fSMingkai Hu  * Copyright 2015 Freescale Semiconductor, Inc.
38281c58fSMingkai Hu  *
48281c58fSMingkai Hu  * SPDX-License-Identifier:	GPL-2.0+
58281c58fSMingkai Hu  */
68281c58fSMingkai Hu 
78281c58fSMingkai Hu #include <common.h>
88281c58fSMingkai Hu #include <asm/io.h>
9*1221ce45SMasahiro Yamada #include <linux/errno.h>
108281c58fSMingkai Hu #include <asm/arch/fsl_serdes.h>
118281c58fSMingkai Hu #include <asm/arch/soc.h>
128281c58fSMingkai Hu 
138281c58fSMingkai Hu #ifdef CONFIG_SYS_FSL_SRDS_1
148281c58fSMingkai Hu static u8 serdes1_prtcl_map[SERDES_PRCTL_COUNT];
158281c58fSMingkai Hu #endif
16da4d620cSQianyu Gong #ifdef CONFIG_SYS_FSL_SRDS_2
17da4d620cSQianyu Gong static u8 serdes2_prtcl_map[SERDES_PRCTL_COUNT];
18da4d620cSQianyu Gong #endif
198281c58fSMingkai Hu 
208281c58fSMingkai Hu int is_serdes_configured(enum srds_prtcl device)
218281c58fSMingkai Hu {
228281c58fSMingkai Hu 	int ret = 0;
238281c58fSMingkai Hu 
248281c58fSMingkai Hu #ifdef CONFIG_SYS_FSL_SRDS_1
258281c58fSMingkai Hu 	ret |= serdes1_prtcl_map[device];
268281c58fSMingkai Hu #endif
27da4d620cSQianyu Gong #ifdef CONFIG_SYS_FSL_SRDS_2
28da4d620cSQianyu Gong 	ret |= serdes2_prtcl_map[device];
29da4d620cSQianyu Gong #endif
308281c58fSMingkai Hu 
318281c58fSMingkai Hu 	return !!ret;
328281c58fSMingkai Hu }
338281c58fSMingkai Hu 
348281c58fSMingkai Hu int serdes_get_first_lane(u32 sd, enum srds_prtcl device)
358281c58fSMingkai Hu {
368281c58fSMingkai Hu 	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
378281c58fSMingkai Hu 	u32 cfg = gur_in32(&gur->rcwsr[4]);
388281c58fSMingkai Hu 	int i;
398281c58fSMingkai Hu 
408281c58fSMingkai Hu 	switch (sd) {
418281c58fSMingkai Hu #ifdef CONFIG_SYS_FSL_SRDS_1
428281c58fSMingkai Hu 	case FSL_SRDS_1:
438281c58fSMingkai Hu 		cfg &= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
448281c58fSMingkai Hu 		cfg >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
458281c58fSMingkai Hu 		break;
468281c58fSMingkai Hu #endif
47da4d620cSQianyu Gong #ifdef CONFIG_SYS_FSL_SRDS_2
48da4d620cSQianyu Gong 	case FSL_SRDS_2:
49da4d620cSQianyu Gong 		cfg &= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK;
50da4d620cSQianyu Gong 		cfg >>= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT;
51da4d620cSQianyu Gong 		break;
52da4d620cSQianyu Gong #endif
538281c58fSMingkai Hu 	default:
548281c58fSMingkai Hu 		printf("invalid SerDes%d\n", sd);
558281c58fSMingkai Hu 		break;
568281c58fSMingkai Hu 	}
578281c58fSMingkai Hu 
588281c58fSMingkai Hu 	/* Is serdes enabled at all? */
598281c58fSMingkai Hu 	if (unlikely(cfg == 0))
608281c58fSMingkai Hu 		return -ENODEV;
618281c58fSMingkai Hu 
628281c58fSMingkai Hu 	for (i = 0; i < SRDS_MAX_LANES; i++) {
638281c58fSMingkai Hu 		if (serdes_get_prtcl(sd, cfg, i) == device)
648281c58fSMingkai Hu 			return i;
658281c58fSMingkai Hu 	}
668281c58fSMingkai Hu 
678281c58fSMingkai Hu 	return -ENODEV;
688281c58fSMingkai Hu }
698281c58fSMingkai Hu 
708281c58fSMingkai Hu int get_serdes_protocol(void)
718281c58fSMingkai Hu {
728281c58fSMingkai Hu 	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
738281c58fSMingkai Hu 	u32 cfg = gur_in32(&gur->rcwsr[4]) &
748281c58fSMingkai Hu 			  FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
758281c58fSMingkai Hu 	cfg >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
768281c58fSMingkai Hu 
778281c58fSMingkai Hu 	return cfg;
788281c58fSMingkai Hu }
798281c58fSMingkai Hu 
808281c58fSMingkai Hu const char *serdes_clock_to_string(u32 clock)
818281c58fSMingkai Hu {
828281c58fSMingkai Hu 	switch (clock) {
838281c58fSMingkai Hu 	case SRDS_PLLCR0_RFCK_SEL_100:
848281c58fSMingkai Hu 		return "100";
858281c58fSMingkai Hu 	case SRDS_PLLCR0_RFCK_SEL_125:
868281c58fSMingkai Hu 		return "125";
878281c58fSMingkai Hu 	case SRDS_PLLCR0_RFCK_SEL_156_25:
888281c58fSMingkai Hu 		return "156.25";
898281c58fSMingkai Hu 	default:
908281c58fSMingkai Hu 		return "100";
918281c58fSMingkai Hu 	}
928281c58fSMingkai Hu }
938281c58fSMingkai Hu 
948281c58fSMingkai Hu void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift,
958281c58fSMingkai Hu 		 u8 serdes_prtcl_map[SERDES_PRCTL_COUNT])
968281c58fSMingkai Hu {
978281c58fSMingkai Hu 	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
988281c58fSMingkai Hu 	u32 cfg;
998281c58fSMingkai Hu 	int lane;
1008281c58fSMingkai Hu 
1011a338921STom Rini 	memset(serdes_prtcl_map, 0, sizeof(u8) * SERDES_PRCTL_COUNT);
1028281c58fSMingkai Hu 
1038281c58fSMingkai Hu 	cfg = gur_in32(&gur->rcwsr[4]) & sd_prctl_mask;
1048281c58fSMingkai Hu 	cfg >>= sd_prctl_shift;
1058281c58fSMingkai Hu 	printf("Using SERDES%d Protocol: %d (0x%x)\n", sd + 1, cfg, cfg);
1068281c58fSMingkai Hu 
1078281c58fSMingkai Hu 	if (!is_serdes_prtcl_valid(sd, cfg))
1088281c58fSMingkai Hu 		printf("SERDES%d[PRTCL] = 0x%x is not valid\n", sd + 1, cfg);
1098281c58fSMingkai Hu 
1108281c58fSMingkai Hu 	for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
1118281c58fSMingkai Hu 		enum srds_prtcl lane_prtcl = serdes_get_prtcl(sd, cfg, lane);
1128281c58fSMingkai Hu 
1138281c58fSMingkai Hu 		if (unlikely(lane_prtcl >= SERDES_PRCTL_COUNT))
1148281c58fSMingkai Hu 			debug("Unknown SerDes lane protocol %d\n", lane_prtcl);
1158281c58fSMingkai Hu 		else
1168281c58fSMingkai Hu 			serdes_prtcl_map[lane_prtcl] = 1;
1178281c58fSMingkai Hu 	}
1188281c58fSMingkai Hu }
1198281c58fSMingkai Hu 
1208281c58fSMingkai Hu void fsl_serdes_init(void)
1218281c58fSMingkai Hu {
1228281c58fSMingkai Hu #ifdef CONFIG_SYS_FSL_SRDS_1
1238281c58fSMingkai Hu 	serdes_init(FSL_SRDS_1,
1248281c58fSMingkai Hu 		    CONFIG_SYS_FSL_SERDES_ADDR,
1258281c58fSMingkai Hu 		    FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK,
1268281c58fSMingkai Hu 		    FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT,
1278281c58fSMingkai Hu 		    serdes1_prtcl_map);
1288281c58fSMingkai Hu #endif
129da4d620cSQianyu Gong #ifdef CONFIG_SYS_FSL_SRDS_2
130da4d620cSQianyu Gong 	serdes_init(FSL_SRDS_2,
131da4d620cSQianyu Gong 		    CONFIG_SYS_FSL_SERDES_ADDR,
132da4d620cSQianyu Gong 		    FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK,
133da4d620cSQianyu Gong 		    FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT,
134da4d620cSQianyu Gong 		    serdes2_prtcl_map);
135da4d620cSQianyu Gong #endif
1368281c58fSMingkai Hu }
137