]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/allwinner/clkng/ccu_h3.c
Merge OpenSSL 1.0.2n.
[FreeBSD/FreeBSD.git] / sys / arm / allwinner / clkng / ccu_h3.c
1 /*-
2  * Copyright (c) 2017 Emmanuel Vadot <manu@freebsd.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
21  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/bus.h>
35
36 #include <dev/extres/clk/clk_div.h>
37 #include <dev/extres/clk/clk_fixed.h>
38 #include <dev/extres/clk/clk_mux.h>
39
40 #if defined(__aarch64__)
41 #include "opt_soc.h"
42 #endif
43
44 #include <arm/allwinner/clkng/aw_ccung.h>
45 #include <arm/allwinner/clkng/aw_clk.h>
46 #include <arm/allwinner/clkng/aw_clk_nm.h>
47 #include <arm/allwinner/clkng/aw_clk_nkmp.h>
48 #include <arm/allwinner/clkng/aw_clk_prediv_mux.h>
49
50 #include <gnu/dts/include/dt-bindings/clock/sun8i-h3-ccu.h>
51 #include <gnu/dts/include/dt-bindings/reset/sun8i-h3-ccu.h>
52
53 #include "ccu_h3.h"
54
55 /* Non-exported resets */
56 #define RST_BUS_SCR             53
57
58 /* Non-exported clocks */
59 #define CLK_PLL_CPUX            0
60 #define CLK_PLL_AUDIO_BASE      1
61 #define CLK_PLL_AUDIO           2
62 #define CLK_PLL_AUDIO_2X        3
63 #define CLK_PLL_AUDIO_4X        4
64 #define CLK_PLL_AUDIO_8X        5
65 #define CLK_PLL_VIDEO           6
66 #define CLK_PLL_VE              7
67 #define CLK_PLL_DDR             8
68 #define CLK_PLL_PERIPH0_2X      10
69 #define CLK_PLL_GPU             11
70 #define CLK_PLL_PERIPH1         12
71 #define CLK_PLL_DE              13
72
73 #define CLK_AXI                 15
74 #define CLK_AHB1                16
75 #define CLK_APB1                17
76 #define CLK_APB2                18
77 #define CLK_AHB2                19
78
79 #define CLK_BUS_SCR             66
80
81 #define CLK_USBPHY0             88
82 #define CLK_USBPHY1             89
83 #define CLK_USBPHY2             90
84 #define CLK_USBPHY3             91
85 #define CLK_USBOHCI0            92
86 #define CLK_USBOHCI1            93
87 #define CLK_USBOHCI2            94
88 #define CLK_USBOHCI3            95
89 #define CLK_DRAM                96
90
91 #define CLK_MBUS                113
92
93 static struct aw_ccung_reset h3_ccu_resets[] = {
94         CCU_RESET(RST_USB_PHY0, 0xcc, 0)
95         CCU_RESET(RST_USB_PHY1, 0xcc, 1)
96         CCU_RESET(RST_USB_PHY2, 0xcc, 2)
97         CCU_RESET(RST_USB_PHY3, 0xcc, 3)
98
99         CCU_RESET(RST_MBUS, 0xfc, 31)
100
101         CCU_RESET(RST_BUS_CE, 0x2c0, 5)
102         CCU_RESET(RST_BUS_DMA, 0x2c0, 6)
103         CCU_RESET(RST_BUS_MMC0, 0x2c0, 8)
104         CCU_RESET(RST_BUS_MMC1, 0x2c0, 9)
105         CCU_RESET(RST_BUS_MMC2, 0x2c0, 10)
106         CCU_RESET(RST_BUS_NAND, 0x2c0, 13)
107         CCU_RESET(RST_BUS_DRAM, 0x2c0, 14)
108         CCU_RESET(RST_BUS_EMAC, 0x2c0, 17)
109         CCU_RESET(RST_BUS_TS, 0x2c0, 18)
110         CCU_RESET(RST_BUS_HSTIMER, 0x2c0, 19)
111         CCU_RESET(RST_BUS_SPI0, 0x2c0, 20)
112         CCU_RESET(RST_BUS_SPI1, 0x2c0, 21)
113         CCU_RESET(RST_BUS_OTG, 0x2c0, 23)
114         CCU_RESET(RST_BUS_EHCI0, 0x2c0, 24)
115         CCU_RESET(RST_BUS_EHCI1, 0x2c0, 25)
116         CCU_RESET(RST_BUS_EHCI2, 0x2c0, 26)
117         CCU_RESET(RST_BUS_EHCI3, 0x2c0, 27)
118         CCU_RESET(RST_BUS_OHCI0, 0x2c0, 28)
119         CCU_RESET(RST_BUS_OHCI1, 0x2c0, 29)
120         CCU_RESET(RST_BUS_OHCI2, 0x2c0, 30)
121         CCU_RESET(RST_BUS_OHCI3, 0x2c0, 31)
122
123         CCU_RESET(RST_BUS_VE, 0x2c4, 0)
124         CCU_RESET(RST_BUS_TCON0, 0x2c4, 3)
125         CCU_RESET(RST_BUS_TCON1, 0x2c4, 4)
126         CCU_RESET(RST_BUS_DEINTERLACE, 0x2c4, 5)
127         CCU_RESET(RST_BUS_CSI, 0x2c4, 8)
128         CCU_RESET(RST_BUS_TVE, 0x2c4, 9)
129         CCU_RESET(RST_BUS_HDMI0, 0x2c4, 10)
130         CCU_RESET(RST_BUS_HDMI1, 0x2c4, 11)
131         CCU_RESET(RST_BUS_DE, 0x2c4, 12)
132         CCU_RESET(RST_BUS_GPU, 0x2c4, 20)
133         CCU_RESET(RST_BUS_MSGBOX, 0x2c4, 21)
134         CCU_RESET(RST_BUS_SPINLOCK, 0x2c4, 22)
135         CCU_RESET(RST_BUS_DBG, 0x2c4, 31)
136
137         CCU_RESET(RST_BUS_EPHY, 0x2c8, 2)
138
139         CCU_RESET(RST_BUS_CODEC, 0x2d0, 0)
140         CCU_RESET(RST_BUS_SPDIF, 0x2d0, 1)
141         CCU_RESET(RST_BUS_THS, 0x2d0, 8)
142         CCU_RESET(RST_BUS_I2S0, 0x2d0, 12)
143         CCU_RESET(RST_BUS_I2S1, 0x2d0, 13)
144         CCU_RESET(RST_BUS_I2S2, 0x2d0, 14)
145
146         CCU_RESET(RST_BUS_I2C0, 0x2d8, 0)
147         CCU_RESET(RST_BUS_I2C1, 0x2d8, 1)
148         CCU_RESET(RST_BUS_I2C2, 0x2d8, 2)
149         CCU_RESET(RST_BUS_UART0, 0x2d8, 16)
150         CCU_RESET(RST_BUS_UART1, 0x2d8, 17)
151         CCU_RESET(RST_BUS_UART2, 0x2d8, 18)
152         CCU_RESET(RST_BUS_UART3, 0x2d8, 19)
153         CCU_RESET(RST_BUS_SCR, 0x2d8, 20)
154 };
155
156 static struct aw_ccung_gate h3_ccu_gates[] = {
157         CCU_GATE(CLK_BUS_CE, "bus-ce", "ahb1", 0x60, 5)
158         CCU_GATE(CLK_BUS_DMA, "bus-dma", "ahb1", 0x60, 6)
159         CCU_GATE(CLK_BUS_MMC0, "bus-mmc0", "ahb1", 0x60, 8)
160         CCU_GATE(CLK_BUS_MMC1, "bus-mmc1", "ahb1", 0x60, 9)
161         CCU_GATE(CLK_BUS_MMC2, "bus-mmc2", "ahb1", 0x60, 10)
162         CCU_GATE(CLK_BUS_NAND, "bus-nand", "ahb1", 0x60, 13)
163         CCU_GATE(CLK_BUS_DRAM, "bus-dram", "ahb1", 0x60, 14)
164         CCU_GATE(CLK_BUS_EMAC, "bus-emac", "ahb2", 0x60, 17)
165         CCU_GATE(CLK_BUS_TS, "bus-ts", "ahb1", 0x60, 18)
166         CCU_GATE(CLK_BUS_HSTIMER, "bus-hstimer", "ahb1", 0x60, 19)
167         CCU_GATE(CLK_BUS_SPI0, "bus-spi0", "ahb1", 0x60, 20)
168         CCU_GATE(CLK_BUS_SPI1, "bus-spi1", "ahb1", 0x60, 21)
169         CCU_GATE(CLK_BUS_OTG, "bus-otg", "ahb1", 0x60, 23)
170         CCU_GATE(CLK_BUS_EHCI0, "bus-ehci0", "ahb1", 0x60, 24)
171         CCU_GATE(CLK_BUS_EHCI1, "bus-ehci1", "ahb2", 0x60, 25)
172         CCU_GATE(CLK_BUS_EHCI2, "bus-ehci2", "ahb2", 0x60, 26)
173         CCU_GATE(CLK_BUS_EHCI3, "bus-ehci3", "ahb2", 0x60, 27)
174         CCU_GATE(CLK_BUS_OHCI0, "bus-ohci0", "ahb1", 0x60, 28)
175         CCU_GATE(CLK_BUS_OHCI1, "bus-ohci1", "ahb2", 0x60, 29)
176         CCU_GATE(CLK_BUS_OHCI2, "bus-ohci2", "ahb2", 0x60, 30)
177         CCU_GATE(CLK_BUS_OHCI3, "bus-ohci3", "ahb2", 0x60, 31)
178
179         CCU_GATE(CLK_BUS_VE, "bus-ve", "ahb1", 0x64, 0)
180         CCU_GATE(CLK_BUS_TCON0, "bus-tcon0", "ahb1", 0x64, 3)
181         CCU_GATE(CLK_BUS_TCON1, "bus-tcon1", "ahb1", 0x64, 4)
182         CCU_GATE(CLK_BUS_DEINTERLACE, "bus-deinterlace", "ahb1", 0x64, 5)
183         CCU_GATE(CLK_BUS_CSI, "bus-csi", "ahb1", 0x64, 8)
184         CCU_GATE(CLK_BUS_TVE, "bus-tve", "ahb1", 0x64, 9)
185         CCU_GATE(CLK_BUS_HDMI, "bus-hdmi", "ahb1", 0x64, 11)
186         CCU_GATE(CLK_BUS_DE, "bus-de", "ahb1", 0x64, 12)
187         CCU_GATE(CLK_BUS_GPU, "bus-gpu", "ahb1", 0x64, 20)
188         CCU_GATE(CLK_BUS_MSGBOX, "bus-msgbox", "ahb1", 0x64, 21)
189         CCU_GATE(CLK_BUS_SPINLOCK, "bus-spinlock", "ahb1", 0x64, 22)
190
191         CCU_GATE(CLK_BUS_CODEC, "bus-codec", "apb1", 0x68, 0)
192         CCU_GATE(CLK_BUS_SPDIF, "bus-spdif", "apb1", 0x68, 1)
193         CCU_GATE(CLK_BUS_PIO, "bus-pio", "apb1", 0x68, 5)
194         CCU_GATE(CLK_BUS_THS, "bus-ths", "apb1", 0x68, 8)
195         CCU_GATE(CLK_BUS_I2S0, "bus-i2s0", "apb1", 0x68, 12)
196         CCU_GATE(CLK_BUS_I2S1, "bus-i2s1", "apb1", 0x68, 13)
197         CCU_GATE(CLK_BUS_I2S2, "bus-i2s2", "apb1", 0x68, 14)
198
199         CCU_GATE(CLK_BUS_I2C0, "bus-i2c0", "apb2", 0x6c, 0)
200         CCU_GATE(CLK_BUS_I2C1, "bus-i2c1", "apb2", 0x6c, 1)
201         CCU_GATE(CLK_BUS_I2C2, "bus-i2c2", "apb2", 0x6c, 2)
202         CCU_GATE(CLK_BUS_UART0, "bus-uart0", "apb2", 0x6c, 16)
203         CCU_GATE(CLK_BUS_UART1, "bus-uart1", "apb2", 0x6c, 17)
204         CCU_GATE(CLK_BUS_UART2, "bus-uart2", "apb2", 0x6c, 18)
205         CCU_GATE(CLK_BUS_UART3, "bus-uart3", "apb2", 0x6c, 19)
206         CCU_GATE(CLK_BUS_SCR, "bus-scr", "apb2", 0x6c, 20)
207
208         CCU_GATE(CLK_BUS_EPHY, "bus-ephy", "ahb1", 0x70, 0)
209         CCU_GATE(CLK_BUS_DBG, "bus-dbg", "ahb1", 0x70, 7)
210
211         CCU_GATE(CLK_USBPHY0, "usb-phy0", "osc24M", 0xcc, 8)
212         CCU_GATE(CLK_USBPHY1, "usb-phy1", "osc24M", 0xcc, 9)
213         CCU_GATE(CLK_USBPHY2, "usb-phy2", "osc24M", 0xcc, 10)
214         CCU_GATE(CLK_USBPHY3, "usb-phy3", "osc24M", 0xcc, 11)
215         CCU_GATE(CLK_USBOHCI0, "usb-ohci0", "osc24M", 0xcc, 16)
216         CCU_GATE(CLK_USBOHCI1, "usb-ohci1", "osc24M", 0xcc, 17)
217         CCU_GATE(CLK_USBOHCI2, "usb-ohci2", "osc24M", 0xcc, 18)
218         CCU_GATE(CLK_USBOHCI3, "usb-ohci3", "osc24M", 0xcc, 19)
219
220         CCU_GATE(CLK_THS, "ths", "thsdiv", 0x74, 31)
221         CCU_GATE(CLK_I2S0, "i2s0", "i2s0mux", 0xB0, 31)
222         CCU_GATE(CLK_I2S1, "i2s1", "i2s1mux", 0xB4, 31)
223         CCU_GATE(CLK_I2S2, "i2s2", "i2s2mux", 0xB8, 31)
224
225         CCU_GATE(CLK_DRAM_VE, "dram-ve", "dram", 0x100, 0)
226         CCU_GATE(CLK_DRAM_CSI, "dram-csi", "dram", 0x100, 1)
227         CCU_GATE(CLK_DRAM_DEINTERLACE, "dram-deinterlace", "dram", 0x100, 2)
228         CCU_GATE(CLK_DRAM_TS, "dram-ts", "dram", 0x100, 3)
229
230         CCU_GATE(CLK_AC_DIG, "ac-dig", "pll_audio", 0x140, 31)
231
232         CCU_GATE(CLK_AVS, "avs", "osc24M", 0x144, 31)
233
234         CCU_GATE(CLK_CSI_MISC, "csi-misc", "osc24M", 0x130, 31)
235
236         CCU_GATE(CLK_HDMI_DDC, "hdmi-ddc", "osc24M", 0x154, 31)
237 };
238
239 static const char *pll_cpux_parents[] = {"osc24M"};
240 NKMP_CLK(pll_cpux_clk,
241     CLK_PLL_CPUX,                               /* id */
242     "pll_cpux", pll_cpux_parents,               /* name, parents */
243     0x00,                                       /* offset */
244     8, 5, 0, 0,                                 /* n factor */
245     4, 2, 0, 0,                                 /* k factor */
246     0, 2, 0, 0,                                 /* m factor */
247     16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO,       /* p factor */
248     31,                                         /* gate */
249     28, 1000,                                   /* lock */
250     AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK | AW_CLK_SCALE_CHANGE);           /* flags */
251
252 static const char *pll_audio_parents[] = {"osc24M"};
253 NKMP_CLK(pll_audio_clk,
254     CLK_PLL_AUDIO,                              /* id */
255     "pll_audio", pll_audio_parents,             /* name, parents */
256     0x08,                                       /* offset */
257     8, 7, 0, 0,                                 /* n factor */
258     0, 0, 1, AW_CLK_FACTOR_FIXED,               /* k factor (fake) */
259     0, 5, 0, 0,                                 /* m factor */
260     16, 4, 0, 0,                                /* p factor */
261     31,                                         /* gate */
262     28, 1000,                                   /* lock */
263     AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK);         /* flags */
264
265 static const char *pll_audio_mult_parents[] = {"pll_audio"};
266 FIXED_CLK(pll_audio_2x_clk,
267     CLK_PLL_AUDIO_2X,                   /* id */
268     "pll_audio-2x",                     /* name */
269     pll_audio_mult_parents,             /* parent */
270     0,                                  /* freq */
271     2,                                  /* mult */
272     1,                                  /* div */
273     0);                                 /* flags */
274 FIXED_CLK(pll_audio_4x_clk,
275     CLK_PLL_AUDIO_4X,                   /* id */
276     "pll_audio-4x",                     /* name */
277     pll_audio_mult_parents,             /* parent */
278     0,                                  /* freq */
279     4,                                  /* mult */
280     1,                                  /* div */
281     0);                                 /* flags */
282 FIXED_CLK(pll_audio_8x_clk,
283     CLK_PLL_AUDIO_8X,                   /* id */
284     "pll_audio-8x",                     /* name */
285     pll_audio_mult_parents,             /* parent */
286     0,                                  /* freq */
287     8,                                  /* mult */
288     1,                                  /* div */
289     0);                                 /* flags */
290
291 static const char *pll_video_parents[] = {"osc24M"};
292 NM_CLK_WITH_FRAC(pll_video_clk,
293     CLK_PLL_VIDEO,                              /* id */
294     "pll_video", pll_video_parents,             /* name, parents */
295     0x10,                                       /* offset */
296     8, 7, 0, 0,                                 /* n factor */
297     0, 4, 0, 0,                                 /* m factor */
298     31, 28, 1000,                               /* gate, lock, lock retries */
299     AW_CLK_HAS_LOCK,                            /* flags */
300     270000000, 297000000,                       /* freq0, freq1 */
301     24, 25);                                    /* mode sel, freq sel */
302
303 static const char *pll_ve_parents[] = {"osc24M"};
304 NM_CLK_WITH_FRAC(pll_ve_clk,
305     CLK_PLL_VE,                         /* id */
306     "pll_ve", pll_ve_parents,                   /* name, parents */
307     0x18,                                       /* offset */
308     8, 7, 0, 0,                                 /* n factor */
309     0, 4, 0, 0,                                 /* m factor */
310     31, 28, 1000,                               /* gate, lock, lock retries */
311     AW_CLK_HAS_LOCK,                            /* flags */
312     270000000, 297000000,                       /* freq0, freq1 */
313     24, 25);                                    /* mode sel, freq sel */
314
315 static const char *pll_ddr_parents[] = {"osc24M"};
316 NKMP_CLK_WITH_UPDATE(pll_ddr_clk,
317     CLK_PLL_DDR,                                /* id */
318     "pll_ddr", pll_ddr_parents,                 /* name, parents */
319     0x20,                                       /* offset */
320     8, 5, 0, 0,                                 /* n factor */
321     4, 2, 0, 0,                                 /* k factor */
322     0, 2, 0, 0,                                 /* m factor */
323     0, 0, 1, AW_CLK_FACTOR_FIXED,               /* p factor (fake) */
324     31,                                         /* gate */
325     28, 1000,                                   /* lock */
326     20,                                         /* update */
327     AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK);         /* flags */
328
329 static const char *pll_periph0_parents[] = {"osc24M"};
330 static const char *pll_periph0_2x_parents[] = {"pll_periph0"};
331 NKMP_CLK(pll_periph0_clk,
332     CLK_PLL_PERIPH0,                            /* id */
333     "pll_periph0", pll_periph0_parents,         /* name, parents */
334     0x28,                                       /* offset */
335     8, 5, 0, 0,                                 /* n factor */
336     4, 2, 0, 0,                                 /* k factor */
337     0, 0, 2, AW_CLK_FACTOR_FIXED,               /* m factor (fake) */
338     0, 0, 1, AW_CLK_FACTOR_FIXED,               /* p factor (fake) */
339     31,                                         /* gate */
340     28, 1000,                                   /* lock */
341     AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK);         /* flags */
342 FIXED_CLK(pll_periph0_2x_clk,
343     CLK_PLL_PERIPH0_2X,                 /* id */
344     "pll_periph0-2x",                   /* name */
345     pll_periph0_2x_parents,             /* parent */
346     0,                                  /* freq */
347     2,                                  /* mult */
348     1,                                  /* div */
349     0);                                 /* flags */
350
351 static const char *pll_gpu_parents[] = {"osc24M"};
352 NM_CLK_WITH_FRAC(pll_gpu_clk,
353     CLK_PLL_GPU,                                /* id */
354     "pll_gpu", pll_gpu_parents,                 /* name, parents */
355     0x38,                                       /* offset */
356     8, 7, 0, 0,                                 /* n factor */
357     0, 4, 0, 0,                                 /* m factor */
358     31, 28, 1000,                               /* gate, lock, lock retries */
359     AW_CLK_HAS_LOCK,                            /* flags */
360     270000000, 297000000,                       /* freq0, freq1 */
361     24, 25);                                    /* mode sel, freq sel */
362
363 static const char *pll_periph1_parents[] = {"osc24M"};
364 NKMP_CLK(pll_periph1_clk,
365     CLK_PLL_PERIPH1,                            /* id */
366     "pll_periph1", pll_periph1_parents,         /* name, parents */
367     0x44,                                       /* offset */
368     8, 5, 0, 0,                                 /* n factor */
369     4, 2, 0, 0,                                 /* k factor */
370     0, 0, 2, AW_CLK_FACTOR_FIXED,               /* m factor (fake) */
371     0, 0, 1, AW_CLK_FACTOR_FIXED,               /* p factor (fake) */
372     31,                                         /* gate */
373     28, 1000,                                   /* lock */
374     AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK);         /* flags */
375
376 static const char *pll_de_parents[] = {"osc24M"};
377 NM_CLK_WITH_FRAC(pll_de_clk,
378     CLK_PLL_DE,                                 /* id */
379     "pll_de", pll_de_parents,                   /* name, parents */
380     0x48,                                       /* offset */
381     8, 7, 0, 0,                                 /* n factor */
382     0, 4, 0, 0,                                 /* m factor */
383     31, 28, 1000,                               /* gate, lock, lock retries */
384     AW_CLK_HAS_LOCK,                            /* flags */
385     270000000, 297000000,                       /* freq0, freq1 */
386     24, 25);                                    /* mode sel, freq sel */
387
388 static const char *cpux_parents[] = {"osc32k", "osc24M", "pll_cpux", "pll_cpux"};
389 MUX_CLK(cpux_clk,
390     CLK_CPUX,                   /* id */
391     "cpux", cpux_parents,       /* name, parents */
392     0x50, 16, 2);               /* offset, shift, width */
393
394 static const char *axi_parents[] = {"cpux"};
395 DIV_CLK(axi_clk,
396     CLK_AXI,                    /* id */
397     "axi", axi_parents,         /* name, parents */
398     0x50,                       /* offset */
399     0, 2,                       /* shift, width */
400     0, NULL);                   /* flags, div table */
401
402 static const char *ahb1_parents[] = {"osc32k", "osc24M", "axi", "pll_periph0"};
403 PREDIV_CLK(ahb1_clk, CLK_AHB1,                                  /* id */
404     "ahb1", ahb1_parents,                                       /* name, parents */
405     0x54,                                                       /* offset */
406     12, 2,                                                      /* mux */
407     4, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO,                        /* div */
408     6, 2, 0, AW_CLK_FACTOR_HAS_COND,                            /* prediv */
409     12, 2, 3);                                                  /* prediv condition */
410
411 static const char *apb1_parents[] = {"ahb1"};
412 static struct clk_div_table apb1_div_table[] = {
413         { .value = 0, .divider = 2, },
414         { .value = 1, .divider = 2, },
415         { .value = 2, .divider = 4, },
416         { .value = 3, .divider = 8, },
417         { },
418 };
419 DIV_CLK(apb1_clk,
420     CLK_APB1,                   /* id */
421     "apb1", apb1_parents,       /* name, parents */
422     0x54,                       /* offset */
423     8, 2,                       /* shift, width */
424     CLK_DIV_WITH_TABLE,         /* flags */
425     apb1_div_table);            /* div table */
426
427 static const char *apb2_parents[] = {"osc32k", "osc24M", "pll_periph0", "pll_periph0"};
428 NM_CLK(apb2_clk,
429     CLK_APB2,                                   /* id */
430     "apb2", apb2_parents,                       /* name, parents */
431     0x58,                                       /* offset */
432     16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO,       /* n factor */
433     0, 5, 0, 0,                                 /* m factor */
434     24, 2,                                      /* mux */
435     0,                                          /* gate */
436     AW_CLK_HAS_MUX);
437
438 static const char *ahb2_parents[] = {"ahb1", "pll_periph0"};
439 PREDIV_CLK(ahb2_clk, CLK_AHB2,                                  /* id */
440     "ahb2", ahb2_parents,                                       /* name, parents */
441     0x5c,                                                       /* offset */
442     0, 2,                                                       /* mux */
443     0, 0, 1, AW_CLK_FACTOR_FIXED,                               /* div */
444     0, 0, 2, AW_CLK_FACTOR_HAS_COND | AW_CLK_FACTOR_FIXED,      /* prediv */
445     0, 2, 1);                                                   /* prediv condition */
446
447 static const char *ths_parents[] = {"osc24M"};
448 static struct clk_div_table ths_div_table[] = {
449         { .value = 0, .divider = 1, },
450         { .value = 1, .divider = 2, },
451         { .value = 2, .divider = 4, },
452         { .value = 3, .divider = 6, },
453         { },
454 };
455 DIV_CLK(thsdiv_clk,
456     0,                          /* id */
457     "thsdiv", ths_parents,      /* name, parents */
458     0x74,                       /* offset */
459     0, 2,                       /* shift, width */
460     CLK_DIV_WITH_TABLE,         /* flags */
461     ths_div_table);             /* div table */
462
463 static const char *mod_parents[] = {"osc24M", "pll_periph0", "pll_periph1"};
464 NM_CLK(nand_clk,
465     CLK_NAND, "nand", mod_parents,              /* id, name, parents */
466     0x80,                                       /* offset */
467     16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO,       /* n factor */
468     0, 4, 0, 0,                                 /* m factor */
469     24, 2,                                      /* mux */
470     31,                                         /* gate */
471     AW_CLK_HAS_GATE | AW_CLK_HAS_MUX);          /* flags */
472
473 NM_CLK(mmc0_clk,
474     CLK_MMC0, "mmc0", mod_parents,              /* id, name, parents */
475     0x88,                                       /* offset */
476     16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO,       /* n factor */
477     0, 4, 0, 0,                                 /* m factor */
478     24, 2,                                      /* mux */
479     31,                                         /* gate */
480     AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
481     AW_CLK_REPARENT);                           /* flags */
482
483 NM_CLK(mmc1_clk,
484     CLK_MMC1, "mmc1", mod_parents,              /* id, name, parents */
485     0x8c,                                       /* offset */
486     16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO,       /* n factor */
487     0, 4, 0, 0,                                 /* m factor */
488     24, 2,                                      /* mux */
489     31,                                         /* gate */
490     AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
491     AW_CLK_REPARENT);                           /* flags */
492
493 NM_CLK(mmc2_clk,
494     CLK_MMC2, "mmc2", mod_parents,              /* id, name, parents */
495     0x90,                                       /* offset */
496     16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO,       /* n factor */
497     0, 4, 0, 0,                                 /* m factor */
498     24, 2,                                      /* mux */
499     31,                                         /* gate */
500     AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
501     AW_CLK_REPARENT);                           /* flags */
502
503 static const char *ts_parents[] = {"osc24M", "pll_periph0"};
504 NM_CLK(ts_clk,
505     CLK_TS, "ts", ts_parents,                   /* id, name, parents */
506     0x98,                                       /* offset */
507     16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO,       /* n factor */
508     0, 4, 0, 0,                                 /* m factor */
509     24, 2,                                      /* mux */
510     31,                                         /* gate */
511     AW_CLK_HAS_GATE | AW_CLK_HAS_MUX);          /* flags */
512
513 NM_CLK(ce_clk,
514     CLK_CE, "ce", mod_parents,                  /* id, name, parents */
515     0x9C,                                       /* offset */
516     16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO,       /* n factor */
517     0, 4, 0, 0,                                 /* m factor */
518     24, 2,                                      /* mux */
519     31,                                         /* gate */
520     AW_CLK_HAS_GATE | AW_CLK_HAS_MUX);          /* flags */
521
522 NM_CLK(spi0_clk,
523     CLK_SPI0, "spi0", mod_parents,              /* id, name, parents */
524     0xA0,                                       /* offset */
525     16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO,       /* n factor */
526     0, 4, 0, 0,                                 /* m factor */
527     24, 2,                                      /* mux */
528     31,                                         /* gate */
529     AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
530     AW_CLK_REPARENT);                           /* flags */
531
532 NM_CLK(spi1_clk,
533     CLK_SPI1, "spi1", mod_parents,              /* id, name, parents */
534     0xA4,                                       /* offset */
535     16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO,       /* n factor */
536     0, 4, 0, 0,                                 /* m factor */
537     24, 2,                                      /* mux */
538     31,                                         /* gate */
539     AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
540     AW_CLK_REPARENT);                           /* flags */
541
542 static const char *i2s_parents[] = {"pll_audio-8x", "pll_audio-4x", "pll_audio-2x", "pll_audio"};
543 MUX_CLK(i2s0mux_clk,
544     0, "i2s0mux", i2s_parents,                  /* id, name, parents */
545     0xb0, 16, 2);                               /* offset, mux shift, mux width */
546 MUX_CLK(i2s1mux_clk,
547     0, "i2s1mux", i2s_parents,                  /* id, name, parents */
548     0xb4, 16, 2);                               /* offset, mux shift, mux width */
549 MUX_CLK(i2s2mux_clk,
550     0, "i2s2mux", i2s_parents,                  /* id, name, parents */
551     0xb8, 16, 2);                               /* offset, mux shift, mux width */
552
553 static const char *spdif_parents[] = {"pll_audio"};
554 NM_CLK(spdif_clk,
555     CLK_SPDIF, "spdif", spdif_parents,          /* id, name, parents */
556     0xC0,                                       /* offset */
557     0, 0, 1, AW_CLK_FACTOR_FIXED,               /* n factor (fake); */
558     0, 4, 0, 0,                                 /* m factor */
559     0, 0,                                       /* mux */
560     31,                                         /* gate */
561     AW_CLK_HAS_GATE);                           /* flags */
562
563 static const char *dram_parents[] = {"pll_ddr", "pll_periph0-2x"};
564 NM_CLK(dram_clk,
565     CLK_DRAM, "dram", dram_parents,             /* id, name, parents */
566     0xF4,                                       /* offset */
567     0, 0, 1, AW_CLK_FACTOR_FIXED,               /* n factor (fake) */
568     0, 4, 0, 0,                                 /* m factor */
569     20, 2,                                      /* mux */
570     0,                                          /* gate */
571     AW_CLK_HAS_MUX);                            /* flags */
572
573 static const char *de_parents[] = {"pll_periph0-2x", "pll_de"};
574 NM_CLK(de_clk,
575     CLK_DE, "de", de_parents,                   /* id, name, parents */
576     0x104,                                      /* offset */
577     0, 0, 1, AW_CLK_FACTOR_FIXED,               /* n factor (fake) */
578     0, 4, 0, 0,                                 /* m factor */
579     24, 2,                                      /* mux */
580     31,                                         /* gate */
581     AW_CLK_HAS_MUX | AW_CLK_HAS_GATE);          /* flags */
582
583 static const char *tcon0_parents[] = {"pll_video"};
584 NM_CLK(tcon0_clk,
585     CLK_TCON0, "tcon0", tcon0_parents,          /* id, name, parents */
586     0x118,                                      /* offset */
587     0, 0, 1, AW_CLK_FACTOR_FIXED,               /* n factor (fake) */
588     0, 4, 0, 0,                                 /* m factor */
589     24, 2,                                      /* mux */
590     31,                                         /* gate */
591     AW_CLK_HAS_MUX | AW_CLK_HAS_GATE);          /* flags */
592
593 static const char *tve_parents[] = {"pll_de", "pll_periph1"};
594 NM_CLK(tve_clk,
595     CLK_TVE, "tve", tve_parents,                /* id, name, parents */
596     0x120,                                      /* offset */
597     0, 0, 1, AW_CLK_FACTOR_FIXED,               /* n factor (fake) */
598     0, 4, 0, 0,                                 /* m factor */
599     24, 2,                                      /* mux */
600     31,                                         /* gate */
601     AW_CLK_HAS_MUX | AW_CLK_HAS_GATE);          /* flags */
602
603 static const char *deinterlace_parents[] = {"pll_periph0", "pll_periph1"};
604 NM_CLK(deinterlace_clk,
605     CLK_DEINTERLACE, "deinterlace", deinterlace_parents,        /* id, name, parents */
606     0x124,                                      /* offset */
607     0, 0, 1, AW_CLK_FACTOR_FIXED,               /* n factor (fake) */
608     0, 4, 0, 0,                                 /* m factor */
609     24, 2,                                      /* mux */
610     31,                                         /* gate */
611     AW_CLK_HAS_MUX | AW_CLK_HAS_GATE);          /* flags */
612
613 static const char *csi_sclk_parents[] = {"pll_periph0", "pll_periph1"};
614 NM_CLK(csi_sclk_clk,
615     CLK_CSI_SCLK, "csi-sclk", csi_sclk_parents, /* id, name, parents */
616     0x134,                                      /* offset */
617     0, 0, 1, AW_CLK_FACTOR_FIXED,               /* n factor (fake) */
618     16, 4, 0, 0,                                /* m factor */
619     24, 2,                                      /* mux */
620     31,                                         /* gate */
621     AW_CLK_HAS_MUX | AW_CLK_HAS_GATE);          /* flags */
622
623 static const char *csi_mclk_parents[] = {"osc24M", "pll_video", "pll_periph1"};
624 NM_CLK(csi_mclk_clk,
625     CLK_CSI_MCLK, "csi-mclk", csi_mclk_parents, /* id, name, parents */
626     0x134,                                      /* offset */
627     0, 0, 1, AW_CLK_FACTOR_FIXED,               /* n factor (fake) */
628     0, 4, 0, 0,                                 /* m factor */
629     8, 2,                                       /* mux */
630     15,                                         /* gate */
631     AW_CLK_HAS_MUX | AW_CLK_HAS_GATE);          /* flags */
632
633 static const char *ve_parents[] = {"pll_ve"};
634 NM_CLK(ve_clk,
635     CLK_VE, "ve", ve_parents,                   /* id, name, parents */
636     0x13C,                                      /* offset */
637     16, 3, 0, 0,                                /* n factor */
638     0, 0, 1, AW_CLK_FACTOR_FIXED,               /* m factor (fake) */
639     0, 0,                                       /* mux */
640     31,                                         /* gate */
641     AW_CLK_HAS_GATE);                           /* flags */
642
643 static const char *hdmi_parents[] = {"pll_video"};
644 NM_CLK(hdmi_clk,
645     CLK_HDMI, "hdmi", hdmi_parents,             /* id, name, parents */
646     0x150,                                      /* offset */
647     0, 0, 1, AW_CLK_FACTOR_FIXED,               /* n factor (fake) */
648     0, 4, 0, 0,                                 /* m factor */
649     24, 2,                                      /* mux */
650     31,                                         /* gate */
651     AW_CLK_HAS_MUX | AW_CLK_HAS_GATE);          /* flags */
652
653 static const char *mbus_parents[] = {"osc24M", "pll_periph0-2x", "pll_ddr"};
654 NM_CLK(mbus_clk,
655     CLK_MBUS, "mbus", mbus_parents,             /* id, name, parents */
656     0x15C,                                      /* offset */
657     0, 0, 1, AW_CLK_FACTOR_FIXED,               /* n factor (fake) */
658     0, 3, 0, 0,                                 /* m factor */
659     24, 2,                                      /* mux */
660     31,                                         /* gate */
661     AW_CLK_HAS_MUX | AW_CLK_HAS_GATE);          /* flags */
662
663 static const char *gpu_parents[] = {"pll_gpu"};
664 NM_CLK(gpu_clk,
665     CLK_GPU, "gpu", gpu_parents,                /* id, name, parents */
666     0x1A0,                                      /* offset */
667     0, 2, 0, 0,                                 /* n factor */
668     0, 0, 1, AW_CLK_FACTOR_FIXED,               /* m factor (fake) */
669     0, 0,                                       /* mux */
670     31,                                         /* gate */
671     AW_CLK_HAS_GATE);                           /* flags */
672
673 static struct aw_clk_nkmp_def *nkmp_clks[] = {
674         &pll_cpux_clk,
675         &pll_audio_clk,
676         &pll_periph0_clk,
677         &pll_periph1_clk,
678         &pll_ddr_clk,
679 };
680
681 static struct aw_clk_nm_def *nm_clks[] = {
682         &pll_video_clk,
683         &pll_ve_clk,
684         &pll_gpu_clk,
685         &pll_de_clk,
686         &apb2_clk,
687         &nand_clk,
688         &mmc0_clk,
689         &mmc1_clk,
690         &mmc2_clk,
691         &ts_clk,
692         &ce_clk,
693         &spi0_clk,
694         &spi1_clk,
695         &spdif_clk,
696         &dram_clk,
697         &de_clk,
698         &tcon0_clk,
699         &tve_clk,
700         &deinterlace_clk,
701         &csi_sclk_clk,
702         &csi_mclk_clk,
703         &ve_clk,
704         &hdmi_clk,
705         &mbus_clk,
706         &gpu_clk,
707 };
708
709 static struct aw_clk_prediv_mux_def *prediv_mux_clks[] = {
710         &ahb1_clk,
711         &ahb2_clk,
712 };
713
714 static struct clk_mux_def *mux_clks[] = {
715         &cpux_clk,
716         &i2s0mux_clk,
717         &i2s1mux_clk,
718         &i2s2mux_clk,
719 };
720
721 static struct clk_div_def *div_clks[] = {
722         &axi_clk,
723         &apb1_clk,
724         &thsdiv_clk,
725 };
726
727 static struct clk_fixed_def *fixed_factor_clks[] = {
728         &pll_periph0_2x_clk,
729         &pll_audio_2x_clk,
730         &pll_audio_4x_clk,
731         &pll_audio_8x_clk,
732 };
733
734 static struct aw_clk_init init_clks[] = {
735         {"ahb1", "pll_periph0", 0, false},
736         {"ahb2", "pll_periph0", 0, false},
737         {"dram", "pll_ddr", 0, false},
738 };
739
740 void
741 ccu_h3_register_clocks(struct aw_ccung_softc *sc)
742 {
743         int i;
744
745         sc->resets = h3_ccu_resets;
746         sc->nresets = nitems(h3_ccu_resets);
747         sc->gates = h3_ccu_gates;
748         sc->ngates = nitems(h3_ccu_gates);
749         sc->clk_init = init_clks;
750         sc->n_clk_init = nitems(init_clks);
751
752         for (i = 0; i < nitems(nkmp_clks); i++)
753                 aw_clk_nkmp_register(sc->clkdom, nkmp_clks[i]);
754         for (i = 0; i < nitems(nm_clks); i++)
755                 aw_clk_nm_register(sc->clkdom, nm_clks[i]);
756         for (i = 0; i < nitems(prediv_mux_clks); i++)
757                 aw_clk_prediv_mux_register(sc->clkdom, prediv_mux_clks[i]);
758
759         for (i = 0; i < nitems(mux_clks); i++)
760                 clknode_mux_register(sc->clkdom, mux_clks[i]);
761         for (i = 0; i < nitems(div_clks); i++)
762                 clknode_div_register(sc->clkdom, div_clks[i]);
763         for (i = 0; i < nitems(fixed_factor_clks); i++)
764                 clknode_fixed_register(sc->clkdom, fixed_factor_clks[i]);
765 }