1432ae724SEmmanuel Vadot /*- 2432ae724SEmmanuel Vadot * Copyright (c) 2015 Luiz Otavio O Souza <loos@FreeBSD.org> 3432ae724SEmmanuel Vadot * All rights reserved. 4432ae724SEmmanuel Vadot * 5432ae724SEmmanuel Vadot * Redistribution and use in source and binary forms, with or without 6432ae724SEmmanuel Vadot * modification, are permitted provided that the following conditions 7432ae724SEmmanuel Vadot * are met: 8432ae724SEmmanuel Vadot * 1. Redistributions of source code must retain the above copyright 9432ae724SEmmanuel Vadot * notice, this list of conditions and the following disclaimer. 10432ae724SEmmanuel Vadot * 2. Redistributions in binary form must reproduce the above copyright 11432ae724SEmmanuel Vadot * notice, this list of conditions and the following disclaimer in the 12432ae724SEmmanuel Vadot * documentation and/or other materials provided with the distribution. 13432ae724SEmmanuel Vadot * 14432ae724SEmmanuel Vadot * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15432ae724SEmmanuel Vadot * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16432ae724SEmmanuel Vadot * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17432ae724SEmmanuel Vadot * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18432ae724SEmmanuel Vadot * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19432ae724SEmmanuel Vadot * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20432ae724SEmmanuel Vadot * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21432ae724SEmmanuel Vadot * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22432ae724SEmmanuel Vadot * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23432ae724SEmmanuel Vadot * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24432ae724SEmmanuel Vadot * SUCH DAMAGE. 25432ae724SEmmanuel Vadot */ 26432ae724SEmmanuel Vadot 27432ae724SEmmanuel Vadot #include <sys/cdefs.h> 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/socket.h> 33432ae724SEmmanuel Vadot #include <sys/module.h> 34432ae724SEmmanuel Vadot 35432ae724SEmmanuel Vadot #include <net/if.h> 36432ae724SEmmanuel Vadot 37432ae724SEmmanuel Vadot #include <machine/bus.h> 38432ae724SEmmanuel Vadot 39*801fb66aSEmmanuel Vadot #include <dev/mii/miivar.h> 40*801fb66aSEmmanuel Vadot 41432ae724SEmmanuel Vadot #include <dev/ofw/ofw_bus.h> 42432ae724SEmmanuel Vadot #include <dev/ofw/ofw_bus_subr.h> 43432ae724SEmmanuel Vadot 44c36125f6SEmmanuel Vadot #include <dev/extres/clk/clk.h> 45c36125f6SEmmanuel Vadot #include <dev/extres/hwreset/hwreset.h> 46432ae724SEmmanuel Vadot #include <dev/extres/regulator/regulator.h> 47432ae724SEmmanuel Vadot 48c36125f6SEmmanuel Vadot #include <arm/allwinner/aw_machdep.h> 49c36125f6SEmmanuel Vadot 50c36125f6SEmmanuel Vadot #include <dev/dwc/if_dwcvar.h> 51c36125f6SEmmanuel Vadot #include <dev/dwc/dwc1000_reg.h> 52c36125f6SEmmanuel Vadot 53432ae724SEmmanuel Vadot #include "if_dwc_if.h" 54432ae724SEmmanuel Vadot 55432ae724SEmmanuel Vadot static int 56432ae724SEmmanuel Vadot a20_if_dwc_probe(device_t dev) 57432ae724SEmmanuel Vadot { 58432ae724SEmmanuel Vadot 59432ae724SEmmanuel Vadot if (!ofw_bus_status_okay(dev)) 60432ae724SEmmanuel Vadot return (ENXIO); 61432ae724SEmmanuel Vadot if (!ofw_bus_is_compatible(dev, "allwinner,sun7i-a20-gmac")) 62432ae724SEmmanuel Vadot return (ENXIO); 63432ae724SEmmanuel Vadot device_set_desc(dev, "A20 Gigabit Ethernet Controller"); 64432ae724SEmmanuel Vadot 65432ae724SEmmanuel Vadot return (BUS_PROBE_DEFAULT); 66432ae724SEmmanuel Vadot } 67432ae724SEmmanuel Vadot 68432ae724SEmmanuel Vadot static int 69432ae724SEmmanuel Vadot a20_if_dwc_init(device_t dev) 70432ae724SEmmanuel Vadot { 71432ae724SEmmanuel Vadot struct dwc_softc *sc; 72432ae724SEmmanuel Vadot const char *tx_parent_name; 73432ae724SEmmanuel Vadot clk_t clk_tx, clk_tx_parent; 74432ae724SEmmanuel Vadot regulator_t reg; 75432ae724SEmmanuel Vadot int error; 76432ae724SEmmanuel Vadot 77432ae724SEmmanuel Vadot sc = device_get_softc(dev); 78432ae724SEmmanuel Vadot 79432ae724SEmmanuel Vadot /* Configure PHY for MII or RGMII mode */ 80432ae724SEmmanuel Vadot switch(sc->phy_mode) { 81*801fb66aSEmmanuel Vadot case MII_CONTYPE_RGMII: 82*801fb66aSEmmanuel Vadot case MII_CONTYPE_RGMII_ID: 83*801fb66aSEmmanuel Vadot case MII_CONTYPE_RGMII_RXID: 84*801fb66aSEmmanuel Vadot case MII_CONTYPE_RGMII_TXID: 85432ae724SEmmanuel Vadot tx_parent_name = "gmac_int_tx"; 86432ae724SEmmanuel Vadot break; 87*801fb66aSEmmanuel Vadot case MII_CONTYPE_MII: 88432ae724SEmmanuel Vadot tx_parent_name = "mii_phy_tx"; 89432ae724SEmmanuel Vadot break; 90432ae724SEmmanuel Vadot default: 91432ae724SEmmanuel Vadot device_printf(dev, "unsupported PHY connection type: %d", 92432ae724SEmmanuel Vadot sc->phy_mode); 93432ae724SEmmanuel Vadot return (ENXIO); 94432ae724SEmmanuel Vadot } 95432ae724SEmmanuel Vadot 96432ae724SEmmanuel Vadot error = clk_get_by_ofw_name(dev, 0, "allwinner_gmac_tx", &clk_tx); 97432ae724SEmmanuel Vadot if (error != 0) { 98432ae724SEmmanuel Vadot device_printf(dev, "could not get tx clk\n"); 99432ae724SEmmanuel Vadot return (error); 100432ae724SEmmanuel Vadot } 101432ae724SEmmanuel Vadot error = clk_get_by_name(dev, tx_parent_name, &clk_tx_parent); 102432ae724SEmmanuel Vadot if (error != 0) { 103432ae724SEmmanuel Vadot device_printf(dev, "could not get clock '%s'\n", 104432ae724SEmmanuel Vadot tx_parent_name); 105432ae724SEmmanuel Vadot return (error); 106432ae724SEmmanuel Vadot } 107432ae724SEmmanuel Vadot error = clk_set_parent_by_clk(clk_tx, clk_tx_parent); 108432ae724SEmmanuel Vadot if (error != 0) { 109432ae724SEmmanuel Vadot device_printf(dev, "could not set tx clk parent\n"); 110432ae724SEmmanuel Vadot return (error); 111432ae724SEmmanuel Vadot } 112432ae724SEmmanuel Vadot 113432ae724SEmmanuel Vadot /* Enable PHY regulator if applicable */ 114432ae724SEmmanuel Vadot if (regulator_get_by_ofw_property(dev, 0, "phy-supply", ®) == 0) { 115432ae724SEmmanuel Vadot error = regulator_enable(reg); 116432ae724SEmmanuel Vadot if (error != 0) { 117432ae724SEmmanuel Vadot device_printf(dev, "could not enable PHY regulator\n"); 118432ae724SEmmanuel Vadot return (error); 119432ae724SEmmanuel Vadot } 120432ae724SEmmanuel Vadot } 121432ae724SEmmanuel Vadot 122432ae724SEmmanuel Vadot return (0); 123432ae724SEmmanuel Vadot } 124432ae724SEmmanuel Vadot 125432ae724SEmmanuel Vadot static int 126432ae724SEmmanuel Vadot a20_if_dwc_mac_type(device_t dev) 127432ae724SEmmanuel Vadot { 128432ae724SEmmanuel Vadot 129432ae724SEmmanuel Vadot return (DWC_GMAC_NORMAL_DESC); 130432ae724SEmmanuel Vadot } 131432ae724SEmmanuel Vadot 132432ae724SEmmanuel Vadot static int 133432ae724SEmmanuel Vadot a20_if_dwc_mii_clk(device_t dev) 134432ae724SEmmanuel Vadot { 135432ae724SEmmanuel Vadot 136432ae724SEmmanuel Vadot return (GMAC_MII_CLK_150_250M_DIV102); 137432ae724SEmmanuel Vadot } 138432ae724SEmmanuel Vadot 139432ae724SEmmanuel Vadot static device_method_t a20_dwc_methods[] = { 140432ae724SEmmanuel Vadot DEVMETHOD(device_probe, a20_if_dwc_probe), 141432ae724SEmmanuel Vadot 142432ae724SEmmanuel Vadot DEVMETHOD(if_dwc_init, a20_if_dwc_init), 143432ae724SEmmanuel Vadot DEVMETHOD(if_dwc_mac_type, a20_if_dwc_mac_type), 144432ae724SEmmanuel Vadot DEVMETHOD(if_dwc_mii_clk, a20_if_dwc_mii_clk), 145432ae724SEmmanuel Vadot 146432ae724SEmmanuel Vadot DEVMETHOD_END 147432ae724SEmmanuel Vadot }; 148432ae724SEmmanuel Vadot 149432ae724SEmmanuel Vadot extern driver_t dwc_driver; 150432ae724SEmmanuel Vadot 151432ae724SEmmanuel Vadot DEFINE_CLASS_1(dwc, a20_dwc_driver, a20_dwc_methods, sizeof(struct dwc_softc), 152432ae724SEmmanuel Vadot dwc_driver); 153432ae724SEmmanuel Vadot DRIVER_MODULE(a20_dwc, simplebus, a20_dwc_driver, 0, 0); 154432ae724SEmmanuel Vadot 155432ae724SEmmanuel Vadot MODULE_DEPEND(a20_dwc, dwc, 1, 1, 1); 156