1 // SPDX-License-Identifier: GPL-2.0+
3 * Driver for ICPlus PHYs
5 * Copyright (c) 2007 Freescale Semiconductor, Inc.
7 #include <linux/kernel.h>
8 #include <linux/string.h>
9 #include <linux/errno.h>
10 #include <linux/unistd.h>
11 #include <linux/interrupt.h>
12 #include <linux/init.h>
13 #include <linux/delay.h>
14 #include <linux/netdevice.h>
15 #include <linux/etherdevice.h>
16 #include <linux/skbuff.h>
17 #include <linux/spinlock.h>
19 #include <linux/module.h>
20 #include <linux/mii.h>
21 #include <linux/ethtool.h>
22 #include <linux/phy.h>
23 #include <linux/property.h>
27 #include <linux/uaccess.h>
29 MODULE_DESCRIPTION("ICPlus IP175C/IP101A/IP101G/IC1001 PHY drivers");
30 MODULE_AUTHOR("Michael Barkowski");
31 MODULE_LICENSE("GPL");
33 /* IP101A/G - IP1001 */
34 #define IP10XX_SPEC_CTRL_STATUS 16 /* Spec. Control Register */
35 #define IP1001_RXPHASE_SEL BIT(0) /* Add delay on RX_CLK */
36 #define IP1001_TXPHASE_SEL BIT(1) /* Add delay on TX_CLK */
37 #define IP1001_SPEC_CTRL_STATUS_2 20 /* IP1001 Spec. Control Reg 2 */
38 #define IP1001_APS_ON 11 /* IP1001 APS Mode bit */
39 #define IP101A_G_APS_ON BIT(1) /* IP101A/G APS Mode bit */
40 #define IP101A_G_IRQ_CONF_STATUS 0x11 /* Conf Info IRQ & Status Reg */
41 #define IP101A_G_IRQ_PIN_USED BIT(15) /* INTR pin used */
42 #define IP101A_G_IRQ_ALL_MASK BIT(11) /* IRQ's inactive */
43 #define IP101A_G_IRQ_SPEED_CHANGE BIT(2)
44 #define IP101A_G_IRQ_DUPLEX_CHANGE BIT(1)
45 #define IP101A_G_IRQ_LINK_CHANGE BIT(0)
47 #define IP101G_PAGE_CONTROL 0x14
48 #define IP101G_PAGE_CONTROL_MASK GENMASK(4, 0)
49 #define IP101G_DIGITAL_IO_SPEC_CTRL 0x1d
50 #define IP101G_DIGITAL_IO_SPEC_CTRL_SEL_INTR32 BIT(2)
52 #define IP175C_PHY_ID 0x02430d80
53 #define IP1001_PHY_ID 0x02430d90
54 #define IP101A_PHY_ID 0x02430c54
56 /* The 32-pin IP101GR package can re-configure the mode of the RXER/INTR_32 pin
57 * (pin number 21). The hardware default is RXER (receive error) mode. But it
58 * can be configured to interrupt mode manually.
60 enum ip101gr_sel_intr32 {
61 IP101GR_SEL_INTR32_KEEP,
62 IP101GR_SEL_INTR32_INTR,
63 IP101GR_SEL_INTR32_RXER,
66 struct ip101a_g_phy_priv {
67 enum ip101gr_sel_intr32 sel_intr32;
70 static int ip175c_config_init(struct phy_device *phydev)
73 static int full_reset_performed;
75 if (full_reset_performed == 0) {
78 err = mdiobus_write(phydev->mdio.bus, 30, 0, 0x175c);
82 /* ensure no bus delays overlap reset period */
83 err = mdiobus_read(phydev->mdio.bus, 30, 0);
85 /* data sheet specifies reset period is 2 msec */
88 /* enable IP175C mode */
89 err = mdiobus_write(phydev->mdio.bus, 29, 31, 0x175c);
93 /* Set MII0 speed and duplex (in PHY mode) */
94 err = mdiobus_write(phydev->mdio.bus, 29, 22, 0x420);
98 /* reset switch ports */
99 for (i = 0; i < 5; i++) {
100 err = mdiobus_write(phydev->mdio.bus, i,
101 MII_BMCR, BMCR_RESET);
106 for (i = 0; i < 5; i++)
107 err = mdiobus_read(phydev->mdio.bus, i, MII_BMCR);
111 full_reset_performed = 1;
114 if (phydev->mdio.addr != 4) {
115 phydev->state = PHY_RUNNING;
116 phydev->speed = SPEED_100;
117 phydev->duplex = DUPLEX_FULL;
119 netif_carrier_on(phydev->attached_dev);
125 static int ip1001_config_init(struct phy_device *phydev)
129 /* Enable Auto Power Saving mode */
130 c = phy_read(phydev, IP1001_SPEC_CTRL_STATUS_2);
134 c = phy_write(phydev, IP1001_SPEC_CTRL_STATUS_2, c);
138 if (phy_interface_is_rgmii(phydev)) {
140 c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS);
144 c &= ~(IP1001_RXPHASE_SEL | IP1001_TXPHASE_SEL);
146 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
147 c |= (IP1001_RXPHASE_SEL | IP1001_TXPHASE_SEL);
148 else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
149 c |= IP1001_RXPHASE_SEL;
150 else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
151 c |= IP1001_TXPHASE_SEL;
153 c = phy_write(phydev, IP10XX_SPEC_CTRL_STATUS, c);
161 static int ip175c_read_status(struct phy_device *phydev)
163 if (phydev->mdio.addr == 4) /* WAN port */
164 genphy_read_status(phydev);
166 /* Don't need to read status for switch ports */
167 phydev->irq = PHY_IGNORE_INTERRUPT;
172 static int ip175c_config_aneg(struct phy_device *phydev)
174 if (phydev->mdio.addr == 4) /* WAN port */
175 genphy_config_aneg(phydev);
180 static int ip101a_g_probe(struct phy_device *phydev)
182 struct device *dev = &phydev->mdio.dev;
183 struct ip101a_g_phy_priv *priv;
185 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
189 /* Both functions (RX error and interrupt status) are sharing the same
190 * pin on the 32-pin IP101GR, so this is an exclusive choice.
192 if (device_property_read_bool(dev, "icplus,select-rx-error") &&
193 device_property_read_bool(dev, "icplus,select-interrupt")) {
195 "RXER and INTR mode cannot be selected together\n");
199 if (device_property_read_bool(dev, "icplus,select-rx-error"))
200 priv->sel_intr32 = IP101GR_SEL_INTR32_RXER;
201 else if (device_property_read_bool(dev, "icplus,select-interrupt"))
202 priv->sel_intr32 = IP101GR_SEL_INTR32_INTR;
204 priv->sel_intr32 = IP101GR_SEL_INTR32_KEEP;
211 static int ip101a_g_config_intr_pin(struct phy_device *phydev)
213 struct ip101a_g_phy_priv *priv = phydev->priv;
216 /* configure the RXER/INTR_32 pin of the 32-pin IP101GR if needed: */
217 switch (priv->sel_intr32) {
218 case IP101GR_SEL_INTR32_RXER:
219 err = phy_modify(phydev, IP101G_DIGITAL_IO_SPEC_CTRL,
220 IP101G_DIGITAL_IO_SPEC_CTRL_SEL_INTR32, 0);
225 case IP101GR_SEL_INTR32_INTR:
226 err = phy_modify(phydev, IP101G_DIGITAL_IO_SPEC_CTRL,
227 IP101G_DIGITAL_IO_SPEC_CTRL_SEL_INTR32,
228 IP101G_DIGITAL_IO_SPEC_CTRL_SEL_INTR32);
234 /* Don't touch IP101G_DIGITAL_IO_SPEC_CTRL because it's not
235 * documented on IP101A and it's not clear whether this would
237 * For the 32-pin IP101GR we simply keep the SEL_INTR32
238 * configuration as set by the bootloader when not configured
239 * to one of the special functions.
247 static int ip101a_config_init(struct phy_device *phydev)
251 /* Enable Auto Power Saving mode */
252 ret = phy_set_bits(phydev, IP10XX_SPEC_CTRL_STATUS, IP101A_G_APS_ON);
256 return ip101a_g_config_intr_pin(phydev);
259 static int ip101g_config_init(struct phy_device *phydev)
261 return ip101a_g_config_intr_pin(phydev);
264 static int ip101a_g_ack_interrupt(struct phy_device *phydev)
266 int err = phy_read(phydev, IP101A_G_IRQ_CONF_STATUS);
274 static int ip101a_g_config_intr(struct phy_device *phydev)
279 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
280 err = ip101a_g_ack_interrupt(phydev);
284 /* INTR pin used: Speed/link/duplex will cause an interrupt */
285 val = IP101A_G_IRQ_PIN_USED;
286 err = phy_write(phydev, IP101A_G_IRQ_CONF_STATUS, val);
288 val = IP101A_G_IRQ_ALL_MASK;
289 err = phy_write(phydev, IP101A_G_IRQ_CONF_STATUS, val);
293 err = ip101a_g_ack_interrupt(phydev);
299 static irqreturn_t ip101a_g_handle_interrupt(struct phy_device *phydev)
303 irq_status = phy_read(phydev, IP101A_G_IRQ_CONF_STATUS);
304 if (irq_status < 0) {
309 if (!(irq_status & (IP101A_G_IRQ_SPEED_CHANGE |
310 IP101A_G_IRQ_DUPLEX_CHANGE |
311 IP101A_G_IRQ_LINK_CHANGE)))
314 phy_trigger_machine(phydev);
319 static int ip101a_g_has_page_register(struct phy_device *phydev)
321 int oldval, val, ret;
323 oldval = phy_read(phydev, IP101G_PAGE_CONTROL);
327 ret = phy_write(phydev, IP101G_PAGE_CONTROL, 0xffff);
331 val = phy_read(phydev, IP101G_PAGE_CONTROL);
335 ret = phy_write(phydev, IP101G_PAGE_CONTROL, oldval);
339 return val == IP101G_PAGE_CONTROL_MASK;
342 static int ip101a_g_match_phy_device(struct phy_device *phydev, bool ip101a)
346 if (phydev->phy_id != IP101A_PHY_ID)
349 /* The IP101A and the IP101G share the same PHY identifier.The IP101G
350 * seems to be a successor of the IP101A and implements more functions.
351 * Amongst other things there is a page select register, which is not
352 * available on the IP101A. Use this to distinguish these two.
354 ret = ip101a_g_has_page_register(phydev);
358 return ip101a == !ret;
361 static int ip101a_match_phy_device(struct phy_device *phydev)
363 return ip101a_g_match_phy_device(phydev, true);
366 static int ip101g_match_phy_device(struct phy_device *phydev)
368 return ip101a_g_match_phy_device(phydev, false);
371 static struct phy_driver icplus_driver[] = {
373 PHY_ID_MATCH_MODEL(IP175C_PHY_ID),
374 .name = "ICPlus IP175C",
375 /* PHY_BASIC_FEATURES */
376 .config_init = ip175c_config_init,
377 .config_aneg = ip175c_config_aneg,
378 .read_status = ip175c_read_status,
379 .suspend = genphy_suspend,
380 .resume = genphy_resume,
382 PHY_ID_MATCH_MODEL(IP1001_PHY_ID),
383 .name = "ICPlus IP1001",
384 /* PHY_GBIT_FEATURES */
385 .config_init = ip1001_config_init,
386 .soft_reset = genphy_soft_reset,
387 .suspend = genphy_suspend,
388 .resume = genphy_resume,
390 .name = "ICPlus IP101A",
391 .match_phy_device = ip101a_match_phy_device,
392 .probe = ip101a_g_probe,
393 .config_intr = ip101a_g_config_intr,
394 .handle_interrupt = ip101a_g_handle_interrupt,
395 .config_init = ip101a_config_init,
396 .soft_reset = genphy_soft_reset,
397 .suspend = genphy_suspend,
398 .resume = genphy_resume,
400 .name = "ICPlus IP101G",
401 .match_phy_device = ip101g_match_phy_device,
402 .probe = ip101a_g_probe,
403 .config_intr = ip101a_g_config_intr,
404 .handle_interrupt = ip101a_g_handle_interrupt,
405 .config_init = ip101g_config_init,
406 .soft_reset = genphy_soft_reset,
407 .suspend = genphy_suspend,
408 .resume = genphy_resume,
411 module_phy_driver(icplus_driver);
413 static struct mdio_device_id __maybe_unused icplus_tbl[] = {
414 { PHY_ID_MATCH_MODEL(IP175C_PHY_ID) },
415 { PHY_ID_MATCH_MODEL(IP1001_PHY_ID) },
416 { PHY_ID_MATCH_EXACT(IP101A_PHY_ID) },
420 MODULE_DEVICE_TABLE(mdio, icplus_tbl);