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