xref: /freebsd/sys/dev/clk/allwinner/ccu_a31.c (revision a91a2465)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2017,2018 Emmanuel Vadot <manu@freebsd.org>
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
22  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #include <sys/param.h>
29 #include <sys/systm.h>
30 #include <sys/bus.h>
31 #include <sys/rman.h>
32 #include <sys/kernel.h>
33 #include <sys/module.h>
34 #include <machine/bus.h>
35 
36 #include <dev/fdt/simplebus.h>
37 
38 #include <dev/ofw/ofw_bus.h>
39 #include <dev/ofw/ofw_bus_subr.h>
40 
41 #include <dev/clk/clk_div.h>
42 #include <dev/clk/clk_fixed.h>
43 #include <dev/clk/clk_mux.h>
44 
45 #include <dev/clk/allwinner/aw_ccung.h>
46 
47 #include <dt-bindings/clock/sun6i-a31-ccu.h>
48 #include <dt-bindings/reset/sun6i-a31-ccu.h>
49 
50 /* Non-exported clocks */
51 #define	CLK_PLL_CPU			0
52 #define	CLK_PLL_AUDIO_BASE		1
53 #define	CLK_PLL_AUDIO			2
54 #define	CLK_PLL_AUDIO_2X		3
55 #define	CLK_PLL_AUDIO_4X		4
56 #define	CLK_PLL_AUDIO_8X		5
57 #define	CLK_PLL_VIDEO0			6
58 #define	CLK_PLL_VIDEO0_2X		7
59 #define	CLK_PLL_VE			8
60 #define	CLK_PLL_DDR			9
61 
62 #define	CLK_PLL_PERIPH_2X		11
63 #define	CLK_PLL_VIDEO1			12
64 #define	CLK_PLL_VIDEO1_2X		13
65 #define	CLK_PLL_GPU			14
66 #define	CLK_PLL_MIPI			15
67 #define	CLK_PLL9			16
68 #define	CLK_PLL10			17
69 
70 #define	CLK_AXI				19
71 #define	CLK_AHB1			20
72 #define	CLK_APB1			21
73 #define	CLK_APB2			22
74 
75 #define	CLK_MDFS			107
76 #define	CLK_SDRAM0			108
77 #define	CLK_SDRAM1			109
78 
79 #define	CLK_MBUS0			141
80 #define	CLK_MBUS1			142
81 
82 static struct aw_ccung_reset a31_ccu_resets[] = {
83 	CCU_RESET(RST_USB_PHY0, 0xcc, 0)
84 	CCU_RESET(RST_USB_PHY1, 0xcc, 1)
85 	CCU_RESET(RST_USB_PHY2, 0xcc, 2)
86 
87 	CCU_RESET(RST_AHB1_MIPI_DSI, 0x2c0, 1)
88 	CCU_RESET(RST_AHB1_SS, 0x2c0, 5)
89 	CCU_RESET(RST_AHB1_DMA, 0x2c0, 6)
90 	CCU_RESET(RST_AHB1_MMC0, 0x2c0, 8)
91 	CCU_RESET(RST_AHB1_MMC1, 0x2c0, 9)
92 	CCU_RESET(RST_AHB1_MMC2, 0x2c0, 10)
93 	CCU_RESET(RST_AHB1_MMC3, 0x2c0, 11)
94 	CCU_RESET(RST_AHB1_NAND1, 0x2c0, 12)
95 	CCU_RESET(RST_AHB1_NAND0, 0x2c0, 13)
96 	CCU_RESET(RST_AHB1_SDRAM, 0x2c0, 14)
97 	CCU_RESET(RST_AHB1_EMAC, 0x2c0, 17)
98 	CCU_RESET(RST_AHB1_TS, 0x2c0, 18)
99 	CCU_RESET(RST_AHB1_HSTIMER, 0x2c0, 19)
100 	CCU_RESET(RST_AHB1_SPI0, 0x2c0, 20)
101 	CCU_RESET(RST_AHB1_SPI1, 0x2c0, 21)
102 	CCU_RESET(RST_AHB1_SPI2, 0x2c0, 22)
103 	CCU_RESET(RST_AHB1_SPI3, 0x2c0, 23)
104 	CCU_RESET(RST_AHB1_OTG, 0x2c0, 24)
105 	CCU_RESET(RST_AHB1_EHCI0, 0x2c0, 26)
106 	CCU_RESET(RST_AHB1_EHCI1, 0x2c0, 27)
107 	CCU_RESET(RST_AHB1_OHCI0, 0x2c0, 29)
108 	CCU_RESET(RST_AHB1_OHCI1, 0x2c0, 30)
109 	CCU_RESET(RST_AHB1_OHCI2, 0x2c0, 31)
110 
111 	CCU_RESET(RST_AHB1_VE, 0x2c4, 0)
112 	CCU_RESET(RST_AHB1_LCD0, 0x2c4, 4)
113 	CCU_RESET(RST_AHB1_LCD1, 0x2c4, 5)
114 	CCU_RESET(RST_AHB1_CSI, 0x2c4, 8)
115 	CCU_RESET(RST_AHB1_HDMI, 0x2c4, 11)
116 	CCU_RESET(RST_AHB1_BE0, 0x2c4, 12)
117 	CCU_RESET(RST_AHB1_BE1, 0x2c4, 13)
118 	CCU_RESET(RST_AHB1_FE0, 0x2c4, 14)
119 	CCU_RESET(RST_AHB1_FE1, 0x2c4, 15)
120 	CCU_RESET(RST_AHB1_MP, 0x2c4, 18)
121 	CCU_RESET(RST_AHB1_GPU, 0x2c4, 20)
122 	CCU_RESET(RST_AHB1_DEU0, 0x2c4, 23)
123 	CCU_RESET(RST_AHB1_DEU1, 0x2c4, 24)
124 	CCU_RESET(RST_AHB1_DRC0, 0x2c4, 25)
125 	CCU_RESET(RST_AHB1_DRC1, 0x2c4, 26)
126 
127 	CCU_RESET(RST_AHB1_LVDS, 0x2c8, 0)
128 
129 	CCU_RESET(RST_APB1_CODEC, 0x2d0, 0)
130 	CCU_RESET(RST_APB1_SPDIF, 0x2d0, 1)
131 	CCU_RESET(RST_APB1_DIGITAL_MIC, 0x2d0, 4)
132 	CCU_RESET(RST_APB1_DAUDIO0, 0x2d0, 12)
133 	CCU_RESET(RST_APB1_DAUDIO1, 0x2d0, 13)
134 
135 	CCU_RESET(RST_APB2_I2C0, 0x2d8, 0)
136 	CCU_RESET(RST_APB2_I2C1, 0x2d8, 1)
137 	CCU_RESET(RST_APB2_I2C2, 0x2d8, 2)
138 	CCU_RESET(RST_APB2_I2C3, 0x2d8, 3)
139 	CCU_RESET(RST_APB2_UART0, 0x2d8, 16)
140 	CCU_RESET(RST_APB2_UART1, 0x2d8, 17)
141 	CCU_RESET(RST_APB2_UART2, 0x2d8, 18)
142 	CCU_RESET(RST_APB2_UART3, 0x2d8, 19)
143 	CCU_RESET(RST_APB2_UART4, 0x2d8, 20)
144 	CCU_RESET(RST_APB2_UART5, 0x2d8, 21)
145 };
146 
147 static struct aw_ccung_gate a31_ccu_gates[] = {
148 	CCU_GATE(CLK_AHB1_MIPIDSI, "ahb1-mipidsi", "ahb1", 0x60, 1)
149 	CCU_GATE(CLK_AHB1_SS, "ahb1-ss", "ahb1", 0x60, 5)
150 	CCU_GATE(CLK_AHB1_DMA, "ahb1-dma", "ahb1", 0x60, 6)
151 	CCU_GATE(CLK_AHB1_MMC0, "ahb1-mmc0", "ahb1", 0x60, 8)
152 	CCU_GATE(CLK_AHB1_MMC1, "ahb1-mmc1", "ahb1", 0x60, 9)
153 	CCU_GATE(CLK_AHB1_MMC2, "ahb1-mmc2", "ahb1", 0x60, 10)
154 	CCU_GATE(CLK_AHB1_MMC3, "ahb1-mmc3", "ahb1", 0x60, 11)
155 	CCU_GATE(CLK_AHB1_NAND1, "ahb1-nand1", "ahb1", 0x60, 12)
156 	CCU_GATE(CLK_AHB1_NAND0, "ahb1-nand0", "ahb1", 0x60, 13)
157 	CCU_GATE(CLK_AHB1_SDRAM, "ahb1-sdram", "ahb1", 0x60, 14)
158 	CCU_GATE(CLK_AHB1_EMAC, "ahb1-emac", "ahb1", 0x60, 17)
159 	CCU_GATE(CLK_AHB1_TS, "ahb1-ts", "ahb1", 0x60, 18)
160 	CCU_GATE(CLK_AHB1_HSTIMER, "ahb1-hstimer", "ahb1", 0x60, 19)
161 	CCU_GATE(CLK_AHB1_SPI0, "ahb1-spi0", "ahb1", 0x60, 20)
162 	CCU_GATE(CLK_AHB1_SPI1, "ahb1-spi1", "ahb1", 0x60, 21)
163 	CCU_GATE(CLK_AHB1_SPI2, "ahb1-spi2", "ahb1", 0x60, 22)
164 	CCU_GATE(CLK_AHB1_SPI3, "ahb1-spi3", "ahb1", 0x60, 23)
165 	CCU_GATE(CLK_AHB1_OTG, "ahb1-otg", "ahb1", 0x60, 24)
166 	CCU_GATE(CLK_AHB1_EHCI0, "ahb1-ehci0", "ahb1", 0x60, 26)
167 	CCU_GATE(CLK_AHB1_EHCI1, "ahb1-ehci1", "ahb1", 0x60, 27)
168 	CCU_GATE(CLK_AHB1_OHCI0, "ahb1-ohci0", "ahb1", 0x60, 29)
169 	CCU_GATE(CLK_AHB1_OHCI1, "ahb1-ohci1", "ahb1", 0x60, 30)
170 	CCU_GATE(CLK_AHB1_OHCI2, "ahb1-ohci2", "ahb1", 0x60, 31)
171 	CCU_GATE(CLK_AHB1_VE, "ahb1-ve", "ahb1", 0x64, 0)
172 	CCU_GATE(CLK_AHB1_LCD0, "ahb1-lcd0", "ahb1", 0x64, 4)
173 	CCU_GATE(CLK_AHB1_LCD1, "ahb1-lcd1", "ahb1", 0x64, 5)
174 	CCU_GATE(CLK_AHB1_CSI, "ahb1-csi", "ahb1", 0x64, 8)
175 	CCU_GATE(CLK_AHB1_HDMI, "ahb1-hdmi", "ahb1", 0x64, 11)
176 	CCU_GATE(CLK_AHB1_BE0, "ahb1-be0", "ahb1", 0x64, 12)
177 	CCU_GATE(CLK_AHB1_BE1, "ahb1-be1", "ahb1", 0x64, 13)
178 	CCU_GATE(CLK_AHB1_FE0, "ahb1-fe0", "ahb1", 0x64, 14)
179 	CCU_GATE(CLK_AHB1_FE1, "ahb1-fe1", "ahb1", 0x64, 15)
180 	CCU_GATE(CLK_AHB1_MP, "ahb1-mp", "ahb1", 0x64, 18)
181 	CCU_GATE(CLK_AHB1_GPU, "ahb1-gpu", "ahb1", 0x64, 20)
182 	CCU_GATE(CLK_AHB1_DEU0, "ahb1-deu0", "ahb1", 0x64, 23)
183 	CCU_GATE(CLK_AHB1_DEU1, "ahb1-deu1", "ahb1", 0x64, 24)
184 	CCU_GATE(CLK_AHB1_DRC0, "ahb1-drc0", "ahb1", 0x64, 25)
185 	CCU_GATE(CLK_AHB1_DRC1, "ahb1-drc1", "ahb1", 0x64, 26)
186 
187 	CCU_GATE(CLK_APB1_CODEC, "apb1-codec", "apb1", 0x68, 0)
188 	CCU_GATE(CLK_APB1_SPDIF, "apb1-spdif", "apb1", 0x68, 1)
189 	CCU_GATE(CLK_APB1_DIGITAL_MIC, "apb1-digital-mic", "apb1", 0x68, 4)
190 	CCU_GATE(CLK_APB1_PIO, "apb1-pio", "apb1", 0x68, 5)
191 	CCU_GATE(CLK_APB1_DAUDIO0, "apb1-daudio0", "apb1", 0x68, 12)
192 	CCU_GATE(CLK_APB1_DAUDIO1, "apb1-daudio1", "apb1", 0x68, 13)
193 
194 	CCU_GATE(CLK_APB2_I2C0, "apb2-i2c0", "apb2", 0x6c, 0)
195 	CCU_GATE(CLK_APB2_I2C1, "apb2-i2c1", "apb2", 0x6c, 1)
196 	CCU_GATE(CLK_APB2_I2C2, "apb2-i2c2", "apb2", 0x6c, 2)
197 	CCU_GATE(CLK_APB2_I2C3, "apb2-i2c3", "apb2", 0x6c, 3)
198 	CCU_GATE(CLK_APB2_UART0, "apb2-uart0", "apb2", 0x6c, 16)
199 	CCU_GATE(CLK_APB2_UART1, "apb2-uart1", "apb2", 0x6c, 17)
200 	CCU_GATE(CLK_APB2_UART2, "apb2-uart2", "apb2", 0x6c, 18)
201 	CCU_GATE(CLK_APB2_UART3, "apb2-uart3", "apb2", 0x6c, 19)
202 	CCU_GATE(CLK_APB2_UART4, "apb2-uart4", "apb2", 0x6c, 20)
203 	CCU_GATE(CLK_APB2_UART5, "apb2-uart5", "apb2", 0x6c, 21)
204 
205 	CCU_GATE(CLK_DAUDIO0, "daudio0", "daudio0mux", 0xb0, 31)
206 	CCU_GATE(CLK_DAUDIO1, "daudio1", "daudio1mux", 0xb4, 31)
207 
208 	CCU_GATE(CLK_USB_PHY0, "usb-phy0", "osc24M", 0xcc, 8)
209 	CCU_GATE(CLK_USB_PHY1, "usb-phy1", "osc24M", 0xcc, 9)
210 	CCU_GATE(CLK_USB_PHY2, "usb-phy2", "osc24M", 0xcc, 10)
211 	CCU_GATE(CLK_USB_OHCI0, "usb-ohci0", "osc24M", 0xcc, 16)
212 	CCU_GATE(CLK_USB_OHCI1, "usb-ohci1", "osc24M", 0xcc, 17)
213 	CCU_GATE(CLK_USB_OHCI2, "usb-ohci2", "osc24M", 0xcc, 18)
214 
215 	CCU_GATE(CLK_DRAM_VE, "dram-ve", "mdfs", 0x100, 0)
216 	CCU_GATE(CLK_DRAM_CSI_ISP, "dram-csi_isp", "mdfs", 0x100, 1)
217 	CCU_GATE(CLK_DRAM_TS, "dram-ts", "mdfs", 0x100, 3)
218 	CCU_GATE(CLK_DRAM_DRC0, "dram-drc0", "mdfs", 0x100, 16)
219 	CCU_GATE(CLK_DRAM_DRC1, "dram-drc1", "mdfs", 0x100, 17)
220 	CCU_GATE(CLK_DRAM_DEU0, "dram-deu0", "mdfs", 0x100, 18)
221 	CCU_GATE(CLK_DRAM_DEU1, "dram-deu1", "mdfs", 0x100, 19)
222 	CCU_GATE(CLK_DRAM_FE0, "dram-fe0", "mdfs", 0x100, 24)
223 	CCU_GATE(CLK_DRAM_FE1, "dram-fe1", "mdfs", 0x100, 25)
224 	CCU_GATE(CLK_DRAM_BE0, "dram-be0", "mdfs", 0x100, 26)
225 	CCU_GATE(CLK_DRAM_BE1, "dram-be1", "mdfs", 0x100, 27)
226 	CCU_GATE(CLK_DRAM_MP, "dram-mp", "mdfs", 0x100, 28)
227 
228 	CCU_GATE(CLK_CODEC, "codec", "pll_audio", 0x140, 31)
229 
230 	CCU_GATE(CLK_AVS, "avs", "pll_audio", 0x144, 31)
231 
232 	CCU_GATE(CLK_DIGITAL_MIC, "digital-mic", "pll_audio", 0x148, 31)
233 
234 	CCU_GATE(CLK_HDMI_DDC, "hdmi-ddc", "osc24M", 0x150, 30)
235 
236 	CCU_GATE(CLK_PS, "ps", "lcd1_ch1", 0x154, 31)
237 };
238 
239 static const char *pll_parents[] = {"osc24M"};
240 
241 NKMP_CLK(pll_cpu_clk,
242     CLK_PLL_CPU,			/* id */
243     "pll_cpu", pll_parents,			/* name, parents */
244     0x00,					/* offset */
245     8, 5, 0, 0,					/* n factor */
246     4, 2, 0, 0,					/* k factor */
247     0, 2, 0, 0,					/* m factor */
248     0, 0, 1, AW_CLK_FACTOR_FIXED,		/* p factor (fake) */
249     31,						/* gate */
250     28, 1000,					/* lock */
251     AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK | AW_CLK_SCALE_CHANGE);		/* flags */
252 
253 NKMP_CLK(pll_audio_clk,
254     CLK_PLL_AUDIO,			/* id */
255     "pll_audio", pll_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, 4, 1, 0,					/* m factor */
260     16, 3, 1, 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 FRAC_CLK(pll_video0_clk,
292     CLK_PLL_VIDEO0,				/* id */
293     "pll_video0", pll_parents,		/* name, parents */
294     0x10,					/* offset */
295     8, 7, 0, 0,					/* n factor */
296     0, 4, 0, 0,					/* m factor */
297     31, 28, 1000,				/* gate, lock, lock retries */
298     AW_CLK_HAS_LOCK,				/* flags */
299     270000000, 297000000,			/* freq0, freq1 */
300     24, 25,					/* mode sel, freq sel */
301     30000000, 600000000);			/* min freq, max freq */
302 static const char *pll_video0_2x_parents[] = {"pll_video0"};
303 FIXED_CLK(pll_video0_2x_clk,
304     CLK_PLL_VIDEO0_2X,		/* id */
305     "pll_video0-2x",			/* name */
306     pll_video0_2x_parents,		/* parent */
307     0,					/* freq */
308     2,					/* mult */
309     1,					/* div */
310     0);					/* flags */
311 
312 FRAC_CLK(pll_ve_clk,
313     CLK_PLL_VE,				/* id */
314     "pll_ve", pll_parents,			/* name, parents */
315     0x18,					/* offset */
316     8, 7, 0, 0,					/* n factor */
317     0, 4, 0, 0,					/* m factor */
318     31, 28, 1000,				/* gate, lock, lock retries */
319     AW_CLK_HAS_LOCK,				/* flags */
320     270000000, 297000000,			/* freq0, freq1 */
321     24, 25,					/* mode sel, freq sel */
322     30000000, 600000000);			/* min freq, max freq */
323 
324 NKMP_CLK_WITH_UPDATE(pll_ddr_clk,
325     CLK_PLL_DDR,				/* id */
326     "pll_ddr", pll_parents,			/* name, parents */
327     0x20,					/* offset */
328     8, 5, 0, 0,					/* n factor */
329     4, 2, 0, 0,					/* k factor */
330     0, 2, 0, 0,					/* m factor */
331     0, 0, 1, AW_CLK_FACTOR_FIXED,		/* p factor (fake) */
332     31,						/* gate */
333     28, 1000,					/* lock */
334     20,						/* update */
335     AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK);		/* flags */
336 
337 NKMP_CLK(pll_periph_clk,
338     CLK_PLL_PERIPH,			/* id */
339     "pll_periph", pll_parents,		/* name, parents */
340     0x28,					/* offset */
341     8, 4, 0, 0,					/* n factor */
342     5, 2, 1, 0,					/* k factor */
343     0, 0, 1, AW_CLK_FACTOR_FIXED,		/* m factor (fake) */
344     0, 0, 1, AW_CLK_FACTOR_FIXED,		/* p factor (fake) */
345     31,						/* gate */
346     28, 1000,					/* lock */
347     AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK);		/* flags */
348 
349 static const char *pll_periph_2x_parents[] = {"pll_periph"};
350 FIXED_CLK(pll_periph_2x_clk,
351     CLK_PLL_PERIPH_2X,	/* id */
352     "pll_periph-2x",			/* name */
353     pll_periph_2x_parents,		/* parent */
354     0,					/* freq */
355     2,					/* mult */
356     1,					/* div */
357     0);					/* flags */
358 
359 FRAC_CLK(pll_video1_clk,
360     CLK_PLL_VIDEO1,				/* id */
361     "pll_video1", pll_parents,		/* name, parents */
362     0x30,					/* offset */
363     8, 7, 0, 0,					/* n factor */
364     0, 4, 0, 0,					/* m factor */
365     31, 28, 1000,				/* gate, lock, lock retries */
366     AW_CLK_HAS_LOCK,				/* flags */
367     270000000, 297000000,			/* freq0, freq1 */
368     24, 25,					/* mode sel, freq sel */
369     30000000, 600000000);			/* min freq, max freq */
370 
371 static const char *pll_video1_2x_parents[] = {"pll_video1"};
372 FIXED_CLK(pll_video1_2x_clk,
373     CLK_PLL_VIDEO1_2X,		/* id */
374     "pll_video1-2x",			/* name */
375     pll_video1_2x_parents,		/* parent */
376     0,					/* freq */
377     2,					/* mult */
378     1,					/* div */
379     0);					/* flags */
380 
381 FRAC_CLK(pll_gpu_clk,
382     CLK_PLL_GPU,				/* id */
383     "pll_gpu", pll_parents,		/* name, parents */
384     0x38,					/* offset */
385     8, 7, 0, 0,					/* n factor */
386     0, 4, 0, 0,					/* m factor */
387     31, 28, 1000,				/* gate, lock, lock retries */
388     AW_CLK_HAS_LOCK,				/* flags */
389     270000000, 297000000,			/* freq0, freq1 */
390     24, 25,					/* mode sel, freq sel */
391     30000000, 600000000);			/* min freq, max freq */
392 
393 static const char *pll_mipi_parents[] = {"pll_video0", "pll_video1"};
394 NKMP_CLK(pll_mipi_clk,
395     CLK_PLL_MIPI,			/* id */
396     "pll_mipi", pll_mipi_parents,		/* name, parents */
397     0x40,					/* offset */
398     8, 4, 0, 0,					/* n factor */
399     4, 2, 1, 0,					/* k factor */
400     0, 2, 0, 0,					/* m factor (fake) */
401     0, 0, 1, AW_CLK_FACTOR_FIXED,		/* p factor (fake) */
402     31,						/* gate */
403     28, 1000,					/* lock */
404     AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK);		/* flags */
405 
406 FRAC_CLK(pll9_clk,
407     CLK_PLL9,				/* id */
408     "pll9", pll_parents,		/* name, parents */
409     0x44,					/* offset */
410     8, 7, 0, 0,					/* n factor */
411     0, 4, 0, 0,					/* m factor */
412     31, 28, 1000,				/* gate, lock, lock retries */
413     AW_CLK_HAS_LOCK,				/* flags */
414     270000000, 297000000,			/* freq0, freq1 */
415     24, 25,					/* mode sel, freq sel */
416     30000000, 600000000);			/* min freq, max freq */
417 
418 FRAC_CLK(pll10_clk,
419     CLK_PLL10,				/* id */
420     "pll10", pll_parents,		/* name, parents */
421     0x48,					/* offset */
422     8, 7, 0, 0,					/* n factor */
423     0, 4, 0, 0,					/* m factor */
424     31, 28, 1000,				/* gate, lock, lock retries */
425     AW_CLK_HAS_LOCK,				/* flags */
426     270000000, 297000000,			/* freq0, freq1 */
427     24, 25,					/* mode sel, freq sel */
428     30000000, 600000000);			/* min freq, max freq */
429 
430 static struct clk_div_table axi_div_table[] = {
431 	{ .value = 0, .divider = 1, },
432 	{ .value = 1, .divider = 2, },
433 	{ .value = 2, .divider = 3, },
434 	{ .value = 3, .divider = 4, },
435 	{ .value = 4, .divider = 4, },
436 	{ .value = 5, .divider = 4, },
437 	{ .value = 6, .divider = 4, },
438 	{ .value = 7, .divider = 4, },
439 	{ },
440 };
441 static const char *axi_parents[] = {"cpu"};
442 DIV_CLK(axi_clk,
443     CLK_AXI,		/* id */
444     "axi", axi_parents,		/* name, parents */
445     0x50,			/* offset */
446     0, 2,			/* shift, mask */
447     0, axi_div_table);		/* flags, div table */
448 
449 static const char *cpu_parents[] = {"osc32k", "osc24M", "pll_cpu", "pll_cpu"};
450 MUX_CLK(cpu_clk,
451     CLK_CPU,		/* id */
452     "cpu", cpu_parents,		/* name, parents */
453     0x50, 16, 2);		/* offset, shift, width */
454 
455 static const char *ahb1_parents[] = {"osc32k", "osc24M", "axi", "pll_periph"};
456 PREDIV_CLK(ahb1_clk,
457     CLK_AHB1,					/* id */
458     "ahb1", ahb1_parents,					/* name, parents */
459     0x54,							/* offset */
460     12, 2,							/* mux */
461     4, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO,			/* div */
462     6, 2, 0, AW_CLK_FACTOR_HAS_COND,				/* prediv */
463     12, 2, 3);							/* prediv condition */
464 
465 static const char *apb1_parents[] = {"ahb1"};
466 static struct clk_div_table apb1_div_table[] = {
467 	{ .value = 0, .divider = 2, },
468 	{ .value = 1, .divider = 2, },
469 	{ .value = 2, .divider = 4, },
470 	{ .value = 3, .divider = 8, },
471 	{ },
472 };
473 DIV_CLK(apb1_clk,
474     CLK_APB1,		/* id */
475     "apb1", apb1_parents,	/* name, parents */
476     0x54,			/* offset */
477     8, 2,			/* shift, mask */
478     CLK_DIV_WITH_TABLE,		/* flags */
479     apb1_div_table);		/* div table */
480 
481 static const char *apb2_parents[] = {"osc32k", "osc24M", "pll_periph", "pll_periph"};
482 NM_CLK(apb2_clk,
483     CLK_APB2,				/* id */
484     "apb2", apb2_parents,			/* name, parents */
485     0x58,					/* offset */
486     16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO,	/* n factor */
487     0, 5, 0, 0,					/* m factor */
488     24, 2,					/* mux */
489     0,						/* gate */
490     AW_CLK_HAS_MUX);
491 
492 static const char *mod_parents[] = {"osc24M", "pll_periph"};
493 NM_CLK(nand0_clk,
494     CLK_NAND0, "nand0", mod_parents,	/* id, name, parents */
495     0x80,					/* offset */
496     16, 3, 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);		/* flags */
501 
502 NM_CLK(nand1_clk,
503     CLK_NAND1, "nand1", mod_parents,	/* id, name, parents */
504     0x80,					/* offset */
505     16, 3, 0, AW_CLK_FACTOR_POWER_OF_TWO,	/* n factor */
506     0, 4, 0, 0,					/* m factor */
507     24, 2,					/* mux */
508     31,						/* gate */
509     AW_CLK_HAS_GATE | AW_CLK_HAS_MUX);		/* flags */
510 
511 NM_CLK(mmc0_clk,
512     CLK_MMC0, "mmc0", mod_parents,	/* id, name, parents */
513     0x88,					/* offset */
514     16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO,	/* n factor */
515     0, 4, 0, 0,					/* m factor */
516     24, 2,					/* mux */
517     31,						/* gate */
518     AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
519     AW_CLK_REPARENT);				/* flags */
520 
521 NM_CLK(mmc1_clk,
522     CLK_MMC1, "mmc1", mod_parents,	/* id, name, parents */
523     0x8c,					/* offset */
524     16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO,	/* n factor */
525     0, 4, 0, 0,					/* m factor */
526     24, 2,					/* mux */
527     31,						/* gate */
528     AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
529     AW_CLK_REPARENT);				/* flags */
530 
531 NM_CLK(mmc2_clk,
532     CLK_MMC2, "mmc2", mod_parents,	/* id, name, parents */
533     0x90,					/* offset */
534     16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO,	/* n factor */
535     0, 4, 0, 0,					/* m factor */
536     24, 2,					/* mux */
537     31,						/* gate */
538     AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
539     AW_CLK_REPARENT);				/* flags */
540 
541 NM_CLK(mmc3_clk,
542     CLK_MMC2, "mmc3", mod_parents,	/* id, name, parents */
543     0x94,					/* offset */
544     16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO,	/* n factor */
545     0, 4, 0, 0,					/* m factor */
546     24, 2,					/* mux */
547     31,						/* gate */
548     AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
549     AW_CLK_REPARENT);				/* flags */
550 
551 static const char *ts_parents[] = {"osc24M", "pll_periph"};
552 NM_CLK(ts_clk,
553     CLK_TS, "ts", ts_parents,		/* id, name, parents */
554     0x98,					/* offset */
555     16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO,	/* n factor */
556     0, 4, 0, 0,					/* m factor */
557     24, 4,					/* mux */
558     31,						/* gate */
559     AW_CLK_HAS_GATE | AW_CLK_HAS_MUX);		/* flags */
560 
561 NM_CLK(ss_clk,
562     CLK_SS, "ss", mod_parents,		/* id, name, parents */
563     0x9C,					/* offset */
564     16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO,	/* n factor */
565     0, 4, 0, 0,					/* m factor */
566     24, 4,					/* mux */
567     31,						/* gate */
568     AW_CLK_HAS_GATE | AW_CLK_HAS_MUX);		/* flags */
569 
570 NM_CLK(spi0_clk,
571     CLK_SPI0, "spi0", mod_parents,	/* id, name, parents */
572     0xA0,					/* offset */
573     16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO,	/* n factor */
574     0, 4, 0, 0,					/* m factor */
575     24, 4,					/* mux */
576     31,						/* gate */
577     AW_CLK_HAS_GATE | AW_CLK_HAS_MUX);		/* flags */
578 
579 NM_CLK(spi1_clk,
580     CLK_SPI1, "spi1", mod_parents,	/* id, name, parents */
581     0xA4,					/* offset */
582     16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO,	/* n factor */
583     0, 4, 0, 0,					/* m factor */
584     24, 4,					/* mux */
585     31,						/* gate */
586     AW_CLK_HAS_GATE | AW_CLK_HAS_MUX);		/* flags */
587 
588 NM_CLK(spi2_clk,
589     CLK_SPI2, "spi2", mod_parents,	/* id, name, parents */
590     0xA8,					/* offset */
591     16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO,	/* n factor */
592     0, 4, 0, 0,					/* m factor */
593     24, 4,					/* mux */
594     31,						/* gate */
595     AW_CLK_HAS_GATE | AW_CLK_HAS_MUX);		/* flags */
596 
597 NM_CLK(spi3_clk,
598     CLK_SPI3, "spi3", mod_parents,	/* id, name, parents */
599     0xAC,					/* offset */
600     16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO,	/* n factor */
601     0, 4, 0, 0,					/* m factor */
602     24, 4,					/* mux */
603     31,						/* gate */
604     AW_CLK_HAS_GATE | AW_CLK_HAS_MUX);		/* flags */
605 
606 static const char *daudio_parents[] = {"pll_audio-8x", "pll_audio-4x", "pll_audio-2x", "pll_audio"};
607 MUX_CLK(daudio0mux_clk,
608     0,
609     "daudio0mux", daudio_parents,
610     0xb0, 16, 2);
611 MUX_CLK(daudio1mux_clk,
612     0,
613     "daudio1mux", daudio_parents,
614     0xb4, 16, 2);
615 
616 static const char *mdfs_parents[] = {"pll_ddr", "pll_periph"};
617 NM_CLK(mdfs_clk,
618     CLK_MDFS, "mdfs", mdfs_parents,	/* id, name, parents */
619     0xF0,					/* offset */
620     16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO,	/* n factor */
621     0, 4, 0, 0,					/* m factor */
622     24, 4,					/* mux */
623     31,						/* gate */
624     AW_CLK_HAS_GATE | AW_CLK_HAS_MUX);		/* flags */
625 
626 static const char *dram_parents[] = {"pll_ddr", "pll_periph"};
627 NM_CLK(sdram0_clk,
628     CLK_SDRAM0, "sdram0", dram_parents,	/* id, name, parents */
629     0xF4,					/* offset */
630     0, 0, 1, AW_CLK_FACTOR_FIXED,		/* n factor (fake) */
631     0, 4, 0, 0,					/* m factor */
632     4, 1,					/* mux */
633     0,						/* gate */
634     AW_CLK_HAS_MUX);				/* flags */
635 NM_CLK(sdram1_clk,
636     CLK_SDRAM1, "sdram1", dram_parents,	/* id, name, parents */
637     0xF4,					/* offset */
638     0, 0, 1, AW_CLK_FACTOR_FIXED,		/* n factor (fake) */
639     8, 4, 0, 0,					/* m factor */
640     12, 1,					/* mux */
641     0,						/* gate */
642     AW_CLK_HAS_MUX);				/* flags */
643 
644 static const char *befe_parents[] = {"pll_video0", "pll_video1", "pll_periph-2x", "pll_gpu", "pll9", "pll10"};
645 NM_CLK(be0_clk,
646     CLK_BE0, "be0", befe_parents,	/* id, name, parents */
647     0x104,					/* offset */
648     0, 0, 1, AW_CLK_FACTOR_FIXED,		/* n factor (fake) */
649     0, 4, 0, 0,					/* m factor */
650     24, 3,					/* mux */
651     31,						/* gate */
652     AW_CLK_HAS_MUX | AW_CLK_HAS_GATE);		/* flags */
653 
654 NM_CLK(be1_clk,
655     CLK_BE1, "be1", befe_parents,	/* id, name, parents */
656     0x108,					/* offset */
657     0, 0, 1, AW_CLK_FACTOR_FIXED,		/* n factor (fake) */
658     0, 4, 0, 0,					/* m factor */
659     24, 3,					/* mux */
660     31,						/* gate */
661     AW_CLK_HAS_MUX | AW_CLK_HAS_GATE);		/* flags */
662 
663 NM_CLK(fe0_clk,
664     CLK_FE0, "fe0", befe_parents,	/* id, name, parents */
665     0x104,					/* offset */
666     0, 0, 1, AW_CLK_FACTOR_FIXED,		/* n factor (fake) */
667     0, 4, 0, 0,					/* m factor */
668     24, 3,					/* mux */
669     31,						/* gate */
670     AW_CLK_HAS_MUX | AW_CLK_HAS_GATE);		/* flags */
671 NM_CLK(fe1_clk,
672     CLK_FE1, "fe1", befe_parents,	/* id, name, parents */
673     0x108,					/* offset */
674     0, 0, 1, AW_CLK_FACTOR_FIXED,		/* n factor (fake) */
675     0, 4, 0, 0,					/* m factor */
676     24, 3,					/* mux */
677     31,						/* gate */
678     AW_CLK_HAS_MUX | AW_CLK_HAS_GATE);		/* flags */
679 
680 static const char *mp_parents[] = {"pll_video0", "pll_video1", "pll9", "pll10"};
681 NM_CLK(mp_clk,
682     CLK_MP, "mp", mp_parents,	/* id, name, parents */
683     0x108,					/* offset */
684     0, 0, 1, AW_CLK_FACTOR_FIXED,		/* n factor (fake) */
685     0, 4, 0, 0,					/* m factor */
686     24, 3,					/* mux */
687     31,						/* gate */
688     AW_CLK_HAS_MUX | AW_CLK_HAS_GATE);		/* flags */
689 
690 static const char *lcd_ch0_parents[] = {"pll_video0", "pll_video1", "pll_video0-2x", "pll_video1-2x", "pll_mipi"};
691 NM_CLK(lcd0_ch0_clk,
692     CLK_LCD0_CH0, "lcd0_ch0", lcd_ch0_parents,	/* id, name, parents */
693     0x118,					/* offset */
694     0, 0, 1, AW_CLK_FACTOR_FIXED,		/* n factor (fake) */
695     0, 0, 1, AW_CLK_FACTOR_FIXED,					/* m factor (fake )*/
696     24, 3,					/* mux */
697     31,						/* gate */
698     AW_CLK_HAS_MUX | AW_CLK_HAS_GATE);		/* flags */
699 
700 NM_CLK(lcd1_ch0_clk,
701     CLK_LCD1_CH0, "lcd1_ch0", lcd_ch0_parents,	/* id, name, parents */
702     0x11C,					/* offset */
703     0, 0, 1, AW_CLK_FACTOR_FIXED,		/* n factor (fake) */
704     0, 0, 1, AW_CLK_FACTOR_FIXED,					/* m factor (fake )*/
705     24, 3,					/* mux */
706     31,						/* gate */
707     AW_CLK_HAS_MUX | AW_CLK_HAS_GATE);		/* flags */
708 
709 static const char *lcd_ch1_parents[] = {"pll_video0", "pll_video1", "pll_video0-2x", "pll_video1-2x"};
710 NM_CLK(lcd0_ch1_clk,
711     CLK_LCD0_CH1, "lcd0_ch1", lcd_ch1_parents,	/* id, name, parents */
712     0x12C,					/* offset */
713     0, 0, 1, AW_CLK_FACTOR_FIXED,		/* n factor (fake) */
714     0, 4, 0, 0,					/* m factor */
715     24, 3,					/* mux */
716     31,						/* gate */
717     AW_CLK_HAS_MUX | AW_CLK_HAS_GATE);		/* flags */
718 
719 NM_CLK(lcd1_ch1_clk,
720     CLK_LCD1_CH1, "lcd1_ch1", lcd_ch1_parents,	/* id, name, parents */
721     0x130,					/* offset */
722     0, 0, 1, AW_CLK_FACTOR_FIXED,		/* n factor (fake) */
723     0, 4, 0, 0,					/* m factor */
724     24, 3,					/* mux */
725     31,						/* gate */
726     AW_CLK_HAS_MUX | AW_CLK_HAS_GATE);		/* flags */
727 
728 /* CSI0 0x134 Need Mux table */
729 /* CSI1 0x138 Need Mux table */
730 
731 static const char *ve_parents[] = {"pll_ve"};
732 NM_CLK(ve_clk,
733     CLK_VE, "ve", ve_parents,		/* id, name, parents */
734     0x13C,					/* offset */
735     16, 3, 0, 0,				/* n factor */
736     0, 0, 1, AW_CLK_FACTOR_FIXED,		/* m factor (fake) */
737     0, 0,					/* mux */
738     31,						/* gate */
739     AW_CLK_HAS_GATE);				/* flags */
740 
741 NM_CLK(hdmi_clk,
742     CLK_HDMI, "hdmi", lcd_ch1_parents,	/* id, name, parents */
743     0x150,					/* offset */
744     0, 0, 1, AW_CLK_FACTOR_FIXED,		/* n factor (fake) */
745     0, 4, 0, 0,					/* m factor */
746     0, 0,					/* mux */
747     31,						/* gate */
748     AW_CLK_HAS_GATE);				/* flags */
749 
750 static const char *mbus_parents[] = {"osc24M", "pll_periph", "pll_ddr"};
751 NM_CLK(mbus0_clk,
752     CLK_MBUS0, "mbus0", mbus_parents,	/* id, name, parents */
753     0x15C,					/* offset */
754     16, 2, 0, 0,				/* n factor */
755     0, 4, 0, 0,					/* m factor */
756     24, 2,					/* mux */
757     31,						/* gate */
758     AW_CLK_HAS_MUX | AW_CLK_HAS_GATE);		/* flags */
759 
760 NM_CLK(mbus1_clk,
761     CLK_MBUS1, "mbus1", mbus_parents,	/* id, name, parents */
762     0x160,					/* offset */
763     16, 2, 0, 0,				/* n factor */
764     0, 4, 0, 0,					/* m factor */
765     24, 2,					/* mux */
766     31,						/* gate */
767     AW_CLK_HAS_MUX | AW_CLK_HAS_GATE);		/* flags */
768 
769 static const char *mipi_parents[] = {"pll_video0", "pll_video1", "pll_video0-2x", "pll_video1-2x"};
770 NM_CLK(mipi_dsi_clk,
771     CLK_MIPI_DSI, "mipi_dsi", mipi_parents,	/* id, name, parents */
772     0x168,					/* offset */
773     0, 0, 1, AW_CLK_FACTOR_FIXED,		/* n factor (fake) */
774     16, 4, 0, 0,				/* m factor */
775     24, 2,					/* mux */
776     31,						/* gate */
777     AW_CLK_HAS_MUX | AW_CLK_HAS_GATE);		/* flags */
778 
779 NM_CLK(mipi_dsi_dphy_clk,
780     CLK_MIPI_DSI_DPHY, "mipi_dsi_dphy", mipi_parents,	/* id, name, parents */
781     0x168,					/* offset */
782     0, 0, 1, AW_CLK_FACTOR_FIXED,		/* n factor (fake) */
783     0, 4, 0, 0,					/* m factor */
784     8, 2,					/* mux */
785     15,						/* gate */
786     AW_CLK_HAS_MUX | AW_CLK_HAS_GATE);		/* flags */
787 
788 NM_CLK(mipi_csi_dphy_clk,
789     CLK_MIPI_CSI_DPHY, "mipi_csi_dphy", mipi_parents,	/* id, name, parents */
790     0x16C,					/* offset */
791     0, 0, 1, AW_CLK_FACTOR_FIXED,		/* n factor (fake) */
792     0, 4, 0, 0,					/* m factor */
793     8, 2,					/* mux */
794     15,						/* gate */
795     AW_CLK_HAS_MUX | AW_CLK_HAS_GATE);		/* flags */
796 
797 static const char *iep_parents[] = {"pll_video0", "pll_video1", "pll_periph-2x", "pll_gpu", "pll9", "pll10"};
798 
799 NM_CLK(iep_drc0_clk,
800     CLK_IEP_DRC0, "iep_drc0", iep_parents,	/* id, name, parents */
801     0x180,					/* offset */
802     0, 0, 1, AW_CLK_FACTOR_FIXED,		/* n factor (fake) */
803     0, 4, 0, 0,					/* m factor */
804     24, 2,					/* mux */
805     31,						/* gate */
806     AW_CLK_HAS_MUX | AW_CLK_HAS_GATE);		/* flags */
807 
808 NM_CLK(iep_drc1_clk,
809     CLK_IEP_DRC1, "iep_drc1", iep_parents,	/* id, name, parents */
810     0x184,					/* offset */
811     0, 0, 1, AW_CLK_FACTOR_FIXED,		/* n factor (fake) */
812     0, 4, 0, 0,					/* m factor */
813     24, 2,					/* mux */
814     31,						/* gate */
815     AW_CLK_HAS_MUX | AW_CLK_HAS_GATE);		/* flags */
816 
817 NM_CLK(iep_deu0_clk,
818     CLK_IEP_DEU0, "iep_deu0", iep_parents,	/* id, name, parents */
819     0x188,					/* offset */
820     0, 0, 1, AW_CLK_FACTOR_FIXED,		/* n factor (fake) */
821     0, 4, 0, 0,					/* m factor */
822     24, 2,					/* mux */
823     31,						/* gate */
824     AW_CLK_HAS_MUX | AW_CLK_HAS_GATE);		/* flags */
825 
826 NM_CLK(iep_deu1_clk,
827     CLK_IEP_DEU1, "iep_deu1", iep_parents,	/* id, name, parents */
828     0x18C,					/* offset */
829     0, 0, 1, AW_CLK_FACTOR_FIXED,		/* n factor (fake) */
830     0, 4, 0, 0,					/* m factor */
831     24, 2,					/* mux */
832     31,						/* gate */
833     AW_CLK_HAS_MUX | AW_CLK_HAS_GATE);		/* flags */
834 
835 static const char *gpu_parents[] = {"pll_gpu", "pll_periph-2x", "pll_video0", "pll_video1", "pll9", "pll10"};
836 PREDIV_CLK(gpu_core_clk,
837     CLK_GPU_CORE,				/* id */
838     "gpu_core", gpu_parents,		/* name, parents */
839     0x1A0,					/* offset */
840     24, 3,					/* mux */
841     0, 3, 0, 0,					/* div */
842     0, 0, 3, AW_CLK_FACTOR_HAS_COND | AW_CLK_FACTOR_FIXED,	/* prediv */
843     24, 2, 1);					/* prediv condition */
844 
845 PREDIV_CLK(gpu_memory_clk,
846     CLK_GPU_MEMORY,				/* id */
847     "gpu_memory", gpu_parents,			/* name, parents */
848     0x1A4,					/* offset */
849     24, 3,					/* mux */
850     0, 3, 0, 0,					/* div */
851     0, 0, 3, AW_CLK_FACTOR_HAS_COND | AW_CLK_FACTOR_FIXED,	/* prediv */
852     24, 2, 1);					/* prediv condition */
853 
854 PREDIV_CLK(gpu_hyd_clk,
855     CLK_GPU_HYD,				/* id */
856     "gpu_hyd", gpu_parents,			/* name, parents */
857     0x1A8,					/* offset */
858     24, 3,					/* mux */
859     0, 3, 0, 0,					/* div */
860     0, 0, 3, AW_CLK_FACTOR_HAS_COND | AW_CLK_FACTOR_FIXED,	/* prediv */
861     24, 2, 1);					/* prediv condition */
862 
863 /* ATS 0x1B0 */
864 /* Trace 0x1B4 */
865 static struct aw_ccung_clk a31_ccu_clks[] = {
866 	{ .type = AW_CLK_NKMP, .clk.nkmp = &pll_cpu_clk},
867 	{ .type = AW_CLK_NKMP, .clk.nkmp = &pll_audio_clk},
868 	{ .type = AW_CLK_NKMP, .clk.nkmp = &pll_periph_clk},
869 	{ .type = AW_CLK_NKMP, .clk.nkmp = &pll_ddr_clk},
870 	{ .type = AW_CLK_NKMP, .clk.nkmp = &pll_mipi_clk},
871 	{ .type = AW_CLK_FRAC, .clk.frac = &pll_video0_clk},
872 	{ .type = AW_CLK_FRAC, .clk.frac = &pll_ve_clk},
873 	{ .type = AW_CLK_FRAC, .clk.frac = &pll_video1_clk},
874 	{ .type = AW_CLK_FRAC, .clk.frac = &pll_gpu_clk},
875 	{ .type = AW_CLK_FRAC, .clk.frac = &pll9_clk},
876 	{ .type = AW_CLK_FRAC, .clk.frac = &pll10_clk},
877 	{ .type = AW_CLK_NM, .clk.nm = &apb2_clk},
878 	{ .type = AW_CLK_NM, .clk.nm = &nand0_clk},
879 	{ .type = AW_CLK_NM, .clk.nm = &nand1_clk},
880 	{ .type = AW_CLK_NM, .clk.nm = &mmc0_clk},
881 	{ .type = AW_CLK_NM, .clk.nm = &mmc1_clk},
882 	{ .type = AW_CLK_NM, .clk.nm = &mmc2_clk},
883 	{ .type = AW_CLK_NM, .clk.nm = &mmc3_clk},
884 	{ .type = AW_CLK_NM, .clk.nm = &ts_clk},
885 	{ .type = AW_CLK_NM, .clk.nm = &ss_clk},
886 	{ .type = AW_CLK_NM, .clk.nm = &spi0_clk},
887 	{ .type = AW_CLK_NM, .clk.nm = &spi1_clk},
888 	{ .type = AW_CLK_NM, .clk.nm = &spi2_clk},
889 	{ .type = AW_CLK_NM, .clk.nm = &spi3_clk},
890 	{ .type = AW_CLK_NM, .clk.nm = &mdfs_clk},
891 	{ .type = AW_CLK_NM, .clk.nm = &sdram0_clk},
892 	{ .type = AW_CLK_NM, .clk.nm = &sdram1_clk},
893 	{ .type = AW_CLK_NM, .clk.nm = &be0_clk},
894 	{ .type = AW_CLK_NM, .clk.nm = &be1_clk},
895 	{ .type = AW_CLK_NM, .clk.nm = &fe0_clk},
896 	{ .type = AW_CLK_NM, .clk.nm = &fe1_clk},
897 	{ .type = AW_CLK_NM, .clk.nm = &mp_clk},
898 	{ .type = AW_CLK_NM, .clk.nm = &lcd0_ch0_clk},
899 	{ .type = AW_CLK_NM, .clk.nm = &lcd1_ch0_clk},
900 	{ .type = AW_CLK_NM, .clk.nm = &lcd0_ch1_clk},
901 	{ .type = AW_CLK_NM, .clk.nm = &lcd1_ch1_clk},
902 	{ .type = AW_CLK_NM, .clk.nm = &ve_clk},
903 	{ .type = AW_CLK_NM, .clk.nm = &hdmi_clk},
904 	{ .type = AW_CLK_NM, .clk.nm = &mbus0_clk},
905 	{ .type = AW_CLK_NM, .clk.nm = &mbus1_clk},
906 	{ .type = AW_CLK_NM, .clk.nm = &mipi_dsi_clk},
907 	{ .type = AW_CLK_NM, .clk.nm = &mipi_dsi_dphy_clk},
908 	{ .type = AW_CLK_NM, .clk.nm = &mipi_csi_dphy_clk},
909 	{ .type = AW_CLK_NM, .clk.nm = &iep_drc0_clk},
910 	{ .type = AW_CLK_NM, .clk.nm = &iep_drc1_clk},
911 	{ .type = AW_CLK_NM, .clk.nm = &iep_deu0_clk},
912 	{ .type = AW_CLK_NM, .clk.nm = &iep_deu1_clk},
913 	{ .type = AW_CLK_PREDIV_MUX, .clk.prediv_mux = &ahb1_clk},
914 	{ .type = AW_CLK_PREDIV_MUX, .clk.prediv_mux = &gpu_core_clk},
915 	{ .type = AW_CLK_PREDIV_MUX, .clk.prediv_mux = &gpu_memory_clk},
916 	{ .type = AW_CLK_PREDIV_MUX, .clk.prediv_mux = &gpu_hyd_clk},
917 	{ .type = AW_CLK_DIV, .clk.div = &axi_clk},
918 	{ .type = AW_CLK_DIV, .clk.div = &apb1_clk},
919 	{ .type = AW_CLK_MUX, .clk.mux = &cpu_clk},
920 	{ .type = AW_CLK_MUX, .clk.mux = &daudio0mux_clk},
921 	{ .type = AW_CLK_MUX, .clk.mux = &daudio1mux_clk},
922 	{ .type = AW_CLK_FIXED, .clk.fixed = &pll_audio_2x_clk},
923 	{ .type = AW_CLK_FIXED, .clk.fixed = &pll_audio_4x_clk},
924 	{ .type = AW_CLK_FIXED, .clk.fixed = &pll_audio_8x_clk},
925 	{ .type = AW_CLK_FIXED, .clk.fixed = &pll_video0_2x_clk},
926 	{ .type = AW_CLK_FIXED, .clk.fixed = &pll_periph_2x_clk},
927 	{ .type = AW_CLK_FIXED, .clk.fixed = &pll_video1_2x_clk},
928 };
929 
930 static int
931 ccu_a31_probe(device_t dev)
932 {
933 
934 	if (!ofw_bus_status_okay(dev))
935 		return (ENXIO);
936 
937 	if (!ofw_bus_is_compatible(dev, "allwinner,sun6i-a31-ccu"))
938 		return (ENXIO);
939 
940 	device_set_desc(dev, "Allwinner A31 Clock Control Unit NG");
941 	return (BUS_PROBE_DEFAULT);
942 }
943 
944 static int
945 ccu_a31_attach(device_t dev)
946 {
947 	struct aw_ccung_softc *sc;
948 
949 	sc = device_get_softc(dev);
950 
951 	sc->resets = a31_ccu_resets;
952 	sc->nresets = nitems(a31_ccu_resets);
953 	sc->gates = a31_ccu_gates;
954 	sc->ngates = nitems(a31_ccu_gates);
955 	sc->clks = a31_ccu_clks;
956 	sc->nclks = nitems(a31_ccu_clks);
957 
958 	return (aw_ccung_attach(dev));
959 }
960 
961 static device_method_t ccu_a31ng_methods[] = {
962 	/* Device interface */
963 	DEVMETHOD(device_probe,		ccu_a31_probe),
964 	DEVMETHOD(device_attach,	ccu_a31_attach),
965 
966 	DEVMETHOD_END
967 };
968 
969 DEFINE_CLASS_1(ccu_a31ng, ccu_a31ng_driver, ccu_a31ng_methods,
970   sizeof(struct aw_ccung_softc), aw_ccung_driver);
971 
972 EARLY_DRIVER_MODULE(ccu_a31ng, simplebus, ccu_a31ng_driver, 0, 0,
973     BUS_PASS_RESOURCE + BUS_PASS_ORDER_MIDDLE);
974