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