xref: /openbsd/sys/dev/fdt/if_dwqe_fdt.c (revision 5e1c6ec4)
1 /*	$OpenBSD: if_dwqe_fdt.c,v 1.18 2024/02/26 18:57:50 kettenis Exp $	*/
2 /*
3  * Copyright (c) 2008, 2019 Mark Kettenis <kettenis@openbsd.org>
4  * Copyright (c) 2017, 2022 Patrick Wildt <patrick@blueri.se>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /*
20  * Driver for the Synopsys Designware ethernet controller.
21  */
22 
23 #include "bpfilter.h"
24 
25 #include <sys/param.h>
26 #include <sys/systm.h>
27 #include <sys/device.h>
28 #include <sys/kernel.h>
29 #include <sys/malloc.h>
30 #include <sys/mbuf.h>
31 #include <sys/queue.h>
32 #include <sys/socket.h>
33 #include <sys/sockio.h>
34 #include <sys/timeout.h>
35 #include <sys/task.h>
36 
37 #include <machine/bus.h>
38 #include <machine/fdt.h>
39 
40 #include <net/if.h>
41 #include <net/if_media.h>
42 
43 #include <dev/ofw/openfirm.h>
44 #include <dev/ofw/ofw_clock.h>
45 #include <dev/ofw/ofw_gpio.h>
46 #include <dev/ofw/ofw_misc.h>
47 #include <dev/ofw/ofw_pinctrl.h>
48 #include <dev/ofw/ofw_regulator.h>
49 #include <dev/ofw/fdt.h>
50 
51 #include <dev/mii/mii.h>
52 #include <dev/mii/miivar.h>
53 
54 #if NBPFILTER > 0
55 #include <net/bpf.h>
56 #endif
57 
58 #include <netinet/in.h>
59 #include <netinet/if_ether.h>
60 
61 #include <dev/ic/dwqevar.h>
62 #include <dev/ic/dwqereg.h>
63 
64 struct dwqe_fdt_softc {
65 	struct dwqe_softc	sc_sc;
66 	struct if_device	sc_ifd;
67 	int			sc_gmac_id;
68 };
69 
70 int	dwqe_fdt_match(struct device *, void *, void *);
71 void	dwqe_fdt_attach(struct device *, struct device *, void *);
72 void	dwqe_setup_jh7110(struct dwqe_softc *);
73 void	dwqe_mii_statchg_jh7110(struct device *);
74 void	dwqe_setup_rk3568(struct dwqe_fdt_softc *);
75 void	dwqe_mii_statchg_rk3568(struct device *);
76 void	dwqe_setup_rk3588(struct dwqe_fdt_softc *);
77 void	dwqe_mii_statchg_rk3588(struct device *);
78 
79 const struct cfattach dwqe_fdt_ca = {
80 	sizeof(struct dwqe_fdt_softc), dwqe_fdt_match, dwqe_fdt_attach
81 };
82 
83 void	dwqe_reset_phy(struct dwqe_softc *, uint32_t);
84 
85 int
dwqe_fdt_match(struct device * parent,void * cfdata,void * aux)86 dwqe_fdt_match(struct device *parent, void *cfdata, void *aux)
87 {
88 	struct fdt_attach_args *faa = aux;
89 
90 	return OF_is_compatible(faa->fa_node, "snps,dwmac-4.20a") ||
91 	    OF_is_compatible(faa->fa_node, "snps,dwmac-5.20");
92 }
93 
94 void
dwqe_fdt_attach(struct device * parent,struct device * self,void * aux)95 dwqe_fdt_attach(struct device *parent, struct device *self, void *aux)
96 {
97 	struct dwqe_fdt_softc *fsc = (void *)self;
98 	struct dwqe_softc *sc = &fsc->sc_sc;
99 	struct fdt_attach_args *faa = aux;
100 	char phy_mode[16] = { 0 };
101 	uint32_t phy, phy_supply;
102 	uint32_t axi_config;
103 	struct ifnet *ifp = &sc->sc_ac.ac_if;
104 	int i, node;
105 
106 	sc->sc_node = faa->fa_node;
107 	sc->sc_iot = faa->fa_iot;
108 	if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr,
109 	    faa->fa_reg[0].size, 0, &sc->sc_ioh)) {
110 		printf(": cannot map registers\n");
111 		return;
112 	}
113 	sc->sc_dmat = faa->fa_dmat;
114 
115 	/* Decide GMAC id through address */
116 	switch (faa->fa_reg[0].addr) {
117 	case 0xfe2a0000:	/* RK3568 */
118 	case 0xfe1b0000:	/* RK3588 */
119 	case 0x16030000:	/* JH7110 */
120 		fsc->sc_gmac_id = 0;
121 		break;
122 	case 0xfe010000:	/* RK3568 */
123 	case 0xfe1c0000:	/* RK3588 */
124 	case 0x16040000:	/* JH7110 */
125 		fsc->sc_gmac_id = 1;
126 		break;
127 	default:
128 		printf(": unknown controller at 0x%llx\n", faa->fa_reg[0].addr);
129 		return;
130 	}
131 
132 	printf(" gmac %d", fsc->sc_gmac_id);
133 
134 	OF_getprop(faa->fa_node, "phy-mode", phy_mode, sizeof(phy_mode));
135 	if (strcmp(phy_mode, "rgmii") == 0)
136 		sc->sc_phy_mode = DWQE_PHY_MODE_RGMII;
137 	else if (strcmp(phy_mode, "rgmii-rxid") == 0)
138 		sc->sc_phy_mode = DWQE_PHY_MODE_RGMII_RXID;
139 	else if (strcmp(phy_mode, "rgmii-txid") == 0)
140 		sc->sc_phy_mode = DWQE_PHY_MODE_RGMII_TXID;
141 	else if (strcmp(phy_mode, "rgmii-id") == 0)
142 		sc->sc_phy_mode = DWQE_PHY_MODE_RGMII_ID;
143 	else if (strcmp(phy_mode, "rmii") == 0)
144 		sc->sc_phy_mode = DWQE_PHY_MODE_RMII;
145 	else
146 		sc->sc_phy_mode = DWQE_PHY_MODE_UNKNOWN;
147 
148 	/* Lookup PHY. */
149 	phy = OF_getpropint(faa->fa_node, "phy", 0);
150 	if (phy == 0)
151 		phy = OF_getpropint(faa->fa_node, "phy-handle", 0);
152 	node = OF_getnodebyphandle(phy);
153 	if (node)
154 		sc->sc_phyloc = OF_getpropint(node, "reg", MII_PHY_ANY);
155 	else
156 		sc->sc_phyloc = MII_PHY_ANY;
157 	sc->sc_mii.mii_node = node;
158 
159 	pinctrl_byname(faa->fa_node, "default");
160 
161 	/* Enable clocks. */
162 	clock_set_assigned(faa->fa_node);
163 	clock_enable(faa->fa_node, "stmmaceth");
164 	clock_enable(faa->fa_node, "pclk");
165 	reset_deassert(faa->fa_node, "stmmaceth");
166 	reset_deassert(faa->fa_node, "ahb");
167 	if (OF_is_compatible(faa->fa_node, "starfive,jh7110-dwmac")) {
168 		clock_enable(faa->fa_node, "tx");
169 		clock_enable(faa->fa_node, "gtx");
170 	} else if (OF_is_compatible(faa->fa_node, "rockchip,rk3568-gmac") ||
171 	    OF_is_compatible(faa->fa_node, "rockchip,rk3588-gmac")) {
172 		clock_enable(faa->fa_node, "aclk_mac");
173 		clock_enable(faa->fa_node, "pclk_mac");
174 		clock_enable(faa->fa_node, "mac_clk_tx");
175 		clock_enable(faa->fa_node, "clk_mac_speed");
176 		if (strcmp(phy_mode, "rmii") == 0) {
177 			clock_enable(faa->fa_node, "mac_clk_rx");
178 			clock_enable(faa->fa_node, "clk_mac_ref");
179 			clock_enable(faa->fa_node, "clk_mac_refout");
180 		}
181 	}
182 	delay(5000);
183 
184 	/* Do hardware specific initializations. */
185 	if (OF_is_compatible(faa->fa_node, "starfive,jh7110-dwmac"))
186 		dwqe_setup_jh7110(sc);
187 	else if (OF_is_compatible(faa->fa_node, "rockchip,rk3568-gmac"))
188 		dwqe_setup_rk3568(fsc);
189 	else if (OF_is_compatible(faa->fa_node, "rockchip,rk3588-gmac"))
190 		dwqe_setup_rk3588(fsc);
191 
192 	/* Power up PHY. */
193 	phy_supply = OF_getpropint(faa->fa_node, "phy-supply", 0);
194 	if (phy_supply)
195 		regulator_enable(phy_supply);
196 
197 	/* Reset PHY */
198 	dwqe_reset_phy(sc, phy);
199 
200 	node = OF_getnodebyname(sc->sc_node, "fixed-link");
201 	if (node) {
202 		sc->sc_fixed_link = 1;
203 
204 		ifp->if_baudrate = IF_Mbps(OF_getpropint(node, "speed", 0));
205 		ifp->if_link_state = OF_getpropbool(node, "full-duplex") ?
206 		    LINK_STATE_FULL_DUPLEX : LINK_STATE_HALF_DUPLEX;
207 	}
208 
209 	sc->sc_clkrate = clock_get_frequency(faa->fa_node, "stmmaceth");
210 	if (sc->sc_clkrate > 500000000)
211 		sc->sc_clk = GMAC_MAC_MDIO_ADDR_CR_500_800;
212 	else if (sc->sc_clkrate > 300000000)
213 		sc->sc_clk = GMAC_MAC_MDIO_ADDR_CR_300_500;
214 	else if (sc->sc_clkrate > 150000000)
215 		sc->sc_clk = GMAC_MAC_MDIO_ADDR_CR_150_250;
216 	else if (sc->sc_clkrate > 100000000)
217 		sc->sc_clk = GMAC_MAC_MDIO_ADDR_CR_100_150;
218 	else if (sc->sc_clkrate > 60000000)
219 		sc->sc_clk = GMAC_MAC_MDIO_ADDR_CR_60_100;
220 	else if (sc->sc_clkrate > 35000000)
221 		sc->sc_clk = GMAC_MAC_MDIO_ADDR_CR_35_60;
222 	else
223 		sc->sc_clk = GMAC_MAC_MDIO_ADDR_CR_20_35;
224 
225 	for (i = 0; i < 4; i++)
226 		sc->sc_hw_feature[i] = dwqe_read(sc, GMAC_MAC_HW_FEATURE(i));
227 
228 	if (OF_getprop(faa->fa_node, "local-mac-address",
229 	    &sc->sc_lladdr, ETHER_ADDR_LEN) != ETHER_ADDR_LEN)
230 		dwqe_lladdr_read(sc, sc->sc_lladdr);
231 
232 	sc->sc_force_thresh_dma_mode =
233 	    OF_getpropbool(faa->fa_node, "snps,force_thresh_dma_mode");
234 
235 	dwqe_reset(sc);
236 
237 	sc->sc_fixed_burst = OF_getpropbool(faa->fa_node, "snps,fixed-burst");
238 	sc->sc_mixed_burst = OF_getpropbool(faa->fa_node, "snps,mixed-burst");
239 	sc->sc_aal = OF_getpropbool(faa->fa_node, "snps,aal");
240 	sc->sc_8xpbl = !OF_getpropbool(faa->fa_node, "snps,no-pbl-x8");
241 	sc->sc_pbl = OF_getpropint(faa->fa_node, "snps,pbl", 8);
242 	sc->sc_txpbl = OF_getpropint(faa->fa_node, "snps,txpbl", sc->sc_pbl);
243 	sc->sc_rxpbl = OF_getpropint(faa->fa_node, "snps,rxpbl", sc->sc_pbl);
244 
245 	/* Configure AXI master. */
246 	axi_config = OF_getpropint(faa->fa_node, "snps,axi-config", 0);
247 	node = OF_getnodebyphandle(axi_config);
248 	if (node) {
249 		sc->sc_axi_config = 1;
250 		sc->sc_lpi_en = OF_getpropbool(node, "snps,lpi_en");
251 		sc->sc_xit_frm = OF_getpropbool(node, "snps,xit_frm");
252 
253 		sc->sc_wr_osr_lmt = OF_getpropint(node, "snps,wr_osr_lmt", 1);
254 		sc->sc_rd_osr_lmt = OF_getpropint(node, "snps,rd_osr_lmt", 1);
255 
256 		OF_getpropintarray(node, "snps,blen", sc->sc_blen, sizeof(sc->sc_blen));
257 	}
258 
259 	if (dwqe_attach(sc) != 0)
260 		return;
261 
262 	if (OF_is_compatible(faa->fa_node, "starfive,jh7110-dwmac") &&
263 	    !OF_getpropbool(faa->fa_node, "starfive,tx-use-rgmii-clk"))
264 		sc->sc_mii.mii_statchg = dwqe_mii_statchg_jh7110;
265 	else if (OF_is_compatible(faa->fa_node, "rockchip,rk3568-gmac"))
266 		sc->sc_mii.mii_statchg = dwqe_mii_statchg_rk3568;
267 	else if (OF_is_compatible(faa->fa_node, "rockchip,rk3588-gmac"))
268 		sc->sc_mii.mii_statchg = dwqe_mii_statchg_rk3588;
269 
270 	sc->sc_ih = fdt_intr_establish(faa->fa_node, IPL_NET | IPL_MPSAFE,
271 	    dwqe_intr, sc, sc->sc_dev.dv_xname);
272 	if (sc->sc_ih == NULL)
273 		printf("%s: can't establish interrupt\n", sc->sc_dev.dv_xname);
274 
275 	fsc->sc_ifd.if_node = faa->fa_node;
276 	fsc->sc_ifd.if_ifp = ifp;
277 	if_register(&fsc->sc_ifd);
278 
279 	/* force a configuration of the clocks/mac */
280 	if (sc->sc_fixed_link)
281 		sc->sc_mii.mii_statchg(self);
282 }
283 
284 void
dwqe_reset_phy(struct dwqe_softc * sc,uint32_t phy)285 dwqe_reset_phy(struct dwqe_softc *sc, uint32_t phy)
286 {
287 	uint32_t *gpio;
288 	uint32_t delays[3];
289 	int active = 1;
290 	int node, len;
291 
292 	node = OF_getnodebyphandle(phy);
293 	if (node && OF_getproplen(node, "reset-gpios") > 0) {
294 		len = OF_getproplen(node, "reset-gpios");
295 
296 		gpio = malloc(len, M_TEMP, M_WAITOK);
297 
298 		/* Gather information. */
299 		OF_getpropintarray(node, "reset-gpios", gpio, len);
300 		delays[0] = OF_getpropint(node, "reset-deassert-us", 0);
301 		delays[1] = OF_getpropint(node, "reset-assert-us", 0);
302 		delays[2] = OF_getpropint(node, "reset-deassert-us", 0);
303 	} else {
304 		len = OF_getproplen(sc->sc_node, "snps,reset-gpio");
305 		if (len <= 0)
306 			return;
307 
308 		gpio = malloc(len, M_TEMP, M_WAITOK);
309 
310 		/* Gather information. */
311 		OF_getpropintarray(sc->sc_node, "snps,reset-gpio", gpio, len);
312 		if (OF_getpropbool(sc->sc_node, "snps-reset-active-low"))
313 			active = 0;
314 		delays[0] = delays[1] = delays[2] = 0;
315 		OF_getpropintarray(sc->sc_node, "snps,reset-delays-us", delays,
316 		    sizeof(delays));
317 	}
318 
319 	/* Perform reset sequence. */
320 	gpio_controller_config_pin(gpio, GPIO_CONFIG_OUTPUT);
321 	gpio_controller_set_pin(gpio, !active);
322 	delay(delays[0]);
323 	gpio_controller_set_pin(gpio, active);
324 	delay(delays[1]);
325 	gpio_controller_set_pin(gpio, !active);
326 	delay(delays[2]);
327 
328 	free(gpio, M_TEMP, len);
329 }
330 
331 /* JH7110 registers */
332 #define JH7110_PHY_INTF_RGMII		1
333 #define JH7110_PHY_INTF_RMII		4
334 
335 /* RK3568 registers */
336 #define RK3568_GRF_GMACx_CON0(x)	(0x0380 + (x) * 0x8)
337 #define  RK3568_GMAC_CLK_RX_DL_CFG(val)		((0x7f << 8) << 16 | ((val) << 8))
338 #define  RK3568_GMAC_CLK_TX_DL_CFG(val)		((0x7f << 0) << 16 | ((val) << 0))
339 #define RK3568_GRF_GMACx_CON1(x)	(0x0384 + (x) * 0x8)
340 #define  RK3568_GMAC_PHY_INTF_SEL_RGMII		((0x7 << 4) << 16 | (0x1 << 4))
341 #define  RK3568_GMAC_PHY_INTF_SEL_RMII		((0x7 << 4) << 16 | (0x4 << 4))
342 #define  RK3568_GMAC_TXCLK_DLY_SET(_v)		((1 << 0) << 16 | ((_v) << 0))
343 #define  RK3568_GMAC_RXCLK_DLY_SET(_v)		((1 << 1) << 16 | ((_v) << 1))
344 
345 /* RK3588 registers */
346 #define RK3588_GRF_GMAC_CON7		0x031c
347 #define  RK3588_GMACx_RXCLK_DLY_ENA(id)		((1 << (2 * (id) + 3)) << 16 | (1 << (2 * (id) + 3)))
348 #define  RK3588_GMACx_TXCLK_DLY_ENA(id)		((1 << (2 * (id) + 2)) << 16 | (1 << (2 * (id) + 2)))
349 #define RK3588_GRF_GMAC_CON8		0x0320
350 #define RK3588_GRF_GMAC_CON9		0x0324
351 #define  RK3588_GMAC_CLK_RX_DL_CFG(val)		((0x7f << 8) << 16 | ((val) << 8))
352 #define  RK3588_GMAC_CLK_TX_DL_CFG(val)		((0x7f << 0) << 16 | ((val) << 0))
353 #define RK3588_PHP_GRF_GMAC_CON0	0x0008
354 #define  RK3588_GMACx_PHY_INTF_SEL_RGMII(id)	((0x7 << (6 * (id) + 3)) << 16 | (0x1 << (6 * (id) + 3)))
355 #define  RK3588_GMACx_PHY_INTF_SEL_RMII(id)	((0x7 << (6 * (id) + 3)) << 16 | (0x4 << (6 * (id) + 3)))
356 #define RK3588_PHP_GRF_CLK_CON1		0x0070
357 #define  RK3588_RMII_MODE_GMACx_RMII(id)	((0x1 << (5 * (id))) << 16 | (0x1 << (5 * (id))))
358 #define  RK3588_RMII_MODE_GMACx_RGMII(id)	((0x1 << (5 * (id))) << 16 | (0x0 << (5 * (id))))
359 #define  RK3588_MII_TX_CLK_SEL_RMII_2_5(id)	((0x3 << (5 * (id) + 2)) << 16 | (0x1 << (5 * (id) + 2)))
360 #define  RK3588_MII_TX_CLK_SEL_RMII_25(id)	((0x3 << (5 * (id) + 2)) << 16 | (0x0 << (5 * (id) + 2)))
361 #define  RK3588_MII_TX_CLK_SEL_RGMII_2_5(id)	((0x3 << (5 * (id) + 2)) << 16 | (0x2 << (5 * (id) + 2)))
362 #define  RK3588_MII_TX_CLK_SEL_RGMII_25(id)	((0x3 << (5 * (id) + 2)) << 16 | (0x3 << (5 * (id) + 2)))
363 #define  RK3588_MII_TX_CLK_SEL_RGMII_125(id)	((0x3 << (5 * (id) + 2)) << 16 | (0x0 << (5 * (id) + 2)))
364 
365 void	dwqe_mii_statchg_jh7110_task(void *);
366 void	dwqe_mii_statchg_rk3568_task(void *);
367 
368 void
dwqe_setup_jh7110(struct dwqe_softc * sc)369 dwqe_setup_jh7110(struct dwqe_softc *sc)
370 {
371 	struct regmap *rm;
372 	uint32_t cells[3];
373 	uint32_t phandle, offset, reg, shift;
374 	char phy_mode[32];
375 	uint32_t iface;
376 
377 	if (OF_getpropintarray(sc->sc_node, "starfive,syscon", cells,
378 	    sizeof(cells)) != sizeof(cells)) {
379 		printf("%s: failed to get starfive,syscon\n", __func__);
380 		return;
381 	}
382 	phandle = cells[0];
383 	offset = cells[1];
384 	shift = cells[2];
385 
386 	rm = regmap_byphandle(phandle);
387 	if (rm == NULL) {
388 		printf("%s: failed to get regmap\n", __func__);
389 		return;
390 	}
391 
392 	if (OF_getprop(sc->sc_node, "phy-mode", phy_mode,
393 	    sizeof(phy_mode)) <= 0)
394 		return;
395 
396 	if (strcmp(phy_mode, "rgmii") == 0 ||
397 	    strcmp(phy_mode, "rgmii-id") == 0) {
398 		iface = JH7110_PHY_INTF_RGMII;
399 	} else if (strcmp(phy_mode, "rmii") == 0) {
400 		iface = JH7110_PHY_INTF_RMII;
401 	} else
402 		return;
403 
404 	reg = regmap_read_4(rm, offset);
405 	reg &= ~(((1U << 3) - 1) << shift);
406 	reg |= iface << shift;
407 	regmap_write_4(rm, offset, reg);
408 
409 	task_set(&sc->sc_statchg_task,
410 	    dwqe_mii_statchg_jh7110_task, sc);
411 }
412 
413 void
dwqe_mii_statchg_jh7110_task(void * arg)414 dwqe_mii_statchg_jh7110_task(void *arg)
415 {
416 	struct dwqe_softc *sc = arg;
417 	struct ifnet *ifp = &sc->sc_ac.ac_if;
418 
419 	dwqe_mii_statchg(&sc->sc_dev);
420 
421 	switch (ifp->if_baudrate) {
422 	case IF_Mbps(10):
423 		clock_set_frequency(sc->sc_node, "tx", 2500000);
424 		break;
425 	case IF_Mbps(100):
426 		clock_set_frequency(sc->sc_node, "tx", 25000000);
427 		break;
428 	case IF_Mbps(1000):
429 		clock_set_frequency(sc->sc_node, "tx", 125000000);
430 		break;
431 	}
432 }
433 
434 void
dwqe_mii_statchg_jh7110(struct device * self)435 dwqe_mii_statchg_jh7110(struct device *self)
436 {
437 	struct dwqe_softc *sc = (void *)self;
438 
439 	task_add(systq, &sc->sc_statchg_task);
440 }
441 
442 void
dwqe_setup_rk3568(struct dwqe_fdt_softc * fsc)443 dwqe_setup_rk3568(struct dwqe_fdt_softc *fsc)
444 {
445 	struct dwqe_softc *sc = &fsc->sc_sc;
446 	struct regmap *rm;
447 	uint32_t grf;
448 	int tx_delay, rx_delay;
449 	uint32_t iface;
450 
451 	grf = OF_getpropint(sc->sc_node, "rockchip,grf", 0);
452 	rm = regmap_byphandle(grf);
453 	if (rm == NULL)
454 		return;
455 
456 	switch (sc->sc_phy_mode) {
457 	case DWQE_PHY_MODE_RGMII:
458 	case DWQE_PHY_MODE_RGMII_ID:
459 	case DWQE_PHY_MODE_RGMII_RXID:
460 	case DWQE_PHY_MODE_RGMII_TXID:
461 		iface = RK3568_GMAC_PHY_INTF_SEL_RGMII;
462 		break;
463 	case DWQE_PHY_MODE_RMII:
464 		iface = RK3568_GMAC_PHY_INTF_SEL_RMII;
465 		break;
466 	default:
467 		return;
468 	}
469 
470 	tx_delay = OF_getpropint(sc->sc_node, "tx_delay", 0x30);
471 	rx_delay = OF_getpropint(sc->sc_node, "rx_delay", 0x10);
472 	switch (sc->sc_phy_mode) {
473 	case DWQE_PHY_MODE_RGMII_ID:
474 		tx_delay = rx_delay = 0;
475 		break;
476 	case DWQE_PHY_MODE_RGMII_RXID:
477 		rx_delay = 0;
478 		break;
479 	case DWQE_PHY_MODE_RGMII_TXID:
480 		tx_delay = 0;
481 		break;
482 	default:
483 		break;
484 	}
485 
486 	/* Program clock delay lines. */
487 	regmap_write_4(rm, RK3568_GRF_GMACx_CON0(fsc->sc_gmac_id),
488 	    RK3568_GMAC_CLK_TX_DL_CFG(tx_delay) |
489 	    RK3568_GMAC_CLK_RX_DL_CFG(rx_delay));
490 
491 	/* Set interface and enable/disable clock delay. */
492 	regmap_write_4(rm, RK3568_GRF_GMACx_CON1(fsc->sc_gmac_id), iface |
493 	    RK3568_GMAC_TXCLK_DLY_SET(tx_delay > 0 ? 1 : 0) |
494 	    RK3568_GMAC_RXCLK_DLY_SET(rx_delay > 0 ? 1 : 0));
495 
496 	task_set(&sc->sc_statchg_task,
497 	    dwqe_mii_statchg_rk3568_task, sc);
498 }
499 
500 void
dwqe_mii_statchg_rk3568_task(void * arg)501 dwqe_mii_statchg_rk3568_task(void *arg)
502 {
503 	struct dwqe_softc *sc = arg;
504 	struct ifnet *ifp = &sc->sc_ac.ac_if;
505 
506 	dwqe_mii_statchg(&sc->sc_dev);
507 
508 	switch (ifp->if_baudrate) {
509 	case IF_Mbps(10):
510 		clock_set_frequency(sc->sc_node, "clk_mac_speed", 2500000);
511 		break;
512 	case IF_Mbps(100):
513 		clock_set_frequency(sc->sc_node, "clk_mac_speed", 25000000);
514 		break;
515 	case IF_Mbps(1000):
516 		clock_set_frequency(sc->sc_node, "clk_mac_speed", 125000000);
517 		break;
518 	}
519 }
520 
521 void
dwqe_mii_statchg_rk3568(struct device * self)522 dwqe_mii_statchg_rk3568(struct device *self)
523 {
524 	struct dwqe_softc *sc = (void *)self;
525 
526 	task_add(systq, &sc->sc_statchg_task);
527 }
528 
529 void
dwqe_setup_rk3588(struct dwqe_fdt_softc * fsc)530 dwqe_setup_rk3588(struct dwqe_fdt_softc *fsc)
531 {
532 	struct dwqe_softc *sc = &fsc->sc_sc;
533 	struct regmap *rm;
534 	struct regmap *php_rm;
535 	uint32_t grf, php_grf;
536 	int tx_delay, rx_delay;
537 	uint32_t iface, clk;
538 
539 	grf = OF_getpropint(sc->sc_node, "rockchip,grf", 0);
540 	rm = regmap_byphandle(grf);
541 	if (rm == NULL)
542 		return;
543 
544 	php_grf = OF_getpropint(sc->sc_node, "rockchip,php-grf", 0);
545 	php_rm = regmap_byphandle(php_grf);
546 	if (php_rm == NULL)
547 		return;
548 
549 	switch (sc->sc_phy_mode) {
550 	case DWQE_PHY_MODE_RGMII:
551 	case DWQE_PHY_MODE_RGMII_ID:
552 	case DWQE_PHY_MODE_RGMII_RXID:
553 	case DWQE_PHY_MODE_RGMII_TXID:
554 		iface = RK3588_GMACx_PHY_INTF_SEL_RGMII(fsc->sc_gmac_id);
555 		clk = RK3588_RMII_MODE_GMACx_RGMII(fsc->sc_gmac_id);
556 		sc->sc_clk_sel_2_5 =
557 		    RK3588_MII_TX_CLK_SEL_RGMII_2_5(fsc->sc_gmac_id);
558 		sc->sc_clk_sel_25 =
559 		    RK3588_MII_TX_CLK_SEL_RGMII_25(fsc->sc_gmac_id);
560 		sc->sc_clk_sel_125 =
561 		    RK3588_MII_TX_CLK_SEL_RGMII_125(fsc->sc_gmac_id);
562 		break;
563 	case DWQE_PHY_MODE_RMII:
564 		iface = RK3588_GMACx_PHY_INTF_SEL_RMII(fsc->sc_gmac_id);
565 		clk = RK3588_RMII_MODE_GMACx_RMII(fsc->sc_gmac_id);
566 		sc->sc_clk_sel_2_5 =
567 		    RK3588_MII_TX_CLK_SEL_RMII_2_5(fsc->sc_gmac_id);
568 		sc->sc_clk_sel_25 =
569 		    RK3588_MII_TX_CLK_SEL_RMII_25(fsc->sc_gmac_id);
570 		break;
571 	default:
572 		return;
573 	}
574 
575 	tx_delay = OF_getpropint(sc->sc_node, "tx_delay", 0x30);
576 	rx_delay = OF_getpropint(sc->sc_node, "rx_delay", 0x10);
577 	switch (sc->sc_phy_mode) {
578 	case DWQE_PHY_MODE_RGMII_ID:
579 		tx_delay = rx_delay = 0;
580 		break;
581 	case DWQE_PHY_MODE_RGMII_RXID:
582 		rx_delay = 0;
583 		break;
584 	case DWQE_PHY_MODE_RGMII_TXID:
585 		tx_delay = 0;
586 		break;
587 	default:
588 		break;
589 	}
590 
591 	/* Set interface and clock. */
592 	regmap_write_4(php_rm, RK3588_PHP_GRF_GMAC_CON0, iface);
593 	regmap_write_4(php_rm, RK3588_PHP_GRF_CLK_CON1, clk);
594 
595 	/* Enable clock delay. */
596 	regmap_write_4(rm, RK3588_GRF_GMAC_CON7,
597 	    RK3588_GMACx_TXCLK_DLY_ENA(fsc->sc_gmac_id) |
598 	    RK3588_GMACx_RXCLK_DLY_ENA(fsc->sc_gmac_id));
599 
600 	/* Program clock delay lines. */
601 	regmap_write_4(rm, fsc->sc_gmac_id == 1 ?
602 	    RK3588_GRF_GMAC_CON9 : RK3588_GRF_GMAC_CON8,
603 	    RK3588_GMAC_CLK_TX_DL_CFG(tx_delay) |
604 	    RK3588_GMAC_CLK_RX_DL_CFG(rx_delay));
605 }
606 
607 void
dwqe_mii_statchg_rk3588(struct device * self)608 dwqe_mii_statchg_rk3588(struct device *self)
609 {
610 	struct dwqe_softc *sc = (void *)self;
611 	struct ifnet *ifp = &sc->sc_ac.ac_if;
612 	struct regmap *php_rm;
613 	uint32_t php_grf;
614 	uint32_t gmac_clk_sel = 0;
615 
616 	dwqe_mii_statchg(self);
617 
618 	php_grf = OF_getpropint(sc->sc_node, "rockchip,php-grf", 0);
619 	php_rm = regmap_byphandle(php_grf);
620 	if (php_rm == NULL)
621 		return;
622 
623 	switch (ifp->if_baudrate) {
624 	case IF_Mbps(10):
625 		gmac_clk_sel = sc->sc_clk_sel_2_5;
626 		break;
627 	case IF_Mbps(100):
628 		gmac_clk_sel = sc->sc_clk_sel_25;
629 		break;
630 	case IF_Mbps(1000):
631 		gmac_clk_sel = sc->sc_clk_sel_125;
632 		break;
633 	}
634 
635 	regmap_write_4(php_rm, RK3588_PHP_GRF_CLK_CON1, gmac_clk_sel);
636 }
637