This source file includes following definitions.
- mvebu_comphy_smc
- mvebu_comphy_get_mode
- mvebu_comphy_get_mux
- mvebu_comphy_get_fw_mode
- mvebu_comphy_ethernet_init_reset
- mvebu_comphy_init_plls
- mvebu_comphy_set_mode_sgmii
- mvebu_comphy_set_mode_rxaui
- mvebu_comphy_set_mode_10gkr
- mvebu_comphy_power_on_legacy
- mvebu_comphy_power_on
- mvebu_comphy_set_mode
- mvebu_comphy_power_off_legacy
- mvebu_comphy_power_off
- mvebu_comphy_xlate
- mvebu_comphy_init_clks
- mvebu_comphy_disable_unprepare_clks
- mvebu_comphy_probe
1
2
3
4
5
6
7
8 #include <linux/arm-smccc.h>
9 #include <linux/clk.h>
10 #include <linux/io.h>
11 #include <linux/iopoll.h>
12 #include <linux/mfd/syscon.h>
13 #include <linux/module.h>
14 #include <linux/phy.h>
15 #include <linux/phy/phy.h>
16 #include <linux/platform_device.h>
17 #include <linux/regmap.h>
18
19
20 #define MVEBU_COMPHY_SERDES_CFG0(n) (0x0 + (n) * 0x1000)
21 #define MVEBU_COMPHY_SERDES_CFG0_PU_PLL BIT(1)
22 #define MVEBU_COMPHY_SERDES_CFG0_GEN_RX(n) ((n) << 3)
23 #define MVEBU_COMPHY_SERDES_CFG0_GEN_TX(n) ((n) << 7)
24 #define MVEBU_COMPHY_SERDES_CFG0_PU_RX BIT(11)
25 #define MVEBU_COMPHY_SERDES_CFG0_PU_TX BIT(12)
26 #define MVEBU_COMPHY_SERDES_CFG0_HALF_BUS BIT(14)
27 #define MVEBU_COMPHY_SERDES_CFG0_RXAUI_MODE BIT(15)
28 #define MVEBU_COMPHY_SERDES_CFG1(n) (0x4 + (n) * 0x1000)
29 #define MVEBU_COMPHY_SERDES_CFG1_RESET BIT(3)
30 #define MVEBU_COMPHY_SERDES_CFG1_RX_INIT BIT(4)
31 #define MVEBU_COMPHY_SERDES_CFG1_CORE_RESET BIT(5)
32 #define MVEBU_COMPHY_SERDES_CFG1_RF_RESET BIT(6)
33 #define MVEBU_COMPHY_SERDES_CFG2(n) (0x8 + (n) * 0x1000)
34 #define MVEBU_COMPHY_SERDES_CFG2_DFE_EN BIT(4)
35 #define MVEBU_COMPHY_SERDES_STATUS0(n) (0x18 + (n) * 0x1000)
36 #define MVEBU_COMPHY_SERDES_STATUS0_TX_PLL_RDY BIT(2)
37 #define MVEBU_COMPHY_SERDES_STATUS0_RX_PLL_RDY BIT(3)
38 #define MVEBU_COMPHY_SERDES_STATUS0_RX_INIT BIT(4)
39 #define MVEBU_COMPHY_PWRPLL_CTRL(n) (0x804 + (n) * 0x1000)
40 #define MVEBU_COMPHY_PWRPLL_CTRL_RFREQ(n) ((n) << 0)
41 #define MVEBU_COMPHY_PWRPLL_PHY_MODE(n) ((n) << 5)
42 #define MVEBU_COMPHY_IMP_CAL(n) (0x80c + (n) * 0x1000)
43 #define MVEBU_COMPHY_IMP_CAL_TX_EXT(n) ((n) << 10)
44 #define MVEBU_COMPHY_IMP_CAL_TX_EXT_EN BIT(15)
45 #define MVEBU_COMPHY_DFE_RES(n) (0x81c + (n) * 0x1000)
46 #define MVEBU_COMPHY_DFE_RES_FORCE_GEN_TBL BIT(15)
47 #define MVEBU_COMPHY_COEF(n) (0x828 + (n) * 0x1000)
48 #define MVEBU_COMPHY_COEF_DFE_EN BIT(14)
49 #define MVEBU_COMPHY_COEF_DFE_CTRL BIT(15)
50 #define MVEBU_COMPHY_GEN1_S0(n) (0x834 + (n) * 0x1000)
51 #define MVEBU_COMPHY_GEN1_S0_TX_AMP(n) ((n) << 1)
52 #define MVEBU_COMPHY_GEN1_S0_TX_EMPH(n) ((n) << 7)
53 #define MVEBU_COMPHY_GEN1_S1(n) (0x838 + (n) * 0x1000)
54 #define MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(n) ((n) << 0)
55 #define MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(n) ((n) << 3)
56 #define MVEBU_COMPHY_GEN1_S1_RX_MUL_FI(n) ((n) << 6)
57 #define MVEBU_COMPHY_GEN1_S1_RX_MUL_FF(n) ((n) << 8)
58 #define MVEBU_COMPHY_GEN1_S1_RX_DFE_EN BIT(10)
59 #define MVEBU_COMPHY_GEN1_S1_RX_DIV(n) ((n) << 11)
60 #define MVEBU_COMPHY_GEN1_S2(n) (0x8f4 + (n) * 0x1000)
61 #define MVEBU_COMPHY_GEN1_S2_TX_EMPH(n) ((n) << 0)
62 #define MVEBU_COMPHY_GEN1_S2_TX_EMPH_EN BIT(4)
63 #define MVEBU_COMPHY_LOOPBACK(n) (0x88c + (n) * 0x1000)
64 #define MVEBU_COMPHY_LOOPBACK_DBUS_WIDTH(n) ((n) << 1)
65 #define MVEBU_COMPHY_VDD_CAL0(n) (0x908 + (n) * 0x1000)
66 #define MVEBU_COMPHY_VDD_CAL0_CONT_MODE BIT(15)
67 #define MVEBU_COMPHY_EXT_SELV(n) (0x914 + (n) * 0x1000)
68 #define MVEBU_COMPHY_EXT_SELV_RX_SAMPL(n) ((n) << 5)
69 #define MVEBU_COMPHY_MISC_CTRL0(n) (0x93c + (n) * 0x1000)
70 #define MVEBU_COMPHY_MISC_CTRL0_ICP_FORCE BIT(5)
71 #define MVEBU_COMPHY_MISC_CTRL0_REFCLK_SEL BIT(10)
72 #define MVEBU_COMPHY_RX_CTRL1(n) (0x940 + (n) * 0x1000)
73 #define MVEBU_COMPHY_RX_CTRL1_RXCLK2X_SEL BIT(11)
74 #define MVEBU_COMPHY_RX_CTRL1_CLK8T_EN BIT(12)
75 #define MVEBU_COMPHY_SPEED_DIV(n) (0x954 + (n) * 0x1000)
76 #define MVEBU_COMPHY_SPEED_DIV_TX_FORCE BIT(7)
77 #define MVEBU_SP_CALIB(n) (0x96c + (n) * 0x1000)
78 #define MVEBU_SP_CALIB_SAMPLER(n) ((n) << 8)
79 #define MVEBU_SP_CALIB_SAMPLER_EN BIT(12)
80 #define MVEBU_COMPHY_TX_SLEW_RATE(n) (0x974 + (n) * 0x1000)
81 #define MVEBU_COMPHY_TX_SLEW_RATE_EMPH(n) ((n) << 5)
82 #define MVEBU_COMPHY_TX_SLEW_RATE_SLC(n) ((n) << 10)
83 #define MVEBU_COMPHY_DTL_CTRL(n) (0x984 + (n) * 0x1000)
84 #define MVEBU_COMPHY_DTL_CTRL_DTL_FLOOP_EN BIT(2)
85 #define MVEBU_COMPHY_FRAME_DETECT0(n) (0xa14 + (n) * 0x1000)
86 #define MVEBU_COMPHY_FRAME_DETECT0_PATN(n) ((n) << 7)
87 #define MVEBU_COMPHY_FRAME_DETECT3(n) (0xa20 + (n) * 0x1000)
88 #define MVEBU_COMPHY_FRAME_DETECT3_LOST_TIMEOUT_EN BIT(12)
89 #define MVEBU_COMPHY_DME(n) (0xa28 + (n) * 0x1000)
90 #define MVEBU_COMPHY_DME_ETH_MODE BIT(7)
91 #define MVEBU_COMPHY_TRAINING0(n) (0xa68 + (n) * 0x1000)
92 #define MVEBU_COMPHY_TRAINING0_P2P_HOLD BIT(15)
93 #define MVEBU_COMPHY_TRAINING5(n) (0xaa4 + (n) * 0x1000)
94 #define MVEBU_COMPHY_TRAINING5_RX_TIMER(n) ((n) << 0)
95 #define MVEBU_COMPHY_TX_TRAIN_PRESET(n) (0xb1c + (n) * 0x1000)
96 #define MVEBU_COMPHY_TX_TRAIN_PRESET_16B_AUTO_EN BIT(8)
97 #define MVEBU_COMPHY_TX_TRAIN_PRESET_PRBS11 BIT(9)
98 #define MVEBU_COMPHY_GEN1_S3(n) (0xc40 + (n) * 0x1000)
99 #define MVEBU_COMPHY_GEN1_S3_FBCK_SEL BIT(9)
100 #define MVEBU_COMPHY_GEN1_S4(n) (0xc44 + (n) * 0x1000)
101 #define MVEBU_COMPHY_GEN1_S4_DFE_RES(n) ((n) << 8)
102 #define MVEBU_COMPHY_TX_PRESET(n) (0xc68 + (n) * 0x1000)
103 #define MVEBU_COMPHY_TX_PRESET_INDEX(n) ((n) << 0)
104 #define MVEBU_COMPHY_GEN1_S5(n) (0xd38 + (n) * 0x1000)
105 #define MVEBU_COMPHY_GEN1_S5_ICP(n) ((n) << 0)
106
107
108 #define MVEBU_COMPHY_CONF1(n) (0x1000 + (n) * 0x28)
109 #define MVEBU_COMPHY_CONF1_PWRUP BIT(1)
110 #define MVEBU_COMPHY_CONF1_USB_PCIE BIT(2)
111 #define MVEBU_COMPHY_CONF6(n) (0x1014 + (n) * 0x28)
112 #define MVEBU_COMPHY_CONF6_40B BIT(18)
113 #define MVEBU_COMPHY_SELECTOR 0x1140
114 #define MVEBU_COMPHY_SELECTOR_PHY(n) ((n) * 0x4)
115 #define MVEBU_COMPHY_PIPE_SELECTOR 0x1144
116 #define MVEBU_COMPHY_PIPE_SELECTOR_PIPE(n) ((n) * 0x4)
117 #define MVEBU_COMPHY_SD1_CTRL1 0x1148
118 #define MVEBU_COMPHY_SD1_CTRL1_RXAUI1_EN BIT(26)
119 #define MVEBU_COMPHY_SD1_CTRL1_RXAUI0_EN BIT(27)
120
121 #define MVEBU_COMPHY_LANES 6
122 #define MVEBU_COMPHY_PORTS 3
123
124 #define COMPHY_SIP_POWER_ON 0x82000001
125 #define COMPHY_SIP_POWER_OFF 0x82000002
126 #define COMPHY_FW_NOT_SUPPORTED (-1)
127
128
129
130
131
132
133
134
135
136
137 #define COMPHY_FW_POL_OFFSET 0
138 #define COMPHY_FW_POL_MASK GENMASK(1, 0)
139 #define COMPHY_FW_SPEED_OFFSET 2
140 #define COMPHY_FW_SPEED_MASK GENMASK(7, 2)
141 #define COMPHY_FW_SPEED_MAX COMPHY_FW_SPEED_MASK
142 #define COMPHY_FW_SPEED_1250 0
143 #define COMPHY_FW_SPEED_3125 2
144 #define COMPHY_FW_SPEED_5000 3
145 #define COMPHY_FW_SPEED_103125 6
146 #define COMPHY_FW_PORT_OFFSET 8
147 #define COMPHY_FW_PORT_MASK GENMASK(11, 8)
148 #define COMPHY_FW_MODE_OFFSET 12
149 #define COMPHY_FW_MODE_MASK GENMASK(16, 12)
150 #define COMPHY_FW_WIDTH_OFFSET 18
151 #define COMPHY_FW_WIDTH_MASK GENMASK(20, 18)
152
153 #define COMPHY_FW_PARAM_FULL(mode, port, speed, pol, width) \
154 ((((pol) << COMPHY_FW_POL_OFFSET) & COMPHY_FW_POL_MASK) | \
155 (((mode) << COMPHY_FW_MODE_OFFSET) & COMPHY_FW_MODE_MASK) | \
156 (((port) << COMPHY_FW_PORT_OFFSET) & COMPHY_FW_PORT_MASK) | \
157 (((speed) << COMPHY_FW_SPEED_OFFSET) & COMPHY_FW_SPEED_MASK) | \
158 (((width) << COMPHY_FW_WIDTH_OFFSET) & COMPHY_FW_WIDTH_MASK))
159
160 #define COMPHY_FW_PARAM(mode, port) \
161 COMPHY_FW_PARAM_FULL(mode, port, COMPHY_FW_SPEED_MAX, 0, 0)
162
163 #define COMPHY_FW_PARAM_ETH(mode, port, speed) \
164 COMPHY_FW_PARAM_FULL(mode, port, speed, 0, 0)
165
166 #define COMPHY_FW_PARAM_PCIE(mode, port, width) \
167 COMPHY_FW_PARAM_FULL(mode, port, COMPHY_FW_SPEED_5000, 0, width)
168
169 #define COMPHY_FW_MODE_SATA 0x1
170 #define COMPHY_FW_MODE_SGMII 0x2
171 #define COMPHY_FW_MODE_HS_SGMII 0x3
172 #define COMPHY_FW_MODE_USB3H 0x4
173 #define COMPHY_FW_MODE_USB3D 0x5
174 #define COMPHY_FW_MODE_PCIE 0x6
175 #define COMPHY_FW_MODE_RXAUI 0x7
176 #define COMPHY_FW_MODE_XFI 0x8
177
178 struct mvebu_comphy_conf {
179 enum phy_mode mode;
180 int submode;
181 unsigned lane;
182 unsigned port;
183 u32 mux;
184 u32 fw_mode;
185 };
186
187 #define ETH_CONF(_lane, _port, _submode, _mux, _fw) \
188 { \
189 .lane = _lane, \
190 .port = _port, \
191 .mode = PHY_MODE_ETHERNET, \
192 .submode = _submode, \
193 .mux = _mux, \
194 .fw_mode = _fw, \
195 }
196
197 #define GEN_CONF(_lane, _port, _mode, _fw) \
198 { \
199 .lane = _lane, \
200 .port = _port, \
201 .mode = _mode, \
202 .submode = PHY_INTERFACE_MODE_NA, \
203 .mux = -1, \
204 .fw_mode = _fw, \
205 }
206
207 static const struct mvebu_comphy_conf mvebu_comphy_cp110_modes[] = {
208
209 GEN_CONF(0, 0, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE),
210 ETH_CONF(0, 1, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII),
211 ETH_CONF(0, 1, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII),
212 GEN_CONF(0, 1, PHY_MODE_SATA, COMPHY_FW_MODE_SATA),
213
214 GEN_CONF(1, 0, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H),
215 GEN_CONF(1, 0, PHY_MODE_USB_DEVICE_SS, COMPHY_FW_MODE_USB3D),
216 GEN_CONF(1, 0, PHY_MODE_SATA, COMPHY_FW_MODE_SATA),
217 GEN_CONF(1, 0, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE),
218 ETH_CONF(1, 2, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII),
219 ETH_CONF(1, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII),
220
221 ETH_CONF(2, 0, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII),
222 ETH_CONF(2, 0, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII),
223 ETH_CONF(2, 0, PHY_INTERFACE_MODE_RXAUI, 0x1, COMPHY_FW_MODE_RXAUI),
224 ETH_CONF(2, 0, PHY_INTERFACE_MODE_10GKR, 0x1, COMPHY_FW_MODE_XFI),
225 GEN_CONF(2, 0, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H),
226 GEN_CONF(2, 0, PHY_MODE_SATA, COMPHY_FW_MODE_SATA),
227 GEN_CONF(2, 0, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE),
228
229 GEN_CONF(3, 0, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE),
230 ETH_CONF(3, 1, PHY_INTERFACE_MODE_SGMII, 0x2, COMPHY_FW_MODE_SGMII),
231 ETH_CONF(3, 1, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_HS_SGMII),
232 ETH_CONF(3, 1, PHY_INTERFACE_MODE_RXAUI, 0x1, COMPHY_FW_MODE_RXAUI),
233 GEN_CONF(3, 1, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H),
234 GEN_CONF(3, 1, PHY_MODE_SATA, COMPHY_FW_MODE_SATA),
235
236 ETH_CONF(4, 0, PHY_INTERFACE_MODE_SGMII, 0x2, COMPHY_FW_MODE_SGMII),
237 ETH_CONF(4, 0, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_HS_SGMII),
238 ETH_CONF(4, 0, PHY_INTERFACE_MODE_10GKR, 0x2, COMPHY_FW_MODE_XFI),
239 ETH_CONF(4, 0, PHY_INTERFACE_MODE_RXAUI, 0x2, COMPHY_FW_MODE_RXAUI),
240 GEN_CONF(4, 0, PHY_MODE_USB_DEVICE_SS, COMPHY_FW_MODE_USB3D),
241 GEN_CONF(4, 1, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H),
242 GEN_CONF(4, 1, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE),
243 ETH_CONF(4, 1, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII),
244 ETH_CONF(4, 1, PHY_INTERFACE_MODE_2500BASEX, -1, COMPHY_FW_MODE_HS_SGMII),
245 ETH_CONF(4, 1, PHY_INTERFACE_MODE_10GKR, -1, COMPHY_FW_MODE_XFI),
246
247 ETH_CONF(5, 1, PHY_INTERFACE_MODE_RXAUI, 0x2, COMPHY_FW_MODE_RXAUI),
248 GEN_CONF(5, 1, PHY_MODE_SATA, COMPHY_FW_MODE_SATA),
249 ETH_CONF(5, 2, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII),
250 ETH_CONF(5, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII),
251 GEN_CONF(5, 2, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE),
252 };
253
254 struct mvebu_comphy_priv {
255 void __iomem *base;
256 struct regmap *regmap;
257 struct device *dev;
258 struct clk *mg_domain_clk;
259 struct clk *mg_core_clk;
260 struct clk *axi_clk;
261 unsigned long cp_phys;
262 };
263
264 struct mvebu_comphy_lane {
265 struct mvebu_comphy_priv *priv;
266 unsigned id;
267 enum phy_mode mode;
268 int submode;
269 int port;
270 };
271
272 static int mvebu_comphy_smc(unsigned long function, unsigned long phys,
273 unsigned long lane, unsigned long mode)
274 {
275 struct arm_smccc_res res;
276
277 arm_smccc_smc(function, phys, lane, mode, 0, 0, 0, 0, &res);
278
279 return res.a0;
280 }
281
282 static int mvebu_comphy_get_mode(bool fw_mode, int lane, int port,
283 enum phy_mode mode, int submode)
284 {
285 int i, n = ARRAY_SIZE(mvebu_comphy_cp110_modes);
286
287 bool ignore_submode = (mode == PHY_MODE_PCIE);
288 const struct mvebu_comphy_conf *conf;
289
290
291 if (mode == PHY_MODE_INVALID)
292 return 0;
293
294 for (i = 0; i < n; i++) {
295 conf = &mvebu_comphy_cp110_modes[i];
296 if (conf->lane == lane &&
297 conf->port == port &&
298 conf->mode == mode &&
299 (conf->submode == submode || ignore_submode))
300 break;
301 }
302
303 if (i == n)
304 return -EINVAL;
305
306 if (fw_mode)
307 return conf->fw_mode;
308 else
309 return conf->mux;
310 }
311
312 static inline int mvebu_comphy_get_mux(int lane, int port,
313 enum phy_mode mode, int submode)
314 {
315 return mvebu_comphy_get_mode(false, lane, port, mode, submode);
316 }
317
318 static inline int mvebu_comphy_get_fw_mode(int lane, int port,
319 enum phy_mode mode, int submode)
320 {
321 return mvebu_comphy_get_mode(true, lane, port, mode, submode);
322 }
323
324 static int mvebu_comphy_ethernet_init_reset(struct mvebu_comphy_lane *lane)
325 {
326 struct mvebu_comphy_priv *priv = lane->priv;
327 u32 val;
328
329 regmap_read(priv->regmap, MVEBU_COMPHY_CONF1(lane->id), &val);
330 val &= ~MVEBU_COMPHY_CONF1_USB_PCIE;
331 val |= MVEBU_COMPHY_CONF1_PWRUP;
332 regmap_write(priv->regmap, MVEBU_COMPHY_CONF1(lane->id), val);
333
334
335 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id));
336 val &= ~(MVEBU_COMPHY_SERDES_CFG0_PU_PLL |
337 MVEBU_COMPHY_SERDES_CFG0_PU_RX |
338 MVEBU_COMPHY_SERDES_CFG0_PU_TX |
339 MVEBU_COMPHY_SERDES_CFG0_HALF_BUS |
340 MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0xf) |
341 MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0xf) |
342 MVEBU_COMPHY_SERDES_CFG0_RXAUI_MODE);
343
344 switch (lane->submode) {
345 case PHY_INTERFACE_MODE_10GKR:
346 val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0xe) |
347 MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0xe);
348 break;
349 case PHY_INTERFACE_MODE_RXAUI:
350 val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0xb) |
351 MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0xb) |
352 MVEBU_COMPHY_SERDES_CFG0_RXAUI_MODE;
353 break;
354 case PHY_INTERFACE_MODE_2500BASEX:
355 val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0x8) |
356 MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0x8) |
357 MVEBU_COMPHY_SERDES_CFG0_HALF_BUS;
358 break;
359 case PHY_INTERFACE_MODE_SGMII:
360 val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0x6) |
361 MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0x6) |
362 MVEBU_COMPHY_SERDES_CFG0_HALF_BUS;
363 break;
364 default:
365 dev_err(priv->dev,
366 "unsupported comphy submode (%d) on lane %d\n",
367 lane->submode,
368 lane->id);
369 return -ENOTSUPP;
370 }
371
372 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id));
373
374 if (lane->submode == PHY_INTERFACE_MODE_RXAUI) {
375 regmap_read(priv->regmap, MVEBU_COMPHY_SD1_CTRL1, &val);
376
377 switch (lane->id) {
378 case 2:
379 case 3:
380 val |= MVEBU_COMPHY_SD1_CTRL1_RXAUI0_EN;
381 break;
382 case 4:
383 case 5:
384 val |= MVEBU_COMPHY_SD1_CTRL1_RXAUI1_EN;
385 break;
386 default:
387 dev_err(priv->dev,
388 "RXAUI is not supported on comphy lane %d\n",
389 lane->id);
390 return -EINVAL;
391 }
392
393 regmap_write(priv->regmap, MVEBU_COMPHY_SD1_CTRL1, val);
394 }
395
396
397 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
398 val &= ~(MVEBU_COMPHY_SERDES_CFG1_RESET |
399 MVEBU_COMPHY_SERDES_CFG1_CORE_RESET |
400 MVEBU_COMPHY_SERDES_CFG1_RF_RESET);
401 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
402
403
404 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
405 val |= MVEBU_COMPHY_SERDES_CFG1_RESET |
406 MVEBU_COMPHY_SERDES_CFG1_CORE_RESET;
407 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
408
409
410 mdelay(1);
411
412
413 regmap_read(priv->regmap, MVEBU_COMPHY_CONF6(lane->id), &val);
414 val &= ~MVEBU_COMPHY_CONF6_40B;
415 regmap_write(priv->regmap, MVEBU_COMPHY_CONF6(lane->id), val);
416
417
418 val = readl(priv->base + MVEBU_COMPHY_MISC_CTRL0(lane->id));
419 val &= ~MVEBU_COMPHY_MISC_CTRL0_REFCLK_SEL;
420 if (lane->submode == PHY_INTERFACE_MODE_10GKR)
421 val |= MVEBU_COMPHY_MISC_CTRL0_ICP_FORCE;
422 writel(val, priv->base + MVEBU_COMPHY_MISC_CTRL0(lane->id));
423
424
425 val = readl(priv->base + MVEBU_COMPHY_PWRPLL_CTRL(lane->id));
426 val &= ~(MVEBU_COMPHY_PWRPLL_CTRL_RFREQ(0x1f) |
427 MVEBU_COMPHY_PWRPLL_PHY_MODE(0x7));
428 val |= MVEBU_COMPHY_PWRPLL_CTRL_RFREQ(0x1) |
429 MVEBU_COMPHY_PWRPLL_PHY_MODE(0x4);
430 writel(val, priv->base + MVEBU_COMPHY_PWRPLL_CTRL(lane->id));
431
432 val = readl(priv->base + MVEBU_COMPHY_LOOPBACK(lane->id));
433 val &= ~MVEBU_COMPHY_LOOPBACK_DBUS_WIDTH(0x7);
434 val |= MVEBU_COMPHY_LOOPBACK_DBUS_WIDTH(0x1);
435 writel(val, priv->base + MVEBU_COMPHY_LOOPBACK(lane->id));
436
437 return 0;
438 }
439
440 static int mvebu_comphy_init_plls(struct mvebu_comphy_lane *lane)
441 {
442 struct mvebu_comphy_priv *priv = lane->priv;
443 u32 val;
444
445
446 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id));
447 val |= MVEBU_COMPHY_SERDES_CFG0_PU_PLL |
448 MVEBU_COMPHY_SERDES_CFG0_PU_RX |
449 MVEBU_COMPHY_SERDES_CFG0_PU_TX;
450 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id));
451
452
453 readl_poll_timeout(priv->base + MVEBU_COMPHY_SERDES_STATUS0(lane->id),
454 val,
455 val & (MVEBU_COMPHY_SERDES_STATUS0_RX_PLL_RDY |
456 MVEBU_COMPHY_SERDES_STATUS0_TX_PLL_RDY),
457 1000, 150000);
458 if (!(val & (MVEBU_COMPHY_SERDES_STATUS0_RX_PLL_RDY |
459 MVEBU_COMPHY_SERDES_STATUS0_TX_PLL_RDY)))
460 return -ETIMEDOUT;
461
462
463 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
464 val |= MVEBU_COMPHY_SERDES_CFG1_RX_INIT;
465 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
466
467
468 readl_poll_timeout(priv->base + MVEBU_COMPHY_SERDES_STATUS0(lane->id),
469 val, val & MVEBU_COMPHY_SERDES_STATUS0_RX_INIT,
470 1000, 10000);
471 if (!(val & MVEBU_COMPHY_SERDES_STATUS0_RX_INIT))
472 return -ETIMEDOUT;
473
474 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
475 val &= ~MVEBU_COMPHY_SERDES_CFG1_RX_INIT;
476 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
477
478 return 0;
479 }
480
481 static int mvebu_comphy_set_mode_sgmii(struct phy *phy)
482 {
483 struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
484 struct mvebu_comphy_priv *priv = lane->priv;
485 u32 val;
486 int err;
487
488 err = mvebu_comphy_ethernet_init_reset(lane);
489 if (err)
490 return err;
491
492 val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
493 val &= ~MVEBU_COMPHY_RX_CTRL1_CLK8T_EN;
494 val |= MVEBU_COMPHY_RX_CTRL1_RXCLK2X_SEL;
495 writel(val, priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
496
497 val = readl(priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id));
498 val &= ~MVEBU_COMPHY_DTL_CTRL_DTL_FLOOP_EN;
499 writel(val, priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id));
500
501 regmap_read(priv->regmap, MVEBU_COMPHY_CONF1(lane->id), &val);
502 val &= ~MVEBU_COMPHY_CONF1_USB_PCIE;
503 val |= MVEBU_COMPHY_CONF1_PWRUP;
504 regmap_write(priv->regmap, MVEBU_COMPHY_CONF1(lane->id), val);
505
506 val = readl(priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
507 val &= ~MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xf);
508 val |= MVEBU_COMPHY_GEN1_S0_TX_EMPH(0x1);
509 writel(val, priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
510
511 return mvebu_comphy_init_plls(lane);
512 }
513
514 static int mvebu_comphy_set_mode_rxaui(struct phy *phy)
515 {
516 struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
517 struct mvebu_comphy_priv *priv = lane->priv;
518 u32 val;
519 int err;
520
521 err = mvebu_comphy_ethernet_init_reset(lane);
522 if (err)
523 return err;
524
525 val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
526 val |= MVEBU_COMPHY_RX_CTRL1_RXCLK2X_SEL |
527 MVEBU_COMPHY_RX_CTRL1_CLK8T_EN;
528 writel(val, priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
529
530 val = readl(priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id));
531 val |= MVEBU_COMPHY_DTL_CTRL_DTL_FLOOP_EN;
532 writel(val, priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id));
533
534 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG2(lane->id));
535 val |= MVEBU_COMPHY_SERDES_CFG2_DFE_EN;
536 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG2(lane->id));
537
538 val = readl(priv->base + MVEBU_COMPHY_DFE_RES(lane->id));
539 val |= MVEBU_COMPHY_DFE_RES_FORCE_GEN_TBL;
540 writel(val, priv->base + MVEBU_COMPHY_DFE_RES(lane->id));
541
542 val = readl(priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
543 val &= ~MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xf);
544 val |= MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xd);
545 writel(val, priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
546
547 val = readl(priv->base + MVEBU_COMPHY_GEN1_S1(lane->id));
548 val &= ~(MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(0x7) |
549 MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(0x7));
550 val |= MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(0x1) |
551 MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(0x1) |
552 MVEBU_COMPHY_GEN1_S1_RX_DFE_EN;
553 writel(val, priv->base + MVEBU_COMPHY_GEN1_S1(lane->id));
554
555 val = readl(priv->base + MVEBU_COMPHY_COEF(lane->id));
556 val &= ~(MVEBU_COMPHY_COEF_DFE_EN | MVEBU_COMPHY_COEF_DFE_CTRL);
557 writel(val, priv->base + MVEBU_COMPHY_COEF(lane->id));
558
559 val = readl(priv->base + MVEBU_COMPHY_GEN1_S4(lane->id));
560 val &= ~MVEBU_COMPHY_GEN1_S4_DFE_RES(0x3);
561 val |= MVEBU_COMPHY_GEN1_S4_DFE_RES(0x1);
562 writel(val, priv->base + MVEBU_COMPHY_GEN1_S4(lane->id));
563
564 return mvebu_comphy_init_plls(lane);
565 }
566
567 static int mvebu_comphy_set_mode_10gkr(struct phy *phy)
568 {
569 struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
570 struct mvebu_comphy_priv *priv = lane->priv;
571 u32 val;
572 int err;
573
574 err = mvebu_comphy_ethernet_init_reset(lane);
575 if (err)
576 return err;
577
578 val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
579 val |= MVEBU_COMPHY_RX_CTRL1_RXCLK2X_SEL |
580 MVEBU_COMPHY_RX_CTRL1_CLK8T_EN;
581 writel(val, priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
582
583 val = readl(priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id));
584 val |= MVEBU_COMPHY_DTL_CTRL_DTL_FLOOP_EN;
585 writel(val, priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id));
586
587
588 val = readl(priv->base + MVEBU_COMPHY_SPEED_DIV(lane->id));
589 val |= MVEBU_COMPHY_SPEED_DIV_TX_FORCE;
590 writel(val, priv->base + MVEBU_COMPHY_SPEED_DIV(lane->id));
591
592 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG2(lane->id));
593 val |= MVEBU_COMPHY_SERDES_CFG2_DFE_EN;
594 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG2(lane->id));
595
596
597 val = readl(priv->base + MVEBU_COMPHY_DFE_RES(lane->id));
598 val |= MVEBU_COMPHY_DFE_RES_FORCE_GEN_TBL;
599 writel(val, priv->base + MVEBU_COMPHY_DFE_RES(lane->id));
600
601 val = readl(priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
602 val &= ~(MVEBU_COMPHY_GEN1_S0_TX_AMP(0x1f) |
603 MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xf));
604 val |= MVEBU_COMPHY_GEN1_S0_TX_AMP(0x1c) |
605 MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xe);
606 writel(val, priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
607
608 val = readl(priv->base + MVEBU_COMPHY_GEN1_S2(lane->id));
609 val &= ~MVEBU_COMPHY_GEN1_S2_TX_EMPH(0xf);
610 val |= MVEBU_COMPHY_GEN1_S2_TX_EMPH_EN;
611 writel(val, priv->base + MVEBU_COMPHY_GEN1_S2(lane->id));
612
613 val = readl(priv->base + MVEBU_COMPHY_TX_SLEW_RATE(lane->id));
614 val |= MVEBU_COMPHY_TX_SLEW_RATE_EMPH(0x3) |
615 MVEBU_COMPHY_TX_SLEW_RATE_SLC(0x3f);
616 writel(val, priv->base + MVEBU_COMPHY_TX_SLEW_RATE(lane->id));
617
618
619 val = readl(priv->base + MVEBU_COMPHY_IMP_CAL(lane->id));
620 val &= ~MVEBU_COMPHY_IMP_CAL_TX_EXT(0x1f);
621 val |= MVEBU_COMPHY_IMP_CAL_TX_EXT(0xe) |
622 MVEBU_COMPHY_IMP_CAL_TX_EXT_EN;
623 writel(val, priv->base + MVEBU_COMPHY_IMP_CAL(lane->id));
624
625 val = readl(priv->base + MVEBU_COMPHY_GEN1_S5(lane->id));
626 val &= ~MVEBU_COMPHY_GEN1_S5_ICP(0xf);
627 writel(val, priv->base + MVEBU_COMPHY_GEN1_S5(lane->id));
628
629 val = readl(priv->base + MVEBU_COMPHY_GEN1_S1(lane->id));
630 val &= ~(MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(0x7) |
631 MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(0x7) |
632 MVEBU_COMPHY_GEN1_S1_RX_MUL_FI(0x3) |
633 MVEBU_COMPHY_GEN1_S1_RX_MUL_FF(0x3));
634 val |= MVEBU_COMPHY_GEN1_S1_RX_DFE_EN |
635 MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(0x2) |
636 MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(0x2) |
637 MVEBU_COMPHY_GEN1_S1_RX_MUL_FF(0x1) |
638 MVEBU_COMPHY_GEN1_S1_RX_DIV(0x3);
639 writel(val, priv->base + MVEBU_COMPHY_GEN1_S1(lane->id));
640
641 val = readl(priv->base + MVEBU_COMPHY_COEF(lane->id));
642 val &= ~(MVEBU_COMPHY_COEF_DFE_EN | MVEBU_COMPHY_COEF_DFE_CTRL);
643 writel(val, priv->base + MVEBU_COMPHY_COEF(lane->id));
644
645 val = readl(priv->base + MVEBU_COMPHY_GEN1_S4(lane->id));
646 val &= ~MVEBU_COMPHY_GEN1_S4_DFE_RES(0x3);
647 val |= MVEBU_COMPHY_GEN1_S4_DFE_RES(0x1);
648 writel(val, priv->base + MVEBU_COMPHY_GEN1_S4(lane->id));
649
650 val = readl(priv->base + MVEBU_COMPHY_GEN1_S3(lane->id));
651 val |= MVEBU_COMPHY_GEN1_S3_FBCK_SEL;
652 writel(val, priv->base + MVEBU_COMPHY_GEN1_S3(lane->id));
653
654
655 val = readl(priv->base + MVEBU_COMPHY_TRAINING5(lane->id));
656 val &= ~MVEBU_COMPHY_TRAINING5_RX_TIMER(0x3ff);
657 val |= MVEBU_COMPHY_TRAINING5_RX_TIMER(0x13);
658 writel(val, priv->base + MVEBU_COMPHY_TRAINING5(lane->id));
659
660
661 val = readl(priv->base + MVEBU_COMPHY_TRAINING0(lane->id));
662 val |= MVEBU_COMPHY_TRAINING0_P2P_HOLD;
663 writel(val, priv->base + MVEBU_COMPHY_TRAINING0(lane->id));
664
665 val = readl(priv->base + MVEBU_COMPHY_TX_PRESET(lane->id));
666 val &= ~MVEBU_COMPHY_TX_PRESET_INDEX(0xf);
667 val |= MVEBU_COMPHY_TX_PRESET_INDEX(0x2);
668 writel(val, priv->base + MVEBU_COMPHY_TX_PRESET(lane->id));
669
670 val = readl(priv->base + MVEBU_COMPHY_FRAME_DETECT3(lane->id));
671 val &= ~MVEBU_COMPHY_FRAME_DETECT3_LOST_TIMEOUT_EN;
672 writel(val, priv->base + MVEBU_COMPHY_FRAME_DETECT3(lane->id));
673
674 val = readl(priv->base + MVEBU_COMPHY_TX_TRAIN_PRESET(lane->id));
675 val |= MVEBU_COMPHY_TX_TRAIN_PRESET_16B_AUTO_EN |
676 MVEBU_COMPHY_TX_TRAIN_PRESET_PRBS11;
677 writel(val, priv->base + MVEBU_COMPHY_TX_TRAIN_PRESET(lane->id));
678
679 val = readl(priv->base + MVEBU_COMPHY_FRAME_DETECT0(lane->id));
680 val &= ~MVEBU_COMPHY_FRAME_DETECT0_PATN(0x1ff);
681 val |= MVEBU_COMPHY_FRAME_DETECT0_PATN(0x88);
682 writel(val, priv->base + MVEBU_COMPHY_FRAME_DETECT0(lane->id));
683
684 val = readl(priv->base + MVEBU_COMPHY_DME(lane->id));
685 val |= MVEBU_COMPHY_DME_ETH_MODE;
686 writel(val, priv->base + MVEBU_COMPHY_DME(lane->id));
687
688 val = readl(priv->base + MVEBU_COMPHY_VDD_CAL0(lane->id));
689 val |= MVEBU_COMPHY_VDD_CAL0_CONT_MODE;
690 writel(val, priv->base + MVEBU_COMPHY_VDD_CAL0(lane->id));
691
692 val = readl(priv->base + MVEBU_SP_CALIB(lane->id));
693 val &= ~MVEBU_SP_CALIB_SAMPLER(0x3);
694 val |= MVEBU_SP_CALIB_SAMPLER(0x3) |
695 MVEBU_SP_CALIB_SAMPLER_EN;
696 writel(val, priv->base + MVEBU_SP_CALIB(lane->id));
697 val &= ~MVEBU_SP_CALIB_SAMPLER_EN;
698 writel(val, priv->base + MVEBU_SP_CALIB(lane->id));
699
700
701 val = readl(priv->base + MVEBU_COMPHY_EXT_SELV(lane->id));
702 val &= ~MVEBU_COMPHY_EXT_SELV_RX_SAMPL(0x1f);
703 val |= MVEBU_COMPHY_EXT_SELV_RX_SAMPL(0x1a);
704 writel(val, priv->base + MVEBU_COMPHY_EXT_SELV(lane->id));
705
706 return mvebu_comphy_init_plls(lane);
707 }
708
709 static int mvebu_comphy_power_on_legacy(struct phy *phy)
710 {
711 struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
712 struct mvebu_comphy_priv *priv = lane->priv;
713 int ret, mux;
714 u32 val;
715
716 mux = mvebu_comphy_get_mux(lane->id, lane->port,
717 lane->mode, lane->submode);
718 if (mux < 0)
719 return -ENOTSUPP;
720
721 regmap_read(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, &val);
722 val &= ~(0xf << MVEBU_COMPHY_PIPE_SELECTOR_PIPE(lane->id));
723 regmap_write(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, val);
724
725 regmap_read(priv->regmap, MVEBU_COMPHY_SELECTOR, &val);
726 val &= ~(0xf << MVEBU_COMPHY_SELECTOR_PHY(lane->id));
727 val |= mux << MVEBU_COMPHY_SELECTOR_PHY(lane->id);
728 regmap_write(priv->regmap, MVEBU_COMPHY_SELECTOR, val);
729
730 switch (lane->submode) {
731 case PHY_INTERFACE_MODE_SGMII:
732 case PHY_INTERFACE_MODE_2500BASEX:
733 ret = mvebu_comphy_set_mode_sgmii(phy);
734 break;
735 case PHY_INTERFACE_MODE_RXAUI:
736 ret = mvebu_comphy_set_mode_rxaui(phy);
737 break;
738 case PHY_INTERFACE_MODE_10GKR:
739 ret = mvebu_comphy_set_mode_10gkr(phy);
740 break;
741 default:
742 return -ENOTSUPP;
743 }
744
745
746 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
747 val |= MVEBU_COMPHY_SERDES_CFG1_RF_RESET;
748 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
749
750 return ret;
751 }
752
753 static int mvebu_comphy_power_on(struct phy *phy)
754 {
755 struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
756 struct mvebu_comphy_priv *priv = lane->priv;
757 int fw_mode, fw_speed;
758 u32 fw_param = 0;
759 int ret;
760
761 fw_mode = mvebu_comphy_get_fw_mode(lane->id, lane->port,
762 lane->mode, lane->submode);
763 if (fw_mode < 0)
764 goto try_legacy;
765
766
767 switch (lane->mode) {
768 case PHY_MODE_ETHERNET:
769 switch (lane->submode) {
770 case PHY_INTERFACE_MODE_RXAUI:
771 dev_dbg(priv->dev, "set lane %d to RXAUI mode\n",
772 lane->id);
773 fw_speed = 0;
774 break;
775 case PHY_INTERFACE_MODE_SGMII:
776 dev_dbg(priv->dev, "set lane %d to 1000BASE-X mode\n",
777 lane->id);
778 fw_speed = COMPHY_FW_SPEED_1250;
779 break;
780 case PHY_INTERFACE_MODE_2500BASEX:
781 dev_dbg(priv->dev, "set lane %d to 2500BASE-X mode\n",
782 lane->id);
783 fw_speed = COMPHY_FW_SPEED_3125;
784 break;
785 case PHY_INTERFACE_MODE_10GKR:
786 dev_dbg(priv->dev, "set lane %d to 10G-KR mode\n",
787 lane->id);
788 fw_speed = COMPHY_FW_SPEED_103125;
789 break;
790 default:
791 dev_err(priv->dev, "unsupported Ethernet mode (%d)\n",
792 lane->submode);
793 return -ENOTSUPP;
794 }
795 fw_param = COMPHY_FW_PARAM_ETH(fw_mode, lane->port, fw_speed);
796 break;
797 case PHY_MODE_USB_HOST_SS:
798 case PHY_MODE_USB_DEVICE_SS:
799 dev_dbg(priv->dev, "set lane %d to USB3 mode\n", lane->id);
800 fw_param = COMPHY_FW_PARAM(fw_mode, lane->port);
801 break;
802 case PHY_MODE_SATA:
803 dev_dbg(priv->dev, "set lane %d to SATA mode\n", lane->id);
804 fw_param = COMPHY_FW_PARAM(fw_mode, lane->port);
805 break;
806 case PHY_MODE_PCIE:
807 dev_dbg(priv->dev, "set lane %d to PCIe mode (x%d)\n", lane->id,
808 lane->submode);
809 fw_param = COMPHY_FW_PARAM_PCIE(fw_mode, lane->port,
810 lane->submode);
811 break;
812 default:
813 dev_err(priv->dev, "unsupported PHY mode (%d)\n", lane->mode);
814 return -ENOTSUPP;
815 }
816
817 ret = mvebu_comphy_smc(COMPHY_SIP_POWER_ON, priv->cp_phys, lane->id,
818 fw_param);
819 if (!ret)
820 return ret;
821
822 if (ret == COMPHY_FW_NOT_SUPPORTED)
823 dev_err(priv->dev,
824 "unsupported SMC call, try updating your firmware\n");
825
826 dev_warn(priv->dev,
827 "Firmware could not configure PHY %d with mode %d (ret: %d), trying legacy method\n",
828 lane->id, lane->mode, ret);
829
830 try_legacy:
831
832 return mvebu_comphy_power_on_legacy(phy);
833 }
834
835 static int mvebu_comphy_set_mode(struct phy *phy,
836 enum phy_mode mode, int submode)
837 {
838 struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
839
840 if (submode == PHY_INTERFACE_MODE_1000BASEX)
841 submode = PHY_INTERFACE_MODE_SGMII;
842
843 if (mvebu_comphy_get_fw_mode(lane->id, lane->port, mode, submode) < 0)
844 return -EINVAL;
845
846 lane->mode = mode;
847 lane->submode = submode;
848
849
850 if (mode == PHY_MODE_PCIE && !lane->submode)
851 lane->submode = 1;
852
853 return 0;
854 }
855
856 static int mvebu_comphy_power_off_legacy(struct phy *phy)
857 {
858 struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
859 struct mvebu_comphy_priv *priv = lane->priv;
860 u32 val;
861
862 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
863 val &= ~(MVEBU_COMPHY_SERDES_CFG1_RESET |
864 MVEBU_COMPHY_SERDES_CFG1_CORE_RESET |
865 MVEBU_COMPHY_SERDES_CFG1_RF_RESET);
866 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
867
868 regmap_read(priv->regmap, MVEBU_COMPHY_SELECTOR, &val);
869 val &= ~(0xf << MVEBU_COMPHY_SELECTOR_PHY(lane->id));
870 regmap_write(priv->regmap, MVEBU_COMPHY_SELECTOR, val);
871
872 regmap_read(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, &val);
873 val &= ~(0xf << MVEBU_COMPHY_PIPE_SELECTOR_PIPE(lane->id));
874 regmap_write(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, val);
875
876 return 0;
877 }
878
879 static int mvebu_comphy_power_off(struct phy *phy)
880 {
881 struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
882 struct mvebu_comphy_priv *priv = lane->priv;
883 int ret;
884
885 ret = mvebu_comphy_smc(COMPHY_SIP_POWER_OFF, priv->cp_phys,
886 lane->id, 0);
887 if (!ret)
888 return ret;
889
890
891 return mvebu_comphy_power_off_legacy(phy);
892 }
893
894 static const struct phy_ops mvebu_comphy_ops = {
895 .power_on = mvebu_comphy_power_on,
896 .power_off = mvebu_comphy_power_off,
897 .set_mode = mvebu_comphy_set_mode,
898 .owner = THIS_MODULE,
899 };
900
901 static struct phy *mvebu_comphy_xlate(struct device *dev,
902 struct of_phandle_args *args)
903 {
904 struct mvebu_comphy_lane *lane;
905 struct phy *phy;
906
907 if (WARN_ON(args->args[0] >= MVEBU_COMPHY_PORTS))
908 return ERR_PTR(-EINVAL);
909
910 phy = of_phy_simple_xlate(dev, args);
911 if (IS_ERR(phy))
912 return phy;
913
914 lane = phy_get_drvdata(phy);
915 lane->port = args->args[0];
916
917 return phy;
918 }
919
920 static int mvebu_comphy_init_clks(struct mvebu_comphy_priv *priv)
921 {
922 int ret;
923
924 priv->mg_domain_clk = devm_clk_get(priv->dev, "mg_clk");
925 if (IS_ERR(priv->mg_domain_clk))
926 return PTR_ERR(priv->mg_domain_clk);
927
928 ret = clk_prepare_enable(priv->mg_domain_clk);
929 if (ret < 0)
930 return ret;
931
932 priv->mg_core_clk = devm_clk_get(priv->dev, "mg_core_clk");
933 if (IS_ERR(priv->mg_core_clk)) {
934 ret = PTR_ERR(priv->mg_core_clk);
935 goto dis_mg_domain_clk;
936 }
937
938 ret = clk_prepare_enable(priv->mg_core_clk);
939 if (ret < 0)
940 goto dis_mg_domain_clk;
941
942 priv->axi_clk = devm_clk_get(priv->dev, "axi_clk");
943 if (IS_ERR(priv->axi_clk)) {
944 ret = PTR_ERR(priv->axi_clk);
945 goto dis_mg_core_clk;
946 }
947
948 ret = clk_prepare_enable(priv->axi_clk);
949 if (ret < 0)
950 goto dis_mg_core_clk;
951
952 return 0;
953
954 dis_mg_core_clk:
955 clk_disable_unprepare(priv->mg_core_clk);
956
957 dis_mg_domain_clk:
958 clk_disable_unprepare(priv->mg_domain_clk);
959
960 priv->mg_domain_clk = NULL;
961 priv->mg_core_clk = NULL;
962 priv->axi_clk = NULL;
963
964 return ret;
965 };
966
967 static void mvebu_comphy_disable_unprepare_clks(struct mvebu_comphy_priv *priv)
968 {
969 if (priv->axi_clk)
970 clk_disable_unprepare(priv->axi_clk);
971
972 if (priv->mg_core_clk)
973 clk_disable_unprepare(priv->mg_core_clk);
974
975 if (priv->mg_domain_clk)
976 clk_disable_unprepare(priv->mg_domain_clk);
977 }
978
979 static int mvebu_comphy_probe(struct platform_device *pdev)
980 {
981 struct mvebu_comphy_priv *priv;
982 struct phy_provider *provider;
983 struct device_node *child;
984 struct resource *res;
985 int ret;
986
987 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
988 if (!priv)
989 return -ENOMEM;
990
991 priv->dev = &pdev->dev;
992 priv->regmap =
993 syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
994 "marvell,system-controller");
995 if (IS_ERR(priv->regmap))
996 return PTR_ERR(priv->regmap);
997 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
998 priv->base = devm_ioremap_resource(&pdev->dev, res);
999 if (IS_ERR(priv->base))
1000 return PTR_ERR(priv->base);
1001
1002
1003
1004
1005
1006 ret = mvebu_comphy_init_clks(priv);
1007 if (ret) {
1008 if (ret == -EPROBE_DEFER)
1009 return ret;
1010 dev_warn(&pdev->dev, "cannot initialize clocks\n");
1011 }
1012
1013
1014
1015
1016
1017 priv->cp_phys = res->start;
1018
1019 for_each_available_child_of_node(pdev->dev.of_node, child) {
1020 struct mvebu_comphy_lane *lane;
1021 struct phy *phy;
1022 u32 val;
1023
1024 ret = of_property_read_u32(child, "reg", &val);
1025 if (ret < 0) {
1026 dev_err(&pdev->dev, "missing 'reg' property (%d)\n",
1027 ret);
1028 continue;
1029 }
1030
1031 if (val >= MVEBU_COMPHY_LANES) {
1032 dev_err(&pdev->dev, "invalid 'reg' property\n");
1033 continue;
1034 }
1035
1036 lane = devm_kzalloc(&pdev->dev, sizeof(*lane), GFP_KERNEL);
1037 if (!lane) {
1038 of_node_put(child);
1039 ret = -ENOMEM;
1040 goto disable_clks;
1041 }
1042
1043 phy = devm_phy_create(&pdev->dev, child, &mvebu_comphy_ops);
1044 if (IS_ERR(phy)) {
1045 of_node_put(child);
1046 ret = PTR_ERR(phy);
1047 goto disable_clks;
1048 }
1049
1050 lane->priv = priv;
1051 lane->mode = PHY_MODE_INVALID;
1052 lane->submode = PHY_INTERFACE_MODE_NA;
1053 lane->id = val;
1054 lane->port = -1;
1055 phy_set_drvdata(phy, lane);
1056
1057
1058
1059
1060
1061
1062
1063
1064 }
1065
1066 dev_set_drvdata(&pdev->dev, priv);
1067 provider = devm_of_phy_provider_register(&pdev->dev,
1068 mvebu_comphy_xlate);
1069
1070 return PTR_ERR_OR_ZERO(provider);
1071
1072 disable_clks:
1073 mvebu_comphy_disable_unprepare_clks(priv);
1074
1075 return ret;
1076 }
1077
1078 static const struct of_device_id mvebu_comphy_of_match_table[] = {
1079 { .compatible = "marvell,comphy-cp110" },
1080 { },
1081 };
1082 MODULE_DEVICE_TABLE(of, mvebu_comphy_of_match_table);
1083
1084 static struct platform_driver mvebu_comphy_driver = {
1085 .probe = mvebu_comphy_probe,
1086 .driver = {
1087 .name = "mvebu-comphy",
1088 .of_match_table = mvebu_comphy_of_match_table,
1089 },
1090 };
1091 module_platform_driver(mvebu_comphy_driver);
1092
1093 MODULE_AUTHOR("Antoine Tenart <antoine.tenart@free-electrons.com>");
1094 MODULE_DESCRIPTION("Common PHY driver for mvebu SoCs");
1095 MODULE_LICENSE("GPL v2");