1
2
3
4
5
6
7#include <common.h>
8#include <phy.h>
9#include <linux/compat.h>
10#include <malloc.h>
11
12#include <dm.h>
13#include <dt-bindings/net/ti-dp83869.h>
14
15
16#define DP83869_DEVADDR 0x1f
17
18#define MII_DP83869_PHYCTRL 0x10
19#define MII_DP83869_MICR 0x12
20#define MII_DP83869_CFG2 0x14
21#define MII_DP83869_BISCR 0x16
22#define DP83869_CTRL 0x1f
23#define DP83869_CFG4 0x1e
24
25
26#define DP83869_GEN_CFG3 0x0031
27#define DP83869_RGMIICTL 0x0032
28#define DP83869_STRAP_STS1 0x006E
29#define DP83869_RGMIIDCTL 0x0086
30#define DP83869_IO_MUX_CFG 0x0170
31#define DP83869_OP_MODE 0x01df
32#define DP83869_FX_CTRL 0x0c00
33
34#define DP83869_SW_RESET BIT(15)
35#define DP83869_SW_RESTART BIT(14)
36
37
38#define MII_DP83869_MICR_AN_ERR_INT_EN BIT(15)
39#define MII_DP83869_MICR_SPEED_CHNG_INT_EN BIT(14)
40#define MII_DP83869_MICR_DUP_MODE_CHNG_INT_EN BIT(13)
41#define MII_DP83869_MICR_PAGE_RXD_INT_EN BIT(12)
42#define MII_DP83869_MICR_AUTONEG_COMP_INT_EN BIT(11)
43#define MII_DP83869_MICR_LINK_STS_CHNG_INT_EN BIT(10)
44#define MII_DP83869_MICR_FALSE_CARRIER_INT_EN BIT(8)
45#define MII_DP83869_MICR_SLEEP_MODE_CHNG_INT_EN BIT(4)
46#define MII_DP83869_MICR_WOL_INT_EN BIT(3)
47#define MII_DP83869_MICR_XGMII_ERR_INT_EN BIT(2)
48#define MII_DP83869_MICR_POL_CHNG_INT_EN BIT(1)
49#define MII_DP83869_MICR_JABBER_INT_EN BIT(0)
50
51#define MII_DP83869_BMCR_DEFAULT (BMCR_ANENABLE | \
52 BMCR_FULLDPLX | \
53 BMCR_SPEED1000)
54
55
56#define DP83869_FX_CTRL_DEFAULT MII_DP83869_BMCR_DEFAULT
57
58
59#define DP83869_CFG1_DEFAULT (ADVERTISE_1000HALF | \
60 ADVERTISE_1000FULL | \
61 CTL1000_AS_MASTER)
62
63
64#define DP83869_RGMII_TX_CLK_DELAY_EN BIT(1)
65#define DP83869_RGMII_RX_CLK_DELAY_EN BIT(0)
66
67
68#define DP83869_STRAP_OP_MODE_MASK GENMASK(2, 0)
69#define DP83869_STRAP_STS1_RESERVED BIT(11)
70#define DP83869_STRAP_MIRROR_ENABLED BIT(12)
71
72
73#define DP83869_PHYCR_RX_FIFO_DEPTH_SHIFT 12
74#define DP83869_PHYCR_RX_FIFO_DEPTH_MASK GENMASK(13, 12)
75#define DP83869_PHYCR_TX_FIFO_DEPTH_SHIFT 14
76#define DP83869_PHYCR_TX_FIFO_DEPTH_MASK GENMASK(15, 14)
77#define DP83869_PHYCR_RESERVED_MASK BIT(11)
78#define DP83869_PHYCR_MDI_CROSSOVER_SHIFT 5
79#define DP83869_PHYCR_MDI_CROSSOVER_MDIX 2
80#define DP83869_PHY_CTRL_DEFAULT 0x48
81
82
83#define DP83869_RGMII_TX_CLK_DELAY_SHIFT 4
84#define DP83869_CLK_DELAY_DEF 7
85
86
87#define MII_DP83869_CFG2_SPEEDOPT_10EN 0x0040
88#define MII_DP83869_CFG2_SGMII_AUTONEGEN 0x0080
89#define MII_DP83869_CFG2_SPEEDOPT_ENH 0x0100
90#define MII_DP83869_CFG2_SPEEDOPT_CNT 0x0800
91#define MII_DP83869_CFG2_SPEEDOPT_INTLOW 0x2000
92#define MII_DP83869_CFG2_MASK 0x003F
93
94
95#define DEFAULT_FIFO_DEPTH DP83869_PHYCR_FIFO_DEPTH_4_B_NIB
96
97
98#define DP83869_IO_MUX_CFG_IO_IMPEDANCE_CTRL 0x1f
99
100#define DP83869_IO_MUX_CFG_IO_IMPEDANCE_MAX 0x0
101#define DP83869_IO_MUX_CFG_IO_IMPEDANCE_MIN 0x1f
102#define DP83869_IO_MUX_CFG_CLK_O_DISABLE BIT(6)
103#define DP83869_IO_MUX_CFG_CLK_O_SEL_SHIFT 8
104#define DP83869_IO_MUX_CFG_CLK_O_SEL_MASK \
105 GENMASK(0x1f, DP83869_IO_MUX_CFG_CLK_O_SEL_SHIFT)
106
107
108#define DP83869_CFG3_PORT_MIRROR_EN BIT(0)
109
110
111#define DP83869_OP_MODE_MII BIT(5)
112#define DP83869_SGMII_RGMII_BRIDGE BIT(6)
113
114enum {
115 DP83869_PORT_MIRRORING_KEEP,
116 DP83869_PORT_MIRRORING_EN,
117 DP83869_PORT_MIRRORING_DIS,
118};
119
120struct dp83869_private {
121 int tx_fifo_depth;
122 int rx_fifo_depth;
123 s32 rx_int_delay;
124 s32 tx_int_delay;
125 int io_impedance;
126 int port_mirroring;
127 bool set_clk_output;
128 int clk_output_sel;
129 int mode;
130};
131
132static int dp83869_readext(struct phy_device *phydev, int addr, int devad, int reg)
133{
134 return phy_read_mmd(phydev, devad, reg);
135}
136
137static int dp83869_writeext(struct phy_device *phydev, int addr, int devad, int reg, u16 val)
138{
139 return phy_write_mmd(phydev, devad, reg, val);
140}
141
142static int dp83869_config_port_mirroring(struct phy_device *phydev)
143{
144 struct dp83869_private *dp83869 =
145 (struct dp83869_private *)phydev->priv;
146 u16 val;
147
148 val = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_CFG4);
149
150 if (dp83869->port_mirroring == DP83869_PORT_MIRRORING_EN)
151 val |= DP83869_CFG3_PORT_MIRROR_EN;
152 else
153 val &= ~DP83869_CFG3_PORT_MIRROR_EN;
154
155 phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_CFG4, val);
156
157 return 0;
158}
159
160#ifdef CONFIG_DM_ETH
161static const int dp83869_internal_delay[] = {250, 500, 750, 1000, 1250, 1500,
162 1750, 2000, 2250, 2500, 2750, 3000,
163 3250, 3500, 3750, 4000};
164
165static int dp83869_set_strapped_mode(struct phy_device *phydev)
166{
167 struct dp83869_private *dp83869 = phydev->priv;
168 int val;
169
170 val = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_STRAP_STS1);
171 if (val < 0)
172 return val;
173
174 dp83869->mode = val & DP83869_STRAP_OP_MODE_MASK;
175
176 return 0;
177}
178
179
180
181
182
183
184static int dp83869_of_init(struct phy_device *phydev)
185{
186 struct dp83869_private * const dp83869 = phydev->priv;
187 const int delay_entries = ARRAY_SIZE(dp83869_internal_delay);
188 int ret;
189 ofnode node;
190
191 node = phy_get_ofnode(phydev);
192 if (!ofnode_valid(node))
193 return -EINVAL;
194
195 dp83869->io_impedance = -EINVAL;
196
197
198 dp83869->clk_output_sel = ofnode_read_u32_default(node, "ti,clk-output-sel",
199 DP83869_CLK_O_SEL_CHN_A_RCLK);
200
201 if (dp83869->clk_output_sel > DP83869_CLK_O_SEL_REF_CLK &&
202 dp83869->clk_output_sel != DP83869_CLK_O_SEL_OFF)
203 dp83869->clk_output_sel = DP83869_CLK_O_SEL_REF_CLK;
204
205
206 ret = ofnode_read_s32(node, "ti,op-mode", &dp83869->mode);
207 if (ret == 0) {
208 if (dp83869->mode < DP83869_RGMII_COPPER_ETHERNET ||
209 dp83869->mode > DP83869_SGMII_COPPER_ETHERNET)
210 return -EINVAL;
211 } else {
212 ret = dp83869_set_strapped_mode(phydev);
213 if (ret)
214 return ret;
215 }
216
217 if (ofnode_read_bool(node, "ti,max-output-impedance"))
218 dp83869->io_impedance = DP83869_IO_MUX_CFG_IO_IMPEDANCE_MAX;
219 else if (ofnode_read_bool(node, "ti,min-output-impedance"))
220 dp83869->io_impedance = DP83869_IO_MUX_CFG_IO_IMPEDANCE_MIN;
221
222 if (ofnode_read_bool(node, "enet-phy-lane-swap")) {
223 dp83869->port_mirroring = DP83869_PORT_MIRRORING_EN;
224 } else {
225 ret = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_STRAP_STS1);
226
227 if (ret < 0)
228 return ret;
229
230 if (ret & DP83869_STRAP_MIRROR_ENABLED)
231 dp83869->port_mirroring = DP83869_PORT_MIRRORING_EN;
232 else
233 dp83869->port_mirroring = DP83869_PORT_MIRRORING_DIS;
234 }
235
236 dp83869->rx_fifo_depth = ofnode_read_s32_default(node, "rx-fifo-depth",
237 DP83869_PHYCR_FIFO_DEPTH_4_B_NIB);
238
239 dp83869->tx_fifo_depth = ofnode_read_s32_default(node, "tx-fifo-depth",
240 DP83869_PHYCR_FIFO_DEPTH_4_B_NIB);
241
242
243 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
244 phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
245 dp83869->rx_int_delay = ofnode_read_u32_default(node, "rx-internal-delay-ps",
246 DP83869_CLK_DELAY_DEF);
247 if (dp83869->rx_int_delay > delay_entries) {
248 dp83869->rx_int_delay = DP83869_CLK_DELAY_DEF;
249 pr_debug("rx-internal-delay-ps not set/invalid, default to %ups\n",
250 dp83869_internal_delay[dp83869->rx_int_delay]);
251 }
252
253 dp83869->rx_int_delay = dp83869_internal_delay[dp83869->rx_int_delay];
254 }
255
256
257 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
258 phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
259 dp83869->tx_int_delay = ofnode_read_u32_default(node, "tx-internal-delay-ps",
260 DP83869_CLK_DELAY_DEF);
261 if (dp83869->tx_int_delay > delay_entries) {
262 dp83869->tx_int_delay = DP83869_CLK_DELAY_DEF;
263 pr_debug("tx-internal-delay-ps not set/invalid, default to %ups\n",
264 dp83869_internal_delay[dp83869->tx_int_delay]);
265 }
266
267 dp83869->tx_int_delay = dp83869_internal_delay[dp83869->tx_int_delay];
268 }
269
270 return 0;
271}
272#else
273static int dp83869_of_init(struct phy_device *phydev)
274{
275 struct dp83869_private *dp83869 = phydev->priv;
276
277 dp83869->rx_int_delay = DP83869_RGMIIDCTL_2_25_NS;
278 dp83869->tx_int_delay = DP83869_RGMIIDCTL_2_75_NS;
279 dp83869->fifo_depth = DEFAULT_FIFO_DEPTH;
280 dp83869->io_impedance = -EINVAL;
281
282 return 0;
283}
284#endif
285
286static int dp83869_configure_rgmii(struct phy_device *phydev,
287 struct dp83869_private *dp83869)
288{
289 int ret = 0, val;
290
291 if (phy_interface_is_rgmii(phydev)) {
292 val = phy_read(phydev, MDIO_DEVAD_NONE, MII_DP83869_PHYCTRL);
293 if (val < 0)
294 return val;
295
296 val &= ~(DP83869_PHYCR_TX_FIFO_DEPTH_MASK | DP83869_PHYCR_RX_FIFO_DEPTH_MASK);
297 val |= (dp83869->tx_fifo_depth << DP83869_PHYCR_TX_FIFO_DEPTH_SHIFT);
298 val |= (dp83869->rx_fifo_depth << DP83869_PHYCR_RX_FIFO_DEPTH_SHIFT);
299
300 ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83869_PHYCTRL, val);
301 if (ret)
302 return ret;
303 }
304
305 if (dp83869->io_impedance >= 0) {
306 val = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_IO_MUX_CFG);
307
308 val &= ~DP83869_IO_MUX_CFG_IO_IMPEDANCE_CTRL;
309 val |= dp83869->io_impedance & DP83869_IO_MUX_CFG_IO_IMPEDANCE_CTRL;
310
311 ret = phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_IO_MUX_CFG, val);
312
313 if (ret)
314 return ret;
315 }
316
317 return ret;
318}
319
320static int dp83869_configure_mode(struct phy_device *phydev,
321 struct dp83869_private *dp83869)
322{
323 int phy_ctrl_val;
324 int ret, val;
325
326 if (dp83869->mode < DP83869_RGMII_COPPER_ETHERNET ||
327 dp83869->mode > DP83869_SGMII_COPPER_ETHERNET)
328 return -EINVAL;
329
330
331
332
333 ret = phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_OP_MODE,
334 dp83869->mode);
335 if (ret)
336 return ret;
337
338 ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, MII_DP83869_BMCR_DEFAULT);
339 if (ret)
340 return ret;
341
342 phy_ctrl_val = (dp83869->rx_fifo_depth << DP83869_PHYCR_RX_FIFO_DEPTH_SHIFT |
343 dp83869->tx_fifo_depth << DP83869_PHYCR_TX_FIFO_DEPTH_SHIFT |
344 DP83869_PHY_CTRL_DEFAULT);
345
346 switch (dp83869->mode) {
347 case DP83869_RGMII_COPPER_ETHERNET:
348 ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83869_PHYCTRL,
349 phy_ctrl_val);
350 if (ret)
351 return ret;
352
353 ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, DP83869_CFG1_DEFAULT);
354 if (ret)
355 return ret;
356
357 ret = dp83869_configure_rgmii(phydev, dp83869);
358 if (ret)
359 return ret;
360 break;
361 case DP83869_RGMII_SGMII_BRIDGE:
362 val = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_OP_MODE);
363
364 val |= DP83869_SGMII_RGMII_BRIDGE;
365
366 ret = phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_OP_MODE, val);
367
368 if (ret)
369 return ret;
370
371 ret = phy_write_mmd(phydev, DP83869_DEVADDR,
372 DP83869_FX_CTRL, DP83869_FX_CTRL_DEFAULT);
373 if (ret)
374 return ret;
375
376 break;
377 case DP83869_1000M_MEDIA_CONVERT:
378 ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83869_PHYCTRL,
379 phy_ctrl_val);
380 if (ret)
381 return ret;
382
383 ret = phy_write_mmd(phydev, DP83869_DEVADDR,
384 DP83869_FX_CTRL, DP83869_FX_CTRL_DEFAULT);
385 if (ret)
386 return ret;
387 break;
388 case DP83869_100M_MEDIA_CONVERT:
389 ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83869_PHYCTRL,
390 phy_ctrl_val);
391 if (ret)
392 return ret;
393 break;
394 case DP83869_SGMII_COPPER_ETHERNET:
395 ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83869_PHYCTRL,
396 phy_ctrl_val);
397 if (ret)
398 return ret;
399
400 ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, DP83869_CFG1_DEFAULT);
401 if (ret)
402 return ret;
403
404 ret = phy_write_mmd(phydev, DP83869_DEVADDR,
405 DP83869_FX_CTRL, DP83869_FX_CTRL_DEFAULT);
406 if (ret)
407 return ret;
408
409 break;
410 default:
411 return -EINVAL;
412 }
413
414 return ret;
415}
416
417static int dp83869_config(struct phy_device *phydev)
418{
419 struct dp83869_private *dp83869;
420 unsigned int val;
421 int ret;
422
423 dp83869 = (struct dp83869_private *)phydev->priv;
424
425 ret = dp83869_of_init(phydev);
426 if (ret)
427 return ret;
428
429 ret = dp83869_configure_mode(phydev, dp83869);
430 if (ret)
431 return ret;
432
433 if (dp83869->port_mirroring != DP83869_PORT_MIRRORING_KEEP)
434 dp83869_config_port_mirroring(phydev);
435
436
437 if (dp83869->clk_output_sel != DP83869_CLK_O_SEL_REF_CLK) {
438 val = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_IO_MUX_CFG);
439
440 val &= ~DP83869_IO_MUX_CFG_CLK_O_SEL_MASK;
441 val |= dp83869->clk_output_sel << DP83869_IO_MUX_CFG_CLK_O_SEL_SHIFT;
442
443 ret = phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_IO_MUX_CFG, val);
444
445 if (ret)
446 return ret;
447 }
448
449 if (phy_interface_is_rgmii(phydev)) {
450 ret = phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_RGMIIDCTL,
451 dp83869->rx_int_delay |
452 dp83869->tx_int_delay << DP83869_RGMII_TX_CLK_DELAY_SHIFT);
453 if (ret)
454 return ret;
455
456 val = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_RGMIICTL);
457 val |= (DP83869_RGMII_TX_CLK_DELAY_EN |
458 DP83869_RGMII_RX_CLK_DELAY_EN);
459
460 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
461 val &= ~(DP83869_RGMII_TX_CLK_DELAY_EN |
462 DP83869_RGMII_RX_CLK_DELAY_EN);
463
464 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
465 val &= ~DP83869_RGMII_TX_CLK_DELAY_EN;
466
467 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
468 val &= ~DP83869_RGMII_RX_CLK_DELAY_EN;
469
470 ret = phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_RGMIICTL,
471 val);
472 }
473
474 genphy_config_aneg(phydev);
475 return 0;
476}
477
478static int dp83869_probe(struct phy_device *phydev)
479{
480 struct dp83869_private *dp83869;
481
482 dp83869 = kzalloc(sizeof(*dp83869), GFP_KERNEL);
483 if (!dp83869)
484 return -ENOMEM;
485
486 phydev->priv = dp83869;
487 return 0;
488}
489
490static struct phy_driver DP83869_driver = {
491 .name = "TI DP83869",
492 .uid = 0x2000a0f1,
493 .mask = 0xfffffff0,
494 .features = PHY_GBIT_FEATURES,
495 .probe = dp83869_probe,
496 .config = &dp83869_config,
497 .startup = &genphy_startup,
498 .shutdown = &genphy_shutdown,
499 .readext = dp83869_readext,
500 .writeext = dp83869_writeext
501};
502
503int phy_dp83869_init(void)
504{
505 phy_register(&DP83869_driver);
506 return 0;
507}
508