xref: /freebsd/sys/dev/dwc/if_dwc_rk.c (revision 432ae724e6ebac4696a7baf5020e2445db06dc2f)
1*432ae724SEmmanuel Vadot /*-
2*432ae724SEmmanuel Vadot  * SPDX-License-Identifier: BSD-2-Clause
3*432ae724SEmmanuel Vadot  *
4*432ae724SEmmanuel Vadot  * Copyright (c) 2018 Emmanuel Vadot <manu@freebsd.org>
5*432ae724SEmmanuel Vadot  *
6*432ae724SEmmanuel Vadot  * Redistribution and use in source and binary forms, with or without
7*432ae724SEmmanuel Vadot  * modification, are permitted provided that the following conditions
8*432ae724SEmmanuel Vadot  * are met:
9*432ae724SEmmanuel Vadot  * 1. Redistributions of source code must retain the above copyright
10*432ae724SEmmanuel Vadot  *    notice, this list of conditions and the following disclaimer.
11*432ae724SEmmanuel Vadot  * 2. Redistributions in binary form must reproduce the above copyright
12*432ae724SEmmanuel Vadot  *    notice, this list of conditions and the following disclaimer in the
13*432ae724SEmmanuel Vadot  *    documentation and/or other materials provided with the distribution.
14*432ae724SEmmanuel Vadot  *
15*432ae724SEmmanuel Vadot  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16*432ae724SEmmanuel Vadot  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17*432ae724SEmmanuel Vadot  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18*432ae724SEmmanuel Vadot  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19*432ae724SEmmanuel Vadot  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20*432ae724SEmmanuel Vadot  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21*432ae724SEmmanuel Vadot  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22*432ae724SEmmanuel Vadot  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23*432ae724SEmmanuel Vadot  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24*432ae724SEmmanuel Vadot  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25*432ae724SEmmanuel Vadot  * SUCH DAMAGE.
26*432ae724SEmmanuel Vadot */
27*432ae724SEmmanuel Vadot 
28*432ae724SEmmanuel Vadot #include <sys/cdefs.h>
29*432ae724SEmmanuel Vadot #include <sys/param.h>
30*432ae724SEmmanuel Vadot #include <sys/systm.h>
31*432ae724SEmmanuel Vadot #include <sys/bus.h>
32*432ae724SEmmanuel Vadot #include <sys/kernel.h>
33*432ae724SEmmanuel Vadot #include <sys/module.h>
34*432ae724SEmmanuel Vadot #include <sys/socket.h>
35*432ae724SEmmanuel Vadot 
36*432ae724SEmmanuel Vadot #include <machine/bus.h>
37*432ae724SEmmanuel Vadot 
38*432ae724SEmmanuel Vadot #include <net/if.h>
39*432ae724SEmmanuel Vadot #include <net/if_media.h>
40*432ae724SEmmanuel Vadot 
41*432ae724SEmmanuel Vadot #include <dev/dwc/if_dwc.h>
42*432ae724SEmmanuel Vadot #include <dev/dwc/if_dwcvar.h>
43*432ae724SEmmanuel Vadot #include <dev/ofw/ofw_bus.h>
44*432ae724SEmmanuel Vadot #include <dev/ofw/ofw_bus_subr.h>
45*432ae724SEmmanuel Vadot 
46*432ae724SEmmanuel Vadot #include <dev/extres/clk/clk.h>
47*432ae724SEmmanuel Vadot #include <dev/extres/hwreset/hwreset.h>
48*432ae724SEmmanuel Vadot #include <dev/extres/regulator/regulator.h>
49*432ae724SEmmanuel Vadot #include <dev/extres/syscon/syscon.h>
50*432ae724SEmmanuel Vadot 
51*432ae724SEmmanuel Vadot #include "if_dwc_if.h"
52*432ae724SEmmanuel Vadot #include "syscon_if.h"
53*432ae724SEmmanuel Vadot 
54*432ae724SEmmanuel Vadot #define	RK3328_GRF_MAC_CON0		0x0900
55*432ae724SEmmanuel Vadot #define	 MAC_CON0_GMAC2IO_TX_DL_CFG_MASK	0x7F
56*432ae724SEmmanuel Vadot #define	 MAC_CON0_GMAC2IO_TX_DL_CFG_SHIFT	0
57*432ae724SEmmanuel Vadot #define	 MAC_CON0_GMAC2IO_RX_DL_CFG_MASK	0x7F
58*432ae724SEmmanuel Vadot #define	 MAC_CON0_GMAC2IO_RX_DL_CFG_SHIFT	7
59*432ae724SEmmanuel Vadot 
60*432ae724SEmmanuel Vadot #define	RK3328_GRF_MAC_CON1		0x0904
61*432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA	(1 << 0)
62*432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA	(1 << 1)
63*432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_GMII_CLK_SEL_MASK	(3 << 11)
64*432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_GMII_CLK_SEL_125	(0 << 11)
65*432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_GMII_CLK_SEL_25	(3 << 11)
66*432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_GMII_CLK_SEL_2_5	(2 << 11)
67*432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_RMII_MODE_MASK	(1 << 9)
68*432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_RMII_MODE		(1 << 9)
69*432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_INTF_SEL_MASK		(7 << 4)
70*432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_INTF_RMII		(4 << 4)
71*432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_INTF_RGMII		(1 << 4)
72*432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_RMII_CLK_SEL_MASK	(1 << 7)
73*432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_RMII_CLK_SEL_25	(1 << 7)
74*432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_RMII_CLK_SEL_2_5	(0 << 7)
75*432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_MAC_SPEED_MASK	(1 << 2)
76*432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_MAC_SPEED_100		(1 << 2)
77*432ae724SEmmanuel Vadot #define	 MAC_CON1_GMAC2IO_MAC_SPEED_10		(0 << 2)
78*432ae724SEmmanuel Vadot #define	RK3328_GRF_MAC_CON2		0x0908
79*432ae724SEmmanuel Vadot #define	RK3328_GRF_MACPHY_CON0		0x0B00
80*432ae724SEmmanuel Vadot #define	 MACPHY_CON0_CLK_50M_MASK		(1 << 14)
81*432ae724SEmmanuel Vadot #define	 MACPHY_CON0_CLK_50M			(1 << 14)
82*432ae724SEmmanuel Vadot #define	 MACPHY_CON0_RMII_MODE_MASK		(3 << 6)
83*432ae724SEmmanuel Vadot #define	 MACPHY_CON0_RMII_MODE			(1 << 6)
84*432ae724SEmmanuel Vadot #define	RK3328_GRF_MACPHY_CON1		0x0B04
85*432ae724SEmmanuel Vadot #define	 MACPHY_CON1_RMII_MODE_MASK		(1 << 9)
86*432ae724SEmmanuel Vadot #define	 MACPHY_CON1_RMII_MODE			(1 << 9)
87*432ae724SEmmanuel Vadot #define	RK3328_GRF_MACPHY_CON2		0x0B08
88*432ae724SEmmanuel Vadot #define	RK3328_GRF_MACPHY_CON3		0x0B0C
89*432ae724SEmmanuel Vadot #define	RK3328_GRF_MACPHY_STATUS	0x0B10
90*432ae724SEmmanuel Vadot 
91*432ae724SEmmanuel Vadot #define	RK3399_GRF_SOC_CON5		0xc214
92*432ae724SEmmanuel Vadot #define	 SOC_CON5_GMAC_CLK_SEL_MASK		(3 << 4)
93*432ae724SEmmanuel Vadot #define	 SOC_CON5_GMAC_CLK_SEL_125		(0 << 4)
94*432ae724SEmmanuel Vadot #define	 SOC_CON5_GMAC_CLK_SEL_25		(3 << 4)
95*432ae724SEmmanuel Vadot #define	 SOC_CON5_GMAC_CLK_SEL_2_5		(2 << 4)
96*432ae724SEmmanuel Vadot #define	RK3399_GRF_SOC_CON6		0xc218
97*432ae724SEmmanuel Vadot #define	 SOC_CON6_GMAC_TXCLK_DLY_ENA		(1 << 7)
98*432ae724SEmmanuel Vadot #define	 SOC_CON6_TX_DL_CFG_MASK		0x7F
99*432ae724SEmmanuel Vadot #define	 SOC_CON6_TX_DL_CFG_SHIFT		0
100*432ae724SEmmanuel Vadot #define	 SOC_CON6_RX_DL_CFG_MASK		0x7F
101*432ae724SEmmanuel Vadot #define	 SOC_CON6_GMAC_RXCLK_DLY_ENA		(1 << 15)
102*432ae724SEmmanuel Vadot #define	 SOC_CON6_RX_DL_CFG_SHIFT		8
103*432ae724SEmmanuel Vadot 
104*432ae724SEmmanuel Vadot struct if_dwc_rk_softc;
105*432ae724SEmmanuel Vadot 
106*432ae724SEmmanuel Vadot typedef void (*if_dwc_rk_set_delaysfn_t)(struct if_dwc_rk_softc *);
107*432ae724SEmmanuel Vadot typedef int (*if_dwc_rk_set_speedfn_t)(struct if_dwc_rk_softc *, int);
108*432ae724SEmmanuel Vadot typedef void (*if_dwc_rk_set_phy_modefn_t)(struct if_dwc_rk_softc *);
109*432ae724SEmmanuel Vadot typedef void (*if_dwc_rk_phy_powerupfn_t)(struct if_dwc_rk_softc *);
110*432ae724SEmmanuel Vadot 
111*432ae724SEmmanuel Vadot struct if_dwc_rk_ops {
112*432ae724SEmmanuel Vadot 	if_dwc_rk_set_delaysfn_t	set_delays;
113*432ae724SEmmanuel Vadot 	if_dwc_rk_set_speedfn_t		set_speed;
114*432ae724SEmmanuel Vadot 	if_dwc_rk_set_phy_modefn_t	set_phy_mode;
115*432ae724SEmmanuel Vadot 	if_dwc_rk_phy_powerupfn_t	phy_powerup;
116*432ae724SEmmanuel Vadot };
117*432ae724SEmmanuel Vadot 
118*432ae724SEmmanuel Vadot struct if_dwc_rk_softc {
119*432ae724SEmmanuel Vadot 	struct dwc_softc	base;
120*432ae724SEmmanuel Vadot 	uint32_t		tx_delay;
121*432ae724SEmmanuel Vadot 	uint32_t		rx_delay;
122*432ae724SEmmanuel Vadot 	bool			integrated_phy;
123*432ae724SEmmanuel Vadot 	bool			clock_in;
124*432ae724SEmmanuel Vadot 	phandle_t		phy_node;
125*432ae724SEmmanuel Vadot 	struct syscon		*grf;
126*432ae724SEmmanuel Vadot 	struct if_dwc_rk_ops	*ops;
127*432ae724SEmmanuel Vadot 	/* Common clocks */
128*432ae724SEmmanuel Vadot 	clk_t			mac_clk_rx;
129*432ae724SEmmanuel Vadot 	clk_t			mac_clk_tx;
130*432ae724SEmmanuel Vadot 	clk_t			aclk_mac;
131*432ae724SEmmanuel Vadot 	clk_t			pclk_mac;
132*432ae724SEmmanuel Vadot 	clk_t			clk_stmmaceth;
133*432ae724SEmmanuel Vadot 	/* RMII clocks */
134*432ae724SEmmanuel Vadot 	clk_t			clk_mac_ref;
135*432ae724SEmmanuel Vadot 	clk_t			clk_mac_refout;
136*432ae724SEmmanuel Vadot 	/* PHY clock */
137*432ae724SEmmanuel Vadot 	clk_t			clk_phy;
138*432ae724SEmmanuel Vadot };
139*432ae724SEmmanuel Vadot 
140*432ae724SEmmanuel Vadot static void rk3328_set_delays(struct if_dwc_rk_softc *sc);
141*432ae724SEmmanuel Vadot static int rk3328_set_speed(struct if_dwc_rk_softc *sc, int speed);
142*432ae724SEmmanuel Vadot static void rk3328_set_phy_mode(struct if_dwc_rk_softc *sc);
143*432ae724SEmmanuel Vadot static void rk3328_phy_powerup(struct if_dwc_rk_softc *sc);
144*432ae724SEmmanuel Vadot 
145*432ae724SEmmanuel Vadot static void rk3399_set_delays(struct if_dwc_rk_softc *sc);
146*432ae724SEmmanuel Vadot static int rk3399_set_speed(struct if_dwc_rk_softc *sc, int speed);
147*432ae724SEmmanuel Vadot 
148*432ae724SEmmanuel Vadot static struct if_dwc_rk_ops rk3288_ops = {
149*432ae724SEmmanuel Vadot };
150*432ae724SEmmanuel Vadot 
151*432ae724SEmmanuel Vadot static struct if_dwc_rk_ops rk3328_ops = {
152*432ae724SEmmanuel Vadot 	.set_delays = rk3328_set_delays,
153*432ae724SEmmanuel Vadot 	.set_speed = rk3328_set_speed,
154*432ae724SEmmanuel Vadot 	.set_phy_mode = rk3328_set_phy_mode,
155*432ae724SEmmanuel Vadot 	.phy_powerup = rk3328_phy_powerup,
156*432ae724SEmmanuel Vadot };
157*432ae724SEmmanuel Vadot 
158*432ae724SEmmanuel Vadot static struct if_dwc_rk_ops rk3399_ops = {
159*432ae724SEmmanuel Vadot 	.set_delays = rk3399_set_delays,
160*432ae724SEmmanuel Vadot 	.set_speed = rk3399_set_speed,
161*432ae724SEmmanuel Vadot };
162*432ae724SEmmanuel Vadot 
163*432ae724SEmmanuel Vadot static struct ofw_compat_data compat_data[] = {
164*432ae724SEmmanuel Vadot 	{"rockchip,rk3288-gmac", (uintptr_t)&rk3288_ops},
165*432ae724SEmmanuel Vadot 	{"rockchip,rk3328-gmac", (uintptr_t)&rk3328_ops},
166*432ae724SEmmanuel Vadot 	{"rockchip,rk3399-gmac", (uintptr_t)&rk3399_ops},
167*432ae724SEmmanuel Vadot 	{NULL,			 0}
168*432ae724SEmmanuel Vadot };
169*432ae724SEmmanuel Vadot 
170*432ae724SEmmanuel Vadot static void
171*432ae724SEmmanuel Vadot rk3328_set_delays(struct if_dwc_rk_softc *sc)
172*432ae724SEmmanuel Vadot {
173*432ae724SEmmanuel Vadot 	uint32_t reg;
174*432ae724SEmmanuel Vadot 	uint32_t tx, rx;
175*432ae724SEmmanuel Vadot 
176*432ae724SEmmanuel Vadot 	if (sc->base.phy_mode != PHY_MODE_RGMII)
177*432ae724SEmmanuel Vadot 		return;
178*432ae724SEmmanuel Vadot 
179*432ae724SEmmanuel Vadot 	reg = SYSCON_READ_4(sc->grf, RK3328_GRF_MAC_CON0);
180*432ae724SEmmanuel Vadot 	tx = ((reg >> MAC_CON0_GMAC2IO_TX_DL_CFG_SHIFT) & MAC_CON0_GMAC2IO_TX_DL_CFG_MASK);
181*432ae724SEmmanuel Vadot 	rx = ((reg >> MAC_CON0_GMAC2IO_RX_DL_CFG_SHIFT) & MAC_CON0_GMAC2IO_RX_DL_CFG_MASK);
182*432ae724SEmmanuel Vadot 
183*432ae724SEmmanuel Vadot 	reg = SYSCON_READ_4(sc->grf, RK3328_GRF_MAC_CON1);
184*432ae724SEmmanuel Vadot 	if (bootverbose) {
185*432ae724SEmmanuel Vadot 		device_printf(sc->base.dev, "current delays settings: tx=%u(%s) rx=%u(%s)\n",
186*432ae724SEmmanuel Vadot 		    tx, ((reg & MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA) ? "enabled" : "disabled"),
187*432ae724SEmmanuel Vadot 		    rx, ((reg & MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA) ? "enabled" : "disabled"));
188*432ae724SEmmanuel Vadot 
189*432ae724SEmmanuel Vadot 		device_printf(sc->base.dev, "setting new RK3328 RX/TX delays:  %d/%d\n",
190*432ae724SEmmanuel Vadot 			sc->tx_delay, sc->rx_delay);
191*432ae724SEmmanuel Vadot 	}
192*432ae724SEmmanuel Vadot 
193*432ae724SEmmanuel Vadot 	reg = (MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA | MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA) << 16;
194*432ae724SEmmanuel Vadot 	reg |= (MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA | MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA);
195*432ae724SEmmanuel Vadot 	SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON1, reg);
196*432ae724SEmmanuel Vadot 
197*432ae724SEmmanuel Vadot 	reg = 0xffff << 16;
198*432ae724SEmmanuel Vadot 	reg |= ((sc->tx_delay & MAC_CON0_GMAC2IO_TX_DL_CFG_MASK) <<
199*432ae724SEmmanuel Vadot 	    MAC_CON0_GMAC2IO_TX_DL_CFG_SHIFT);
200*432ae724SEmmanuel Vadot 	reg |= ((sc->rx_delay & MAC_CON0_GMAC2IO_TX_DL_CFG_MASK) <<
201*432ae724SEmmanuel Vadot 	    MAC_CON0_GMAC2IO_RX_DL_CFG_SHIFT);
202*432ae724SEmmanuel Vadot 	SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON0, reg);
203*432ae724SEmmanuel Vadot }
204*432ae724SEmmanuel Vadot 
205*432ae724SEmmanuel Vadot static int
206*432ae724SEmmanuel Vadot rk3328_set_speed(struct if_dwc_rk_softc *sc, int speed)
207*432ae724SEmmanuel Vadot {
208*432ae724SEmmanuel Vadot 	uint32_t reg;
209*432ae724SEmmanuel Vadot 
210*432ae724SEmmanuel Vadot 	switch (sc->base.phy_mode) {
211*432ae724SEmmanuel Vadot 	case PHY_MODE_RGMII:
212*432ae724SEmmanuel Vadot 		switch (speed) {
213*432ae724SEmmanuel Vadot 		case IFM_1000_T:
214*432ae724SEmmanuel Vadot 		case IFM_1000_SX:
215*432ae724SEmmanuel Vadot 			reg = MAC_CON1_GMAC2IO_GMII_CLK_SEL_125;
216*432ae724SEmmanuel Vadot 			break;
217*432ae724SEmmanuel Vadot 		case IFM_100_TX:
218*432ae724SEmmanuel Vadot 			reg = MAC_CON1_GMAC2IO_GMII_CLK_SEL_25;
219*432ae724SEmmanuel Vadot 			break;
220*432ae724SEmmanuel Vadot 		case IFM_10_T:
221*432ae724SEmmanuel Vadot 			reg = MAC_CON1_GMAC2IO_GMII_CLK_SEL_2_5;
222*432ae724SEmmanuel Vadot 			break;
223*432ae724SEmmanuel Vadot 		default:
224*432ae724SEmmanuel Vadot 			device_printf(sc->base.dev, "unsupported RGMII media %u\n", speed);
225*432ae724SEmmanuel Vadot 			return (-1);
226*432ae724SEmmanuel Vadot 		}
227*432ae724SEmmanuel Vadot 
228*432ae724SEmmanuel Vadot 		SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON1,
229*432ae724SEmmanuel Vadot 		    ((MAC_CON1_GMAC2IO_GMII_CLK_SEL_MASK << 16) | reg));
230*432ae724SEmmanuel Vadot 		break;
231*432ae724SEmmanuel Vadot 	case PHY_MODE_RMII:
232*432ae724SEmmanuel Vadot 		switch (speed) {
233*432ae724SEmmanuel Vadot 		case IFM_100_TX:
234*432ae724SEmmanuel Vadot 			reg = MAC_CON1_GMAC2IO_RMII_CLK_SEL_25 |
235*432ae724SEmmanuel Vadot 			    MAC_CON1_GMAC2IO_MAC_SPEED_100;
236*432ae724SEmmanuel Vadot 			break;
237*432ae724SEmmanuel Vadot 		case IFM_10_T:
238*432ae724SEmmanuel Vadot 			reg = MAC_CON1_GMAC2IO_RMII_CLK_SEL_2_5 |
239*432ae724SEmmanuel Vadot 			    MAC_CON1_GMAC2IO_MAC_SPEED_10;
240*432ae724SEmmanuel Vadot 			break;
241*432ae724SEmmanuel Vadot 		default:
242*432ae724SEmmanuel Vadot 			device_printf(sc->base.dev, "unsupported RMII media %u\n", speed);
243*432ae724SEmmanuel Vadot 			return (-1);
244*432ae724SEmmanuel Vadot 		}
245*432ae724SEmmanuel Vadot 
246*432ae724SEmmanuel Vadot 		SYSCON_WRITE_4(sc->grf,
247*432ae724SEmmanuel Vadot 		    sc->integrated_phy ? RK3328_GRF_MAC_CON2 : RK3328_GRF_MAC_CON1,
248*432ae724SEmmanuel Vadot 		    reg |
249*432ae724SEmmanuel Vadot 		    ((MAC_CON1_GMAC2IO_RMII_CLK_SEL_MASK | MAC_CON1_GMAC2IO_MAC_SPEED_MASK) << 16));
250*432ae724SEmmanuel Vadot 		break;
251*432ae724SEmmanuel Vadot 	}
252*432ae724SEmmanuel Vadot 
253*432ae724SEmmanuel Vadot 	return (0);
254*432ae724SEmmanuel Vadot }
255*432ae724SEmmanuel Vadot 
256*432ae724SEmmanuel Vadot static void
257*432ae724SEmmanuel Vadot rk3328_set_phy_mode(struct if_dwc_rk_softc *sc)
258*432ae724SEmmanuel Vadot {
259*432ae724SEmmanuel Vadot 
260*432ae724SEmmanuel Vadot 	switch (sc->base.phy_mode) {
261*432ae724SEmmanuel Vadot 	case PHY_MODE_RGMII:
262*432ae724SEmmanuel Vadot 		SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON1,
263*432ae724SEmmanuel Vadot 		    ((MAC_CON1_GMAC2IO_INTF_SEL_MASK | MAC_CON1_GMAC2IO_RMII_MODE_MASK) << 16) |
264*432ae724SEmmanuel Vadot 		    MAC_CON1_GMAC2IO_INTF_RGMII);
265*432ae724SEmmanuel Vadot 		break;
266*432ae724SEmmanuel Vadot 	case PHY_MODE_RMII:
267*432ae724SEmmanuel Vadot 		SYSCON_WRITE_4(sc->grf, sc->integrated_phy ? RK3328_GRF_MAC_CON2 : RK3328_GRF_MAC_CON1,
268*432ae724SEmmanuel Vadot 		    ((MAC_CON1_GMAC2IO_INTF_SEL_MASK | MAC_CON1_GMAC2IO_RMII_MODE_MASK) << 16) |
269*432ae724SEmmanuel Vadot 		    MAC_CON1_GMAC2IO_INTF_RMII | MAC_CON1_GMAC2IO_RMII_MODE);
270*432ae724SEmmanuel Vadot 		break;
271*432ae724SEmmanuel Vadot 	}
272*432ae724SEmmanuel Vadot }
273*432ae724SEmmanuel Vadot 
274*432ae724SEmmanuel Vadot static void
275*432ae724SEmmanuel Vadot rk3328_phy_powerup(struct if_dwc_rk_softc *sc)
276*432ae724SEmmanuel Vadot {
277*432ae724SEmmanuel Vadot 	SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON1,
278*432ae724SEmmanuel Vadot 	    (MACPHY_CON1_RMII_MODE_MASK << 16) |
279*432ae724SEmmanuel Vadot 	    MACPHY_CON1_RMII_MODE);
280*432ae724SEmmanuel Vadot }
281*432ae724SEmmanuel Vadot 
282*432ae724SEmmanuel Vadot static void
283*432ae724SEmmanuel Vadot rk3399_set_delays(struct if_dwc_rk_softc *sc)
284*432ae724SEmmanuel Vadot {
285*432ae724SEmmanuel Vadot 	uint32_t reg, tx, rx;
286*432ae724SEmmanuel Vadot 
287*432ae724SEmmanuel Vadot 	if (sc->base.phy_mode != PHY_MODE_RGMII)
288*432ae724SEmmanuel Vadot 		return;
289*432ae724SEmmanuel Vadot 
290*432ae724SEmmanuel Vadot 	reg = SYSCON_READ_4(sc->grf, RK3399_GRF_SOC_CON6);
291*432ae724SEmmanuel Vadot 	tx = ((reg >> SOC_CON6_TX_DL_CFG_SHIFT) & SOC_CON6_TX_DL_CFG_MASK);
292*432ae724SEmmanuel Vadot 	rx = ((reg >> SOC_CON6_RX_DL_CFG_SHIFT) & SOC_CON6_RX_DL_CFG_MASK);
293*432ae724SEmmanuel Vadot 
294*432ae724SEmmanuel Vadot 	if (bootverbose) {
295*432ae724SEmmanuel Vadot 		device_printf(sc->base.dev, "current delays settings: tx=%u(%s) rx=%u(%s)\n",
296*432ae724SEmmanuel Vadot 		    tx, ((reg & SOC_CON6_GMAC_TXCLK_DLY_ENA) ? "enabled" : "disabled"),
297*432ae724SEmmanuel Vadot 		    rx, ((reg & SOC_CON6_GMAC_RXCLK_DLY_ENA) ? "enabled" : "disabled"));
298*432ae724SEmmanuel Vadot 
299*432ae724SEmmanuel Vadot 		device_printf(sc->base.dev, "setting new RK3399 RX/TX delays:  %d/%d\n",
300*432ae724SEmmanuel Vadot 		    sc->rx_delay, sc->tx_delay);
301*432ae724SEmmanuel Vadot 	}
302*432ae724SEmmanuel Vadot 
303*432ae724SEmmanuel Vadot 	reg = 0xFFFF << 16;
304*432ae724SEmmanuel Vadot 	reg |= ((sc->tx_delay & SOC_CON6_TX_DL_CFG_MASK) <<
305*432ae724SEmmanuel Vadot 	    SOC_CON6_TX_DL_CFG_SHIFT);
306*432ae724SEmmanuel Vadot 	reg |= ((sc->rx_delay & SOC_CON6_RX_DL_CFG_MASK) <<
307*432ae724SEmmanuel Vadot 	    SOC_CON6_RX_DL_CFG_SHIFT);
308*432ae724SEmmanuel Vadot 	reg |= SOC_CON6_GMAC_TXCLK_DLY_ENA | SOC_CON6_GMAC_RXCLK_DLY_ENA;
309*432ae724SEmmanuel Vadot 
310*432ae724SEmmanuel Vadot 	SYSCON_WRITE_4(sc->grf, RK3399_GRF_SOC_CON6, reg);
311*432ae724SEmmanuel Vadot }
312*432ae724SEmmanuel Vadot 
313*432ae724SEmmanuel Vadot static int
314*432ae724SEmmanuel Vadot rk3399_set_speed(struct if_dwc_rk_softc *sc, int speed)
315*432ae724SEmmanuel Vadot {
316*432ae724SEmmanuel Vadot 	uint32_t reg;
317*432ae724SEmmanuel Vadot 
318*432ae724SEmmanuel Vadot 	switch (speed) {
319*432ae724SEmmanuel Vadot 	case IFM_1000_T:
320*432ae724SEmmanuel Vadot 	case IFM_1000_SX:
321*432ae724SEmmanuel Vadot 		reg = SOC_CON5_GMAC_CLK_SEL_125;
322*432ae724SEmmanuel Vadot 		break;
323*432ae724SEmmanuel Vadot 	case IFM_100_TX:
324*432ae724SEmmanuel Vadot 		reg = SOC_CON5_GMAC_CLK_SEL_25;
325*432ae724SEmmanuel Vadot 		break;
326*432ae724SEmmanuel Vadot 	case IFM_10_T:
327*432ae724SEmmanuel Vadot 		reg = SOC_CON5_GMAC_CLK_SEL_2_5;
328*432ae724SEmmanuel Vadot 		break;
329*432ae724SEmmanuel Vadot 	default:
330*432ae724SEmmanuel Vadot 		device_printf(sc->base.dev, "unsupported media %u\n", speed);
331*432ae724SEmmanuel Vadot 		return (-1);
332*432ae724SEmmanuel Vadot 	}
333*432ae724SEmmanuel Vadot 
334*432ae724SEmmanuel Vadot 	SYSCON_WRITE_4(sc->grf, RK3399_GRF_SOC_CON5,
335*432ae724SEmmanuel Vadot 	    ((SOC_CON5_GMAC_CLK_SEL_MASK << 16) | reg));
336*432ae724SEmmanuel Vadot 	return (0);
337*432ae724SEmmanuel Vadot }
338*432ae724SEmmanuel Vadot 
339*432ae724SEmmanuel Vadot static int
340*432ae724SEmmanuel Vadot if_dwc_rk_sysctl_delays(SYSCTL_HANDLER_ARGS)
341*432ae724SEmmanuel Vadot {
342*432ae724SEmmanuel Vadot 	struct if_dwc_rk_softc *sc;
343*432ae724SEmmanuel Vadot 	int rv;
344*432ae724SEmmanuel Vadot 	uint32_t rxtx;
345*432ae724SEmmanuel Vadot 
346*432ae724SEmmanuel Vadot 	sc = arg1;
347*432ae724SEmmanuel Vadot 	rxtx = ((sc->rx_delay << 8) | sc->tx_delay);
348*432ae724SEmmanuel Vadot 
349*432ae724SEmmanuel Vadot 	rv = sysctl_handle_int(oidp, &rxtx, 0, req);
350*432ae724SEmmanuel Vadot 	if (rv != 0 || req->newptr == NULL)
351*432ae724SEmmanuel Vadot 		return (rv);
352*432ae724SEmmanuel Vadot 	sc->tx_delay = rxtx & 0xff;
353*432ae724SEmmanuel Vadot 	sc->rx_delay = (rxtx >> 8) & 0xff;
354*432ae724SEmmanuel Vadot 
355*432ae724SEmmanuel Vadot 	if (sc->ops->set_delays)
356*432ae724SEmmanuel Vadot 	    sc->ops->set_delays(sc);
357*432ae724SEmmanuel Vadot 
358*432ae724SEmmanuel Vadot 	return (0);
359*432ae724SEmmanuel Vadot }
360*432ae724SEmmanuel Vadot 
361*432ae724SEmmanuel Vadot static int
362*432ae724SEmmanuel Vadot if_dwc_rk_init_sysctl(struct if_dwc_rk_softc *sc)
363*432ae724SEmmanuel Vadot {
364*432ae724SEmmanuel Vadot 	struct sysctl_oid *child;
365*432ae724SEmmanuel Vadot 	struct sysctl_ctx_list *ctx_list;
366*432ae724SEmmanuel Vadot 
367*432ae724SEmmanuel Vadot 	ctx_list = device_get_sysctl_ctx(sc->base.dev);
368*432ae724SEmmanuel Vadot 	child = device_get_sysctl_tree(sc->base.dev);
369*432ae724SEmmanuel Vadot 	SYSCTL_ADD_PROC(ctx_list,
370*432ae724SEmmanuel Vadot 	    SYSCTL_CHILDREN(child), OID_AUTO, "delays",
371*432ae724SEmmanuel Vadot 	    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, sc, 0,
372*432ae724SEmmanuel Vadot 	    if_dwc_rk_sysctl_delays, "", "RGMII RX/TX delays: ((rx << 8) | tx)");
373*432ae724SEmmanuel Vadot 
374*432ae724SEmmanuel Vadot 	return (0);
375*432ae724SEmmanuel Vadot }
376*432ae724SEmmanuel Vadot 
377*432ae724SEmmanuel Vadot static int
378*432ae724SEmmanuel Vadot if_dwc_rk_probe(device_t dev)
379*432ae724SEmmanuel Vadot {
380*432ae724SEmmanuel Vadot 
381*432ae724SEmmanuel Vadot 	if (!ofw_bus_status_okay(dev))
382*432ae724SEmmanuel Vadot 		return (ENXIO);
383*432ae724SEmmanuel Vadot 	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
384*432ae724SEmmanuel Vadot 		return (ENXIO);
385*432ae724SEmmanuel Vadot 	device_set_desc(dev, "Rockchip Gigabit Ethernet Controller");
386*432ae724SEmmanuel Vadot 
387*432ae724SEmmanuel Vadot 	return (BUS_PROBE_DEFAULT);
388*432ae724SEmmanuel Vadot }
389*432ae724SEmmanuel Vadot 
390*432ae724SEmmanuel Vadot static int
391*432ae724SEmmanuel Vadot if_dwc_rk_init_clocks(device_t dev)
392*432ae724SEmmanuel Vadot {
393*432ae724SEmmanuel Vadot 	struct if_dwc_rk_softc *sc;
394*432ae724SEmmanuel Vadot 	int error;
395*432ae724SEmmanuel Vadot 
396*432ae724SEmmanuel Vadot 	sc = device_get_softc(dev);
397*432ae724SEmmanuel Vadot 	error = clk_set_assigned(dev, ofw_bus_get_node(dev));
398*432ae724SEmmanuel Vadot 	if (error != 0) {
399*432ae724SEmmanuel Vadot 		device_printf(dev, "clk_set_assigned failed\n");
400*432ae724SEmmanuel Vadot 		return (error);
401*432ae724SEmmanuel Vadot 	}
402*432ae724SEmmanuel Vadot 
403*432ae724SEmmanuel Vadot 	/* Enable clocks */
404*432ae724SEmmanuel Vadot 	error = clk_get_by_ofw_name(dev, 0, "stmmaceth", &sc->clk_stmmaceth);
405*432ae724SEmmanuel Vadot 	if (error != 0) {
406*432ae724SEmmanuel Vadot 		device_printf(dev, "could not find clock stmmaceth\n");
407*432ae724SEmmanuel Vadot 		return (error);
408*432ae724SEmmanuel Vadot 	}
409*432ae724SEmmanuel Vadot 
410*432ae724SEmmanuel Vadot 	if (clk_get_by_ofw_name(dev, 0, "mac_clk_rx", &sc->mac_clk_rx) != 0) {
411*432ae724SEmmanuel Vadot 		device_printf(sc->base.dev, "could not get mac_clk_rx clock\n");
412*432ae724SEmmanuel Vadot 		sc->mac_clk_rx = NULL;
413*432ae724SEmmanuel Vadot 	}
414*432ae724SEmmanuel Vadot 
415*432ae724SEmmanuel Vadot 	if (clk_get_by_ofw_name(dev, 0, "mac_clk_tx", &sc->mac_clk_tx) != 0) {
416*432ae724SEmmanuel Vadot 		device_printf(sc->base.dev, "could not get mac_clk_tx clock\n");
417*432ae724SEmmanuel Vadot 		sc->mac_clk_tx = NULL;
418*432ae724SEmmanuel Vadot 	}
419*432ae724SEmmanuel Vadot 
420*432ae724SEmmanuel Vadot 	if (clk_get_by_ofw_name(dev, 0, "aclk_mac", &sc->aclk_mac) != 0) {
421*432ae724SEmmanuel Vadot 		device_printf(sc->base.dev, "could not get aclk_mac clock\n");
422*432ae724SEmmanuel Vadot 		sc->aclk_mac = NULL;
423*432ae724SEmmanuel Vadot 	}
424*432ae724SEmmanuel Vadot 
425*432ae724SEmmanuel Vadot 	if (clk_get_by_ofw_name(dev, 0, "pclk_mac", &sc->pclk_mac) != 0) {
426*432ae724SEmmanuel Vadot 		device_printf(sc->base.dev, "could not get pclk_mac clock\n");
427*432ae724SEmmanuel Vadot 		sc->pclk_mac = NULL;
428*432ae724SEmmanuel Vadot 	}
429*432ae724SEmmanuel Vadot 
430*432ae724SEmmanuel Vadot 	if (sc->base.phy_mode == PHY_MODE_RGMII) {
431*432ae724SEmmanuel Vadot 		if (clk_get_by_ofw_name(dev, 0, "clk_mac_ref", &sc->clk_mac_ref) != 0) {
432*432ae724SEmmanuel Vadot 			device_printf(sc->base.dev, "could not get clk_mac_ref clock\n");
433*432ae724SEmmanuel Vadot 			sc->clk_mac_ref = NULL;
434*432ae724SEmmanuel Vadot 		}
435*432ae724SEmmanuel Vadot 
436*432ae724SEmmanuel Vadot 		if (!sc->clock_in) {
437*432ae724SEmmanuel Vadot 			if (clk_get_by_ofw_name(dev, 0, "clk_mac_refout", &sc->clk_mac_refout) != 0) {
438*432ae724SEmmanuel Vadot 				device_printf(sc->base.dev, "could not get clk_mac_refout clock\n");
439*432ae724SEmmanuel Vadot 				sc->clk_mac_refout = NULL;
440*432ae724SEmmanuel Vadot 			}
441*432ae724SEmmanuel Vadot 
442*432ae724SEmmanuel Vadot 			clk_set_freq(sc->clk_stmmaceth, 50000000, 0);
443*432ae724SEmmanuel Vadot 		}
444*432ae724SEmmanuel Vadot 	}
445*432ae724SEmmanuel Vadot 
446*432ae724SEmmanuel Vadot 	if ((sc->phy_node != 0) && sc->integrated_phy) {
447*432ae724SEmmanuel Vadot 		if (clk_get_by_ofw_index(dev, sc->phy_node, 0, &sc->clk_phy) != 0) {
448*432ae724SEmmanuel Vadot 			device_printf(sc->base.dev, "could not get PHY clock\n");
449*432ae724SEmmanuel Vadot 			sc->clk_phy = NULL;
450*432ae724SEmmanuel Vadot 		}
451*432ae724SEmmanuel Vadot 
452*432ae724SEmmanuel Vadot 		if (sc->clk_phy) {
453*432ae724SEmmanuel Vadot 			clk_set_freq(sc->clk_phy, 50000000, 0);
454*432ae724SEmmanuel Vadot 		}
455*432ae724SEmmanuel Vadot 	}
456*432ae724SEmmanuel Vadot 
457*432ae724SEmmanuel Vadot 	if (sc->base.phy_mode == PHY_MODE_RMII) {
458*432ae724SEmmanuel Vadot 		if (sc->mac_clk_rx)
459*432ae724SEmmanuel Vadot 			clk_enable(sc->mac_clk_rx);
460*432ae724SEmmanuel Vadot 		if (sc->clk_mac_ref)
461*432ae724SEmmanuel Vadot 			clk_enable(sc->clk_mac_ref);
462*432ae724SEmmanuel Vadot 		if (sc->clk_mac_refout)
463*432ae724SEmmanuel Vadot 			clk_enable(sc->clk_mac_refout);
464*432ae724SEmmanuel Vadot 	}
465*432ae724SEmmanuel Vadot 	if (sc->clk_phy)
466*432ae724SEmmanuel Vadot 		clk_enable(sc->clk_phy);
467*432ae724SEmmanuel Vadot 	if (sc->aclk_mac)
468*432ae724SEmmanuel Vadot 		clk_enable(sc->aclk_mac);
469*432ae724SEmmanuel Vadot 	if (sc->pclk_mac)
470*432ae724SEmmanuel Vadot 		clk_enable(sc->pclk_mac);
471*432ae724SEmmanuel Vadot 	if (sc->mac_clk_tx)
472*432ae724SEmmanuel Vadot 		clk_enable(sc->mac_clk_tx);
473*432ae724SEmmanuel Vadot 
474*432ae724SEmmanuel Vadot 	DELAY(50);
475*432ae724SEmmanuel Vadot 
476*432ae724SEmmanuel Vadot 	return (0);
477*432ae724SEmmanuel Vadot }
478*432ae724SEmmanuel Vadot 
479*432ae724SEmmanuel Vadot static int
480*432ae724SEmmanuel Vadot if_dwc_rk_init(device_t dev)
481*432ae724SEmmanuel Vadot {
482*432ae724SEmmanuel Vadot 	struct if_dwc_rk_softc *sc;
483*432ae724SEmmanuel Vadot 	phandle_t node;
484*432ae724SEmmanuel Vadot 	uint32_t rx, tx;
485*432ae724SEmmanuel Vadot 	int err;
486*432ae724SEmmanuel Vadot 	pcell_t phy_handle;
487*432ae724SEmmanuel Vadot 	char *clock_in_out;
488*432ae724SEmmanuel Vadot 	hwreset_t phy_reset;
489*432ae724SEmmanuel Vadot 	regulator_t phy_supply;
490*432ae724SEmmanuel Vadot 
491*432ae724SEmmanuel Vadot 	sc = device_get_softc(dev);
492*432ae724SEmmanuel Vadot 	node = ofw_bus_get_node(dev);
493*432ae724SEmmanuel Vadot 	sc->ops = (struct if_dwc_rk_ops *)ofw_bus_search_compatible(dev, compat_data)->ocd_data;
494*432ae724SEmmanuel Vadot 	if (OF_hasprop(node, "rockchip,grf") &&
495*432ae724SEmmanuel Vadot 	    syscon_get_by_ofw_property(dev, node,
496*432ae724SEmmanuel Vadot 	    "rockchip,grf", &sc->grf) != 0) {
497*432ae724SEmmanuel Vadot 		device_printf(dev, "cannot get grf driver handle\n");
498*432ae724SEmmanuel Vadot 		return (ENXIO);
499*432ae724SEmmanuel Vadot 	}
500*432ae724SEmmanuel Vadot 
501*432ae724SEmmanuel Vadot 	if (OF_getencprop(node, "tx_delay", &tx, sizeof(tx)) <= 0)
502*432ae724SEmmanuel Vadot 		tx = 0x30;
503*432ae724SEmmanuel Vadot 	if (OF_getencprop(node, "rx_delay", &rx, sizeof(rx)) <= 0)
504*432ae724SEmmanuel Vadot 		rx = 0x10;
505*432ae724SEmmanuel Vadot 	sc->tx_delay = tx;
506*432ae724SEmmanuel Vadot 	sc->rx_delay = rx;
507*432ae724SEmmanuel Vadot 
508*432ae724SEmmanuel Vadot 	sc->clock_in = true;
509*432ae724SEmmanuel Vadot 	if (OF_getprop_alloc(node, "clock_in_out", (void **)&clock_in_out)) {
510*432ae724SEmmanuel Vadot 		if (strcmp(clock_in_out, "input") == 0)
511*432ae724SEmmanuel Vadot 			sc->clock_in = true;
512*432ae724SEmmanuel Vadot 		else
513*432ae724SEmmanuel Vadot 			sc->clock_in = false;
514*432ae724SEmmanuel Vadot 		OF_prop_free(clock_in_out);
515*432ae724SEmmanuel Vadot 	}
516*432ae724SEmmanuel Vadot 
517*432ae724SEmmanuel Vadot 	if (OF_getencprop(node, "phy-handle", (void *)&phy_handle,
518*432ae724SEmmanuel Vadot 	    sizeof(phy_handle)) > 0)
519*432ae724SEmmanuel Vadot 		sc->phy_node = OF_node_from_xref(phy_handle);
520*432ae724SEmmanuel Vadot 
521*432ae724SEmmanuel Vadot 	if (sc->phy_node)
522*432ae724SEmmanuel Vadot 		sc->integrated_phy = OF_hasprop(sc->phy_node, "phy-is-integrated");
523*432ae724SEmmanuel Vadot 
524*432ae724SEmmanuel Vadot 	if (sc->integrated_phy)
525*432ae724SEmmanuel Vadot 		device_printf(sc->base.dev, "PHY is integrated\n");
526*432ae724SEmmanuel Vadot 
527*432ae724SEmmanuel Vadot 	if_dwc_rk_init_clocks(dev);
528*432ae724SEmmanuel Vadot 
529*432ae724SEmmanuel Vadot 	if (sc->ops->set_phy_mode)
530*432ae724SEmmanuel Vadot 	    sc->ops->set_phy_mode(sc);
531*432ae724SEmmanuel Vadot 
532*432ae724SEmmanuel Vadot 	if (sc->ops->set_delays)
533*432ae724SEmmanuel Vadot 	    sc->ops->set_delays(sc);
534*432ae724SEmmanuel Vadot 
535*432ae724SEmmanuel Vadot 	/*
536*432ae724SEmmanuel Vadot 	 * this also sets delays if tunable is defined
537*432ae724SEmmanuel Vadot 	 */
538*432ae724SEmmanuel Vadot 	err = if_dwc_rk_init_sysctl(sc);
539*432ae724SEmmanuel Vadot 	if (err != 0)
540*432ae724SEmmanuel Vadot 		return (err);
541*432ae724SEmmanuel Vadot 
542*432ae724SEmmanuel Vadot 	if (regulator_get_by_ofw_property(sc->base.dev, 0,
543*432ae724SEmmanuel Vadot 		            "phy-supply", &phy_supply) == 0) {
544*432ae724SEmmanuel Vadot 		if (regulator_enable(phy_supply)) {
545*432ae724SEmmanuel Vadot 			device_printf(sc->base.dev,
546*432ae724SEmmanuel Vadot 			    "cannot enable 'phy' regulator\n");
547*432ae724SEmmanuel Vadot 		}
548*432ae724SEmmanuel Vadot 	}
549*432ae724SEmmanuel Vadot 	else
550*432ae724SEmmanuel Vadot 		device_printf(sc->base.dev, "no phy-supply property\n");
551*432ae724SEmmanuel Vadot 
552*432ae724SEmmanuel Vadot 	/* Power up */
553*432ae724SEmmanuel Vadot 	if (sc->integrated_phy) {
554*432ae724SEmmanuel Vadot 		if (sc->ops->phy_powerup)
555*432ae724SEmmanuel Vadot 			sc->ops->phy_powerup(sc);
556*432ae724SEmmanuel Vadot 
557*432ae724SEmmanuel Vadot 		SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON0,
558*432ae724SEmmanuel Vadot 		    (MACPHY_CON0_CLK_50M_MASK << 16) |
559*432ae724SEmmanuel Vadot 		    MACPHY_CON0_CLK_50M);
560*432ae724SEmmanuel Vadot 		SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON0,
561*432ae724SEmmanuel Vadot 		    (MACPHY_CON0_RMII_MODE_MASK << 16) |
562*432ae724SEmmanuel Vadot 		    MACPHY_CON0_RMII_MODE);
563*432ae724SEmmanuel Vadot 		SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON2, 0xffff1234);
564*432ae724SEmmanuel Vadot 		SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON3, 0x003f0035);
565*432ae724SEmmanuel Vadot 
566*432ae724SEmmanuel Vadot 		if (hwreset_get_by_ofw_idx(dev, sc->phy_node, 0, &phy_reset)  == 0) {
567*432ae724SEmmanuel Vadot 			hwreset_assert(phy_reset);
568*432ae724SEmmanuel Vadot 			DELAY(20);
569*432ae724SEmmanuel Vadot 			hwreset_deassert(phy_reset);
570*432ae724SEmmanuel Vadot 			DELAY(20);
571*432ae724SEmmanuel Vadot 		}
572*432ae724SEmmanuel Vadot 	}
573*432ae724SEmmanuel Vadot 
574*432ae724SEmmanuel Vadot 	return (0);
575*432ae724SEmmanuel Vadot }
576*432ae724SEmmanuel Vadot 
577*432ae724SEmmanuel Vadot static int
578*432ae724SEmmanuel Vadot if_dwc_rk_mac_type(device_t dev)
579*432ae724SEmmanuel Vadot {
580*432ae724SEmmanuel Vadot 
581*432ae724SEmmanuel Vadot 	return (DWC_GMAC_NORMAL_DESC);
582*432ae724SEmmanuel Vadot }
583*432ae724SEmmanuel Vadot 
584*432ae724SEmmanuel Vadot static int
585*432ae724SEmmanuel Vadot if_dwc_rk_mii_clk(device_t dev)
586*432ae724SEmmanuel Vadot {
587*432ae724SEmmanuel Vadot 
588*432ae724SEmmanuel Vadot 	/* Should be calculated from the clock */
589*432ae724SEmmanuel Vadot 	return (GMAC_MII_CLK_150_250M_DIV102);
590*432ae724SEmmanuel Vadot }
591*432ae724SEmmanuel Vadot 
592*432ae724SEmmanuel Vadot static int
593*432ae724SEmmanuel Vadot if_dwc_rk_set_speed(device_t dev, int speed)
594*432ae724SEmmanuel Vadot {
595*432ae724SEmmanuel Vadot 	struct if_dwc_rk_softc *sc;
596*432ae724SEmmanuel Vadot 
597*432ae724SEmmanuel Vadot 	sc = device_get_softc(dev);
598*432ae724SEmmanuel Vadot 
599*432ae724SEmmanuel Vadot 	if (sc->ops->set_speed)
600*432ae724SEmmanuel Vadot 	    return sc->ops->set_speed(sc, speed);
601*432ae724SEmmanuel Vadot 
602*432ae724SEmmanuel Vadot 	return (0);
603*432ae724SEmmanuel Vadot }
604*432ae724SEmmanuel Vadot 
605*432ae724SEmmanuel Vadot static device_method_t if_dwc_rk_methods[] = {
606*432ae724SEmmanuel Vadot 	DEVMETHOD(device_probe,		if_dwc_rk_probe),
607*432ae724SEmmanuel Vadot 
608*432ae724SEmmanuel Vadot 	DEVMETHOD(if_dwc_init,		if_dwc_rk_init),
609*432ae724SEmmanuel Vadot 	DEVMETHOD(if_dwc_mac_type,	if_dwc_rk_mac_type),
610*432ae724SEmmanuel Vadot 	DEVMETHOD(if_dwc_mii_clk,	if_dwc_rk_mii_clk),
611*432ae724SEmmanuel Vadot 	DEVMETHOD(if_dwc_set_speed,	if_dwc_rk_set_speed),
612*432ae724SEmmanuel Vadot 
613*432ae724SEmmanuel Vadot 	DEVMETHOD_END
614*432ae724SEmmanuel Vadot };
615*432ae724SEmmanuel Vadot 
616*432ae724SEmmanuel Vadot extern driver_t dwc_driver;
617*432ae724SEmmanuel Vadot 
618*432ae724SEmmanuel Vadot DEFINE_CLASS_1(dwc, dwc_rk_driver, if_dwc_rk_methods,
619*432ae724SEmmanuel Vadot     sizeof(struct if_dwc_rk_softc), dwc_driver);
620*432ae724SEmmanuel Vadot DRIVER_MODULE(dwc_rk, simplebus, dwc_rk_driver, 0, 0);
621*432ae724SEmmanuel Vadot MODULE_DEPEND(dwc_rk, dwc, 1, 1, 1);
622