aw_if_dwc.c revision 297627
1288050Sloos/*- 2288050Sloos * Copyright (c) 2015 Luiz Otavio O Souza <loos@FreeBSD.org> 3288050Sloos * All rights reserved. 4288050Sloos * 5288050Sloos * Redistribution and use in source and binary forms, with or without 6288050Sloos * modification, are permitted provided that the following conditions 7288050Sloos * are met: 8288050Sloos * 1. Redistributions of source code must retain the above copyright 9288050Sloos * notice, this list of conditions and the following disclaimer. 10288050Sloos * 2. Redistributions in binary form must reproduce the above copyright 11288050Sloos * notice, this list of conditions and the following disclaimer in the 12288050Sloos * documentation and/or other materials provided with the distribution. 13288050Sloos * 14288050Sloos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15288050Sloos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16288050Sloos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17288050Sloos * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18288050Sloos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19288050Sloos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20288050Sloos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21288050Sloos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22288050Sloos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23288050Sloos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24288050Sloos * SUCH DAMAGE. 25288050Sloos */ 26288050Sloos 27288050Sloos#include <sys/cdefs.h> 28288050Sloos__FBSDID("$FreeBSD: head/sys/arm/allwinner/a20/a20_if_dwc.c 297627 2016-04-06 23:11:03Z jmcneill $"); 29288050Sloos 30288050Sloos#include <sys/param.h> 31288050Sloos#include <sys/systm.h> 32288050Sloos#include <sys/bus.h> 33288050Sloos#include <sys/kernel.h> 34288050Sloos#include <sys/module.h> 35288050Sloos 36288050Sloos#include <machine/bus.h> 37288050Sloos 38288050Sloos#include <dev/dwc/if_dwc.h> 39288050Sloos#include <dev/dwc/if_dwcvar.h> 40288050Sloos#include <dev/ofw/ofw_bus.h> 41288050Sloos#include <dev/ofw/ofw_bus_subr.h> 42288050Sloos 43296093Sandrew#include <arm/allwinner/allwinner_machdep.h> 44297627Sjmcneill#include <dev/extres/clk/clk.h> 45288050Sloos 46288050Sloos#include "if_dwc_if.h" 47288050Sloos 48288050Sloosstatic int 49288050Sloosa20_if_dwc_probe(device_t dev) 50288050Sloos{ 51288050Sloos 52288050Sloos if (!ofw_bus_status_okay(dev)) 53288050Sloos return (ENXIO); 54288050Sloos if (!ofw_bus_is_compatible(dev, "allwinner,sun7i-a20-gmac")) 55288050Sloos return (ENXIO); 56288050Sloos device_set_desc(dev, "A20 Gigabit Ethernet Controller"); 57288050Sloos 58288050Sloos return (BUS_PROBE_DEFAULT); 59288050Sloos} 60288050Sloos 61288050Sloosstatic int 62288050Sloosa20_if_dwc_init(device_t dev) 63288050Sloos{ 64297627Sjmcneill const char *tx_parent_name; 65297627Sjmcneill char *phy_type; 66297627Sjmcneill clk_t clk_tx, clk_tx_parent; 67297627Sjmcneill phandle_t node; 68297627Sjmcneill int error; 69288050Sloos 70297627Sjmcneill node = ofw_bus_get_node(dev); 71297627Sjmcneill 72297627Sjmcneill /* Configure PHY for MII or RGMII mode */ 73297627Sjmcneill if (OF_getprop_alloc(node, "phy-mode", 1, (void **)&phy_type)) { 74297627Sjmcneill error = clk_get_by_ofw_name(dev, "allwinner_gmac_tx", &clk_tx); 75297627Sjmcneill if (error != 0) { 76297627Sjmcneill device_printf(dev, "could not get tx clk\n"); 77297627Sjmcneill return (error); 78297627Sjmcneill } 79297627Sjmcneill 80297627Sjmcneill if (strcmp(phy_type, "rgmii") == 0) 81297627Sjmcneill tx_parent_name = "gmac_int_tx"; 82297627Sjmcneill else 83297627Sjmcneill tx_parent_name = "mii_phy_tx"; 84297627Sjmcneill 85297627Sjmcneill error = clk_get_by_name(dev, tx_parent_name, &clk_tx_parent); 86297627Sjmcneill if (error != 0) { 87297627Sjmcneill device_printf(dev, "could not get clock '%s'\n", 88297627Sjmcneill tx_parent_name); 89297627Sjmcneill return (error); 90297627Sjmcneill } 91297627Sjmcneill 92297627Sjmcneill error = clk_set_parent_by_clk(clk_tx, clk_tx_parent); 93297627Sjmcneill if (error != 0) { 94297627Sjmcneill device_printf(dev, "could not set tx clk parent\n"); 95297627Sjmcneill return (error); 96297627Sjmcneill } 97296093Sandrew } 98288050Sloos 99288050Sloos return (0); 100288050Sloos} 101288050Sloos 102288050Sloosstatic int 103288050Sloosa20_if_dwc_mac_type(device_t dev) 104288050Sloos{ 105288050Sloos 106288050Sloos return (DWC_GMAC_ALT_DESC); 107288050Sloos} 108288050Sloos 109288050Sloosstatic int 110288050Sloosa20_if_dwc_mii_clk(device_t dev) 111288050Sloos{ 112288050Sloos 113288050Sloos return (GMAC_MII_CLK_150_250M_DIV102); 114288050Sloos} 115288050Sloos 116288050Sloosstatic device_method_t a20_dwc_methods[] = { 117288050Sloos DEVMETHOD(device_probe, a20_if_dwc_probe), 118288050Sloos 119288050Sloos DEVMETHOD(if_dwc_init, a20_if_dwc_init), 120288050Sloos DEVMETHOD(if_dwc_mac_type, a20_if_dwc_mac_type), 121288050Sloos DEVMETHOD(if_dwc_mii_clk, a20_if_dwc_mii_clk), 122288050Sloos 123288050Sloos DEVMETHOD_END 124288050Sloos}; 125288050Sloos 126288050Sloosstatic devclass_t a20_dwc_devclass; 127288050Sloos 128288050Sloosextern driver_t dwc_driver; 129288050Sloos 130288050SloosDEFINE_CLASS_1(dwc, a20_dwc_driver, a20_dwc_methods, sizeof(struct dwc_softc), 131288050Sloos dwc_driver); 132288050SloosDRIVER_MODULE(a20_dwc, simplebus, a20_dwc_driver, a20_dwc_devclass, 0, 0); 133288050Sloos 134288050SloosMODULE_DEPEND(a20_dwc, dwc, 1, 1, 1); 135