xref: /openbmc/linux/drivers/phy/marvell/phy-mvebu-cp110-comphy.c (revision f79e4d5f92a129a1159c973735007d4ddc8541f3)
1 /*
2  * Copyright (C) 2017 Marvell
3  *
4  * Antoine Tenart <antoine.tenart@free-electrons.com>
5  *
6  * This file is licensed under the terms of the GNU General Public
7  * License version 2. This program is licensed "as is" without any
8  * warranty of any kind, whether express or implied.
9  */
10 
11 #include <linux/io.h>
12 #include <linux/iopoll.h>
13 #include <linux/mfd/syscon.h>
14 #include <linux/module.h>
15 #include <linux/phy/phy.h>
16 #include <linux/platform_device.h>
17 #include <linux/regmap.h>
18 
19 /* Relative to priv->base */
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_CFG1(n)		(0x4 + (n) * 0x1000)
28 #define     MVEBU_COMPHY_SERDES_CFG1_RESET	BIT(3)
29 #define     MVEBU_COMPHY_SERDES_CFG1_RX_INIT	BIT(4)
30 #define     MVEBU_COMPHY_SERDES_CFG1_CORE_RESET	BIT(5)
31 #define     MVEBU_COMPHY_SERDES_CFG1_RF_RESET	BIT(6)
32 #define MVEBU_COMPHY_SERDES_CFG2(n)		(0x8 + (n) * 0x1000)
33 #define     MVEBU_COMPHY_SERDES_CFG2_DFE_EN	BIT(4)
34 #define MVEBU_COMPHY_SERDES_STATUS0(n)		(0x18 + (n) * 0x1000)
35 #define     MVEBU_COMPHY_SERDES_STATUS0_TX_PLL_RDY	BIT(2)
36 #define     MVEBU_COMPHY_SERDES_STATUS0_RX_PLL_RDY	BIT(3)
37 #define     MVEBU_COMPHY_SERDES_STATUS0_RX_INIT		BIT(4)
38 #define MVEBU_COMPHY_PWRPLL_CTRL(n)		(0x804 + (n) * 0x1000)
39 #define     MVEBU_COMPHY_PWRPLL_CTRL_RFREQ(n)	((n) << 0)
40 #define     MVEBU_COMPHY_PWRPLL_PHY_MODE(n)	((n) << 5)
41 #define MVEBU_COMPHY_IMP_CAL(n)			(0x80c + (n) * 0x1000)
42 #define     MVEBU_COMPHY_IMP_CAL_TX_EXT(n)	((n) << 10)
43 #define     MVEBU_COMPHY_IMP_CAL_TX_EXT_EN	BIT(15)
44 #define MVEBU_COMPHY_DFE_RES(n)			(0x81c + (n) * 0x1000)
45 #define     MVEBU_COMPHY_DFE_RES_FORCE_GEN_TBL	BIT(15)
46 #define MVEBU_COMPHY_COEF(n)			(0x828 + (n) * 0x1000)
47 #define     MVEBU_COMPHY_COEF_DFE_EN		BIT(14)
48 #define     MVEBU_COMPHY_COEF_DFE_CTRL		BIT(15)
49 #define MVEBU_COMPHY_GEN1_S0(n)			(0x834 + (n) * 0x1000)
50 #define     MVEBU_COMPHY_GEN1_S0_TX_AMP(n)	((n) << 1)
51 #define     MVEBU_COMPHY_GEN1_S0_TX_EMPH(n)	((n) << 7)
52 #define MVEBU_COMPHY_GEN1_S1(n)			(0x838 + (n) * 0x1000)
53 #define     MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(n)	((n) << 0)
54 #define     MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(n)	((n) << 3)
55 #define     MVEBU_COMPHY_GEN1_S1_RX_MUL_FI(n)	((n) << 6)
56 #define     MVEBU_COMPHY_GEN1_S1_RX_MUL_FF(n)	((n) << 8)
57 #define     MVEBU_COMPHY_GEN1_S1_RX_DFE_EN	BIT(10)
58 #define     MVEBU_COMPHY_GEN1_S1_RX_DIV(n)	((n) << 11)
59 #define MVEBU_COMPHY_GEN1_S2(n)			(0x8f4 + (n) * 0x1000)
60 #define     MVEBU_COMPHY_GEN1_S2_TX_EMPH(n)	((n) << 0)
61 #define     MVEBU_COMPHY_GEN1_S2_TX_EMPH_EN	BIT(4)
62 #define MVEBU_COMPHY_LOOPBACK(n)		(0x88c + (n) * 0x1000)
63 #define     MVEBU_COMPHY_LOOPBACK_DBUS_WIDTH(n)	((n) << 1)
64 #define MVEBU_COMPHY_VDD_CAL0(n)		(0x908 + (n) * 0x1000)
65 #define     MVEBU_COMPHY_VDD_CAL0_CONT_MODE	BIT(15)
66 #define MVEBU_COMPHY_EXT_SELV(n)		(0x914 + (n) * 0x1000)
67 #define     MVEBU_COMPHY_EXT_SELV_RX_SAMPL(n)	((n) << 5)
68 #define MVEBU_COMPHY_MISC_CTRL0(n)		(0x93c + (n) * 0x1000)
69 #define     MVEBU_COMPHY_MISC_CTRL0_ICP_FORCE	BIT(5)
70 #define     MVEBU_COMPHY_MISC_CTRL0_REFCLK_SEL	BIT(10)
71 #define MVEBU_COMPHY_RX_CTRL1(n)		(0x940 + (n) * 0x1000)
72 #define     MVEBU_COMPHY_RX_CTRL1_RXCLK2X_SEL	BIT(11)
73 #define     MVEBU_COMPHY_RX_CTRL1_CLK8T_EN	BIT(12)
74 #define MVEBU_COMPHY_SPEED_DIV(n)		(0x954 + (n) * 0x1000)
75 #define     MVEBU_COMPHY_SPEED_DIV_TX_FORCE	BIT(7)
76 #define MVEBU_SP_CALIB(n)			(0x96c + (n) * 0x1000)
77 #define     MVEBU_SP_CALIB_SAMPLER(n)		((n) << 8)
78 #define     MVEBU_SP_CALIB_SAMPLER_EN		BIT(12)
79 #define MVEBU_COMPHY_TX_SLEW_RATE(n)		(0x974 + (n) * 0x1000)
80 #define     MVEBU_COMPHY_TX_SLEW_RATE_EMPH(n)	((n) << 5)
81 #define     MVEBU_COMPHY_TX_SLEW_RATE_SLC(n)	((n) << 10)
82 #define MVEBU_COMPHY_DLT_CTRL(n)		(0x984 + (n) * 0x1000)
83 #define     MVEBU_COMPHY_DLT_CTRL_DTL_FLOOP_EN	BIT(2)
84 #define MVEBU_COMPHY_FRAME_DETECT0(n)		(0xa14 + (n) * 0x1000)
85 #define     MVEBU_COMPHY_FRAME_DETECT0_PATN(n)	((n) << 7)
86 #define MVEBU_COMPHY_FRAME_DETECT3(n)		(0xa20 + (n) * 0x1000)
87 #define     MVEBU_COMPHY_FRAME_DETECT3_LOST_TIMEOUT_EN	BIT(12)
88 #define MVEBU_COMPHY_DME(n)			(0xa28 + (n) * 0x1000)
89 #define     MVEBU_COMPHY_DME_ETH_MODE		BIT(7)
90 #define MVEBU_COMPHY_TRAINING0(n)		(0xa68 + (n) * 0x1000)
91 #define     MVEBU_COMPHY_TRAINING0_P2P_HOLD	BIT(15)
92 #define MVEBU_COMPHY_TRAINING5(n)		(0xaa4 + (n) * 0x1000)
93 #define	    MVEBU_COMPHY_TRAINING5_RX_TIMER(n)	((n) << 0)
94 #define MVEBU_COMPHY_TX_TRAIN_PRESET(n)		(0xb1c + (n) * 0x1000)
95 #define     MVEBU_COMPHY_TX_TRAIN_PRESET_16B_AUTO_EN	BIT(8)
96 #define     MVEBU_COMPHY_TX_TRAIN_PRESET_PRBS11		BIT(9)
97 #define MVEBU_COMPHY_GEN1_S3(n)			(0xc40 + (n) * 0x1000)
98 #define     MVEBU_COMPHY_GEN1_S3_FBCK_SEL	BIT(9)
99 #define MVEBU_COMPHY_GEN1_S4(n)			(0xc44 + (n) * 0x1000)
100 #define	    MVEBU_COMPHY_GEN1_S4_DFE_RES(n)	((n) << 8)
101 #define MVEBU_COMPHY_TX_PRESET(n)		(0xc68 + (n) * 0x1000)
102 #define     MVEBU_COMPHY_TX_PRESET_INDEX(n)	((n) << 0)
103 #define MVEBU_COMPHY_GEN1_S5(n)			(0xd38 + (n) * 0x1000)
104 #define     MVEBU_COMPHY_GEN1_S5_ICP(n)		((n) << 0)
105 
106 /* Relative to priv->regmap */
107 #define MVEBU_COMPHY_CONF1(n)			(0x1000 + (n) * 0x28)
108 #define     MVEBU_COMPHY_CONF1_PWRUP		BIT(1)
109 #define     MVEBU_COMPHY_CONF1_USB_PCIE		BIT(2)	/* 0: Ethernet/SATA */
110 #define MVEBU_COMPHY_CONF6(n)			(0x1014 + (n) * 0x28)
111 #define     MVEBU_COMPHY_CONF6_40B		BIT(18)
112 #define MVEBU_COMPHY_SELECTOR			0x1140
113 #define     MVEBU_COMPHY_SELECTOR_PHY(n)	((n) * 0x4)
114 #define MVEBU_COMPHY_PIPE_SELECTOR		0x1144
115 #define     MVEBU_COMPHY_PIPE_SELECTOR_PIPE(n)	((n) * 0x4)
116 
117 #define MVEBU_COMPHY_LANES	6
118 #define MVEBU_COMPHY_PORTS	3
119 
120 struct mvebu_comhy_conf {
121 	enum phy_mode mode;
122 	unsigned lane;
123 	unsigned port;
124 	u32 mux;
125 };
126 
127 #define MVEBU_COMPHY_CONF(_lane, _port, _mode, _mux)	\
128 	{						\
129 		.lane = _lane,				\
130 		.port = _port,				\
131 		.mode = _mode,				\
132 		.mux = _mux,				\
133 	}
134 
135 static const struct mvebu_comhy_conf mvebu_comphy_cp110_modes[] = {
136 	/* lane 0 */
137 	MVEBU_COMPHY_CONF(0, 1, PHY_MODE_SGMII, 0x1),
138 	MVEBU_COMPHY_CONF(0, 1, PHY_MODE_2500SGMII, 0x1),
139 	/* lane 1 */
140 	MVEBU_COMPHY_CONF(1, 2, PHY_MODE_SGMII, 0x1),
141 	MVEBU_COMPHY_CONF(1, 2, PHY_MODE_2500SGMII, 0x1),
142 	/* lane 2 */
143 	MVEBU_COMPHY_CONF(2, 0, PHY_MODE_SGMII, 0x1),
144 	MVEBU_COMPHY_CONF(2, 0, PHY_MODE_2500SGMII, 0x1),
145 	MVEBU_COMPHY_CONF(2, 0, PHY_MODE_10GKR, 0x1),
146 	/* lane 3 */
147 	MVEBU_COMPHY_CONF(3, 1, PHY_MODE_SGMII, 0x2),
148 	MVEBU_COMPHY_CONF(3, 1, PHY_MODE_2500SGMII, 0x2),
149 	/* lane 4 */
150 	MVEBU_COMPHY_CONF(4, 0, PHY_MODE_SGMII, 0x2),
151 	MVEBU_COMPHY_CONF(4, 0, PHY_MODE_2500SGMII, 0x2),
152 	MVEBU_COMPHY_CONF(4, 0, PHY_MODE_10GKR, 0x2),
153 	MVEBU_COMPHY_CONF(4, 1, PHY_MODE_SGMII, 0x1),
154 	/* lane 5 */
155 	MVEBU_COMPHY_CONF(5, 2, PHY_MODE_SGMII, 0x1),
156 	MVEBU_COMPHY_CONF(5, 2, PHY_MODE_2500SGMII, 0x1),
157 };
158 
159 struct mvebu_comphy_priv {
160 	void __iomem *base;
161 	struct regmap *regmap;
162 	struct device *dev;
163 };
164 
165 struct mvebu_comphy_lane {
166 	struct mvebu_comphy_priv *priv;
167 	unsigned id;
168 	enum phy_mode mode;
169 	int port;
170 };
171 
172 static int mvebu_comphy_get_mux(int lane, int port, enum phy_mode mode)
173 {
174 	int i, n = ARRAY_SIZE(mvebu_comphy_cp110_modes);
175 
176 	/* Unused PHY mux value is 0x0 */
177 	if (mode == PHY_MODE_INVALID)
178 		return 0;
179 
180 	for (i = 0; i < n; i++) {
181 		if (mvebu_comphy_cp110_modes[i].lane == lane &&
182 		    mvebu_comphy_cp110_modes[i].port == port &&
183 		    mvebu_comphy_cp110_modes[i].mode == mode)
184 			break;
185 	}
186 
187 	if (i == n)
188 		return -EINVAL;
189 
190 	return mvebu_comphy_cp110_modes[i].mux;
191 }
192 
193 static void mvebu_comphy_ethernet_init_reset(struct mvebu_comphy_lane *lane,
194 					     enum phy_mode mode)
195 {
196 	struct mvebu_comphy_priv *priv = lane->priv;
197 	u32 val;
198 
199 	regmap_read(priv->regmap, MVEBU_COMPHY_CONF1(lane->id), &val);
200 	val &= ~MVEBU_COMPHY_CONF1_USB_PCIE;
201 	val |= MVEBU_COMPHY_CONF1_PWRUP;
202 	regmap_write(priv->regmap, MVEBU_COMPHY_CONF1(lane->id), val);
203 
204 	/* Select baud rates and PLLs */
205 	val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id));
206 	val &= ~(MVEBU_COMPHY_SERDES_CFG0_PU_PLL |
207 		 MVEBU_COMPHY_SERDES_CFG0_PU_RX |
208 		 MVEBU_COMPHY_SERDES_CFG0_PU_TX |
209 		 MVEBU_COMPHY_SERDES_CFG0_HALF_BUS |
210 		 MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0xf) |
211 		 MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0xf));
212 	if (mode == PHY_MODE_10GKR)
213 		val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0xe) |
214 		       MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0xe);
215 	else if (mode == PHY_MODE_2500SGMII)
216 		val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0x8) |
217 		       MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0x8) |
218 		       MVEBU_COMPHY_SERDES_CFG0_HALF_BUS;
219 	else if (mode == PHY_MODE_SGMII)
220 		val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0x6) |
221 		       MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0x6) |
222 		       MVEBU_COMPHY_SERDES_CFG0_HALF_BUS;
223 	writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id));
224 
225 	/* reset */
226 	val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
227 	val &= ~(MVEBU_COMPHY_SERDES_CFG1_RESET |
228 		 MVEBU_COMPHY_SERDES_CFG1_CORE_RESET |
229 		 MVEBU_COMPHY_SERDES_CFG1_RF_RESET);
230 	writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
231 
232 	/* de-assert reset */
233 	val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
234 	val |= MVEBU_COMPHY_SERDES_CFG1_RESET |
235 	       MVEBU_COMPHY_SERDES_CFG1_CORE_RESET;
236 	writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
237 
238 	/* wait until clocks are ready */
239 	mdelay(1);
240 
241 	/* exlicitly disable 40B, the bits isn't clear on reset */
242 	regmap_read(priv->regmap, MVEBU_COMPHY_CONF6(lane->id), &val);
243 	val &= ~MVEBU_COMPHY_CONF6_40B;
244 	regmap_write(priv->regmap, MVEBU_COMPHY_CONF6(lane->id), val);
245 
246 	/* refclk selection */
247 	val = readl(priv->base + MVEBU_COMPHY_MISC_CTRL0(lane->id));
248 	val &= ~MVEBU_COMPHY_MISC_CTRL0_REFCLK_SEL;
249 	if (mode == PHY_MODE_10GKR)
250 		val |= MVEBU_COMPHY_MISC_CTRL0_ICP_FORCE;
251 	writel(val, priv->base + MVEBU_COMPHY_MISC_CTRL0(lane->id));
252 
253 	/* power and pll selection */
254 	val = readl(priv->base + MVEBU_COMPHY_PWRPLL_CTRL(lane->id));
255 	val &= ~(MVEBU_COMPHY_PWRPLL_CTRL_RFREQ(0x1f) |
256 		 MVEBU_COMPHY_PWRPLL_PHY_MODE(0x7));
257 	val |= MVEBU_COMPHY_PWRPLL_CTRL_RFREQ(0x1) |
258 	       MVEBU_COMPHY_PWRPLL_PHY_MODE(0x4);
259 	writel(val, priv->base + MVEBU_COMPHY_PWRPLL_CTRL(lane->id));
260 
261 	val = readl(priv->base + MVEBU_COMPHY_LOOPBACK(lane->id));
262 	val &= ~MVEBU_COMPHY_LOOPBACK_DBUS_WIDTH(0x7);
263 	val |= MVEBU_COMPHY_LOOPBACK_DBUS_WIDTH(0x1);
264 	writel(val, priv->base + MVEBU_COMPHY_LOOPBACK(lane->id));
265 }
266 
267 static int mvebu_comphy_init_plls(struct mvebu_comphy_lane *lane,
268 				  enum phy_mode mode)
269 {
270 	struct mvebu_comphy_priv *priv = lane->priv;
271 	u32 val;
272 
273 	/* SERDES external config */
274 	val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id));
275 	val |= MVEBU_COMPHY_SERDES_CFG0_PU_PLL |
276 	       MVEBU_COMPHY_SERDES_CFG0_PU_RX |
277 	       MVEBU_COMPHY_SERDES_CFG0_PU_TX;
278 	writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id));
279 
280 	/* check rx/tx pll */
281 	readl_poll_timeout(priv->base + MVEBU_COMPHY_SERDES_STATUS0(lane->id),
282 			   val,
283 			   val & (MVEBU_COMPHY_SERDES_STATUS0_RX_PLL_RDY |
284 				  MVEBU_COMPHY_SERDES_STATUS0_TX_PLL_RDY),
285 			   1000, 150000);
286 	if (!(val & (MVEBU_COMPHY_SERDES_STATUS0_RX_PLL_RDY |
287 		     MVEBU_COMPHY_SERDES_STATUS0_TX_PLL_RDY)))
288 		return -ETIMEDOUT;
289 
290 	/* rx init */
291 	val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
292 	val |= MVEBU_COMPHY_SERDES_CFG1_RX_INIT;
293 	writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
294 
295 	/* check rx */
296 	readl_poll_timeout(priv->base + MVEBU_COMPHY_SERDES_STATUS0(lane->id),
297 			   val, val & MVEBU_COMPHY_SERDES_STATUS0_RX_INIT,
298 			   1000, 10000);
299 	if (!(val & MVEBU_COMPHY_SERDES_STATUS0_RX_INIT))
300 		return -ETIMEDOUT;
301 
302 	val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
303 	val &= ~MVEBU_COMPHY_SERDES_CFG1_RX_INIT;
304 	writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
305 
306 	return 0;
307 }
308 
309 static int mvebu_comphy_set_mode_sgmii(struct phy *phy, enum phy_mode mode)
310 {
311 	struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
312 	struct mvebu_comphy_priv *priv = lane->priv;
313 	u32 val;
314 
315 	mvebu_comphy_ethernet_init_reset(lane, mode);
316 
317 	val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
318 	val &= ~MVEBU_COMPHY_RX_CTRL1_CLK8T_EN;
319 	val |= MVEBU_COMPHY_RX_CTRL1_RXCLK2X_SEL;
320 	writel(val, priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
321 
322 	val = readl(priv->base + MVEBU_COMPHY_DLT_CTRL(lane->id));
323 	val &= ~MVEBU_COMPHY_DLT_CTRL_DTL_FLOOP_EN;
324 	writel(val, priv->base + MVEBU_COMPHY_DLT_CTRL(lane->id));
325 
326 	regmap_read(priv->regmap, MVEBU_COMPHY_CONF1(lane->id), &val);
327 	val &= ~MVEBU_COMPHY_CONF1_USB_PCIE;
328 	val |= MVEBU_COMPHY_CONF1_PWRUP;
329 	regmap_write(priv->regmap, MVEBU_COMPHY_CONF1(lane->id), val);
330 
331 	val = readl(priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
332 	val &= ~MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xf);
333 	val |= MVEBU_COMPHY_GEN1_S0_TX_EMPH(0x1);
334 	writel(val, priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
335 
336 	return mvebu_comphy_init_plls(lane, PHY_MODE_SGMII);
337 }
338 
339 static int mvebu_comphy_set_mode_10gkr(struct phy *phy)
340 {
341 	struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
342 	struct mvebu_comphy_priv *priv = lane->priv;
343 	u32 val;
344 
345 	mvebu_comphy_ethernet_init_reset(lane, PHY_MODE_10GKR);
346 
347 	val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
348 	val |= MVEBU_COMPHY_RX_CTRL1_RXCLK2X_SEL |
349 	       MVEBU_COMPHY_RX_CTRL1_CLK8T_EN;
350 	writel(val, priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
351 
352 	val = readl(priv->base + MVEBU_COMPHY_DLT_CTRL(lane->id));
353 	val |= MVEBU_COMPHY_DLT_CTRL_DTL_FLOOP_EN;
354 	writel(val, priv->base + MVEBU_COMPHY_DLT_CTRL(lane->id));
355 
356 	/* Speed divider */
357 	val = readl(priv->base + MVEBU_COMPHY_SPEED_DIV(lane->id));
358 	val |= MVEBU_COMPHY_SPEED_DIV_TX_FORCE;
359 	writel(val, priv->base + MVEBU_COMPHY_SPEED_DIV(lane->id));
360 
361 	val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG2(lane->id));
362 	val |= MVEBU_COMPHY_SERDES_CFG2_DFE_EN;
363 	writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG2(lane->id));
364 
365 	/* DFE resolution */
366 	val = readl(priv->base + MVEBU_COMPHY_DFE_RES(lane->id));
367 	val |= MVEBU_COMPHY_DFE_RES_FORCE_GEN_TBL;
368 	writel(val, priv->base + MVEBU_COMPHY_DFE_RES(lane->id));
369 
370 	val = readl(priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
371 	val &= ~(MVEBU_COMPHY_GEN1_S0_TX_AMP(0x1f) |
372 		 MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xf));
373 	val |= MVEBU_COMPHY_GEN1_S0_TX_AMP(0x1c) |
374 	       MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xe);
375 	writel(val, priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
376 
377 	val = readl(priv->base + MVEBU_COMPHY_GEN1_S2(lane->id));
378 	val &= ~MVEBU_COMPHY_GEN1_S2_TX_EMPH(0xf);
379 	val |= MVEBU_COMPHY_GEN1_S2_TX_EMPH_EN;
380 	writel(val, priv->base + MVEBU_COMPHY_GEN1_S2(lane->id));
381 
382 	val = readl(priv->base + MVEBU_COMPHY_TX_SLEW_RATE(lane->id));
383 	val |= MVEBU_COMPHY_TX_SLEW_RATE_EMPH(0x3) |
384 	       MVEBU_COMPHY_TX_SLEW_RATE_SLC(0x3f);
385 	writel(val, priv->base + MVEBU_COMPHY_TX_SLEW_RATE(lane->id));
386 
387 	/* Impedance calibration */
388 	val = readl(priv->base + MVEBU_COMPHY_IMP_CAL(lane->id));
389 	val &= ~MVEBU_COMPHY_IMP_CAL_TX_EXT(0x1f);
390 	val |= MVEBU_COMPHY_IMP_CAL_TX_EXT(0xe) |
391 	       MVEBU_COMPHY_IMP_CAL_TX_EXT_EN;
392 	writel(val, priv->base + MVEBU_COMPHY_IMP_CAL(lane->id));
393 
394 	val = readl(priv->base + MVEBU_COMPHY_GEN1_S5(lane->id));
395 	val &= ~MVEBU_COMPHY_GEN1_S5_ICP(0xf);
396 	writel(val, priv->base + MVEBU_COMPHY_GEN1_S5(lane->id));
397 
398 	val = readl(priv->base + MVEBU_COMPHY_GEN1_S1(lane->id));
399 	val &= ~(MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(0x7) |
400 		 MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(0x7) |
401 		 MVEBU_COMPHY_GEN1_S1_RX_MUL_FI(0x3) |
402 		 MVEBU_COMPHY_GEN1_S1_RX_MUL_FF(0x3));
403 	val |= MVEBU_COMPHY_GEN1_S1_RX_DFE_EN |
404 	       MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(0x2) |
405 	       MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(0x2) |
406 	       MVEBU_COMPHY_GEN1_S1_RX_MUL_FF(0x1) |
407 	       MVEBU_COMPHY_GEN1_S1_RX_DIV(0x3);
408 	writel(val, priv->base + MVEBU_COMPHY_GEN1_S1(lane->id));
409 
410 	val = readl(priv->base + MVEBU_COMPHY_COEF(lane->id));
411 	val &= ~(MVEBU_COMPHY_COEF_DFE_EN | MVEBU_COMPHY_COEF_DFE_CTRL);
412 	writel(val, priv->base + MVEBU_COMPHY_COEF(lane->id));
413 
414 	val = readl(priv->base + MVEBU_COMPHY_GEN1_S4(lane->id));
415 	val &= ~MVEBU_COMPHY_GEN1_S4_DFE_RES(0x3);
416 	val |= MVEBU_COMPHY_GEN1_S4_DFE_RES(0x1);
417 	writel(val, priv->base + MVEBU_COMPHY_GEN1_S4(lane->id));
418 
419 	val = readl(priv->base + MVEBU_COMPHY_GEN1_S3(lane->id));
420 	val |= MVEBU_COMPHY_GEN1_S3_FBCK_SEL;
421 	writel(val, priv->base + MVEBU_COMPHY_GEN1_S3(lane->id));
422 
423 	/* rx training timer */
424 	val = readl(priv->base + MVEBU_COMPHY_TRAINING5(lane->id));
425 	val &= ~MVEBU_COMPHY_TRAINING5_RX_TIMER(0x3ff);
426 	val |= MVEBU_COMPHY_TRAINING5_RX_TIMER(0x13);
427 	writel(val, priv->base + MVEBU_COMPHY_TRAINING5(lane->id));
428 
429 	/* tx train peak to peak hold */
430 	val = readl(priv->base + MVEBU_COMPHY_TRAINING0(lane->id));
431 	val |= MVEBU_COMPHY_TRAINING0_P2P_HOLD;
432 	writel(val, priv->base + MVEBU_COMPHY_TRAINING0(lane->id));
433 
434 	val = readl(priv->base + MVEBU_COMPHY_TX_PRESET(lane->id));
435 	val &= ~MVEBU_COMPHY_TX_PRESET_INDEX(0xf);
436 	val |= MVEBU_COMPHY_TX_PRESET_INDEX(0x2);	/* preset coeff */
437 	writel(val, priv->base + MVEBU_COMPHY_TX_PRESET(lane->id));
438 
439 	val = readl(priv->base + MVEBU_COMPHY_FRAME_DETECT3(lane->id));
440 	val &= ~MVEBU_COMPHY_FRAME_DETECT3_LOST_TIMEOUT_EN;
441 	writel(val, priv->base + MVEBU_COMPHY_FRAME_DETECT3(lane->id));
442 
443 	val = readl(priv->base + MVEBU_COMPHY_TX_TRAIN_PRESET(lane->id));
444 	val |= MVEBU_COMPHY_TX_TRAIN_PRESET_16B_AUTO_EN |
445 	       MVEBU_COMPHY_TX_TRAIN_PRESET_PRBS11;
446 	writel(val, priv->base + MVEBU_COMPHY_TX_TRAIN_PRESET(lane->id));
447 
448 	val = readl(priv->base + MVEBU_COMPHY_FRAME_DETECT0(lane->id));
449 	val &= ~MVEBU_COMPHY_FRAME_DETECT0_PATN(0x1ff);
450 	val |= MVEBU_COMPHY_FRAME_DETECT0_PATN(0x88);
451 	writel(val, priv->base + MVEBU_COMPHY_FRAME_DETECT0(lane->id));
452 
453 	val = readl(priv->base + MVEBU_COMPHY_DME(lane->id));
454 	val |= MVEBU_COMPHY_DME_ETH_MODE;
455 	writel(val, priv->base + MVEBU_COMPHY_DME(lane->id));
456 
457 	val = readl(priv->base + MVEBU_COMPHY_VDD_CAL0(lane->id));
458 	val |= MVEBU_COMPHY_VDD_CAL0_CONT_MODE;
459 	writel(val, priv->base + MVEBU_COMPHY_VDD_CAL0(lane->id));
460 
461 	val = readl(priv->base + MVEBU_SP_CALIB(lane->id));
462 	val &= ~MVEBU_SP_CALIB_SAMPLER(0x3);
463 	val |= MVEBU_SP_CALIB_SAMPLER(0x3) |
464 	       MVEBU_SP_CALIB_SAMPLER_EN;
465 	writel(val, priv->base + MVEBU_SP_CALIB(lane->id));
466 	val &= ~MVEBU_SP_CALIB_SAMPLER_EN;
467 	writel(val, priv->base + MVEBU_SP_CALIB(lane->id));
468 
469 	/* External rx regulator */
470 	val = readl(priv->base + MVEBU_COMPHY_EXT_SELV(lane->id));
471 	val &= ~MVEBU_COMPHY_EXT_SELV_RX_SAMPL(0x1f);
472 	val |= MVEBU_COMPHY_EXT_SELV_RX_SAMPL(0x1a);
473 	writel(val, priv->base + MVEBU_COMPHY_EXT_SELV(lane->id));
474 
475 	return mvebu_comphy_init_plls(lane, PHY_MODE_10GKR);
476 }
477 
478 static int mvebu_comphy_power_on(struct phy *phy)
479 {
480 	struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
481 	struct mvebu_comphy_priv *priv = lane->priv;
482 	int ret, mux;
483 	u32 val;
484 
485 	mux = mvebu_comphy_get_mux(lane->id, lane->port, lane->mode);
486 	if (mux < 0)
487 		return -ENOTSUPP;
488 
489 	regmap_read(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, &val);
490 	val &= ~(0xf << MVEBU_COMPHY_PIPE_SELECTOR_PIPE(lane->id));
491 	regmap_write(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, val);
492 
493 	regmap_read(priv->regmap, MVEBU_COMPHY_SELECTOR, &val);
494 	val &= ~(0xf << MVEBU_COMPHY_SELECTOR_PHY(lane->id));
495 	val |= mux << MVEBU_COMPHY_SELECTOR_PHY(lane->id);
496 	regmap_write(priv->regmap, MVEBU_COMPHY_SELECTOR, val);
497 
498 	switch (lane->mode) {
499 	case PHY_MODE_SGMII:
500 	case PHY_MODE_2500SGMII:
501 		ret = mvebu_comphy_set_mode_sgmii(phy, lane->mode);
502 		break;
503 	case PHY_MODE_10GKR:
504 		ret = mvebu_comphy_set_mode_10gkr(phy);
505 		break;
506 	default:
507 		return -ENOTSUPP;
508 	}
509 
510 	/* digital reset */
511 	val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
512 	val |= MVEBU_COMPHY_SERDES_CFG1_RF_RESET;
513 	writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
514 
515 	return ret;
516 }
517 
518 static int mvebu_comphy_set_mode(struct phy *phy, enum phy_mode mode)
519 {
520 	struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
521 
522 	if (mvebu_comphy_get_mux(lane->id, lane->port, mode) < 0)
523 		return -EINVAL;
524 
525 	lane->mode = mode;
526 	return 0;
527 }
528 
529 static int mvebu_comphy_power_off(struct phy *phy)
530 {
531 	struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
532 	struct mvebu_comphy_priv *priv = lane->priv;
533 	u32 val;
534 
535 	val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
536 	val &= ~(MVEBU_COMPHY_SERDES_CFG1_RESET |
537 		 MVEBU_COMPHY_SERDES_CFG1_CORE_RESET |
538 		 MVEBU_COMPHY_SERDES_CFG1_RF_RESET);
539 	writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
540 
541 	regmap_read(priv->regmap, MVEBU_COMPHY_SELECTOR, &val);
542 	val &= ~(0xf << MVEBU_COMPHY_SELECTOR_PHY(lane->id));
543 	regmap_write(priv->regmap, MVEBU_COMPHY_SELECTOR, val);
544 
545 	regmap_read(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, &val);
546 	val &= ~(0xf << MVEBU_COMPHY_PIPE_SELECTOR_PIPE(lane->id));
547 	regmap_write(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, val);
548 
549 	return 0;
550 }
551 
552 static const struct phy_ops mvebu_comphy_ops = {
553 	.power_on	= mvebu_comphy_power_on,
554 	.power_off	= mvebu_comphy_power_off,
555 	.set_mode	= mvebu_comphy_set_mode,
556 	.owner		= THIS_MODULE,
557 };
558 
559 static struct phy *mvebu_comphy_xlate(struct device *dev,
560 				      struct of_phandle_args *args)
561 {
562 	struct mvebu_comphy_lane *lane;
563 	struct phy *phy;
564 
565 	if (WARN_ON(args->args[0] >= MVEBU_COMPHY_PORTS))
566 		return ERR_PTR(-EINVAL);
567 
568 	phy = of_phy_simple_xlate(dev, args);
569 	if (IS_ERR(phy))
570 		return phy;
571 
572 	lane = phy_get_drvdata(phy);
573 	if (lane->port >= 0)
574 		return ERR_PTR(-EBUSY);
575 	lane->port = args->args[0];
576 
577 	return phy;
578 }
579 
580 static int mvebu_comphy_probe(struct platform_device *pdev)
581 {
582 	struct mvebu_comphy_priv *priv;
583 	struct phy_provider *provider;
584 	struct device_node *child;
585 	struct resource *res;
586 
587 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
588 	if (!priv)
589 		return -ENOMEM;
590 
591 	priv->dev = &pdev->dev;
592 	priv->regmap =
593 		syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
594 						"marvell,system-controller");
595 	if (IS_ERR(priv->regmap))
596 		return PTR_ERR(priv->regmap);
597 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
598 	priv->base = devm_ioremap_resource(&pdev->dev, res);
599 	if (IS_ERR(priv->base))
600 		return PTR_ERR(priv->base);
601 
602 	for_each_available_child_of_node(pdev->dev.of_node, child) {
603 		struct mvebu_comphy_lane *lane;
604 		struct phy *phy;
605 		int ret;
606 		u32 val;
607 
608 		ret = of_property_read_u32(child, "reg", &val);
609 		if (ret < 0) {
610 			dev_err(&pdev->dev, "missing 'reg' property (%d)\n",
611 				ret);
612 			continue;
613 		}
614 
615 		if (val >= MVEBU_COMPHY_LANES) {
616 			dev_err(&pdev->dev, "invalid 'reg' property\n");
617 			continue;
618 		}
619 
620 		lane = devm_kzalloc(&pdev->dev, sizeof(*lane), GFP_KERNEL);
621 		if (!lane)
622 			return -ENOMEM;
623 
624 		phy = devm_phy_create(&pdev->dev, child, &mvebu_comphy_ops);
625 		if (IS_ERR(phy))
626 			return PTR_ERR(phy);
627 
628 		lane->priv = priv;
629 		lane->mode = PHY_MODE_INVALID;
630 		lane->id = val;
631 		lane->port = -1;
632 		phy_set_drvdata(phy, lane);
633 
634 		/*
635 		 * Once all modes are supported in this driver we should call
636 		 * mvebu_comphy_power_off(phy) here to avoid relying on the
637 		 * bootloader/firmware configuration.
638 		 */
639 	}
640 
641 	dev_set_drvdata(&pdev->dev, priv);
642 	provider = devm_of_phy_provider_register(&pdev->dev,
643 						 mvebu_comphy_xlate);
644 	return PTR_ERR_OR_ZERO(provider);
645 }
646 
647 static const struct of_device_id mvebu_comphy_of_match_table[] = {
648 	{ .compatible = "marvell,comphy-cp110" },
649 	{ },
650 };
651 MODULE_DEVICE_TABLE(of, mvebu_comphy_of_match_table);
652 
653 static struct platform_driver mvebu_comphy_driver = {
654 	.probe	= mvebu_comphy_probe,
655 	.driver	= {
656 		.name = "mvebu-comphy",
657 		.of_match_table = mvebu_comphy_of_match_table,
658 	},
659 };
660 module_platform_driver(mvebu_comphy_driver);
661 
662 MODULE_AUTHOR("Antoine Tenart <antoine.tenart@free-electrons.com>");
663 MODULE_DESCRIPTION("Common PHY driver for mvebu SoCs");
664 MODULE_LICENSE("GPL v2");
665