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