xref: /netbsd-src/sys/arch/riscv/starfive/jh7110_clkc.c (revision 69e3e2014d41f6c3bb640748819afa7c8b28ecbc)
1 /* $NetBSD: jh7110_clkc.c,v 1.8 2025/01/17 08:04:16 skrll Exp $ */
2 
3 /*-
4  * Copyright (c) 2023 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Nick Hudson
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: jh7110_clkc.c,v 1.8 2025/01/17 08:04:16 skrll Exp $");
34 
35 #include <sys/param.h>
36 
37 #include <sys/bus.h>
38 #include <sys/device.h>
39 #include <sys/kmem.h>
40 
41 #include <dev/clk/clk_backend.h>
42 
43 #include <dev/fdt/fdtvar.h>
44 
45 #include <riscv/starfive/jh71x0_clkc.h>
46 
47 /* SYSCRG clocks */
48 #define JH7110_SYSCLK_CPU_ROOT			0
49 #define JH7110_SYSCLK_CPU_CORE			1
50 #define JH7110_SYSCLK_CPU_BUS			2
51 #define JH7110_SYSCLK_GPU_ROOT			3
52 #define JH7110_SYSCLK_PERH_ROOT			4
53 #define JH7110_SYSCLK_BUS_ROOT			5
54 #define JH7110_SYSCLK_NOCSTG_BUS		6
55 #define JH7110_SYSCLK_AXI_CFG0			7
56 #define JH7110_SYSCLK_STG_AXIAHB		8
57 #define JH7110_SYSCLK_AHB0			9
58 #define JH7110_SYSCLK_AHB1			10
59 #define JH7110_SYSCLK_APB_BUS			11
60 #define JH7110_SYSCLK_APB0			12
61 #define JH7110_SYSCLK_PLL0_DIV2			13
62 #define JH7110_SYSCLK_PLL1_DIV2			14
63 #define JH7110_SYSCLK_PLL2_DIV2			15
64 #define JH7110_SYSCLK_AUDIO_ROOT		16
65 #define JH7110_SYSCLK_MCLK_INNER		17
66 #define JH7110_SYSCLK_MCLK			18
67 #define JH7110_SYSCLK_MCLK_OUT			19
68 #define JH7110_SYSCLK_ISP_2X			20
69 #define JH7110_SYSCLK_ISP_AXI			21
70 #define JH7110_SYSCLK_GCLK0			22
71 #define JH7110_SYSCLK_GCLK1			23
72 #define JH7110_SYSCLK_GCLK2			24
73 #define JH7110_SYSCLK_CORE			25
74 #define JH7110_SYSCLK_CORE1			26
75 #define JH7110_SYSCLK_CORE2			27
76 #define JH7110_SYSCLK_CORE3			28
77 #define JH7110_SYSCLK_CORE4			29
78 #define JH7110_SYSCLK_DEBUG			30
79 #define JH7110_SYSCLK_RTC_TOGGLE		31
80 #define JH7110_SYSCLK_TRACE0			32
81 #define JH7110_SYSCLK_TRACE1			33
82 #define JH7110_SYSCLK_TRACE2			34
83 #define JH7110_SYSCLK_TRACE3			35
84 #define JH7110_SYSCLK_TRACE4			36
85 #define JH7110_SYSCLK_TRACE_COM			37
86 #define JH7110_SYSCLK_NOC_BUS_CPU_AXI		38
87 #define JH7110_SYSCLK_NOC_BUS_AXICFG0_AXI	39
88 #define JH7110_SYSCLK_OSC_DIV2			40
89 #define JH7110_SYSCLK_PLL1_DIV4			41
90 #define JH7110_SYSCLK_PLL1_DIV8			42
91 #define JH7110_SYSCLK_DDR_BUS			43
92 #define JH7110_SYSCLK_DDR_AXI			44
93 #define JH7110_SYSCLK_GPU_CORE			45
94 #define JH7110_SYSCLK_GPU_CORE_CLK		46
95 #define JH7110_SYSCLK_GPU_SYS_CLK		47
96 #define JH7110_SYSCLK_GPU_APB			48
97 #define JH7110_SYSCLK_GPU_RTC_TOGGLE		49
98 #define JH7110_SYSCLK_NOC_BUS_GPU_AXI		50
99 #define JH7110_SYSCLK_ISP_TOP_CORE		51
100 #define JH7110_SYSCLK_ISP_TOP_AXI		52
101 #define JH7110_SYSCLK_NOC_BUS_ISP_AXI		53
102 #define JH7110_SYSCLK_HIFI4_CORE		54
103 #define JH7110_SYSCLK_HIFI4_AXI			55
104 #define JH7110_SYSCLK_AXI_CFG1_MAIN		56
105 #define JH7110_SYSCLK_AXI_CFG1_AHB		57
106 #define JH7110_SYSCLK_VOUT_SRC			58
107 #define JH7110_SYSCLK_VOUT_AXI			59
108 #define JH7110_SYSCLK_NOC_BUS_DISP_AXI		60
109 #define JH7110_SYSCLK_VOUT_TOP_AHB		61
110 #define JH7110_SYSCLK_VOUT_TOP_AXI		62
111 #define JH7110_SYSCLK_VOUT_TOP_HDMITX0_MCLK	63
112 #define JH7110_SYSCLK_VOUT_TOP_MIPIPHY_REF	64
113 #define JH7110_SYSCLK_JPEGC_AXI			65
114 #define JH7110_SYSCLK_CODAJ12_AXI		66
115 #define JH7110_SYSCLK_CODAJ12_CORE		67
116 #define JH7110_SYSCLK_CODAJ12_APB		68
117 #define JH7110_SYSCLK_VDEC_AXI			69
118 #define JH7110_SYSCLK_WAVE511_AXI		70
119 #define JH7110_SYSCLK_WAVE511_BPU		71
120 #define JH7110_SYSCLK_WAVE511_VCE		72
121 #define JH7110_SYSCLK_WAVE511_APB		73
122 #define JH7110_SYSCLK_VDEC_JPG			74
123 #define JH7110_SYSCLK_VDEC_MAIN			75
124 #define JH7110_SYSCLK_NOC_BUS_VDEC_AXI		76
125 #define JH7110_SYSCLK_VENC_AXI			77
126 #define JH7110_SYSCLK_WAVE420L_AXI		78
127 #define JH7110_SYSCLK_WAVE420L_BPU		79
128 #define JH7110_SYSCLK_WAVE420L_VCE		80
129 #define JH7110_SYSCLK_WAVE420L_APB		81
130 #define JH7110_SYSCLK_NOC_BUS_VENC_AXI		82
131 #define JH7110_SYSCLK_AXI_CFG0_MAIN_DIV		83
132 #define JH7110_SYSCLK_AXI_CFG0_MAIN		84
133 #define JH7110_SYSCLK_AXI_CFG0_HIFI4		85
134 #define JH7110_SYSCLK_AXIMEM2_AXI		86
135 #define JH7110_SYSCLK_QSPI_AHB			87
136 #define JH7110_SYSCLK_QSPI_APB			88
137 #define JH7110_SYSCLK_QSPI_REF_SRC		89
138 #define JH7110_SYSCLK_QSPI_REF			90
139 #define JH7110_SYSCLK_SDIO0_AHB			91
140 #define JH7110_SYSCLK_SDIO1_AHB			92
141 #define JH7110_SYSCLK_SDIO0_SDCARD		93
142 #define JH7110_SYSCLK_SDIO1_SDCARD		94
143 #define JH7110_SYSCLK_USB_125M			95
144 #define JH7110_SYSCLK_NOC_BUS_STG_AXI		96
145 #define JH7110_SYSCLK_GMAC1_AHB			97
146 #define JH7110_SYSCLK_GMAC1_AXI			98
147 #define JH7110_SYSCLK_GMAC_SRC			99
148 #define JH7110_SYSCLK_GMAC1_GTXCLK		100
149 #define JH7110_SYSCLK_GMAC1_RMII_RTX		101
150 #define JH7110_SYSCLK_GMAC1_PTP			102
151 #define JH7110_SYSCLK_GMAC1_RX			103
152 #define JH7110_SYSCLK_GMAC1_RX_INV		104
153 #define JH7110_SYSCLK_GMAC1_TX			105
154 #define JH7110_SYSCLK_GMAC1_TX_INV		106
155 #define JH7110_SYSCLK_GMAC1_GTXC		107
156 #define JH7110_SYSCLK_GMAC0_GTXCLK		108
157 #define JH7110_SYSCLK_GMAC0_PTP			109
158 #define JH7110_SYSCLK_GMAC_PHY			110
159 #define JH7110_SYSCLK_GMAC0_GTXC		111
160 #define JH7110_SYSCLK_IOMUX_APB			112
161 #define JH7110_SYSCLK_MAILBOX_APB		113
162 #define JH7110_SYSCLK_INT_CTRL_APB		114
163 #define JH7110_SYSCLK_CAN0_APB			115
164 #define JH7110_SYSCLK_CAN0_TIMER		116
165 #define JH7110_SYSCLK_CAN0_CAN			117
166 #define JH7110_SYSCLK_CAN1_APB			118
167 #define JH7110_SYSCLK_CAN1_TIMER		119
168 #define JH7110_SYSCLK_CAN1_CAN			120
169 #define JH7110_SYSCLK_PWM_APB			121
170 #define JH7110_SYSCLK_WDT_APB			122
171 #define JH7110_SYSCLK_WDT_CORE			123
172 #define JH7110_SYSCLK_TIMER_APB			124
173 #define JH7110_SYSCLK_TIMER0			125
174 #define JH7110_SYSCLK_TIMER1			126
175 #define JH7110_SYSCLK_TIMER2			127
176 #define JH7110_SYSCLK_TIMER3			128
177 #define JH7110_SYSCLK_TEMP_APB			129
178 #define JH7110_SYSCLK_TEMP_CORE			130
179 #define JH7110_SYSCLK_SPI0_APB			131
180 #define JH7110_SYSCLK_SPI1_APB			132
181 #define JH7110_SYSCLK_SPI2_APB			133
182 #define JH7110_SYSCLK_SPI3_APB			134
183 #define JH7110_SYSCLK_SPI4_APB			135
184 #define JH7110_SYSCLK_SPI5_APB			136
185 #define JH7110_SYSCLK_SPI6_APB			137
186 #define JH7110_SYSCLK_I2C0_APB			138
187 #define JH7110_SYSCLK_I2C1_APB			139
188 #define JH7110_SYSCLK_I2C2_APB			140
189 #define JH7110_SYSCLK_I2C3_APB			141
190 #define JH7110_SYSCLK_I2C4_APB			142
191 #define JH7110_SYSCLK_I2C5_APB			143
192 #define JH7110_SYSCLK_I2C6_APB			144
193 #define JH7110_SYSCLK_UART0_APB			145
194 #define JH7110_SYSCLK_UART0_CORE		146
195 #define JH7110_SYSCLK_UART1_APB			147
196 #define JH7110_SYSCLK_UART1_CORE		148
197 #define JH7110_SYSCLK_UART2_APB			149
198 #define JH7110_SYSCLK_UART2_CORE		150
199 #define JH7110_SYSCLK_UART3_APB			151
200 #define JH7110_SYSCLK_UART3_CORE		152
201 #define JH7110_SYSCLK_UART4_APB			153
202 #define JH7110_SYSCLK_UART4_CORE		154
203 #define JH7110_SYSCLK_UART5_APB			155
204 #define JH7110_SYSCLK_UART5_CORE		156
205 #define JH7110_SYSCLK_PWMDAC_APB		157
206 #define JH7110_SYSCLK_PWMDAC_CORE		158
207 #define JH7110_SYSCLK_SPDIF_APB			159
208 #define JH7110_SYSCLK_SPDIF_CORE		160
209 #define JH7110_SYSCLK_I2STX0_APB		161
210 #define JH7110_SYSCLK_I2STX0_BCLK_MST		162
211 #define JH7110_SYSCLK_I2STX0_BCLK_MST_INV	163
212 #define JH7110_SYSCLK_I2STX0_LRCK_MST		164
213 #define JH7110_SYSCLK_I2STX0_BCLK		165
214 #define JH7110_SYSCLK_I2STX0_BCLK_INV		166
215 #define JH7110_SYSCLK_I2STX0_LRCK		167
216 #define JH7110_SYSCLK_I2STX1_APB		168
217 #define JH7110_SYSCLK_I2STX1_BCLK_MST		169
218 #define JH7110_SYSCLK_I2STX1_BCLK_MST_INV	170
219 #define JH7110_SYSCLK_I2STX1_LRCK_MST		171
220 #define JH7110_SYSCLK_I2STX1_BCLK		172
221 #define JH7110_SYSCLK_I2STX1_BCLK_INV		173
222 #define JH7110_SYSCLK_I2STX1_LRCK		174
223 #define JH7110_SYSCLK_I2SRX_APB			175
224 #define JH7110_SYSCLK_I2SRX_BCLK_MST		176
225 #define JH7110_SYSCLK_I2SRX_BCLK_MST_INV	177
226 #define JH7110_SYSCLK_I2SRX_LRCK_MST		178
227 #define JH7110_SYSCLK_I2SRX_BCLK		179
228 #define JH7110_SYSCLK_I2SRX_BCLK_INV		180
229 #define JH7110_SYSCLK_I2SRX_LRCK		181
230 #define JH7110_SYSCLK_PDM_DMIC			182
231 #define JH7110_SYSCLK_PDM_APB			183
232 #define JH7110_SYSCLK_TDM_AHB			184
233 #define JH7110_SYSCLK_TDM_APB			185
234 #define JH7110_SYSCLK_TDM_INTERNAL		186
235 #define JH7110_SYSCLK_TDM_TDM			187
236 #define JH7110_SYSCLK_TDM_TDM_INV		188
237 #define JH7110_SYSCLK_JTAG_CERTIFICATION_TRNG	189
238 
239 #define JH7110_SYSCLK_NCLKS			190
240 
241 /* external clocks */
242 #define JH7110_SYSCLK_PLL0_OUT			(JH7110_SYSCLK_NCLKS + 0)
243 #define JH7110_SYSCLK_PLL1_OUT			(JH7110_SYSCLK_NCLKS + 1)
244 #define JH7110_SYSCLK_PLL2_OUT			(JH7110_SYSCLK_NCLKS + 2)
245 
246 /* AONCRG clocks */
247 #define JH7110_AONCLK_OSC_DIV4			0
248 #define JH7110_AONCLK_APB_FUNC			1
249 #define JH7110_AONCLK_GMAC0_AHB			2
250 #define JH7110_AONCLK_GMAC0_AXI			3
251 #define JH7110_AONCLK_GMAC0_RMII_RTX		4
252 #define JH7110_AONCLK_GMAC0_TX			5
253 #define JH7110_AONCLK_GMAC0_TX_INV		6
254 #define JH7110_AONCLK_GMAC0_RX			7
255 #define JH7110_AONCLK_GMAC0_RX_INV		8
256 #define JH7110_AONCLK_OTPC_APB			9
257 #define JH7110_AONCLK_RTC_APB			10
258 #define JH7110_AONCLK_RTC_INTERNAL		11
259 #define JH7110_AONCLK_RTC_32K			12
260 #define JH7110_AONCLK_RTC_CAL			13
261 
262 #define JH7110_AONCLK_NCLKS			14
263 
264 /* STGCRG clocks */
265 #define JH7110_STGCLK_HIFI4_CLK_CORE		0
266 #define JH7110_STGCLK_USB0_APB			1
267 #define JH7110_STGCLK_USB0_UTMI_APB		2
268 #define JH7110_STGCLK_USB0_AXI			3
269 #define JH7110_STGCLK_USB0_LPM			4
270 #define JH7110_STGCLK_USB0_STB			5
271 #define JH7110_STGCLK_USB0_APP_125		6
272 #define JH7110_STGCLK_USB0_REFCLK		7
273 #define JH7110_STGCLK_PCIE0_AXI_MST0		8
274 #define JH7110_STGCLK_PCIE0_APB			9
275 #define JH7110_STGCLK_PCIE0_TL			10
276 #define JH7110_STGCLK_PCIE1_AXI_MST0		11
277 #define JH7110_STGCLK_PCIE1_APB			12
278 #define JH7110_STGCLK_PCIE1_TL			13
279 #define JH7110_STGCLK_PCIE_SLV_MAIN		14
280 #define JH7110_STGCLK_SEC_AHB			15
281 #define JH7110_STGCLK_SEC_MISC_AHB		16
282 #define JH7110_STGCLK_GRP0_MAIN			17
283 #define JH7110_STGCLK_GRP0_BUS			18
284 #define JH7110_STGCLK_GRP0_STG			19
285 #define JH7110_STGCLK_GRP1_MAIN			20
286 #define JH7110_STGCLK_GRP1_BUS			21
287 #define JH7110_STGCLK_GRP1_STG			22
288 #define JH7110_STGCLK_GRP1_HIFI			23
289 #define JH7110_STGCLK_E2_RTC			24
290 #define JH7110_STGCLK_E2_CORE			25
291 #define JH7110_STGCLK_E2_DBG			26
292 #define JH7110_STGCLK_DMA1P_AXI			27
293 #define JH7110_STGCLK_DMA1P_AHB			28
294 
295 #define JH7110_STGCLK_NCLKS			29
296 
297 /* ISPCRG clocks */
298 #define JH7110_ISPCLK_DOM4_APB_FUNC		0
299 #define JH7110_ISPCLK_MIPI_RX0_PXL		1
300 #define JH7110_ISPCLK_DVP_INV			2
301 #define JH7110_ISPCLK_M31DPHY_CFG_IN		3
302 #define JH7110_ISPCLK_M31DPHY_REF_IN		4
303 #define JH7110_ISPCLK_M31DPHY_TX_ESC_LAN0	5
304 #define JH7110_ISPCLK_VIN_APB			6
305 #define JH7110_ISPCLK_VIN_SYS			7
306 #define JH7110_ISPCLK_VIN_PIXEL_IF0		8
307 #define JH7110_ISPCLK_VIN_PIXEL_IF1		9
308 #define JH7110_ISPCLK_VIN_PIXEL_IF2		10
309 #define JH7110_ISPCLK_VIN_PIXEL_IF3		11
310 #define JH7110_ISPCLK_VIN_P_AXI_WR		12
311 #define JH7110_ISPCLK_ISPV2_TOP_WRAPPER_C	13
312 
313 #define JH7110_ISPCLK_NCLKS			14
314 
315 /* VOUTCRG clocks */
316 #define JH7110_VOUTCLK_APB			0
317 #define JH7110_VOUTCLK_DC8200_PIX		1
318 #define JH7110_VOUTCLK_DSI_SYS			2
319 #define JH7110_VOUTCLK_TX_ESC			3
320 #define JH7110_VOUTCLK_DC8200_AXI		4
321 #define JH7110_VOUTCLK_DC8200_CORE		5
322 #define JH7110_VOUTCLK_DC8200_AHB		6
323 #define JH7110_VOUTCLK_DC8200_PIX0		7
324 #define JH7110_VOUTCLK_DC8200_PIX1		8
325 #define JH7110_VOUTCLK_DOM_VOUT_TOP_LCD		9
326 #define JH7110_VOUTCLK_DSITX_APB		10
327 #define JH7110_VOUTCLK_DSITX_SYS		11
328 #define JH7110_VOUTCLK_DSITX_DPI		12
329 #define JH7110_VOUTCLK_DSITX_TXESC		13
330 #define JH7110_VOUTCLK_MIPITX_DPHY_TXESC	14
331 #define JH7110_VOUTCLK_HDMI_TX_MCLK		15
332 #define JH7110_VOUTCLK_HDMI_TX_BCLK		16
333 #define JH7110_VOUTCLK_HDMI_TX_SYS		17
334 
335 #define JH7110_VOUTCLK_NCLKS			18
336 
337 static const char *cpu_root_parents[] = {
338 	"osc", "pll0_out"
339 };
340 
341 static const char *gpu_root_parents[] = {
342 	"pll2_out", "pll1_out",
343 };
344 
345 static const char *bus_root_parents[] = {
346 	"osc", "pll2_out",
347 };
348 
349 static const char *mclk_parents[] = {
350 	"mclk_inner", "mclk_ext"
351 };
352 
353 static const char *ddr_bus_parents[] = {
354 	"osc_div2", "pll1_div2", "pll1_div4", "pll1_div8"
355 };
356 
357 static const char *qspi_ref_parents[] = {
358 	"osc", "qspi_ref_src",
359 };
360 
361 static const char *isp_2x_parents[] = {
362 	"pll2_out", "pll1_out"
363 };
364 
365 static const char *i2stx0_lrck_parents[] = {
366 	"i2stx0_lrck_mst", "i2stx_lrck_ext",
367 };
368 
369 static const char *i2stx0_bclk_parents[] = {
370 	"i2stx0_bclk_mst", "i2stx_bclk_ext",
371 };
372 
373 static const char *i2stx1_bclk_parents[] = {
374 	"i2stx1_bclk_mst", "i2stx_bclk_ext",
375 };
376 
377 static const char *gmac1_rx_parents[] = {
378 	"gmac1_rgmii_rxin", "gmac1_rmii_rtx",
379 };
380 
381 static const char *i2srx_bclk_root_parents[] = {
382 	"i2srx_bclk_mst", "i2srx_bclk_ext",
383 };
384 
385 static const char *i2srx_lrck_parents[] = {
386 	"i2srx_lrck_mst", "i2srx_lrck_ext",
387 };
388 
389 static const char *tdm_tdm_parents[] = {
390 	"tdm_internal", "tdm_ext",
391 };
392 
393 static const char *i2stx1_lrck_parents[] = {
394 	"i2stx1_lrck_mst", "i2stx_lrck_ext",
395 };
396 
397 static const char *i2stx1_lrck_mst_parents[] = {
398 	"i2stx1_bclk_mst_inv", "i2stx1_bclk_mst",
399 };
400 
401 static const char *gmac1_tx_parents[] = {
402 	"gmac1_gtxclk", "gmac1_rmii_rtx",
403 };
404 
405 static const char *perh_root_parents[] = {
406 	"pll0_out", "pll2_out",
407 };
408 
409 static const char *i2stx0_lrck_mst_parents[] = {
410 	"i2stx0_bclk_mst_inv", "i2stx0_bclk_mst"
411 };
412 
413 static const char *i2srx_lrck_mst_parents[] = {
414 	"i2srx_bclk_mst_inv", "i2srx_bclk_mst",
415 };
416 
417 static struct jh71x0_clkc_clk jh7110_sysclk_clocks[] = {
418 	JH71X0CLKC_FIXED_FACTOR(JH7110_SYSCLK_PLL0_OUT,	"pll0_out",	"osc",	 3, 125),
419 	JH71X0CLKC_FIXED_FACTOR(JH7110_SYSCLK_PLL1_OUT,	"pll1_out",	"osc",	12, 533),
420 	JH71X0CLKC_FIXED_FACTOR(JH7110_SYSCLK_PLL2_OUT,	"pll2_out",	"osc",	 2,  99),
421 
422 	JH71X0CLKC_MUX(JH7110_SYSCLK_CPU_ROOT, "cpu_root", cpu_root_parents),
423 	JH71X0CLKC_MUX(JH7110_SYSCLK_GPU_ROOT, "gpu_root", gpu_root_parents),
424 	JH71X0CLKC_MUX(JH7110_SYSCLK_BUS_ROOT, "bus_root", bus_root_parents),
425 
426 	JH71X0CLKC_DIV(JH7110_SYSCLK_CPU_CORE, "cpu_core", 7, "cpu_root"),
427 	JH71X0CLKC_DIV(JH7110_SYSCLK_CPU_BUS,  "cpu_bus", 2, "cpu_core"),
428 
429 	JH71X0CLKC_MUXDIV(JH7110_SYSCLK_PERH_ROOT, "perh_root", 2, perh_root_parents),
430 
431 	JH71X0CLKC_DIV(JH7110_SYSCLK_NOCSTG_BUS, "nocstg_bus", 3, "bus_root"),
432 	JH71X0CLKC_DIV(JH7110_SYSCLK_AXI_CFG0, "axi_cfg0", 3, "bus_root"),
433 	JH71X0CLKC_DIV(JH7110_SYSCLK_STG_AXIAHB, "stg_axiahb", 2, "axi_cfg0"),
434 	JH71X0CLKC_GATE(JH7110_SYSCLK_AHB0, "ahb0", "stg_axiahb"), // CLK_IS_CRITICAL,
435 	JH71X0CLKC_GATE(JH7110_SYSCLK_AHB1, "ahb1", "stg_axiahb"),// CLK_IS_CRITICAL,
436 	JH71X0CLKC_DIV(JH7110_SYSCLK_APB_BUS, "apb_bus", 8, "stg_axiahb"),
437 	JH71X0CLKC_GATE(JH7110_SYSCLK_APB0, "apb0", "apb_bus"),// CLK_IS_CRITICAL,
438 	JH71X0CLKC_DIV(JH7110_SYSCLK_PLL0_DIV2, "pll0_div2", 2, "pll0_out"),
439 	JH71X0CLKC_DIV(JH7110_SYSCLK_PLL1_DIV2, "pll1_div2", 2, "pll1_out"),
440 	JH71X0CLKC_DIV(JH7110_SYSCLK_PLL2_DIV2, "pll2_div2", 2, "pll2_out"),
441 	JH71X0CLKC_DIV(JH7110_SYSCLK_AUDIO_ROOT, "audio_root", 8, "pll2_out"),
442 	JH71X0CLKC_DIV(JH7110_SYSCLK_MCLK_INNER, "mclk_inner", 64, "audio_root"),
443 
444 	JH71X0CLKC_MUX(JH7110_SYSCLK_MCLK, "mclk", mclk_parents),
445 
446 	JH71X0CLKC_GATE(JH7110_SYSCLK_MCLK_OUT, "mclk_out", "mclk_inner"),
447 
448 	JH71X0CLKC_MUXDIV(JH7110_SYSCLK_ISP_2X, "isp_2x", 8, isp_2x_parents),
449 
450 	JH71X0CLKC_DIV(JH7110_SYSCLK_ISP_AXI, "isp_axi", 4, "isp_2x"),
451 	JH71X0CLKC_GATEDIV(JH7110_SYSCLK_GCLK0, "gclk0", 62, "pll0_div2"),
452 	JH71X0CLKC_GATEDIV(JH7110_SYSCLK_GCLK1, "gclk1",62, "pll1_div2"),
453 	JH71X0CLKC_GATEDIV(JH7110_SYSCLK_GCLK2, "gclk2",62, "pll2_div2"),
454 	/* cores */
455 	JH71X0CLKC_GATE(JH7110_SYSCLK_CORE, "core", "cpu_core"),// CLK_IS_CRITICAL,
456 	JH71X0CLKC_GATE(JH7110_SYSCLK_CORE1, "core1", "cpu_core"),// CLK_IS_CRITICAL,
457 	JH71X0CLKC_GATE(JH7110_SYSCLK_CORE2, "core2", "cpu_core"),// CLK_IS_CRITICAL,
458 	JH71X0CLKC_GATE(JH7110_SYSCLK_CORE3, "core3", "cpu_core"),// CLK_IS_CRITICAL,
459 	JH71X0CLKC_GATE(JH7110_SYSCLK_CORE4, "core4", "cpu_core"),// CLK_IS_CRITICAL,
460 	JH71X0CLKC_GATE(JH7110_SYSCLK_DEBUG, "debug", "cpu_bus"),
461 	JH71X0CLKC_DIV(JH7110_SYSCLK_RTC_TOGGLE, "rtc_toggle", 6, "osc"),
462 	JH71X0CLKC_GATE(JH7110_SYSCLK_TRACE0, "trace0", "cpu_core"),
463 	JH71X0CLKC_GATE(JH7110_SYSCLK_TRACE1, "trace1", "cpu_core"),
464 	JH71X0CLKC_GATE(JH7110_SYSCLK_TRACE2, "trace2", "cpu_core"),
465 	JH71X0CLKC_GATE(JH7110_SYSCLK_TRACE3, "trace3", "cpu_core"),
466 	JH71X0CLKC_GATE(JH7110_SYSCLK_TRACE4, "trace4", "cpu_core"),
467 	JH71X0CLKC_GATE(JH7110_SYSCLK_TRACE_COM, "trace_com", "cpu_bus"),
468 	/* noc */
469 	JH71X0CLKC_GATE(JH7110_SYSCLK_NOC_BUS_CPU_AXI, "noc_bus_cpu_axi", "cpu_bus"), // CLK_IS_CRITICAL,
470 	JH71X0CLKC_GATE(JH7110_SYSCLK_NOC_BUS_AXICFG0_AXI, "noc_bus_axicfg0_axi", "axi_cfg0"),// CLK_IS_CRITICAL,
471 	/* ddr */
472 	JH71X0CLKC_DIV(JH7110_SYSCLK_OSC_DIV2, "osc_div2", 2, "osc"),
473 	JH71X0CLKC_DIV(JH7110_SYSCLK_PLL1_DIV4, "pll1_div4", 2, "pll1_div2"),
474 	JH71X0CLKC_DIV(JH7110_SYSCLK_PLL1_DIV8, "pll1_div8", 2, "pll1_div4"),
475 	JH71X0CLKC_MUX(JH7110_SYSCLK_DDR_BUS, "ddr_bus", ddr_bus_parents),
476 
477 	JH71X0CLKC_GATE(JH7110_SYSCLK_DDR_AXI, "ddr_axi", "ddr_bus"),// CLK_IS_CRITICAL,
478 	/* gpu */
479 	JH71X0CLKC_DIV(JH7110_SYSCLK_GPU_CORE, "gpu_core", 7, "gpu_root"),
480 	JH71X0CLKC_GATE(JH7110_SYSCLK_GPU_CORE_CLK, "gpu_core_clk", "gpu_core"),
481 	JH71X0CLKC_GATE(JH7110_SYSCLK_GPU_SYS_CLK, "gpu_sys_clk", "isp_axi"),
482 	JH71X0CLKC_GATE(JH7110_SYSCLK_GPU_APB, "gpu_apb", "apb_bus"),
483 	JH71X0CLKC_GATEDIV(JH7110_SYSCLK_GPU_RTC_TOGGLE, "gpu_rtc_toggle", 12, "osc"),
484 	JH71X0CLKC_GATE(JH7110_SYSCLK_NOC_BUS_GPU_AXI, "noc_bus_gpu_axi", "gpu_core"),
485 	/* isp */
486 	JH71X0CLKC_GATE(JH7110_SYSCLK_ISP_TOP_CORE, "isp_top_core", "isp_2x"),
487 	JH71X0CLKC_GATE(JH7110_SYSCLK_ISP_TOP_AXI, "isp_top_axi", "isp_axi"),
488 	JH71X0CLKC_GATE(JH7110_SYSCLK_NOC_BUS_ISP_AXI, "noc_bus_isp_axi", "isp_axi"), // CLK_IS_CRITICAL,
489 	/* hifi4 */
490 	JH71X0CLKC_DIV(JH7110_SYSCLK_HIFI4_CORE, "hifi4_core", 15, "bus_root"),
491 	JH71X0CLKC_DIV(JH7110_SYSCLK_HIFI4_AXI, "hifi4_axi", 2, "hifi4_core"),
492 	/* axi_cfg1 */
493 	JH71X0CLKC_GATE(JH7110_SYSCLK_AXI_CFG1_MAIN, "axi_cfg1_main", "isp_axi"), // CLK_IS_CRITICAL
494 	JH71X0CLKC_GATE(JH7110_SYSCLK_AXI_CFG1_AHB, "axi_cfg1_ahb", "ahb0"), // CLK_IS_CRITICAL
495 	/* vout */
496 	JH71X0CLKC_GATE(JH7110_SYSCLK_VOUT_SRC, "vout_src", "pll2_out"),
497 	JH71X0CLKC_DIV(JH7110_SYSCLK_VOUT_AXI, "vout_axi", 7, "pll2_out"),
498 	JH71X0CLKC_GATE(JH7110_SYSCLK_NOC_BUS_DISP_AXI, "noc_bus_disp_axi", "vout_axi"),
499 	JH71X0CLKC_GATE(JH7110_SYSCLK_VOUT_TOP_AHB, "vout_top_ahb", "ahb1"),
500 	JH71X0CLKC_GATE(JH7110_SYSCLK_VOUT_TOP_AXI, "vout_top_axi", "vout_axi"),
501 	JH71X0CLKC_GATE(JH7110_SYSCLK_VOUT_TOP_HDMITX0_MCLK, "vout_top_hdmitx0_mclk", "mclk_out"),
502 	JH71X0CLKC_DIV(JH7110_SYSCLK_VOUT_TOP_MIPIPHY_REF, "vout_top_mipiphy_ref", 2, "osc"),
503 	/* jpegc */
504 	JH71X0CLKC_DIV(JH7110_SYSCLK_JPEGC_AXI, "jpegc_axi", 16, "pll2_out"),
505 	JH71X0CLKC_GATE(JH7110_SYSCLK_CODAJ12_AXI, "codaj12_axi", "jpegc_axi"),
506 	JH71X0CLKC_GATEDIV(JH7110_SYSCLK_CODAJ12_CORE, "codaj12_core",16, "pll2_out"),
507 	JH71X0CLKC_GATE(JH7110_SYSCLK_CODAJ12_APB, "codaj12_apb", "apb_bus"),
508 	/* vdec */
509 	JH71X0CLKC_DIV(JH7110_SYSCLK_VDEC_AXI, "vdec_axi", 7, "bus_root"),
510 	JH71X0CLKC_GATE(JH7110_SYSCLK_WAVE511_AXI, "wave511_axi", "vdec_axi"),
511 	JH71X0CLKC_GATEDIV(JH7110_SYSCLK_WAVE511_BPU, "wave511_bpu",7, "bus_root"),
512 	JH71X0CLKC_GATEDIV(JH7110_SYSCLK_WAVE511_VCE, "wave511_vce", 7, "pll0_out"),
513 	JH71X0CLKC_GATE(JH7110_SYSCLK_WAVE511_APB, "wave511_apb", "apb_bus"),
514 	JH71X0CLKC_GATE(JH7110_SYSCLK_VDEC_JPG, "vdec_jpg", "jpegc_axi"),
515 	JH71X0CLKC_GATE(JH7110_SYSCLK_VDEC_MAIN, "vdec_main", "vdec_axi"),
516 	JH71X0CLKC_GATE(JH7110_SYSCLK_NOC_BUS_VDEC_AXI, "noc_bus_vdec_axi", "vdec_axi"),
517 	/* venc */
518 	JH71X0CLKC_DIV(JH7110_SYSCLK_VENC_AXI, "venc_axi", 15, "pll2_out"),
519 	JH71X0CLKC_GATE(JH7110_SYSCLK_WAVE420L_AXI, "wave420l_axi", "venc_axi"),
520 	JH71X0CLKC_GATEDIV(JH7110_SYSCLK_WAVE420L_BPU, "wave420l_bpu",15, "pll2_out"),
521 	JH71X0CLKC_GATEDIV(JH7110_SYSCLK_WAVE420L_VCE, "wave420l_vce",15, "pll2_out"),
522 	JH71X0CLKC_GATE(JH7110_SYSCLK_WAVE420L_APB, "wave420l_apb", "apb_bus"),
523 	JH71X0CLKC_GATE(JH7110_SYSCLK_NOC_BUS_VENC_AXI, "noc_bus_venc_axi", "venc_axi"),
524 	/* axi_cfg0 */
525 	JH71X0CLKC_GATE(JH7110_SYSCLK_AXI_CFG0_MAIN_DIV, "axi_cfg0_main_div", "ahb1"), // CLK_IS_CRITICAL
526 	JH71X0CLKC_GATE(JH7110_SYSCLK_AXI_CFG0_MAIN, "axi_cfg0_main", "axi_cfg0"), // CLK_IS_CRITICAL
527 	JH71X0CLKC_GATE(JH7110_SYSCLK_AXI_CFG0_HIFI4, "axi_cfg0_hifi4", "hifi4_axi"), // CLK_IS_CRITICAL,
528 	/* intmem */
529 	JH71X0CLKC_GATE(JH7110_SYSCLK_AXIMEM2_AXI, "aximem2_axi", "axi_cfg0"),
530 	/* qspi */
531 	JH71X0CLKC_GATE(JH7110_SYSCLK_QSPI_AHB, "qspi_ahb", "ahb1"),
532 	JH71X0CLKC_GATE(JH7110_SYSCLK_QSPI_APB, "qspi_apb", "apb_bus"),
533 	JH71X0CLKC_DIV(JH7110_SYSCLK_QSPI_REF_SRC, "qspi_ref_src", 16, "pll0_out"),
534 	JH71X0CLKC_MUXGATE(JH7110_SYSCLK_QSPI_REF, "qspi_ref", qspi_ref_parents),
535 
536 	/* sdio */
537 	JH71X0CLKC_GATE(JH7110_SYSCLK_SDIO0_AHB, "sdio0_ahb", "ahb0"),
538 	JH71X0CLKC_GATE(JH7110_SYSCLK_SDIO1_AHB, "sdio1_ahb", "ahb0"),
539 	JH71X0CLKC_GATEDIV(JH7110_SYSCLK_SDIO0_SDCARD, "sdio0_sdcard", 15, "axi_cfg0"),
540 	JH71X0CLKC_GATEDIV(JH7110_SYSCLK_SDIO1_SDCARD, "sdio1_sdcard", 15, "axi_cfg0"),
541 	/* stg */
542 	JH71X0CLKC_DIV(JH7110_SYSCLK_USB_125M, "usb_125m", 15, "pll0_out"),
543 	JH71X0CLKC_GATE(JH7110_SYSCLK_NOC_BUS_STG_AXI, "noc_bus_stg_axi", "nocstg_bus"), // CLK_IS_CRITICAL,
544 	/* gmac1 */
545 	JH71X0CLKC_GATE(JH7110_SYSCLK_GMAC1_AHB, "gmac1_ahb", "ahb0"),
546 	JH71X0CLKC_GATE(JH7110_SYSCLK_GMAC1_AXI, "gmac1_axi", "stg_axiahb"),
547 	JH71X0CLKC_DIV(JH7110_SYSCLK_GMAC_SRC, "gmac_src", 7, "pll0_out"),
548 	JH71X0CLKC_DIV(JH7110_SYSCLK_GMAC1_GTXCLK, "gmac1_gtxclk", 15, "pll0_out"),
549 	JH71X0CLKC_DIV(JH7110_SYSCLK_GMAC1_RMII_RTX, "gmac1_rmii_rtx", 30, "gmac1_rmii_refin"),
550 	JH71X0CLKC_GATEDIV(JH7110_SYSCLK_GMAC1_PTP, "gmac1_ptp",31, "gmac_src"),
551 	JH71X0CLKC_MUX(JH7110_SYSCLK_GMAC1_RX, "gmac1_rx", gmac1_rx_parents),
552 
553 	JH71X0CLKC_INV(JH7110_SYSCLK_GMAC1_RX_INV, "gmac1_rx_inv", "gmac1_rx"),
554 	JH71X0CLKC_MUXGATE_FLAGS(JH7110_SYSCLK_GMAC1_TX, "gmac1_tx", gmac1_tx_parents, CLK_SET_RATE_PARENT), // CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
555 	JH71X0CLKC_INV(JH7110_SYSCLK_GMAC1_TX_INV, "gmac1_tx_inv", "gmac1_tx"),
556 	JH71X0CLKC_GATE(JH7110_SYSCLK_GMAC1_GTXC, "gmac1_gtxc", "gmac1_gtxclk"),
557 	/* gmac0 */
558 	JH71X0CLKC_GATEDIV(JH7110_SYSCLK_GMAC0_GTXCLK, "gmac0_gtxclk",15, "pll0_out"),
559 	JH71X0CLKC_GATEDIV(JH7110_SYSCLK_GMAC0_PTP, "gmac0_ptp",31, "gmac_src"),
560 	JH71X0CLKC_GATEDIV(JH7110_SYSCLK_GMAC_PHY, "gmac_phy",31, "gmac_src"),
561 	JH71X0CLKC_GATE(JH7110_SYSCLK_GMAC0_GTXC, "gmac0_gtxc", "gmac0_gtxclk"),
562 	/* apb misc */
563 	JH71X0CLKC_GATE(JH7110_SYSCLK_IOMUX_APB, "iomux_apb", "apb_bus"),
564 	JH71X0CLKC_GATE(JH7110_SYSCLK_MAILBOX_APB, "mailbox_apb", "apb_bus"),
565 	JH71X0CLKC_GATE(JH7110_SYSCLK_INT_CTRL_APB, "int_ctrl_apb", "apb_bus"),
566 	/* can0 */
567 	JH71X0CLKC_GATE(JH7110_SYSCLK_CAN0_APB, "can0_apb", "apb_bus"),
568 	JH71X0CLKC_GATEDIV(JH7110_SYSCLK_CAN0_TIMER, "can0_timer",24, "osc"),
569 	JH71X0CLKC_GATEDIV(JH7110_SYSCLK_CAN0_CAN, "can0_can",63, "perh_root"),
570 	/* can1 */
571 	JH71X0CLKC_GATE(JH7110_SYSCLK_CAN1_APB, "can1_apb", "apb_bus"),
572 	JH71X0CLKC_GATEDIV(JH7110_SYSCLK_CAN1_TIMER, "can1_timer",24, "osc"),
573 	JH71X0CLKC_GATEDIV(JH7110_SYSCLK_CAN1_CAN, "can1_can",63, "perh_root"),
574 	/* pwm */
575 	JH71X0CLKC_GATE(JH7110_SYSCLK_PWM_APB, "pwm_apb", "apb_bus"),
576 	/* wdt */
577 	JH71X0CLKC_GATE(JH7110_SYSCLK_WDT_APB, "wdt_apb", "apb_bus"),
578 	JH71X0CLKC_GATE(JH7110_SYSCLK_WDT_CORE, "wdt_core", "osc"),
579 	/* timer */
580 	JH71X0CLKC_GATE(JH7110_SYSCLK_TIMER_APB, "timer_apb", "apb_bus"),
581 	JH71X0CLKC_GATE(JH7110_SYSCLK_TIMER0, "timer0", "osc"),
582 	JH71X0CLKC_GATE(JH7110_SYSCLK_TIMER1, "timer1", "osc"),
583 	JH71X0CLKC_GATE(JH7110_SYSCLK_TIMER2, "timer2", "osc"),
584 	JH71X0CLKC_GATE(JH7110_SYSCLK_TIMER3, "timer3", "osc"),
585 	/* temp sensor */
586 	JH71X0CLKC_GATE(JH7110_SYSCLK_TEMP_APB, "temp_apb", "apb_bus"),
587 	JH71X0CLKC_GATEDIV(JH7110_SYSCLK_TEMP_CORE, "temp_core",24, "osc"),
588 	/* spi */
589 	JH71X0CLKC_GATE(JH7110_SYSCLK_SPI0_APB, "spi0_apb", "apb0"),
590 	JH71X0CLKC_GATE(JH7110_SYSCLK_SPI1_APB, "spi1_apb", "apb0"),
591 	JH71X0CLKC_GATE(JH7110_SYSCLK_SPI2_APB, "spi2_apb", "apb0"),
592 	JH71X0CLKC_GATE(JH7110_SYSCLK_SPI3_APB, "spi3_apb", "apb_bus"),
593 	JH71X0CLKC_GATE(JH7110_SYSCLK_SPI4_APB, "spi4_apb", "apb_bus"),
594 	JH71X0CLKC_GATE(JH7110_SYSCLK_SPI5_APB, "spi5_apb", "apb_bus"),
595 	JH71X0CLKC_GATE(JH7110_SYSCLK_SPI6_APB, "spi6_apb", "apb_bus"),
596 	/* i2c */
597 	JH71X0CLKC_GATE(JH7110_SYSCLK_I2C0_APB, "i2c0_apb", "apb0"),
598 	JH71X0CLKC_GATE(JH7110_SYSCLK_I2C1_APB, "i2c1_apb", "apb0"),
599 	JH71X0CLKC_GATE(JH7110_SYSCLK_I2C2_APB, "i2c2_apb", "apb0"),
600 	JH71X0CLKC_GATE(JH7110_SYSCLK_I2C3_APB, "i2c3_apb", "apb_bus"),
601 	JH71X0CLKC_GATE(JH7110_SYSCLK_I2C4_APB, "i2c4_apb", "apb_bus"),
602 	JH71X0CLKC_GATE(JH7110_SYSCLK_I2C5_APB, "i2c5_apb", "apb_bus"),
603 	JH71X0CLKC_GATE(JH7110_SYSCLK_I2C6_APB, "i2c6_apb", "apb_bus"),
604 	/* uart */
605 	JH71X0CLKC_GATE(JH7110_SYSCLK_UART0_APB, "uart0_apb", "apb0"),
606 	JH71X0CLKC_GATE(JH7110_SYSCLK_UART0_CORE, "uart0_core", "osc"),
607 	JH71X0CLKC_GATE(JH7110_SYSCLK_UART1_APB, "uart1_apb", "apb0"),
608 	JH71X0CLKC_GATE(JH7110_SYSCLK_UART1_CORE, "uart1_core", "osc"),
609 	JH71X0CLKC_GATE(JH7110_SYSCLK_UART2_APB, "uart2_apb", "apb0"),
610 	JH71X0CLKC_GATE(JH7110_SYSCLK_UART2_CORE, "uart2_core", "osc"),
611 	JH71X0CLKC_GATE(JH7110_SYSCLK_UART3_APB, "uart3_apb", "apb0"),
612 	JH71X0CLKC_GATEDIV(JH7110_SYSCLK_UART3_CORE, "uart3_core",10, "perh_root"),
613 	JH71X0CLKC_GATE(JH7110_SYSCLK_UART4_APB, "uart4_apb", "apb0"),
614 	JH71X0CLKC_GATEDIV(JH7110_SYSCLK_UART4_CORE, "uart4_core",10, "perh_root"),
615 	JH71X0CLKC_GATE(JH7110_SYSCLK_UART5_APB, "uart5_apb", "apb0"),
616 	JH71X0CLKC_GATEDIV(JH7110_SYSCLK_UART5_CORE, "uart5_core",10, "perh_root"),
617 	/* pwmdac */
618 	JH71X0CLKC_GATE(JH7110_SYSCLK_PWMDAC_APB, "pwmdac_apb", "apb0"),
619 	JH71X0CLKC_GATEDIV(JH7110_SYSCLK_PWMDAC_CORE, "pwmdac_core",256, "audio_root"),
620 	/* spdif */
621 	JH71X0CLKC_GATE(JH7110_SYSCLK_SPDIF_APB, "spdif_apb", "apb0"),
622 	JH71X0CLKC_GATE(JH7110_SYSCLK_SPDIF_CORE, "spdif_core", "mclk_out"),
623 	/* i2stx0 */
624 	JH71X0CLKC_GATE(JH7110_SYSCLK_I2STX0_APB, "i2stx0_apb", "apb0"),
625 	JH71X0CLKC_GATEDIV(JH7110_SYSCLK_I2STX0_BCLK_MST, "i2stx0_bclk_mst",32, "mclk_out"),
626 	JH71X0CLKC_INV(JH7110_SYSCLK_I2STX0_BCLK_MST_INV, "i2stx0_bclk_mst_inv", "i2stx0_bclk_mst"),
627 
628 	JH71X0CLKC_MUXDIV(JH7110_SYSCLK_I2STX0_LRCK_MST, "i2stx0_lrck_mst", 64, i2stx0_lrck_mst_parents),
629 
630 	JH71X0CLKC_MUX(JH7110_SYSCLK_I2STX0_BCLK, "i2stx0_bclk", i2stx0_bclk_parents),
631 	JH71X0CLKC_INV(JH7110_SYSCLK_I2STX0_BCLK_INV, "i2stx0_bclk_inv", "i2stx0_bclk"),
632 	JH71X0CLKC_MUX(JH7110_SYSCLK_I2STX0_LRCK, "i2stx0_lrck", i2stx0_lrck_parents),
633 	/* i2stx1 */
634 	JH71X0CLKC_GATE(JH7110_SYSCLK_I2STX1_APB, "i2stx1_apb", "apb0"),
635 	JH71X0CLKC_GATEDIV(JH7110_SYSCLK_I2STX1_BCLK_MST, "i2stx1_bclk_mst",32, "mclk_out"),
636 	JH71X0CLKC_INV(JH7110_SYSCLK_I2STX1_BCLK_MST_INV, "i2stx1_bclk_mst_inv", "i2stx1_bclk_mst"),
637 
638 	JH71X0CLKC_MUXDIV(JH7110_SYSCLK_I2STX1_LRCK_MST, "i2stx1_lrck_mst", 64, i2stx1_lrck_mst_parents),
639 
640 	JH71X0CLKC_MUX(JH7110_SYSCLK_I2STX1_BCLK, "i2stx1_bclk", i2stx1_bclk_parents),
641 	JH71X0CLKC_INV(JH7110_SYSCLK_I2STX1_BCLK_INV, "i2stx1_bclk_inv", "i2stx1_bclk"),
642 	JH71X0CLKC_MUX(JH7110_SYSCLK_I2STX1_LRCK, "i2stx1_lrck", i2stx1_lrck_parents),
643 	/* i2srx */
644 	JH71X0CLKC_GATE(JH7110_SYSCLK_I2SRX_APB, "i2srx_apb", "apb0"),
645 	JH71X0CLKC_GATEDIV(JH7110_SYSCLK_I2SRX_BCLK_MST, "i2srx_bclk_mst", 32, "mclk_out"),
646 	JH71X0CLKC_INV(JH7110_SYSCLK_I2SRX_BCLK_MST_INV, "i2srx_bclk_mst_inv", "i2srx_bclk_mst"),
647 
648 	JH71X0CLKC_MUXDIV(JH7110_SYSCLK_I2SRX_LRCK_MST, "i2srx_lrck_mst", 64, i2srx_lrck_mst_parents),
649 
650 	JH71X0CLKC_MUX(JH7110_SYSCLK_I2SRX_BCLK, "i2srx_bclk", i2srx_bclk_root_parents),
651 	JH71X0CLKC_INV(JH7110_SYSCLK_I2SRX_BCLK_INV, "i2srx_bclk_inv", "i2srx_bclk"),
652 	JH71X0CLKC_MUX(JH7110_SYSCLK_I2SRX_LRCK, "i2srx_lrck", i2srx_lrck_parents),
653 	/* pdm */
654 	JH71X0CLKC_GATEDIV(JH7110_SYSCLK_PDM_DMIC, "pdm_dmic",64, "mclk_out"),
655 	JH71X0CLKC_GATE(JH7110_SYSCLK_PDM_APB, "pdm_apb", "apb0"),
656 	/* tdm */
657 	JH71X0CLKC_GATE(JH7110_SYSCLK_TDM_AHB, "tdm_ahb", "ahb0"),
658 	JH71X0CLKC_GATE(JH7110_SYSCLK_TDM_APB, "tdm_apb", "apb0"),
659 	JH71X0CLKC_GATEDIV(JH7110_SYSCLK_TDM_INTERNAL, "tdm_internal",64, "mclk_out"),
660 	JH71X0CLKC_MUX(JH7110_SYSCLK_TDM_TDM, "tdm_tdm", tdm_tdm_parents),
661 	JH71X0CLKC_INV(JH7110_SYSCLK_TDM_TDM_INV, "tdm_tdm_inv", "tdm_tdm"),
662 	/* jtag */
663 	JH71X0CLKC_DIV(JH7110_SYSCLK_JTAG_CERTIFICATION_TRNG, "jtag_certification_trng", 4, "osc"),
664 };
665 
666 static const char *apb_func_parents[] = {
667 	"osc_div4", "osc",
668 };
669 
670 static const char *gmac0_tx_parents[] = {
671 	"gmac0_gtxclk", "gmac0_rmii_rtx"
672 };
673 
674 static const char *gmac0_rx_parents[] = {
675 	"gmac0_rgmii_rxin", "gmac0_rmii_rtx",
676 };
677 
678 static const char *rtc_32k_parents[] = {
679 	"rtc_osc", "rtc_internal",
680 };
681 
682 static struct jh71x0_clkc_clk jh7110_aonclk_clocks[] = {
683 	/* source */
684 	JH71X0CLKC_DIV(JH7110_AONCLK_OSC_DIV4, "osc_div4", 4, "osc"),
685 	JH71X0CLKC_MUX(JH7110_AONCLK_APB_FUNC, "apb_func", apb_func_parents),
686 	/* gmac0 */
687 	JH71X0CLKC_GATE(JH7110_AONCLK_GMAC0_AHB, "gmac0_ahb", "stg_axiahb"),
688 	JH71X0CLKC_GATE(JH7110_AONCLK_GMAC0_AXI, "gmac0_axi", "stg_axiahb"),
689 	JH71X0CLKC_DIV(JH7110_AONCLK_GMAC0_RMII_RTX, "gmac0_rmii_rtx", 30, "gmac0_rmii_refin"),
690 	JH71X0CLKC_MUXGATE(JH7110_AONCLK_GMAC0_TX, "gmac0_tx",gmac0_tx_parents),
691 	JH71X0CLKC_INV(JH7110_AONCLK_GMAC0_TX_INV, "gmac0_tx_inv", "gmac0_tx"),
692 	JH71X0CLKC_MUX_FLAGS(JH7110_AONCLK_GMAC0_RX, "gmac0_rx", gmac0_rx_parents, CLK_SET_RATE_PARENT), // CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT
693 	JH71X0CLKC_INV(JH7110_AONCLK_GMAC0_RX_INV, "gmac0_rx_inv", "gmac0_rx"),
694 	/* otpc */
695 	JH71X0CLKC_GATE(JH7110_AONCLK_OTPC_APB, "otpc_apb", "apb_bus"),
696 	/* rtc */
697 	JH71X0CLKC_GATE(JH7110_AONCLK_RTC_APB, "rtc_apb", "apb_bus"),
698 	JH71X0CLKC_DIV(JH7110_AONCLK_RTC_INTERNAL, "rtc_internal", 1022, "osc"),
699 	JH71X0CLKC_MUX(JH7110_AONCLK_RTC_32K, "rtc_32k", rtc_32k_parents),
700 	JH71X0CLKC_GATE(JH7110_AONCLK_RTC_CAL, "rtc_cal", "osc"),
701 };
702 
703 
704 static struct jh71x0_clkc_clk jh7110_stgclk_clocks[] = {
705 	/* hifi4 */
706 	JH71X0CLKC_GATE(JH7110_STGCLK_HIFI4_CLK_CORE, "hifi4_clk_core", "hifi4_core"),
707 	/* usb */
708 	JH71X0CLKC_GATE(JH7110_STGCLK_USB0_APB, "usb0_apb", "apb_bus"),
709 	JH71X0CLKC_GATE(JH7110_STGCLK_USB0_UTMI_APB, "usb0_utmi_apb", "apb_bus"),
710 	JH71X0CLKC_GATE(JH7110_STGCLK_USB0_AXI, "usb0_axi", "stg_axiahb"),
711 	JH71X0CLKC_GATEDIV(JH7110_STGCLK_USB0_LPM, "usb0_lpm", 2, "osc"),
712 	JH71X0CLKC_GATEDIV(JH7110_STGCLK_USB0_STB, "usb0_stb", 4, "osc"),
713 	JH71X0CLKC_GATE(JH7110_STGCLK_USB0_APP_125, "usb0_app_125", "usb_125m"),
714 	JH71X0CLKC_DIV(JH7110_STGCLK_USB0_REFCLK, "usb0_refclk", 2, "osc"),
715 	/* pci-e */
716 	JH71X0CLKC_GATE(JH7110_STGCLK_PCIE0_AXI_MST0, "pcie0_axi_mst0", "stg_axiahb"),
717 	JH71X0CLKC_GATE(JH7110_STGCLK_PCIE0_APB, "pcie0_apb", "apb_bus"),
718 	JH71X0CLKC_GATE(JH7110_STGCLK_PCIE0_TL, "pcie0_tl", "stg_axiahb"),
719 	JH71X0CLKC_GATE(JH7110_STGCLK_PCIE1_AXI_MST0, "pcie1_axi_mst0", "stg_axiahb"),
720 	JH71X0CLKC_GATE(JH7110_STGCLK_PCIE1_APB, "pcie1_apb", "apb_bus"),
721 	JH71X0CLKC_GATE(JH7110_STGCLK_PCIE1_TL, "pcie1_tl", "stg_axiahb"),
722 	JH71X0CLKC_GATE(JH7110_STGCLK_PCIE_SLV_MAIN, "pcie_slv_main", "stg_axiahb"), // CLK_IS_CRITICAL
723 	/* security */
724 	JH71X0CLKC_GATE(JH7110_STGCLK_SEC_AHB, "sec_ahb", "stg_axiahb"),
725 	JH71X0CLKC_GATE(JH7110_STGCLK_SEC_MISC_AHB, "sec_misc_ahb", "stg_axiahb"),
726 	/* stg mtrx */
727 	JH71X0CLKC_GATE(JH7110_STGCLK_GRP0_MAIN, "mtrx_grp0_main", "cpu_bus"), // CLK_IS_CRITICAL
728 	JH71X0CLKC_GATE(JH7110_STGCLK_GRP0_BUS, "mtrx_grp0_bus", "nocstg_bus"), // CLK_IS_CRITICAL
729 	JH71X0CLKC_GATE(JH7110_STGCLK_GRP0_STG, "mtrx_grp0_stg", "stg_axiahb"), // CLK_IS_CRITICAL
730 	JH71X0CLKC_GATE(JH7110_STGCLK_GRP1_MAIN, "mtrx_grp1_main", "cpu_bus"), // CLK_IS_CRITICAL
731 	JH71X0CLKC_GATE(JH7110_STGCLK_GRP1_BUS, "mtrx_grp1_bus", "nocstg_bus"), // CLK_IS_CRITICAL
732 	JH71X0CLKC_GATE(JH7110_STGCLK_GRP1_STG, "mtrx_grp1_stg", "stg_axiahb"), // CLK_IS_CRITICAL
733 	JH71X0CLKC_GATE(JH7110_STGCLK_GRP1_HIFI, "mtrx_grp1_hifi", "hifi4_axi"), // CLK_IS_CRITICAL
734 	/* e24_rvpi */
735 	JH71X0CLKC_GATEDIV(JH7110_STGCLK_E2_RTC, "e2_rtc", 24, "osc"),
736 	JH71X0CLKC_GATE(JH7110_STGCLK_E2_CORE, "e2_core", "stg_axiahb"),
737 	JH71X0CLKC_GATE(JH7110_STGCLK_E2_DBG, "e2_dbg", "stg_axiahb"),
738 	/* dw_sgdma1p */
739 	JH71X0CLKC_GATE(JH7110_STGCLK_DMA1P_AXI, "dma1p_axi", "stg_axiahb"),
740 	JH71X0CLKC_GATE(JH7110_STGCLK_DMA1P_AHB, "dma1p_ahb", "stg_axiahb"),
741 };
742 
743 #if 0
744 static const char *vin_p_axi_wr_parents[] = {
745 	"mipi_rx0_pxl", "dvp_inv",
746 };
747 
748 static const char *ispv2_top_wrapper_c_parents[] = {
749 	"mipi_rx0_pxl", "dvp_inv",
750 };
751 
752 static struct jh71x0_clkc_clk jh7110_ispclk_clocks[] = {
753 	/* syscon */
754 	JH71X0CLKC_DIV(JH7110_ISPCLK_DOM4_APB_FUNC, "dom4_apb_func", 15, "isp_top_axi"),
755 	JH71X0CLKC_DIV(JH7110_ISPCLK_MIPI_RX0_PXL, "mipi_rx0_pxl", 8, "isp_top_core"),
756 	JH71X0CLKC_INV(JH7110_ISPCLK_DVP_INV, "dvp_inv", "dvp_clk"),
757 	/* vin */
758 	JH71X0CLKC_DIV(JH7110_ISPCLK_M31DPHY_CFG_IN, "m31dphy_cfg_in", 16, "isp_top_core"),
759 	JH71X0CLKC_DIV(JH7110_ISPCLK_M31DPHY_REF_IN, "m31dphy_ref_in", 16, "isp_top_core"),
760 	JH71X0CLKC_DIV(JH7110_ISPCLK_M31DPHY_TX_ESC_LAN0, "m31dphy_tx_esc_lan0", 60, "isp_top_core"),
761 	JH71X0CLKC_GATE(JH7110_ISPCLK_VIN_APB, "vin_apb", "dom4_apb_func"),
762 	JH71X0CLKC_DIV(JH7110_ISPCLK_VIN_SYS, "vin_sys", 8, "isp_top_core"),
763 	JH71X0CLKC_GATE(JH7110_ISPCLK_VIN_PIXEL_IF0, "vin_pixel_if0", "mipi_rx0_pxl"),
764 	JH71X0CLKC_GATE(JH7110_ISPCLK_VIN_PIXEL_IF1, "vin_pixel_if1", "mipi_rx0_pxl"),
765 	JH71X0CLKC_GATE(JH7110_ISPCLK_VIN_PIXEL_IF2, "vin_pixel_if2", "mipi_rx0_pxl"),
766 	JH71X0CLKC_GATE(JH7110_ISPCLK_VIN_PIXEL_IF3, "vin_pixel_if3", "mipi_rx0_pxl"),
767 	JH71X0CLKC_MUX(JH7110_ISPCLK_VIN_P_AXI_WR, "vin_p_axi_wr", vin_p_axi_wr_parents),
768 	/* ispv2_top_wrapper */
769 	JH71X0CLKC_MUXGATE(JH7110_ISPCLK_ISPV2_TOP_WRAPPER_C, "ispv2_top_wrapper_c", ispv2_top_wrapper_c_parents),
770 };
771 #endif
772 
773 static const char *dc8200_pix0_parents[] = {
774 	"dc8200_pix", "hdmitx0_pixelclk",
775 };
776 
777 static const char *dc8200_pix1_parents[] = {
778 	"dc8200_pix", "hdmitx0_pixelclk",
779 };
780 
781 static const char *dsiTx_dpi_parents[] = {
782 	"dc8200_pix", "hdmitx0_pixelclk",
783 };
784 
785 static const char *dom_vout_top_lcd_parents[] = {
786 	"dc8200_pix0", "dc8200_pix1",
787 };
788 
789 static struct jh71x0_clkc_clk jh7110_voutclk_clocks[] = {
790 	/* divider */
791 	JH71X0CLKC_DIV(JH7110_VOUTCLK_APB, "apb", 8, "vout_top_ahb"),
792 	JH71X0CLKC_DIV(JH7110_VOUTCLK_DC8200_PIX, "dc8200_pix", 63, "vout_src"),
793 	JH71X0CLKC_DIV(JH7110_VOUTCLK_DSI_SYS, "dsi_sys", 31, "vout_src"),
794 	JH71X0CLKC_DIV(JH7110_VOUTCLK_TX_ESC, "tx_esc", 31, "vout_top_ahb"),
795 	/* dc8200 */
796 	JH71X0CLKC_GATE(JH7110_VOUTCLK_DC8200_AXI, "dc8200_axi", "vout_top_axi"),
797 	JH71X0CLKC_GATE(JH7110_VOUTCLK_DC8200_CORE, "dc8200_core", "vout_top_axi"),
798 	JH71X0CLKC_GATE(JH7110_VOUTCLK_DC8200_AHB, "dc8200_ahb", "vout_top_ahb"),
799 	JH71X0CLKC_MUXGATE(JH7110_VOUTCLK_DC8200_PIX0, "dc8200_pix0", dc8200_pix0_parents),
800 	JH71X0CLKC_MUXGATE(JH7110_VOUTCLK_DC8200_PIX1, "dc8200_pix1", dc8200_pix1_parents),
801 	/* LCD */
802 	JH71X0CLKC_MUXGATE(JH7110_VOUTCLK_DOM_VOUT_TOP_LCD, "dom_vout_top_lcd", dom_vout_top_lcd_parents),
803 	/* dsiTx */
804 	JH71X0CLKC_GATE(JH7110_VOUTCLK_DSITX_APB, "dsiTx_apb", "dsi_sys"),
805 	JH71X0CLKC_GATE(JH7110_VOUTCLK_DSITX_SYS, "dsiTx_sys", "dsi_sys"),
806 	JH71X0CLKC_MUXGATE(JH7110_VOUTCLK_DSITX_DPI, "dsiTx_dpi", dsiTx_dpi_parents),
807 	JH71X0CLKC_GATE(JH7110_VOUTCLK_DSITX_TXESC, "dsiTx_txesc", "tx_esc"),
808 	/* mipitx DPHY */
809 	JH71X0CLKC_GATE(JH7110_VOUTCLK_MIPITX_DPHY_TXESC, "mipitx_dphy_txesc", "tx_esc"),
810 	/* hdmi */
811 	JH71X0CLKC_GATE(JH7110_VOUTCLK_HDMI_TX_MCLK, "hdmi_tx_mclk", "vout_top_hdmitx0_mclk"),
812 	JH71X0CLKC_GATE(JH7110_VOUTCLK_HDMI_TX_BCLK, "hdmi_tx_bclk", "i2stx0_bclk"),
813 	JH71X0CLKC_GATE(JH7110_VOUTCLK_HDMI_TX_SYS, "hdmi_tx_sys", "apb"),
814 };
815 
816 struct jh7110_clock_config {
817 	struct jh71x0_clkc_clk *jhcc_clocks;
818 	size_t jhcc_nclks;
819 };
820 
821 static struct jh7110_clock_config jh7110_sysclk_config = {
822 	.jhcc_clocks = jh7110_sysclk_clocks,
823 	.jhcc_nclks = __arraycount(jh7110_sysclk_clocks),
824 };
825 
826 static struct jh7110_clock_config jh7110_aonclk_config = {
827 	.jhcc_clocks = jh7110_aonclk_clocks,
828 	.jhcc_nclks = __arraycount(jh7110_aonclk_clocks),
829 };
830 
831 static struct jh7110_clock_config jh7110_stgclk_config = {
832 	.jhcc_clocks = jh7110_stgclk_clocks,
833 	.jhcc_nclks = __arraycount(jh7110_stgclk_clocks),
834 };
835 
836 #if 0
837 static struct jh7110_clock_config jh7110_ispclk_config = {
838 	.jhcc_clocks = jh7110_ispclk_clocks,
839 	.jhcc_nclks = __arraycount(jh7110_ispclk_clocks),
840 };
841 #endif
842 
843 static struct jh7110_clock_config jh7110_voutclk_config = {
844 	.jhcc_clocks = jh7110_voutclk_clocks,
845 	.jhcc_nclks = __arraycount(jh7110_voutclk_clocks),
846 };
847 
848 
849 #define JH7110_SYSRST_ASSERT			0x2f8
850 #define JH7110_SYSRST_STATUS			0x308
851 #define JH7110_SYSRST_NRESETS			126
852 
853 #define JH7110_AONRST_ASSERT			0x38
854 #define JH7110_AONRST_STATUS			0x3c
855 #define JH7110_AONRST_NRESETS			8
856 
857 #define JH7110_STGRST_ASSERT			0x74
858 #define JH7110_STGRST_STATUS			0x78
859 #define JH7110_STGRST_NRESETS			23
860 
861 #define JH7110_ISPRST_ASSERT			0x38
862 #define JH7110_ISPRST_STATUS			0x3c
863 #define JH7110_ISPRST_NRESETS			12
864 
865 #define JH7110_VOUTRST_ASSERT			0x48
866 #define JH7110_VOUTRST_STATUS			0x4c
867 #define JH7110_VOUTRST_NRESETS			12
868 
869 struct jh7110_reset_config {
870 	size_t jhcr_nresets;
871 	bus_size_t jhcr_assert;
872 	bus_size_t jhcr_status;
873 };
874 
875 static struct jh7110_reset_config jh7110_sysrst_config = {
876 	.jhcr_nresets = JH7110_SYSRST_NRESETS,
877 	.jhcr_assert = JH7110_SYSRST_ASSERT,
878 	.jhcr_status = JH7110_SYSRST_STATUS,
879 };
880 
881 static struct jh7110_reset_config jh7110_aonrst_config = {
882 	.jhcr_nresets = JH7110_AONRST_NRESETS,
883 	.jhcr_assert = JH7110_AONRST_ASSERT,
884 	.jhcr_status = JH7110_AONRST_STATUS,
885 };
886 
887 static struct jh7110_reset_config jh7110_stgrst_config = {
888 	.jhcr_nresets = JH7110_STGRST_NRESETS,
889 	.jhcr_assert = JH7110_STGRST_ASSERT,
890 	.jhcr_status = JH7110_STGRST_STATUS,
891 };
892 
893 #if 0
894 static struct jh7110_reset_config jh7110_isprst_config = {
895 	.jhcr_nresets = JH7110_ISPRST_NRESETS,
896 	.jhcr_assert = JH7110_ISPRST_ASSERT,
897 	.jhcr_status = JH7110_ISPRST_STATUS,
898 };
899 #endif
900 
901 static struct jh7110_reset_config jh7110_voutrst_config = {
902 	.jhcr_nresets = JH7110_VOUTRST_NRESETS,
903 	.jhcr_assert = JH7110_VOUTRST_ASSERT,
904 	.jhcr_status = JH7110_VOUTRST_STATUS,
905 };
906 
907 struct jh7110_crg {
908 	const char *jhc_name;
909 	struct jh7110_clock_config *jhc_clk;
910 	struct jh7110_reset_config *jhc_rst;
911 	bool jhc_debug;
912 };
913 
914 
915 static struct jh7110_crg jh7110_sys_config = {
916 	.jhc_name = "System",
917 	.jhc_clk = &jh7110_sysclk_config,
918 	.jhc_rst = &jh7110_sysrst_config,
919 	.jhc_debug = true,
920 };
921 
922 
923 static struct jh7110_crg jh7110_aon_config = {
924 	.jhc_name = "Always-On",
925 	.jhc_clk = &jh7110_aonclk_config,
926 	.jhc_rst = &jh7110_aonrst_config,
927 	.jhc_debug = true,
928 };
929 
930 static struct jh7110_crg jh7110_stg_config = {
931 	.jhc_name = "System-Top-Group",
932 	.jhc_clk = &jh7110_stgclk_config,
933 	.jhc_rst = &jh7110_stgrst_config,
934 	.jhc_debug = true,
935 };
936 
937 #if 0
938 static struct jh7110_crg jh7110_isp_config = {
939 	.jhc_name = "Image-Signal-Process",
940 	.jhc_clk = &jh7110_ispclk_config,
941 	.jhc_rst = &jh7110_isprst_config,
942 };
943 #endif
944 
945 static struct jh7110_crg jh7110_vout_config = {
946 	.jhc_name = "Video Output",
947 	.jhc_clk = &jh7110_voutclk_config,
948 	.jhc_rst = &jh7110_voutrst_config,
949 	.jhc_debug = true,
950 };
951 
952 
953 static const struct device_compatible_entry compat_data[] = {
954 	{ .compat = "starfive,jh7110-syscrg", .data = &jh7110_sys_config },
955 	{ .compat = "starfive,jh7110-aoncrg", .data = &jh7110_aon_config },
956 	{ .compat = "starfive,jh7110-stgcrg", .data = &jh7110_stg_config },
957 //	{ .compat = "starfive,jh7110-ispcrg", .data = &jh7110_isp_config },
958 	{ .compat = "starfive,jh7110-voutcrg", .data = &jh7110_vout_config },
959 	DEVICE_COMPAT_EOL
960 };
961 
962 #define CLK_LOCK(sc)							\
963 	mutex_enter(&sc->sc_lock);
964 #define CLK_UNLOCK(sc)							\
965 	mutex_exit(&sc->sc_lock);
966 
967 #define RD4(sc, reg)							\
968 	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
969 #define WR4(sc, reg, val)						\
970 	bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
971 
972 #define JH7110_RESET_RETRIES 1000
973 
974 static void *
975 jh7110_clkc_reset_acquire(device_t dev, const void *data, size_t len)
976 {
977 	struct jh71x0_clkc_softc * const sc = device_private(dev);
978 
979 	if (len != sizeof(uint32_t))
980 		return NULL;
981 
982 	const uint32_t reset_id = be32dec(data);
983 	if (reset_id >= sc->sc_nrsts)
984 		return NULL;
985 
986 	uint32_t *reset = kmem_alloc(sizeof(uint32_t), KM_SLEEP);
987 	*reset = reset_id;
988 
989 	return reset;
990 }
991 
992 static void
993 jh7110_clkc_reset_release(device_t dev, void *priv)
994 {
995 
996 	kmem_free(priv, sizeof(uint32_t));
997 }
998 
999 static int
1000 jh7110_clkc_reset_set(struct jh71x0_clkc_softc *sc, unsigned reset_id,
1001     bool assert)
1002 {
1003 	const uint32_t off = (reset_id / 32) * sizeof(uint32_t);
1004 	const uint32_t bit = reset_id % 32;
1005 	const bus_size_t assert_reg = sc->sc_reset_assert + off;
1006 	const bus_size_t status_reg = sc->sc_reset_status + off;
1007 
1008 	CLK_LOCK(sc);
1009 
1010 	const uint32_t val = RD4(sc, assert_reg);
1011 	if (assert)
1012 		WR4(sc, assert_reg, val | __BIT(bit));
1013 	else
1014 		WR4(sc, assert_reg, val & ~__BIT(bit));
1015 
1016 	unsigned i;
1017 	uint32_t status;
1018 	for (i = 0; i < JH7110_RESET_RETRIES; i++) {
1019 		status = RD4(sc, status_reg);
1020 		bool asserted = (status & __BIT(bit)) == 0;
1021 		if (asserted == assert)
1022 			break;
1023 	}
1024 	CLK_UNLOCK(sc);
1025 
1026 	if (i >= JH7110_RESET_RETRIES) {
1027 		printf("%s: reset %3d status %#010x / %2d didn't %sassert\n",
1028 		    __func__, reset_id, status, bit, assert ? "" : "de");
1029 		return ETIMEDOUT;
1030 	}
1031 
1032 	return 0;
1033 }
1034 
1035 static int
1036 jh7110_clkc_reset_assert(device_t dev, void *priv)
1037 {
1038 	struct jh71x0_clkc_softc * const sc = device_private(dev);
1039 	const uint32_t *reset = priv;
1040 	const uint32_t reset_id = *reset;
1041 
1042 	return jh7110_clkc_reset_set(sc, reset_id, true);
1043 }
1044 
1045 static int
1046 jh7110_clkc_reset_deassert(device_t dev, void *priv)
1047 {
1048 	struct jh71x0_clkc_softc * const sc = device_private(dev);
1049 	const uint32_t *reset = priv;
1050 	const uint32_t reset_id = *reset;
1051 
1052 	return jh7110_clkc_reset_set(sc, reset_id, false);
1053 }
1054 
1055 
1056 static const struct fdtbus_reset_controller_func jh7110_clkc_fdtreset_funcs = {
1057 	.acquire = jh7110_clkc_reset_acquire,
1058 	.release = jh7110_clkc_reset_release,
1059 	.reset_assert = jh7110_clkc_reset_assert,
1060 	.reset_deassert = jh7110_clkc_reset_deassert,
1061 };
1062 
1063 
1064 static struct clk *
1065 jh7110_clkc_clock_decode(device_t dev, int phandle, const void *data,
1066     size_t len)
1067 {
1068 	struct jh71x0_clkc_softc * const sc = device_private(dev);
1069 
1070 	if (len != sizeof(uint32_t))
1071 		return NULL;
1072 
1073 	u_int id = be32dec(data);
1074 	if (id >= sc->sc_nclks) {
1075 		return NULL;
1076 	}
1077 	if (sc->sc_clk[id].jcc_type == JH71X0CLK_UNKNOWN) {
1078 		printf("Unknown clock %d\n", id);
1079 		return NULL;
1080 	}
1081 	return &sc->sc_clk[id].jcc_clk;
1082 }
1083 
1084 static const struct fdtbus_clock_controller_func jh7110_clkc_fdtclock_funcs = {
1085 	.decode = jh7110_clkc_clock_decode
1086 };
1087 
1088 static int
1089 jh7110_clkc_match(device_t parent, cfdata_t cf, void *aux)
1090 {
1091 	struct fdt_attach_args * const faa = aux;
1092 
1093 	return of_compatible_match(faa->faa_phandle, compat_data);
1094 }
1095 
1096 static void
1097 jh7110_clkc_attach(device_t parent, device_t self, void *aux)
1098 {
1099 	struct jh71x0_clkc_softc * const sc = device_private(self);
1100 	struct fdt_attach_args * const faa = aux;
1101 	const int phandle = faa->faa_phandle;
1102 	bus_addr_t addr;
1103 	bus_size_t size;
1104 
1105 	if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
1106 		aprint_error(": couldn't get registers\n");
1107 		return;
1108 	}
1109 
1110 	sc->sc_dev = self;
1111 	sc->sc_phandle = phandle;
1112 	sc->sc_bst = faa->faa_bst;
1113 	if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
1114 		aprint_error(": couldn't map registers\n");
1115 		return;
1116 	}
1117 
1118 	sc->sc_clkdom.name = device_xname(self);
1119 	sc->sc_clkdom.funcs = &jh71x0_clkc_funcs;
1120 	sc->sc_clkdom.priv = sc;
1121 
1122 	const struct jh7110_crg *jhc =
1123 	    of_compatible_lookup(phandle, compat_data)->data;
1124 	KASSERT(jhc != NULL);
1125 
1126 	struct jh7110_clock_config * const jhcc = jhc->jhc_clk;
1127 	struct jh7110_reset_config * const jhcr = jhc->jhc_rst;
1128 	sc->sc_clk = jhcc->jhcc_clocks;
1129 	sc->sc_nclks = jhcc->jhcc_nclks;
1130 
1131 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
1132 	sc->sc_nrsts = jhcr->jhcr_nresets;
1133 	sc->sc_reset_assert = jhcr->jhcr_assert;
1134 	sc->sc_reset_status = jhcr->jhcr_status;
1135 
1136 	for (size_t id = 0; id < sc->sc_nclks; id++) {
1137 		if (sc->sc_clk[id].jcc_type == JH71X0CLK_UNKNOWN)
1138 			continue;
1139 
1140 		sc->sc_clk[id].jcc_clk.domain = &sc->sc_clkdom;
1141 		// Names already populated.
1142 		clk_attach(&sc->sc_clk[id].jcc_clk);
1143 	}
1144 
1145 	aprint_naive("\n");
1146 	aprint_normal(": JH7110 %s Clock and Reset Generator\n",
1147 	    jhc->jhc_name);
1148 
1149 	if (jhc->jhc_debug) {
1150 		for (size_t id = 0; id < sc->sc_nclks; id++) {
1151 			if (sc->sc_clk[id].jcc_type == JH71X0CLK_UNKNOWN)
1152 				continue;
1153 
1154 			struct clk * const clk = &sc->sc_clk[id].jcc_clk;
1155 
1156 			aprint_debug_dev(self, "id %zu [%s]: %u Hz\n", id,
1157 			    clk->name ? clk->name : "<none>", clk_get_rate(clk));
1158 		}
1159 	}
1160 
1161 	fdtbus_register_clock_controller(self, phandle, &jh7110_clkc_fdtclock_funcs);
1162 	fdtbus_register_reset_controller(self, phandle, &jh7110_clkc_fdtreset_funcs);
1163 }
1164 
1165 CFATTACH_DECL_NEW(jh7110_clkc, sizeof(struct jh71x0_clkc_softc),
1166 	jh7110_clkc_match, jh7110_clkc_attach, NULL, NULL);
1167