xref: /openbsd/sys/arch/riscv64/dev/stfclock.c (revision 3bef86f7)
1 /*	$OpenBSD: stfclock.c,v 1.12 2023/09/23 18:29:55 kettenis Exp $	*/
2 /*
3  * Copyright (c) 2022 Mark Kettenis <kettenis@openbsd.org>
4  * Copyright (c) 2023 Joel Sing <jsing@openbsd.org>
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 #include <sys/param.h>
20 #include <sys/systm.h>
21 #include <sys/device.h>
22 #include <sys/malloc.h>
23 
24 #include <machine/intr.h>
25 #include <machine/bus.h>
26 #include <machine/fdt.h>
27 
28 #include <dev/ofw/openfirm.h>
29 #include <dev/ofw/ofw_clock.h>
30 #include <dev/ofw/ofw_misc.h>
31 #include <dev/ofw/fdt.h>
32 
33 /* JH7100 Clock IDs */
34 #define JH7100_CLK_CPUNDBUS_ROOT	0
35 #define JH7100_CLK_GMACUSB_ROOT		3
36 #define JH7100_CLK_PERH0_ROOT		4
37 #define JH7100_CLK_PERH1_ROOT		5
38 #define JH7100_CLK_CPUNBUS_ROOT_DIV	12
39 #define JH7100_CLK_PERH0_SRC		14
40 #define JH7100_CLK_PERH1_SRC		15
41 #define JH7100_CLK_PLL2_REF		19
42 #define JH7100_CLK_AHB_BUS		22
43 #define JH7100_CLK_SDIO0_AHB		114
44 #define JH7100_CLK_SDIO0_CCLKINT	115
45 #define JH7100_CLK_SDIO0_CCLKINT_INV	116
46 #define JH7100_CLK_SDIO1_AHB		117
47 #define JH7100_CLK_SDIO1_CCLKINT	118
48 #define JH7100_CLK_SDIO1_CCLKINT_INV	119
49 #define JH7100_CLK_GMAC_AHB		120
50 #define JH7100_CLK_GMAC_ROOT_DIV	121
51 #define JH7100_CLK_GMAC_GTX		123
52 #define JH7100_CLK_UART0_CORE		147
53 #define JH7100_CLK_UART3_CORE		162
54 #define JH7100_CLK_TEMP_APB		183
55 #define JH7100_CLK_TEMP_SENSE		184
56 #define JH7100_CLK_PLL0_OUT		186
57 #define JH7100_CLK_PLL1_OUT		187
58 #define JH7100_CLK_PLL2_OUT		188
59 
60 #define JH7100_CLK_OSC_SYS		255
61 #define JH7100_CLK_OSC_AUD		254
62 
63 /* JH7110 Clock IDs */
64 #define JH7110_AONCLK_GMAC0_AHB		2
65 #define JH7110_AONCLK_GMAC0_AXI		3
66 #define JH7110_AONCLK_GMAC0_RMII_RTX	4
67 #define JH7110_AONCLK_GMAC0_TX		5
68 #define JH7110_AONCLK_GMAC0_TX_INV	6
69 
70 #define JH7110_AONCLK_OSC		14
71 #define JH7110_AONCLK_GMAC0_RMII_REFIN	15
72 #define JH7110_AONCLK_STG_AXIAHB	17
73 #define JH7110_AONCLK_GMAC0_GTXCLK	19
74 
75 #define JH7110_AONCLK_ASSERT_OFFSET	0x38
76 #define JH7110_AONCLK_STATUS_OFFSET	0x3c
77 
78 #define JH7110_CLK_PLL0_OUT		0
79 #define JH7110_CLK_PLL1_OUT		1
80 #define JH7110_CLK_PLL2_OUT		2
81 
82 #define JH7110_STGCLK_PCIE0_AXI_MST0	8
83 #define JH7110_STGCLK_PCIE0_APB		9
84 #define JH7110_STGCLK_PCIE0_TL		10
85 #define JH7110_STGCLK_PCIE1_AXI_MST0	11
86 #define JH7110_STGCLK_PCIE1_APB		12
87 #define JH7110_STGCLK_PCIE1_TL		13
88 #define JH7110_STGCLK_SEC_AHB		15
89 #define JH7110_STGCLK_SEC_MISC_AHB	16
90 
91 #define JH7110_STGCLK_ASSERT_OFFSET	0x74
92 #define JH7110_STGCLK_STATUS_OFFSET	0x78
93 
94 #define JH7110_SYSCLK_CPU_ROOT		0
95 #define JH7110_SYSCLK_CPU_CORE		1
96 #define JH7110_SYSCLK_CPU_BUS		2
97 #define JH7110_SYSCLK_BUS_ROOT		5
98 #define JH7110_SYSCLK_AXI_CFG0		7
99 #define JH7110_SYSCLK_STG_AXIAHB	8
100 #define JH7110_SYSCLK_AHB0		9
101 #define JH7110_SYSCLK_AHB1		10
102 #define JH7110_SYSCLK_APB_BUS		11
103 #define JH7110_SYSCLK_APB0		12
104 
105 #define JH7110_SYSCLK_SDIO0_AHB		91
106 #define JH7110_SYSCLK_SDIO1_AHB		92
107 #define JH7110_SYSCLK_SDIO0_SDCARD	93
108 #define JH7110_SYSCLK_SDIO1_SDCARD	94
109 #define JH7110_SYSCLK_NOC_BUS_STG_AXI	96
110 #define JH7110_SYSCLK_GMAC1_AHB		97
111 #define JH7110_SYSCLK_GMAC1_AXI		98
112 #define JH7110_SYSCLK_GMAC1_GTXCLK	100
113 #define JH7110_SYSCLK_GMAC1_RMII_RTX	101
114 #define JH7110_SYSCLK_GMAC1_PTP		102
115 #define JH7110_SYSCLK_GMAC1_TX		105
116 #define JH7110_SYSCLK_GMAC1_TX_INV	106
117 #define JH7110_SYSCLK_GMAC1_GTXC	107
118 #define JH7110_SYSCLK_GMAC0_GTXCLK	108
119 #define JH7110_SYSCLK_GMAC0_PTP		109
120 #define JH7110_SYSCLK_GMAC0_GTXC	111
121 #define JH7110_SYSCLK_IOMUX_APB		112
122 #define JH7110_SYSCLK_TEMP_APB		129
123 #define JH7110_SYSCLK_TEMP_CORE		130
124 #define JH7110_SYSCLK_I2C0_APB		138
125 #define JH7110_SYSCLK_I2C1_APB		139
126 #define JH7110_SYSCLK_I2C2_APB		140
127 #define JH7110_SYSCLK_I2C3_APB		141
128 #define JH7110_SYSCLK_I2C4_APB		142
129 #define JH7110_SYSCLK_I2C5_APB		143
130 #define JH7110_SYSCLK_I2C6_APB		144
131 #define JH7110_SYSCLK_UART0_CORE	146
132 
133 #define JH7110_SYSCLK_OSC		190
134 #define JH7110_SYSCLK_GMAC1_RMII_REFIN	191
135 #define JH7110_SYSCLK_PLL0_OUT		199
136 #define JH7110_SYSCLK_PLL1_OUT		200
137 #define JH7110_SYSCLK_PLL2_OUT		201
138 
139 #define JH7110_SYSCLK_ASSERT_OFFSET	0x2f8
140 #define JH7110_SYSCLK_STATUS_OFFSET	0x308
141 
142 /* Registers */
143 #define CLKMUX_MASK		0x03000000
144 #define CLKMUX_SHIFT		24
145 #define CLKDIV_MASK		0x00ffffff
146 #define CLKDIV_SHIFT		0
147 
148 #define PLL0DACPD_MASK		0x01000000
149 #define PLL0DACPD_SHIFT		24
150 #define PLL0DSMPD_MASK		0x02000000
151 #define PLL0DSMPD_SHIFT		25
152 #define PLL0FBDIV_MASK		0x00000fff
153 #define PLL0FBDIV_SHIFT		0
154 #define PLLDACPD_MASK		0x00008000
155 #define PLLDACPD_SHIFT		15
156 #define PLLDSMPD_MASK		0x00010000
157 #define PLLDSMPD_SHIFT		16
158 #define PLLFBDIV_MASK		0x1ffe0000
159 #define PLLFBDIV_SHIFT		17
160 #define PLLFRAC_MASK		0x00ffffff
161 #define PLLFRAC_SHIFT		0
162 #define PLLPOSTDIV1_MASK	0x30000000
163 #define PLLPOSTDIV1_SHIFT	28
164 #define PLLPREDIV_MASK		0x0000003f
165 #define PLLPREDIV_SHIFT		0
166 
167 #define JH7110_PLL0_BASE	0x0018
168 #define JH7110_PLL1_BASE	0x0024
169 #define JH7110_PLL2_BASE	0x002c
170 #define JH7110_PLL0_PD_OFF	0x0000
171 #define JH7110_PLL0_FBDIV_OFF	0x0004
172 #define JH7110_PLL0_FRAC_OFF	0x0008
173 #define JH7110_PLL0_PREDIV_OFF	0x000c
174 #define JH7110_PLL_PD_OFF	0x0000
175 #define JH7110_PLL_FRAC_OFF	0x0004
176 #define JH7110_PLL_PREDIV_OFF	0x0008
177 
178 #define HREAD4(sc, reg)							\
179 	(bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg)))
180 #define HWRITE4(sc, reg, val)						\
181 	bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
182 #define HSET4(sc, reg, bits)						\
183 	HWRITE4((sc), (reg), HREAD4((sc), (reg)) | (bits))
184 #define HCLR4(sc, reg, bits)						\
185 	HWRITE4((sc), (reg), HREAD4((sc), (reg)) & ~(bits))
186 
187 struct stfclock_softc {
188 	struct device		sc_dev;
189 	bus_space_tag_t		sc_iot;
190 	bus_space_handle_t	sc_ioh;
191 	struct regmap		*sc_rm;
192 	int			sc_node;
193 
194 	struct clock_device	sc_cd;
195 	struct reset_device	sc_rd;
196 };
197 
198 int	stfclock_match(struct device *, void *, void *);
199 void	stfclock_attach(struct device *, struct device *, void *);
200 
201 const struct cfattach stfclock_ca = {
202 	sizeof (struct stfclock_softc), stfclock_match, stfclock_attach
203 };
204 
205 struct cfdriver stfclock_cd = {
206 	NULL, "stfclock", DV_DULL
207 };
208 
209 uint32_t stfclock_get_frequency_jh7100(void *, uint32_t *);
210 int	stfclock_set_frequency_jh7100(void *, uint32_t *, uint32_t);
211 void	stfclock_enable_jh7100(void *, uint32_t *, int);
212 
213 uint32_t stfclock_get_frequency_jh7110_aon(void *, uint32_t *);
214 int	stfclock_set_frequency_jh7110_aon(void *, uint32_t *, uint32_t);
215 void	stfclock_enable_jh7110_aon(void *, uint32_t *, int);
216 void	stfclock_reset_jh7110_aon(void *, uint32_t *, int);
217 
218 uint32_t stfclock_get_frequency_jh7110_pll(void *, uint32_t *);
219 int	stfclock_set_frequency_jh7110_pll(void *, uint32_t *, uint32_t);
220 void	stfclock_enable_jh7110_pll(void *, uint32_t *, int);
221 
222 uint32_t stfclock_get_frequency_jh7110_stg(void *, uint32_t *);
223 int	stfclock_set_frequency_jh7110_stg(void *, uint32_t *, uint32_t);
224 void	stfclock_enable_jh7110_stg(void *, uint32_t *, int);
225 void	stfclock_reset_jh7110_stg(void *, uint32_t *, int);
226 
227 uint32_t stfclock_get_frequency_jh7110_sys(void *, uint32_t *);
228 int	stfclock_set_frequency_jh7110_sys(void *, uint32_t *, uint32_t);
229 void	stfclock_enable_jh7110_sys(void *, uint32_t *, int);
230 void	stfclock_reset_jh7110_sys(void *, uint32_t *, int);
231 
232 int
233 stfclock_match(struct device *parent, void *match, void *aux)
234 {
235 	struct fdt_attach_args *faa = aux;
236 
237 	return OF_is_compatible(faa->fa_node, "starfive,jh7100-clkgen") ||
238 	    OF_is_compatible(faa->fa_node, "starfive,jh7110-aoncrg") ||
239 	    OF_is_compatible(faa->fa_node, "starfive,jh7110-pll") ||
240 	    OF_is_compatible(faa->fa_node, "starfive,jh7110-stgcrg") ||
241 	    OF_is_compatible(faa->fa_node, "starfive,jh7110-syscrg");
242 }
243 
244 void
245 stfclock_attach(struct device *parent, struct device *self, void *aux)
246 {
247 	struct stfclock_softc *sc = (struct stfclock_softc *)self;
248 	struct fdt_attach_args *faa = aux;
249 
250 	if (OF_is_compatible(faa->fa_node, "starfive,jh7110-pll")) {
251 		sc->sc_rm = regmap_bynode(OF_parent(faa->fa_node));
252 		if (sc->sc_rm == NULL) {
253 			printf(": can't get regmap\n");
254 			return;
255 		}
256 	} else {
257 		if (faa->fa_nreg < 1) {
258 			printf(": no registers\n");
259 			return;
260 		}
261 		sc->sc_iot = faa->fa_iot;
262 		if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr,
263 		    faa->fa_reg[0].size, 0, &sc->sc_ioh)) {
264 			printf(": can't map registers\n");
265 			return;
266 		}
267 	}
268 
269 	sc->sc_node = faa->fa_node;
270 
271 	sc->sc_cd.cd_node = faa->fa_node;
272 	sc->sc_cd.cd_cookie = sc;
273 
274 	if (OF_is_compatible(faa->fa_node, "starfive,jh7100-clkgen")) {
275 		sc->sc_cd.cd_get_frequency = stfclock_get_frequency_jh7100;
276 		sc->sc_cd.cd_set_frequency = stfclock_set_frequency_jh7100;
277 		sc->sc_cd.cd_enable = stfclock_enable_jh7100;
278 		printf("\n");
279 	} else if (OF_is_compatible(faa->fa_node, "starfive,jh7110-aoncrg")) {
280 		sc->sc_cd.cd_get_frequency = stfclock_get_frequency_jh7110_aon;
281 		sc->sc_cd.cd_set_frequency = stfclock_set_frequency_jh7110_aon;
282 		sc->sc_cd.cd_enable = stfclock_enable_jh7110_aon;
283 
284 		sc->sc_rd.rd_node = sc->sc_node;
285 		sc->sc_rd.rd_cookie = sc;
286 		sc->sc_rd.rd_reset = stfclock_reset_jh7110_aon;
287 		reset_register(&sc->sc_rd);
288 
289 		printf(": aoncrg\n");
290 	} else if (OF_is_compatible(faa->fa_node, "starfive,jh7110-pll")) {
291 		sc->sc_cd.cd_get_frequency = stfclock_get_frequency_jh7110_pll;
292 		sc->sc_cd.cd_set_frequency = stfclock_set_frequency_jh7110_pll;
293 		sc->sc_cd.cd_enable = stfclock_enable_jh7110_pll;
294 		printf(": pll\n");
295 	} else if (OF_is_compatible(faa->fa_node, "starfive,jh7110-stgcrg")) {
296 		sc->sc_cd.cd_get_frequency = stfclock_get_frequency_jh7110_stg;
297 		sc->sc_cd.cd_set_frequency = stfclock_set_frequency_jh7110_stg;
298 		sc->sc_cd.cd_enable = stfclock_enable_jh7110_stg;
299 
300 		sc->sc_rd.rd_node = sc->sc_node;
301 		sc->sc_rd.rd_cookie = sc;
302 		sc->sc_rd.rd_reset = stfclock_reset_jh7110_stg;
303 		reset_register(&sc->sc_rd);
304 
305 		printf(": stgcrg\n");
306 	} else if (OF_is_compatible(faa->fa_node, "starfive,jh7110-syscrg")) {
307 		sc->sc_cd.cd_get_frequency = stfclock_get_frequency_jh7110_sys;
308 		sc->sc_cd.cd_set_frequency = stfclock_set_frequency_jh7110_sys;
309 		sc->sc_cd.cd_enable = stfclock_enable_jh7110_sys;
310 
311 		sc->sc_rd.rd_node = sc->sc_node;
312 		sc->sc_rd.rd_cookie = sc;
313 		sc->sc_rd.rd_reset = stfclock_reset_jh7110_sys;
314 		reset_register(&sc->sc_rd);
315 
316 		printf(": syscrg\n");
317 	}
318 
319 	KASSERT(sc->sc_cd.cd_get_frequency);
320 
321 	clock_register(&sc->sc_cd);
322 }
323 
324 uint32_t
325 stfclock_get_frequency_jh7100(void *cookie, uint32_t *cells)
326 {
327 	struct stfclock_softc *sc = cookie;
328 	uint32_t idx = cells[0];
329 	uint32_t parent, freq;
330 	uint32_t reg, div, mux;
331 
332 	switch (idx) {
333 	case JH7100_CLK_OSC_SYS:
334 		return clock_get_frequency(sc->sc_node, "osc_sys");
335 	case JH7100_CLK_OSC_AUD:
336 		return clock_get_frequency(sc->sc_node, "osc_aud");
337 
338 	case JH7100_CLK_PLL0_OUT:
339 		parent = JH7100_CLK_OSC_SYS;
340 		return 40 * stfclock_get_frequency_jh7100(sc, &parent);
341 	case JH7100_CLK_PLL1_OUT:
342 		parent = JH7100_CLK_OSC_SYS;
343 		return 64 * stfclock_get_frequency_jh7100(sc, &parent);
344 	case JH7100_CLK_PLL2_OUT:
345 		parent = JH7100_CLK_PLL2_REF;
346 		return 55 * stfclock_get_frequency_jh7100(sc, &parent);
347 	}
348 
349 	reg = HREAD4(sc, idx * 4);
350 	mux = (reg & CLKMUX_MASK) >> CLKMUX_SHIFT;
351 	div = (reg & CLKDIV_MASK) >> CLKDIV_SHIFT;
352 
353 	switch (idx) {
354 	case JH7100_CLK_CPUNDBUS_ROOT:
355 		switch (mux) {
356 		default:
357 			parent = JH7100_CLK_OSC_SYS;
358 			break;
359 		case 1:
360 			parent = JH7100_CLK_PLL0_OUT;
361 			break;
362 		case 2:
363 			parent = JH7100_CLK_PLL1_OUT;
364 			break;
365 		case 3:
366 			parent = JH7100_CLK_PLL2_OUT;
367 			break;
368 		}
369 		return stfclock_get_frequency_jh7100(sc, &parent);
370 	case JH7100_CLK_GMACUSB_ROOT:
371 		switch (mux) {
372 		default:
373 			parent = JH7100_CLK_OSC_SYS;
374 			break;
375 		case 1:
376 			parent = JH7100_CLK_PLL0_OUT;
377 			break;
378 		case 2:
379 			parent = JH7100_CLK_PLL2_OUT;
380 			break;
381 		}
382 		return stfclock_get_frequency_jh7100(sc, &parent);
383 	case JH7100_CLK_PERH0_ROOT:
384 		mux = (reg >> 24) & 1;
385 		parent = mux ? JH7100_CLK_PLL0_OUT : JH7100_CLK_OSC_SYS;
386 		return stfclock_get_frequency_jh7100(sc, &parent);
387 	case JH7100_CLK_PERH1_ROOT:
388 		mux = (reg >> 24) & 1;
389 		parent = mux ? JH7100_CLK_PLL2_OUT : JH7100_CLK_OSC_SYS;
390 		return stfclock_get_frequency_jh7100(sc, &parent);
391 	case JH7100_CLK_PLL2_REF:
392 		parent = mux ? JH7100_CLK_OSC_AUD : JH7100_CLK_OSC_SYS;
393 		return stfclock_get_frequency_jh7100(sc, &parent);
394 	}
395 
396 	switch (idx) {
397 	case JH7100_CLK_PERH0_SRC:
398 		parent = JH7100_CLK_PERH0_ROOT;
399 		break;
400 	case JH7100_CLK_PERH1_SRC:
401 		parent = JH7100_CLK_PERH1_ROOT;
402 		break;
403 	case JH7100_CLK_CPUNBUS_ROOT_DIV:
404 		parent = JH7100_CLK_CPUNDBUS_ROOT;
405 		break;
406 	case JH7100_CLK_AHB_BUS:
407 		parent = JH7100_CLK_CPUNBUS_ROOT_DIV;
408 		break;
409 	case JH7100_CLK_SDIO0_CCLKINT:
410 	case JH7100_CLK_UART3_CORE:
411 		parent = JH7100_CLK_PERH0_SRC;
412 		break;
413 	case JH7100_CLK_SDIO1_CCLKINT:
414 	case JH7100_CLK_UART0_CORE:
415 		parent = JH7100_CLK_PERH1_SRC;
416 		break;
417 	case JH7100_CLK_SDIO0_AHB:
418 	case JH7100_CLK_SDIO1_AHB:
419 	case JH7100_CLK_GMAC_AHB:
420 		parent = JH7100_CLK_AHB_BUS;
421 		div = 1;
422 		break;
423 	case JH7100_CLK_SDIO0_CCLKINT_INV:
424 		parent = JH7100_CLK_SDIO0_CCLKINT;
425 		div = 1;
426 		break;
427 	case JH7100_CLK_SDIO1_CCLKINT_INV:
428 		parent = JH7100_CLK_SDIO1_CCLKINT;
429 		div = 1;
430 		break;
431 	case JH7100_CLK_GMAC_ROOT_DIV:
432 		parent = JH7100_CLK_GMACUSB_ROOT;
433 		break;
434 	case JH7100_CLK_GMAC_GTX:
435 		parent = JH7100_CLK_GMAC_ROOT_DIV;
436 		break;
437 	default:
438 		printf("%s: unknown clock 0x%08x\n", __func__, idx);
439 		return 0;
440 	}
441 
442 	freq = stfclock_get_frequency_jh7100(sc, &parent);
443 	return freq / div;
444 }
445 
446 int
447 stfclock_set_frequency_jh7100(void *cookie, uint32_t *cells, uint32_t freq)
448 {
449 	uint32_t idx = cells[0];
450 
451 	printf("%s: not handled 0x%08x (freq=0x%08x)\n", __func__, idx, freq);
452 
453 	return -1;
454 }
455 
456 void
457 stfclock_enable_jh7100(void *cookie, uint32_t *cells, int on)
458 {
459 	struct stfclock_softc *sc = cookie;
460 	uint32_t idx = cells[0];
461 
462 	switch (idx) {
463 	case JH7100_CLK_SDIO0_CCLKINT:
464 	case JH7100_CLK_SDIO0_CCLKINT_INV:
465 	case JH7100_CLK_SDIO1_CCLKINT:
466 	case JH7100_CLK_SDIO1_CCLKINT_INV:
467 	case JH7100_CLK_SDIO0_AHB:
468 	case JH7100_CLK_SDIO1_AHB:
469 	case JH7100_CLK_GMAC_AHB:
470 	case JH7100_CLK_GMAC_GTX:
471 	case JH7100_CLK_UART0_CORE:
472 	case JH7100_CLK_UART3_CORE:
473 	case JH7100_CLK_TEMP_APB:
474 	case JH7100_CLK_TEMP_SENSE:
475 		if (on)
476 			HSET4(sc, idx * 4, 1U << 31);
477 		else
478 			HCLR4(sc, idx * 4, 1U << 31);
479 		return;
480 	case JH7100_CLK_GMAC_ROOT_DIV:
481 		/* No gate */
482 		return;
483 	}
484 
485 	printf("%s: unknown clock 0x%08x\n", __func__, idx);
486 }
487 
488 uint32_t
489 stfclock_get_frequency_jh7110_aon(void *cookie, uint32_t *cells)
490 {
491 	struct stfclock_softc *sc = cookie;
492 	uint32_t idx = cells[0];
493 	uint32_t parent, freq;
494 	uint32_t reg, div, mux;
495 
496 	switch (idx) {
497 	case JH7110_AONCLK_OSC:
498 		return clock_get_frequency(sc->sc_node, "osc");
499 	case JH7110_AONCLK_STG_AXIAHB:
500 		return clock_get_frequency(sc->sc_node, "stg_axiahb");
501 	case JH7110_AONCLK_GMAC0_RMII_REFIN:
502 		return clock_get_frequency(sc->sc_node, "gmac0_rmii_refin");
503 	case JH7110_AONCLK_GMAC0_GTXCLK:
504 		return clock_get_frequency(sc->sc_node, "gmac0_gtxclk");
505 	}
506 
507 	reg = HREAD4(sc, idx * 4);
508 	mux = (reg & CLKMUX_MASK) >> CLKMUX_SHIFT;
509 	div = (reg & CLKDIV_MASK) >> CLKDIV_SHIFT;
510 
511 	switch (idx) {
512 	case JH7110_AONCLK_GMAC0_TX:
513 		parent = mux ? JH7110_AONCLK_GMAC0_RMII_RTX :
514 		    JH7110_AONCLK_GMAC0_GTXCLK;
515 		return stfclock_get_frequency_jh7110_aon(sc, &parent);
516 	}
517 
518 	switch (idx) {
519 	case JH7110_AONCLK_GMAC0_AXI:
520 		parent = JH7110_AONCLK_STG_AXIAHB;
521 		div = 1;
522 		break;
523 	case JH7110_AONCLK_GMAC0_RMII_RTX:
524 		parent = JH7110_AONCLK_GMAC0_RMII_REFIN;
525 		break;
526 	case JH7110_AONCLK_GMAC0_TX_INV:
527 		parent = JH7110_AONCLK_GMAC0_TX;
528 		div = 1;
529 		break;
530 	default:
531 		printf("%s: unknown clock 0x%08x\n", __func__, idx);
532 		return 0;
533 	}
534 
535 	if (div == 0) {
536 		printf("%s: zero divisor for clock 0x%08x\n", __func__, idx);
537 		return 0;
538 	}
539 
540 	freq = stfclock_get_frequency_jh7110_aon(sc, &parent);
541 	return freq / div;
542 }
543 
544 int
545 stfclock_set_frequency_jh7110_aon(void *cookie, uint32_t *cells, uint32_t freq)
546 {
547 	struct stfclock_softc *sc = cookie;
548 	uint32_t idx = cells[0];
549 	uint32_t parent, parent_freq;
550 	uint32_t reg, div, mux;
551 
552 	switch (idx) {
553 	case JH7110_AONCLK_GMAC0_RMII_REFIN:
554 		return clock_set_frequency(sc->sc_node, "gmac0_rmii_refin", freq);
555 	case JH7110_AONCLK_GMAC0_GTXCLK:
556 		return clock_set_frequency(sc->sc_node, "gmac0_gtxclk", freq);
557 	}
558 
559 	reg = HREAD4(sc, idx * 4);
560 	mux = (reg & CLKMUX_MASK) >> CLKMUX_SHIFT;
561 
562 	switch (idx) {
563 	case JH7110_AONCLK_GMAC0_TX:
564 		parent = mux ? JH7110_AONCLK_GMAC0_RMII_RTX :
565 		    JH7110_AONCLK_GMAC0_GTXCLK;
566 		return stfclock_set_frequency_jh7110_aon(sc, &parent, freq);
567 	case JH7110_AONCLK_GMAC0_TX_INV:
568 		parent = JH7110_AONCLK_GMAC0_TX;
569 		return stfclock_set_frequency_jh7110_aon(sc, &parent, freq);
570 	}
571 
572 	switch (idx) {
573 	case JH7110_AONCLK_GMAC0_RMII_RTX:
574 		parent = JH7110_AONCLK_GMAC0_RMII_REFIN;
575 		break;
576 	default:
577 		printf("%s: not handled 0x%08x (freq=0x%08x)\n",
578 		    __func__, idx, freq);
579 		return -1;
580 	}
581 
582 	parent_freq = stfclock_get_frequency_jh7110_sys(sc, &parent);
583 	div = parent_freq / freq;
584 
585 	reg &= ~CLKDIV_MASK;
586 	reg |= (div << CLKDIV_SHIFT);
587 	HWRITE4(sc, idx * 4, reg);
588 
589 	return 0;
590 }
591 
592 void
593 stfclock_enable_jh7110_aon(void *cookie, uint32_t *cells, int on)
594 {
595 	struct stfclock_softc *sc = cookie;
596 	uint32_t idx = cells[0];
597 
598 	switch (idx) {
599 	case JH7110_AONCLK_GMAC0_TX_INV:
600 		idx = JH7110_AONCLK_GMAC0_TX;
601 		break;
602 	}
603 
604 	switch (idx) {
605 	case JH7110_AONCLK_GMAC0_AHB:
606 	case JH7110_AONCLK_GMAC0_AXI:
607 	case JH7110_AONCLK_GMAC0_TX:
608 		if (on)
609 			HSET4(sc, idx * 4, 1U << 31);
610 		else
611 			HCLR4(sc, idx * 4, 1U << 31);
612 		return;
613 	}
614 
615 	printf("%s: unknown clock 0x%08x\n", __func__, idx);
616 }
617 
618 void
619 stfclock_reset_jh7110_aon(void *cookie, uint32_t *cells, int assert)
620 {
621 	struct stfclock_softc *sc = cookie;
622 	uint32_t idx = cells[0];
623 	uint32_t bits, offset;
624 
625 	offset = JH7110_AONCLK_ASSERT_OFFSET + (idx / 32) * 4;
626 	bits = 1U << (idx % 32);
627 
628 	if (assert)
629 		HSET4(sc, offset, bits);
630 	else
631 		HCLR4(sc, offset, bits);
632 }
633 
634 uint32_t
635 stfclock_get_frequency_jh7110_pll(void *cookie, uint32_t *cells)
636 {
637 	struct stfclock_softc *sc = cookie;
638 	uint32_t idx = cells[0];
639 	uint32_t dacpd, dsmpd, fbdiv, frac, prediv, postdiv1, reg;
640 	uint64_t frac_val, parent_freq;
641 	bus_size_t base;
642 
643 	parent_freq = clock_get_frequency_idx(sc->sc_node, 0);
644 	if (parent_freq == 0) {
645 		printf("%s: failed to get parent frequency\n", __func__);
646 		return 0;
647 	}
648 
649 	switch (idx) {
650 	case JH7110_CLK_PLL0_OUT:
651 		base = JH7110_PLL0_BASE;
652 		break;
653 	case JH7110_CLK_PLL1_OUT:
654 		base = JH7110_PLL1_BASE;
655 		break;
656 	case JH7110_CLK_PLL2_OUT:
657 		base = JH7110_PLL2_BASE;
658 		break;
659 	default:
660 		printf("%s: unknown clock 0x08%x\n", __func__, idx);
661 		return 0;
662 	}
663 
664 	switch (idx) {
665 	case JH7110_CLK_PLL0_OUT:
666 		reg = regmap_read_4(sc->sc_rm, base + JH7110_PLL0_PD_OFF);
667 		dacpd = (reg & PLL0DACPD_MASK) >> PLL0DACPD_SHIFT;
668 		dsmpd = (reg & PLL0DSMPD_MASK) >> PLL0DSMPD_SHIFT;
669 
670 		reg = regmap_read_4(sc->sc_rm, base + JH7110_PLL0_FBDIV_OFF);
671 		fbdiv = (reg & PLL0FBDIV_MASK) >> PLL0FBDIV_SHIFT;
672 
673 		reg = regmap_read_4(sc->sc_rm, base + JH7110_PLL0_FRAC_OFF);
674 		frac = (reg & PLLFRAC_MASK) >> PLLFRAC_SHIFT;
675 		postdiv1 = 1 << ((reg & PLLPOSTDIV1_MASK) >> PLLPOSTDIV1_SHIFT);
676 
677 		reg = regmap_read_4(sc->sc_rm, base + JH7110_PLL0_PREDIV_OFF);
678 		prediv = (reg & PLLPREDIV_MASK) >> PLLPREDIV_SHIFT;
679 		break;
680 
681 	case JH7110_CLK_PLL1_OUT:
682 	case JH7110_CLK_PLL2_OUT:
683 		reg = regmap_read_4(sc->sc_rm, base + JH7110_PLL_PD_OFF);
684 		dacpd = (reg & PLLDACPD_MASK) >> PLLDACPD_SHIFT;
685 		dsmpd = (reg & PLLDSMPD_MASK) >> PLLDSMPD_SHIFT;
686 		fbdiv = (reg & PLLFBDIV_MASK) >> PLLFBDIV_SHIFT;
687 
688 		reg = regmap_read_4(sc->sc_rm, base + JH7110_PLL_FRAC_OFF);
689 		frac = (reg & PLLFRAC_MASK) >> PLLFRAC_SHIFT;
690 		postdiv1 = 1 << ((reg & PLLPOSTDIV1_MASK) >> PLLPOSTDIV1_SHIFT);
691 
692 		reg = regmap_read_4(sc->sc_rm, base + JH7110_PLL_PREDIV_OFF);
693 		prediv = (reg & PLLPREDIV_MASK) >> PLLPREDIV_SHIFT;
694 		break;
695 	}
696 
697 	if (fbdiv == 0 || prediv == 0 || postdiv1 == 0) {
698 		printf("%s: zero divisor\n", __func__);
699 		return 0;
700 	}
701 
702 	if (dacpd != dsmpd)
703 		return 0;
704 
705 	/* Integer mode (dacpd/dsmpd both 1) or fraction mode (both 0). */
706 	frac_val = 0;
707 	if (dacpd == 0 && dsmpd == 0)
708 		frac_val = ((uint64_t)frac * 1000) / (1 << 24);
709 
710 	return parent_freq / 1000 * (fbdiv * 1000 + frac_val) / prediv / postdiv1;
711 }
712 
713 int
714 stfclock_set_frequency_jh7110_pll(void *cookie, uint32_t *cells, uint32_t freq)
715 {
716 	struct stfclock_softc *sc = cookie;
717 	uint32_t idx = cells[0];
718 	uint32_t dacpd, dsmpd, fbdiv, prediv, postdiv1, reg;
719 	bus_size_t base = JH7110_PLL0_BASE;
720 
721 	switch (idx) {
722 	case JH7110_CLK_PLL0_OUT:
723 		/*
724 		 * Supported frequencies are carefully selected such
725 		 * that they can be obtained by only changing the
726 		 * pre-divider.
727 		 */
728 		switch (freq) {
729 		case 375000000:
730 			prediv = 8;
731 			break;
732 		case 500000000:
733 			prediv = 6;
734 			break;
735 		case 750000000:
736 			prediv = 4;
737 			break;
738 		case 1000000000:
739 			prediv = 3;
740 			break;
741 		case 1500000000:
742 			prediv = 2;
743 			break;
744 		default:
745 			return -1;
746 		}
747 
748 		reg = regmap_read_4(sc->sc_rm, base + JH7110_PLL0_PD_OFF);
749 		dacpd = (reg & PLL0DACPD_MASK) >> PLL0DACPD_SHIFT;
750 		dsmpd = (reg & PLL0DSMPD_MASK) >> PLL0DSMPD_SHIFT;
751 
752 		reg = regmap_read_4(sc->sc_rm, base + JH7110_PLL0_FBDIV_OFF);
753 		fbdiv = (reg & PLL0FBDIV_MASK) >> PLL0FBDIV_SHIFT;
754 
755 		reg = regmap_read_4(sc->sc_rm, base + JH7110_PLL0_FRAC_OFF);
756 		postdiv1 = 1 << ((reg & PLLPOSTDIV1_MASK) >> PLLPOSTDIV1_SHIFT);
757 
758 		if (dacpd != 1 || dsmpd != 1 || fbdiv != 125 || postdiv1 != 1) {
759 			printf("%s: misconfigured PLL0\n", __func__);
760 			return -1;
761 		}
762 
763 		reg = regmap_read_4(sc->sc_rm, base + JH7110_PLL0_PREDIV_OFF);
764 		reg &= ~PLLPREDIV_MASK;
765 		reg |= (prediv << PLLPREDIV_SHIFT);
766 		regmap_write_4(sc->sc_rm, base + JH7110_PLL0_PREDIV_OFF, reg);
767 		return 0;
768 	}
769 
770 	printf("%s: not handled 0x%08x (freq=0x%08x)\n", __func__, idx, freq);
771 
772 	return -1;
773 }
774 
775 void
776 stfclock_enable_jh7110_pll(void *cookie, uint32_t *cells, int on)
777 {
778 	uint32_t idx = cells[0];
779 
780 	printf("%s: not handled 0x%08x\n", __func__, idx);
781 }
782 
783 uint32_t
784 stfclock_get_frequency_jh7110_stg(void *cookie, uint32_t *cells)
785 {
786 	uint32_t idx = cells[0];
787 
788 	printf("%s: unknown clock 0x%08x\n", __func__, idx);
789 	return 0;
790 }
791 
792 int
793 stfclock_set_frequency_jh7110_stg(void *cookie, uint32_t *cells, uint32_t freq)
794 {
795 	uint32_t idx = cells[0];
796 
797 	printf("%s: not handled 0x%08x (freq=0x%08x)\n", __func__, idx, freq);
798 
799 	return -1;
800 }
801 
802 void
803 stfclock_enable_jh7110_stg(void *cookie, uint32_t *cells, int on)
804 {
805 	struct stfclock_softc *sc = cookie;
806 	uint32_t idx = cells[0];
807 
808 	switch (idx) {
809 	case JH7110_STGCLK_PCIE0_AXI_MST0:
810 	case JH7110_STGCLK_PCIE0_APB:
811 	case JH7110_STGCLK_PCIE0_TL:
812 	case JH7110_STGCLK_PCIE1_AXI_MST0:
813 	case JH7110_STGCLK_PCIE1_APB:
814 	case JH7110_STGCLK_PCIE1_TL:
815 	case JH7110_STGCLK_SEC_AHB:
816 	case JH7110_STGCLK_SEC_MISC_AHB:
817 		if (on)
818 			HSET4(sc, idx * 4, 1U << 31);
819 		else
820 			HCLR4(sc, idx * 4, 1U << 31);
821 		return;
822 	}
823 
824 	printf("%s: unknown clock 0x%08x\n", __func__, idx);
825 }
826 
827 void
828 stfclock_reset_jh7110_stg(void *cookie, uint32_t *cells, int assert)
829 {
830 	struct stfclock_softc *sc = cookie;
831 	uint32_t idx = cells[0];
832 	uint32_t bits, offset;
833 
834 	offset = JH7110_STGCLK_ASSERT_OFFSET + (idx / 32) * 4;
835 	bits = 1U << (idx % 32);
836 
837 	if (assert)
838 		HSET4(sc, offset, bits);
839 	else
840 		HCLR4(sc, offset, bits);
841 }
842 
843 uint32_t
844 stfclock_get_frequency_jh7110_sys(void *cookie, uint32_t *cells)
845 {
846 	struct stfclock_softc *sc = cookie;
847 	uint32_t idx = cells[0];
848 	uint32_t parent, freq;
849 	uint32_t reg, div, mux;
850 
851 	switch (idx) {
852 	case JH7110_SYSCLK_OSC:
853 		return clock_get_frequency(sc->sc_node, "osc");
854 	case JH7110_SYSCLK_GMAC1_RMII_REFIN:
855 		return clock_get_frequency(sc->sc_node, "gmac1_rmii_refin");
856 	case JH7110_SYSCLK_PLL0_OUT:
857 		return clock_get_frequency(sc->sc_node, "pll0_out");
858 	case JH7110_SYSCLK_PLL1_OUT:
859 		return clock_get_frequency(sc->sc_node, "pll1_out");
860 	case JH7110_SYSCLK_PLL2_OUT:
861 		return clock_get_frequency(sc->sc_node, "pll2_out");
862 	}
863 
864 	reg = HREAD4(sc, idx * 4);
865 	mux = (reg & CLKMUX_MASK) >> CLKMUX_SHIFT;
866 	div = (reg & CLKDIV_MASK) >> CLKDIV_SHIFT;
867 
868 	switch (idx) {
869 	case JH7110_SYSCLK_CPU_ROOT:
870 		mux = (reg >> 24) & 1;
871 		parent = mux ? JH7110_SYSCLK_PLL0_OUT : JH7110_SYSCLK_OSC;
872 		return stfclock_get_frequency_jh7110_sys(sc, &parent);
873 	case JH7110_SYSCLK_BUS_ROOT:
874 		mux = (reg >> 24) & 1;
875 		parent = mux ? JH7110_SYSCLK_PLL2_OUT : JH7110_SYSCLK_OSC;
876 		return stfclock_get_frequency_jh7110_sys(sc, &parent);
877 	case JH7110_SYSCLK_GMAC1_TX:
878 		parent = mux ? JH7110_SYSCLK_GMAC1_RMII_RTX :
879 		    JH7110_SYSCLK_GMAC1_GTXCLK;
880 		return stfclock_get_frequency_jh7110_sys(sc, &parent);
881 	}
882 
883 	switch (idx) {
884 	case JH7110_SYSCLK_CPU_CORE:
885 		parent = JH7110_SYSCLK_CPU_ROOT;
886 		break;
887 	case JH7110_SYSCLK_AXI_CFG0:
888 		parent = JH7110_SYSCLK_BUS_ROOT;
889 		break;
890 	case JH7110_SYSCLK_STG_AXIAHB:
891 		parent = JH7110_SYSCLK_AXI_CFG0;
892 		break;
893 	case JH7110_SYSCLK_AHB0:
894 	case JH7110_SYSCLK_AHB1:
895 	case JH7110_SYSCLK_APB_BUS:
896 		parent = JH7110_SYSCLK_STG_AXIAHB;
897 		break;
898 	case JH7110_SYSCLK_APB0:
899 		parent = JH7110_SYSCLK_APB_BUS;
900 		div = 1;
901 		break;
902 	case JH7110_SYSCLK_SDIO0_AHB:
903 	case JH7110_SYSCLK_SDIO1_AHB:
904 		parent = JH7110_SYSCLK_AHB0;
905 		break;
906 	case JH7110_SYSCLK_SDIO0_SDCARD:
907 	case JH7110_SYSCLK_SDIO1_SDCARD:
908 		parent = JH7110_SYSCLK_AXI_CFG0;
909 		break;
910 	case JH7110_SYSCLK_GMAC1_AXI:
911 		parent = JH7110_SYSCLK_STG_AXIAHB;
912 		div = 1;
913 		break;
914 	case JH7110_SYSCLK_GMAC1_GTXCLK:
915 		parent = JH7110_SYSCLK_PLL0_OUT;
916 		break;
917 	case JH7110_SYSCLK_GMAC1_RMII_RTX:
918 		parent = JH7110_SYSCLK_GMAC1_RMII_REFIN;
919 		break;
920 	case JH7110_SYSCLK_GMAC1_TX_INV:
921 		parent = JH7110_SYSCLK_GMAC1_TX;
922 		div = 1;
923 		break;
924 	case JH7110_SYSCLK_GMAC0_GTXCLK:
925 		parent = JH7110_SYSCLK_PLL0_OUT;
926 		break;
927 	case JH7110_SYSCLK_TEMP_APB:
928 		parent = JH7110_SYSCLK_APB_BUS;
929 		break;
930 	case JH7110_SYSCLK_TEMP_CORE:
931 		parent = JH7110_SYSCLK_OSC;
932 		break;
933 	case JH7110_SYSCLK_I2C0_APB:
934 	case JH7110_SYSCLK_I2C1_APB:
935 	case JH7110_SYSCLK_I2C2_APB:
936 		parent = JH7110_SYSCLK_APB0;
937 		div = 1;
938 		break;
939 	case JH7110_SYSCLK_I2C3_APB:
940 	case JH7110_SYSCLK_I2C4_APB:
941 	case JH7110_SYSCLK_I2C5_APB:
942 	case JH7110_SYSCLK_I2C6_APB:
943 		parent = JH7110_SYSCLK_APB_BUS;
944 		div = 1;
945 		break;
946 	case JH7110_SYSCLK_UART0_CORE:
947 		parent = JH7110_SYSCLK_OSC;
948 		div = 1;
949 		break;
950 	default:
951 		printf("%s: unknown clock 0x%08x\n", __func__, idx);
952 		return 0;
953 	}
954 
955 	if (div == 0) {
956 		printf("%s: zero divisor for clock 0x%08x\n", __func__, idx);
957 		return 0;
958 	}
959 
960 	freq = stfclock_get_frequency_jh7110_sys(sc, &parent);
961 	return freq / div;
962 }
963 
964 int
965 stfclock_set_frequency_jh7110_sys(void *cookie, uint32_t *cells, uint32_t freq)
966 {
967 	struct stfclock_softc *sc = cookie;
968 	uint32_t idx = cells[0];
969 	uint32_t parent, parent_freq;
970 	uint32_t reg, div, mux;
971 
972 	switch (idx) {
973 	case JH7110_SYSCLK_GMAC1_RMII_REFIN:
974 		return clock_set_frequency(sc->sc_node, "gmac1_rmii_refin", freq);
975 	}
976 
977 	/*
978 	 * Firmware on the VisionFive 2 initializes PLL0 to 1 GHz and
979 	 * runs the CPU cores at this frequency.  But there is no
980 	 * operating point in the device tree with this frequency and
981 	 * it means we can't run at the supported maximum frequency of
982 	 * 1.5 GHz.
983 	 *
984 	 * So if we're switching away from the 1 GHz boot frequency,
985 	 * bump the PLL0 frequency up to 1.5 GHz.  But set the divider
986 	 * for the CPU clock to 2 to make sure we don't run at a
987 	 * frequency that is too high for the default CPU voltage.
988 	 */
989 	if (idx == JH7110_SYSCLK_CPU_CORE && freq != 1000000000 &&
990 	    stfclock_get_frequency_jh7110_sys(sc, &idx) == 1000000000) {
991 		reg = HREAD4(sc, idx * 4);
992 		reg &= ~CLKDIV_MASK;
993 		reg |= (2 << CLKDIV_SHIFT);
994 		HWRITE4(sc, idx * 4, reg);
995 		clock_set_frequency(sc->sc_node, "pll0_out", 1500000000);
996 	}
997 
998 	reg = HREAD4(sc, idx * 4);
999 	mux = (reg & CLKMUX_MASK) >> CLKMUX_SHIFT;
1000 
1001 	switch (idx) {
1002 	case JH7110_SYSCLK_GMAC1_TX:
1003 		parent = mux ? JH7110_SYSCLK_GMAC1_RMII_RTX :
1004 		    JH7110_SYSCLK_GMAC1_GTXCLK;
1005 		return stfclock_set_frequency_jh7110_sys(sc, &parent, freq);
1006 	case JH7110_SYSCLK_GMAC1_TX_INV:
1007 		parent = JH7110_SYSCLK_GMAC1_TX;
1008 		return stfclock_set_frequency_jh7110_sys(sc, &parent, freq);
1009 	}
1010 
1011 	switch (idx) {
1012 	case JH7110_SYSCLK_CPU_CORE:
1013 		parent = JH7110_SYSCLK_CPU_ROOT;
1014 		break;
1015 	case JH7110_SYSCLK_GMAC1_GTXCLK:
1016 		parent = JH7110_SYSCLK_PLL0_OUT;
1017 		break;
1018 	case JH7110_SYSCLK_GMAC1_RMII_RTX:
1019 		parent = JH7110_SYSCLK_GMAC1_RMII_REFIN;
1020 		break;
1021 	case JH7110_SYSCLK_GMAC0_GTXCLK:
1022 		parent = JH7110_SYSCLK_PLL0_OUT;
1023 		break;
1024 	default:
1025 		printf("%s: not handled 0x%08x (freq=0x%08x)\n",
1026 		    __func__, idx, freq);
1027 		return -1;
1028 	}
1029 
1030 	parent_freq = stfclock_get_frequency_jh7110_sys(sc, &parent);
1031 	div = parent_freq / freq;
1032 
1033 	reg &= ~CLKDIV_MASK;
1034 	reg |= (div << CLKDIV_SHIFT);
1035 	HWRITE4(sc, idx * 4, reg);
1036 
1037 	return 0;
1038 }
1039 
1040 void
1041 stfclock_enable_jh7110_sys(void *cookie, uint32_t *cells, int on)
1042 {
1043 	struct stfclock_softc *sc = cookie;
1044 	uint32_t idx = cells[0];
1045 	uint32_t parent;
1046 
1047 	switch (idx) {
1048 	case JH7110_SYSCLK_GMAC1_TX_INV:
1049 		idx = JH7110_SYSCLK_GMAC1_TX;
1050 		break;
1051 	case JH7110_SYSCLK_GMAC1_GTXC:
1052 		parent = JH7110_SYSCLK_GMAC1_GTXCLK;
1053 		stfclock_enable_jh7110_sys(sc, &parent, on);
1054 		break;
1055 	case JH7110_SYSCLK_GMAC0_GTXC:
1056 		parent = JH7110_SYSCLK_GMAC0_GTXCLK;
1057 		stfclock_enable_jh7110_sys(sc, &parent, on);
1058 		break;
1059 	}
1060 
1061 	switch (idx) {
1062 	case JH7110_SYSCLK_SDIO0_AHB:
1063 	case JH7110_SYSCLK_SDIO1_AHB:
1064 	case JH7110_SYSCLK_SDIO0_SDCARD:
1065 	case JH7110_SYSCLK_SDIO1_SDCARD:
1066 	case JH7110_SYSCLK_NOC_BUS_STG_AXI:
1067 	case JH7110_SYSCLK_GMAC1_AHB:
1068 	case JH7110_SYSCLK_GMAC1_AXI:
1069 	case JH7110_SYSCLK_GMAC1_GTXCLK:
1070 	case JH7110_SYSCLK_GMAC1_PTP:
1071 	case JH7110_SYSCLK_GMAC1_TX:
1072 	case JH7110_SYSCLK_GMAC1_GTXC:
1073 	case JH7110_SYSCLK_GMAC0_GTXCLK:
1074 	case JH7110_SYSCLK_GMAC0_PTP:
1075 	case JH7110_SYSCLK_GMAC0_GTXC:
1076 	case JH7110_SYSCLK_IOMUX_APB:
1077 	case JH7110_SYSCLK_TEMP_APB:
1078 	case JH7110_SYSCLK_TEMP_CORE:
1079 	case JH7110_SYSCLK_I2C0_APB:
1080 	case JH7110_SYSCLK_I2C1_APB:
1081 	case JH7110_SYSCLK_I2C2_APB:
1082 	case JH7110_SYSCLK_I2C3_APB:
1083 	case JH7110_SYSCLK_I2C4_APB:
1084 	case JH7110_SYSCLK_I2C5_APB:
1085 	case JH7110_SYSCLK_I2C6_APB:
1086 	case JH7110_SYSCLK_UART0_CORE:
1087 		if (on)
1088 			HSET4(sc, idx * 4, 1U << 31);
1089 		else
1090 			HCLR4(sc, idx * 4, 1U << 31);
1091 		return;
1092 	}
1093 
1094 	printf("%s: unknown clock 0x%08x\n", __func__, idx);
1095 }
1096 
1097 void
1098 stfclock_reset_jh7110_sys(void *cookie, uint32_t *cells, int assert)
1099 {
1100 	struct stfclock_softc *sc = cookie;
1101 	uint32_t idx = cells[0];
1102 	uint32_t bits, offset;
1103 
1104 	offset = JH7110_SYSCLK_ASSERT_OFFSET + (idx / 32) * 4;
1105 	bits = 1U << (idx % 32);
1106 
1107 	if (assert)
1108 		HSET4(sc, offset, bits);
1109 	else
1110 		HCLR4(sc, offset, bits);
1111 }
1112