2 * Copyright 2012 Freescale Semiconductor, Inc.
4 * SPDX-License-Identifier: GPL-2.0+
8 #include <asm/fsl_serdes.h>
9 #include <asm/immap_85xx.h>
11 #include <asm/processor.h>
12 #include <asm/fsl_law.h>
13 #include <asm/errno.h>
14 #include "fsl_corenet2_serdes.h"
16 static u64 serdes1_prtcl_map
;
17 static u64 serdes2_prtcl_map
;
18 #ifdef CONFIG_SYS_FSL_SRDS_3
19 static u64 serdes3_prtcl_map
;
21 #ifdef CONFIG_SYS_FSL_SRDS_4
22 static u64 serdes4_prtcl_map
;
26 static const char *serdes_prtcl_str
[] = {
36 [SGMII_FM1_DTSEC1
] = "SGMII_FM1_DTSEC1",
37 [SGMII_FM1_DTSEC2
] = "SGMII_FM1_DTSEC2",
38 [SGMII_FM1_DTSEC3
] = "SGMII_FM1_DTSEC3",
39 [SGMII_FM1_DTSEC4
] = "SGMII_FM1_DTSEC4",
40 [SGMII_FM1_DTSEC5
] = "SGMII_FM1_DTSEC5",
41 [SGMII_FM1_DTSEC6
] = "SGMII_FM1_DTSEC6",
42 [SGMII_FM2_DTSEC1
] = "SGMII_FM2_DTSEC1",
43 [SGMII_FM2_DTSEC2
] = "SGMII_FM2_DTSEC2",
44 [SGMII_FM2_DTSEC3
] = "SGMII_FM2_DTSEC3",
45 [SGMII_FM2_DTSEC4
] = "SGMII_FM2_DTSEC4",
46 [XAUI_FM1
] = "XAUI_FM1",
47 [XAUI_FM2
] = "XAUI_FM2",
57 [XAUI_FM1_MAC9
] = "XAUI_FM1_MAC9",
58 [XAUI_FM1_MAC10
] = "XAUI_FM1_MAC10",
59 [XAUI_FM2_MAC9
] = "XAUI_FM2_MAC9",
60 [XAUI_FM2_MAC10
] = "XAUI_FM2_MAC10",
61 [HIGIG_FM1_MAC9
] = "HiGig_FM1_MAC9",
62 [HIGIG_FM1_MAC10
] = "HiGig_FM1_MAC10",
63 [HIGIG_FM2_MAC9
] = "HiGig_FM2_MAC9",
64 [HIGIG_FM2_MAC10
] = "HiGig_FM2_MAC10",
65 [QSGMII_FM1_A
] = "QSGMII_FM1_A",
66 [QSGMII_FM1_B
] = "QSGMII_FM1_B",
67 [QSGMII_FM2_A
] = "QSGMII_FM2_A",
68 [QSGMII_FM2_B
] = "QSGMII_FM2_B",
69 [XFI_FM1_MAC9
] = "XFI_FM1_MAC9",
70 [XFI_FM1_MAC10
] = "XFI_FM1_MAC10",
71 [XFI_FM2_MAC9
] = "XFI_FM2_MAC9",
72 [XFI_FM2_MAC10
] = "XFI_FM2_MAC10",
73 [INTERLAKEN
] = "INTERLAKEN",
77 int is_serdes_configured(enum srds_prtcl device
)
81 ret
|= (1ULL << device
) & serdes1_prtcl_map
;
82 ret
|= (1ULL << device
) & serdes2_prtcl_map
;
83 #ifdef CONFIG_SYS_FSL_SRDS_3
84 ret
|= (1ULL << device
) & serdes3_prtcl_map
;
86 #ifdef CONFIG_SYS_FSL_SRDS_4
87 ret
|= (1ULL << device
) & serdes4_prtcl_map
;
93 int serdes_get_first_lane(u32 sd
, enum srds_prtcl device
)
95 const ccsr_gur_t
*gur
= (void __iomem
*)(CONFIG_SYS_MPC85xx_GUTS_ADDR
);
96 u32 cfg
= in_be32(&gur
->rcwsr
[4]);
101 cfg
&= FSL_CORENET2_RCWSR4_SRDS1_PRTCL
;
102 cfg
>>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT
;
105 cfg
&= FSL_CORENET2_RCWSR4_SRDS2_PRTCL
;
106 cfg
>>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT
;
108 #ifdef CONFIG_SYS_FSL_SRDS_3
110 cfg
&= FSL_CORENET2_RCWSR4_SRDS3_PRTCL
;
111 cfg
>>= FSL_CORENET2_RCWSR4_SRDS3_PRTCL_SHIFT
;
114 #ifdef CONFIG_SYS_FSL_SRDS_4
116 cfg
&= FSL_CORENET2_RCWSR4_SRDS4_PRTCL
;
117 cfg
>>= FSL_CORENET2_RCWSR4_SRDS4_PRTCL_SHIFT
;
121 printf("invalid SerDes%d\n", sd
);
124 /* Is serdes enabled at all? */
125 if (unlikely(cfg
== 0))
128 for (i
= 0; i
< SRDS_MAX_LANES
; i
++) {
129 if (serdes_get_prtcl(sd
, cfg
, i
) == device
)
136 u64
serdes_init(u32 sd
, u32 sd_addr
, u32 sd_prctl_mask
, u32 sd_prctl_shift
)
138 ccsr_gur_t
*gur
= (void __iomem
*)(CONFIG_SYS_MPC85xx_GUTS_ADDR
);
139 u64 serdes_prtcl_map
= 0;
143 cfg
= in_be32(&gur
->rcwsr
[4]) & sd_prctl_mask
;
144 /* Is serdes enabled at all? */
146 printf("SERDES%d is not enabled\n", sd
+ 1);
150 cfg
>>= sd_prctl_shift
;
151 printf("Using SERDES%d Protocol: %d (0x%x)\n", sd
+ 1, cfg
, cfg
);
152 if (!is_serdes_prtcl_valid(sd
, cfg
))
153 printf("SERDES%d[PRTCL] = 0x%x is not valid\n", sd
+ 1, cfg
);
155 for (lane
= 0; lane
< SRDS_MAX_LANES
; lane
++) {
156 enum srds_prtcl lane_prtcl
= serdes_get_prtcl(sd
, cfg
, lane
);
157 serdes_prtcl_map
|= (1ULL << lane_prtcl
);
160 return serdes_prtcl_map
;
163 void fsl_serdes_init(void)
166 serdes1_prtcl_map
= serdes_init(FSL_SRDS_1
,
167 CONFIG_SYS_FSL_CORENET_SERDES_ADDR
,
168 FSL_CORENET2_RCWSR4_SRDS1_PRTCL
,
169 FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT
);
170 serdes2_prtcl_map
= serdes_init(FSL_SRDS_2
,
171 CONFIG_SYS_FSL_CORENET_SERDES_ADDR
+ FSL_SRDS_2
* 0x1000,
172 FSL_CORENET2_RCWSR4_SRDS2_PRTCL
,
173 FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT
);
174 #ifdef CONFIG_SYS_FSL_SRDS_3
175 serdes3_prtcl_map
= serdes_init(FSL_SRDS_3
,
176 CONFIG_SYS_FSL_CORENET_SERDES_ADDR
+ FSL_SRDS_3
* 0x1000,
177 FSL_CORENET2_RCWSR4_SRDS3_PRTCL
,
178 FSL_CORENET2_RCWSR4_SRDS3_PRTCL_SHIFT
);
180 #ifdef CONFIG_SYS_FSL_SRDS_4
181 serdes4_prtcl_map
= serdes_init(FSL_SRDS_4
,
182 CONFIG_SYS_FSL_CORENET_SERDES_ADDR
+ FSL_SRDS_4
* 0x1000,
183 FSL_CORENET2_RCWSR4_SRDS4_PRTCL
,
184 FSL_CORENET2_RCWSR4_SRDS4_PRTCL_SHIFT
);