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