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