1 // SPDX-License-Identifier: GPL-2.0+
2 /**
3 *
4 * Driver for ROCKCHIP RK630 Ethernet PHYs
5 *
6 * Copyright (c) 2020, Rockchip Electronics Co., Ltd
7 *
8 * David Wu <david.wu@rock-chips.com>
9 *
10 */
11
12 #include <linux/ethtool.h>
13 #include <linux/kernel.h>
14 #include <linux/interrupt.h>
15 #include <linux/module.h>
16 #include <linux/mfd/core.h>
17 #include <linux/mii.h>
18 #include <linux/netdevice.h>
19 #include <linux/nvmem-consumer.h>
20 #include <linux/of_irq.h>
21 #include <linux/phy.h>
22 #include <linux/platform_device.h>
23 #include <linux/wakelock.h>
24
25 #define RK630_PHY_ID 0x00441400
26
27 /* PAGE 0 */
28 #define REG_MMD_ACCESS_CONTROL 0x0d
29 #define REG_MMD_ACCESS_DATA_ADDRESS 0x0e
30 #define REG_INTERRUPT_STATUS 0X10
31 #define REG_INTERRUPT_MASK 0X11
32 #define REG_GLOBAL_CONFIGURATION 0X13
33 #define REG_MAC_ADDRESS0 0x16
34 #define REG_MAC_ADDRESS1 0x17
35 #define REG_MAC_ADDRESS2 0x18
36
37 #define REG_PAGE_SEL 0x1F
38
39 /* PAGE 1 */
40 #define REG_PAGE1_APS_CTRL 0x12
41 #define REG_PAGE1_UAPS_CONFIGURE 0X13
42 #define REG_PAGE1_EEE_CONFIGURE 0x17
43
44 /* PAGE 2 */
45 #define REG_PAGE2_AFE_CTRL 0x18
46
47 /* PAGE 6 */
48 #define REG_PAGE6_ADC_ANONTROL 0x10
49 #define REG_PAGE6_GAIN_ANONTROL 0x12
50 #define REG_PAGE6_AFE_RX_CTRL 0x13
51 #define REG_PAGE6_AFE_TX_CTRL 0x14
52 #define REG_PAGE6_AFE_DRIVER2 0x15
53 #define REG_PAGE6_CP_CURRENT 0x17
54 #define REG_PAGE6_ADC_OP_BIAS 0x18
55 #define REG_PAGE6_RX_DECTOR 0x19
56 #define REG_PAGE6_TX_MOS_DRV 0x1B
57 #define REG_PAGE6_AFE_PDCW 0x1c
58
59 /* PAGE 8 */
60 #define REG_PAGE8_AFE_CTRL 0x18
61 #define REG_PAGE8_AUTO_CAL 0x1d
62
63 /*
64 * Fixed address:
65 * Addr: 1 --- RK630@S40
66 * 2 --- RV1106@T22
67 */
68 #define PHY_ADDR_S40 1
69 #define PHY_ADDR_T22 2
70
71 #define T22_TX_LEVEL_100M 0x2d
72 #define T22_TX_LEVEL_10M 0x32
73
74 struct rk630_phy_priv {
75 struct phy_device *phydev;
76 bool ieee;
77 int wol_irq;
78 struct wake_lock wol_wake_lock;
79 int tx_level_100M;
80 int tx_level_10M;
81 };
82
rk630_phy_t22_get_tx_level_from_efuse(struct phy_device * phydev)83 static void rk630_phy_t22_get_tx_level_from_efuse(struct phy_device *phydev)
84 {
85 struct rk630_phy_priv *priv = phydev->priv;
86 unsigned int tx_level_100M = T22_TX_LEVEL_100M;
87 unsigned int tx_level_10M = T22_TX_LEVEL_10M;
88 unsigned char *efuse_buf;
89 struct nvmem_cell *cell;
90 size_t len;
91
92 cell = nvmem_cell_get(&phydev->mdio.dev, "txlevel");
93 if (IS_ERR(cell)) {
94 phydev_err(phydev, "failed to get txlevel cell: %ld, use default\n",
95 PTR_ERR(cell));
96 } else {
97 efuse_buf = nvmem_cell_read(cell, &len);
98 nvmem_cell_put(cell);
99 if (!IS_ERR(efuse_buf)) {
100 if (len == 2 && efuse_buf[0] > 0 && efuse_buf[1] > 0) {
101 tx_level_100M = efuse_buf[1];
102 tx_level_10M = efuse_buf[0];
103 }
104 kfree(efuse_buf);
105 } else {
106 phydev_err(phydev, "failed to get efuse buf, use default\n");
107 }
108 }
109
110 priv->tx_level_100M = tx_level_100M;
111 priv->tx_level_10M = tx_level_10M;
112 }
113
rk630_phy_wol_enable(struct phy_device * phydev)114 static void rk630_phy_wol_enable(struct phy_device *phydev)
115 {
116 struct net_device *ndev = phydev->attached_dev;
117 u32 value;
118
119 /* Switch to page 0 */
120 phy_write(phydev, REG_PAGE_SEL, 0x0000);
121 phy_write(phydev, REG_MAC_ADDRESS0, ((u16)ndev->dev_addr[0] << 8) + ndev->dev_addr[1]);
122 phy_write(phydev, REG_MAC_ADDRESS1, ((u16)ndev->dev_addr[2] << 8) + ndev->dev_addr[3]);
123 phy_write(phydev, REG_MAC_ADDRESS2, ((u16)ndev->dev_addr[4] << 8) + ndev->dev_addr[5]);
124
125 value = phy_read(phydev, REG_GLOBAL_CONFIGURATION);
126 value |= BIT(8);
127 value &= ~BIT(7);
128 value |= BIT(10);
129 phy_write(phydev, REG_GLOBAL_CONFIGURATION, value);
130
131 value = phy_read(phydev, REG_INTERRUPT_MASK);
132 value |= BIT(14);
133 phy_write(phydev, REG_INTERRUPT_MASK, value);
134 }
135
rk630_phy_wol_disable(struct phy_device * phydev)136 static void rk630_phy_wol_disable(struct phy_device *phydev)
137 {
138 u32 value;
139
140 /* Switch to page 0 */
141 phy_write(phydev, REG_PAGE_SEL, 0x0000);
142 value = phy_read(phydev, REG_GLOBAL_CONFIGURATION);
143 value &= ~BIT(10);
144 phy_write(phydev, REG_GLOBAL_CONFIGURATION, value);
145 }
146
rk630_phy_ieee_set(struct phy_device * phydev,bool enable)147 static void rk630_phy_ieee_set(struct phy_device *phydev, bool enable)
148 {
149 u32 value;
150
151 /* Switch to page 1 */
152 phy_write(phydev, REG_PAGE_SEL, 0x0100);
153 value = phy_read(phydev, REG_PAGE1_EEE_CONFIGURE);
154 if (enable)
155 value |= BIT(3);
156 else
157 value &= ~BIT(3);
158 phy_write(phydev, REG_PAGE1_EEE_CONFIGURE, value);
159 /* Switch to page 0 */
160 phy_write(phydev, REG_PAGE_SEL, 0x0000);
161 }
162
rk630_phy_set_aps(struct phy_device * phydev,bool enable)163 static void rk630_phy_set_aps(struct phy_device *phydev, bool enable)
164 {
165 u32 value;
166
167 /* Switch to page 1 */
168 phy_write(phydev, REG_PAGE_SEL, 0x0100);
169 value = phy_read(phydev, REG_PAGE1_APS_CTRL);
170 if (enable)
171 value |= BIT(15);
172 else
173 value &= ~BIT(15);
174 phy_write(phydev, REG_PAGE1_APS_CTRL, value);
175 /* Switch to page 0 */
176 phy_write(phydev, REG_PAGE_SEL, 0x0000);
177 }
178
rk630_phy_set_uaps(struct phy_device * phydev,bool enable)179 static void rk630_phy_set_uaps(struct phy_device *phydev, bool enable)
180 {
181 u32 value;
182
183 /* Switch to page 1 */
184 phy_write(phydev, REG_PAGE_SEL, 0x0100);
185 value = phy_read(phydev, REG_PAGE1_UAPS_CONFIGURE);
186 if (enable)
187 value |= BIT(15);
188 else
189 value &= ~BIT(15);
190 phy_write(phydev, REG_PAGE1_UAPS_CONFIGURE, value);
191 /* Switch to page 0 */
192 phy_write(phydev, REG_PAGE_SEL, 0x0000);
193 }
194
rk630_phy_s40_config_init(struct phy_device * phydev)195 static void rk630_phy_s40_config_init(struct phy_device *phydev)
196 {
197 phy_write(phydev, 0, phy_read(phydev, 0) & ~BIT(13));
198
199 /* Switch to page 1 */
200 phy_write(phydev, REG_PAGE_SEL, 0x0100);
201 /* Disable APS */
202 phy_write(phydev, REG_PAGE1_APS_CTRL, 0x4824);
203 /* Switch to page 2 */
204 phy_write(phydev, REG_PAGE_SEL, 0x0200);
205 /* PHYAFE TRX optimization */
206 phy_write(phydev, REG_PAGE2_AFE_CTRL, 0x0000);
207 /* Switch to page 6 */
208 phy_write(phydev, REG_PAGE_SEL, 0x0600);
209 /* PHYAFE TX optimization */
210 phy_write(phydev, REG_PAGE6_AFE_TX_CTRL, 0x708f);
211 /* PHYAFE RX optimization */
212 phy_write(phydev, REG_PAGE6_AFE_RX_CTRL, 0xf000);
213 phy_write(phydev, REG_PAGE6_AFE_DRIVER2, 0x1530);
214
215 /* Switch to page 8 */
216 phy_write(phydev, REG_PAGE_SEL, 0x0800);
217 /* PHYAFE TRX optimization */
218 phy_write(phydev, REG_PAGE8_AFE_CTRL, 0x00bc);
219
220 /* Switch to page 0 */
221 phy_write(phydev, REG_PAGE_SEL, 0x0000);
222 }
223
rk630_phy_t22_config_init(struct phy_device * phydev)224 static void rk630_phy_t22_config_init(struct phy_device *phydev)
225 {
226 struct rk630_phy_priv *priv = phydev->priv;
227
228 /* Switch to page 1 */
229 phy_write(phydev, REG_PAGE_SEL, 0x0100);
230 /* Enable offset clock */
231 phy_write(phydev, 0x10, 0xfbfe);
232 /* Disable APS */
233 phy_write(phydev, REG_PAGE1_APS_CTRL, 0x4824);
234 /* Switch to page 2 */
235 phy_write(phydev, REG_PAGE_SEL, 0x0200);
236 /* PHYAFE TRX optimization */
237 phy_write(phydev, REG_PAGE2_AFE_CTRL, 0x0000);
238 /* Switch to page 6 */
239 phy_write(phydev, REG_PAGE_SEL, 0x0600);
240 /* PHYAFE ADC optimization */
241 phy_write(phydev, REG_PAGE6_ADC_ANONTROL, 0x555e);
242 /* PHYAFE Gain optimization */
243 phy_write(phydev, REG_PAGE6_GAIN_ANONTROL, 0x0400);
244 /* PHYAFE EQ optimization */
245 phy_write(phydev, REG_PAGE6_AFE_TX_CTRL, 0x1088);
246
247 if (priv->tx_level_100M <= 0 || priv->tx_level_10M <= 0)
248 rk630_phy_t22_get_tx_level_from_efuse(phydev);
249
250 /* PHYAFE TX optimization */
251 phy_write(phydev, REG_PAGE6_AFE_DRIVER2,
252 (priv->tx_level_100M << 8) | priv->tx_level_10M);
253 /* PHYAFE CP current optimization */
254 phy_write(phydev, REG_PAGE6_CP_CURRENT, 0x0575);
255 /* ADC OP BIAS optimization */
256 phy_write(phydev, REG_PAGE6_ADC_OP_BIAS, 0x0000);
257 /* Rx signal detctor level optimization */
258 phy_write(phydev, REG_PAGE6_RX_DECTOR, 0x0408);
259 /* PHYAFE PDCW optimization */
260 phy_write(phydev, REG_PAGE6_AFE_PDCW, 0x8880);
261 /* Add PHY Tx mos drive, reduce power noise/jitter */
262 phy_write(phydev, REG_PAGE6_TX_MOS_DRV, 0x888e);
263
264 /* Switch to page 8 */
265 phy_write(phydev, REG_PAGE_SEL, 0x0800);
266 /* Disable auto-cal */
267 phy_write(phydev, REG_PAGE8_AUTO_CAL, 0x0844);
268 /* Reatart offset calibration */
269 phy_write(phydev, 0x13, 0xc096);
270
271 /* Switch to page 0 */
272 phy_write(phydev, REG_PAGE_SEL, 0x0000);
273
274 /* Disable eee mode advertised */
275 phy_write(phydev, REG_MMD_ACCESS_CONTROL, 0x0007);
276 phy_write(phydev, REG_MMD_ACCESS_DATA_ADDRESS, 0x003c);
277 phy_write(phydev, REG_MMD_ACCESS_CONTROL, 0x4007);
278 phy_write(phydev, REG_MMD_ACCESS_DATA_ADDRESS, 0x0000);
279 }
280
rk630_phy_config_init(struct phy_device * phydev)281 static int rk630_phy_config_init(struct phy_device *phydev)
282 {
283 switch (phydev->mdio.addr) {
284 case PHY_ADDR_S40:
285 rk630_phy_s40_config_init(phydev);
286 /*
287 * Ultra Auto-Power Saving Mode (UAPS) is designed to
288 * save power when cable is not plugged into PHY.
289 */
290 rk630_phy_set_uaps(phydev, true);
291 break;
292 case PHY_ADDR_T22:
293 rk630_phy_t22_config_init(phydev);
294 rk630_phy_set_aps(phydev, true);
295 rk630_phy_set_uaps(phydev, true);
296 break;
297 default:
298 phydev_err(phydev, "Unsupported address for current phy: %d\n",
299 phydev->mdio.addr);
300 return -EINVAL;
301 }
302
303 rk630_phy_ieee_set(phydev, true);
304
305 return 0;
306 }
307
rk630_link_change_notify(struct phy_device * phydev)308 static void rk630_link_change_notify(struct phy_device *phydev)
309 {
310 unsigned int val;
311
312 if (phydev->state == PHY_RUNNING || phydev->state == PHY_NOLINK) {
313 /* Switch to page 6 */
314 phy_write(phydev, REG_PAGE_SEL, 0x0600);
315 val = phy_read(phydev, REG_PAGE6_AFE_TX_CTRL);
316 val &= ~GENMASK(14, 13);
317 if (phydev->speed == SPEED_10 && phydev->link)
318 val |= BIT(13);
319 phy_write(phydev, REG_PAGE6_AFE_TX_CTRL, val);
320 /* Switch to page 0 */
321 phy_write(phydev, REG_PAGE_SEL, 0x0000);
322 }
323 }
324
rk630_wol_irq_thread(int irq,void * dev_id)325 static irqreturn_t rk630_wol_irq_thread(int irq, void *dev_id)
326 {
327 struct rk630_phy_priv *priv = (struct rk630_phy_priv *)dev_id;
328
329 phy_write(priv->phydev, REG_INTERRUPT_STATUS, BIT(14));
330 wake_lock_timeout(&priv->wol_wake_lock, msecs_to_jiffies(8000));
331 return IRQ_HANDLED;
332 }
333
rk630_phy_probe(struct phy_device * phydev)334 static int rk630_phy_probe(struct phy_device *phydev)
335 {
336 struct rk630_phy_priv *priv;
337 int ret;
338
339 priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
340 if (!priv)
341 return -ENOMEM;
342
343 phydev->priv = priv;
344
345 priv->wol_irq = of_irq_get_byname(phydev->mdio.dev.of_node, "wol_irq");
346 if (priv->wol_irq == -EPROBE_DEFER)
347 return priv->wol_irq;
348
349 if (priv->wol_irq > 0) {
350 wake_lock_init(&priv->wol_wake_lock,
351 WAKE_LOCK_SUSPEND, "wol_wake_lock");
352 ret = devm_request_threaded_irq(&phydev->mdio.dev, priv->wol_irq,
353 NULL, rk630_wol_irq_thread,
354 IRQF_TRIGGER_FALLING | IRQF_SHARED | IRQF_ONESHOT,
355 "wol_irq", priv);
356 if (ret) {
357 wake_lock_destroy(&priv->wol_wake_lock);
358 phydev_err(phydev, "request wol_irq failed: %d\n", ret);
359 return ret;
360 }
361 disable_irq(priv->wol_irq);
362 enable_irq_wake(priv->wol_irq);
363 }
364
365 priv->phydev = phydev;
366
367 return 0;
368 }
369
rk630_phy_remove(struct phy_device * phydev)370 static void rk630_phy_remove(struct phy_device *phydev)
371 {
372 struct rk630_phy_priv *priv = phydev->priv;
373
374 if (priv->wol_irq > 0)
375 wake_lock_destroy(&priv->wol_wake_lock);
376 }
377
rk630_phy_suspend(struct phy_device * phydev)378 static int rk630_phy_suspend(struct phy_device *phydev)
379 {
380 struct rk630_phy_priv *priv = phydev->priv;
381
382 if (priv->wol_irq > 0) {
383 rk630_phy_wol_enable(phydev);
384 phy_write(phydev, REG_INTERRUPT_MASK, BIT(14));
385 enable_irq(priv->wol_irq);
386 }
387 return genphy_suspend(phydev);
388 }
389
rk630_phy_resume(struct phy_device * phydev)390 static int rk630_phy_resume(struct phy_device *phydev)
391 {
392 struct rk630_phy_priv *priv = phydev->priv;
393
394 if (priv->wol_irq > 0) {
395 rk630_phy_wol_disable(phydev);
396 phy_write(phydev, REG_INTERRUPT_MASK, 0);
397 disable_irq(priv->wol_irq);
398 }
399
400 return genphy_resume(phydev);
401 }
402
403 static struct phy_driver rk630_phy_driver[] = {
404 {
405 .phy_id = RK630_PHY_ID,
406 .phy_id_mask = 0xffffffff,
407 .name = "RK630 PHY",
408 .features = PHY_BASIC_FEATURES,
409 .flags = 0,
410 .link_change_notify = rk630_link_change_notify,
411 .probe = rk630_phy_probe,
412 .remove = rk630_phy_remove,
413 .soft_reset = genphy_soft_reset,
414 .config_init = rk630_phy_config_init,
415 .config_aneg = genphy_config_aneg,
416 .read_status = genphy_read_status,
417 .suspend = rk630_phy_suspend,
418 .resume = rk630_phy_resume,
419 },
420 };
421
422 static struct mdio_device_id __maybe_unused rk630_phy_tbl[] = {
423 { RK630_PHY_ID, 0xffffffff },
424 { }
425 };
426
427 MODULE_DEVICE_TABLE(mdio, rk630_phy_tbl);
428
429 module_phy_driver(rk630_phy_driver);
430
431 MODULE_AUTHOR("David Wu <david.wu@rock-chips.com>");
432 MODULE_DESCRIPTION("Rockchip RK630 Ethernet PHY driver");
433 MODULE_LICENSE("GPL v2");
434