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