jh7100_clkc.c revision 1.6 1 1.6 skrll /* $NetBSD: jh7100_clkc.c,v 1.6 2025/01/18 17:21:26 skrll Exp $ */
2 1.1 skrll
3 1.1 skrll /*-
4 1.1 skrll * Copyright (c) 2023 The NetBSD Foundation, Inc.
5 1.1 skrll * All rights reserved.
6 1.1 skrll *
7 1.1 skrll * This code is derived from software contributed to The NetBSD Foundation
8 1.1 skrll * by Nick Hudson
9 1.1 skrll *
10 1.1 skrll * Redistribution and use in source and binary forms, with or without
11 1.1 skrll * modification, are permitted provided that the following conditions
12 1.1 skrll * are met:
13 1.1 skrll * 1. Redistributions of source code must retain the above copyright
14 1.1 skrll * notice, this list of conditions and the following disclaimer.
15 1.1 skrll * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 skrll * notice, this list of conditions and the following disclaimer in the
17 1.1 skrll * documentation and/or other materials provided with the distribution.
18 1.1 skrll *
19 1.1 skrll * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 1.1 skrll * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 1.1 skrll * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 1.1 skrll * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 1.1 skrll * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 1.1 skrll * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 1.1 skrll * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 1.1 skrll * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 1.1 skrll * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 1.1 skrll * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 1.1 skrll * POSSIBILITY OF SUCH DAMAGE.
30 1.1 skrll */
31 1.1 skrll
32 1.1 skrll #include <sys/cdefs.h>
33 1.6 skrll __KERNEL_RCSID(0, "$NetBSD: jh7100_clkc.c,v 1.6 2025/01/18 17:21:26 skrll Exp $");
34 1.1 skrll
35 1.1 skrll #include <sys/param.h>
36 1.1 skrll
37 1.1 skrll #include <sys/bus.h>
38 1.1 skrll #include <sys/device.h>
39 1.1 skrll
40 1.1 skrll #include <dev/clk/clk_backend.h>
41 1.1 skrll
42 1.1 skrll #include <dev/fdt/fdtvar.h>
43 1.1 skrll
44 1.3 skrll #include <riscv/starfive/jh71x0_clkc.h>
45 1.1 skrll
46 1.1 skrll
47 1.4 skrll #define JH7100_CLK_CPUNDBUS_ROOT 0
48 1.4 skrll #define JH7100_CLK_DSP_ROOT 2
49 1.4 skrll #define JH7100_CLK_GMACUSB_ROOT 3
50 1.4 skrll #define JH7100_CLK_PERH0_ROOT 4
51 1.4 skrll #define JH7100_CLK_PERH1_ROOT 5
52 1.4 skrll #define JH7100_CLK_VOUT_ROOT 7
53 1.4 skrll #define JH7100_CLK_AUDIO_ROOT 8
54 1.4 skrll #define JH7100_CLK_VOUTBUS_ROOT 11
55 1.4 skrll #define JH7100_CLK_CPUNBUS_ROOT_DIV 12
56 1.4 skrll #define JH7100_CLK_DSP_ROOT_DIV 13
57 1.4 skrll #define JH7100_CLK_PERH0_SRC 14
58 1.4 skrll #define JH7100_CLK_PERH1_SRC 15
59 1.4 skrll #define JH7100_CLK_PLL2_REF 19
60 1.4 skrll #define JH7100_CLK_CPU_CORE 20
61 1.4 skrll #define JH7100_CLK_CPU_AXI 21
62 1.4 skrll #define JH7100_CLK_AHB_BUS 22
63 1.4 skrll #define JH7100_CLK_APB1_BUS 23
64 1.4 skrll #define JH7100_CLK_APB2_BUS 24
65 1.4 skrll #define JH7100_CLK_DOM7AHB_BUS 26
66 1.4 skrll #define JH7100_CLK_SGDMA2P_AXI 31
67 1.4 skrll #define JH7100_CLK_SGDMA2P_AHB 33
68 1.4 skrll #define JH7100_CLK_VP6_CORE 38
69 1.4 skrll #define JH7100_CLK_JPEG_APB 50
70 1.4 skrll #define JH7100_CLK_SGDMA1P_BUS 84
71 1.4 skrll #define JH7100_CLK_SGDMA1P_AXI 85
72 1.4 skrll #define JH7100_CLK_AUDIO_DIV 95
73 1.4 skrll #define JH7100_CLK_AUDIO_SRC 96
74 1.4 skrll #define JH7100_CLK_AUDIO_12288 97
75 1.4 skrll #define JH7100_CLK_VOUT_SRC 109
76 1.4 skrll #define JH7100_CLK_DISPBUS_SRC 110
77 1.4 skrll #define JH7100_CLK_DISP_BUS 111
78 1.4 skrll #define JH7100_CLK_DISP_AXI 112
79 1.4 skrll #define JH7100_CLK_SDIO0_AHB 114
80 1.4 skrll #define JH7100_CLK_SDIO0_CCLKINT 115
81 1.4 skrll #define JH7100_CLK_SDIO0_CCLKINT_INV 116
82 1.4 skrll #define JH7100_CLK_SDIO1_AHB 117
83 1.4 skrll #define JH7100_CLK_SDIO1_CCLKINT 118
84 1.4 skrll #define JH7100_CLK_SDIO1_CCLKINT_INV 119
85 1.4 skrll #define JH7100_CLK_GMAC_AHB 120
86 1.4 skrll #define JH7100_CLK_GMAC_ROOT_DIV 121
87 1.4 skrll #define JH7100_CLK_GMAC_PTP_REF 122
88 1.4 skrll #define JH7100_CLK_GMAC_GTX 123
89 1.4 skrll #define JH7100_CLK_GMAC_RMII_TX 124
90 1.4 skrll #define JH7100_CLK_GMAC_RMII_RX 125
91 1.4 skrll #define JH7100_CLK_GMAC_TX 126
92 1.4 skrll #define JH7100_CLK_GMAC_TX_INV 127
93 1.4 skrll #define JH7100_CLK_GMAC_RX_PRE 128
94 1.4 skrll #define JH7100_CLK_GMAC_RX_INV 129
95 1.4 skrll #define JH7100_CLK_GMAC_RMII 130
96 1.4 skrll #define JH7100_CLK_GMAC_TOPHYREF 131
97 1.4 skrll #define JH7100_CLK_QSPI_AHB 137
98 1.4 skrll #define JH7100_CLK_SEC_AHB 140
99 1.4 skrll #define JH7100_CLK_TRNG_APB 144
100 1.4 skrll #define JH7100_CLK_OTP_APB 145
101 1.4 skrll #define JH7100_CLK_UART0_APB 146
102 1.4 skrll #define JH7100_CLK_UART0_CORE 147
103 1.4 skrll #define JH7100_CLK_UART1_APB 148
104 1.4 skrll #define JH7100_CLK_UART1_CORE 149
105 1.4 skrll #define JH7100_CLK_SPI0_APB 150
106 1.4 skrll #define JH7100_CLK_SPI0_CORE 151
107 1.4 skrll #define JH7100_CLK_SPI1_APB 152
108 1.4 skrll #define JH7100_CLK_SPI1_CORE 153
109 1.4 skrll #define JH7100_CLK_I2C0_APB 154
110 1.4 skrll #define JH7100_CLK_I2C0_CORE 155
111 1.4 skrll #define JH7100_CLK_I2C1_APB 156
112 1.4 skrll #define JH7100_CLK_I2C1_CORE 157
113 1.4 skrll #define JH7100_CLK_GPIO_APB 158
114 1.4 skrll #define JH7100_CLK_UART2_APB 159
115 1.4 skrll #define JH7100_CLK_UART2_CORE 160
116 1.4 skrll #define JH7100_CLK_UART3_APB 161
117 1.4 skrll #define JH7100_CLK_UART3_CORE 162
118 1.4 skrll #define JH7100_CLK_SPI2_APB 163
119 1.4 skrll #define JH7100_CLK_SPI2_CORE 164
120 1.4 skrll #define JH7100_CLK_SPI3_APB 165
121 1.4 skrll #define JH7100_CLK_SPI3_CORE 166
122 1.4 skrll #define JH7100_CLK_I2C2_APB 167
123 1.4 skrll #define JH7100_CLK_I2C2_CORE 168
124 1.4 skrll #define JH7100_CLK_I2C3_APB 169
125 1.4 skrll #define JH7100_CLK_I2C3_CORE 170
126 1.4 skrll #define JH7100_CLK_WDTIMER_APB 171
127 1.4 skrll #define JH7100_CLK_WDT_CORE 172
128 1.4 skrll #define JH7100_CLK_PWM_APB 181
129 1.6 skrll #define JH7100_CLK_TEMP_APB 183
130 1.6 skrll #define JH7100_CLK_TEMP_SENSE 184
131 1.4 skrll
132 1.4 skrll #define JH7100_CLK_PLL0_OUT 186
133 1.4 skrll #define JH7100_CLK_PLL1_OUT 187
134 1.4 skrll #define JH7100_CLK_PLL2_OUT 188
135 1.1 skrll
136 1.4 skrll #define JH7100_NCLKS 189
137 1.1 skrll
138 1.5 skrll #define JH7100_AUDCLK_ADC_MCLK 0
139 1.5 skrll #define JH7100_AUDCLK_I2S1_MCLK 1
140 1.5 skrll #define JH7100_AUDCLK_I2SADC_APB 2
141 1.5 skrll #define JH7100_AUDCLK_I2SADC_BCLK 3
142 1.5 skrll #define JH7100_AUDCLK_I2SADC_BCLK_N 4
143 1.5 skrll #define JH7100_AUDCLK_I2SADC_LRCLK 5
144 1.5 skrll #define JH7100_AUDCLK_PDM_APB 6
145 1.5 skrll #define JH7100_AUDCLK_PDM_MCLK 7
146 1.5 skrll #define JH7100_AUDCLK_I2SVAD_APB 8
147 1.5 skrll #define JH7100_AUDCLK_SPDIF 9
148 1.5 skrll #define JH7100_AUDCLK_SPDIF_APB 10
149 1.5 skrll #define JH7100_AUDCLK_PWMDAC_APB 11
150 1.5 skrll #define JH7100_AUDCLK_DAC_MCLK 12
151 1.5 skrll #define JH7100_AUDCLK_I2SDAC_APB 13
152 1.5 skrll #define JH7100_AUDCLK_I2SDAC_BCLK 14
153 1.5 skrll #define JH7100_AUDCLK_I2SDAC_BCLK_N 15
154 1.5 skrll #define JH7100_AUDCLK_I2SDAC_LRCLK 16
155 1.5 skrll #define JH7100_AUDCLK_I2S1_APB 17
156 1.5 skrll #define JH7100_AUDCLK_I2S1_BCLK 18
157 1.5 skrll #define JH7100_AUDCLK_I2S1_BCLK_N 19
158 1.5 skrll #define JH7100_AUDCLK_I2S1_LRCLK 20
159 1.5 skrll #define JH7100_AUDCLK_I2SDAC16K_APB 21
160 1.5 skrll #define JH7100_AUDCLK_APB0_BUS 22
161 1.5 skrll #define JH7100_AUDCLK_DMA1P_AHB 23
162 1.5 skrll #define JH7100_AUDCLK_USB_APB 24
163 1.5 skrll #define JH7100_AUDCLK_USB_LPM 25
164 1.5 skrll #define JH7100_AUDCLK_USB_STB 26
165 1.5 skrll #define JH7100_AUDCLK_APB_EN 27
166 1.5 skrll #define JH7100_AUDCLK_VAD_MEM 28
167 1.5 skrll
168 1.5 skrll #define JH7100_AUDCLK_NCLKS 29
169 1.5 skrll
170 1.1 skrll
171 1.1 skrll static const char *cpundbus_root_parents[] = {
172 1.1 skrll "osc_sys", "pll0_out", "pll1_out", "pll2_out",
173 1.1 skrll };
174 1.1 skrll
175 1.1 skrll static const char *dsp_root_parents[] = {
176 1.1 skrll "osc_sys", "pll0_out", "pll1_out", "pll2_out",
177 1.1 skrll };
178 1.1 skrll
179 1.1 skrll static const char *gmacusb_root_parents[] = {
180 1.1 skrll "osc_sys", "pll0_out", "pll2_out",
181 1.1 skrll };
182 1.1 skrll
183 1.1 skrll static const char *perh0_root_parents[] = {
184 1.1 skrll "osc_sys", "pll0_out",
185 1.1 skrll };
186 1.1 skrll
187 1.1 skrll static const char *perh1_root_parents[] = {
188 1.1 skrll "osc_sys", "pll2_out",
189 1.1 skrll };
190 1.1 skrll
191 1.1 skrll static const char *pll2_refclk_parents[] = {
192 1.1 skrll "osc_sys", "osc_aud",
193 1.1 skrll };
194 1.1 skrll
195 1.1 skrll static const char *vout_root_parents[] = {
196 1.1 skrll "osc_aud", "pll0_out", "pll2_out",
197 1.1 skrll };
198 1.1 skrll
199 1.1 skrll static const char *gmac_rx_pre_parents[] = {
200 1.1 skrll "gmac_gr_mii_rxclk", "gmac_rmii_rxclk",
201 1.1 skrll };
202 1.1 skrll
203 1.1 skrll static const char *gmac_tx_parents[] = {
204 1.1 skrll "gmac_gtxclk", "gmac_tx_inv", "gmac_rmii_txclk",
205 1.1 skrll };
206 1.1 skrll
207 1.1 skrll
208 1.3 skrll static struct jh71x0_clkc_clk jh7100_clocks[] = {
209 1.3 skrll JH71X0CLKC_FIXED_FACTOR(JH7100_CLK_PLL0_OUT, "pll0_out", "osc_sys", 1, 40),
210 1.3 skrll JH71X0CLKC_FIXED_FACTOR(JH7100_CLK_PLL1_OUT, "pll1_out", "osc_sys", 1, 64),
211 1.3 skrll JH71X0CLKC_FIXED_FACTOR(JH7100_CLK_PLL2_OUT, "pll2_out", "pll2_refclk", 1, 55),
212 1.3 skrll
213 1.3 skrll JH71X0CLKC_MUX(JH7100_CLK_CPUNDBUS_ROOT, "cpundbus_root", cpundbus_root_parents),
214 1.3 skrll JH71X0CLKC_MUX(JH7100_CLK_DSP_ROOT, "dsp_root", dsp_root_parents),
215 1.3 skrll JH71X0CLKC_MUX(JH7100_CLK_GMACUSB_ROOT, "gmacusb_root", gmacusb_root_parents),
216 1.3 skrll JH71X0CLKC_MUX(JH7100_CLK_PERH0_ROOT, "perh0_root", perh0_root_parents),
217 1.3 skrll JH71X0CLKC_MUX(JH7100_CLK_PERH1_ROOT, "perh1_root", perh1_root_parents),
218 1.3 skrll JH71X0CLKC_MUX(JH7100_CLK_PLL2_REF, "pll2_refclk", pll2_refclk_parents),
219 1.1 skrll
220 1.3 skrll JH71X0CLKC_MUX(JH7100_CLK_VOUT_ROOT, "vout_root", vout_root_parents),
221 1.3 skrll JH71X0CLKC_MUX(JH7100_CLK_VOUTBUS_ROOT, "voutbus_root", vout_root_parents),
222 1.1 skrll
223 1.3 skrll JH71X0CLKC_MUX_FLAGS(JH7100_CLK_GMAC_TX, "gmac_tx", gmac_tx_parents, CLK_SET_RATE_PARENT),
224 1.1 skrll
225 1.3 skrll JH71X0CLKC_MUX(JH7100_CLK_GMAC_RX_PRE, "gmac_rx_pre", gmac_rx_pre_parents),
226 1.1 skrll
227 1.3 skrll JH71X0CLKC_DIV(JH7100_CLK_CPUNBUS_ROOT_DIV, "cpunbus_root_div",
228 1.1 skrll 2, "cpundbus_root"),
229 1.3 skrll JH71X0CLKC_DIV(JH7100_CLK_PERH0_SRC, "perh0_src", 4, "perh0_root"),
230 1.3 skrll JH71X0CLKC_DIV(JH7100_CLK_PERH1_SRC, "perh1_src", 4, "perh1_root"),
231 1.1 skrll
232 1.3 skrll JH71X0CLKC_DIV(JH7100_CLK_AHB_BUS, "ahb_bus", 8, "cpunbus_root_div"),
233 1.3 skrll JH71X0CLKC_DIV(JH7100_CLK_APB1_BUS, "apb1_bus", 8, "ahb_bus"),
234 1.3 skrll JH71X0CLKC_DIV(JH7100_CLK_APB2_BUS, "apb2_bus", 8, "ahb_bus"),
235 1.3 skrll JH71X0CLKC_DIV(JH7100_CLK_CPU_CORE, "cpu_core", 8, "cpunbus_root_div"),
236 1.3 skrll JH71X0CLKC_DIV(JH7100_CLK_CPU_AXI, "cpu_axi", 8, "cpu_core"),
237 1.3 skrll JH71X0CLKC_DIV(JH7100_CLK_GMAC_ROOT_DIV, "gmac_root_div", 8, "gmacusb_root"),
238 1.3 skrll JH71X0CLKC_DIV(JH7100_CLK_DSP_ROOT_DIV, "dsp_root_div", 4, "dsp_root"),
239 1.3 skrll JH71X0CLKC_DIV(JH7100_CLK_SGDMA1P_BUS, "sgdma1p_bus", 8, "cpunbus_root_div"),
240 1.3 skrll
241 1.3 skrll JH71X0CLKC_DIV(JH7100_CLK_DISPBUS_SRC, "dispbus_src", 4, "voutbus_root"),
242 1.3 skrll
243 1.3 skrll JH71X0CLKC_DIV(JH7100_CLK_DISP_BUS, "disp_bus", 4, "dispbus_src"),
244 1.3 skrll
245 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_UART0_APB, "uart0_apb", "apb1_bus"),
246 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_UART1_APB, "uart1_apb", "apb1_bus"),
247 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_UART2_APB, "uart2_apb", "apb2_bus"),
248 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_UART3_APB, "uart3_apb", "apb2_bus"),
249 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_SGDMA2P_AXI, "sgdma2p_axi", "cpu_axi"),
250 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_SGDMA2P_AHB, "sgdma2p_ahb", "ahb_bus"),
251 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_SGDMA1P_AXI, "sgdma1p_axi", "sgdma1p_bus"),
252 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_GPIO_APB, "gpio_apb", "apb1_bus"),
253 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_I2C0_APB, "i2c0_apb", "apb1_bus"),
254 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_I2C1_APB, "i2c1_apb", "apb1_bus"),
255 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_I2C2_APB, "i2c2_apb", "apb2_bus"),
256 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_I2C3_APB, "i2c3_apb", "apb2_bus"),
257 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_TRNG_APB, "trng_apb", "apb1_bus"),
258 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_SEC_AHB, "sec_ahb", "ahb_bus"),
259 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_GMAC_AHB, "gmac_ahb", "ahb_bus"),
260 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_GMAC_AHB, "gmac_ahb", "ahb_bus"),
261 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_JPEG_APB, "jpeg_apb", "apb1_bus"),
262 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_PWM_APB, "pwm_apb", "apb2_bus"),
263 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_QSPI_AHB, "qspi_ahb", "ahb_bus"),
264 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_SPI0_APB, "spi0_apb", "apb1_bus"),
265 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_SPI1_APB, "spi1_apb", "apb1_bus"),
266 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_SPI2_APB, "spi2_apb", "apb2_bus"),
267 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_SPI3_APB, "spi3_apb", "apb2_bus"),
268 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_SDIO0_AHB, "sdio0_ahb", "ahb_bus"),
269 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_SDIO1_AHB, "sdio1_ahb", "ahb_bus"),
270 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_OTP_APB, "otp_apb", "apb1_bus"),
271 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_DOM7AHB_BUS, "dom7ahb_bus", "ahb_bus"),
272 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_AUDIO_SRC, "audio_src", "audio_div"),
273 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_AUDIO_12288, "audio_12288", "osc_aud"),
274 1.3 skrll
275 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_DISP_AXI, "disp_axi", "disp_bus"),
276 1.3 skrll
277 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_GMAC_RMII, "gmac_rmii", "gmac_rmii_ref"),
278 1.3 skrll
279 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_WDTIMER_APB, "wdtimer_apb", "apb2_bus"),
280 1.3 skrll
281 1.6 skrll JH71X0CLKC_GATE(JH7100_CLK_TEMP_APB, "temp_apb", "apb2_bus"),
282 1.6 skrll
283 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_UART0_CORE, "uart0_core", 63, "perh1_src"),
284 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_UART1_CORE, "uart1_core", 63, "perh1_src"),
285 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_UART2_CORE, "uart2_core", 63, "perh0_src"),
286 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_UART3_CORE, "uart3_core", 63, "perh0_src"),
287 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_I2C0_CORE, "i2c0_core", 63, "perh1_src"),
288 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_I2C1_CORE, "i2c1_core", 63, "perh1_src"),
289 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_I2C2_CORE, "i2c2_core", 63, "perh0_src"),
290 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_I2C3_CORE, "i2c3_core", 63, "perh0_src"),
291 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_GMAC_PTP_REF, "gmac_ptp_refclk", 31, "gmac_root_div"),
292 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_VP6_CORE, "vp6_core", 4, "dsp_root_div"),
293 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_VP6_CORE, "vp6_core", 4, "dsp_root_div"),
294 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_SPI0_CORE, "spi0_core", 63, "perh1_src"),
295 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_SPI1_CORE, "spi1_core", 63, "perh1_src"),
296 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_SPI2_CORE, "spi2_core", 63, "perh0_src"),
297 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_SPI3_CORE, "spi3_core", 63, "perh0_src"),
298 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_VP6_CORE, "vp6_core", 4, "dsp_root_div"),
299 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_SDIO0_CCLKINT, "sdio0_cclkint", 24, "perh0_src"),
300 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_SDIO1_CCLKINT, "sdio1_cclkint", 24, "perh1_src"),
301 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_AUDIO_ROOT, "audio_root", 8, "pll0_out"),
302 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_VOUT_SRC, "vout_src", 4, "vout_root"),
303 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_WDT_CORE, "wdt_coreclk", 63, "perh0_src"),
304 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", 255, "gmac_root_div"),
305 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", 8, "gmac_rmii_ref"),
306 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", 8, "gmac_rmii_ref"),
307 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_GMAC_TOPHYREF, "gmac_tophyref", 127, "gmac_root_div"),
308 1.6 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_TEMP_SENSE, "temp_sense", 31, "osc_sys"),
309 1.3 skrll
310 1.3 skrll JH71X0CLKC_FRACDIV(JH7100_CLK_AUDIO_DIV, "audio_div", "audio_root"),
311 1.3 skrll
312 1.3 skrll JH71X0CLKC_INV(JH7100_CLK_SDIO0_CCLKINT_INV, "sdio0_cclkint_inv", "sdio0_cclkint"),
313 1.3 skrll JH71X0CLKC_INV(JH7100_CLK_SDIO1_CCLKINT_INV, "sdio1_cclkint_inv", "sdio1_cclkint"),
314 1.3 skrll JH71X0CLKC_INV(JH7100_CLK_GMAC_RX_INV, "gmac_rx_inv", "gmac_rx_pre"),
315 1.3 skrll JH71X0CLKC_INV(JH7100_CLK_GMAC_TX_INV, "gmac_tx_inv", "gmac_tx"),
316 1.1 skrll };
317 1.1 skrll
318 1.3 skrll
319 1.5 skrll static const char *adc_mclk_parents[] = {
320 1.5 skrll "audio_src", "audio_12288",
321 1.5 skrll };
322 1.5 skrll
323 1.5 skrll static const char *i2s1_mclk_parents[] = {
324 1.5 skrll "audio_src", "audio_12288",
325 1.5 skrll };
326 1.5 skrll
327 1.5 skrll static const char *i2sadc_bclk_parents[] = {
328 1.5 skrll "adc_mclk", "i2sadc_bclk_iopad"
329 1.5 skrll };
330 1.5 skrll
331 1.5 skrll static const char *i2sadc_lrclk_parents[] = {
332 1.5 skrll "i2sadc_bclk_n", "i2sadc_lrclk_iopad", "i2sadc_bclk",
333 1.5 skrll };
334 1.5 skrll
335 1.5 skrll static const char *pdm_mclk_parents[] = {
336 1.5 skrll "audio_src", "audio_12288",
337 1.5 skrll };
338 1.5 skrll
339 1.5 skrll static const char *spdif_parents[] = {
340 1.5 skrll "audio_src", "audio_12288",
341 1.5 skrll };
342 1.5 skrll
343 1.5 skrll static const char *dac_mclk_parents[] = {
344 1.5 skrll "audio_src", "audio_12288",
345 1.5 skrll };
346 1.5 skrll
347 1.5 skrll static const char *i2sdac_bclk_parents[] = {
348 1.5 skrll "dac_mclk", "i2sadc_blk_iopad",
349 1.5 skrll };
350 1.5 skrll
351 1.5 skrll static const char *i2sdac_lrclk_parents[] = {
352 1.5 skrll "i2s1_mclk", "i2sadc_blk_iopad",
353 1.5 skrll };
354 1.5 skrll
355 1.5 skrll static const char *i2s1_bclk_parents[] = {
356 1.5 skrll "i2s1_mclk", "i2sadc_blk_iopad",
357 1.5 skrll };
358 1.5 skrll
359 1.5 skrll static const char *i2s1_lrclk_parents[] = {
360 1.5 skrll "i2s1_bclk_n", "i2sadc_lrclk_iopad",
361 1.5 skrll };
362 1.5 skrll
363 1.5 skrll static const char *vad_mem_parents[] = {
364 1.5 skrll "vad_intmem", "audio_12288",
365 1.5 skrll };
366 1.5 skrll
367 1.5 skrll
368 1.5 skrll static struct jh71x0_clkc_clk jh7100_audclk_clocks[] = {
369 1.5 skrll JH71X0CLKC_MUXDIVGATE(JH7100_AUDCLK_ADC_MCLK, "adc_mclk", 15, adc_mclk_parents),
370 1.5 skrll JH71X0CLKC_MUXDIVGATE(JH7100_AUDCLK_I2S1_MCLK, "i2s1_mclk", 15, i2s1_mclk_parents),
371 1.5 skrll
372 1.5 skrll JH71X0CLKC_GATE(JH7100_AUDCLK_I2SADC_APB, "i2sadc_apb", "apb0_bus"),
373 1.5 skrll
374 1.5 skrll JH71X0CLKC_MUXDIV(JH7100_AUDCLK_I2SADC_BCLK, "i2sadc_bclk", 31, i2sadc_bclk_parents),
375 1.5 skrll
376 1.5 skrll JH71X0CLKC_INV(JH7100_AUDCLK_I2SADC_BCLK_N, "i2sadc_bclk_n", "i2sadc_bclk"),
377 1.5 skrll JH71X0CLKC_MUXDIV(JH7100_AUDCLK_I2SADC_LRCLK, "i2sadc_lrclk", 63, i2sadc_lrclk_parents),
378 1.5 skrll JH71X0CLKC_GATE(JH7100_AUDCLK_PDM_APB, "pdm_apb", "apb0_bus"),
379 1.5 skrll JH71X0CLKC_MUXDIVGATE(JH7100_AUDCLK_PDM_MCLK, "pdm_mclk", 15, pdm_mclk_parents),
380 1.5 skrll JH71X0CLKC_GATE(JH7100_AUDCLK_I2SVAD_APB, "i2svad_apb", "apb0_bus"),
381 1.5 skrll JH71X0CLKC_MUXDIVGATE(JH7100_AUDCLK_SPDIF, "spdif", 15, spdif_parents),
382 1.5 skrll JH71X0CLKC_GATE(JH7100_AUDCLK_SPDIF_APB, "spdif_apb", "apb0_bus"),
383 1.5 skrll JH71X0CLKC_GATE(JH7100_AUDCLK_PWMDAC_APB, "pwmdac_apb", "apb0_bus"),
384 1.5 skrll JH71X0CLKC_MUXDIVGATE(JH7100_AUDCLK_DAC_MCLK, "dac_mclk", 15, dac_mclk_parents),
385 1.5 skrll JH71X0CLKC_GATE(JH7100_AUDCLK_I2SDAC_APB, "i2sdac_apb", "apb0_bus"),
386 1.5 skrll JH71X0CLKC_MUXDIV(JH7100_AUDCLK_I2SDAC_BCLK, "i2sdac_bclk", 31, i2sdac_bclk_parents),
387 1.5 skrll JH71X0CLKC_INV(JH7100_AUDCLK_I2SDAC_BCLK_N, "i2sdac_bclk_n", "i2sdac_bclk"),
388 1.5 skrll JH71X0CLKC_MUXDIV(JH7100_AUDCLK_I2SDAC_LRCLK, "i2sdac_lrclk", 31, i2sdac_lrclk_parents),
389 1.5 skrll JH71X0CLKC_GATE(JH7100_AUDCLK_I2S1_APB, "i2s1_apb", "apb0_bus"),
390 1.5 skrll JH71X0CLKC_MUXDIV(JH7100_AUDCLK_I2S1_BCLK, "i2s1_bclk", 31, i2s1_bclk_parents),
391 1.5 skrll JH71X0CLKC_INV(JH7100_AUDCLK_I2S1_BCLK_N, "i2s1_bclk_n", "i2s1_bclk"),
392 1.5 skrll JH71X0CLKC_MUXDIV(JH7100_AUDCLK_I2S1_LRCLK, "i2s1_lrclk", 63, i2s1_lrclk_parents),
393 1.5 skrll JH71X0CLKC_GATE(JH7100_AUDCLK_I2SDAC16K_APB, "i2s1dac16k_apb", "apb0_bus"),
394 1.5 skrll JH71X0CLKC_DIV(JH7100_AUDCLK_APB0_BUS, "apb0_bus", 8, "dom7ahb_bus"),
395 1.5 skrll JH71X0CLKC_GATE(JH7100_AUDCLK_DMA1P_AHB, "dma1p_ahb", "dom7ahb_bus"),
396 1.5 skrll JH71X0CLKC_GATE(JH7100_AUDCLK_USB_APB, "usb_apb", /*CLK_IGNORE_UNUSED,*/ "apb_en"),
397 1.5 skrll JH71X0CLKC_GATEDIV(JH7100_AUDCLK_USB_LPM, "usb_lpm", /*CLK_IGNORE_UNUSED,*/ 4, "usb_apb"),
398 1.5 skrll JH71X0CLKC_GATEDIV(JH7100_AUDCLK_USB_STB, "usb_stb", /*CLK_IGNORE_UNUSED,*/ 3, "usb_apb"),
399 1.5 skrll JH71X0CLKC_DIV(JH7100_AUDCLK_APB_EN, "apb_en", 8, "dom7ahb_bus"),
400 1.5 skrll JH71X0CLKC_MUX(JH7100_AUDCLK_VAD_MEM, "vad_mem", vad_mem_parents),
401 1.5 skrll };
402 1.5 skrll
403 1.5 skrll struct jh7100_clk_config {
404 1.5 skrll const char *jhcc_name;
405 1.5 skrll struct jh71x0_clkc_clk *jhcc_clocks;
406 1.5 skrll size_t jhcc_nclks;
407 1.5 skrll };
408 1.5 skrll
409 1.5 skrll static struct jh7100_clk_config jh7100_clk_config = {
410 1.5 skrll .jhcc_name = "System",
411 1.5 skrll .jhcc_clocks = jh7100_clocks,
412 1.5 skrll .jhcc_nclks = __arraycount(jh7100_clocks),
413 1.5 skrll };
414 1.5 skrll
415 1.5 skrll
416 1.5 skrll static struct jh7100_clk_config jh7110_audclk_config = {
417 1.5 skrll .jhcc_name = "Audio",
418 1.5 skrll .jhcc_clocks = jh7100_audclk_clocks,
419 1.5 skrll .jhcc_nclks = __arraycount(jh7100_audclk_clocks),
420 1.5 skrll };
421 1.5 skrll
422 1.1 skrll static const struct device_compatible_entry compat_data[] = {
423 1.5 skrll { .compat = "starfive,jh7100-clkgen", .data = &jh7100_clk_config },
424 1.5 skrll { .compat = "starfive,jh7100-audclk", .data = &jh7110_audclk_config },
425 1.1 skrll DEVICE_COMPAT_EOL
426 1.1 skrll };
427 1.1 skrll
428 1.1 skrll
429 1.1 skrll static struct clk *
430 1.1 skrll jh7100_clkc_fdt_decode(device_t dev, int phandle, const void *data,
431 1.1 skrll size_t len)
432 1.1 skrll {
433 1.3 skrll struct jh71x0_clkc_softc * const sc = device_private(dev);
434 1.1 skrll
435 1.1 skrll if (len != 4)
436 1.1 skrll return NULL;
437 1.1 skrll
438 1.1 skrll u_int id = be32dec(data);
439 1.1 skrll if (id >= sc->sc_nclks)
440 1.1 skrll return NULL;
441 1.1 skrll
442 1.3 skrll if (sc->sc_clk[id].jcc_type == JH71X0CLK_UNKNOWN) {
443 1.1 skrll printf("Unknown clock %d\n", id);
444 1.1 skrll return NULL;
445 1.1 skrll }
446 1.1 skrll return &sc->sc_clk[id].jcc_clk;
447 1.1 skrll }
448 1.1 skrll
449 1.1 skrll static const struct fdtbus_clock_controller_func jh7100_clkc_fdt_funcs = {
450 1.1 skrll .decode = jh7100_clkc_fdt_decode
451 1.1 skrll };
452 1.1 skrll
453 1.1 skrll static int
454 1.1 skrll jh7100_clkc_match(device_t parent, cfdata_t cf, void *aux)
455 1.1 skrll {
456 1.1 skrll struct fdt_attach_args * const faa = aux;
457 1.1 skrll
458 1.1 skrll return of_compatible_match(faa->faa_phandle, compat_data);
459 1.1 skrll }
460 1.1 skrll
461 1.1 skrll static void
462 1.1 skrll jh7100_clkc_attach(device_t parent, device_t self, void *aux)
463 1.1 skrll {
464 1.3 skrll struct jh71x0_clkc_softc * const sc = device_private(self);
465 1.1 skrll struct fdt_attach_args * const faa = aux;
466 1.1 skrll const int phandle = faa->faa_phandle;
467 1.5 skrll char infomsg[128] = "";
468 1.1 skrll bus_addr_t addr;
469 1.1 skrll bus_size_t size;
470 1.1 skrll int error;
471 1.1 skrll
472 1.1 skrll error = fdtbus_get_reg(phandle, 0, &addr, &size);
473 1.1 skrll if (error) {
474 1.1 skrll aprint_error(": couldn't get registers\n");
475 1.1 skrll return;
476 1.1 skrll }
477 1.1 skrll
478 1.1 skrll sc->sc_dev = self;
479 1.1 skrll sc->sc_phandle = phandle;
480 1.1 skrll sc->sc_bst = faa->faa_bst;
481 1.1 skrll error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
482 1.1 skrll if (error) {
483 1.1 skrll aprint_error(": couldn't map registers\n");
484 1.1 skrll return;
485 1.1 skrll }
486 1.1 skrll
487 1.5 skrll const struct jh7100_clk_config *jhcc =
488 1.5 skrll of_compatible_lookup(phandle, compat_data)->data;
489 1.5 skrll KASSERT(jhcc != NULL);
490 1.5 skrll
491 1.5 skrll if (jhcc == &jh7100_clk_config) {
492 1.5 skrll struct clk * const osclk = fdtbus_clock_get(phandle, "osc_sys");
493 1.5 skrll if (osclk == NULL) {
494 1.5 skrll aprint_error(": couldn't get osc_sys\n");
495 1.5 skrll return;
496 1.5 skrll }
497 1.5 skrll u_int osclk_rate = clk_get_rate(osclk);
498 1.5 skrll
499 1.5 skrll struct clk * const oaclk = fdtbus_clock_get(phandle, "osc_aud");
500 1.5 skrll if (oaclk == NULL) {
501 1.5 skrll aprint_error(": couldn't get osc_aud\n");
502 1.5 skrll return;
503 1.5 skrll }
504 1.5 skrll u_int oaclk_rate = clk_get_rate(oaclk);
505 1.1 skrll
506 1.5 skrll snprintf(infomsg, sizeof(infomsg), "(OSC0 %u Hz, OSC1 %u Hz)",
507 1.5 skrll osclk_rate, oaclk_rate);
508 1.1 skrll }
509 1.1 skrll
510 1.1 skrll sc->sc_clkdom.name = device_xname(self);
511 1.3 skrll sc->sc_clkdom.funcs = &jh71x0_clkc_funcs;
512 1.1 skrll sc->sc_clkdom.priv = sc;
513 1.1 skrll
514 1.5 skrll sc->sc_clk = jhcc->jhcc_clocks;
515 1.5 skrll sc->sc_nclks = jhcc->jhcc_nclks;
516 1.1 skrll for (size_t id = 0; id < sc->sc_nclks; id++) {
517 1.3 skrll if (sc->sc_clk[id].jcc_type == JH71X0CLK_UNKNOWN)
518 1.1 skrll continue;
519 1.1 skrll
520 1.1 skrll sc->sc_clk[id].jcc_clk.domain = &sc->sc_clkdom;
521 1.1 skrll clk_attach(&sc->sc_clk[id].jcc_clk);
522 1.1 skrll }
523 1.1 skrll
524 1.1 skrll aprint_naive("\n");
525 1.5 skrll aprint_normal(": JH7100 %s clocks %s\n", jhcc->jhcc_name, infomsg);
526 1.1 skrll
527 1.1 skrll for (size_t id = 0; id < sc->sc_nclks; id++) {
528 1.3 skrll if (sc->sc_clk[id].jcc_type == JH71X0CLK_UNKNOWN)
529 1.1 skrll continue;
530 1.1 skrll
531 1.1 skrll struct clk * const clk = &sc->sc_clk[id].jcc_clk;
532 1.1 skrll
533 1.1 skrll aprint_debug_dev(self, "id %zu [%s]: %u Hz\n", id,
534 1.1 skrll clk->name ? clk->name : "<none>", clk_get_rate(clk));
535 1.1 skrll }
536 1.1 skrll
537 1.1 skrll fdtbus_register_clock_controller(self, phandle, &jh7100_clkc_fdt_funcs);
538 1.1 skrll }
539 1.1 skrll
540 1.3 skrll CFATTACH_DECL_NEW(jh7100_clkc, sizeof(struct jh71x0_clkc_softc),
541 1.3 skrll jh7100_clkc_match, jh7100_clkc_attach, NULL, NULL);
542