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