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> 36*b911f504SEmmanuel Vadot #include <net/if_media.h> 37432ae724SEmmanuel Vadot 38432ae724SEmmanuel Vadot #include <machine/bus.h> 39432ae724SEmmanuel Vadot 40801fb66aSEmmanuel Vadot #include <dev/mii/miivar.h> 41801fb66aSEmmanuel Vadot 42432ae724SEmmanuel Vadot #include <dev/ofw/ofw_bus.h> 43432ae724SEmmanuel Vadot #include <dev/ofw/ofw_bus_subr.h> 44432ae724SEmmanuel Vadot 45c36125f6SEmmanuel Vadot #include <dev/extres/clk/clk.h> 46c36125f6SEmmanuel Vadot #include <dev/extres/hwreset/hwreset.h> 47432ae724SEmmanuel Vadot #include <dev/extres/regulator/regulator.h> 48432ae724SEmmanuel Vadot 49c36125f6SEmmanuel Vadot #include <arm/allwinner/aw_machdep.h> 50c36125f6SEmmanuel Vadot 51c36125f6SEmmanuel Vadot #include <dev/dwc/if_dwcvar.h> 52c36125f6SEmmanuel Vadot #include <dev/dwc/dwc1000_reg.h> 53c36125f6SEmmanuel Vadot 54432ae724SEmmanuel Vadot #include "if_dwc_if.h" 55432ae724SEmmanuel Vadot 56432ae724SEmmanuel Vadot static int 57432ae724SEmmanuel Vadot a20_if_dwc_probe(device_t dev) 58432ae724SEmmanuel Vadot { 59432ae724SEmmanuel Vadot 60432ae724SEmmanuel Vadot if (!ofw_bus_status_okay(dev)) 61432ae724SEmmanuel Vadot return (ENXIO); 62432ae724SEmmanuel Vadot if (!ofw_bus_is_compatible(dev, "allwinner,sun7i-a20-gmac")) 63432ae724SEmmanuel Vadot return (ENXIO); 64432ae724SEmmanuel Vadot device_set_desc(dev, "A20 Gigabit Ethernet Controller"); 65432ae724SEmmanuel Vadot 66432ae724SEmmanuel Vadot return (BUS_PROBE_DEFAULT); 67432ae724SEmmanuel Vadot } 68432ae724SEmmanuel Vadot 69432ae724SEmmanuel Vadot static int 70432ae724SEmmanuel Vadot a20_if_dwc_init(device_t dev) 71432ae724SEmmanuel Vadot { 72432ae724SEmmanuel Vadot struct dwc_softc *sc; 73432ae724SEmmanuel Vadot const char *tx_parent_name; 74432ae724SEmmanuel Vadot clk_t clk_tx, clk_tx_parent; 75432ae724SEmmanuel Vadot regulator_t reg; 76432ae724SEmmanuel Vadot int error; 77432ae724SEmmanuel Vadot 78432ae724SEmmanuel Vadot sc = device_get_softc(dev); 79432ae724SEmmanuel Vadot 80432ae724SEmmanuel Vadot /* Configure PHY for MII or RGMII mode */ 81432ae724SEmmanuel Vadot switch(sc->phy_mode) { 82801fb66aSEmmanuel Vadot case MII_CONTYPE_RGMII: 83801fb66aSEmmanuel Vadot case MII_CONTYPE_RGMII_ID: 84801fb66aSEmmanuel Vadot case MII_CONTYPE_RGMII_RXID: 85801fb66aSEmmanuel Vadot case MII_CONTYPE_RGMII_TXID: 86432ae724SEmmanuel Vadot tx_parent_name = "gmac_int_tx"; 87432ae724SEmmanuel Vadot break; 88801fb66aSEmmanuel Vadot case MII_CONTYPE_MII: 89432ae724SEmmanuel Vadot tx_parent_name = "mii_phy_tx"; 90432ae724SEmmanuel Vadot break; 91432ae724SEmmanuel Vadot default: 92432ae724SEmmanuel Vadot device_printf(dev, "unsupported PHY connection type: %d", 93432ae724SEmmanuel Vadot sc->phy_mode); 94432ae724SEmmanuel Vadot return (ENXIO); 95432ae724SEmmanuel Vadot } 96432ae724SEmmanuel Vadot 97432ae724SEmmanuel Vadot error = clk_get_by_ofw_name(dev, 0, "allwinner_gmac_tx", &clk_tx); 98432ae724SEmmanuel Vadot if (error != 0) { 99432ae724SEmmanuel Vadot device_printf(dev, "could not get tx clk\n"); 100432ae724SEmmanuel Vadot return (error); 101432ae724SEmmanuel Vadot } 102432ae724SEmmanuel Vadot error = clk_get_by_name(dev, tx_parent_name, &clk_tx_parent); 103432ae724SEmmanuel Vadot if (error != 0) { 104432ae724SEmmanuel Vadot device_printf(dev, "could not get clock '%s'\n", 105432ae724SEmmanuel Vadot tx_parent_name); 106432ae724SEmmanuel Vadot return (error); 107432ae724SEmmanuel Vadot } 108432ae724SEmmanuel Vadot error = clk_set_parent_by_clk(clk_tx, clk_tx_parent); 109432ae724SEmmanuel Vadot if (error != 0) { 110432ae724SEmmanuel Vadot device_printf(dev, "could not set tx clk parent\n"); 111432ae724SEmmanuel Vadot return (error); 112432ae724SEmmanuel Vadot } 113432ae724SEmmanuel Vadot 114432ae724SEmmanuel Vadot /* Enable PHY regulator if applicable */ 115432ae724SEmmanuel Vadot if (regulator_get_by_ofw_property(dev, 0, "phy-supply", ®) == 0) { 116432ae724SEmmanuel Vadot error = regulator_enable(reg); 117432ae724SEmmanuel Vadot if (error != 0) { 118432ae724SEmmanuel Vadot device_printf(dev, "could not enable PHY regulator\n"); 119432ae724SEmmanuel Vadot return (error); 120432ae724SEmmanuel Vadot } 121432ae724SEmmanuel Vadot } 122432ae724SEmmanuel Vadot 123432ae724SEmmanuel Vadot return (0); 124432ae724SEmmanuel Vadot } 125432ae724SEmmanuel Vadot 126432ae724SEmmanuel Vadot static int 127432ae724SEmmanuel Vadot a20_if_dwc_mii_clk(device_t dev) 128432ae724SEmmanuel Vadot { 129432ae724SEmmanuel Vadot 130432ae724SEmmanuel Vadot return (GMAC_MII_CLK_150_250M_DIV102); 131432ae724SEmmanuel Vadot } 132432ae724SEmmanuel Vadot 133432ae724SEmmanuel Vadot static device_method_t a20_dwc_methods[] = { 134432ae724SEmmanuel Vadot DEVMETHOD(device_probe, a20_if_dwc_probe), 135432ae724SEmmanuel Vadot 136432ae724SEmmanuel Vadot DEVMETHOD(if_dwc_init, a20_if_dwc_init), 137432ae724SEmmanuel Vadot DEVMETHOD(if_dwc_mii_clk, a20_if_dwc_mii_clk), 138432ae724SEmmanuel Vadot 139432ae724SEmmanuel Vadot DEVMETHOD_END 140432ae724SEmmanuel Vadot }; 141432ae724SEmmanuel Vadot 142432ae724SEmmanuel Vadot extern driver_t dwc_driver; 143432ae724SEmmanuel Vadot 144432ae724SEmmanuel Vadot DEFINE_CLASS_1(dwc, a20_dwc_driver, a20_dwc_methods, sizeof(struct dwc_softc), 145432ae724SEmmanuel Vadot dwc_driver); 146432ae724SEmmanuel Vadot DRIVER_MODULE(a20_dwc, simplebus, a20_dwc_driver, 0, 0); 147432ae724SEmmanuel Vadot 148432ae724SEmmanuel Vadot MODULE_DEPEND(a20_dwc, dwc, 1, 1, 1); 149