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
82static 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
147static 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
239static const char *pll_parents[] = {"osc24M"};
240
241NKMP_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
253NKMP_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
265static const char *pll_audio_mult_parents[] = {"pll_audio"};
266FIXED_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 */
274FIXED_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 */
282FIXED_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
291FRAC_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 */
302static const char *pll_video0_2x_parents[] = {"pll_video0"};
303FIXED_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
312FRAC_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
324NKMP_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
337NKMP_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
349static const char *pll_periph_2x_parents[] = {"pll_periph"};
350FIXED_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
359FRAC_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
371static const char *pll_video1_2x_parents[] = {"pll_video1"};
372FIXED_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
381FRAC_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
393static const char *pll_mipi_parents[] = {"pll_video0", "pll_video1"};
394NKMP_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
406FRAC_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
418FRAC_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
430static 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};
441static const char *axi_parents[] = {"cpu"};
442DIV_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
449static const char *cpu_parents[] = {"osc32k", "osc24M", "pll_cpu", "pll_cpu"};
450MUX_CLK(cpu_clk,
451    CLK_CPU,		/* id */
452    "cpu", cpu_parents,		/* name, parents */
453    0x50, 16, 2);		/* offset, shift, width */
454
455static const char *ahb1_parents[] = {"osc32k", "osc24M", "axi", "pll_periph"};
456PREDIV_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
465static const char *apb1_parents[] = {"ahb1"};
466static 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};
473DIV_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
481static const char *apb2_parents[] = {"osc32k", "osc24M", "pll_periph", "pll_periph"};
482NM_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
492static const char *mod_parents[] = {"osc24M", "pll_periph"};
493NM_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
502NM_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
511NM_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
521NM_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
531NM_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
541NM_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
551static const char *ts_parents[] = {"osc24M", "pll_periph"};
552NM_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
561NM_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
570NM_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
579NM_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
588NM_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
597NM_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
606static const char *daudio_parents[] = {"pll_audio-8x", "pll_audio-4x", "pll_audio-2x", "pll_audio"};
607MUX_CLK(daudio0mux_clk,
608    0,
609    "daudio0mux", daudio_parents,
610    0xb0, 16, 2);
611MUX_CLK(daudio1mux_clk,
612    0,
613    "daudio1mux", daudio_parents,
614    0xb4, 16, 2);
615
616static const char *mdfs_parents[] = {"pll_ddr", "pll_periph"};
617NM_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
626static const char *dram_parents[] = {"pll_ddr", "pll_periph"};
627NM_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 */
635NM_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
644static const char *befe_parents[] = {"pll_video0", "pll_video1", "pll_periph-2x", "pll_gpu", "pll9", "pll10"};
645NM_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
654NM_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
663NM_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 */
671NM_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
680static const char *mp_parents[] = {"pll_video0", "pll_video1", "pll9", "pll10"};
681NM_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
690static const char *lcd_ch0_parents[] = {"pll_video0", "pll_video1", "pll_video0-2x", "pll_video1-2x", "pll_mipi"};
691NM_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
700NM_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
709static const char *lcd_ch1_parents[] = {"pll_video0", "pll_video1", "pll_video0-2x", "pll_video1-2x"};
710NM_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
719NM_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
731static const char *ve_parents[] = {"pll_ve"};
732NM_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
741NM_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
750static const char *mbus_parents[] = {"osc24M", "pll_periph", "pll_ddr"};
751NM_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
760NM_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
769static const char *mipi_parents[] = {"pll_video0", "pll_video1", "pll_video0-2x", "pll_video1-2x"};
770NM_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
779NM_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
788NM_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
797static const char *iep_parents[] = {"pll_video0", "pll_video1", "pll_periph-2x", "pll_gpu", "pll9", "pll10"};
798
799NM_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
808NM_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
817NM_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
826NM_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
835static const char *gpu_parents[] = {"pll_gpu", "pll_periph-2x", "pll_video0", "pll_video1", "pll9", "pll10"};
836PREDIV_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
845PREDIV_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
854PREDIV_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 */
865static 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
930static int
931ccu_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
944static int
945ccu_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
961static 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
969DEFINE_CLASS_1(ccu_a31ng, ccu_a31ng_driver, ccu_a31ng_methods,
970  sizeof(struct aw_ccung_softc), aw_ccung_driver);
971
972EARLY_DRIVER_MODULE(ccu_a31ng, simplebus, ccu_a31ng_driver, 0, 0,
973    BUS_PASS_RESOURCE + BUS_PASS_ORDER_MIDDLE);
974