]> Git Repo - J-linux.git/blob - drivers/net/phy/dp83822.c
Merge tag 'kbuild-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy...
[J-linux.git] / drivers / net / phy / dp83822.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Driver for the Texas Instruments DP83822, DP83825 and DP83826 PHYs.
3  *
4  * Copyright (C) 2017 Texas Instruments Inc.
5  */
6
7 #include <linux/ethtool.h>
8 #include <linux/etherdevice.h>
9 #include <linux/kernel.h>
10 #include <linux/mii.h>
11 #include <linux/module.h>
12 #include <linux/of.h>
13 #include <linux/phy.h>
14 #include <linux/netdevice.h>
15 #include <linux/bitfield.h>
16
17 #define DP83822_PHY_ID          0x2000a240
18 #define DP83825S_PHY_ID         0x2000a140
19 #define DP83825I_PHY_ID         0x2000a150
20 #define DP83825CM_PHY_ID        0x2000a160
21 #define DP83825CS_PHY_ID        0x2000a170
22 #define DP83826C_PHY_ID         0x2000a130
23 #define DP83826NC_PHY_ID        0x2000a110
24
25 #define DP83822_DEVADDR         0x1f
26
27 #define MII_DP83822_CTRL_2      0x0a
28 #define MII_DP83822_PHYSTS      0x10
29 #define MII_DP83822_PHYSCR      0x11
30 #define MII_DP83822_MISR1       0x12
31 #define MII_DP83822_MISR2       0x13
32 #define MII_DP83822_FCSCR       0x14
33 #define MII_DP83822_RCSR        0x17
34 #define MII_DP83822_RESET_CTRL  0x1f
35 #define MII_DP83822_GENCFG      0x465
36 #define MII_DP83822_SOR1        0x467
37
38 /* DP83826 specific registers */
39 #define MII_DP83826_VOD_CFG1    0x30b
40 #define MII_DP83826_VOD_CFG2    0x30c
41
42 /* GENCFG */
43 #define DP83822_SIG_DET_LOW     BIT(0)
44
45 /* Control Register 2 bits */
46 #define DP83822_FX_ENABLE       BIT(14)
47
48 #define DP83822_HW_RESET        BIT(15)
49 #define DP83822_SW_RESET        BIT(14)
50
51 /* PHY STS bits */
52 #define DP83822_PHYSTS_DUPLEX                   BIT(2)
53 #define DP83822_PHYSTS_10                       BIT(1)
54 #define DP83822_PHYSTS_LINK                     BIT(0)
55
56 /* PHYSCR Register Fields */
57 #define DP83822_PHYSCR_INT_OE           BIT(0) /* Interrupt Output Enable */
58 #define DP83822_PHYSCR_INTEN            BIT(1) /* Interrupt Enable */
59
60 /* MISR1 bits */
61 #define DP83822_RX_ERR_HF_INT_EN        BIT(0)
62 #define DP83822_FALSE_CARRIER_HF_INT_EN BIT(1)
63 #define DP83822_ANEG_COMPLETE_INT_EN    BIT(2)
64 #define DP83822_DUP_MODE_CHANGE_INT_EN  BIT(3)
65 #define DP83822_SPEED_CHANGED_INT_EN    BIT(4)
66 #define DP83822_LINK_STAT_INT_EN        BIT(5)
67 #define DP83822_ENERGY_DET_INT_EN       BIT(6)
68 #define DP83822_LINK_QUAL_INT_EN        BIT(7)
69
70 /* MISR2 bits */
71 #define DP83822_JABBER_DET_INT_EN       BIT(0)
72 #define DP83822_WOL_PKT_INT_EN          BIT(1)
73 #define DP83822_SLEEP_MODE_INT_EN       BIT(2)
74 #define DP83822_MDI_XOVER_INT_EN        BIT(3)
75 #define DP83822_LB_FIFO_INT_EN          BIT(4)
76 #define DP83822_PAGE_RX_INT_EN          BIT(5)
77 #define DP83822_ANEG_ERR_INT_EN         BIT(6)
78 #define DP83822_EEE_ERROR_CHANGE_INT_EN BIT(7)
79
80 /* INT_STAT1 bits */
81 #define DP83822_WOL_INT_EN      BIT(4)
82 #define DP83822_WOL_INT_STAT    BIT(12)
83
84 #define MII_DP83822_RXSOP1      0x04a5
85 #define MII_DP83822_RXSOP2      0x04a6
86 #define MII_DP83822_RXSOP3      0x04a7
87
88 /* WoL Registers */
89 #define MII_DP83822_WOL_CFG     0x04a0
90 #define MII_DP83822_WOL_STAT    0x04a1
91 #define MII_DP83822_WOL_DA1     0x04a2
92 #define MII_DP83822_WOL_DA2     0x04a3
93 #define MII_DP83822_WOL_DA3     0x04a4
94
95 /* WoL bits */
96 #define DP83822_WOL_MAGIC_EN    BIT(0)
97 #define DP83822_WOL_SECURE_ON   BIT(5)
98 #define DP83822_WOL_EN          BIT(7)
99 #define DP83822_WOL_INDICATION_SEL BIT(8)
100 #define DP83822_WOL_CLR_INDICATION BIT(11)
101
102 /* RCSR bits */
103 #define DP83822_RMII_MODE_EN    BIT(5)
104 #define DP83822_RMII_MODE_SEL   BIT(7)
105 #define DP83822_RGMII_MODE_EN   BIT(9)
106 #define DP83822_RX_CLK_SHIFT    BIT(12)
107 #define DP83822_TX_CLK_SHIFT    BIT(11)
108
109 /* SOR1 mode */
110 #define DP83822_STRAP_MODE1     0
111 #define DP83822_STRAP_MODE2     BIT(0)
112 #define DP83822_STRAP_MODE3     BIT(1)
113 #define DP83822_STRAP_MODE4     GENMASK(1, 0)
114
115 #define DP83822_COL_STRAP_MASK  GENMASK(11, 10)
116 #define DP83822_COL_SHIFT       10
117 #define DP83822_RX_ER_STR_MASK  GENMASK(9, 8)
118 #define DP83822_RX_ER_SHIFT     8
119
120 /* DP83826: VOD_CFG1 & VOD_CFG2 */
121 #define DP83826_VOD_CFG1_MINUS_MDIX_MASK        GENMASK(13, 12)
122 #define DP83826_VOD_CFG1_MINUS_MDI_MASK         GENMASK(11, 6)
123 #define DP83826_VOD_CFG2_MINUS_MDIX_MASK        GENMASK(15, 12)
124 #define DP83826_VOD_CFG2_PLUS_MDIX_MASK         GENMASK(11, 6)
125 #define DP83826_VOD_CFG2_PLUS_MDI_MASK          GENMASK(5, 0)
126 #define DP83826_CFG_DAC_MINUS_MDIX_5_TO_4       GENMASK(5, 4)
127 #define DP83826_CFG_DAC_MINUS_MDIX_3_TO_0       GENMASK(3, 0)
128 #define DP83826_CFG_DAC_PERCENT_PER_STEP        625
129 #define DP83826_CFG_DAC_PERCENT_DEFAULT         10000
130 #define DP83826_CFG_DAC_MINUS_DEFAULT           0x30
131 #define DP83826_CFG_DAC_PLUS_DEFAULT            0x10
132
133 #define MII_DP83822_FIBER_ADVERTISE    (ADVERTISED_TP | ADVERTISED_MII | \
134                                         ADVERTISED_FIBRE | \
135                                         ADVERTISED_Pause | ADVERTISED_Asym_Pause)
136
137 struct dp83822_private {
138         bool fx_signal_det_low;
139         int fx_enabled;
140         u16 fx_sd_enable;
141         u8 cfg_dac_minus;
142         u8 cfg_dac_plus;
143 };
144
145 static int dp83822_set_wol(struct phy_device *phydev,
146                            struct ethtool_wolinfo *wol)
147 {
148         struct net_device *ndev = phydev->attached_dev;
149         u16 value;
150         const u8 *mac;
151
152         if (wol->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) {
153                 mac = (const u8 *)ndev->dev_addr;
154
155                 if (!is_valid_ether_addr(mac))
156                         return -EINVAL;
157
158                 /* MAC addresses start with byte 5, but stored in mac[0].
159                  * 822 PHYs store bytes 4|5, 2|3, 0|1
160                  */
161                 phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_DA1,
162                               (mac[1] << 8) | mac[0]);
163                 phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_DA2,
164                               (mac[3] << 8) | mac[2]);
165                 phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_DA3,
166                               (mac[5] << 8) | mac[4]);
167
168                 value = phy_read_mmd(phydev, DP83822_DEVADDR,
169                                      MII_DP83822_WOL_CFG);
170                 if (wol->wolopts & WAKE_MAGIC)
171                         value |= DP83822_WOL_MAGIC_EN;
172                 else
173                         value &= ~DP83822_WOL_MAGIC_EN;
174
175                 if (wol->wolopts & WAKE_MAGICSECURE) {
176                         phy_write_mmd(phydev, DP83822_DEVADDR,
177                                       MII_DP83822_RXSOP1,
178                                       (wol->sopass[1] << 8) | wol->sopass[0]);
179                         phy_write_mmd(phydev, DP83822_DEVADDR,
180                                       MII_DP83822_RXSOP2,
181                                       (wol->sopass[3] << 8) | wol->sopass[2]);
182                         phy_write_mmd(phydev, DP83822_DEVADDR,
183                                       MII_DP83822_RXSOP3,
184                                       (wol->sopass[5] << 8) | wol->sopass[4]);
185                         value |= DP83822_WOL_SECURE_ON;
186                 } else {
187                         value &= ~DP83822_WOL_SECURE_ON;
188                 }
189
190                 /* Clear any pending WoL interrupt */
191                 phy_read(phydev, MII_DP83822_MISR2);
192
193                 value |= DP83822_WOL_EN | DP83822_WOL_INDICATION_SEL |
194                          DP83822_WOL_CLR_INDICATION;
195
196                 return phy_write_mmd(phydev, DP83822_DEVADDR,
197                                      MII_DP83822_WOL_CFG, value);
198         } else {
199                 return phy_clear_bits_mmd(phydev, DP83822_DEVADDR,
200                                           MII_DP83822_WOL_CFG, DP83822_WOL_EN);
201         }
202 }
203
204 static void dp83822_get_wol(struct phy_device *phydev,
205                             struct ethtool_wolinfo *wol)
206 {
207         int value;
208         u16 sopass_val;
209
210         wol->supported = (WAKE_MAGIC | WAKE_MAGICSECURE);
211         wol->wolopts = 0;
212
213         value = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG);
214
215         if (value & DP83822_WOL_MAGIC_EN)
216                 wol->wolopts |= WAKE_MAGIC;
217
218         if (value & DP83822_WOL_SECURE_ON) {
219                 sopass_val = phy_read_mmd(phydev, DP83822_DEVADDR,
220                                           MII_DP83822_RXSOP1);
221                 wol->sopass[0] = (sopass_val & 0xff);
222                 wol->sopass[1] = (sopass_val >> 8);
223
224                 sopass_val = phy_read_mmd(phydev, DP83822_DEVADDR,
225                                           MII_DP83822_RXSOP2);
226                 wol->sopass[2] = (sopass_val & 0xff);
227                 wol->sopass[3] = (sopass_val >> 8);
228
229                 sopass_val = phy_read_mmd(phydev, DP83822_DEVADDR,
230                                           MII_DP83822_RXSOP3);
231                 wol->sopass[4] = (sopass_val & 0xff);
232                 wol->sopass[5] = (sopass_val >> 8);
233
234                 wol->wolopts |= WAKE_MAGICSECURE;
235         }
236
237         /* WoL is not enabled so set wolopts to 0 */
238         if (!(value & DP83822_WOL_EN))
239                 wol->wolopts = 0;
240 }
241
242 static int dp83822_config_intr(struct phy_device *phydev)
243 {
244         struct dp83822_private *dp83822 = phydev->priv;
245         int misr_status;
246         int physcr_status;
247         int err;
248
249         if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
250                 misr_status = phy_read(phydev, MII_DP83822_MISR1);
251                 if (misr_status < 0)
252                         return misr_status;
253
254                 misr_status |= (DP83822_LINK_STAT_INT_EN |
255                                 DP83822_ENERGY_DET_INT_EN |
256                                 DP83822_LINK_QUAL_INT_EN);
257
258                 /* Private data pointer is NULL on DP83825 */
259                 if (!dp83822 || !dp83822->fx_enabled)
260                         misr_status |= DP83822_ANEG_COMPLETE_INT_EN |
261                                        DP83822_DUP_MODE_CHANGE_INT_EN |
262                                        DP83822_SPEED_CHANGED_INT_EN;
263
264
265                 err = phy_write(phydev, MII_DP83822_MISR1, misr_status);
266                 if (err < 0)
267                         return err;
268
269                 misr_status = phy_read(phydev, MII_DP83822_MISR2);
270                 if (misr_status < 0)
271                         return misr_status;
272
273                 misr_status |= (DP83822_JABBER_DET_INT_EN |
274                                 DP83822_SLEEP_MODE_INT_EN |
275                                 DP83822_LB_FIFO_INT_EN |
276                                 DP83822_PAGE_RX_INT_EN |
277                                 DP83822_EEE_ERROR_CHANGE_INT_EN);
278
279                 /* Private data pointer is NULL on DP83825 */
280                 if (!dp83822 || !dp83822->fx_enabled)
281                         misr_status |= DP83822_ANEG_ERR_INT_EN |
282                                        DP83822_WOL_PKT_INT_EN;
283
284                 err = phy_write(phydev, MII_DP83822_MISR2, misr_status);
285                 if (err < 0)
286                         return err;
287
288                 physcr_status = phy_read(phydev, MII_DP83822_PHYSCR);
289                 if (physcr_status < 0)
290                         return physcr_status;
291
292                 physcr_status |= DP83822_PHYSCR_INT_OE | DP83822_PHYSCR_INTEN;
293
294         } else {
295                 err = phy_write(phydev, MII_DP83822_MISR1, 0);
296                 if (err < 0)
297                         return err;
298
299                 err = phy_write(phydev, MII_DP83822_MISR2, 0);
300                 if (err < 0)
301                         return err;
302
303                 physcr_status = phy_read(phydev, MII_DP83822_PHYSCR);
304                 if (physcr_status < 0)
305                         return physcr_status;
306
307                 physcr_status &= ~DP83822_PHYSCR_INTEN;
308         }
309
310         return phy_write(phydev, MII_DP83822_PHYSCR, physcr_status);
311 }
312
313 static irqreturn_t dp83822_handle_interrupt(struct phy_device *phydev)
314 {
315         bool trigger_machine = false;
316         int irq_status;
317
318         /* The MISR1 and MISR2 registers are holding the interrupt status in
319          * the upper half (15:8), while the lower half (7:0) is used for
320          * controlling the interrupt enable state of those individual interrupt
321          * sources. To determine the possible interrupt sources, just read the
322          * MISR* register and use it directly to know which interrupts have
323          * been enabled previously or not.
324          */
325         irq_status = phy_read(phydev, MII_DP83822_MISR1);
326         if (irq_status < 0) {
327                 phy_error(phydev);
328                 return IRQ_NONE;
329         }
330         if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
331                 trigger_machine = true;
332
333         irq_status = phy_read(phydev, MII_DP83822_MISR2);
334         if (irq_status < 0) {
335                 phy_error(phydev);
336                 return IRQ_NONE;
337         }
338         if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
339                 trigger_machine = true;
340
341         if (!trigger_machine)
342                 return IRQ_NONE;
343
344         phy_trigger_machine(phydev);
345
346         return IRQ_HANDLED;
347 }
348
349 static int dp8382x_disable_wol(struct phy_device *phydev)
350 {
351         return phy_clear_bits_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG,
352                                   DP83822_WOL_EN | DP83822_WOL_MAGIC_EN |
353                                   DP83822_WOL_SECURE_ON);
354 }
355
356 static int dp83822_read_status(struct phy_device *phydev)
357 {
358         struct dp83822_private *dp83822 = phydev->priv;
359         int status = phy_read(phydev, MII_DP83822_PHYSTS);
360         int ctrl2;
361         int ret;
362
363         if (dp83822->fx_enabled) {
364                 if (status & DP83822_PHYSTS_LINK) {
365                         phydev->speed = SPEED_UNKNOWN;
366                         phydev->duplex = DUPLEX_UNKNOWN;
367                 } else {
368                         ctrl2 = phy_read(phydev, MII_DP83822_CTRL_2);
369                         if (ctrl2 < 0)
370                                 return ctrl2;
371
372                         if (!(ctrl2 & DP83822_FX_ENABLE)) {
373                                 ret = phy_write(phydev, MII_DP83822_CTRL_2,
374                                                 DP83822_FX_ENABLE | ctrl2);
375                                 if (ret < 0)
376                                         return ret;
377                         }
378                 }
379         }
380
381         ret = genphy_read_status(phydev);
382         if (ret)
383                 return ret;
384
385         if (status < 0)
386                 return status;
387
388         if (status & DP83822_PHYSTS_DUPLEX)
389                 phydev->duplex = DUPLEX_FULL;
390         else
391                 phydev->duplex = DUPLEX_HALF;
392
393         if (status & DP83822_PHYSTS_10)
394                 phydev->speed = SPEED_10;
395         else
396                 phydev->speed = SPEED_100;
397
398         return 0;
399 }
400
401 static int dp83822_config_init(struct phy_device *phydev)
402 {
403         struct dp83822_private *dp83822 = phydev->priv;
404         struct device *dev = &phydev->mdio.dev;
405         int rgmii_delay = 0;
406         s32 rx_int_delay;
407         s32 tx_int_delay;
408         int err = 0;
409         int bmcr;
410
411         if (phy_interface_is_rgmii(phydev)) {
412                 rx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0,
413                                                       true);
414
415                 /* Set DP83822_RX_CLK_SHIFT to enable rx clk internal delay */
416                 if (rx_int_delay > 0)
417                         rgmii_delay |= DP83822_RX_CLK_SHIFT;
418
419                 tx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0,
420                                                       false);
421
422                 /* Set DP83822_TX_CLK_SHIFT to disable tx clk internal delay */
423                 if (tx_int_delay <= 0)
424                         rgmii_delay |= DP83822_TX_CLK_SHIFT;
425
426                 err = phy_modify_mmd(phydev, DP83822_DEVADDR, MII_DP83822_RCSR,
427                                      DP83822_RX_CLK_SHIFT | DP83822_TX_CLK_SHIFT, rgmii_delay);
428                 if (err)
429                         return err;
430
431                 err = phy_set_bits_mmd(phydev, DP83822_DEVADDR,
432                                        MII_DP83822_RCSR, DP83822_RGMII_MODE_EN);
433
434                 if (err)
435                         return err;
436         } else {
437                 err = phy_clear_bits_mmd(phydev, DP83822_DEVADDR,
438                                          MII_DP83822_RCSR, DP83822_RGMII_MODE_EN);
439
440                 if (err)
441                         return err;
442         }
443
444         if (dp83822->fx_enabled) {
445                 err = phy_modify(phydev, MII_DP83822_CTRL_2,
446                                  DP83822_FX_ENABLE, 1);
447                 if (err < 0)
448                         return err;
449
450                 /* Only allow advertising what this PHY supports */
451                 linkmode_and(phydev->advertising, phydev->advertising,
452                              phydev->supported);
453
454                 linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
455                                  phydev->supported);
456                 linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
457                                  phydev->advertising);
458                 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Full_BIT,
459                                  phydev->supported);
460                 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Half_BIT,
461                                  phydev->supported);
462                 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Full_BIT,
463                                  phydev->advertising);
464                 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Half_BIT,
465                                  phydev->advertising);
466
467                 /* Auto neg is not supported in fiber mode */
468                 bmcr = phy_read(phydev, MII_BMCR);
469                 if (bmcr < 0)
470                         return bmcr;
471
472                 if (bmcr & BMCR_ANENABLE) {
473                         err =  phy_modify(phydev, MII_BMCR, BMCR_ANENABLE, 0);
474                         if (err < 0)
475                                 return err;
476                 }
477                 phydev->autoneg = AUTONEG_DISABLE;
478                 linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
479                                    phydev->supported);
480                 linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
481                                    phydev->advertising);
482
483                 /* Setup fiber advertisement */
484                 err = phy_modify_changed(phydev, MII_ADVERTISE,
485                                          MII_DP83822_FIBER_ADVERTISE,
486                                          MII_DP83822_FIBER_ADVERTISE);
487
488                 if (err < 0)
489                         return err;
490
491                 if (dp83822->fx_signal_det_low) {
492                         err = phy_set_bits_mmd(phydev, DP83822_DEVADDR,
493                                                MII_DP83822_GENCFG,
494                                                DP83822_SIG_DET_LOW);
495                         if (err)
496                                 return err;
497                 }
498         }
499         return dp8382x_disable_wol(phydev);
500 }
501
502 static int dp83826_config_rmii_mode(struct phy_device *phydev)
503 {
504         struct device *dev = &phydev->mdio.dev;
505         const char *of_val;
506         int ret;
507
508         if (!device_property_read_string(dev, "ti,rmii-mode", &of_val)) {
509                 if (strcmp(of_val, "master") == 0) {
510                         ret = phy_clear_bits_mmd(phydev, DP83822_DEVADDR, MII_DP83822_RCSR,
511                                                  DP83822_RMII_MODE_SEL);
512                 } else if (strcmp(of_val, "slave") == 0) {
513                         ret = phy_set_bits_mmd(phydev, DP83822_DEVADDR, MII_DP83822_RCSR,
514                                                DP83822_RMII_MODE_SEL);
515                 } else {
516                         phydev_err(phydev, "Invalid value for ti,rmii-mode property (%s)\n",
517                                    of_val);
518                         ret = -EINVAL;
519                 }
520
521                 if (ret)
522                         return ret;
523         }
524
525         return 0;
526 }
527
528 static int dp83826_config_init(struct phy_device *phydev)
529 {
530         struct dp83822_private *dp83822 = phydev->priv;
531         u16 val, mask;
532         int ret;
533
534         if (phydev->interface == PHY_INTERFACE_MODE_RMII) {
535                 ret = phy_set_bits_mmd(phydev, DP83822_DEVADDR, MII_DP83822_RCSR,
536                                        DP83822_RMII_MODE_EN);
537                 if (ret)
538                         return ret;
539
540                 ret = dp83826_config_rmii_mode(phydev);
541                 if (ret)
542                         return ret;
543         } else {
544                 ret = phy_clear_bits_mmd(phydev, DP83822_DEVADDR, MII_DP83822_RCSR,
545                                          DP83822_RMII_MODE_EN);
546                 if (ret)
547                         return ret;
548         }
549
550         if (dp83822->cfg_dac_minus != DP83826_CFG_DAC_MINUS_DEFAULT) {
551                 val = FIELD_PREP(DP83826_VOD_CFG1_MINUS_MDI_MASK, dp83822->cfg_dac_minus) |
552                       FIELD_PREP(DP83826_VOD_CFG1_MINUS_MDIX_MASK,
553                                  FIELD_GET(DP83826_CFG_DAC_MINUS_MDIX_5_TO_4,
554                                            dp83822->cfg_dac_minus));
555                 mask = DP83826_VOD_CFG1_MINUS_MDIX_MASK | DP83826_VOD_CFG1_MINUS_MDI_MASK;
556                 ret = phy_modify_mmd(phydev, DP83822_DEVADDR, MII_DP83826_VOD_CFG1, mask, val);
557                 if (ret)
558                         return ret;
559
560                 val = FIELD_PREP(DP83826_VOD_CFG2_MINUS_MDIX_MASK,
561                                  FIELD_GET(DP83826_CFG_DAC_MINUS_MDIX_3_TO_0,
562                                            dp83822->cfg_dac_minus));
563                 mask = DP83826_VOD_CFG2_MINUS_MDIX_MASK;
564                 ret = phy_modify_mmd(phydev, DP83822_DEVADDR, MII_DP83826_VOD_CFG2, mask, val);
565                 if (ret)
566                         return ret;
567         }
568
569         if (dp83822->cfg_dac_plus != DP83826_CFG_DAC_PLUS_DEFAULT) {
570                 val = FIELD_PREP(DP83826_VOD_CFG2_PLUS_MDIX_MASK, dp83822->cfg_dac_plus) |
571                       FIELD_PREP(DP83826_VOD_CFG2_PLUS_MDI_MASK, dp83822->cfg_dac_plus);
572                 mask = DP83826_VOD_CFG2_PLUS_MDIX_MASK | DP83826_VOD_CFG2_PLUS_MDI_MASK;
573                 ret = phy_modify_mmd(phydev, DP83822_DEVADDR, MII_DP83826_VOD_CFG2, mask, val);
574                 if (ret)
575                         return ret;
576         }
577
578         return dp8382x_disable_wol(phydev);
579 }
580
581 static int dp8382x_config_init(struct phy_device *phydev)
582 {
583         return dp8382x_disable_wol(phydev);
584 }
585
586 static int dp83822_phy_reset(struct phy_device *phydev)
587 {
588         int err;
589
590         err = phy_write(phydev, MII_DP83822_RESET_CTRL, DP83822_SW_RESET);
591         if (err < 0)
592                 return err;
593
594         return phydev->drv->config_init(phydev);
595 }
596
597 #ifdef CONFIG_OF_MDIO
598 static int dp83822_of_init(struct phy_device *phydev)
599 {
600         struct dp83822_private *dp83822 = phydev->priv;
601         struct device *dev = &phydev->mdio.dev;
602
603         /* Signal detection for the PHY is only enabled if the FX_EN and the
604          * SD_EN pins are strapped. Signal detection can only enabled if FX_EN
605          * is strapped otherwise signal detection is disabled for the PHY.
606          */
607         if (dp83822->fx_enabled && dp83822->fx_sd_enable)
608                 dp83822->fx_signal_det_low = device_property_present(dev,
609                                                                      "ti,link-loss-low");
610         if (!dp83822->fx_enabled)
611                 dp83822->fx_enabled = device_property_present(dev,
612                                                               "ti,fiber-mode");
613
614         return 0;
615 }
616
617 static int dp83826_to_dac_minus_one_regval(int percent)
618 {
619         int tmp = DP83826_CFG_DAC_PERCENT_DEFAULT - percent;
620
621         return tmp / DP83826_CFG_DAC_PERCENT_PER_STEP;
622 }
623
624 static int dp83826_to_dac_plus_one_regval(int percent)
625 {
626         int tmp = percent - DP83826_CFG_DAC_PERCENT_DEFAULT;
627
628         return tmp / DP83826_CFG_DAC_PERCENT_PER_STEP;
629 }
630
631 static void dp83826_of_init(struct phy_device *phydev)
632 {
633         struct dp83822_private *dp83822 = phydev->priv;
634         struct device *dev = &phydev->mdio.dev;
635         u32 val;
636
637         dp83822->cfg_dac_minus = DP83826_CFG_DAC_MINUS_DEFAULT;
638         if (!device_property_read_u32(dev, "ti,cfg-dac-minus-one-bp", &val))
639                 dp83822->cfg_dac_minus += dp83826_to_dac_minus_one_regval(val);
640
641         dp83822->cfg_dac_plus = DP83826_CFG_DAC_PLUS_DEFAULT;
642         if (!device_property_read_u32(dev, "ti,cfg-dac-plus-one-bp", &val))
643                 dp83822->cfg_dac_plus += dp83826_to_dac_plus_one_regval(val);
644 }
645 #else
646 static int dp83822_of_init(struct phy_device *phydev)
647 {
648         return 0;
649 }
650
651 static void dp83826_of_init(struct phy_device *phydev)
652 {
653 }
654 #endif /* CONFIG_OF_MDIO */
655
656 static int dp83822_read_straps(struct phy_device *phydev)
657 {
658         struct dp83822_private *dp83822 = phydev->priv;
659         int fx_enabled, fx_sd_enable;
660         int val;
661
662         val = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_SOR1);
663         if (val < 0)
664                 return val;
665
666         phydev_dbg(phydev, "SOR1 strap register: 0x%04x\n", val);
667
668         fx_enabled = (val & DP83822_COL_STRAP_MASK) >> DP83822_COL_SHIFT;
669         if (fx_enabled == DP83822_STRAP_MODE2 ||
670             fx_enabled == DP83822_STRAP_MODE3)
671                 dp83822->fx_enabled = 1;
672
673         if (dp83822->fx_enabled) {
674                 fx_sd_enable = (val & DP83822_RX_ER_STR_MASK) >> DP83822_RX_ER_SHIFT;
675                 if (fx_sd_enable == DP83822_STRAP_MODE3 ||
676                     fx_sd_enable == DP83822_STRAP_MODE4)
677                         dp83822->fx_sd_enable = 1;
678         }
679
680         return 0;
681 }
682
683 static int dp83822_probe(struct phy_device *phydev)
684 {
685         struct dp83822_private *dp83822;
686         int ret;
687
688         dp83822 = devm_kzalloc(&phydev->mdio.dev, sizeof(*dp83822),
689                                GFP_KERNEL);
690         if (!dp83822)
691                 return -ENOMEM;
692
693         phydev->priv = dp83822;
694
695         ret = dp83822_read_straps(phydev);
696         if (ret)
697                 return ret;
698
699         dp83822_of_init(phydev);
700
701         if (dp83822->fx_enabled)
702                 phydev->port = PORT_FIBRE;
703
704         return 0;
705 }
706
707 static int dp83826_probe(struct phy_device *phydev)
708 {
709         struct dp83822_private *dp83822;
710
711         dp83822 = devm_kzalloc(&phydev->mdio.dev, sizeof(*dp83822),
712                                GFP_KERNEL);
713         if (!dp83822)
714                 return -ENOMEM;
715
716         phydev->priv = dp83822;
717
718         dp83826_of_init(phydev);
719
720         return 0;
721 }
722
723 static int dp83822_suspend(struct phy_device *phydev)
724 {
725         int value;
726
727         value = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG);
728
729         if (!(value & DP83822_WOL_EN))
730                 genphy_suspend(phydev);
731
732         return 0;
733 }
734
735 static int dp83822_resume(struct phy_device *phydev)
736 {
737         int value;
738
739         genphy_resume(phydev);
740
741         value = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG);
742
743         phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG, value |
744                       DP83822_WOL_CLR_INDICATION);
745
746         return 0;
747 }
748
749 #define DP83822_PHY_DRIVER(_id, _name)                          \
750         {                                                       \
751                 PHY_ID_MATCH_MODEL(_id),                        \
752                 .name           = (_name),                      \
753                 /* PHY_BASIC_FEATURES */                        \
754                 .probe          = dp83822_probe,                \
755                 .soft_reset     = dp83822_phy_reset,            \
756                 .config_init    = dp83822_config_init,          \
757                 .read_status    = dp83822_read_status,          \
758                 .get_wol = dp83822_get_wol,                     \
759                 .set_wol = dp83822_set_wol,                     \
760                 .config_intr = dp83822_config_intr,             \
761                 .handle_interrupt = dp83822_handle_interrupt,   \
762                 .suspend = dp83822_suspend,                     \
763                 .resume = dp83822_resume,                       \
764         }
765
766 #define DP83826_PHY_DRIVER(_id, _name)                          \
767         {                                                       \
768                 PHY_ID_MATCH_MODEL(_id),                        \
769                 .name           = (_name),                      \
770                 /* PHY_BASIC_FEATURES */                        \
771                 .probe          = dp83826_probe,                \
772                 .soft_reset     = dp83822_phy_reset,            \
773                 .config_init    = dp83826_config_init,          \
774                 .get_wol = dp83822_get_wol,                     \
775                 .set_wol = dp83822_set_wol,                     \
776                 .config_intr = dp83822_config_intr,             \
777                 .handle_interrupt = dp83822_handle_interrupt,   \
778                 .suspend = dp83822_suspend,                     \
779                 .resume = dp83822_resume,                       \
780         }
781
782 #define DP8382X_PHY_DRIVER(_id, _name)                          \
783         {                                                       \
784                 PHY_ID_MATCH_MODEL(_id),                        \
785                 .name           = (_name),                      \
786                 /* PHY_BASIC_FEATURES */                        \
787                 .soft_reset     = dp83822_phy_reset,            \
788                 .config_init    = dp8382x_config_init,          \
789                 .get_wol = dp83822_get_wol,                     \
790                 .set_wol = dp83822_set_wol,                     \
791                 .config_intr = dp83822_config_intr,             \
792                 .handle_interrupt = dp83822_handle_interrupt,   \
793                 .suspend = dp83822_suspend,                     \
794                 .resume = dp83822_resume,                       \
795         }
796
797 static struct phy_driver dp83822_driver[] = {
798         DP83822_PHY_DRIVER(DP83822_PHY_ID, "TI DP83822"),
799         DP8382X_PHY_DRIVER(DP83825I_PHY_ID, "TI DP83825I"),
800         DP83826_PHY_DRIVER(DP83826C_PHY_ID, "TI DP83826C"),
801         DP83826_PHY_DRIVER(DP83826NC_PHY_ID, "TI DP83826NC"),
802         DP8382X_PHY_DRIVER(DP83825S_PHY_ID, "TI DP83825S"),
803         DP8382X_PHY_DRIVER(DP83825CM_PHY_ID, "TI DP83825M"),
804         DP8382X_PHY_DRIVER(DP83825CS_PHY_ID, "TI DP83825CS"),
805 };
806 module_phy_driver(dp83822_driver);
807
808 static struct mdio_device_id __maybe_unused dp83822_tbl[] = {
809         { DP83822_PHY_ID, 0xfffffff0 },
810         { DP83825I_PHY_ID, 0xfffffff0 },
811         { DP83826C_PHY_ID, 0xfffffff0 },
812         { DP83826NC_PHY_ID, 0xfffffff0 },
813         { DP83825S_PHY_ID, 0xfffffff0 },
814         { DP83825CM_PHY_ID, 0xfffffff0 },
815         { DP83825CS_PHY_ID, 0xfffffff0 },
816         { },
817 };
818 MODULE_DEVICE_TABLE(mdio, dp83822_tbl);
819
820 MODULE_DESCRIPTION("Texas Instruments DP83822 PHY driver");
821 MODULE_AUTHOR("Dan Murphy <[email protected]");
822 MODULE_LICENSE("GPL v2");
This page took 0.077858 seconds and 4 git commands to generate.