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