xref: /freebsd/sys/dev/dwc/if_dwc_rk.c (revision 50059a60edec3c8c37e2f7b490fef83ec288b2da)
1432ae724SEmmanuel Vadot /*-
2432ae724SEmmanuel Vadot  * SPDX-License-Identifier: BSD-2-Clause
3432ae724SEmmanuel Vadot  *
4432ae724SEmmanuel Vadot  * Copyright (c) 2018 Emmanuel Vadot <manu@freebsd.org>
5432ae724SEmmanuel Vadot  *
6432ae724SEmmanuel Vadot  * Redistribution and use in source and binary forms, with or without
7432ae724SEmmanuel Vadot  * modification, are permitted provided that the following conditions
8432ae724SEmmanuel Vadot  * are met:
9432ae724SEmmanuel Vadot  * 1. Redistributions of source code must retain the above copyright
10432ae724SEmmanuel Vadot  *    notice, this list of conditions and the following disclaimer.
11432ae724SEmmanuel Vadot  * 2. Redistributions in binary form must reproduce the above copyright
12432ae724SEmmanuel Vadot  *    notice, this list of conditions and the following disclaimer in the
13432ae724SEmmanuel Vadot  *    documentation and/or other materials provided with the distribution.
14432ae724SEmmanuel Vadot  *
15432ae724SEmmanuel Vadot  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16432ae724SEmmanuel Vadot  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17432ae724SEmmanuel Vadot  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18432ae724SEmmanuel Vadot  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19432ae724SEmmanuel Vadot  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20432ae724SEmmanuel Vadot  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21432ae724SEmmanuel Vadot  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22432ae724SEmmanuel Vadot  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23432ae724SEmmanuel Vadot  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24432ae724SEmmanuel Vadot  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25432ae724SEmmanuel Vadot  * SUCH DAMAGE.
26432ae724SEmmanuel Vadot */
27432ae724SEmmanuel Vadot 
28432ae724SEmmanuel Vadot #include <sys/cdefs.h>
29432ae724SEmmanuel Vadot #include <sys/param.h>
30432ae724SEmmanuel Vadot #include <sys/systm.h>
31432ae724SEmmanuel Vadot #include <sys/bus.h>
32432ae724SEmmanuel Vadot #include <sys/kernel.h>
33432ae724SEmmanuel Vadot #include <sys/module.h>
34432ae724SEmmanuel Vadot #include <sys/socket.h>
35432ae724SEmmanuel Vadot 
36432ae724SEmmanuel Vadot #include <machine/bus.h>
37432ae724SEmmanuel Vadot 
38432ae724SEmmanuel Vadot #include <net/if.h>
39432ae724SEmmanuel Vadot #include <net/if_media.h>
40432ae724SEmmanuel Vadot 
41432ae724SEmmanuel Vadot #include <dev/extres/clk/clk.h>
42432ae724SEmmanuel Vadot #include <dev/extres/hwreset/hwreset.h>
43432ae724SEmmanuel Vadot #include <dev/extres/regulator/regulator.h>
44432ae724SEmmanuel Vadot #include <dev/extres/syscon/syscon.h>
45432ae724SEmmanuel Vadot 
46*50059a60SEmmanuel Vadot #include <dev/dwc/if_dwc.h>
47*50059a60SEmmanuel Vadot #include <dev/dwc/if_dwcvar.h>
48*50059a60SEmmanuel Vadot #include <dev/ofw/ofw_bus.h>
49*50059a60SEmmanuel Vadot #include <dev/ofw/ofw_bus_subr.h>
50*50059a60SEmmanuel Vadot 
51432ae724SEmmanuel Vadot #include "if_dwc_if.h"
52432ae724SEmmanuel Vadot #include "syscon_if.h"
53432ae724SEmmanuel Vadot 
54432ae724SEmmanuel Vadot #define	RK3328_GRF_MAC_CON0		0x0900
55432ae724SEmmanuel Vadot #define	 MAC_CON0_GMAC2IO_TX_DL_CFG_MASK	0x7F
56432ae724SEmmanuel Vadot #define	 MAC_CON0_GMAC2IO_TX_DL_CFG_SHIFT	0
57432ae724SEmmanuel Vadot #define	 MAC_CON0_GMAC2IO_RX_DL_CFG_MASK	0x7F
58432ae724SEmmanuel Vadot #define	 MAC_CON0_GMAC2IO_RX_DL_CFG_SHIFT	7
59432ae724SEmmanuel Vadot 
60432ae724SEmmanuel Vadot #define	RK3328_GRF_MAC_CON1		0x0904
61432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA	(1 << 0)
62432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA	(1 << 1)
63432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_GMII_CLK_SEL_MASK	(3 << 11)
64432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_GMII_CLK_SEL_125	(0 << 11)
65432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_GMII_CLK_SEL_25	(3 << 11)
66432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_GMII_CLK_SEL_2_5	(2 << 11)
67432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_RMII_MODE_MASK	(1 << 9)
68432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_RMII_MODE		(1 << 9)
69432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_INTF_SEL_MASK		(7 << 4)
70432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_INTF_RMII		(4 << 4)
71432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_INTF_RGMII		(1 << 4)
72432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_RMII_CLK_SEL_MASK	(1 << 7)
73432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_RMII_CLK_SEL_25	(1 << 7)
74432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_RMII_CLK_SEL_2_5	(0 << 7)
75432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_MAC_SPEED_MASK	(1 << 2)
76432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_MAC_SPEED_100		(1 << 2)
77432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_MAC_SPEED_10		(0 << 2)
78432ae724SEmmanuel Vadot #define	RK3328_GRF_MAC_CON2		0x0908
79432ae724SEmmanuel Vadot #define	RK3328_GRF_MACPHY_CON0		0x0B00
80432ae724SEmmanuel Vadot #define	 MACPHY_CON0_CLK_50M_MASK		(1 << 14)
81432ae724SEmmanuel Vadot #define	 MACPHY_CON0_CLK_50M			(1 << 14)
82432ae724SEmmanuel Vadot #define	 MACPHY_CON0_RMII_MODE_MASK		(3 << 6)
83432ae724SEmmanuel Vadot #define	 MACPHY_CON0_RMII_MODE			(1 << 6)
84432ae724SEmmanuel Vadot #define	RK3328_GRF_MACPHY_CON1		0x0B04
85432ae724SEmmanuel Vadot #define	 MACPHY_CON1_RMII_MODE_MASK		(1 << 9)
86432ae724SEmmanuel Vadot #define	 MACPHY_CON1_RMII_MODE			(1 << 9)
87432ae724SEmmanuel Vadot #define	RK3328_GRF_MACPHY_CON2		0x0B08
88432ae724SEmmanuel Vadot #define	RK3328_GRF_MACPHY_CON3		0x0B0C
89432ae724SEmmanuel Vadot #define	RK3328_GRF_MACPHY_STATUS	0x0B10
90432ae724SEmmanuel Vadot 
91432ae724SEmmanuel Vadot #define	RK3399_GRF_SOC_CON5		0xc214
92432ae724SEmmanuel Vadot #define	 SOC_CON5_GMAC_CLK_SEL_MASK		(3 << 4)
93432ae724SEmmanuel Vadot #define	 SOC_CON5_GMAC_CLK_SEL_125		(0 << 4)
94432ae724SEmmanuel Vadot #define	 SOC_CON5_GMAC_CLK_SEL_25		(3 << 4)
95432ae724SEmmanuel Vadot #define	 SOC_CON5_GMAC_CLK_SEL_2_5		(2 << 4)
96432ae724SEmmanuel Vadot #define	RK3399_GRF_SOC_CON6		0xc218
97432ae724SEmmanuel Vadot #define	 SOC_CON6_GMAC_TXCLK_DLY_ENA		(1 << 7)
98432ae724SEmmanuel Vadot #define	 SOC_CON6_TX_DL_CFG_MASK		0x7F
99432ae724SEmmanuel Vadot #define	 SOC_CON6_TX_DL_CFG_SHIFT		0
100432ae724SEmmanuel Vadot #define	 SOC_CON6_RX_DL_CFG_MASK		0x7F
101432ae724SEmmanuel Vadot #define	 SOC_CON6_GMAC_RXCLK_DLY_ENA		(1 << 15)
102432ae724SEmmanuel Vadot #define	 SOC_CON6_RX_DL_CFG_SHIFT		8
103432ae724SEmmanuel Vadot 
104432ae724SEmmanuel Vadot struct if_dwc_rk_softc;
105432ae724SEmmanuel Vadot 
106432ae724SEmmanuel Vadot typedef void (*if_dwc_rk_set_delaysfn_t)(struct if_dwc_rk_softc *);
107432ae724SEmmanuel Vadot typedef int (*if_dwc_rk_set_speedfn_t)(struct if_dwc_rk_softc *, int);
108432ae724SEmmanuel Vadot typedef void (*if_dwc_rk_set_phy_modefn_t)(struct if_dwc_rk_softc *);
109432ae724SEmmanuel Vadot typedef void (*if_dwc_rk_phy_powerupfn_t)(struct if_dwc_rk_softc *);
110432ae724SEmmanuel Vadot 
111432ae724SEmmanuel Vadot struct if_dwc_rk_ops {
112432ae724SEmmanuel Vadot 	if_dwc_rk_set_delaysfn_t	set_delays;
113432ae724SEmmanuel Vadot 	if_dwc_rk_set_speedfn_t		set_speed;
114432ae724SEmmanuel Vadot 	if_dwc_rk_set_phy_modefn_t	set_phy_mode;
115432ae724SEmmanuel Vadot 	if_dwc_rk_phy_powerupfn_t	phy_powerup;
116432ae724SEmmanuel Vadot };
117432ae724SEmmanuel Vadot 
118432ae724SEmmanuel Vadot struct if_dwc_rk_softc {
119432ae724SEmmanuel Vadot 	struct dwc_softc	base;
120432ae724SEmmanuel Vadot 	uint32_t		tx_delay;
121432ae724SEmmanuel Vadot 	uint32_t		rx_delay;
122432ae724SEmmanuel Vadot 	bool			integrated_phy;
123432ae724SEmmanuel Vadot 	bool			clock_in;
124432ae724SEmmanuel Vadot 	phandle_t		phy_node;
125432ae724SEmmanuel Vadot 	struct syscon		*grf;
126432ae724SEmmanuel Vadot 	struct if_dwc_rk_ops	*ops;
127432ae724SEmmanuel Vadot 	/* Common clocks */
128432ae724SEmmanuel Vadot 	clk_t			mac_clk_rx;
129432ae724SEmmanuel Vadot 	clk_t			mac_clk_tx;
130432ae724SEmmanuel Vadot 	clk_t			aclk_mac;
131432ae724SEmmanuel Vadot 	clk_t			pclk_mac;
132432ae724SEmmanuel Vadot 	clk_t			clk_stmmaceth;
133*50059a60SEmmanuel Vadot 	clk_t			clk_mac_speed;
134432ae724SEmmanuel Vadot 	/* RMII clocks */
135432ae724SEmmanuel Vadot 	clk_t			clk_mac_ref;
136432ae724SEmmanuel Vadot 	clk_t			clk_mac_refout;
137432ae724SEmmanuel Vadot 	/* PHY clock */
138432ae724SEmmanuel Vadot 	clk_t			clk_phy;
139432ae724SEmmanuel Vadot };
140432ae724SEmmanuel Vadot 
141432ae724SEmmanuel Vadot static void rk3328_set_delays(struct if_dwc_rk_softc *sc);
142432ae724SEmmanuel Vadot static int rk3328_set_speed(struct if_dwc_rk_softc *sc, int speed);
143432ae724SEmmanuel Vadot static void rk3328_set_phy_mode(struct if_dwc_rk_softc *sc);
144432ae724SEmmanuel Vadot static void rk3328_phy_powerup(struct if_dwc_rk_softc *sc);
145432ae724SEmmanuel Vadot 
146432ae724SEmmanuel Vadot static void rk3399_set_delays(struct if_dwc_rk_softc *sc);
147432ae724SEmmanuel Vadot static int rk3399_set_speed(struct if_dwc_rk_softc *sc, int speed);
148432ae724SEmmanuel Vadot 
149432ae724SEmmanuel Vadot static struct if_dwc_rk_ops rk3288_ops = {
150432ae724SEmmanuel Vadot };
151432ae724SEmmanuel Vadot 
152432ae724SEmmanuel Vadot static struct if_dwc_rk_ops rk3328_ops = {
153432ae724SEmmanuel Vadot 	.set_delays = rk3328_set_delays,
154432ae724SEmmanuel Vadot 	.set_speed = rk3328_set_speed,
155432ae724SEmmanuel Vadot 	.set_phy_mode = rk3328_set_phy_mode,
156432ae724SEmmanuel Vadot 	.phy_powerup = rk3328_phy_powerup,
157432ae724SEmmanuel Vadot };
158432ae724SEmmanuel Vadot 
159432ae724SEmmanuel Vadot static struct if_dwc_rk_ops rk3399_ops = {
160432ae724SEmmanuel Vadot 	.set_delays = rk3399_set_delays,
161432ae724SEmmanuel Vadot 	.set_speed = rk3399_set_speed,
162432ae724SEmmanuel Vadot };
163432ae724SEmmanuel Vadot 
164432ae724SEmmanuel Vadot static struct ofw_compat_data compat_data[] = {
165432ae724SEmmanuel Vadot 	{"rockchip,rk3288-gmac", (uintptr_t)&rk3288_ops},
166432ae724SEmmanuel Vadot 	{"rockchip,rk3328-gmac", (uintptr_t)&rk3328_ops},
167432ae724SEmmanuel Vadot 	{"rockchip,rk3399-gmac", (uintptr_t)&rk3399_ops},
168432ae724SEmmanuel Vadot 	{NULL,			 0}
169432ae724SEmmanuel Vadot };
170432ae724SEmmanuel Vadot 
171432ae724SEmmanuel Vadot static void
172432ae724SEmmanuel Vadot rk3328_set_delays(struct if_dwc_rk_softc *sc)
173432ae724SEmmanuel Vadot {
174432ae724SEmmanuel Vadot 	uint32_t reg;
175432ae724SEmmanuel Vadot 	uint32_t tx, rx;
176432ae724SEmmanuel Vadot 
177432ae724SEmmanuel Vadot 	if (sc->base.phy_mode != PHY_MODE_RGMII)
178432ae724SEmmanuel Vadot 		return;
179432ae724SEmmanuel Vadot 
180432ae724SEmmanuel Vadot 	reg = SYSCON_READ_4(sc->grf, RK3328_GRF_MAC_CON0);
181432ae724SEmmanuel Vadot 	tx = ((reg >> MAC_CON0_GMAC2IO_TX_DL_CFG_SHIFT) & MAC_CON0_GMAC2IO_TX_DL_CFG_MASK);
182432ae724SEmmanuel Vadot 	rx = ((reg >> MAC_CON0_GMAC2IO_RX_DL_CFG_SHIFT) & MAC_CON0_GMAC2IO_RX_DL_CFG_MASK);
183432ae724SEmmanuel Vadot 
184432ae724SEmmanuel Vadot 	reg = SYSCON_READ_4(sc->grf, RK3328_GRF_MAC_CON1);
185432ae724SEmmanuel Vadot 	if (bootverbose) {
186432ae724SEmmanuel Vadot 		device_printf(sc->base.dev, "current delays settings: tx=%u(%s) rx=%u(%s)\n",
187432ae724SEmmanuel Vadot 		    tx, ((reg & MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA) ? "enabled" : "disabled"),
188432ae724SEmmanuel Vadot 		    rx, ((reg & MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA) ? "enabled" : "disabled"));
189432ae724SEmmanuel Vadot 
190432ae724SEmmanuel Vadot 		device_printf(sc->base.dev, "setting new RK3328 RX/TX delays:  %d/%d\n",
191432ae724SEmmanuel Vadot 			sc->tx_delay, sc->rx_delay);
192432ae724SEmmanuel Vadot 	}
193432ae724SEmmanuel Vadot 
194432ae724SEmmanuel Vadot 	reg = (MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA | MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA) << 16;
195432ae724SEmmanuel Vadot 	reg |= (MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA | MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA);
196432ae724SEmmanuel Vadot 	SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON1, reg);
197432ae724SEmmanuel Vadot 
198432ae724SEmmanuel Vadot 	reg = 0xffff << 16;
199432ae724SEmmanuel Vadot 	reg |= ((sc->tx_delay & MAC_CON0_GMAC2IO_TX_DL_CFG_MASK) <<
200432ae724SEmmanuel Vadot 	    MAC_CON0_GMAC2IO_TX_DL_CFG_SHIFT);
201432ae724SEmmanuel Vadot 	reg |= ((sc->rx_delay & MAC_CON0_GMAC2IO_TX_DL_CFG_MASK) <<
202432ae724SEmmanuel Vadot 	    MAC_CON0_GMAC2IO_RX_DL_CFG_SHIFT);
203432ae724SEmmanuel Vadot 	SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON0, reg);
204432ae724SEmmanuel Vadot }
205432ae724SEmmanuel Vadot 
206432ae724SEmmanuel Vadot static int
207432ae724SEmmanuel Vadot rk3328_set_speed(struct if_dwc_rk_softc *sc, int speed)
208432ae724SEmmanuel Vadot {
209432ae724SEmmanuel Vadot 	uint32_t reg;
210432ae724SEmmanuel Vadot 
211432ae724SEmmanuel Vadot 	switch (sc->base.phy_mode) {
212432ae724SEmmanuel Vadot 	case PHY_MODE_RGMII:
213432ae724SEmmanuel Vadot 		switch (speed) {
214432ae724SEmmanuel Vadot 		case IFM_1000_T:
215432ae724SEmmanuel Vadot 		case IFM_1000_SX:
216432ae724SEmmanuel Vadot 			reg = MAC_CON1_GMAC2IO_GMII_CLK_SEL_125;
217432ae724SEmmanuel Vadot 			break;
218432ae724SEmmanuel Vadot 		case IFM_100_TX:
219432ae724SEmmanuel Vadot 			reg = MAC_CON1_GMAC2IO_GMII_CLK_SEL_25;
220432ae724SEmmanuel Vadot 			break;
221432ae724SEmmanuel Vadot 		case IFM_10_T:
222432ae724SEmmanuel Vadot 			reg = MAC_CON1_GMAC2IO_GMII_CLK_SEL_2_5;
223432ae724SEmmanuel Vadot 			break;
224432ae724SEmmanuel Vadot 		default:
225432ae724SEmmanuel Vadot 			device_printf(sc->base.dev, "unsupported RGMII media %u\n", speed);
226432ae724SEmmanuel Vadot 			return (-1);
227432ae724SEmmanuel Vadot 		}
228432ae724SEmmanuel Vadot 
229432ae724SEmmanuel Vadot 		SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON1,
230432ae724SEmmanuel Vadot 		    ((MAC_CON1_GMAC2IO_GMII_CLK_SEL_MASK << 16) | reg));
231432ae724SEmmanuel Vadot 		break;
232432ae724SEmmanuel Vadot 	case PHY_MODE_RMII:
233432ae724SEmmanuel Vadot 		switch (speed) {
234432ae724SEmmanuel Vadot 		case IFM_100_TX:
235432ae724SEmmanuel Vadot 			reg = MAC_CON1_GMAC2IO_RMII_CLK_SEL_25 |
236432ae724SEmmanuel Vadot 			    MAC_CON1_GMAC2IO_MAC_SPEED_100;
237432ae724SEmmanuel Vadot 			break;
238432ae724SEmmanuel Vadot 		case IFM_10_T:
239432ae724SEmmanuel Vadot 			reg = MAC_CON1_GMAC2IO_RMII_CLK_SEL_2_5 |
240432ae724SEmmanuel Vadot 			    MAC_CON1_GMAC2IO_MAC_SPEED_10;
241432ae724SEmmanuel Vadot 			break;
242432ae724SEmmanuel Vadot 		default:
243432ae724SEmmanuel Vadot 			device_printf(sc->base.dev, "unsupported RMII media %u\n", speed);
244432ae724SEmmanuel Vadot 			return (-1);
245432ae724SEmmanuel Vadot 		}
246432ae724SEmmanuel Vadot 
247432ae724SEmmanuel Vadot 		SYSCON_WRITE_4(sc->grf,
248432ae724SEmmanuel Vadot 		    sc->integrated_phy ? RK3328_GRF_MAC_CON2 : RK3328_GRF_MAC_CON1,
249432ae724SEmmanuel Vadot 		    reg |
250432ae724SEmmanuel Vadot 		    ((MAC_CON1_GMAC2IO_RMII_CLK_SEL_MASK | MAC_CON1_GMAC2IO_MAC_SPEED_MASK) << 16));
251432ae724SEmmanuel Vadot 		break;
252432ae724SEmmanuel Vadot 	}
253432ae724SEmmanuel Vadot 
254432ae724SEmmanuel Vadot 	return (0);
255432ae724SEmmanuel Vadot }
256432ae724SEmmanuel Vadot 
257432ae724SEmmanuel Vadot static void
258432ae724SEmmanuel Vadot rk3328_set_phy_mode(struct if_dwc_rk_softc *sc)
259432ae724SEmmanuel Vadot {
260432ae724SEmmanuel Vadot 
261432ae724SEmmanuel Vadot 	switch (sc->base.phy_mode) {
262432ae724SEmmanuel Vadot 	case PHY_MODE_RGMII:
263432ae724SEmmanuel Vadot 		SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON1,
264432ae724SEmmanuel Vadot 		    ((MAC_CON1_GMAC2IO_INTF_SEL_MASK | MAC_CON1_GMAC2IO_RMII_MODE_MASK) << 16) |
265432ae724SEmmanuel Vadot 		    MAC_CON1_GMAC2IO_INTF_RGMII);
266432ae724SEmmanuel Vadot 		break;
267432ae724SEmmanuel Vadot 	case PHY_MODE_RMII:
268432ae724SEmmanuel Vadot 		SYSCON_WRITE_4(sc->grf, sc->integrated_phy ? RK3328_GRF_MAC_CON2 : RK3328_GRF_MAC_CON1,
269432ae724SEmmanuel Vadot 		    ((MAC_CON1_GMAC2IO_INTF_SEL_MASK | MAC_CON1_GMAC2IO_RMII_MODE_MASK) << 16) |
270432ae724SEmmanuel Vadot 		    MAC_CON1_GMAC2IO_INTF_RMII | MAC_CON1_GMAC2IO_RMII_MODE);
271432ae724SEmmanuel Vadot 		break;
272432ae724SEmmanuel Vadot 	}
273432ae724SEmmanuel Vadot }
274432ae724SEmmanuel Vadot 
275432ae724SEmmanuel Vadot static void
276432ae724SEmmanuel Vadot rk3328_phy_powerup(struct if_dwc_rk_softc *sc)
277432ae724SEmmanuel Vadot {
278432ae724SEmmanuel Vadot 	SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON1,
279432ae724SEmmanuel Vadot 	    (MACPHY_CON1_RMII_MODE_MASK << 16) |
280432ae724SEmmanuel Vadot 	    MACPHY_CON1_RMII_MODE);
281432ae724SEmmanuel Vadot }
282432ae724SEmmanuel Vadot 
283432ae724SEmmanuel Vadot static void
284432ae724SEmmanuel Vadot rk3399_set_delays(struct if_dwc_rk_softc *sc)
285432ae724SEmmanuel Vadot {
286432ae724SEmmanuel Vadot 	uint32_t reg, tx, rx;
287432ae724SEmmanuel Vadot 
288432ae724SEmmanuel Vadot 	if (sc->base.phy_mode != PHY_MODE_RGMII)
289432ae724SEmmanuel Vadot 		return;
290432ae724SEmmanuel Vadot 
291432ae724SEmmanuel Vadot 	reg = SYSCON_READ_4(sc->grf, RK3399_GRF_SOC_CON6);
292432ae724SEmmanuel Vadot 	tx = ((reg >> SOC_CON6_TX_DL_CFG_SHIFT) & SOC_CON6_TX_DL_CFG_MASK);
293432ae724SEmmanuel Vadot 	rx = ((reg >> SOC_CON6_RX_DL_CFG_SHIFT) & SOC_CON6_RX_DL_CFG_MASK);
294432ae724SEmmanuel Vadot 
295432ae724SEmmanuel Vadot 	if (bootverbose) {
296432ae724SEmmanuel Vadot 		device_printf(sc->base.dev, "current delays settings: tx=%u(%s) rx=%u(%s)\n",
297432ae724SEmmanuel Vadot 		    tx, ((reg & SOC_CON6_GMAC_TXCLK_DLY_ENA) ? "enabled" : "disabled"),
298432ae724SEmmanuel Vadot 		    rx, ((reg & SOC_CON6_GMAC_RXCLK_DLY_ENA) ? "enabled" : "disabled"));
299432ae724SEmmanuel Vadot 
300432ae724SEmmanuel Vadot 		device_printf(sc->base.dev, "setting new RK3399 RX/TX delays:  %d/%d\n",
301432ae724SEmmanuel Vadot 		    sc->rx_delay, sc->tx_delay);
302432ae724SEmmanuel Vadot 	}
303432ae724SEmmanuel Vadot 
304432ae724SEmmanuel Vadot 	reg = 0xFFFF << 16;
305432ae724SEmmanuel Vadot 	reg |= ((sc->tx_delay & SOC_CON6_TX_DL_CFG_MASK) <<
306432ae724SEmmanuel Vadot 	    SOC_CON6_TX_DL_CFG_SHIFT);
307432ae724SEmmanuel Vadot 	reg |= ((sc->rx_delay & SOC_CON6_RX_DL_CFG_MASK) <<
308432ae724SEmmanuel Vadot 	    SOC_CON6_RX_DL_CFG_SHIFT);
309432ae724SEmmanuel Vadot 	reg |= SOC_CON6_GMAC_TXCLK_DLY_ENA | SOC_CON6_GMAC_RXCLK_DLY_ENA;
310432ae724SEmmanuel Vadot 
311432ae724SEmmanuel Vadot 	SYSCON_WRITE_4(sc->grf, RK3399_GRF_SOC_CON6, reg);
312432ae724SEmmanuel Vadot }
313432ae724SEmmanuel Vadot 
314432ae724SEmmanuel Vadot static int
315432ae724SEmmanuel Vadot rk3399_set_speed(struct if_dwc_rk_softc *sc, int speed)
316432ae724SEmmanuel Vadot {
317432ae724SEmmanuel Vadot 	uint32_t reg;
318432ae724SEmmanuel Vadot 
319432ae724SEmmanuel Vadot 	switch (speed) {
320432ae724SEmmanuel Vadot 	case IFM_1000_T:
321432ae724SEmmanuel Vadot 	case IFM_1000_SX:
322432ae724SEmmanuel Vadot 		reg = SOC_CON5_GMAC_CLK_SEL_125;
323432ae724SEmmanuel Vadot 		break;
324432ae724SEmmanuel Vadot 	case IFM_100_TX:
325432ae724SEmmanuel Vadot 		reg = SOC_CON5_GMAC_CLK_SEL_25;
326432ae724SEmmanuel Vadot 		break;
327432ae724SEmmanuel Vadot 	case IFM_10_T:
328432ae724SEmmanuel Vadot 		reg = SOC_CON5_GMAC_CLK_SEL_2_5;
329432ae724SEmmanuel Vadot 		break;
330432ae724SEmmanuel Vadot 	default:
331432ae724SEmmanuel Vadot 		device_printf(sc->base.dev, "unsupported media %u\n", speed);
332432ae724SEmmanuel Vadot 		return (-1);
333432ae724SEmmanuel Vadot 	}
334432ae724SEmmanuel Vadot 
335432ae724SEmmanuel Vadot 	SYSCON_WRITE_4(sc->grf, RK3399_GRF_SOC_CON5,
336432ae724SEmmanuel Vadot 	    ((SOC_CON5_GMAC_CLK_SEL_MASK << 16) | reg));
337432ae724SEmmanuel Vadot 	return (0);
338432ae724SEmmanuel Vadot }
339432ae724SEmmanuel Vadot 
340432ae724SEmmanuel Vadot static int
341432ae724SEmmanuel Vadot if_dwc_rk_sysctl_delays(SYSCTL_HANDLER_ARGS)
342432ae724SEmmanuel Vadot {
343432ae724SEmmanuel Vadot 	struct if_dwc_rk_softc *sc;
344432ae724SEmmanuel Vadot 	int rv;
345432ae724SEmmanuel Vadot 	uint32_t rxtx;
346432ae724SEmmanuel Vadot 
347432ae724SEmmanuel Vadot 	sc = arg1;
348432ae724SEmmanuel Vadot 	rxtx = ((sc->rx_delay << 8) | sc->tx_delay);
349432ae724SEmmanuel Vadot 
350432ae724SEmmanuel Vadot 	rv = sysctl_handle_int(oidp, &rxtx, 0, req);
351432ae724SEmmanuel Vadot 	if (rv != 0 || req->newptr == NULL)
352432ae724SEmmanuel Vadot 		return (rv);
353432ae724SEmmanuel Vadot 	sc->tx_delay = rxtx & 0xff;
354432ae724SEmmanuel Vadot 	sc->rx_delay = (rxtx >> 8) & 0xff;
355432ae724SEmmanuel Vadot 
356432ae724SEmmanuel Vadot 	if (sc->ops->set_delays)
357432ae724SEmmanuel Vadot 	    sc->ops->set_delays(sc);
358432ae724SEmmanuel Vadot 
359432ae724SEmmanuel Vadot 	return (0);
360432ae724SEmmanuel Vadot }
361432ae724SEmmanuel Vadot 
362432ae724SEmmanuel Vadot static int
363432ae724SEmmanuel Vadot if_dwc_rk_init_sysctl(struct if_dwc_rk_softc *sc)
364432ae724SEmmanuel Vadot {
365432ae724SEmmanuel Vadot 	struct sysctl_oid *child;
366432ae724SEmmanuel Vadot 	struct sysctl_ctx_list *ctx_list;
367432ae724SEmmanuel Vadot 
368432ae724SEmmanuel Vadot 	ctx_list = device_get_sysctl_ctx(sc->base.dev);
369432ae724SEmmanuel Vadot 	child = device_get_sysctl_tree(sc->base.dev);
370432ae724SEmmanuel Vadot 	SYSCTL_ADD_PROC(ctx_list,
371432ae724SEmmanuel Vadot 	    SYSCTL_CHILDREN(child), OID_AUTO, "delays",
372432ae724SEmmanuel Vadot 	    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, sc, 0,
373432ae724SEmmanuel Vadot 	    if_dwc_rk_sysctl_delays, "", "RGMII RX/TX delays: ((rx << 8) | tx)");
374432ae724SEmmanuel Vadot 
375432ae724SEmmanuel Vadot 	return (0);
376432ae724SEmmanuel Vadot }
377432ae724SEmmanuel Vadot 
378432ae724SEmmanuel Vadot static int
379432ae724SEmmanuel Vadot if_dwc_rk_probe(device_t dev)
380432ae724SEmmanuel Vadot {
381432ae724SEmmanuel Vadot 
382432ae724SEmmanuel Vadot 	if (!ofw_bus_status_okay(dev))
383432ae724SEmmanuel Vadot 		return (ENXIO);
384432ae724SEmmanuel Vadot 	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
385432ae724SEmmanuel Vadot 		return (ENXIO);
386432ae724SEmmanuel Vadot 	device_set_desc(dev, "Rockchip Gigabit Ethernet Controller");
387432ae724SEmmanuel Vadot 
388432ae724SEmmanuel Vadot 	return (BUS_PROBE_DEFAULT);
389432ae724SEmmanuel Vadot }
390432ae724SEmmanuel Vadot 
391432ae724SEmmanuel Vadot static int
392432ae724SEmmanuel Vadot if_dwc_rk_init_clocks(device_t dev)
393432ae724SEmmanuel Vadot {
394432ae724SEmmanuel Vadot 	struct if_dwc_rk_softc *sc;
395432ae724SEmmanuel Vadot 
396432ae724SEmmanuel Vadot 	sc = device_get_softc(dev);
397432ae724SEmmanuel Vadot 
398432ae724SEmmanuel Vadot 	/* Enable clocks */
399432ae724SEmmanuel Vadot 
400432ae724SEmmanuel Vadot 	if (clk_get_by_ofw_name(dev, 0, "mac_clk_tx", &sc->mac_clk_tx) != 0) {
401432ae724SEmmanuel Vadot 		device_printf(sc->base.dev, "could not get mac_clk_tx clock\n");
402432ae724SEmmanuel Vadot 		sc->mac_clk_tx = NULL;
403432ae724SEmmanuel Vadot 	}
404432ae724SEmmanuel Vadot 
405432ae724SEmmanuel Vadot 	if (clk_get_by_ofw_name(dev, 0, "aclk_mac", &sc->aclk_mac) != 0) {
406432ae724SEmmanuel Vadot 		device_printf(sc->base.dev, "could not get aclk_mac clock\n");
407432ae724SEmmanuel Vadot 		sc->aclk_mac = NULL;
408432ae724SEmmanuel Vadot 	}
409432ae724SEmmanuel Vadot 
410432ae724SEmmanuel Vadot 	if (clk_get_by_ofw_name(dev, 0, "pclk_mac", &sc->pclk_mac) != 0) {
411432ae724SEmmanuel Vadot 		device_printf(sc->base.dev, "could not get pclk_mac clock\n");
412432ae724SEmmanuel Vadot 		sc->pclk_mac = NULL;
413432ae724SEmmanuel Vadot 	}
414432ae724SEmmanuel Vadot 
415*50059a60SEmmanuel Vadot 	/* Optional clock */
416*50059a60SEmmanuel Vadot 	clk_get_by_ofw_name(dev, 0, "clk_mac_speed", &sc->clk_mac_speed);
417*50059a60SEmmanuel Vadot 
418*50059a60SEmmanuel Vadot 	if (sc->base.phy_mode == PHY_MODE_RMII) {
419*50059a60SEmmanuel Vadot 		if (clk_get_by_ofw_name(dev, 0, "mac_clk_rx", &sc->mac_clk_rx) != 0) {
420*50059a60SEmmanuel Vadot 			device_printf(sc->base.dev, "could not get mac_clk_rx clock\n");
421*50059a60SEmmanuel Vadot 			sc->mac_clk_rx = NULL;
422*50059a60SEmmanuel Vadot 		}
423*50059a60SEmmanuel Vadot 
424432ae724SEmmanuel Vadot 		if (clk_get_by_ofw_name(dev, 0, "clk_mac_ref", &sc->clk_mac_ref) != 0) {
425432ae724SEmmanuel Vadot 			device_printf(sc->base.dev, "could not get clk_mac_ref clock\n");
426432ae724SEmmanuel Vadot 			sc->clk_mac_ref = NULL;
427432ae724SEmmanuel Vadot 		}
428432ae724SEmmanuel Vadot 
429432ae724SEmmanuel Vadot 		if (!sc->clock_in) {
430432ae724SEmmanuel Vadot 			if (clk_get_by_ofw_name(dev, 0, "clk_mac_refout", &sc->clk_mac_refout) != 0) {
431432ae724SEmmanuel Vadot 				device_printf(sc->base.dev, "could not get clk_mac_refout clock\n");
432432ae724SEmmanuel Vadot 				sc->clk_mac_refout = NULL;
433432ae724SEmmanuel Vadot 			}
434432ae724SEmmanuel Vadot 
435432ae724SEmmanuel Vadot 			clk_set_freq(sc->clk_stmmaceth, 50000000, 0);
436432ae724SEmmanuel Vadot 		}
437432ae724SEmmanuel Vadot 	}
438432ae724SEmmanuel Vadot 
439432ae724SEmmanuel Vadot 	if ((sc->phy_node != 0) && sc->integrated_phy) {
440432ae724SEmmanuel Vadot 		if (clk_get_by_ofw_index(dev, sc->phy_node, 0, &sc->clk_phy) != 0) {
441432ae724SEmmanuel Vadot 			device_printf(sc->base.dev, "could not get PHY clock\n");
442432ae724SEmmanuel Vadot 			sc->clk_phy = NULL;
443432ae724SEmmanuel Vadot 		}
444432ae724SEmmanuel Vadot 
445432ae724SEmmanuel Vadot 		if (sc->clk_phy) {
446432ae724SEmmanuel Vadot 			clk_set_freq(sc->clk_phy, 50000000, 0);
447432ae724SEmmanuel Vadot 		}
448432ae724SEmmanuel Vadot 	}
449432ae724SEmmanuel Vadot 
450432ae724SEmmanuel Vadot 	if (sc->base.phy_mode == PHY_MODE_RMII) {
451432ae724SEmmanuel Vadot 		if (sc->mac_clk_rx)
452432ae724SEmmanuel Vadot 			clk_enable(sc->mac_clk_rx);
453432ae724SEmmanuel Vadot 		if (sc->clk_mac_ref)
454432ae724SEmmanuel Vadot 			clk_enable(sc->clk_mac_ref);
455432ae724SEmmanuel Vadot 		if (sc->clk_mac_refout)
456432ae724SEmmanuel Vadot 			clk_enable(sc->clk_mac_refout);
457432ae724SEmmanuel Vadot 	}
458432ae724SEmmanuel Vadot 	if (sc->clk_phy)
459432ae724SEmmanuel Vadot 		clk_enable(sc->clk_phy);
460432ae724SEmmanuel Vadot 	if (sc->aclk_mac)
461432ae724SEmmanuel Vadot 		clk_enable(sc->aclk_mac);
462432ae724SEmmanuel Vadot 	if (sc->pclk_mac)
463432ae724SEmmanuel Vadot 		clk_enable(sc->pclk_mac);
464432ae724SEmmanuel Vadot 	if (sc->mac_clk_tx)
465432ae724SEmmanuel Vadot 		clk_enable(sc->mac_clk_tx);
466*50059a60SEmmanuel Vadot 	if (sc->clk_mac_speed)
467*50059a60SEmmanuel Vadot 		clk_enable(sc->clk_mac_speed);
468432ae724SEmmanuel Vadot 
469432ae724SEmmanuel Vadot 	DELAY(50);
470432ae724SEmmanuel Vadot 
471432ae724SEmmanuel Vadot 	return (0);
472432ae724SEmmanuel Vadot }
473432ae724SEmmanuel Vadot 
474432ae724SEmmanuel Vadot static int
475432ae724SEmmanuel Vadot if_dwc_rk_init(device_t dev)
476432ae724SEmmanuel Vadot {
477432ae724SEmmanuel Vadot 	struct if_dwc_rk_softc *sc;
478432ae724SEmmanuel Vadot 	phandle_t node;
479432ae724SEmmanuel Vadot 	uint32_t rx, tx;
480432ae724SEmmanuel Vadot 	int err;
481432ae724SEmmanuel Vadot 	pcell_t phy_handle;
482432ae724SEmmanuel Vadot 	char *clock_in_out;
483432ae724SEmmanuel Vadot 	hwreset_t phy_reset;
484432ae724SEmmanuel Vadot 	regulator_t phy_supply;
485432ae724SEmmanuel Vadot 
486432ae724SEmmanuel Vadot 	sc = device_get_softc(dev);
487432ae724SEmmanuel Vadot 	node = ofw_bus_get_node(dev);
488432ae724SEmmanuel Vadot 	sc->ops = (struct if_dwc_rk_ops *)ofw_bus_search_compatible(dev, compat_data)->ocd_data;
489432ae724SEmmanuel Vadot 	if (OF_hasprop(node, "rockchip,grf") &&
490432ae724SEmmanuel Vadot 	    syscon_get_by_ofw_property(dev, node,
491432ae724SEmmanuel Vadot 	    "rockchip,grf", &sc->grf) != 0) {
492432ae724SEmmanuel Vadot 		device_printf(dev, "cannot get grf driver handle\n");
493432ae724SEmmanuel Vadot 		return (ENXIO);
494432ae724SEmmanuel Vadot 	}
495432ae724SEmmanuel Vadot 
496432ae724SEmmanuel Vadot 	if (OF_getencprop(node, "tx_delay", &tx, sizeof(tx)) <= 0)
497432ae724SEmmanuel Vadot 		tx = 0x30;
498432ae724SEmmanuel Vadot 	if (OF_getencprop(node, "rx_delay", &rx, sizeof(rx)) <= 0)
499432ae724SEmmanuel Vadot 		rx = 0x10;
500432ae724SEmmanuel Vadot 	sc->tx_delay = tx;
501432ae724SEmmanuel Vadot 	sc->rx_delay = rx;
502432ae724SEmmanuel Vadot 
503432ae724SEmmanuel Vadot 	sc->clock_in = true;
504432ae724SEmmanuel Vadot 	if (OF_getprop_alloc(node, "clock_in_out", (void **)&clock_in_out)) {
505432ae724SEmmanuel Vadot 		if (strcmp(clock_in_out, "input") == 0)
506432ae724SEmmanuel Vadot 			sc->clock_in = true;
507432ae724SEmmanuel Vadot 		else
508432ae724SEmmanuel Vadot 			sc->clock_in = false;
509432ae724SEmmanuel Vadot 		OF_prop_free(clock_in_out);
510432ae724SEmmanuel Vadot 	}
511432ae724SEmmanuel Vadot 
512432ae724SEmmanuel Vadot 	if (OF_getencprop(node, "phy-handle", (void *)&phy_handle,
513432ae724SEmmanuel Vadot 	    sizeof(phy_handle)) > 0)
514432ae724SEmmanuel Vadot 		sc->phy_node = OF_node_from_xref(phy_handle);
515432ae724SEmmanuel Vadot 
516432ae724SEmmanuel Vadot 	if (sc->phy_node)
517432ae724SEmmanuel Vadot 		sc->integrated_phy = OF_hasprop(sc->phy_node, "phy-is-integrated");
518432ae724SEmmanuel Vadot 
519432ae724SEmmanuel Vadot 	if (sc->integrated_phy)
520432ae724SEmmanuel Vadot 		device_printf(sc->base.dev, "PHY is integrated\n");
521432ae724SEmmanuel Vadot 
522432ae724SEmmanuel Vadot 	if_dwc_rk_init_clocks(dev);
523432ae724SEmmanuel Vadot 
524432ae724SEmmanuel Vadot 	if (sc->ops->set_phy_mode)
525432ae724SEmmanuel Vadot 	    sc->ops->set_phy_mode(sc);
526432ae724SEmmanuel Vadot 
527432ae724SEmmanuel Vadot 	if (sc->ops->set_delays)
528432ae724SEmmanuel Vadot 	    sc->ops->set_delays(sc);
529432ae724SEmmanuel Vadot 
530432ae724SEmmanuel Vadot 	/*
531432ae724SEmmanuel Vadot 	 * this also sets delays if tunable is defined
532432ae724SEmmanuel Vadot 	 */
533432ae724SEmmanuel Vadot 	err = if_dwc_rk_init_sysctl(sc);
534432ae724SEmmanuel Vadot 	if (err != 0)
535432ae724SEmmanuel Vadot 		return (err);
536432ae724SEmmanuel Vadot 
537432ae724SEmmanuel Vadot 	if (regulator_get_by_ofw_property(sc->base.dev, 0,
538432ae724SEmmanuel Vadot 		            "phy-supply", &phy_supply) == 0) {
539432ae724SEmmanuel Vadot 		if (regulator_enable(phy_supply)) {
540432ae724SEmmanuel Vadot 			device_printf(sc->base.dev,
541432ae724SEmmanuel Vadot 			    "cannot enable 'phy' regulator\n");
542432ae724SEmmanuel Vadot 		}
543432ae724SEmmanuel Vadot 	}
544432ae724SEmmanuel Vadot 	else
545432ae724SEmmanuel Vadot 		device_printf(sc->base.dev, "no phy-supply property\n");
546432ae724SEmmanuel Vadot 
547432ae724SEmmanuel Vadot 	/* Power up */
548432ae724SEmmanuel Vadot 	if (sc->integrated_phy) {
549432ae724SEmmanuel Vadot 		if (sc->ops->phy_powerup)
550432ae724SEmmanuel Vadot 			sc->ops->phy_powerup(sc);
551432ae724SEmmanuel Vadot 
552432ae724SEmmanuel Vadot 		SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON0,
553432ae724SEmmanuel Vadot 		    (MACPHY_CON0_CLK_50M_MASK << 16) |
554432ae724SEmmanuel Vadot 		    MACPHY_CON0_CLK_50M);
555432ae724SEmmanuel Vadot 		SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON0,
556432ae724SEmmanuel Vadot 		    (MACPHY_CON0_RMII_MODE_MASK << 16) |
557432ae724SEmmanuel Vadot 		    MACPHY_CON0_RMII_MODE);
558432ae724SEmmanuel Vadot 		SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON2, 0xffff1234);
559432ae724SEmmanuel Vadot 		SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON3, 0x003f0035);
560432ae724SEmmanuel Vadot 
561432ae724SEmmanuel Vadot 		if (hwreset_get_by_ofw_idx(dev, sc->phy_node, 0, &phy_reset)  == 0) {
562432ae724SEmmanuel Vadot 			hwreset_assert(phy_reset);
563432ae724SEmmanuel Vadot 			DELAY(20);
564432ae724SEmmanuel Vadot 			hwreset_deassert(phy_reset);
565432ae724SEmmanuel Vadot 			DELAY(20);
566432ae724SEmmanuel Vadot 		}
567432ae724SEmmanuel Vadot 	}
568432ae724SEmmanuel Vadot 
569432ae724SEmmanuel Vadot 	return (0);
570432ae724SEmmanuel Vadot }
571432ae724SEmmanuel Vadot 
572432ae724SEmmanuel Vadot static int
573432ae724SEmmanuel Vadot if_dwc_rk_mac_type(device_t dev)
574432ae724SEmmanuel Vadot {
575432ae724SEmmanuel Vadot 
576432ae724SEmmanuel Vadot 	return (DWC_GMAC_NORMAL_DESC);
577432ae724SEmmanuel Vadot }
578432ae724SEmmanuel Vadot 
579432ae724SEmmanuel Vadot static int
580432ae724SEmmanuel Vadot if_dwc_rk_mii_clk(device_t dev)
581432ae724SEmmanuel Vadot {
582432ae724SEmmanuel Vadot 
583432ae724SEmmanuel Vadot 	/* Should be calculated from the clock */
584432ae724SEmmanuel Vadot 	return (GMAC_MII_CLK_150_250M_DIV102);
585432ae724SEmmanuel Vadot }
586432ae724SEmmanuel Vadot 
587432ae724SEmmanuel Vadot static int
588432ae724SEmmanuel Vadot if_dwc_rk_set_speed(device_t dev, int speed)
589432ae724SEmmanuel Vadot {
590432ae724SEmmanuel Vadot 	struct if_dwc_rk_softc *sc;
591432ae724SEmmanuel Vadot 
592432ae724SEmmanuel Vadot 	sc = device_get_softc(dev);
593432ae724SEmmanuel Vadot 
594432ae724SEmmanuel Vadot 	if (sc->ops->set_speed)
595432ae724SEmmanuel Vadot 	    return sc->ops->set_speed(sc, speed);
596432ae724SEmmanuel Vadot 
597432ae724SEmmanuel Vadot 	return (0);
598432ae724SEmmanuel Vadot }
599432ae724SEmmanuel Vadot 
600432ae724SEmmanuel Vadot static device_method_t if_dwc_rk_methods[] = {
601432ae724SEmmanuel Vadot 	DEVMETHOD(device_probe,		if_dwc_rk_probe),
602432ae724SEmmanuel Vadot 
603432ae724SEmmanuel Vadot 	DEVMETHOD(if_dwc_init,		if_dwc_rk_init),
604432ae724SEmmanuel Vadot 	DEVMETHOD(if_dwc_mac_type,	if_dwc_rk_mac_type),
605432ae724SEmmanuel Vadot 	DEVMETHOD(if_dwc_mii_clk,	if_dwc_rk_mii_clk),
606432ae724SEmmanuel Vadot 	DEVMETHOD(if_dwc_set_speed,	if_dwc_rk_set_speed),
607432ae724SEmmanuel Vadot 
608432ae724SEmmanuel Vadot 	DEVMETHOD_END
609432ae724SEmmanuel Vadot };
610432ae724SEmmanuel Vadot 
611432ae724SEmmanuel Vadot extern driver_t dwc_driver;
612432ae724SEmmanuel Vadot 
613432ae724SEmmanuel Vadot DEFINE_CLASS_1(dwc, dwc_rk_driver, if_dwc_rk_methods,
614432ae724SEmmanuel Vadot     sizeof(struct if_dwc_rk_softc), dwc_driver);
615432ae724SEmmanuel Vadot DRIVER_MODULE(dwc_rk, simplebus, dwc_rk_driver, 0, 0);
616432ae724SEmmanuel Vadot MODULE_DEPEND(dwc_rk, dwc, 1, 1, 1);
617