]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - ti-analog-linux-kernel/analog-linux.git/blob - drivers/net/phy/dp83tc812.c
net: phy: dp83tc812: Add support for dp83tc812 phy
[ti-analog-linux-kernel/analog-linux.git] / drivers / net / phy / dp83tc812.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Driver for the Texas Instruments DP83TC812 PHY
4  *
5  * Copyright (C) 2021 Texas Instruments Incorporated - http://www.ti.com/
6  *
7  */
9 #include <linux/ethtool.h>
10 #include <linux/etherdevice.h>
11 #include <linux/kernel.h>
12 #include <linux/mii.h>
13 #include <linux/module.h>
14 #include <linux/of.h>
15 #include <linux/phy.h>
16 #include <linux/netdevice.h>
18 #define DP83TC812_CS1_0_PHY_ID  0x2000a270
19 #define DP83TC812_CS2_0_PHY_ID  0x2000a271
20 #define DP83TC813_CS2_0_PHY_ID  0x2000a211
21 #define DP83TC814_CS2_0_PHY_ID  0x2000a261
23 #define DP83812_DEVADDR         0x1f
24 #define DP83812_DEVADDR_MMD1    0x1
26 #define DP83812_STRAP           0x45d
27 #define MII_DP83812_SGMII_CTRL  0x608
28 #define MII_DP83812_RGMII_CTRL  0x600
29 #define MII_DP83812_INT_STAT1   0x12
30 #define MII_DP83812_INT_STAT2   0x13
31 #define MII_DP83812_INT_STAT3   0x18
32 #define MII_DP83812_RESET_CTRL  0x1f
34 #define DP83812_HW_RESET        BIT(15)
35 #define DP83812_SW_RESET        BIT(14)
37 /* INT_STAT1 bits */
38 #define DP83812_RX_ERR_CNT_HALF_FULL_INT_EN     BIT(0)
39 #define DP83812_TX_ERR_CNT_HALF_FULL_INT_EN     BIT(1)
40 #define DP83812_MS_TRAIN_DONE_INT_EN            BIT(2)
41 #define DP83812_ESD_EVENT_INT_EN                BIT(3)
42 #define DP83812_LINK_STAT_INT_EN                BIT(5)
43 #define DP83812_ENERGY_DET_INT_EN               BIT(6)
44 #define DP83812_LINK_QUAL_INT_EN                BIT(7)
46 /* INT_STAT2 bits */
47 #define DP83812_JABBER_INT_EN           BIT(0)
48 #define DP83812_POL_INT_EN              BIT(1)
49 #define DP83812_SLEEP_MODE_INT_EN       BIT(2)
50 #define DP83812_OVERTEMP_INT_EN         BIT(3)
51 #define DP83812_FIFO_INT_EN             BIT(4)
52 #define DP83812_PAGE_RXD_INT_EN         BIT(5)
53 #define DP83812_OVERVOLTAGE_INT_EN      BIT(6)
54 #define DP83812_UNDERVOLTAGE_INT_EN     BIT(7)
56 /* INT_STAT3 bits */
57 #define DP83812_LPS_INT_EN              BIT(0)
58 #define DP83812_WUP_INT_EN              BIT(1)
59 #define DP83812_WAKE_REQ_INT_EN         BIT(2)
60 #define DP83811_NO_FRAME_INT_EN         BIT(3)
61 #define DP83811_POR_DONE_INT_EN         BIT(4)
62 #define DP83812_SLEEP_FAIL_INT_EN       BIT(5)
64 /* RGMII_CTRL bits */
65 #define DP83812_RGMII_EN                BIT(3)
67 /* SGMII CTRL bits */
68 #define DP83812_SGMII_AUTO_NEG_EN       BIT(0)
69 #define DP83812_SGMII_EN                BIT(9)
71 /* Strap bits */
72 #define DP83812_MASTER_MODE     BIT(9)
73 #define DP83812_RGMII_IS_EN     BIT(7)
75 enum dp83812_chip_type {
76         DP83812_CS1 = 0,
77         DP83812_CS2,
78         DP83813_CS2,
79         DP83814_CS2,
80 };
82 struct dp83812_init_reg {
83         int     reg;
84         int     val;
85 };
87 static const struct dp83812_init_reg dp83812_master_cs1_0_init[] = {
88         {0x523, 0x0001},
89         {0x800, 0xf864},
90         {0x803, 0x1552},
91         {0x804, 0x1a66},
92         {0x805, 0x1f7b},
93         {0x81f, 0x2a88},
94         {0x825, 0x40e5},
95         {0x82b, 0x7f3f},
96         {0x830, 0x0543},
97         {0x836, 0x5008},
98         {0x83a, 0x08e0},
99         {0x83b, 0x0845},
100         {0x83e, 0x0445},
101         {0x855, 0x9b9a},
102         {0x85f, 0x2010},
103         {0x860, 0x6040},
104         {0x86c, 0x1333},
105         {0x86b, 0x3e10},
106         {0x872, 0x88c0},
107         {0x873, 0x0003},
108         {0x879, 0x000f},
109         {0x87b, 0x0070},
110         {0x87c, 0x003f},
111         {0x89e, 0x00aa},
112         {0x523, 0x0000},
113 };
115 static const struct dp83812_init_reg dp83812_master_cs2_0_init[] = {
116         {0x523, 0x0001},
117         {0x81C, 0x0fe2},
118         {0x872, 0x0300},
119         {0x879, 0x0f00},
120         {0x806, 0x2952},
121         {0x807, 0x3361},
122         {0x808, 0x3D7B},
123         {0x83E, 0x045F},
124         {0x834, 0x8000},
125         {0x862, 0x00E8},
126         {0x896, 0x32CB},
127         {0x03E, 0x0009},
128         {0x01f, 0x4000},
129         {0x523, 0x0000},
130 };
132 static const struct dp83812_init_reg dp83812_slave_cs1_0_init[] = {
133         {0x523, 0x0001},
134         {0x803, 0x1b52},
135         {0x804, 0x216c},
136         {0x805, 0x277b},
137         {0x827, 0x3000},
138         {0x830, 0x0543},
139         {0x83a, 0x0020},
140         {0x83c, 0x0001},
141         {0x855, 0x9b9a},
142         {0x85f, 0x2010},
143         {0x860, 0x6040},
144         {0x86c, 0x0333},
145         {0x872, 0x88c0},
146         {0x873, 0x0021},
147         {0x879, 0x000f},
148         {0x87b, 0x0070},
149         {0x87c, 0x0002},
150         {0x897, 0x003f},
151         {0x89e, 0x00a2},
152         {0x510, 0x000f},
153         {0x523, 0x0000},
154 };
156 static const struct dp83812_init_reg dp83812_slave_cs2_0_init[] = {
157         {0x523, 0x0001},
158         {0x873, 0x0821},
159         {0x896, 0x22ff},
160         {0x89E, 0x0000},
161         {0x01f, 0x4000},
162         {0x523, 0x0000},
163 };
165 struct dp83812_private {
166         int chip;
167         bool is_master;
168         bool is_rgmii;
169         bool is_sgmii;
170 };
172 static int dp83812_read_straps(struct phy_device *phydev)
174         struct dp83812_private *dp83812 = phydev->priv;
175         int strap;
177         strap = phy_read_mmd(phydev, DP83812_DEVADDR, DP83812_STRAP);
178         if (strap < 0)
179                 return strap;
181         printk("%s: Strap is 0x%X\n", __func__, strap);
182         if (strap & DP83812_MASTER_MODE)
183                 dp83812->is_master = true;
185         if (strap & DP83812_RGMII_IS_EN)
186                 dp83812->is_rgmii = true;
187         return 0;
188 };
190 static int dp83812_reset(struct phy_device *phydev, bool hw_reset)
192         int ret;
194         if (hw_reset)
195                 ret = phy_write(phydev, MII_DP83812_RESET_CTRL,
196                                 DP83812_HW_RESET);
197         else
198                 ret = phy_write(phydev, MII_DP83812_RESET_CTRL,
199                                 DP83812_SW_RESET);
201         if (ret)
202                 return ret;
204         mdelay(100);
206         return 0;
209 static int dp83812_phy_reset(struct phy_device *phydev)
211         int err;
212         int ret;
214         err = phy_write(phydev, MII_DP83812_RESET_CTRL, DP83812_HW_RESET);
215         if (err < 0)
216                 return err;
218         ret = dp83812_read_straps(phydev);
219         if (ret)
220                 return ret;
222         return 0;
225 static int dp83812_write_seq(struct phy_device *phydev, const struct
226                                 dp83812_init_reg *init_data, int size)
228         int ret;
229         int i;
231         for (i = 0; i < size; i++) {
232                 ret = phy_write_mmd(phydev, DP83812_DEVADDR, init_data[i].reg,
233                                         init_data[i].val);
234         if (ret)
235                 return ret;
236         }
237         return 0;
240 static int dp83812_chip_init(struct phy_device *phydev)
242         struct dp83812_private *dp83812 = phydev->priv;
243         int ret;
245         ret = dp83812_reset(phydev, true);
246         if (ret)
247                 return ret;
249         if (dp83812->is_master)
250                 ret = phy_write_mmd(phydev, DP83812_DEVADDR_MMD1, 0x0834, 0xc001);
251                 // ret = phy_write_mmd(phydev, DP83812_DEVADDR, 0x0834, 0xc001);
252         else
253                 ret = phy_write_mmd(phydev, DP83812_DEVADDR_MMD1, 0x0834, 0x8001);
254                 // ret = phy_write_mmd(phydev, DP83812_DEVADDR, 0x0834, 0x8001);
256         switch (dp83812->chip) {
257         case DP83812_CS1:
258                 if (dp83812->is_master)
259                         ret = dp83812_write_seq(phydev,
260                                                 dp83812_master_cs1_0_init,
261                                                 ARRAY_SIZE(dp83812_master_cs1_0_init));
262                 else
263                         ret = dp83812_write_seq(phydev,
264                                                 dp83812_slave_cs1_0_init,
265                                                 ARRAY_SIZE(dp83812_slave_cs1_0_init));
266         break;
267         case DP83812_CS2:
268                 if (dp83812->is_master)
269                         ret = dp83812_write_seq(phydev,
270                                                 dp83812_master_cs2_0_init,
271                                                 ARRAY_SIZE(dp83812_master_cs2_0_init));
272                 else
273                         ret = dp83812_write_seq(phydev,
274                                                 dp83812_slave_cs2_0_init,
275                                                 ARRAY_SIZE(dp83812_slave_cs2_0_init));
276         break;
277         case DP83813_CS2:
278                 if (dp83812->is_master)
279                         ret = dp83812_write_seq(phydev,
280                                                 dp83812_master_cs2_0_init,
281                                                 ARRAY_SIZE(dp83812_master_cs2_0_init));
282                 else
283                         ret = dp83812_write_seq(phydev,
284                                                 dp83812_slave_cs2_0_init,
285                                                 ARRAY_SIZE(dp83812_slave_cs2_0_init));
286         break;
287         case DP83814_CS2:
288                 if (dp83812->is_master)
289                         ret = dp83812_write_seq(phydev,
290                                                 dp83812_master_cs2_0_init,
291                                                 ARRAY_SIZE(dp83812_master_cs2_0_init));
292                 else
293                         ret = dp83812_write_seq(phydev,
294                                                 dp83812_slave_cs2_0_init,
295                                                 ARRAY_SIZE(dp83812_slave_cs2_0_init));
296         break;
297         default:
298                 return -EINVAL;
299         };
301         if (ret)
302                 return ret;
304         mdelay(10);
305         // phy_write_mmd(phydev, DP83812_DEVADDR, 0x523, 0x00);
306         /* Do a soft reset to restart the PHY with updated values */
307         return dp83812_reset(phydev, false);
310 static int dp83812_config_init(struct phy_device *phydev)
312         int value, err;
314         err = dp83812_chip_init(phydev);
315         if (err)
316                 return err;
318         value = phy_read_mmd(phydev, DP83812_DEVADDR, MII_DP83812_SGMII_CTRL);
319         if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
320                 err = phy_write_mmd(phydev, DP83812_DEVADDR, MII_DP83812_SGMII_CTRL,
321                                         (DP83812_SGMII_EN | value));
322         } else {
323                 err = phy_write_mmd(phydev, DP83812_DEVADDR, MII_DP83812_SGMII_CTRL,
324                                         (~DP83812_SGMII_EN & value));
325         }
327         if (err < 0)
329                 return err;
331         return 0;
334 static int dp83812_ack_interrupt(struct phy_device *phydev)
336         int err;
338         err = phy_read(phydev, MII_DP83812_INT_STAT1);
339         if (err < 0)
340                 return err;
342         err = phy_read(phydev, MII_DP83812_INT_STAT2);
343         if (err < 0)
344                 return err;
346         err = phy_read(phydev, MII_DP83812_INT_STAT3);
347         if (err < 0)
348                 return err;
350         return 0;
353 static int dp83812_config_intr(struct phy_device *phydev)
355         int misr_status, err;
357         if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
358                 misr_status = phy_read(phydev, MII_DP83812_INT_STAT1);
359                 if (misr_status < 0)
360                         return misr_status;
362                 misr_status |= (DP83812_ESD_EVENT_INT_EN |
363                                 DP83812_LINK_STAT_INT_EN |
364                                 DP83812_ENERGY_DET_INT_EN |
365                                 DP83812_LINK_QUAL_INT_EN);
367                 err = phy_write(phydev, MII_DP83812_INT_STAT1, misr_status);
368                 if (err < 0)
369                         return err;
371                 misr_status = phy_read(phydev, MII_DP83812_INT_STAT2);
372                 if (misr_status < 0)
373                         return misr_status;
375                 misr_status |= (DP83812_SLEEP_MODE_INT_EN |
376                                 DP83812_OVERTEMP_INT_EN |
377                                 DP83812_OVERVOLTAGE_INT_EN |
378                                 DP83812_UNDERVOLTAGE_INT_EN);
380                 err = phy_write(phydev, MII_DP83812_INT_STAT2, misr_status);
381                 if (err < 0)
382                         return err;
384                 misr_status = phy_read(phydev, MII_DP83812_INT_STAT3);
385                 if (misr_status < 0)
386                         return misr_status;
388                 misr_status |= (DP83812_LPS_INT_EN |
389                                 DP83812_WAKE_REQ_INT_EN |
390                                 DP83811_NO_FRAME_INT_EN |
391                                 DP83811_POR_DONE_INT_EN);
393                 err = phy_write(phydev, MII_DP83812_INT_STAT3, misr_status);
395         } else {
396                 err = phy_write(phydev, MII_DP83812_INT_STAT1, 0);
397                 if (err < 0)
398                         return err;
400                 err = phy_write(phydev, MII_DP83812_INT_STAT2, 0);
401                 if (err < 0)
402                         return err;
404                 err = phy_write(phydev, MII_DP83812_INT_STAT3, 0);
405         }
407         return err;
410 #if 0
411 static irqreturn_t dp83812_handle_interrupt(struct phy_device *phydev)
413         bool trigger_machine = false;
414         int irq_status;
416         /* The INT_STAT registers 1, 2 and 3 are holding the interrupt status
417          * in the upper half (15:8), while the lower half (7:0) is used for
418          * controlling the interrupt enable state of those individual interrupt
419          * sources. To determine the possible interrupt sources, just read the
420          * INT_STAT* register and use it directly to know which interrupts have
421          * been enabled previously or not.
422          */
423         irq_status = phy_read(phydev, MII_DP83812_INT_STAT1);
424         if (irq_status < 0) {
425                 phy_error(phydev);
426                 return IRQ_NONE;
427         }
428         if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
429                 trigger_machine = true;
431         irq_status = phy_read(phydev, MII_DP83812_INT_STAT2);
432         if (irq_status < 0) {
433                 phy_error(phydev);
434                 return IRQ_NONE;
435         }
436         if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
437                 trigger_machine = true;
439         irq_status = phy_read(phydev, MII_DP83812_INT_STAT3);
440         if (irq_status < 0) {
441                 phy_error(phydev);
442                 return IRQ_NONE;
443         }
444         if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
445                 trigger_machine = true;
447         if (!trigger_machine)
448                 return IRQ_NONE;
450         phy_trigger_machine(phydev);
452         return IRQ_HANDLED;
454 #endif
456 static int dp83812_config_aneg(struct phy_device *phydev)
458         int value, err;
460         if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
461                 value = phy_read_mmd(phydev, DP83812_DEVADDR, MII_DP83812_SGMII_CTRL);
462                 if (phydev->autoneg == AUTONEG_ENABLE) {
463                         err = phy_write_mmd(phydev, DP83812_DEVADDR,
464                                             MII_DP83812_SGMII_CTRL,
465                                         (DP83812_SGMII_AUTO_NEG_EN | value));
466                         if (err < 0)
467                                 return err;
468                 } else {
469                         err = phy_write_mmd(phydev, DP83812_DEVADDR,
470                                             MII_DP83812_SGMII_CTRL,
471                                         (~DP83812_SGMII_AUTO_NEG_EN & value));
472                         if (err < 0)
473                                 return err;
474                 }
475         }
476         return genphy_config_aneg(phydev);
481 static int dp83812_probe(struct phy_device *phydev)
483         struct dp83812_private *dp83812;
484         int ret;
486         dp83812 = devm_kzalloc(&phydev->mdio.dev, sizeof(*dp83812), GFP_KERNEL);
487         if (!dp83812)
488                 return -ENOMEM;
490         ret = dp83812_read_straps(phydev);
491         if (ret)
492                 return ret;
494         switch (phydev->phy_id) {
495         case DP83TC812_CS1_0_PHY_ID:
496                 dp83812->chip = DP83812_CS1;
497         break;
498         case DP83TC812_CS2_0_PHY_ID:
499                 dp83812->chip = DP83812_CS2;
500         break;
501         case DP83TC813_CS2_0_PHY_ID:
502                 dp83812->chip = DP83813_CS2;
503                 break;
504         case DP83TC814_CS2_0_PHY_ID:
505                 dp83812->chip = DP83814_CS2;
506         break;
507         default:
508         return -EINVAL;
509         };
510 /* vikram : above code added to switch between different phy ids */
512         return dp83812_config_init(phydev);
515 #define DP83812_PHY_DRIVER(_id, _name)                          \
516         {                                                       \
517                 PHY_ID_MATCH_EXACT(_id),                        \
518                 .name           = (_name),                      \
519                 .probe          = dp83812_probe,                \
520                 /* PHY_BASIC_FEATURES */                        \
521                 .soft_reset     = dp83812_phy_reset,            \
522                 .config_init    = dp83812_config_init,          \
523                 .config_aneg = dp83812_config_aneg,             \
524                 .ack_interrupt = dp83812_ack_interrupt,         \
525 /*if 0                                                          \
526                 .handle_interrupt = dp83812_handle_interrupt,   \
527 #endif  */                                                      \
528                 .config_intr = dp83812_config_intr,             \
529                 .suspend = genphy_suspend,                      \
530                 .resume = genphy_resume,                        \
531         }
533 static struct phy_driver dp83812_driver[] = {
534         DP83812_PHY_DRIVER(DP83TC812_CS1_0_PHY_ID, "TI DP83TC812CS1.0"),
535         DP83812_PHY_DRIVER(DP83TC812_CS2_0_PHY_ID, "TI DP83TC812CS2.0"),
536         DP83812_PHY_DRIVER(DP83TC813_CS2_0_PHY_ID, "TI DP83TC813CS2.0"),
537         DP83812_PHY_DRIVER(DP83TC814_CS2_0_PHY_ID, "TI DP83TC814CS2.0"),
538         };
540 module_phy_driver(dp83812_driver);
542 static struct mdio_device_id __maybe_unused dp83812_tbl[] = {
543         { PHY_ID_MATCH_EXACT(DP83TC812_CS1_0_PHY_ID) },
544         { PHY_ID_MATCH_EXACT(DP83TC812_CS2_0_PHY_ID) },
545         { PHY_ID_MATCH_EXACT(DP83TC813_CS2_0_PHY_ID) },
546         { PHY_ID_MATCH_EXACT(DP83TC814_CS2_0_PHY_ID) },
547         { },
548 };
550 MODULE_DESCRIPTION("Texas Instruments DP83TC812 PHY driver");
551 MODULE_AUTHOR("Hari Nagalla <hnagalla@ti.com");
552 MODULE_LICENSE("GPL");