blob: b6fb5adae1f42c2320f618ad005efdd09bc8fc24 [file] [log] [blame]
Dominic Rath11147e02021-12-22 08:57:46 +01001// SPDX-License-Identifier: GPL-2.0
2/*
3 * TI PHY drivers
4 *
5 */
6
Dominic Rath11147e02021-12-22 08:57:46 +01007#include <phy.h>
8#include <linux/compat.h>
9#include <malloc.h>
10
11#include <dm.h>
12#include <dt-bindings/net/ti-dp83869.h>
13
14/* TI DP83869 */
15#define DP83869_DEVADDR 0x1f
16
17#define MII_DP83869_PHYCTRL 0x10
18#define MII_DP83869_MICR 0x12
19#define MII_DP83869_CFG2 0x14
20#define MII_DP83869_BISCR 0x16
21#define DP83869_CTRL 0x1f
22#define DP83869_CFG4 0x1e
23
24/* Extended Registers */
25#define DP83869_GEN_CFG3 0x0031
26#define DP83869_RGMIICTL 0x0032
27#define DP83869_STRAP_STS1 0x006E
28#define DP83869_RGMIIDCTL 0x0086
29#define DP83869_IO_MUX_CFG 0x0170
30#define DP83869_OP_MODE 0x01df
31#define DP83869_FX_CTRL 0x0c00
32
33#define DP83869_SW_RESET BIT(15)
34#define DP83869_SW_RESTART BIT(14)
35
36/* MICR Interrupt bits */
37#define MII_DP83869_MICR_AN_ERR_INT_EN BIT(15)
38#define MII_DP83869_MICR_SPEED_CHNG_INT_EN BIT(14)
39#define MII_DP83869_MICR_DUP_MODE_CHNG_INT_EN BIT(13)
40#define MII_DP83869_MICR_PAGE_RXD_INT_EN BIT(12)
41#define MII_DP83869_MICR_AUTONEG_COMP_INT_EN BIT(11)
42#define MII_DP83869_MICR_LINK_STS_CHNG_INT_EN BIT(10)
43#define MII_DP83869_MICR_FALSE_CARRIER_INT_EN BIT(8)
44#define MII_DP83869_MICR_SLEEP_MODE_CHNG_INT_EN BIT(4)
45#define MII_DP83869_MICR_WOL_INT_EN BIT(3)
46#define MII_DP83869_MICR_XGMII_ERR_INT_EN BIT(2)
47#define MII_DP83869_MICR_POL_CHNG_INT_EN BIT(1)
48#define MII_DP83869_MICR_JABBER_INT_EN BIT(0)
49
50#define MII_DP83869_BMCR_DEFAULT (BMCR_ANENABLE | \
51 BMCR_FULLDPLX | \
52 BMCR_SPEED1000)
53
54/* This is the same bit mask as the BMCR so re-use the BMCR default */
55#define DP83869_FX_CTRL_DEFAULT MII_DP83869_BMCR_DEFAULT
56
57/* CFG1 bits */
58#define DP83869_CFG1_DEFAULT (ADVERTISE_1000HALF | \
59 ADVERTISE_1000FULL | \
60 CTL1000_AS_MASTER)
61
62/* RGMIICTL bits */
63#define DP83869_RGMII_TX_CLK_DELAY_EN BIT(1)
64#define DP83869_RGMII_RX_CLK_DELAY_EN BIT(0)
65
66/* STRAP_STS1 bits */
67#define DP83869_STRAP_OP_MODE_MASK GENMASK(2, 0)
68#define DP83869_STRAP_STS1_RESERVED BIT(11)
69#define DP83869_STRAP_MIRROR_ENABLED BIT(12)
70
71/* PHY CTRL bits */
72#define DP83869_PHYCR_RX_FIFO_DEPTH_SHIFT 12
73#define DP83869_PHYCR_RX_FIFO_DEPTH_MASK GENMASK(13, 12)
74#define DP83869_PHYCR_TX_FIFO_DEPTH_SHIFT 14
75#define DP83869_PHYCR_TX_FIFO_DEPTH_MASK GENMASK(15, 14)
76#define DP83869_PHYCR_RESERVED_MASK BIT(11)
77#define DP83869_PHYCR_MDI_CROSSOVER_SHIFT 5
78#define DP83869_PHYCR_MDI_CROSSOVER_MDIX 2
79#define DP83869_PHY_CTRL_DEFAULT 0x48
80
81/* RGMIIDCTL bits */
82#define DP83869_RGMII_TX_CLK_DELAY_SHIFT 4
Frank de Brabander7322e6f2023-10-06 14:24:39 +020083#define DP83869_CLK_DELAY_STEP 250
84#define DP83869_CLK_DELAY_MIN 250
85#define DP83869_CLK_DELAY_MAX 4000
86#define DP83869_CLK_DELAY_DEFAULT 2000
Dominic Rath11147e02021-12-22 08:57:46 +010087
88/* CFG2 bits */
89#define MII_DP83869_CFG2_SPEEDOPT_10EN 0x0040
90#define MII_DP83869_CFG2_SGMII_AUTONEGEN 0x0080
91#define MII_DP83869_CFG2_SPEEDOPT_ENH 0x0100
92#define MII_DP83869_CFG2_SPEEDOPT_CNT 0x0800
93#define MII_DP83869_CFG2_SPEEDOPT_INTLOW 0x2000
94#define MII_DP83869_CFG2_MASK 0x003F
95
96/* User setting - can be taken from DTS */
97#define DEFAULT_FIFO_DEPTH DP83869_PHYCR_FIFO_DEPTH_4_B_NIB
98
99/* IO_MUX_CFG bits */
100#define DP83869_IO_MUX_CFG_IO_IMPEDANCE_CTRL 0x1f
101
102#define DP83869_IO_MUX_CFG_IO_IMPEDANCE_MAX 0x0
103#define DP83869_IO_MUX_CFG_IO_IMPEDANCE_MIN 0x1f
104#define DP83869_IO_MUX_CFG_CLK_O_DISABLE BIT(6)
105#define DP83869_IO_MUX_CFG_CLK_O_SEL_SHIFT 8
106#define DP83869_IO_MUX_CFG_CLK_O_SEL_MASK \
107 GENMASK(0x1f, DP83869_IO_MUX_CFG_CLK_O_SEL_SHIFT)
108
109/* CFG3 bits */
110#define DP83869_CFG3_PORT_MIRROR_EN BIT(0)
111
112/* OP MODE bits */
113#define DP83869_OP_MODE_MII BIT(5)
114#define DP83869_SGMII_RGMII_BRIDGE BIT(6)
115
116enum {
117 DP83869_PORT_MIRRORING_KEEP,
118 DP83869_PORT_MIRRORING_EN,
119 DP83869_PORT_MIRRORING_DIS,
120};
121
122struct dp83869_private {
123 int tx_fifo_depth;
124 int rx_fifo_depth;
125 s32 rx_int_delay;
126 s32 tx_int_delay;
127 int io_impedance;
128 int port_mirroring;
129 bool set_clk_output;
130 int clk_output_sel;
131 int mode;
132};
133
134static int dp83869_readext(struct phy_device *phydev, int addr, int devad, int reg)
135{
136 return phy_read_mmd(phydev, devad, reg);
137}
138
139static int dp83869_writeext(struct phy_device *phydev, int addr, int devad, int reg, u16 val)
140{
141 return phy_write_mmd(phydev, devad, reg, val);
142}
143
144static int dp83869_config_port_mirroring(struct phy_device *phydev)
145{
146 struct dp83869_private *dp83869 =
147 (struct dp83869_private *)phydev->priv;
148 u16 val;
149
150 val = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_CFG4);
151
152 if (dp83869->port_mirroring == DP83869_PORT_MIRRORING_EN)
153 val |= DP83869_CFG3_PORT_MIRROR_EN;
154 else
155 val &= ~DP83869_CFG3_PORT_MIRROR_EN;
156
157 phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_CFG4, val);
158
159 return 0;
160}
161
Dominic Rath11147e02021-12-22 08:57:46 +0100162static int dp83869_set_strapped_mode(struct phy_device *phydev)
163{
164 struct dp83869_private *dp83869 = phydev->priv;
165 int val;
166
167 val = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_STRAP_STS1);
168 if (val < 0)
169 return val;
170
171 dp83869->mode = val & DP83869_STRAP_OP_MODE_MASK;
172
173 return 0;
174}
175
176/**
177 * dp83869_data_init - Convenience function for setting PHY specific data
178 *
179 * @phydev: the phy_device struct
180 */
181static int dp83869_of_init(struct phy_device *phydev)
182{
183 struct dp83869_private * const dp83869 = phydev->priv;
Dominic Rath11147e02021-12-22 08:57:46 +0100184 int ret;
185 ofnode node;
186
187 node = phy_get_ofnode(phydev);
188 if (!ofnode_valid(node))
189 return -EINVAL;
190
191 dp83869->io_impedance = -EINVAL;
192
193 /* Optional configuration, set to default if required */
194 dp83869->clk_output_sel = ofnode_read_u32_default(node, "ti,clk-output-sel",
195 DP83869_CLK_O_SEL_CHN_A_RCLK);
196
197 if (dp83869->clk_output_sel > DP83869_CLK_O_SEL_REF_CLK &&
198 dp83869->clk_output_sel != DP83869_CLK_O_SEL_OFF)
199 dp83869->clk_output_sel = DP83869_CLK_O_SEL_REF_CLK;
200
201 /* If operation mode is not set use setting from straps */
202 ret = ofnode_read_s32(node, "ti,op-mode", &dp83869->mode);
203 if (ret == 0) {
204 if (dp83869->mode < DP83869_RGMII_COPPER_ETHERNET ||
205 dp83869->mode > DP83869_SGMII_COPPER_ETHERNET)
206 return -EINVAL;
207 } else {
208 ret = dp83869_set_strapped_mode(phydev);
209 if (ret)
210 return ret;
211 }
212
213 if (ofnode_read_bool(node, "ti,max-output-impedance"))
214 dp83869->io_impedance = DP83869_IO_MUX_CFG_IO_IMPEDANCE_MAX;
215 else if (ofnode_read_bool(node, "ti,min-output-impedance"))
216 dp83869->io_impedance = DP83869_IO_MUX_CFG_IO_IMPEDANCE_MIN;
217
218 if (ofnode_read_bool(node, "enet-phy-lane-swap")) {
219 dp83869->port_mirroring = DP83869_PORT_MIRRORING_EN;
220 } else {
221 ret = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_STRAP_STS1);
222
223 if (ret < 0)
224 return ret;
225
226 if (ret & DP83869_STRAP_MIRROR_ENABLED)
227 dp83869->port_mirroring = DP83869_PORT_MIRRORING_EN;
228 else
229 dp83869->port_mirroring = DP83869_PORT_MIRRORING_DIS;
230 }
231
232 dp83869->rx_fifo_depth = ofnode_read_s32_default(node, "rx-fifo-depth",
233 DP83869_PHYCR_FIFO_DEPTH_4_B_NIB);
234
235 dp83869->tx_fifo_depth = ofnode_read_s32_default(node, "tx-fifo-depth",
236 DP83869_PHYCR_FIFO_DEPTH_4_B_NIB);
237
Frank de Brabander7322e6f2023-10-06 14:24:39 +0200238 /* Internal clock delay values can be configured in steps of
239 * 250ps (0.25ns). The register field for clock delay is 4-bits wide,
240 * the values range from 0b0000 for 0.25ns to 0b1111 for 4ns.
241 */
242
Dominic Rath11147e02021-12-22 08:57:46 +0100243 /* RX delay *must* be specified if internal delay of RX is used. */
244 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
245 phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
Frank de Brabander7322e6f2023-10-06 14:24:39 +0200246 dp83869->rx_int_delay = ofnode_read_u32_default(node,
247 "rx-internal-delay-ps", DP83869_CLK_DELAY_DEFAULT);
248 if (dp83869->rx_int_delay > DP83869_CLK_DELAY_MAX ||
249 dp83869->rx_int_delay < DP83869_CLK_DELAY_MIN ||
250 dp83869->rx_int_delay % DP83869_CLK_DELAY_STEP) {
251 dp83869->rx_int_delay = DP83869_CLK_DELAY_DEFAULT;
252 pr_warn("rx-internal-delay-ps not set/invalid, default"
253 " to %ups\n", DP83869_CLK_DELAY_DEFAULT);
Dominic Rath11147e02021-12-22 08:57:46 +0100254 }
255
Frank de Brabander7322e6f2023-10-06 14:24:39 +0200256 dp83869->rx_int_delay =
257 (dp83869->rx_int_delay - DP83869_CLK_DELAY_STEP)
258 / DP83869_CLK_DELAY_STEP;
Dominic Rath11147e02021-12-22 08:57:46 +0100259 }
260
Frank de Brabander7322e6f2023-10-06 14:24:39 +0200261 /* TX delay *must* be specified if internal delay of TX is used. */
Dominic Rath11147e02021-12-22 08:57:46 +0100262 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
263 phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
Frank de Brabander7322e6f2023-10-06 14:24:39 +0200264 dp83869->tx_int_delay = ofnode_read_u32_default(node,
265 "tx-internal-delay-ps", DP83869_CLK_DELAY_DEFAULT);
266 if (dp83869->tx_int_delay > DP83869_CLK_DELAY_MAX ||
267 dp83869->tx_int_delay < DP83869_CLK_DELAY_MIN ||
268 dp83869->tx_int_delay % DP83869_CLK_DELAY_STEP) {
269 dp83869->tx_int_delay = DP83869_CLK_DELAY_DEFAULT;
270 pr_warn("tx-internal-delay-ps not set/invalid, default"
271 " to %ups\n", DP83869_CLK_DELAY_DEFAULT);
Dominic Rath11147e02021-12-22 08:57:46 +0100272 }
273
Frank de Brabander7322e6f2023-10-06 14:24:39 +0200274 dp83869->tx_int_delay =
275 (dp83869->tx_int_delay - DP83869_CLK_DELAY_STEP)
276 / DP83869_CLK_DELAY_STEP;
Dominic Rath11147e02021-12-22 08:57:46 +0100277 }
278
279 return 0;
280}
Dominic Rath11147e02021-12-22 08:57:46 +0100281
282static int dp83869_configure_rgmii(struct phy_device *phydev,
283 struct dp83869_private *dp83869)
284{
285 int ret = 0, val;
286
287 if (phy_interface_is_rgmii(phydev)) {
288 val = phy_read(phydev, MDIO_DEVAD_NONE, MII_DP83869_PHYCTRL);
289 if (val < 0)
290 return val;
291
292 val &= ~(DP83869_PHYCR_TX_FIFO_DEPTH_MASK | DP83869_PHYCR_RX_FIFO_DEPTH_MASK);
293 val |= (dp83869->tx_fifo_depth << DP83869_PHYCR_TX_FIFO_DEPTH_SHIFT);
294 val |= (dp83869->rx_fifo_depth << DP83869_PHYCR_RX_FIFO_DEPTH_SHIFT);
295
296 ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83869_PHYCTRL, val);
297 if (ret)
298 return ret;
299 }
300
301 if (dp83869->io_impedance >= 0) {
302 val = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_IO_MUX_CFG);
303
304 val &= ~DP83869_IO_MUX_CFG_IO_IMPEDANCE_CTRL;
305 val |= dp83869->io_impedance & DP83869_IO_MUX_CFG_IO_IMPEDANCE_CTRL;
306
307 ret = phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_IO_MUX_CFG, val);
308
309 if (ret)
310 return ret;
311 }
312
313 return ret;
314}
315
316static int dp83869_configure_mode(struct phy_device *phydev,
317 struct dp83869_private *dp83869)
318{
319 int phy_ctrl_val;
320 int ret, val;
321
322 if (dp83869->mode < DP83869_RGMII_COPPER_ETHERNET ||
323 dp83869->mode > DP83869_SGMII_COPPER_ETHERNET)
324 return -EINVAL;
325
326 /* Below init sequence for each operational mode is defined in
327 * section 9.4.8 of the datasheet.
328 */
329 ret = phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_OP_MODE,
330 dp83869->mode);
331 if (ret)
332 return ret;
333
334 ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, MII_DP83869_BMCR_DEFAULT);
335 if (ret)
336 return ret;
337
338 phy_ctrl_val = (dp83869->rx_fifo_depth << DP83869_PHYCR_RX_FIFO_DEPTH_SHIFT |
339 dp83869->tx_fifo_depth << DP83869_PHYCR_TX_FIFO_DEPTH_SHIFT |
340 DP83869_PHY_CTRL_DEFAULT);
341
342 switch (dp83869->mode) {
343 case DP83869_RGMII_COPPER_ETHERNET:
344 ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83869_PHYCTRL,
345 phy_ctrl_val);
346 if (ret)
347 return ret;
348
349 ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, DP83869_CFG1_DEFAULT);
350 if (ret)
351 return ret;
352
353 ret = dp83869_configure_rgmii(phydev, dp83869);
354 if (ret)
355 return ret;
356 break;
357 case DP83869_RGMII_SGMII_BRIDGE:
358 val = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_OP_MODE);
359
360 val |= DP83869_SGMII_RGMII_BRIDGE;
361
362 ret = phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_OP_MODE, val);
363
364 if (ret)
365 return ret;
366
367 ret = phy_write_mmd(phydev, DP83869_DEVADDR,
368 DP83869_FX_CTRL, DP83869_FX_CTRL_DEFAULT);
369 if (ret)
370 return ret;
371
372 break;
373 case DP83869_1000M_MEDIA_CONVERT:
374 ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83869_PHYCTRL,
375 phy_ctrl_val);
376 if (ret)
377 return ret;
378
379 ret = phy_write_mmd(phydev, DP83869_DEVADDR,
380 DP83869_FX_CTRL, DP83869_FX_CTRL_DEFAULT);
381 if (ret)
382 return ret;
383 break;
384 case DP83869_100M_MEDIA_CONVERT:
385 ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83869_PHYCTRL,
386 phy_ctrl_val);
387 if (ret)
388 return ret;
389 break;
390 case DP83869_SGMII_COPPER_ETHERNET:
391 ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83869_PHYCTRL,
392 phy_ctrl_val);
393 if (ret)
394 return ret;
395
396 ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, DP83869_CFG1_DEFAULT);
397 if (ret)
398 return ret;
399
400 ret = phy_write_mmd(phydev, DP83869_DEVADDR,
401 DP83869_FX_CTRL, DP83869_FX_CTRL_DEFAULT);
402 if (ret)
403 return ret;
404
405 break;
406 default:
407 return -EINVAL;
408 }
409
410 return ret;
411}
412
413static int dp83869_config(struct phy_device *phydev)
414{
415 struct dp83869_private *dp83869;
416 unsigned int val;
417 int ret;
418
419 dp83869 = (struct dp83869_private *)phydev->priv;
420
421 ret = dp83869_of_init(phydev);
422 if (ret)
423 return ret;
424
425 ret = dp83869_configure_mode(phydev, dp83869);
426 if (ret)
427 return ret;
428
429 if (dp83869->port_mirroring != DP83869_PORT_MIRRORING_KEEP)
430 dp83869_config_port_mirroring(phydev);
431
432 /* Clock output selection if muxing property is set */
433 if (dp83869->clk_output_sel != DP83869_CLK_O_SEL_REF_CLK) {
434 val = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_IO_MUX_CFG);
435
436 val &= ~DP83869_IO_MUX_CFG_CLK_O_SEL_MASK;
437 val |= dp83869->clk_output_sel << DP83869_IO_MUX_CFG_CLK_O_SEL_SHIFT;
438
439 ret = phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_IO_MUX_CFG, val);
440
441 if (ret)
442 return ret;
443 }
444
445 if (phy_interface_is_rgmii(phydev)) {
446 ret = phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_RGMIIDCTL,
447 dp83869->rx_int_delay |
448 dp83869->tx_int_delay << DP83869_RGMII_TX_CLK_DELAY_SHIFT);
449 if (ret)
450 return ret;
451
452 val = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_RGMIICTL);
453 val |= (DP83869_RGMII_TX_CLK_DELAY_EN |
454 DP83869_RGMII_RX_CLK_DELAY_EN);
455
456 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
457 val &= ~(DP83869_RGMII_TX_CLK_DELAY_EN |
458 DP83869_RGMII_RX_CLK_DELAY_EN);
459
460 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
461 val &= ~DP83869_RGMII_TX_CLK_DELAY_EN;
462
463 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
464 val &= ~DP83869_RGMII_RX_CLK_DELAY_EN;
465
466 ret = phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_RGMIICTL,
467 val);
468 }
469
470 genphy_config_aneg(phydev);
471 return 0;
472}
473
474static int dp83869_probe(struct phy_device *phydev)
475{
476 struct dp83869_private *dp83869;
477
478 dp83869 = kzalloc(sizeof(*dp83869), GFP_KERNEL);
479 if (!dp83869)
480 return -ENOMEM;
481
482 phydev->priv = dp83869;
483 return 0;
484}
485
Marek Vasut417463c2023-03-19 18:03:04 +0100486U_BOOT_PHY_DRIVER(dp83869) = {
Dominic Rath11147e02021-12-22 08:57:46 +0100487 .name = "TI DP83869",
488 .uid = 0x2000a0f1,
489 .mask = 0xfffffff0,
490 .features = PHY_GBIT_FEATURES,
491 .probe = dp83869_probe,
492 .config = &dp83869_config,
493 .startup = &genphy_startup,
494 .shutdown = &genphy_shutdown,
495 .readext = dp83869_readext,
496 .writeext = dp83869_writeext
497};