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