1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * RealTek PHY drivers
4 *
5 * Copyright 2010-2011, 2015 Freescale Semiconductor, Inc.
6 * author Andy Fleming
7 * Copyright 2016 Karsten Merker <merker@debian.org>
8 */
9#include <common.h>
10#include <linux/bitops.h>
11#include <phy.h>
12#include <linux/delay.h>
13
14#define PHY_RTL8211x_FORCE_MASTER BIT(1)
15#define PHY_RTL8211F_FORCE_EEE_RXC_ON BIT(3)
16#define PHY_RTL8201F_S700_RMII_TIMINGS BIT(4)
17
18#define PHY_AUTONEGOTIATE_TIMEOUT 5000
19
20/* RTL8211x 1000BASE-T Control Register */
21#define MIIM_RTL8211x_CTRL1000T_MSCE BIT(12);
22#define MIIM_RTL8211x_CTRL1000T_MASTER BIT(11);
23
24/* RTL8211x PHY Status Register */
25#define MIIM_RTL8211x_PHY_STATUS       0x11
26#define MIIM_RTL8211x_PHYSTAT_SPEED    0xc000
27#define MIIM_RTL8211x_PHYSTAT_GBIT     0x8000
28#define MIIM_RTL8211x_PHYSTAT_100      0x4000
29#define MIIM_RTL8211x_PHYSTAT_DUPLEX   0x2000
30#define MIIM_RTL8211x_PHYSTAT_SPDDONE  0x0800
31#define MIIM_RTL8211x_PHYSTAT_LINK     0x0400
32
33/* RTL8211x PHY Interrupt Enable Register */
34#define MIIM_RTL8211x_PHY_INER         0x12
35#define MIIM_RTL8211x_PHY_INTR_ENA     0x9f01
36#define MIIM_RTL8211x_PHY_INTR_DIS     0x0000
37
38/* RTL8211x PHY Interrupt Status Register */
39#define MIIM_RTL8211x_PHY_INSR         0x13
40
41/* RTL8211F PHY Status Register */
42#define MIIM_RTL8211F_PHY_STATUS       0x1a
43#define MIIM_RTL8211F_AUTONEG_ENABLE   0x1000
44#define MIIM_RTL8211F_PHYSTAT_SPEED    0x0030
45#define MIIM_RTL8211F_PHYSTAT_GBIT     0x0020
46#define MIIM_RTL8211F_PHYSTAT_100      0x0010
47#define MIIM_RTL8211F_PHYSTAT_DUPLEX   0x0008
48#define MIIM_RTL8211F_PHYSTAT_SPDDONE  0x0800
49#define MIIM_RTL8211F_PHYSTAT_LINK     0x0004
50
51#define MIIM_RTL8211E_CONFREG		0x1c
52#define MIIM_RTL8211E_CTRL_DELAY	BIT(13)
53#define MIIM_RTL8211E_TX_DELAY		BIT(12)
54#define MIIM_RTL8211E_RX_DELAY		BIT(11)
55
56#define MIIM_RTL8211E_EXT_PAGE_SELECT  0x1e
57
58#define MIIM_RTL8211F_PAGE_SELECT      0x1f
59#define MIIM_RTL8211F_TX_DELAY		0x100
60#define MIIM_RTL8211F_RX_DELAY		0x8
61#define MIIM_RTL8211F_LCR		0x10
62
63#define RTL8201F_RMSR			0x10
64
65#define RMSR_RX_TIMING_SHIFT		BIT(2)
66#define RMSR_RX_TIMING_MASK		GENMASK(7, 4)
67#define RMSR_RX_TIMING_VAL		0x4
68#define RMSR_TX_TIMING_SHIFT		BIT(3)
69#define RMSR_TX_TIMING_MASK		GENMASK(11, 8)
70#define RMSR_TX_TIMING_VAL		0x5
71
72static int rtl8211f_phy_extread(struct phy_device *phydev, int addr,
73				int devaddr, int regnum)
74{
75	int oldpage = phy_read(phydev, MDIO_DEVAD_NONE,
76			       MIIM_RTL8211F_PAGE_SELECT);
77	int val;
78
79	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, devaddr);
80	val = phy_read(phydev, MDIO_DEVAD_NONE, regnum);
81	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, oldpage);
82
83	return val;
84}
85
86static int rtl8211f_phy_extwrite(struct phy_device *phydev, int addr,
87				 int devaddr, int regnum, u16 val)
88{
89	int oldpage = phy_read(phydev, MDIO_DEVAD_NONE,
90			       MIIM_RTL8211F_PAGE_SELECT);
91
92	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, devaddr);
93	phy_write(phydev, MDIO_DEVAD_NONE, regnum, val);
94	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, oldpage);
95
96	return 0;
97}
98
99static int rtl8211b_probe(struct phy_device *phydev)
100{
101#ifdef CONFIG_RTL8211X_PHY_FORCE_MASTER
102	phydev->flags |= PHY_RTL8211x_FORCE_MASTER;
103#endif
104
105	return 0;
106}
107
108static int rtl8211e_probe(struct phy_device *phydev)
109{
110	return 0;
111}
112
113static int rtl8211f_probe(struct phy_device *phydev)
114{
115#ifdef CONFIG_RTL8211F_PHY_FORCE_EEE_RXC_ON
116	phydev->flags |= PHY_RTL8211F_FORCE_EEE_RXC_ON;
117#endif
118
119	return 0;
120}
121
122static int rtl8210f_probe(struct phy_device *phydev)
123{
124#ifdef CONFIG_RTL8201F_PHY_S700_RMII_TIMINGS
125	phydev->flags |= PHY_RTL8201F_S700_RMII_TIMINGS;
126#endif
127
128	return 0;
129}
130
131/* RealTek RTL8211x */
132static int rtl8211x_config(struct phy_device *phydev)
133{
134	phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);
135
136	/* mask interrupt at init; if the interrupt is
137	 * needed indeed, it should be explicitly enabled
138	 */
139	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_INER,
140		  MIIM_RTL8211x_PHY_INTR_DIS);
141
142	if (phydev->flags & PHY_RTL8211x_FORCE_MASTER) {
143		unsigned int reg;
144
145		reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000);
146		/* force manual master/slave configuration */
147		reg |= MIIM_RTL8211x_CTRL1000T_MSCE;
148		/* force master mode */
149		reg |= MIIM_RTL8211x_CTRL1000T_MASTER;
150		phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, reg);
151	}
152	/* read interrupt status just to clear it */
153	phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_INER);
154
155	genphy_config_aneg(phydev);
156
157	return 0;
158}
159
160/* RealTek RTL8201F */
161static int rtl8201f_config(struct phy_device *phydev)
162{
163	unsigned int reg;
164
165	if (phydev->flags & PHY_RTL8201F_S700_RMII_TIMINGS) {
166		phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT,
167			  7);
168		reg = phy_read(phydev, MDIO_DEVAD_NONE, RTL8201F_RMSR);
169		reg &= ~(RMSR_RX_TIMING_MASK | RMSR_TX_TIMING_MASK);
170		/* Set the needed Rx/Tx Timings for proper PHY operation */
171		reg |= (RMSR_RX_TIMING_VAL << RMSR_RX_TIMING_SHIFT)
172		       | (RMSR_TX_TIMING_VAL << RMSR_TX_TIMING_SHIFT);
173		phy_write(phydev, MDIO_DEVAD_NONE, RTL8201F_RMSR, reg);
174		phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT,
175			  0);
176	}
177
178	genphy_config_aneg(phydev);
179
180	return 0;
181}
182
183static int rtl8211e_config(struct phy_device *phydev)
184{
185	int reg, val;
186
187	/* enable TX/RX delay for rgmii-* modes, and disable them for rgmii. */
188	switch (phydev->interface) {
189	case PHY_INTERFACE_MODE_RGMII:
190		val = MIIM_RTL8211E_CTRL_DELAY;
191		break;
192	case PHY_INTERFACE_MODE_RGMII_ID:
193		val = MIIM_RTL8211E_CTRL_DELAY | MIIM_RTL8211E_TX_DELAY |
194		      MIIM_RTL8211E_RX_DELAY;
195		break;
196	case PHY_INTERFACE_MODE_RGMII_RXID:
197		val = MIIM_RTL8211E_CTRL_DELAY | MIIM_RTL8211E_RX_DELAY;
198		break;
199	case PHY_INTERFACE_MODE_RGMII_TXID:
200		val = MIIM_RTL8211E_CTRL_DELAY | MIIM_RTL8211E_TX_DELAY;
201		break;
202	default: /* the rest of the modes imply leaving delays as is. */
203		goto default_delay;
204	}
205
206	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, 7);
207	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211E_EXT_PAGE_SELECT, 0xa4);
208
209	reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211E_CONFREG);
210	reg &= ~(MIIM_RTL8211E_TX_DELAY | MIIM_RTL8211E_RX_DELAY);
211	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211E_CONFREG, reg | val);
212
213	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, 0);
214
215default_delay:
216	genphy_config_aneg(phydev);
217
218	return 0;
219}
220
221static int rtl8211f_config(struct phy_device *phydev)
222{
223	u16 reg;
224
225	if (phydev->flags & PHY_RTL8211F_FORCE_EEE_RXC_ON) {
226		unsigned int reg;
227
228		reg = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1);
229		reg &= ~MDIO_PCS_CTRL1_CLKSTOP_EN;
230		phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1, reg);
231	}
232
233	phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);
234
235	phy_write(phydev, MDIO_DEVAD_NONE,
236		  MIIM_RTL8211F_PAGE_SELECT, 0xd08);
237	reg = phy_read(phydev, MDIO_DEVAD_NONE, 0x11);
238
239	/* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */
240	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
241	    phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
242		reg |= MIIM_RTL8211F_TX_DELAY;
243	else
244		reg &= ~MIIM_RTL8211F_TX_DELAY;
245
246	phy_write(phydev, MDIO_DEVAD_NONE, 0x11, reg);
247
248	/* enable RX-delay for rgmii-id and rgmii-rxid, otherwise disable it */
249	reg = phy_read(phydev, MDIO_DEVAD_NONE, 0x15);
250	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
251	    phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
252		reg |= MIIM_RTL8211F_RX_DELAY;
253	else
254		reg &= ~MIIM_RTL8211F_RX_DELAY;
255	phy_write(phydev, MDIO_DEVAD_NONE, 0x15, reg);
256
257	/* restore to default page 0 */
258	phy_write(phydev, MDIO_DEVAD_NONE,
259		  MIIM_RTL8211F_PAGE_SELECT, 0x0);
260
261	/* Set green LED for Link, yellow LED for Active */
262	phy_write(phydev, MDIO_DEVAD_NONE,
263		  MIIM_RTL8211F_PAGE_SELECT, 0xd04);
264	phy_write(phydev, MDIO_DEVAD_NONE, 0x10, 0x617f);
265	phy_write(phydev, MDIO_DEVAD_NONE,
266		  MIIM_RTL8211F_PAGE_SELECT, 0x0);
267
268	genphy_config_aneg(phydev);
269
270	return 0;
271}
272
273static int rtl8211x_parse_status(struct phy_device *phydev)
274{
275	unsigned int speed;
276	unsigned int mii_reg;
277
278	mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_STATUS);
279
280	if (!(mii_reg & MIIM_RTL8211x_PHYSTAT_SPDDONE)) {
281		int i = 0;
282
283		/* in case of timeout ->link is cleared */
284		phydev->link = 1;
285		puts("Waiting for PHY realtime link");
286		while (!(mii_reg & MIIM_RTL8211x_PHYSTAT_SPDDONE)) {
287			/* Timeout reached ? */
288			if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
289				puts(" TIMEOUT !\n");
290				phydev->link = 0;
291				break;
292			}
293
294			if ((i++ % 1000) == 0)
295				putc('.');
296			udelay(1000);	/* 1 ms */
297			mii_reg = phy_read(phydev, MDIO_DEVAD_NONE,
298					MIIM_RTL8211x_PHY_STATUS);
299		}
300		puts(" done\n");
301		udelay(500000);	/* another 500 ms (results in faster booting) */
302	} else {
303		if (mii_reg & MIIM_RTL8211x_PHYSTAT_LINK)
304			phydev->link = 1;
305		else
306			phydev->link = 0;
307	}
308
309	if (mii_reg & MIIM_RTL8211x_PHYSTAT_DUPLEX)
310		phydev->duplex = DUPLEX_FULL;
311	else
312		phydev->duplex = DUPLEX_HALF;
313
314	speed = (mii_reg & MIIM_RTL8211x_PHYSTAT_SPEED);
315
316	switch (speed) {
317	case MIIM_RTL8211x_PHYSTAT_GBIT:
318		phydev->speed = SPEED_1000;
319		break;
320	case MIIM_RTL8211x_PHYSTAT_100:
321		phydev->speed = SPEED_100;
322		break;
323	default:
324		phydev->speed = SPEED_10;
325	}
326
327	return 0;
328}
329
330static int rtl8211f_parse_status(struct phy_device *phydev)
331{
332	unsigned int speed;
333	unsigned int mii_reg;
334	int i = 0;
335
336	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, 0xa43);
337	mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PHY_STATUS);
338
339	phydev->link = 1;
340	while (!(mii_reg & MIIM_RTL8211F_PHYSTAT_LINK)) {
341		if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
342			puts(" TIMEOUT !\n");
343			phydev->link = 0;
344			break;
345		}
346
347		if ((i++ % 1000) == 0)
348			putc('.');
349		udelay(1000);
350		mii_reg = phy_read(phydev, MDIO_DEVAD_NONE,
351				   MIIM_RTL8211F_PHY_STATUS);
352	}
353
354	if (mii_reg & MIIM_RTL8211F_PHYSTAT_DUPLEX)
355		phydev->duplex = DUPLEX_FULL;
356	else
357		phydev->duplex = DUPLEX_HALF;
358
359	speed = (mii_reg & MIIM_RTL8211F_PHYSTAT_SPEED);
360
361	switch (speed) {
362	case MIIM_RTL8211F_PHYSTAT_GBIT:
363		phydev->speed = SPEED_1000;
364		break;
365	case MIIM_RTL8211F_PHYSTAT_100:
366		phydev->speed = SPEED_100;
367		break;
368	default:
369		phydev->speed = SPEED_10;
370	}
371
372	return 0;
373}
374
375static int rtl8211x_startup(struct phy_device *phydev)
376{
377	int ret;
378
379	/* Read the Status (2x to make sure link is right) */
380	ret = genphy_update_link(phydev);
381	if (ret)
382		return ret;
383
384	return rtl8211x_parse_status(phydev);
385}
386
387static int rtl8211f_startup(struct phy_device *phydev)
388{
389	int ret;
390
391	/* Read the Status (2x to make sure link is right) */
392	ret = genphy_update_link(phydev);
393	if (ret)
394		return ret;
395	/* Read the Status (2x to make sure link is right) */
396
397	return rtl8211f_parse_status(phydev);
398}
399
400/* Support for RTL8211B PHY */
401U_BOOT_PHY_DRIVER(rtl8211b) = {
402	.name = "RealTek RTL8211B",
403	.uid = 0x1cc912,
404	.mask = 0xffffff,
405	.features = PHY_GBIT_FEATURES,
406	.probe = &rtl8211b_probe,
407	.config = &rtl8211x_config,
408	.startup = &rtl8211x_startup,
409	.shutdown = &genphy_shutdown,
410};
411
412/* Support for RTL8211E-VB-CG, RTL8211E-VL-CG and RTL8211EG-VB-CG PHYs */
413U_BOOT_PHY_DRIVER(rtl8211e) = {
414	.name = "RealTek RTL8211E",
415	.uid = 0x1cc915,
416	.mask = 0xffffff,
417	.features = PHY_GBIT_FEATURES,
418	.probe = &rtl8211e_probe,
419	.config = &rtl8211e_config,
420	.startup = &genphy_startup,
421	.shutdown = &genphy_shutdown,
422};
423
424/* Support for RTL8211DN PHY */
425U_BOOT_PHY_DRIVER(rtl8211dn) = {
426	.name = "RealTek RTL8211DN",
427	.uid = 0x1cc914,
428	.mask = 0xffffff,
429	.features = PHY_GBIT_FEATURES,
430	.config = &rtl8211x_config,
431	.startup = &rtl8211x_startup,
432	.shutdown = &genphy_shutdown,
433};
434
435/* Support for RTL8211F PHY */
436U_BOOT_PHY_DRIVER(rtl8211f) = {
437	.name = "RealTek RTL8211F",
438	.uid = 0x1cc916,
439	.mask = 0xffffff,
440	.features = PHY_GBIT_FEATURES,
441	.probe = &rtl8211f_probe,
442	.config = &rtl8211f_config,
443	.startup = &rtl8211f_startup,
444	.shutdown = &genphy_shutdown,
445	.readext = &rtl8211f_phy_extread,
446	.writeext = &rtl8211f_phy_extwrite,
447};
448
449/* Support for RTL8211F-VD PHY */
450U_BOOT_PHY_DRIVER(rtl8211fvd) = {
451	.name = "RealTek RTL8211F-VD",
452	.uid = 0x1cc878,
453	.mask = 0xffffff,
454	.features = PHY_GBIT_FEATURES,
455	.probe = &rtl8211f_probe,
456	.config = &rtl8211f_config,
457	.startup = &rtl8211f_startup,
458	.shutdown = &genphy_shutdown,
459	.readext = &rtl8211f_phy_extread,
460	.writeext = &rtl8211f_phy_extwrite,
461};
462
463/* Support for RTL8201F PHY */
464U_BOOT_PHY_DRIVER(rtl8201f) = {
465	.name = "RealTek RTL8201F 10/100Mbps Ethernet",
466	.uid = 0x1cc816,
467	.mask = 0xffffff,
468	.features = PHY_BASIC_FEATURES,
469	.probe = &rtl8210f_probe,
470	.config = &rtl8201f_config,
471	.startup = &genphy_startup,
472	.shutdown = &genphy_shutdown,
473};
474