xref: /freebsd/sys/dev/eqos/if_eqos_starfive.c (revision cd92dd23241e22dce06ebeb0c8e98eec5afcc896)
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