xref: /openbmc/linux/drivers/net/phy/realtek.c (revision be709d48)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * drivers/net/phy/realtek.c
4  *
5  * Driver for Realtek PHYs
6  *
7  * Author: Johnson Leung <r58129@freescale.com>
8  *
9  * Copyright (c) 2004 Freescale Semiconductor, Inc.
10  */
11 #include <linux/bitops.h>
12 #include <linux/phy.h>
13 #include <linux/module.h>
14 
15 #define RTL821x_PHYSR				0x11
16 #define RTL821x_PHYSR_DUPLEX			BIT(13)
17 #define RTL821x_PHYSR_SPEED			GENMASK(15, 14)
18 
19 #define RTL821x_INER				0x12
20 #define RTL8211B_INER_INIT			0x6400
21 #define RTL8211E_INER_LINK_STATUS		BIT(10)
22 #define RTL8211F_INER_LINK_STATUS		BIT(4)
23 
24 #define RTL821x_INSR				0x13
25 
26 #define RTL821x_PAGE_SELECT			0x1f
27 
28 #define RTL8211F_INSR				0x1d
29 
30 #define RTL8211F_TX_DELAY			BIT(8)
31 
32 #define RTL8201F_ISR				0x1e
33 #define RTL8201F_IER				0x13
34 
35 #define RTL8366RB_POWER_SAVE			0x15
36 #define RTL8366RB_POWER_SAVE_ON			BIT(12)
37 
38 MODULE_DESCRIPTION("Realtek PHY driver");
39 MODULE_AUTHOR("Johnson Leung");
40 MODULE_LICENSE("GPL");
41 
42 static int rtl821x_read_page(struct phy_device *phydev)
43 {
44 	return __phy_read(phydev, RTL821x_PAGE_SELECT);
45 }
46 
47 static int rtl821x_write_page(struct phy_device *phydev, int page)
48 {
49 	return __phy_write(phydev, RTL821x_PAGE_SELECT, page);
50 }
51 
52 static int rtl8201_ack_interrupt(struct phy_device *phydev)
53 {
54 	int err;
55 
56 	err = phy_read(phydev, RTL8201F_ISR);
57 
58 	return (err < 0) ? err : 0;
59 }
60 
61 static int rtl821x_ack_interrupt(struct phy_device *phydev)
62 {
63 	int err;
64 
65 	err = phy_read(phydev, RTL821x_INSR);
66 
67 	return (err < 0) ? err : 0;
68 }
69 
70 static int rtl8211f_ack_interrupt(struct phy_device *phydev)
71 {
72 	int err;
73 
74 	err = phy_read_paged(phydev, 0xa43, RTL8211F_INSR);
75 
76 	return (err < 0) ? err : 0;
77 }
78 
79 static int rtl8201_config_intr(struct phy_device *phydev)
80 {
81 	u16 val;
82 
83 	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
84 		val = BIT(13) | BIT(12) | BIT(11);
85 	else
86 		val = 0;
87 
88 	return phy_write_paged(phydev, 0x7, RTL8201F_IER, val);
89 }
90 
91 static int rtl8211b_config_intr(struct phy_device *phydev)
92 {
93 	int err;
94 
95 	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
96 		err = phy_write(phydev, RTL821x_INER,
97 				RTL8211B_INER_INIT);
98 	else
99 		err = phy_write(phydev, RTL821x_INER, 0);
100 
101 	return err;
102 }
103 
104 static int rtl8211e_config_intr(struct phy_device *phydev)
105 {
106 	int err;
107 
108 	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
109 		err = phy_write(phydev, RTL821x_INER,
110 				RTL8211E_INER_LINK_STATUS);
111 	else
112 		err = phy_write(phydev, RTL821x_INER, 0);
113 
114 	return err;
115 }
116 
117 static int rtl8211f_config_intr(struct phy_device *phydev)
118 {
119 	u16 val;
120 
121 	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
122 		val = RTL8211F_INER_LINK_STATUS;
123 	else
124 		val = 0;
125 
126 	return phy_write_paged(phydev, 0xa42, RTL821x_INER, val);
127 }
128 
129 static int rtl8211_config_aneg(struct phy_device *phydev)
130 {
131 	int ret;
132 
133 	ret = genphy_config_aneg(phydev);
134 	if (ret < 0)
135 		return ret;
136 
137 	/* Quirk was copied from vendor driver. Unfortunately it includes no
138 	 * description of the magic numbers.
139 	 */
140 	if (phydev->speed == SPEED_100 && phydev->autoneg == AUTONEG_DISABLE) {
141 		phy_write(phydev, 0x17, 0x2138);
142 		phy_write(phydev, 0x0e, 0x0260);
143 	} else {
144 		phy_write(phydev, 0x17, 0x2108);
145 		phy_write(phydev, 0x0e, 0x0000);
146 	}
147 
148 	return 0;
149 }
150 
151 static int rtl8211c_config_init(struct phy_device *phydev)
152 {
153 	/* RTL8211C has an issue when operating in Gigabit slave mode */
154 	phy_set_bits(phydev, MII_CTRL1000,
155 		     CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER);
156 
157 	return genphy_config_init(phydev);
158 }
159 
160 static int rtl8211f_config_init(struct phy_device *phydev)
161 {
162 	int ret;
163 	u16 val = 0;
164 
165 	ret = genphy_config_init(phydev);
166 	if (ret < 0)
167 		return ret;
168 
169 	/* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */
170 	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
171 	    phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
172 		val = RTL8211F_TX_DELAY;
173 
174 	return phy_modify_paged(phydev, 0xd08, 0x11, RTL8211F_TX_DELAY, val);
175 }
176 
177 static int rtl8211b_suspend(struct phy_device *phydev)
178 {
179 	phy_write(phydev, MII_MMD_DATA, BIT(9));
180 
181 	return genphy_suspend(phydev);
182 }
183 
184 static int rtl8211b_resume(struct phy_device *phydev)
185 {
186 	phy_write(phydev, MII_MMD_DATA, 0);
187 
188 	return genphy_resume(phydev);
189 }
190 
191 static int rtl8366rb_config_init(struct phy_device *phydev)
192 {
193 	int ret;
194 
195 	ret = genphy_config_init(phydev);
196 	if (ret < 0)
197 		return ret;
198 
199 	ret = phy_set_bits(phydev, RTL8366RB_POWER_SAVE,
200 			   RTL8366RB_POWER_SAVE_ON);
201 	if (ret) {
202 		dev_err(&phydev->mdio.dev,
203 			"error enabling power management\n");
204 	}
205 
206 	return ret;
207 }
208 
209 static struct phy_driver realtek_drvs[] = {
210 	{
211 		PHY_ID_MATCH_EXACT(0x00008201),
212 		.name           = "RTL8201CP Ethernet",
213 		.features       = PHY_BASIC_FEATURES,
214 	}, {
215 		PHY_ID_MATCH_EXACT(0x001cc816),
216 		.name		= "RTL8201F Fast Ethernet",
217 		.features	= PHY_BASIC_FEATURES,
218 		.ack_interrupt	= &rtl8201_ack_interrupt,
219 		.config_intr	= &rtl8201_config_intr,
220 		.suspend	= genphy_suspend,
221 		.resume		= genphy_resume,
222 		.read_page	= rtl821x_read_page,
223 		.write_page	= rtl821x_write_page,
224 	}, {
225 		PHY_ID_MATCH_EXACT(0x001cc910),
226 		.name		= "RTL8211 Gigabit Ethernet",
227 		.features	= PHY_GBIT_FEATURES,
228 		.config_aneg	= rtl8211_config_aneg,
229 		.read_mmd	= &genphy_read_mmd_unsupported,
230 		.write_mmd	= &genphy_write_mmd_unsupported,
231 	}, {
232 		PHY_ID_MATCH_EXACT(0x001cc912),
233 		.name		= "RTL8211B Gigabit Ethernet",
234 		.features	= PHY_GBIT_FEATURES,
235 		.ack_interrupt	= &rtl821x_ack_interrupt,
236 		.config_intr	= &rtl8211b_config_intr,
237 		.read_mmd	= &genphy_read_mmd_unsupported,
238 		.write_mmd	= &genphy_write_mmd_unsupported,
239 		.suspend	= rtl8211b_suspend,
240 		.resume		= rtl8211b_resume,
241 	}, {
242 		PHY_ID_MATCH_EXACT(0x001cc913),
243 		.name		= "RTL8211C Gigabit Ethernet",
244 		.features	= PHY_GBIT_FEATURES,
245 		.config_init	= rtl8211c_config_init,
246 		.read_mmd	= &genphy_read_mmd_unsupported,
247 		.write_mmd	= &genphy_write_mmd_unsupported,
248 	}, {
249 		PHY_ID_MATCH_EXACT(0x001cc914),
250 		.name		= "RTL8211DN Gigabit Ethernet",
251 		.features	= PHY_GBIT_FEATURES,
252 		.ack_interrupt	= rtl821x_ack_interrupt,
253 		.config_intr	= rtl8211e_config_intr,
254 		.suspend	= genphy_suspend,
255 		.resume		= genphy_resume,
256 	}, {
257 		PHY_ID_MATCH_EXACT(0x001cc915),
258 		.name		= "RTL8211E Gigabit Ethernet",
259 		.features	= PHY_GBIT_FEATURES,
260 		.ack_interrupt	= &rtl821x_ack_interrupt,
261 		.config_intr	= &rtl8211e_config_intr,
262 		.suspend	= genphy_suspend,
263 		.resume		= genphy_resume,
264 	}, {
265 		PHY_ID_MATCH_EXACT(0x001cc916),
266 		.name		= "RTL8211F Gigabit Ethernet",
267 		.features	= PHY_GBIT_FEATURES,
268 		.config_init	= &rtl8211f_config_init,
269 		.ack_interrupt	= &rtl8211f_ack_interrupt,
270 		.config_intr	= &rtl8211f_config_intr,
271 		.suspend	= genphy_suspend,
272 		.resume		= genphy_resume,
273 		.read_page	= rtl821x_read_page,
274 		.write_page	= rtl821x_write_page,
275 	}, {
276 		PHY_ID_MATCH_EXACT(0x001cc800),
277 		.name		= "Generic Realtek PHY",
278 		.features	= PHY_GBIT_FEATURES,
279 		.config_init	= genphy_config_init,
280 		.suspend	= genphy_suspend,
281 		.resume		= genphy_resume,
282 		.read_page	= rtl821x_read_page,
283 		.write_page	= rtl821x_write_page,
284 	}, {
285 		PHY_ID_MATCH_EXACT(0x001cc961),
286 		.name		= "RTL8366RB Gigabit Ethernet",
287 		.features	= PHY_GBIT_FEATURES,
288 		.config_init	= &rtl8366rb_config_init,
289 		/* These interrupts are handled by the irq controller
290 		 * embedded inside the RTL8366RB, they get unmasked when the
291 		 * irq is requested and ACKed by reading the status register,
292 		 * which is done by the irqchip code.
293 		 */
294 		.ack_interrupt	= genphy_no_ack_interrupt,
295 		.config_intr	= genphy_no_config_intr,
296 		.suspend	= genphy_suspend,
297 		.resume		= genphy_resume,
298 	},
299 };
300 
301 module_phy_driver(realtek_drvs);
302 
303 static const struct mdio_device_id __maybe_unused realtek_tbl[] = {
304 	{ PHY_ID_MATCH_VENDOR(0x001cc800) },
305 	{ }
306 };
307 
308 MODULE_DEVICE_TABLE(mdio, realtek_tbl);
309