1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2024 Jari Sihvola <jsihv@gmx.com> 5 */ 6 7 #include "opt_platform.h" 8 #include <sys/cdefs.h> 9 #include <sys/param.h> 10 #include <sys/bus.h> 11 #include <sys/kernel.h> 12 #include <sys/module.h> 13 #include <sys/systm.h> 14 #include <sys/endian.h> 15 #include <sys/gpio.h> 16 #include <sys/rman.h> 17 #include <sys/socket.h> 18 #include <machine/bus.h> 19 20 #include <net/if.h> 21 #include <net/if_media.h> 22 #include <dev/mii/mii.h> 23 #include <dev/mii/miivar.h> 24 25 #include <dev/ofw/ofw_bus.h> 26 #include <dev/ofw/ofw_bus_subr.h> 27 28 #include <dev/hwreset/hwreset.h> 29 #include <dev/regulator/regulator.h> 30 31 #include <dev/eqos/if_eqos_var.h> 32 33 #include "if_eqos_if.h" 34 #include "gpio_if.h" 35 36 #include <dev/clk/clk.h> 37 38 /* JH7110's board specific code for eqos Ethernet controller driver */ 39 40 #define JH7110_CSR_FREQ 198000000 41 42 #define WR4(sc, o, v) bus_write_4(sc->base.res[EQOS_RES_MEM], (o), (v)) 43 44 static const struct ofw_compat_data compat_data[] = { 45 {"starfive,jh7110-dwmac", 1}, 46 { NULL, 0} 47 }; 48 49 struct if_eqos_starfive_softc { 50 struct eqos_softc base; 51 clk_t gtx; 52 clk_t tx; 53 clk_t stmmaceth; 54 clk_t pclk; 55 }; 56 57 static int 58 if_eqos_starfive_set_speed(device_t dev, int speed) 59 { 60 struct if_eqos_starfive_softc *sc = device_get_softc(dev); 61 uint64_t freq; 62 int err; 63 64 switch (speed) { 65 case IFM_1000_T: 66 case IFM_1000_SX: 67 freq = 125000000; 68 break; 69 case IFM_100_TX: 70 freq = 25000000; 71 break; 72 case IFM_10_T: 73 freq = 2500000; 74 break; 75 default: 76 device_printf(dev, "unsupported media %u\n", speed); 77 return (-EINVAL); 78 } 79 80 clk_set_freq(sc->gtx, freq, 0); 81 err = clk_enable(sc->gtx); 82 if (err != 0) { 83 device_printf(dev, "Could not enable clock %s\n", 84 clk_get_name(sc->gtx)); 85 } 86 87 return (0); 88 } 89 90 91 92 static int 93 if_eqos_starfive_clk_init(device_t dev) 94 { 95 struct if_eqos_starfive_softc *sc = device_get_softc(dev); 96 int err; 97 98 if (clk_get_by_ofw_name(dev, 0, "gtx", &sc->gtx) != 0) { 99 device_printf(sc->base.dev, "could not get gtx clock\n"); 100 return (ENXIO); 101 } 102 103 if (clk_get_by_ofw_name(dev, 0, "tx", &sc->tx) == 0) { 104 err = clk_enable(sc->tx); 105 if (err != 0) { 106 device_printf(dev, "Could not enable clock %s\n", 107 clk_get_name(sc->tx)); 108 } 109 } 110 if (clk_get_by_ofw_name(dev, 0, "stmmaceth", &sc->stmmaceth) == 0) { 111 err = clk_enable(sc->stmmaceth); 112 if (err != 0) { 113 device_printf(dev, "Could not enable clock %s\n", 114 clk_get_name(sc->stmmaceth)); 115 } 116 } 117 if (clk_get_by_ofw_name(dev, 0, "pclk", &sc->pclk) == 0) { 118 err = clk_enable(sc->pclk); 119 if (err != 0) { 120 device_printf(dev, "Could not enable clock %s\n", 121 clk_get_name(sc->pclk)); 122 } 123 } 124 125 return (0); 126 } 127 128 static int 129 if_eqos_starfive_init(device_t dev) 130 { 131 struct if_eqos_starfive_softc *sc = device_get_softc(dev); 132 hwreset_t rst_ahb, rst_stmmaceth; 133 phandle_t node; 134 135 node = ofw_bus_get_node(dev); 136 137 sc->base.ttc = 0x10; 138 sc->base.rtc = 0; 139 140 if (OF_hasprop(node, "snps,force_thresh_dma_mode")) 141 sc->base.thresh_dma_mode = true; 142 143 if (OF_hasprop(node, "snps,no-pbl-x8")) 144 sc->base.pblx8 = false; 145 146 if (OF_hasprop(node, "snps,txpbl")) { 147 OF_getencprop(node, "snps,txpbl", &sc->base.txpbl, 148 sizeof(sc->base.txpbl)); 149 } 150 if (OF_hasprop(node, "snps,rxpbl")) { 151 OF_getencprop(node, "snps,rxpbl", &sc->base.rxpbl, 152 sizeof(sc->base.rxpbl)); 153 } 154 155 if (hwreset_get_by_ofw_name(dev, 0, "ahb", &rst_ahb)) { 156 device_printf(dev, "Cannot get ahb reset\n"); 157 return (ENXIO); 158 } 159 if (hwreset_assert(rst_ahb) != 0) { 160 device_printf(dev, "Cannot assert ahb reset\n"); 161 return (ENXIO); 162 } 163 164 if (hwreset_get_by_ofw_name(dev, 0, "stmmaceth", &rst_stmmaceth)) { 165 device_printf(dev, "Cannot get stmmaceth reset\n"); 166 return (ENXIO); 167 } 168 if (hwreset_assert(rst_stmmaceth) != 0) { 169 device_printf(dev, "Cannot assert stmmaceth reset\n"); 170 return (ENXIO); 171 } 172 173 sc->base.csr_clock = JH7110_CSR_FREQ; 174 sc->base.csr_clock_range = GMAC_MAC_MDIO_ADDRESS_CR_150_250; 175 176 if (if_eqos_starfive_clk_init(dev) != 0) { 177 device_printf(dev, "Clock initialization failed\n"); 178 return (ENXIO); 179 } 180 if (hwreset_deassert(rst_ahb) != 0) { 181 device_printf(dev, "Cannot deassert rst_ahb\n"); 182 return (ENXIO); 183 } 184 if (hwreset_deassert(rst_stmmaceth) != 0) { 185 device_printf(dev, "Cannot deassert rst_stmmaceth\n"); 186 return (ENXIO); 187 } 188 189 return (0); 190 } 191 192 static int 193 eqos_starfive_probe(device_t dev) 194 { 195 if (!ofw_bus_status_okay(dev)) 196 return (ENXIO); 197 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) 198 return (ENXIO); 199 200 device_set_desc(dev, "DesignWare EQOS Gigabit Ethernet for JH7110"); 201 202 return (BUS_PROBE_DEFAULT); 203 } 204 205 206 static device_method_t eqos_starfive_methods[] = { 207 /* Device interface */ 208 DEVMETHOD(device_probe, eqos_starfive_probe), 209 210 /* EQOS interface */ 211 DEVMETHOD(if_eqos_init, if_eqos_starfive_init), 212 DEVMETHOD(if_eqos_set_speed, if_eqos_starfive_set_speed), 213 214 DEVMETHOD_END 215 }; 216 217 DEFINE_CLASS_1(eqos, eqos_starfive_driver, eqos_starfive_methods, 218 sizeof(struct if_eqos_starfive_softc), eqos_driver); 219 DRIVER_MODULE(eqos_starfive, simplebus, eqos_starfive_driver, 0, 0); 220