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