1432ae724SEmmanuel Vadot /*- 2432ae724SEmmanuel Vadot * SPDX-License-Identifier: BSD-2-Clause 3432ae724SEmmanuel Vadot * 4432ae724SEmmanuel Vadot * Copyright (c) 2018 Emmanuel Vadot <manu@freebsd.org> 5432ae724SEmmanuel Vadot * 6432ae724SEmmanuel Vadot * Redistribution and use in source and binary forms, with or without 7432ae724SEmmanuel Vadot * modification, are permitted provided that the following conditions 8432ae724SEmmanuel Vadot * are met: 9432ae724SEmmanuel Vadot * 1. Redistributions of source code must retain the above copyright 10432ae724SEmmanuel Vadot * notice, this list of conditions and the following disclaimer. 11432ae724SEmmanuel Vadot * 2. Redistributions in binary form must reproduce the above copyright 12432ae724SEmmanuel Vadot * notice, this list of conditions and the following disclaimer in the 13432ae724SEmmanuel Vadot * documentation and/or other materials provided with the distribution. 14432ae724SEmmanuel Vadot * 15432ae724SEmmanuel Vadot * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16432ae724SEmmanuel Vadot * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17432ae724SEmmanuel Vadot * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18432ae724SEmmanuel Vadot * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19432ae724SEmmanuel Vadot * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20432ae724SEmmanuel Vadot * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21432ae724SEmmanuel Vadot * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22432ae724SEmmanuel Vadot * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23432ae724SEmmanuel Vadot * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24432ae724SEmmanuel Vadot * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25432ae724SEmmanuel Vadot * SUCH DAMAGE. 26432ae724SEmmanuel Vadot */ 27432ae724SEmmanuel Vadot 28432ae724SEmmanuel Vadot #include <sys/param.h> 29432ae724SEmmanuel Vadot #include <sys/systm.h> 30432ae724SEmmanuel Vadot #include <sys/bus.h> 31432ae724SEmmanuel Vadot #include <sys/kernel.h> 32432ae724SEmmanuel Vadot #include <sys/module.h> 33432ae724SEmmanuel Vadot #include <sys/socket.h> 34432ae724SEmmanuel Vadot 35432ae724SEmmanuel Vadot #include <machine/bus.h> 36432ae724SEmmanuel Vadot 37432ae724SEmmanuel Vadot #include <net/if.h> 38432ae724SEmmanuel Vadot #include <net/if_media.h> 39432ae724SEmmanuel Vadot 40801fb66aSEmmanuel Vadot #include <dev/mii/miivar.h> 41801fb66aSEmmanuel Vadot 42c36125f6SEmmanuel Vadot #include <dev/ofw/ofw_bus.h> 43c36125f6SEmmanuel Vadot #include <dev/ofw/ofw_bus_subr.h> 44c36125f6SEmmanuel Vadot 45*be82b3a0SEmmanuel Vadot #include <dev/clk/clk.h> 46432ae724SEmmanuel Vadot #include <dev/extres/hwreset/hwreset.h> 47432ae724SEmmanuel Vadot #include <dev/extres/regulator/regulator.h> 48432ae724SEmmanuel Vadot #include <dev/extres/syscon/syscon.h> 49432ae724SEmmanuel Vadot 5050059a60SEmmanuel Vadot #include <dev/dwc/if_dwcvar.h> 51c36125f6SEmmanuel Vadot #include <dev/dwc/dwc1000_reg.h> 5250059a60SEmmanuel Vadot 53432ae724SEmmanuel Vadot #include "if_dwc_if.h" 54432ae724SEmmanuel Vadot #include "syscon_if.h" 55432ae724SEmmanuel Vadot 56432ae724SEmmanuel Vadot #define RK3328_GRF_MAC_CON0 0x0900 57432ae724SEmmanuel Vadot #define MAC_CON0_GMAC2IO_TX_DL_CFG_MASK 0x7F 58432ae724SEmmanuel Vadot #define MAC_CON0_GMAC2IO_TX_DL_CFG_SHIFT 0 59432ae724SEmmanuel Vadot #define MAC_CON0_GMAC2IO_RX_DL_CFG_MASK 0x7F 60432ae724SEmmanuel Vadot #define MAC_CON0_GMAC2IO_RX_DL_CFG_SHIFT 7 61432ae724SEmmanuel Vadot 62432ae724SEmmanuel Vadot #define RK3328_GRF_MAC_CON1 0x0904 63432ae724SEmmanuel Vadot #define MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA (1 << 0) 64432ae724SEmmanuel Vadot #define MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA (1 << 1) 65432ae724SEmmanuel Vadot #define MAC_CON1_GMAC2IO_GMII_CLK_SEL_MASK (3 << 11) 66432ae724SEmmanuel Vadot #define MAC_CON1_GMAC2IO_GMII_CLK_SEL_125 (0 << 11) 67432ae724SEmmanuel Vadot #define MAC_CON1_GMAC2IO_GMII_CLK_SEL_25 (3 << 11) 68432ae724SEmmanuel Vadot #define MAC_CON1_GMAC2IO_GMII_CLK_SEL_2_5 (2 << 11) 69432ae724SEmmanuel Vadot #define MAC_CON1_GMAC2IO_RMII_MODE_MASK (1 << 9) 70432ae724SEmmanuel Vadot #define MAC_CON1_GMAC2IO_RMII_MODE (1 << 9) 71432ae724SEmmanuel Vadot #define MAC_CON1_GMAC2IO_INTF_SEL_MASK (7 << 4) 72432ae724SEmmanuel Vadot #define MAC_CON1_GMAC2IO_INTF_RMII (4 << 4) 73432ae724SEmmanuel Vadot #define MAC_CON1_GMAC2IO_INTF_RGMII (1 << 4) 74432ae724SEmmanuel Vadot #define MAC_CON1_GMAC2IO_RMII_CLK_SEL_MASK (1 << 7) 75432ae724SEmmanuel Vadot #define MAC_CON1_GMAC2IO_RMII_CLK_SEL_25 (1 << 7) 76432ae724SEmmanuel Vadot #define MAC_CON1_GMAC2IO_RMII_CLK_SEL_2_5 (0 << 7) 77432ae724SEmmanuel Vadot #define MAC_CON1_GMAC2IO_MAC_SPEED_MASK (1 << 2) 78432ae724SEmmanuel Vadot #define MAC_CON1_GMAC2IO_MAC_SPEED_100 (1 << 2) 79432ae724SEmmanuel Vadot #define MAC_CON1_GMAC2IO_MAC_SPEED_10 (0 << 2) 80432ae724SEmmanuel Vadot #define RK3328_GRF_MAC_CON2 0x0908 81432ae724SEmmanuel Vadot #define RK3328_GRF_MACPHY_CON0 0x0B00 82432ae724SEmmanuel Vadot #define MACPHY_CON0_CLK_50M_MASK (1 << 14) 83432ae724SEmmanuel Vadot #define MACPHY_CON0_CLK_50M (1 << 14) 84432ae724SEmmanuel Vadot #define MACPHY_CON0_RMII_MODE_MASK (3 << 6) 85432ae724SEmmanuel Vadot #define MACPHY_CON0_RMII_MODE (1 << 6) 86432ae724SEmmanuel Vadot #define RK3328_GRF_MACPHY_CON1 0x0B04 87432ae724SEmmanuel Vadot #define MACPHY_CON1_RMII_MODE_MASK (1 << 9) 88432ae724SEmmanuel Vadot #define MACPHY_CON1_RMII_MODE (1 << 9) 89432ae724SEmmanuel Vadot #define RK3328_GRF_MACPHY_CON2 0x0B08 90432ae724SEmmanuel Vadot #define RK3328_GRF_MACPHY_CON3 0x0B0C 91432ae724SEmmanuel Vadot #define RK3328_GRF_MACPHY_STATUS 0x0B10 92432ae724SEmmanuel Vadot 93432ae724SEmmanuel Vadot #define RK3399_GRF_SOC_CON5 0xc214 94432ae724SEmmanuel Vadot #define SOC_CON5_GMAC_CLK_SEL_MASK (3 << 4) 95432ae724SEmmanuel Vadot #define SOC_CON5_GMAC_CLK_SEL_125 (0 << 4) 96432ae724SEmmanuel Vadot #define SOC_CON5_GMAC_CLK_SEL_25 (3 << 4) 97432ae724SEmmanuel Vadot #define SOC_CON5_GMAC_CLK_SEL_2_5 (2 << 4) 98432ae724SEmmanuel Vadot #define RK3399_GRF_SOC_CON6 0xc218 99432ae724SEmmanuel Vadot #define SOC_CON6_GMAC_TXCLK_DLY_ENA (1 << 7) 100432ae724SEmmanuel Vadot #define SOC_CON6_TX_DL_CFG_MASK 0x7F 101432ae724SEmmanuel Vadot #define SOC_CON6_TX_DL_CFG_SHIFT 0 102432ae724SEmmanuel Vadot #define SOC_CON6_RX_DL_CFG_MASK 0x7F 103432ae724SEmmanuel Vadot #define SOC_CON6_GMAC_RXCLK_DLY_ENA (1 << 15) 104432ae724SEmmanuel Vadot #define SOC_CON6_RX_DL_CFG_SHIFT 8 105432ae724SEmmanuel Vadot 106432ae724SEmmanuel Vadot struct if_dwc_rk_softc; 107432ae724SEmmanuel Vadot 108432ae724SEmmanuel Vadot typedef void (*if_dwc_rk_set_delaysfn_t)(struct if_dwc_rk_softc *); 109432ae724SEmmanuel Vadot typedef int (*if_dwc_rk_set_speedfn_t)(struct if_dwc_rk_softc *, int); 110432ae724SEmmanuel Vadot typedef void (*if_dwc_rk_set_phy_modefn_t)(struct if_dwc_rk_softc *); 111432ae724SEmmanuel Vadot typedef void (*if_dwc_rk_phy_powerupfn_t)(struct if_dwc_rk_softc *); 112432ae724SEmmanuel Vadot 113432ae724SEmmanuel Vadot struct if_dwc_rk_ops { 114432ae724SEmmanuel Vadot if_dwc_rk_set_delaysfn_t set_delays; 115432ae724SEmmanuel Vadot if_dwc_rk_set_speedfn_t set_speed; 116432ae724SEmmanuel Vadot if_dwc_rk_set_phy_modefn_t set_phy_mode; 117432ae724SEmmanuel Vadot if_dwc_rk_phy_powerupfn_t phy_powerup; 118432ae724SEmmanuel Vadot }; 119432ae724SEmmanuel Vadot 120432ae724SEmmanuel Vadot struct if_dwc_rk_softc { 121432ae724SEmmanuel Vadot struct dwc_softc base; 122432ae724SEmmanuel Vadot uint32_t tx_delay; 123432ae724SEmmanuel Vadot uint32_t rx_delay; 124432ae724SEmmanuel Vadot bool integrated_phy; 125432ae724SEmmanuel Vadot bool clock_in; 126432ae724SEmmanuel Vadot phandle_t phy_node; 127432ae724SEmmanuel Vadot struct syscon *grf; 128432ae724SEmmanuel Vadot struct if_dwc_rk_ops *ops; 129432ae724SEmmanuel Vadot /* Common clocks */ 130432ae724SEmmanuel Vadot clk_t mac_clk_rx; 131432ae724SEmmanuel Vadot clk_t mac_clk_tx; 132432ae724SEmmanuel Vadot clk_t aclk_mac; 133432ae724SEmmanuel Vadot clk_t pclk_mac; 134432ae724SEmmanuel Vadot clk_t clk_stmmaceth; 13550059a60SEmmanuel Vadot clk_t clk_mac_speed; 136432ae724SEmmanuel Vadot /* RMII clocks */ 137432ae724SEmmanuel Vadot clk_t clk_mac_ref; 138432ae724SEmmanuel Vadot clk_t clk_mac_refout; 139432ae724SEmmanuel Vadot /* PHY clock */ 140432ae724SEmmanuel Vadot clk_t clk_phy; 141432ae724SEmmanuel Vadot }; 142432ae724SEmmanuel Vadot 143432ae724SEmmanuel Vadot static void rk3328_set_delays(struct if_dwc_rk_softc *sc); 144432ae724SEmmanuel Vadot static int rk3328_set_speed(struct if_dwc_rk_softc *sc, int speed); 145432ae724SEmmanuel Vadot static void rk3328_set_phy_mode(struct if_dwc_rk_softc *sc); 146432ae724SEmmanuel Vadot static void rk3328_phy_powerup(struct if_dwc_rk_softc *sc); 147432ae724SEmmanuel Vadot 148432ae724SEmmanuel Vadot static void rk3399_set_delays(struct if_dwc_rk_softc *sc); 149432ae724SEmmanuel Vadot static int rk3399_set_speed(struct if_dwc_rk_softc *sc, int speed); 150432ae724SEmmanuel Vadot 151432ae724SEmmanuel Vadot static struct if_dwc_rk_ops rk3288_ops = { 152432ae724SEmmanuel Vadot }; 153432ae724SEmmanuel Vadot 154432ae724SEmmanuel Vadot static struct if_dwc_rk_ops rk3328_ops = { 155432ae724SEmmanuel Vadot .set_delays = rk3328_set_delays, 156432ae724SEmmanuel Vadot .set_speed = rk3328_set_speed, 157432ae724SEmmanuel Vadot .set_phy_mode = rk3328_set_phy_mode, 158432ae724SEmmanuel Vadot .phy_powerup = rk3328_phy_powerup, 159432ae724SEmmanuel Vadot }; 160432ae724SEmmanuel Vadot 161432ae724SEmmanuel Vadot static struct if_dwc_rk_ops rk3399_ops = { 162432ae724SEmmanuel Vadot .set_delays = rk3399_set_delays, 163432ae724SEmmanuel Vadot .set_speed = rk3399_set_speed, 164432ae724SEmmanuel Vadot }; 165432ae724SEmmanuel Vadot 166432ae724SEmmanuel Vadot static struct ofw_compat_data compat_data[] = { 167432ae724SEmmanuel Vadot {"rockchip,rk3288-gmac", (uintptr_t)&rk3288_ops}, 168432ae724SEmmanuel Vadot {"rockchip,rk3328-gmac", (uintptr_t)&rk3328_ops}, 169432ae724SEmmanuel Vadot {"rockchip,rk3399-gmac", (uintptr_t)&rk3399_ops}, 170432ae724SEmmanuel Vadot {NULL, 0} 171432ae724SEmmanuel Vadot }; 172432ae724SEmmanuel Vadot 173432ae724SEmmanuel Vadot static void 174432ae724SEmmanuel Vadot rk3328_set_delays(struct if_dwc_rk_softc *sc) 175432ae724SEmmanuel Vadot { 176432ae724SEmmanuel Vadot uint32_t reg; 177432ae724SEmmanuel Vadot uint32_t tx, rx; 178432ae724SEmmanuel Vadot 179801fb66aSEmmanuel Vadot if (!mii_contype_is_rgmii(sc->base.phy_mode)) 180432ae724SEmmanuel Vadot return; 181432ae724SEmmanuel Vadot 182432ae724SEmmanuel Vadot reg = SYSCON_READ_4(sc->grf, RK3328_GRF_MAC_CON0); 183432ae724SEmmanuel Vadot tx = ((reg >> MAC_CON0_GMAC2IO_TX_DL_CFG_SHIFT) & MAC_CON0_GMAC2IO_TX_DL_CFG_MASK); 184432ae724SEmmanuel Vadot rx = ((reg >> MAC_CON0_GMAC2IO_RX_DL_CFG_SHIFT) & MAC_CON0_GMAC2IO_RX_DL_CFG_MASK); 185432ae724SEmmanuel Vadot 186432ae724SEmmanuel Vadot reg = SYSCON_READ_4(sc->grf, RK3328_GRF_MAC_CON1); 187432ae724SEmmanuel Vadot if (bootverbose) { 188432ae724SEmmanuel Vadot device_printf(sc->base.dev, "current delays settings: tx=%u(%s) rx=%u(%s)\n", 189432ae724SEmmanuel Vadot tx, ((reg & MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA) ? "enabled" : "disabled"), 190432ae724SEmmanuel Vadot rx, ((reg & MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA) ? "enabled" : "disabled")); 191432ae724SEmmanuel Vadot 192432ae724SEmmanuel Vadot device_printf(sc->base.dev, "setting new RK3328 RX/TX delays: %d/%d\n", 193432ae724SEmmanuel Vadot sc->tx_delay, sc->rx_delay); 194432ae724SEmmanuel Vadot } 195432ae724SEmmanuel Vadot 196432ae724SEmmanuel Vadot reg = (MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA | MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA) << 16; 197432ae724SEmmanuel Vadot reg |= (MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA | MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA); 198432ae724SEmmanuel Vadot SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON1, reg); 199432ae724SEmmanuel Vadot 200432ae724SEmmanuel Vadot reg = 0xffff << 16; 201432ae724SEmmanuel Vadot reg |= ((sc->tx_delay & MAC_CON0_GMAC2IO_TX_DL_CFG_MASK) << 202432ae724SEmmanuel Vadot MAC_CON0_GMAC2IO_TX_DL_CFG_SHIFT); 203432ae724SEmmanuel Vadot reg |= ((sc->rx_delay & MAC_CON0_GMAC2IO_TX_DL_CFG_MASK) << 204432ae724SEmmanuel Vadot MAC_CON0_GMAC2IO_RX_DL_CFG_SHIFT); 205432ae724SEmmanuel Vadot SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON0, reg); 206432ae724SEmmanuel Vadot } 207432ae724SEmmanuel Vadot 208432ae724SEmmanuel Vadot static int 209432ae724SEmmanuel Vadot rk3328_set_speed(struct if_dwc_rk_softc *sc, int speed) 210432ae724SEmmanuel Vadot { 211432ae724SEmmanuel Vadot uint32_t reg; 212432ae724SEmmanuel Vadot 213432ae724SEmmanuel Vadot switch (sc->base.phy_mode) { 214801fb66aSEmmanuel Vadot case MII_CONTYPE_RGMII: 215801fb66aSEmmanuel Vadot case MII_CONTYPE_RGMII_ID: 216801fb66aSEmmanuel Vadot case MII_CONTYPE_RGMII_RXID: 217801fb66aSEmmanuel Vadot case MII_CONTYPE_RGMII_TXID: 218432ae724SEmmanuel Vadot switch (speed) { 219432ae724SEmmanuel Vadot case IFM_1000_T: 220432ae724SEmmanuel Vadot case IFM_1000_SX: 221432ae724SEmmanuel Vadot reg = MAC_CON1_GMAC2IO_GMII_CLK_SEL_125; 222432ae724SEmmanuel Vadot break; 223432ae724SEmmanuel Vadot case IFM_100_TX: 224432ae724SEmmanuel Vadot reg = MAC_CON1_GMAC2IO_GMII_CLK_SEL_25; 225432ae724SEmmanuel Vadot break; 226432ae724SEmmanuel Vadot case IFM_10_T: 227432ae724SEmmanuel Vadot reg = MAC_CON1_GMAC2IO_GMII_CLK_SEL_2_5; 228432ae724SEmmanuel Vadot break; 229432ae724SEmmanuel Vadot default: 230432ae724SEmmanuel Vadot device_printf(sc->base.dev, "unsupported RGMII media %u\n", speed); 231432ae724SEmmanuel Vadot return (-1); 232432ae724SEmmanuel Vadot } 233432ae724SEmmanuel Vadot 234432ae724SEmmanuel Vadot SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON1, 235432ae724SEmmanuel Vadot ((MAC_CON1_GMAC2IO_GMII_CLK_SEL_MASK << 16) | reg)); 236432ae724SEmmanuel Vadot break; 237801fb66aSEmmanuel Vadot case MII_CONTYPE_RMII: 238432ae724SEmmanuel Vadot switch (speed) { 239432ae724SEmmanuel Vadot case IFM_100_TX: 240432ae724SEmmanuel Vadot reg = MAC_CON1_GMAC2IO_RMII_CLK_SEL_25 | 241432ae724SEmmanuel Vadot MAC_CON1_GMAC2IO_MAC_SPEED_100; 242432ae724SEmmanuel Vadot break; 243432ae724SEmmanuel Vadot case IFM_10_T: 244432ae724SEmmanuel Vadot reg = MAC_CON1_GMAC2IO_RMII_CLK_SEL_2_5 | 245432ae724SEmmanuel Vadot MAC_CON1_GMAC2IO_MAC_SPEED_10; 246432ae724SEmmanuel Vadot break; 247432ae724SEmmanuel Vadot default: 248432ae724SEmmanuel Vadot device_printf(sc->base.dev, "unsupported RMII media %u\n", speed); 249432ae724SEmmanuel Vadot return (-1); 250432ae724SEmmanuel Vadot } 251432ae724SEmmanuel Vadot 252432ae724SEmmanuel Vadot SYSCON_WRITE_4(sc->grf, 253432ae724SEmmanuel Vadot sc->integrated_phy ? RK3328_GRF_MAC_CON2 : RK3328_GRF_MAC_CON1, 254432ae724SEmmanuel Vadot reg | 255432ae724SEmmanuel Vadot ((MAC_CON1_GMAC2IO_RMII_CLK_SEL_MASK | MAC_CON1_GMAC2IO_MAC_SPEED_MASK) << 16)); 256432ae724SEmmanuel Vadot break; 257432ae724SEmmanuel Vadot } 258432ae724SEmmanuel Vadot 259432ae724SEmmanuel Vadot return (0); 260432ae724SEmmanuel Vadot } 261432ae724SEmmanuel Vadot 262432ae724SEmmanuel Vadot static void 263432ae724SEmmanuel Vadot rk3328_set_phy_mode(struct if_dwc_rk_softc *sc) 264432ae724SEmmanuel Vadot { 265432ae724SEmmanuel Vadot 266432ae724SEmmanuel Vadot switch (sc->base.phy_mode) { 267801fb66aSEmmanuel Vadot case MII_CONTYPE_RGMII: 268801fb66aSEmmanuel Vadot case MII_CONTYPE_RGMII_ID: 269801fb66aSEmmanuel Vadot case MII_CONTYPE_RGMII_RXID: 270801fb66aSEmmanuel Vadot case MII_CONTYPE_RGMII_TXID: 271432ae724SEmmanuel Vadot SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON1, 272432ae724SEmmanuel Vadot ((MAC_CON1_GMAC2IO_INTF_SEL_MASK | MAC_CON1_GMAC2IO_RMII_MODE_MASK) << 16) | 273432ae724SEmmanuel Vadot MAC_CON1_GMAC2IO_INTF_RGMII); 274432ae724SEmmanuel Vadot break; 275801fb66aSEmmanuel Vadot case MII_CONTYPE_RMII: 276432ae724SEmmanuel Vadot SYSCON_WRITE_4(sc->grf, sc->integrated_phy ? RK3328_GRF_MAC_CON2 : RK3328_GRF_MAC_CON1, 277432ae724SEmmanuel Vadot ((MAC_CON1_GMAC2IO_INTF_SEL_MASK | MAC_CON1_GMAC2IO_RMII_MODE_MASK) << 16) | 278432ae724SEmmanuel Vadot MAC_CON1_GMAC2IO_INTF_RMII | MAC_CON1_GMAC2IO_RMII_MODE); 279432ae724SEmmanuel Vadot break; 280432ae724SEmmanuel Vadot } 281432ae724SEmmanuel Vadot } 282432ae724SEmmanuel Vadot 283432ae724SEmmanuel Vadot static void 284432ae724SEmmanuel Vadot rk3328_phy_powerup(struct if_dwc_rk_softc *sc) 285432ae724SEmmanuel Vadot { 286432ae724SEmmanuel Vadot SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON1, 287432ae724SEmmanuel Vadot (MACPHY_CON1_RMII_MODE_MASK << 16) | 288432ae724SEmmanuel Vadot MACPHY_CON1_RMII_MODE); 289432ae724SEmmanuel Vadot } 290432ae724SEmmanuel Vadot 291432ae724SEmmanuel Vadot static void 292432ae724SEmmanuel Vadot rk3399_set_delays(struct if_dwc_rk_softc *sc) 293432ae724SEmmanuel Vadot { 294432ae724SEmmanuel Vadot uint32_t reg, tx, rx; 295432ae724SEmmanuel Vadot 296801fb66aSEmmanuel Vadot if (!mii_contype_is_rgmii(sc->base.phy_mode)) 297432ae724SEmmanuel Vadot return; 298432ae724SEmmanuel Vadot 299432ae724SEmmanuel Vadot reg = SYSCON_READ_4(sc->grf, RK3399_GRF_SOC_CON6); 300432ae724SEmmanuel Vadot tx = ((reg >> SOC_CON6_TX_DL_CFG_SHIFT) & SOC_CON6_TX_DL_CFG_MASK); 301432ae724SEmmanuel Vadot rx = ((reg >> SOC_CON6_RX_DL_CFG_SHIFT) & SOC_CON6_RX_DL_CFG_MASK); 302432ae724SEmmanuel Vadot 303432ae724SEmmanuel Vadot if (bootverbose) { 304432ae724SEmmanuel Vadot device_printf(sc->base.dev, "current delays settings: tx=%u(%s) rx=%u(%s)\n", 305432ae724SEmmanuel Vadot tx, ((reg & SOC_CON6_GMAC_TXCLK_DLY_ENA) ? "enabled" : "disabled"), 306432ae724SEmmanuel Vadot rx, ((reg & SOC_CON6_GMAC_RXCLK_DLY_ENA) ? "enabled" : "disabled")); 307432ae724SEmmanuel Vadot 308432ae724SEmmanuel Vadot device_printf(sc->base.dev, "setting new RK3399 RX/TX delays: %d/%d\n", 309432ae724SEmmanuel Vadot sc->rx_delay, sc->tx_delay); 310432ae724SEmmanuel Vadot } 311432ae724SEmmanuel Vadot 312432ae724SEmmanuel Vadot reg = 0xFFFF << 16; 313432ae724SEmmanuel Vadot reg |= ((sc->tx_delay & SOC_CON6_TX_DL_CFG_MASK) << 314432ae724SEmmanuel Vadot SOC_CON6_TX_DL_CFG_SHIFT); 315432ae724SEmmanuel Vadot reg |= ((sc->rx_delay & SOC_CON6_RX_DL_CFG_MASK) << 316432ae724SEmmanuel Vadot SOC_CON6_RX_DL_CFG_SHIFT); 317432ae724SEmmanuel Vadot reg |= SOC_CON6_GMAC_TXCLK_DLY_ENA | SOC_CON6_GMAC_RXCLK_DLY_ENA; 318432ae724SEmmanuel Vadot 319432ae724SEmmanuel Vadot SYSCON_WRITE_4(sc->grf, RK3399_GRF_SOC_CON6, reg); 320432ae724SEmmanuel Vadot } 321432ae724SEmmanuel Vadot 322432ae724SEmmanuel Vadot static int 323432ae724SEmmanuel Vadot rk3399_set_speed(struct if_dwc_rk_softc *sc, int speed) 324432ae724SEmmanuel Vadot { 325432ae724SEmmanuel Vadot uint32_t reg; 326432ae724SEmmanuel Vadot 327432ae724SEmmanuel Vadot switch (speed) { 328432ae724SEmmanuel Vadot case IFM_1000_T: 329432ae724SEmmanuel Vadot case IFM_1000_SX: 330432ae724SEmmanuel Vadot reg = SOC_CON5_GMAC_CLK_SEL_125; 331432ae724SEmmanuel Vadot break; 332432ae724SEmmanuel Vadot case IFM_100_TX: 333432ae724SEmmanuel Vadot reg = SOC_CON5_GMAC_CLK_SEL_25; 334432ae724SEmmanuel Vadot break; 335432ae724SEmmanuel Vadot case IFM_10_T: 336432ae724SEmmanuel Vadot reg = SOC_CON5_GMAC_CLK_SEL_2_5; 337432ae724SEmmanuel Vadot break; 338432ae724SEmmanuel Vadot default: 339432ae724SEmmanuel Vadot device_printf(sc->base.dev, "unsupported media %u\n", speed); 340432ae724SEmmanuel Vadot return (-1); 341432ae724SEmmanuel Vadot } 342432ae724SEmmanuel Vadot 343432ae724SEmmanuel Vadot SYSCON_WRITE_4(sc->grf, RK3399_GRF_SOC_CON5, 344432ae724SEmmanuel Vadot ((SOC_CON5_GMAC_CLK_SEL_MASK << 16) | reg)); 345432ae724SEmmanuel Vadot return (0); 346432ae724SEmmanuel Vadot } 347432ae724SEmmanuel Vadot 348432ae724SEmmanuel Vadot static int 349432ae724SEmmanuel Vadot if_dwc_rk_sysctl_delays(SYSCTL_HANDLER_ARGS) 350432ae724SEmmanuel Vadot { 351432ae724SEmmanuel Vadot struct if_dwc_rk_softc *sc; 352432ae724SEmmanuel Vadot int rv; 353432ae724SEmmanuel Vadot uint32_t rxtx; 354432ae724SEmmanuel Vadot 355432ae724SEmmanuel Vadot sc = arg1; 356432ae724SEmmanuel Vadot rxtx = ((sc->rx_delay << 8) | sc->tx_delay); 357432ae724SEmmanuel Vadot 358432ae724SEmmanuel Vadot rv = sysctl_handle_int(oidp, &rxtx, 0, req); 359432ae724SEmmanuel Vadot if (rv != 0 || req->newptr == NULL) 360432ae724SEmmanuel Vadot return (rv); 361432ae724SEmmanuel Vadot sc->tx_delay = rxtx & 0xff; 362432ae724SEmmanuel Vadot sc->rx_delay = (rxtx >> 8) & 0xff; 363432ae724SEmmanuel Vadot 364432ae724SEmmanuel Vadot if (sc->ops->set_delays) 365432ae724SEmmanuel Vadot sc->ops->set_delays(sc); 366432ae724SEmmanuel Vadot 367432ae724SEmmanuel Vadot return (0); 368432ae724SEmmanuel Vadot } 369432ae724SEmmanuel Vadot 370432ae724SEmmanuel Vadot static int 371432ae724SEmmanuel Vadot if_dwc_rk_init_sysctl(struct if_dwc_rk_softc *sc) 372432ae724SEmmanuel Vadot { 373432ae724SEmmanuel Vadot struct sysctl_oid *child; 374432ae724SEmmanuel Vadot struct sysctl_ctx_list *ctx_list; 375432ae724SEmmanuel Vadot 376432ae724SEmmanuel Vadot ctx_list = device_get_sysctl_ctx(sc->base.dev); 377432ae724SEmmanuel Vadot child = device_get_sysctl_tree(sc->base.dev); 378432ae724SEmmanuel Vadot SYSCTL_ADD_PROC(ctx_list, 379432ae724SEmmanuel Vadot SYSCTL_CHILDREN(child), OID_AUTO, "delays", 380432ae724SEmmanuel Vadot CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, sc, 0, 381432ae724SEmmanuel Vadot if_dwc_rk_sysctl_delays, "", "RGMII RX/TX delays: ((rx << 8) | tx)"); 382432ae724SEmmanuel Vadot 383432ae724SEmmanuel Vadot return (0); 384432ae724SEmmanuel Vadot } 385432ae724SEmmanuel Vadot 386432ae724SEmmanuel Vadot static int 387432ae724SEmmanuel Vadot if_dwc_rk_probe(device_t dev) 388432ae724SEmmanuel Vadot { 389432ae724SEmmanuel Vadot 390432ae724SEmmanuel Vadot if (!ofw_bus_status_okay(dev)) 391432ae724SEmmanuel Vadot return (ENXIO); 392432ae724SEmmanuel Vadot if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) 393432ae724SEmmanuel Vadot return (ENXIO); 394432ae724SEmmanuel Vadot device_set_desc(dev, "Rockchip Gigabit Ethernet Controller"); 395432ae724SEmmanuel Vadot 396432ae724SEmmanuel Vadot return (BUS_PROBE_DEFAULT); 397432ae724SEmmanuel Vadot } 398432ae724SEmmanuel Vadot 399432ae724SEmmanuel Vadot static int 400432ae724SEmmanuel Vadot if_dwc_rk_init_clocks(device_t dev) 401432ae724SEmmanuel Vadot { 402432ae724SEmmanuel Vadot struct if_dwc_rk_softc *sc; 403432ae724SEmmanuel Vadot 404432ae724SEmmanuel Vadot sc = device_get_softc(dev); 405432ae724SEmmanuel Vadot 406432ae724SEmmanuel Vadot /* Enable clocks */ 407432ae724SEmmanuel Vadot 408432ae724SEmmanuel Vadot if (clk_get_by_ofw_name(dev, 0, "mac_clk_tx", &sc->mac_clk_tx) != 0) { 409432ae724SEmmanuel Vadot device_printf(sc->base.dev, "could not get mac_clk_tx clock\n"); 410432ae724SEmmanuel Vadot sc->mac_clk_tx = NULL; 411432ae724SEmmanuel Vadot } 412432ae724SEmmanuel Vadot 413432ae724SEmmanuel Vadot if (clk_get_by_ofw_name(dev, 0, "aclk_mac", &sc->aclk_mac) != 0) { 414432ae724SEmmanuel Vadot device_printf(sc->base.dev, "could not get aclk_mac clock\n"); 415432ae724SEmmanuel Vadot sc->aclk_mac = NULL; 416432ae724SEmmanuel Vadot } 417432ae724SEmmanuel Vadot 418432ae724SEmmanuel Vadot if (clk_get_by_ofw_name(dev, 0, "pclk_mac", &sc->pclk_mac) != 0) { 419432ae724SEmmanuel Vadot device_printf(sc->base.dev, "could not get pclk_mac clock\n"); 420432ae724SEmmanuel Vadot sc->pclk_mac = NULL; 421432ae724SEmmanuel Vadot } 422432ae724SEmmanuel Vadot 42350059a60SEmmanuel Vadot /* Optional clock */ 42450059a60SEmmanuel Vadot clk_get_by_ofw_name(dev, 0, "clk_mac_speed", &sc->clk_mac_speed); 42550059a60SEmmanuel Vadot 426801fb66aSEmmanuel Vadot if (sc->base.phy_mode == MII_CONTYPE_RMII) { 42750059a60SEmmanuel Vadot if (clk_get_by_ofw_name(dev, 0, "mac_clk_rx", &sc->mac_clk_rx) != 0) { 42850059a60SEmmanuel Vadot device_printf(sc->base.dev, "could not get mac_clk_rx clock\n"); 42950059a60SEmmanuel Vadot sc->mac_clk_rx = NULL; 43050059a60SEmmanuel Vadot } 43150059a60SEmmanuel Vadot 432432ae724SEmmanuel Vadot if (clk_get_by_ofw_name(dev, 0, "clk_mac_ref", &sc->clk_mac_ref) != 0) { 433432ae724SEmmanuel Vadot device_printf(sc->base.dev, "could not get clk_mac_ref clock\n"); 434432ae724SEmmanuel Vadot sc->clk_mac_ref = NULL; 435432ae724SEmmanuel Vadot } 436432ae724SEmmanuel Vadot 437432ae724SEmmanuel Vadot if (!sc->clock_in) { 438432ae724SEmmanuel Vadot if (clk_get_by_ofw_name(dev, 0, "clk_mac_refout", &sc->clk_mac_refout) != 0) { 439432ae724SEmmanuel Vadot device_printf(sc->base.dev, "could not get clk_mac_refout clock\n"); 440432ae724SEmmanuel Vadot sc->clk_mac_refout = NULL; 441432ae724SEmmanuel Vadot } 442432ae724SEmmanuel Vadot 443432ae724SEmmanuel Vadot clk_set_freq(sc->clk_stmmaceth, 50000000, 0); 444432ae724SEmmanuel Vadot } 445432ae724SEmmanuel Vadot } 446432ae724SEmmanuel Vadot 447432ae724SEmmanuel Vadot if ((sc->phy_node != 0) && sc->integrated_phy) { 448432ae724SEmmanuel Vadot if (clk_get_by_ofw_index(dev, sc->phy_node, 0, &sc->clk_phy) != 0) { 449432ae724SEmmanuel Vadot device_printf(sc->base.dev, "could not get PHY clock\n"); 450432ae724SEmmanuel Vadot sc->clk_phy = NULL; 451432ae724SEmmanuel Vadot } 452432ae724SEmmanuel Vadot 453432ae724SEmmanuel Vadot if (sc->clk_phy) { 454432ae724SEmmanuel Vadot clk_set_freq(sc->clk_phy, 50000000, 0); 455432ae724SEmmanuel Vadot } 456432ae724SEmmanuel Vadot } 457432ae724SEmmanuel Vadot 458801fb66aSEmmanuel Vadot if (sc->base.phy_mode == MII_CONTYPE_RMII) { 459432ae724SEmmanuel Vadot if (sc->mac_clk_rx) 460432ae724SEmmanuel Vadot clk_enable(sc->mac_clk_rx); 461432ae724SEmmanuel Vadot if (sc->clk_mac_ref) 462432ae724SEmmanuel Vadot clk_enable(sc->clk_mac_ref); 463432ae724SEmmanuel Vadot if (sc->clk_mac_refout) 464432ae724SEmmanuel Vadot clk_enable(sc->clk_mac_refout); 465432ae724SEmmanuel Vadot } 466432ae724SEmmanuel Vadot if (sc->clk_phy) 467432ae724SEmmanuel Vadot clk_enable(sc->clk_phy); 468432ae724SEmmanuel Vadot if (sc->aclk_mac) 469432ae724SEmmanuel Vadot clk_enable(sc->aclk_mac); 470432ae724SEmmanuel Vadot if (sc->pclk_mac) 471432ae724SEmmanuel Vadot clk_enable(sc->pclk_mac); 472432ae724SEmmanuel Vadot if (sc->mac_clk_tx) 473432ae724SEmmanuel Vadot clk_enable(sc->mac_clk_tx); 47450059a60SEmmanuel Vadot if (sc->clk_mac_speed) 47550059a60SEmmanuel Vadot clk_enable(sc->clk_mac_speed); 476432ae724SEmmanuel Vadot 477432ae724SEmmanuel Vadot DELAY(50); 478432ae724SEmmanuel Vadot 479432ae724SEmmanuel Vadot return (0); 480432ae724SEmmanuel Vadot } 481432ae724SEmmanuel Vadot 482432ae724SEmmanuel Vadot static int 483432ae724SEmmanuel Vadot if_dwc_rk_init(device_t dev) 484432ae724SEmmanuel Vadot { 485432ae724SEmmanuel Vadot struct if_dwc_rk_softc *sc; 486432ae724SEmmanuel Vadot phandle_t node; 487432ae724SEmmanuel Vadot uint32_t rx, tx; 488432ae724SEmmanuel Vadot int err; 489432ae724SEmmanuel Vadot pcell_t phy_handle; 490432ae724SEmmanuel Vadot char *clock_in_out; 491432ae724SEmmanuel Vadot hwreset_t phy_reset; 492432ae724SEmmanuel Vadot regulator_t phy_supply; 493432ae724SEmmanuel Vadot 494432ae724SEmmanuel Vadot sc = device_get_softc(dev); 495432ae724SEmmanuel Vadot node = ofw_bus_get_node(dev); 496432ae724SEmmanuel Vadot sc->ops = (struct if_dwc_rk_ops *)ofw_bus_search_compatible(dev, compat_data)->ocd_data; 497432ae724SEmmanuel Vadot if (OF_hasprop(node, "rockchip,grf") && 498432ae724SEmmanuel Vadot syscon_get_by_ofw_property(dev, node, 499432ae724SEmmanuel Vadot "rockchip,grf", &sc->grf) != 0) { 500432ae724SEmmanuel Vadot device_printf(dev, "cannot get grf driver handle\n"); 501432ae724SEmmanuel Vadot return (ENXIO); 502432ae724SEmmanuel Vadot } 503432ae724SEmmanuel Vadot 504432ae724SEmmanuel Vadot if (OF_getencprop(node, "tx_delay", &tx, sizeof(tx)) <= 0) 505432ae724SEmmanuel Vadot tx = 0x30; 506432ae724SEmmanuel Vadot if (OF_getencprop(node, "rx_delay", &rx, sizeof(rx)) <= 0) 507432ae724SEmmanuel Vadot rx = 0x10; 508432ae724SEmmanuel Vadot sc->tx_delay = tx; 509432ae724SEmmanuel Vadot sc->rx_delay = rx; 510432ae724SEmmanuel Vadot 511432ae724SEmmanuel Vadot sc->clock_in = true; 512432ae724SEmmanuel Vadot if (OF_getprop_alloc(node, "clock_in_out", (void **)&clock_in_out)) { 513432ae724SEmmanuel Vadot if (strcmp(clock_in_out, "input") == 0) 514432ae724SEmmanuel Vadot sc->clock_in = true; 515432ae724SEmmanuel Vadot else 516432ae724SEmmanuel Vadot sc->clock_in = false; 517432ae724SEmmanuel Vadot OF_prop_free(clock_in_out); 518432ae724SEmmanuel Vadot } 519432ae724SEmmanuel Vadot 520432ae724SEmmanuel Vadot if (OF_getencprop(node, "phy-handle", (void *)&phy_handle, 521432ae724SEmmanuel Vadot sizeof(phy_handle)) > 0) 522432ae724SEmmanuel Vadot sc->phy_node = OF_node_from_xref(phy_handle); 523432ae724SEmmanuel Vadot 524432ae724SEmmanuel Vadot if (sc->phy_node) 525432ae724SEmmanuel Vadot sc->integrated_phy = OF_hasprop(sc->phy_node, "phy-is-integrated"); 526432ae724SEmmanuel Vadot 527432ae724SEmmanuel Vadot if (sc->integrated_phy) 528432ae724SEmmanuel Vadot device_printf(sc->base.dev, "PHY is integrated\n"); 529432ae724SEmmanuel Vadot 530432ae724SEmmanuel Vadot if_dwc_rk_init_clocks(dev); 531432ae724SEmmanuel Vadot 532432ae724SEmmanuel Vadot if (sc->ops->set_phy_mode) 533432ae724SEmmanuel Vadot sc->ops->set_phy_mode(sc); 534432ae724SEmmanuel Vadot 535432ae724SEmmanuel Vadot if (sc->ops->set_delays) 536432ae724SEmmanuel Vadot sc->ops->set_delays(sc); 537432ae724SEmmanuel Vadot 538432ae724SEmmanuel Vadot /* 539432ae724SEmmanuel Vadot * this also sets delays if tunable is defined 540432ae724SEmmanuel Vadot */ 541432ae724SEmmanuel Vadot err = if_dwc_rk_init_sysctl(sc); 542432ae724SEmmanuel Vadot if (err != 0) 543432ae724SEmmanuel Vadot return (err); 544432ae724SEmmanuel Vadot 545432ae724SEmmanuel Vadot if (regulator_get_by_ofw_property(sc->base.dev, 0, 546432ae724SEmmanuel Vadot "phy-supply", &phy_supply) == 0) { 547432ae724SEmmanuel Vadot if (regulator_enable(phy_supply)) { 548432ae724SEmmanuel Vadot device_printf(sc->base.dev, 549432ae724SEmmanuel Vadot "cannot enable 'phy' regulator\n"); 550432ae724SEmmanuel Vadot } 551432ae724SEmmanuel Vadot } 552432ae724SEmmanuel Vadot else 553432ae724SEmmanuel Vadot device_printf(sc->base.dev, "no phy-supply property\n"); 554432ae724SEmmanuel Vadot 555432ae724SEmmanuel Vadot /* Power up */ 556432ae724SEmmanuel Vadot if (sc->integrated_phy) { 557432ae724SEmmanuel Vadot if (sc->ops->phy_powerup) 558432ae724SEmmanuel Vadot sc->ops->phy_powerup(sc); 559432ae724SEmmanuel Vadot 560432ae724SEmmanuel Vadot SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON0, 561432ae724SEmmanuel Vadot (MACPHY_CON0_CLK_50M_MASK << 16) | 562432ae724SEmmanuel Vadot MACPHY_CON0_CLK_50M); 563432ae724SEmmanuel Vadot SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON0, 564432ae724SEmmanuel Vadot (MACPHY_CON0_RMII_MODE_MASK << 16) | 565432ae724SEmmanuel Vadot MACPHY_CON0_RMII_MODE); 566432ae724SEmmanuel Vadot SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON2, 0xffff1234); 567432ae724SEmmanuel Vadot SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON3, 0x003f0035); 568432ae724SEmmanuel Vadot 569432ae724SEmmanuel Vadot if (hwreset_get_by_ofw_idx(dev, sc->phy_node, 0, &phy_reset) == 0) { 570432ae724SEmmanuel Vadot hwreset_assert(phy_reset); 571432ae724SEmmanuel Vadot DELAY(20); 572432ae724SEmmanuel Vadot hwreset_deassert(phy_reset); 573432ae724SEmmanuel Vadot DELAY(20); 574432ae724SEmmanuel Vadot } 575432ae724SEmmanuel Vadot } 576432ae724SEmmanuel Vadot 577432ae724SEmmanuel Vadot return (0); 578432ae724SEmmanuel Vadot } 579432ae724SEmmanuel Vadot 580432ae724SEmmanuel Vadot static int 581432ae724SEmmanuel Vadot if_dwc_rk_mii_clk(device_t dev) 582432ae724SEmmanuel Vadot { 583cf037a17SEmmanuel Vadot struct if_dwc_rk_softc *sc; 584cf037a17SEmmanuel Vadot uint64_t freq; 585cf037a17SEmmanuel Vadot int rv; 586432ae724SEmmanuel Vadot 587cf037a17SEmmanuel Vadot sc = device_get_softc(dev); 588cf037a17SEmmanuel Vadot if ((rv = clk_get_freq(sc->pclk_mac, &freq)) != 0) 589cf037a17SEmmanuel Vadot return (-rv); 590cf037a17SEmmanuel Vadot freq = freq / 1000 / 1000; 591cf037a17SEmmanuel Vadot 592cf037a17SEmmanuel Vadot if (freq >= 60 && freq <= 100) 593cf037a17SEmmanuel Vadot return (GMAC_MII_CLK_60_100M_DIV42); 594cf037a17SEmmanuel Vadot else if (freq >= 100 && freq <= 150) 595cf037a17SEmmanuel Vadot return (GMAC_MII_CLK_100_150M_DIV62); 596cf037a17SEmmanuel Vadot else if (freq >= 20 && freq <= 35) 597cf037a17SEmmanuel Vadot return (GMAC_MII_CLK_25_35M_DIV16); 598cf037a17SEmmanuel Vadot else if (freq >= 35 && freq <= 60) 599cf037a17SEmmanuel Vadot return (GMAC_MII_CLK_35_60M_DIV26); 600cf037a17SEmmanuel Vadot else if (freq >= 150 && freq <= 250) 601432ae724SEmmanuel Vadot return (GMAC_MII_CLK_150_250M_DIV102); 602cf037a17SEmmanuel Vadot else if (freq >= 250 && freq <= 300) 603cf037a17SEmmanuel Vadot return (GMAC_MII_CLK_250_300M_DIV124); 604cf037a17SEmmanuel Vadot 605cf037a17SEmmanuel Vadot return (-ERANGE); 606432ae724SEmmanuel Vadot } 607432ae724SEmmanuel Vadot 608432ae724SEmmanuel Vadot static int 609432ae724SEmmanuel Vadot if_dwc_rk_set_speed(device_t dev, int speed) 610432ae724SEmmanuel Vadot { 611432ae724SEmmanuel Vadot struct if_dwc_rk_softc *sc; 612432ae724SEmmanuel Vadot 613432ae724SEmmanuel Vadot sc = device_get_softc(dev); 614432ae724SEmmanuel Vadot 615432ae724SEmmanuel Vadot if (sc->ops->set_speed) 616432ae724SEmmanuel Vadot return sc->ops->set_speed(sc, speed); 617432ae724SEmmanuel Vadot 618432ae724SEmmanuel Vadot return (0); 619432ae724SEmmanuel Vadot } 620432ae724SEmmanuel Vadot 621432ae724SEmmanuel Vadot static device_method_t if_dwc_rk_methods[] = { 622432ae724SEmmanuel Vadot DEVMETHOD(device_probe, if_dwc_rk_probe), 623432ae724SEmmanuel Vadot 624432ae724SEmmanuel Vadot DEVMETHOD(if_dwc_init, if_dwc_rk_init), 625432ae724SEmmanuel Vadot DEVMETHOD(if_dwc_mii_clk, if_dwc_rk_mii_clk), 626432ae724SEmmanuel Vadot DEVMETHOD(if_dwc_set_speed, if_dwc_rk_set_speed), 627432ae724SEmmanuel Vadot 628432ae724SEmmanuel Vadot DEVMETHOD_END 629432ae724SEmmanuel Vadot }; 630432ae724SEmmanuel Vadot 631432ae724SEmmanuel Vadot extern driver_t dwc_driver; 632432ae724SEmmanuel Vadot 633432ae724SEmmanuel Vadot DEFINE_CLASS_1(dwc, dwc_rk_driver, if_dwc_rk_methods, 634432ae724SEmmanuel Vadot sizeof(struct if_dwc_rk_softc), dwc_driver); 635432ae724SEmmanuel Vadot DRIVER_MODULE(dwc_rk, simplebus, dwc_rk_driver, 0, 0); 636432ae724SEmmanuel Vadot MODULE_DEPEND(dwc_rk, dwc, 1, 1, 1); 637