jh7100_clkc.c revision 1.3 1 1.3 skrll /* $NetBSD: jh7100_clkc.c,v 1.3 2024/07/27 07:09:50 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.3 skrll __KERNEL_RCSID(0, "$NetBSD: jh7100_clkc.c,v 1.3 2024/07/27 07:09:50 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.1 skrll #define JH7100_CLK_CPUNDBUS_ROOT 0
48 1.1 skrll #define JH7100_CLK_DSP_ROOT 2
49 1.1 skrll #define JH7100_CLK_GMACUSB_ROOT 3
50 1.1 skrll #define JH7100_CLK_PERH0_ROOT 4
51 1.1 skrll #define JH7100_CLK_PERH1_ROOT 5
52 1.1 skrll #define JH7100_CLK_VOUT_ROOT 7
53 1.1 skrll #define JH7100_CLK_AUDIO_ROOT 8
54 1.1 skrll #define JH7100_CLK_VOUTBUS_ROOT 11
55 1.1 skrll #define JH7100_CLK_CPUNBUS_ROOT_DIV 12
56 1.1 skrll #define JH7100_CLK_DSP_ROOT_DIV 13
57 1.1 skrll #define JH7100_CLK_PERH0_SRC 14
58 1.1 skrll #define JH7100_CLK_PERH1_SRC 15
59 1.1 skrll #define JH7100_CLK_PLL2_REF 19
60 1.1 skrll #define JH7100_CLK_CPU_CORE 20
61 1.1 skrll #define JH7100_CLK_CPU_AXI 21
62 1.1 skrll #define JH7100_CLK_AHB_BUS 22
63 1.1 skrll #define JH7100_CLK_APB1_BUS 23
64 1.1 skrll #define JH7100_CLK_APB2_BUS 24
65 1.1 skrll #define JH7100_CLK_DOM7AHB_BUS 26
66 1.1 skrll #define JH7100_CLK_SGDMA2P_AXI 31
67 1.1 skrll #define JH7100_CLK_SGDMA2P_AHB 33
68 1.1 skrll #define JH7100_CLK_VP6_CORE 38
69 1.1 skrll #define JH7100_CLK_JPEG_APB 50
70 1.1 skrll #define JH7100_CLK_SGDMA1P_BUS 84
71 1.1 skrll #define JH7100_CLK_SGDMA1P_AXI 85
72 1.1 skrll #define JH7100_CLK_AUDIO_DIV 95
73 1.1 skrll #define JH7100_CLK_AUDIO_SRC 96
74 1.1 skrll #define JH7100_CLK_AUDIO_12288 97
75 1.1 skrll #define JH7100_CLK_VOUT_SRC 109
76 1.1 skrll #define JH7100_CLK_DISPBUS_SRC 110
77 1.1 skrll #define JH7100_CLK_DISP_BUS 111
78 1.1 skrll #define JH7100_CLK_DISP_AXI 112
79 1.1 skrll #define JH7100_CLK_SDIO0_AHB 114
80 1.1 skrll #define JH7100_CLK_SDIO0_CCLKINT 115
81 1.1 skrll #define JH7100_CLK_SDIO0_CCLKINT_INV 116
82 1.1 skrll #define JH7100_CLK_SDIO1_AHB 117
83 1.1 skrll #define JH7100_CLK_SDIO1_CCLKINT 118
84 1.1 skrll #define JH7100_CLK_SDIO1_CCLKINT_INV 119
85 1.1 skrll #define JH7100_CLK_GMAC_AHB 120
86 1.1 skrll #define JH7100_CLK_GMAC_ROOT_DIV 121
87 1.1 skrll #define JH7100_CLK_GMAC_PTP_REF 122
88 1.1 skrll #define JH7100_CLK_GMAC_GTX 123
89 1.1 skrll #define JH7100_CLK_GMAC_RMII_TX 124
90 1.1 skrll #define JH7100_CLK_GMAC_RMII_RX 125
91 1.1 skrll #define JH7100_CLK_GMAC_TX 126
92 1.1 skrll #define JH7100_CLK_GMAC_TX_INV 127
93 1.1 skrll #define JH7100_CLK_GMAC_RX_PRE 128
94 1.1 skrll #define JH7100_CLK_GMAC_RX_INV 129
95 1.1 skrll #define JH7100_CLK_GMAC_RMII 130
96 1.1 skrll #define JH7100_CLK_GMAC_TOPHYREF 131
97 1.1 skrll #define JH7100_CLK_QSPI_AHB 137
98 1.1 skrll #define JH7100_CLK_SEC_AHB 140
99 1.1 skrll #define JH7100_CLK_TRNG_APB 144
100 1.1 skrll #define JH7100_CLK_OTP_APB 145
101 1.1 skrll #define JH7100_CLK_UART0_APB 146
102 1.1 skrll #define JH7100_CLK_UART0_CORE 147
103 1.1 skrll #define JH7100_CLK_UART1_APB 148
104 1.1 skrll #define JH7100_CLK_UART1_CORE 149
105 1.1 skrll #define JH7100_CLK_SPI0_APB 150
106 1.1 skrll #define JH7100_CLK_SPI0_CORE 151
107 1.1 skrll #define JH7100_CLK_SPI1_APB 152
108 1.1 skrll #define JH7100_CLK_SPI1_CORE 153
109 1.1 skrll #define JH7100_CLK_I2C0_APB 154
110 1.1 skrll #define JH7100_CLK_I2C0_CORE 155
111 1.1 skrll #define JH7100_CLK_I2C1_APB 156
112 1.1 skrll #define JH7100_CLK_I2C1_CORE 157
113 1.1 skrll #define JH7100_CLK_GPIO_APB 158
114 1.1 skrll #define JH7100_CLK_UART2_APB 159
115 1.1 skrll #define JH7100_CLK_UART2_CORE 160
116 1.1 skrll #define JH7100_CLK_UART3_APB 161
117 1.1 skrll #define JH7100_CLK_UART3_CORE 162
118 1.1 skrll #define JH7100_CLK_SPI2_APB 163
119 1.1 skrll #define JH7100_CLK_SPI2_CORE 164
120 1.1 skrll #define JH7100_CLK_SPI3_APB 165
121 1.1 skrll #define JH7100_CLK_SPI3_CORE 166
122 1.1 skrll #define JH7100_CLK_I2C2_APB 167
123 1.1 skrll #define JH7100_CLK_I2C2_CORE 168
124 1.1 skrll #define JH7100_CLK_I2C3_APB 169
125 1.1 skrll #define JH7100_CLK_I2C3_CORE 170
126 1.1 skrll #define JH7100_CLK_WDTIMER_APB 171
127 1.1 skrll #define JH7100_CLK_WDT_CORE 172
128 1.1 skrll #define JH7100_CLK_PWM_APB 181
129 1.1 skrll
130 1.1 skrll #define JH7100_CLK_PLL0_OUT 186
131 1.1 skrll #define JH7100_CLK_PLL1_OUT 187
132 1.1 skrll #define JH7100_CLK_PLL2_OUT 188
133 1.1 skrll
134 1.1 skrll #define JH7100_NCLKS 189
135 1.1 skrll
136 1.1 skrll
137 1.1 skrll static const char *cpundbus_root_parents[] = {
138 1.1 skrll "osc_sys", "pll0_out", "pll1_out", "pll2_out",
139 1.1 skrll };
140 1.1 skrll
141 1.1 skrll static const char *dsp_root_parents[] = {
142 1.1 skrll "osc_sys", "pll0_out", "pll1_out", "pll2_out",
143 1.1 skrll };
144 1.1 skrll
145 1.1 skrll static const char *gmacusb_root_parents[] = {
146 1.1 skrll "osc_sys", "pll0_out", "pll2_out",
147 1.1 skrll };
148 1.1 skrll
149 1.1 skrll static const char *perh0_root_parents[] = {
150 1.1 skrll "osc_sys", "pll0_out",
151 1.1 skrll };
152 1.1 skrll
153 1.1 skrll static const char *perh1_root_parents[] = {
154 1.1 skrll "osc_sys", "pll2_out",
155 1.1 skrll };
156 1.1 skrll
157 1.1 skrll static const char *pll2_refclk_parents[] = {
158 1.1 skrll "osc_sys", "osc_aud",
159 1.1 skrll };
160 1.1 skrll
161 1.1 skrll static const char *vout_root_parents[] = {
162 1.1 skrll "osc_aud", "pll0_out", "pll2_out",
163 1.1 skrll };
164 1.1 skrll
165 1.1 skrll static const char *gmac_rx_pre_parents[] = {
166 1.1 skrll "gmac_gr_mii_rxclk", "gmac_rmii_rxclk",
167 1.1 skrll };
168 1.1 skrll
169 1.1 skrll static const char *gmac_tx_parents[] = {
170 1.1 skrll "gmac_gtxclk", "gmac_tx_inv", "gmac_rmii_txclk",
171 1.1 skrll };
172 1.1 skrll
173 1.1 skrll
174 1.3 skrll static struct jh71x0_clkc_clk jh7100_clocks[] = {
175 1.3 skrll JH71X0CLKC_FIXED_FACTOR(JH7100_CLK_PLL0_OUT, "pll0_out", "osc_sys", 1, 40),
176 1.3 skrll JH71X0CLKC_FIXED_FACTOR(JH7100_CLK_PLL1_OUT, "pll1_out", "osc_sys", 1, 64),
177 1.3 skrll JH71X0CLKC_FIXED_FACTOR(JH7100_CLK_PLL2_OUT, "pll2_out", "pll2_refclk", 1, 55),
178 1.3 skrll
179 1.3 skrll JH71X0CLKC_MUX(JH7100_CLK_CPUNDBUS_ROOT, "cpundbus_root", cpundbus_root_parents),
180 1.3 skrll JH71X0CLKC_MUX(JH7100_CLK_DSP_ROOT, "dsp_root", dsp_root_parents),
181 1.3 skrll JH71X0CLKC_MUX(JH7100_CLK_GMACUSB_ROOT, "gmacusb_root", gmacusb_root_parents),
182 1.3 skrll JH71X0CLKC_MUX(JH7100_CLK_PERH0_ROOT, "perh0_root", perh0_root_parents),
183 1.3 skrll JH71X0CLKC_MUX(JH7100_CLK_PERH1_ROOT, "perh1_root", perh1_root_parents),
184 1.3 skrll JH71X0CLKC_MUX(JH7100_CLK_PLL2_REF, "pll2_refclk", pll2_refclk_parents),
185 1.1 skrll
186 1.3 skrll JH71X0CLKC_MUX(JH7100_CLK_VOUT_ROOT, "vout_root", vout_root_parents),
187 1.3 skrll JH71X0CLKC_MUX(JH7100_CLK_VOUTBUS_ROOT, "voutbus_root", vout_root_parents),
188 1.1 skrll
189 1.3 skrll JH71X0CLKC_MUX_FLAGS(JH7100_CLK_GMAC_TX, "gmac_tx", gmac_tx_parents, CLK_SET_RATE_PARENT),
190 1.1 skrll
191 1.3 skrll JH71X0CLKC_MUX(JH7100_CLK_GMAC_RX_PRE, "gmac_rx_pre", gmac_rx_pre_parents),
192 1.1 skrll
193 1.3 skrll JH71X0CLKC_DIV(JH7100_CLK_CPUNBUS_ROOT_DIV, "cpunbus_root_div",
194 1.1 skrll 2, "cpundbus_root"),
195 1.3 skrll JH71X0CLKC_DIV(JH7100_CLK_PERH0_SRC, "perh0_src", 4, "perh0_root"),
196 1.3 skrll JH71X0CLKC_DIV(JH7100_CLK_PERH1_SRC, "perh1_src", 4, "perh1_root"),
197 1.1 skrll
198 1.3 skrll JH71X0CLKC_DIV(JH7100_CLK_AHB_BUS, "ahb_bus", 8, "cpunbus_root_div"),
199 1.3 skrll JH71X0CLKC_DIV(JH7100_CLK_APB1_BUS, "apb1_bus", 8, "ahb_bus"),
200 1.3 skrll JH71X0CLKC_DIV(JH7100_CLK_APB2_BUS, "apb2_bus", 8, "ahb_bus"),
201 1.3 skrll JH71X0CLKC_DIV(JH7100_CLK_CPU_CORE, "cpu_core", 8, "cpunbus_root_div"),
202 1.3 skrll JH71X0CLKC_DIV(JH7100_CLK_CPU_AXI, "cpu_axi", 8, "cpu_core"),
203 1.3 skrll JH71X0CLKC_DIV(JH7100_CLK_GMAC_ROOT_DIV, "gmac_root_div", 8, "gmacusb_root"),
204 1.3 skrll JH71X0CLKC_DIV(JH7100_CLK_DSP_ROOT_DIV, "dsp_root_div", 4, "dsp_root"),
205 1.3 skrll JH71X0CLKC_DIV(JH7100_CLK_SGDMA1P_BUS, "sgdma1p_bus", 8, "cpunbus_root_div"),
206 1.3 skrll
207 1.3 skrll JH71X0CLKC_DIV(JH7100_CLK_DISPBUS_SRC, "dispbus_src", 4, "voutbus_root"),
208 1.3 skrll
209 1.3 skrll JH71X0CLKC_DIV(JH7100_CLK_DISP_BUS, "disp_bus", 4, "dispbus_src"),
210 1.3 skrll
211 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_UART0_APB, "uart0_apb", "apb1_bus"),
212 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_UART1_APB, "uart1_apb", "apb1_bus"),
213 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_UART2_APB, "uart2_apb", "apb2_bus"),
214 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_UART3_APB, "uart3_apb", "apb2_bus"),
215 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_SGDMA2P_AXI, "sgdma2p_axi", "cpu_axi"),
216 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_SGDMA2P_AHB, "sgdma2p_ahb", "ahb_bus"),
217 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_SGDMA1P_AXI, "sgdma1p_axi", "sgdma1p_bus"),
218 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_GPIO_APB, "gpio_apb", "apb1_bus"),
219 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_I2C0_APB, "i2c0_apb", "apb1_bus"),
220 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_I2C1_APB, "i2c1_apb", "apb1_bus"),
221 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_I2C2_APB, "i2c2_apb", "apb2_bus"),
222 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_I2C3_APB, "i2c3_apb", "apb2_bus"),
223 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_TRNG_APB, "trng_apb", "apb1_bus"),
224 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_SEC_AHB, "sec_ahb", "ahb_bus"),
225 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_GMAC_AHB, "gmac_ahb", "ahb_bus"),
226 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_GMAC_AHB, "gmac_ahb", "ahb_bus"),
227 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_JPEG_APB, "jpeg_apb", "apb1_bus"),
228 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_PWM_APB, "pwm_apb", "apb2_bus"),
229 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_QSPI_AHB, "qspi_ahb", "ahb_bus"),
230 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_SPI0_APB, "spi0_apb", "apb1_bus"),
231 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_SPI1_APB, "spi1_apb", "apb1_bus"),
232 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_SPI2_APB, "spi2_apb", "apb2_bus"),
233 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_SPI3_APB, "spi3_apb", "apb2_bus"),
234 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_SDIO0_AHB, "sdio0_ahb", "ahb_bus"),
235 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_SDIO1_AHB, "sdio1_ahb", "ahb_bus"),
236 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_OTP_APB, "otp_apb", "apb1_bus"),
237 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_DOM7AHB_BUS, "dom7ahb_bus", "ahb_bus"),
238 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_AUDIO_SRC, "audio_src", "audio_div"),
239 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_AUDIO_12288, "audio_12288", "osc_aud"),
240 1.3 skrll
241 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_DISP_AXI, "disp_axi", "disp_bus"),
242 1.3 skrll
243 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_GMAC_RMII, "gmac_rmii", "gmac_rmii_ref"),
244 1.3 skrll
245 1.3 skrll JH71X0CLKC_GATE(JH7100_CLK_WDTIMER_APB, "wdtimer_apb", "apb2_bus"),
246 1.3 skrll
247 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_UART0_CORE, "uart0_core", 63, "perh1_src"),
248 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_UART1_CORE, "uart1_core", 63, "perh1_src"),
249 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_UART2_CORE, "uart2_core", 63, "perh0_src"),
250 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_UART3_CORE, "uart3_core", 63, "perh0_src"),
251 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_I2C0_CORE, "i2c0_core", 63, "perh1_src"),
252 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_I2C1_CORE, "i2c1_core", 63, "perh1_src"),
253 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_I2C2_CORE, "i2c2_core", 63, "perh0_src"),
254 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_I2C3_CORE, "i2c3_core", 63, "perh0_src"),
255 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_GMAC_PTP_REF, "gmac_ptp_refclk", 31, "gmac_root_div"),
256 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_VP6_CORE, "vp6_core", 4, "dsp_root_div"),
257 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_VP6_CORE, "vp6_core", 4, "dsp_root_div"),
258 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_SPI0_CORE, "spi0_core", 63, "perh1_src"),
259 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_SPI1_CORE, "spi1_core", 63, "perh1_src"),
260 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_SPI2_CORE, "spi2_core", 63, "perh0_src"),
261 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_SPI3_CORE, "spi3_core", 63, "perh0_src"),
262 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_VP6_CORE, "vp6_core", 4, "dsp_root_div"),
263 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_SDIO0_CCLKINT, "sdio0_cclkint", 24, "perh0_src"),
264 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_SDIO1_CCLKINT, "sdio1_cclkint", 24, "perh1_src"),
265 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_AUDIO_ROOT, "audio_root", 8, "pll0_out"),
266 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_VOUT_SRC, "vout_src", 4, "vout_root"),
267 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_WDT_CORE, "wdt_coreclk", 63, "perh0_src"),
268 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", 255, "gmac_root_div"),
269 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", 8, "gmac_rmii_ref"),
270 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", 8, "gmac_rmii_ref"),
271 1.3 skrll JH71X0CLKC_GATEDIV(JH7100_CLK_GMAC_TOPHYREF, "gmac_tophyref", 127, "gmac_root_div"),
272 1.3 skrll
273 1.3 skrll JH71X0CLKC_FRACDIV(JH7100_CLK_AUDIO_DIV, "audio_div", "audio_root"),
274 1.3 skrll
275 1.3 skrll JH71X0CLKC_INV(JH7100_CLK_SDIO0_CCLKINT_INV, "sdio0_cclkint_inv", "sdio0_cclkint"),
276 1.3 skrll JH71X0CLKC_INV(JH7100_CLK_SDIO1_CCLKINT_INV, "sdio1_cclkint_inv", "sdio1_cclkint"),
277 1.3 skrll JH71X0CLKC_INV(JH7100_CLK_GMAC_RX_INV, "gmac_rx_inv", "gmac_rx_pre"),
278 1.3 skrll JH71X0CLKC_INV(JH7100_CLK_GMAC_TX_INV, "gmac_tx_inv", "gmac_tx"),
279 1.1 skrll };
280 1.1 skrll
281 1.3 skrll
282 1.1 skrll static const struct device_compatible_entry compat_data[] = {
283 1.1 skrll { .compat = "starfive,jh7100-clkgen" },
284 1.1 skrll DEVICE_COMPAT_EOL
285 1.1 skrll };
286 1.1 skrll
287 1.1 skrll
288 1.1 skrll static struct clk *
289 1.1 skrll jh7100_clkc_fdt_decode(device_t dev, int phandle, const void *data,
290 1.1 skrll size_t len)
291 1.1 skrll {
292 1.3 skrll struct jh71x0_clkc_softc * const sc = device_private(dev);
293 1.1 skrll
294 1.1 skrll if (len != 4)
295 1.1 skrll return NULL;
296 1.1 skrll
297 1.1 skrll u_int id = be32dec(data);
298 1.1 skrll if (id >= sc->sc_nclks)
299 1.1 skrll return NULL;
300 1.1 skrll
301 1.3 skrll if (sc->sc_clk[id].jcc_type == JH71X0CLK_UNKNOWN) {
302 1.1 skrll printf("Unknown clock %d\n", id);
303 1.1 skrll return NULL;
304 1.1 skrll }
305 1.1 skrll return &sc->sc_clk[id].jcc_clk;
306 1.1 skrll }
307 1.1 skrll
308 1.1 skrll static const struct fdtbus_clock_controller_func jh7100_clkc_fdt_funcs = {
309 1.1 skrll .decode = jh7100_clkc_fdt_decode
310 1.1 skrll };
311 1.1 skrll
312 1.1 skrll static int
313 1.1 skrll jh7100_clkc_match(device_t parent, cfdata_t cf, void *aux)
314 1.1 skrll {
315 1.1 skrll struct fdt_attach_args * const faa = aux;
316 1.1 skrll
317 1.1 skrll return of_compatible_match(faa->faa_phandle, compat_data);
318 1.1 skrll }
319 1.1 skrll
320 1.1 skrll static void
321 1.1 skrll jh7100_clkc_attach(device_t parent, device_t self, void *aux)
322 1.1 skrll {
323 1.3 skrll struct jh71x0_clkc_softc * const sc = device_private(self);
324 1.1 skrll struct fdt_attach_args * const faa = aux;
325 1.1 skrll const int phandle = faa->faa_phandle;
326 1.1 skrll bus_addr_t addr;
327 1.1 skrll bus_size_t size;
328 1.1 skrll int error;
329 1.1 skrll
330 1.1 skrll error = fdtbus_get_reg(phandle, 0, &addr, &size);
331 1.1 skrll if (error) {
332 1.1 skrll aprint_error(": couldn't get registers\n");
333 1.1 skrll return;
334 1.1 skrll }
335 1.1 skrll
336 1.1 skrll sc->sc_dev = self;
337 1.1 skrll sc->sc_phandle = phandle;
338 1.1 skrll sc->sc_bst = faa->faa_bst;
339 1.1 skrll error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
340 1.1 skrll if (error) {
341 1.1 skrll aprint_error(": couldn't map registers\n");
342 1.1 skrll return;
343 1.1 skrll }
344 1.1 skrll
345 1.1 skrll struct clk * const osclk = fdtbus_clock_get(phandle, "osc_sys");
346 1.1 skrll if (osclk == NULL) {
347 1.1 skrll aprint_error(": couldn't get osc_sys\n");
348 1.1 skrll return;
349 1.1 skrll }
350 1.3 skrll u_int osclk_rate = clk_get_rate(osclk);
351 1.1 skrll
352 1.1 skrll struct clk * const oaclk = fdtbus_clock_get(phandle, "osc_aud");
353 1.1 skrll if (oaclk == NULL) {
354 1.1 skrll aprint_error(": couldn't get osc_aud\n");
355 1.1 skrll return;
356 1.1 skrll }
357 1.3 skrll u_int oaclk_rate = clk_get_rate(oaclk);
358 1.1 skrll
359 1.1 skrll sc->sc_clkdom.name = device_xname(self);
360 1.3 skrll sc->sc_clkdom.funcs = &jh71x0_clkc_funcs;
361 1.1 skrll sc->sc_clkdom.priv = sc;
362 1.1 skrll
363 1.1 skrll sc->sc_clk = jh7100_clocks;
364 1.1 skrll sc->sc_nclks = __arraycount(jh7100_clocks);
365 1.1 skrll for (size_t id = 0; id < sc->sc_nclks; id++) {
366 1.3 skrll if (sc->sc_clk[id].jcc_type == JH71X0CLK_UNKNOWN)
367 1.1 skrll continue;
368 1.1 skrll
369 1.1 skrll sc->sc_clk[id].jcc_clk.domain = &sc->sc_clkdom;
370 1.1 skrll clk_attach(&sc->sc_clk[id].jcc_clk);
371 1.1 skrll }
372 1.1 skrll
373 1.1 skrll aprint_naive("\n");
374 1.1 skrll aprint_normal(": JH7100 (OSC0 %u Hz, OSC1 %u Hz)\n",
375 1.3 skrll osclk_rate, oaclk_rate);
376 1.1 skrll
377 1.1 skrll for (size_t id = 0; id < sc->sc_nclks; id++) {
378 1.3 skrll if (sc->sc_clk[id].jcc_type == JH71X0CLK_UNKNOWN)
379 1.1 skrll continue;
380 1.1 skrll
381 1.1 skrll struct clk * const clk = &sc->sc_clk[id].jcc_clk;
382 1.1 skrll
383 1.1 skrll aprint_debug_dev(self, "id %zu [%s]: %u Hz\n", id,
384 1.1 skrll clk->name ? clk->name : "<none>", clk_get_rate(clk));
385 1.1 skrll }
386 1.1 skrll
387 1.1 skrll fdtbus_register_clock_controller(self, phandle, &jh7100_clkc_fdt_funcs);
388 1.1 skrll }
389 1.1 skrll
390 1.3 skrll CFATTACH_DECL_NEW(jh7100_clkc, sizeof(struct jh71x0_clkc_softc),
391 1.3 skrll jh7100_clkc_match, jh7100_clkc_attach, NULL, NULL);
392