1 /*
2  * Copyright 2012 Freescale Semiconductor, Inc.
3  *
4  * SPDX-License-Identifier:	GPL-2.0+
5  */
6 
7 #include <common.h>
8 #include <asm/fsl_serdes.h>
9 #include <asm/processor.h>
10 #include <asm/io.h>
11 #include "fsl_corenet2_serdes.h"
12 
13 struct serdes_config {
14 	u8 protocol;
15 	u8 lanes[SRDS_MAX_LANES];
16 };
17 
18 #ifdef CONFIG_PPC_B4860
19 static struct serdes_config serdes1_cfg_tbl[] = {
20 	/* SerDes 1 */
21 	{0x02, {AURORA, AURORA, CPRI6, CPRI5,
22 		CPRI4, CPRI3, CPRI2, CPRI1} },
23 	{0x04, {AURORA, AURORA, CPRI6, CPRI5,
24 		CPRI4, CPRI3, CPRI2, CPRI1} },
25 	{0x05, {AURORA, AURORA, CPRI6, CPRI5,
26 		CPRI4, CPRI3, CPRI2, CPRI1} },
27 	{0x06, {AURORA, AURORA, CPRI6, CPRI5,
28 		CPRI4, CPRI3, CPRI2, CPRI1} },
29 	{0x08, {AURORA, AURORA, CPRI6, CPRI5,
30 		CPRI4, CPRI3, CPRI2, CPRI1} },
31 	{0x09, {AURORA, AURORA, CPRI6, CPRI5,
32 		CPRI4, CPRI3, CPRI2, CPRI1} },
33 	{0x0A, {AURORA, AURORA, CPRI6, CPRI5,
34 		CPRI4, CPRI3, CPRI2, CPRI1} },
35 	{0x0B, {AURORA, AURORA, CPRI6, CPRI5,
36 		CPRI4, CPRI3, CPRI2, CPRI1} },
37 	{0x0C, {AURORA, AURORA, CPRI6, CPRI5,
38 		CPRI4, CPRI3, CPRI2, CPRI1} },
39 	{0x0D, {CPRI8, CPRI7, CPRI6, CPRI5,
40 		CPRI4, CPRI3, CPRI2, CPRI1}},
41 	{0x0E, {CPRI8, CPRI7,	CPRI6, CPRI5,
42 		CPRI4, CPRI3, CPRI2, CPRI1}},
43 	{0x12, {CPRI8, CPRI7,	CPRI6, CPRI5,
44 		CPRI4, CPRI3, CPRI2, CPRI1}},
45 	{0x29, {SGMII_FM1_DTSEC5, SGMII_FM1_DTSEC6,
46 		CPRI6, CPRI5, CPRI4, CPRI3, CPRI2, CPRI1} },
47 	{0x2a, {SGMII_FM1_DTSEC5, SGMII_FM1_DTSEC6,
48 		CPRI6, CPRI5, CPRI4, CPRI3, CPRI2, CPRI1}},
49 	{0x2C, {SGMII_FM1_DTSEC5, SGMII_FM1_DTSEC6,
50 		CPRI6, CPRI5, CPRI4, CPRI3, CPRI2, CPRI1}},
51 	{0x2D, {SGMII_FM1_DTSEC5, SGMII_FM1_DTSEC6,
52 		CPRI6, CPRI5, CPRI4, CPRI3, CPRI2, CPRI1}},
53 	{0x2E, {SGMII_FM1_DTSEC5, SGMII_FM1_DTSEC6,
54 		CPRI6, CPRI5, CPRI4, CPRI3, CPRI2, CPRI1}},
55 	{0x2F, {AURORA, AURORA,
56 		SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4,
57 		CPRI4, CPRI3, CPRI2, CPRI1} },
58 	{0x30, {AURORA, AURORA,
59 		SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4,
60 		CPRI4, CPRI3, CPRI2, CPRI1}},
61 	{0x32, {AURORA, AURORA,
62 		SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4,
63 		CPRI4, CPRI3, CPRI2, CPRI1}},
64 	{0x33, {AURORA, AURORA,
65 		SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4,
66 		CPRI4, CPRI3, CPRI2, CPRI1}},
67 	{0x34, {AURORA, AURORA,
68 		SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4,
69 		CPRI4, CPRI3, CPRI2, CPRI1}},
70 	{0x39, {AURORA, AURORA, CPRI6, CPRI5,
71 		CPRI4, CPRI3, CPRI2, CPRI1} },
72 	{0x3A, {AURORA, AURORA, CPRI6, CPRI5,
73 		CPRI4, CPRI3, CPRI2, CPRI1} },
74 	{0x3C, {AURORA, AURORA, CPRI6, CPRI5,
75 		CPRI4, CPRI3, CPRI2, CPRI1} },
76 	{0x3D, {AURORA, AURORA, CPRI6, CPRI5,
77 		CPRI4, CPRI3, CPRI2, CPRI1} },
78 	{0x3E, {CPRI8, CPRI7,	CPRI6, CPRI5,
79 		CPRI4, CPRI3, CPRI2, CPRI1}},
80 	{0x5C, {AURORA, AURORA,
81 		SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4,
82 		CPRI4, CPRI3, CPRI2, CPRI1} },
83 	{0x5D, {AURORA, AURORA,
84 		SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4,
85 		CPRI4, CPRI3, CPRI2, CPRI1} },
86 	{}
87 };
88 static struct serdes_config serdes2_cfg_tbl[] = {
89 	/* SerDes 2 */
90 	{0x17, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2,
91 		SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4,
92 		AURORA, AURORA,	SRIO1, SRIO1} },
93 	{0x18, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2,
94 		SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4,
95 		AURORA, AURORA,	SRIO1, SRIO1}},
96 	{0x1D, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2,
97 		SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4,
98 		AURORA, AURORA,	SRIO1, SRIO1}},
99 	{0x2A, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2,
100 		SRIO2, SRIO2,
101 		AURORA, AURORA, SRIO1, SRIO1} },
102 	{0x2B, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2,
103 		SRIO2, SRIO2,
104 		AURORA, AURORA, SRIO1, SRIO1}},
105 	{0x30, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2,
106 		SRIO2, SRIO2,
107 		AURORA, AURORA,
108 		SRIO1, SRIO1}},
109 	{0x48, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2,
110 		SGMII_FM1_DTSEC3, AURORA,
111 		SRIO1, SRIO1, SRIO1, SRIO1} },
112 	{0x49, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2,
113 		SGMII_FM1_DTSEC3, AURORA,
114 		SRIO1, SRIO1, SRIO1, SRIO1}},
115 	{0x4A, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2,
116 		SGMII_FM1_DTSEC3, AURORA,
117 		SRIO1, SRIO1, SRIO1, SRIO1}},
118 	{0x4C, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2,
119 		SGMII_FM1_DTSEC3, AURORA,
120 		SRIO1, SRIO1, SRIO1, SRIO1}},
121 	{0x4E, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2,
122 		SGMII_FM1_DTSEC3, AURORA,
123 		SRIO1, SRIO1, SRIO1, SRIO1}},
124 	{0x79, {SRIO2, SRIO2, SRIO2, SRIO2,
125 		SRIO1, SRIO1, SRIO1, SRIO1} },
126 	{0x7A, {SRIO2, SRIO2, SRIO2, SRIO2,
127 		SRIO1, SRIO1, SRIO1, SRIO1}},
128 	{0x83, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2,
129 		SRIO2, SRIO2, AURORA, AURORA,
130 		XFI_FM1_MAC9, XFI_FM1_MAC10} },
131 	{0x84, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2,
132 		SRIO2, SRIO2, AURORA, AURORA,
133 		XFI_FM1_MAC9, XFI_FM1_MAC10}},
134 	{0x85, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2,
135 		SRIO2, SRIO2, AURORA, AURORA,
136 		XFI_FM1_MAC9, XFI_FM1_MAC10}},
137 	{0x86, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2,
138 		SRIO2, SRIO2,
139 		SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4,
140 		XFI_FM1_MAC9, XFI_FM1_MAC10} },
141 	{0x87, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2,
142 		SRIO2, SRIO2,
143 		SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4,
144 		XFI_FM1_MAC9, XFI_FM1_MAC10}},
145 	{0x8C, {SRIO2, SRIO2, SRIO2, SRIO2,
146 		SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4,
147 		XFI_FM1_MAC9, XFI_FM1_MAC10} },
148 	{0x8D, {SRIO2, SRIO2, SRIO2, SRIO2,
149 		SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4,
150 		XFI_FM1_MAC9, XFI_FM1_MAC10}},
151 	{0x93, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2,
152 		SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4,
153 		XAUI_FM1_MAC10, XAUI_FM1_MAC10,
154 		XAUI_FM1_MAC10, XAUI_FM1_MAC10}},
155 	{0x9E, {PCIE1, PCIE1,	PCIE1, PCIE1,
156 		XAUI_FM1_MAC10, XAUI_FM1_MAC10,
157 		XAUI_FM1_MAC10, XAUI_FM1_MAC10}},
158 	{0x9A, {PCIE1, PCIE1,
159 		SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4,
160 		XAUI_FM1_MAC10, XAUI_FM1_MAC10,
161 		XAUI_FM1_MAC10, XAUI_FM1_MAC10}},
162 	{0xB1, {PCIE1, PCIE1, PCIE1, PCIE1,
163 		SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4,
164 		XFI_FM1_MAC9, XFI_FM1_MAC10} },
165 	{0xB2, {PCIE1, PCIE1, PCIE1, PCIE1,
166 		SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4,
167 		XFI_FM1_MAC9, XFI_FM1_MAC10}},
168 	{0xC3, {XAUI_FM1_MAC9, XAUI_FM1_MAC9,
169 		XAUI_FM1_MAC9, XAUI_FM1_MAC9,
170 		SRIO1, SRIO1, SRIO1, SRIO1}},
171 	{0x98, {XAUI_FM1_MAC9, XAUI_FM1_MAC9,
172 		XAUI_FM1_MAC9, XAUI_FM1_MAC9,
173 		XAUI_FM1_MAC10, XAUI_FM1_MAC10,
174 		XAUI_FM1_MAC10, XAUI_FM1_MAC10}},
175 	{}
176 };
177 #endif
178 
179 #ifdef CONFIG_PPC_B4420
180 static struct serdes_config serdes1_cfg_tbl[] = {
181 	{0x0D, {NONE, NONE, CPRI6, CPRI5,
182 		CPRI4, CPRI3, NONE, NONE} },
183 	{0x0E, {NONE, NONE, CPRI8, CPRI5,
184 		CPRI4, CPRI3, NONE, NONE} },
185 	{0x0F, {NONE, NONE, CPRI6, CPRI5,
186 		CPRI4, CPRI3, NONE, NONE} },
187 	{0x18, {NONE, NONE,
188 		SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4,
189 		NONE, NONE, NONE, NONE} },
190 	{0x1B, {NONE, NONE,
191 		SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4,
192 		NONE, NONE, NONE, NONE} },
193 	{0x1E, {NONE, NONE, AURORA, AURORA,
194 		NONE, NONE, NONE, NONE} },
195 	{0x21, {NONE, NONE, AURORA, AURORA,
196 		NONE, NONE, NONE, NONE} },
197 	{0x3E, {NONE, NONE, CPRI6, CPRI5,
198 		CPRI4, CPRI3, NONE, NONE} },
199 	{}
200 };
201 static struct serdes_config serdes2_cfg_tbl[] = {
202 	{0x49, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2,
203 		SGMII_FM1_DTSEC3, AURORA,
204 		NONE, NONE, NONE, NONE} },
205 	{0x4A, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2,
206 		SGMII_FM1_DTSEC3, AURORA,
207 		NONE, NONE, NONE, NONE} },
208 	{0x6F, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2,
209 		AURORA, AURORA,	NONE, NONE, NONE, NONE} },
210 	{0x70, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2,
211 		AURORA, AURORA,	NONE, NONE, NONE, NONE} },
212 	{0x9A, {PCIE1, PCIE1,
213 		SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4,
214 		NONE, NONE, NONE, NONE} },
215 	{0x9E, {PCIE1, PCIE1, PCIE1, PCIE1,
216 		NONE, NONE, NONE, NONE} },
217 	{}
218 };
219 #endif
220 
221 static struct serdes_config *serdes_cfg_tbl[] = {
222 	serdes1_cfg_tbl,
223 	serdes2_cfg_tbl,
224 };
225 
226 enum srds_prtcl serdes_get_prtcl(int serdes, int cfg, int lane)
227 {
228 	struct serdes_config *ptr;
229 
230 	if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
231 		return 0;
232 
233 	ptr = serdes_cfg_tbl[serdes];
234 	while (ptr->protocol) {
235 		if (ptr->protocol == cfg)
236 			return ptr->lanes[lane];
237 		ptr++;
238 	}
239 
240 	return 0;
241 }
242 
243 int is_serdes_prtcl_valid(int serdes, u32 prtcl)
244 {
245 	int i;
246 	struct serdes_config *ptr;
247 
248 	if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
249 		return 0;
250 
251 	ptr = serdes_cfg_tbl[serdes];
252 	while (ptr->protocol) {
253 		if (ptr->protocol == prtcl)
254 			break;
255 		ptr++;
256 	}
257 
258 	if (!ptr->protocol)
259 		return 0;
260 
261 	for (i = 0; i < SRDS_MAX_LANES; i++) {
262 		if (ptr->lanes[i] != NONE)
263 			return 1;
264 	}
265 
266 	return 0;
267 }
268