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
if_eqos_starfive_set_speed(device_t dev,int speed)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
if_eqos_starfive_clk_init(device_t dev)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
if_eqos_starfive_init(device_t dev)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
eqos_starfive_probe(device_t dev)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