GNU Linux-libre 5.10.215-gnu1
[releases.git] / drivers / phy / marvell / phy-mvebu-cp110-comphy.c
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
177 struct 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
206 static 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
253 struct 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
263 struct 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
271 static 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
290 static 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
320 static 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
326 static 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
332 static 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
448 static 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
489 static 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
522 static 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
575 static 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
717 static 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
761 static 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
838 try_legacy:
839         /* Fallback to Linux's implementation */
840         return mvebu_comphy_power_on_legacy(phy);
841 }
842
843 static 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
864 static 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
887 static 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
902 static 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
909 static 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
928 static 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
962 dis_mg_core_clk:
963         clk_disable_unprepare(priv->mg_core_clk);
964
965 dis_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
975 static 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
987 static 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
1080 disable_clks:
1081         mvebu_comphy_disable_unprepare_clks(priv);
1082
1083         return ret;
1084 }
1085
1086 static const struct of_device_id mvebu_comphy_of_match_table[] = {
1087         { .compatible = "marvell,comphy-cp110" },
1088         { },
1089 };
1090 MODULE_DEVICE_TABLE(of, mvebu_comphy_of_match_table);
1091
1092 static 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 };
1099 module_platform_driver(mvebu_comphy_driver);
1100
1101 MODULE_AUTHOR("Antoine Tenart <antoine.tenart@free-electrons.com>");
1102 MODULE_DESCRIPTION("Common PHY driver for mvebu SoCs");
1103 MODULE_LICENSE("GPL v2");