Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/dev/clk/allwinner/ccu_d1.c
39536 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2022 Julien Cassette <[email protected]>
5
* Copyright (c) 2024 The FreeBSD Foundation
6
*
7
* Portions of this software were developed by Mitchell Horne
8
* <[email protected]> under sponsorship from the FreeBSD Foundation.
9
*
10
* Redistribution and use in source and binary forms, with or without
11
* modification, are permitted provided that the following conditions
12
* are met:
13
* 1. Redistributions of source code must retain the above copyright
14
* notice, this list of conditions and the following disclaimer.
15
* 2. Redistributions in binary form must reproduce the above copyright
16
* notice, this list of conditions and the following disclaimer in the
17
* documentation and/or other materials provided with the distribution.
18
*
19
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29
* SUCH DAMAGE.
30
*/
31
32
#include <sys/param.h>
33
#include <sys/systm.h>
34
#include <sys/bus.h>
35
#include <sys/rman.h>
36
#include <sys/kernel.h>
37
#include <sys/module.h>
38
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/clk/clk_div.h>
47
#include <dev/clk/clk_fixed.h>
48
#include <dev/clk/clk_mux.h>
49
50
#include <dev/clk/allwinner/aw_ccung.h>
51
52
#include <dt-bindings/clock/sun20i-d1-ccu.h>
53
#include <dt-bindings/reset/sun20i-d1-ccu.h>
54
55
static struct aw_ccung_reset ccu_d1_resets[] = {
56
CCU_RESET(RST_MBUS, 0x540, 30)
57
CCU_RESET(RST_BUS_DE, 0x60C, 16)
58
CCU_RESET(RST_BUS_DI, 0x62C, 16)
59
CCU_RESET(RST_BUS_G2D, 0x63C, 16)
60
CCU_RESET(RST_BUS_CE, 0x68C, 16)
61
CCU_RESET(RST_BUS_VE, 0x69C, 16)
62
CCU_RESET(RST_BUS_DMA, 0x70C, 16)
63
CCU_RESET(RST_BUS_MSGBOX0, 0x71C, 16)
64
CCU_RESET(RST_BUS_MSGBOX1, 0x71C, 17)
65
CCU_RESET(RST_BUS_MSGBOX2, 0x71C, 18)
66
CCU_RESET(RST_BUS_SPINLOCK, 0x72C, 16)
67
CCU_RESET(RST_BUS_HSTIMER, 0x73C, 16)
68
CCU_RESET(RST_BUS_DBG, 0x78C, 16)
69
CCU_RESET(RST_BUS_PWM, 0x7AC, 16)
70
CCU_RESET(RST_BUS_DRAM, 0x80C, 16)
71
CCU_RESET(RST_BUS_MMC0, 0x84C, 16)
72
CCU_RESET(RST_BUS_MMC1, 0x84C, 17)
73
CCU_RESET(RST_BUS_MMC2, 0x84C, 18)
74
CCU_RESET(RST_BUS_UART0, 0x90C, 16)
75
CCU_RESET(RST_BUS_UART1, 0x90C, 17)
76
CCU_RESET(RST_BUS_UART2, 0x90C, 18)
77
CCU_RESET(RST_BUS_UART3, 0x90C, 19)
78
CCU_RESET(RST_BUS_UART4, 0x90C, 20)
79
CCU_RESET(RST_BUS_UART5, 0x90C, 21)
80
CCU_RESET(RST_BUS_I2C0, 0x91C, 16)
81
CCU_RESET(RST_BUS_I2C1, 0x91C, 17)
82
CCU_RESET(RST_BUS_I2C2, 0x91C, 18)
83
CCU_RESET(RST_BUS_I2C3, 0x91C, 19)
84
CCU_RESET(RST_BUS_SPI0, 0x96C, 16)
85
CCU_RESET(RST_BUS_SPI1, 0x96C, 17)
86
CCU_RESET(RST_BUS_EMAC, 0x97C, 16)
87
CCU_RESET(RST_BUS_IR_TX, 0x9CC, 16)
88
CCU_RESET(RST_BUS_GPADC, 0x9EC, 16)
89
CCU_RESET(RST_BUS_THS, 0x9FC, 16)
90
CCU_RESET(RST_BUS_I2S0, 0xA20, 16)
91
CCU_RESET(RST_BUS_I2S1, 0xA20, 17)
92
CCU_RESET(RST_BUS_I2S2, 0xA20, 18)
93
CCU_RESET(RST_BUS_SPDIF, 0xA2C, 16)
94
CCU_RESET(RST_BUS_DMIC, 0xA4C, 16)
95
CCU_RESET(RST_BUS_AUDIO, 0xA5C, 16)
96
CCU_RESET(RST_USB_PHY0, 0xA70, 30)
97
CCU_RESET(RST_USB_PHY1, 0xA74, 30)
98
CCU_RESET(RST_BUS_OHCI0, 0xA8C, 16)
99
CCU_RESET(RST_BUS_OHCI1, 0xA8C, 17)
100
CCU_RESET(RST_BUS_EHCI0, 0xA8C, 20)
101
CCU_RESET(RST_BUS_EHCI1, 0xA8C, 21)
102
CCU_RESET(RST_BUS_OTG, 0xA8C, 24)
103
CCU_RESET(RST_BUS_LRADC, 0xA9C, 16)
104
CCU_RESET(RST_BUS_DPSS_TOP, 0xABC, 16)
105
CCU_RESET(RST_BUS_MIPI_DSI, 0xB4C, 16)
106
CCU_RESET(RST_BUS_TCON_LCD0, 0xB7C, 16)
107
CCU_RESET(RST_BUS_TCON_TV, 0xB9C, 16)
108
CCU_RESET(RST_BUS_LVDS0, 0xBAC, 16)
109
CCU_RESET(RST_BUS_TVE, 0xBBC, 17)
110
CCU_RESET(RST_BUS_TVE_TOP, 0xBBC, 16)
111
CCU_RESET(RST_BUS_TVD, 0xBDC, 17)
112
CCU_RESET(RST_BUS_TVD_TOP, 0xBDC, 16)
113
CCU_RESET(RST_BUS_LEDC, 0xBFC, 16)
114
CCU_RESET(RST_BUS_CSI, 0xC1C, 16)
115
CCU_RESET(RST_BUS_TPADC, 0xC5C, 16)
116
CCU_RESET(RST_DSP, 0xC7C, 16)
117
CCU_RESET(RST_BUS_DSP_CFG, 0xC7C, 17)
118
CCU_RESET(RST_BUS_DSP_DBG, 0xC7C, 18)
119
CCU_RESET(RST_BUS_RISCV_CFG, 0xD0C, 16)
120
CCU_RESET(RST_BUS_CAN0, 0x92C, 16)
121
CCU_RESET(RST_BUS_CAN1, 0x92C, 17)
122
};
123
124
static struct aw_ccung_gate ccu_d1_gates[] = {
125
CCU_GATE(CLK_BUS_DE, "bus-de", "psi-ahb", 0x60C, 0)
126
CCU_GATE(CLK_BUS_DI, "bus-di", "psi-ahb", 0x62C, 0)
127
CCU_GATE(CLK_BUS_G2D, "bus-g2d", "psi-ahb", 0x63C, 0)
128
CCU_GATE(CLK_BUS_CE, "bus-ce", "psi-ahb", 0x68C, 0)
129
CCU_GATE(CLK_BUS_VE, "bus-ve", "psi-ahb", 0x690, 0)
130
CCU_GATE(CLK_BUS_DMA, "bus-dma", "psi-ahb", 0x70C, 0)
131
CCU_GATE(CLK_BUS_MSGBOX0, "bus-msgbox0", "psi-ahb", 0x71C, 0)
132
CCU_GATE(CLK_BUS_MSGBOX1, "bus-msgbox1", "psi-ahb", 0x71C, 1)
133
CCU_GATE(CLK_BUS_MSGBOX2, "bus-msgbox2", "psi-ahb", 0x71C, 2)
134
CCU_GATE(CLK_BUS_SPINLOCK, "bus-spinlock", "psi-ahb", 0x72C, 0)
135
CCU_GATE(CLK_BUS_HSTIMER, "bus-hstimer", "psi-ahb", 0x73C, 0)
136
CCU_GATE(CLK_AVS, "avs", "dcxo", 0x740, 31)
137
CCU_GATE(CLK_BUS_DBG, "bus-dbg", "psi-ahb", 0x78C, 0)
138
CCU_GATE(CLK_BUS_PWM, "bus-pwm", "psi-ahb", 0x7AC, 0)
139
CCU_GATE(CLK_BUS_IOMMU, "bus-iommu", "apb0", 0x7BC, 0)
140
CCU_GATE(CLK_MBUS_DMA, "mbus-dma", "mbus", 0x804, 0)
141
CCU_GATE(CLK_MBUS_VE, "mbus-ve", "mbus", 0x804, 1)
142
CCU_GATE(CLK_MBUS_CE, "mbus-ce", "mbus", 0x804, 2)
143
CCU_GATE(CLK_MBUS_TVIN, "mbus-tvin", "mbus", 0x804, 7)
144
CCU_GATE(CLK_MBUS_CSI, "mbus-csi", "mbus", 0x804, 8)
145
CCU_GATE(CLK_MBUS_G2D, "mbus-g2d", "mbus", 0x804, 10)
146
CCU_GATE(CLK_MBUS_RISCV, "mbus-riscv", "mbus", 0x804, 11)
147
CCU_GATE(CLK_BUS_DRAM, "bus-dram", "psi-ahb", 0x80C, 0)
148
CCU_GATE(CLK_BUS_MMC0, "bus-mmc0", "psi-ahb", 0x84C, 0)
149
CCU_GATE(CLK_BUS_MMC1, "bus-mmc1", "psi-ahb", 0x84C, 1)
150
CCU_GATE(CLK_BUS_MMC2, "bus-mmc2", "psi-ahb", 0x84C, 2)
151
CCU_GATE(CLK_BUS_UART0, "bus-uart0", "apb1", 0x90C, 0)
152
CCU_GATE(CLK_BUS_UART1, "bus-uart1", "apb1", 0x90C, 1)
153
CCU_GATE(CLK_BUS_UART2, "bus-uart2", "apb1", 0x90C, 2)
154
CCU_GATE(CLK_BUS_UART3, "bus-uart3", "apb1", 0x90C, 3)
155
CCU_GATE(CLK_BUS_UART4, "bus-uart4", "apb1", 0x90C, 4)
156
CCU_GATE(CLK_BUS_UART5, "bus-uart5", "apb1", 0x90C, 5)
157
CCU_GATE(CLK_BUS_I2C0, "bus-i2c0", "apb1", 0x91C, 0)
158
CCU_GATE(CLK_BUS_I2C1, "bus-i2c1", "apb1", 0x91C, 1)
159
CCU_GATE(CLK_BUS_I2C2, "bus-i2c2", "apb1", 0x91C, 2)
160
CCU_GATE(CLK_BUS_I2C3, "bus-i2c3", "apb1", 0x91C, 3)
161
CCU_GATE(CLK_BUS_SPI0, "bus-spi0", "psi-ahb", 0x96C, 0)
162
CCU_GATE(CLK_BUS_SPI1, "bus-spi1", "psi-ahb", 0x96C, 1)
163
CCU_GATE(CLK_BUS_EMAC, "bus-emac", "psi-ahb", 0x97C, 0)
164
CCU_GATE(CLK_BUS_IR_TX, "bus-ir-tx", "apb0", 0x9CC, 0)
165
CCU_GATE(CLK_BUS_GPADC, "bus-gpadc", "apb0", 0x9EC, 0)
166
CCU_GATE(CLK_BUS_THS, "bus-ths", "apb0", 0x9FC, 0)
167
CCU_GATE(CLK_BUS_I2S0, "bus-i2s0", "apb0", 0xA10, 0)
168
CCU_GATE(CLK_BUS_I2S1, "bus-i2s1", "apb0", 0xA10, 1)
169
CCU_GATE(CLK_BUS_I2S2, "bus-i2s2", "apb0", 0xA10, 2)
170
CCU_GATE(CLK_BUS_SPDIF, "bus-spdif", "apb0", 0xA2C, 0)
171
CCU_GATE(CLK_BUS_DMIC, "bus-dmic", "apb0", 0xA4C, 0)
172
CCU_GATE(CLK_BUS_AUDIO, "bus-audio", "apb0", 0xA5C, 0)
173
CCU_GATE(CLK_BUS_OHCI0, "bus-ohci0", "psi-ahb", 0xA8C, 0)
174
CCU_GATE(CLK_BUS_OHCI1, "bus-ohci1", "psi-ahb", 0xA8C, 1)
175
CCU_GATE(CLK_BUS_EHCI0, "bus-ehci0", "psi-ahb", 0xA8C, 4)
176
CCU_GATE(CLK_BUS_EHCI1, "bus-ehci1", "psi-ahb", 0xA8C, 5)
177
CCU_GATE(CLK_BUS_OTG, "bus-otg", "psi-ahb", 0xA8C, 8)
178
CCU_GATE(CLK_BUS_LRADC, "bus-lradc", "apb0", 0xA9C, 0)
179
CCU_GATE(CLK_BUS_DPSS_TOP, "bus-dpss-top", "psi-ahb", 0xABC, 0)
180
CCU_GATE(CLK_BUS_MIPI_DSI, "bus-mipi-dsi", "psi-ahb", 0xB4C, 0)
181
CCU_GATE(CLK_BUS_TCON_LCD0, "bus-tcon-lcd0", "psi-ahb", 0xB7C, 0)
182
CCU_GATE(CLK_BUS_TCON_TV, "bus-tcon-tv", "psi-ahb", 0xB9C, 0)
183
CCU_GATE(CLK_BUS_TVE_TOP, "bus-tve-top", "psi-ahb", 0xBBC, 0)
184
CCU_GATE(CLK_BUS_TVE, "bus-tve", "psi-ahb", 0xBBC, 1)
185
CCU_GATE(CLK_BUS_TVD_TOP, "bus-tvd-top", "psi-ahb", 0xBDC, 0)
186
CCU_GATE(CLK_BUS_TVD, "bus-tvd", "psi-ahb", 0xBDC, 1)
187
CCU_GATE(CLK_BUS_LEDC, "bus-ledc", "psi-ahb", 0xBFC, 0)
188
CCU_GATE(CLK_BUS_CSI, "bus-csi", "psi-ahb", 0xC1C, 0)
189
CCU_GATE(CLK_BUS_TPADC, "bus-tpadc", "apb0", 0xC5C, 0)
190
CCU_GATE(CLK_BUS_TZMA, "bus-tzma", "apb0", 0xC6C, 0)
191
CCU_GATE(CLK_BUS_DSP_CFG, "bus-dsp-cfg", "psi-ahb", 0xC7C, 1)
192
CCU_GATE(CLK_BUS_RISCV_CFG, "bus-riscv-cfg", "psi-ahb", 0xD0C, 0)
193
CCU_GATE(CLK_BUS_CAN0, "bus-can0", "apb1", 0x92C, 0)
194
CCU_GATE(CLK_BUS_CAN1, "bus-can1", "apb1", 0x92C, 1)
195
};
196
197
static const char *pll_cpux_parents[] = { "dcxo" };
198
NP_CLK(pll_cpux_clk,
199
CLK_PLL_CPUX, /* id */
200
"pll_cpux", /* name */
201
pll_cpux_parents, /* parents */
202
0x0, /* offset */
203
8, 8, 0, 0, /* n factor */
204
0, 2, 0, 0, /* p factor */
205
27, /* gate */
206
28, 1000, /* lock */
207
AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */
208
209
static const char *pll_ddr0_parents[] = { "dcxo" };
210
NMM_CLK(pll_ddr0_clk,
211
CLK_PLL_DDR0, /* id */
212
"pll_ddr0", /* name */
213
pll_ddr0_parents, /* parents */
214
0x10, /* offset */
215
8, 7, 0, 0, /* n factor */
216
0, 1, 0, 0, /* m0 factor */
217
1, 1, 0, 0, /* m1 factor */
218
27, /* gate */
219
28, 1000, /* lock */
220
AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */
221
222
/* PLL_PERIPH(4X) = 24 MHz * N / M1 / M0 */
223
static const char *pll_periph0_4x_parents[] = { "dcxo" };
224
NMM_CLK(pll_periph0_4x_clk,
225
CLK_PLL_PERIPH0_4X, /* id */
226
"pll_periph0_4x", /* name */
227
pll_periph0_4x_parents, /* parents */
228
0x20, /* offset */
229
8, 8, 0, 0, /* n factor */
230
0, 1, 0, 0, /* m0 factor */
231
1, 1, 0, 0, /* m1 factor */
232
27, /* gate */
233
28, 1000, /* lock */
234
AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */
235
236
/* PLL_PERIPH0(2X) = 24 MHz * N / M / P0 */
237
static const char *pll_periph0_2x_parents[] = { "pll_periph0_4x" };
238
M_CLK(pll_periph0_2x_clk,
239
CLK_PLL_PERIPH0_2X, /* id */
240
"pll_periph0_2x", /* name */
241
pll_periph0_2x_parents, /* parents */
242
0x20, /* offset */
243
16, 3, 0, 0, /* m factor */
244
0, 0, /* mux */
245
0, /* gate */
246
0); /* flags */
247
248
/* PLL_PERIPH0(800M) = 24 MHz * N / M / P1 */
249
static const char *pll_periph0_800m_parents[] = { "pll_periph0_4x" };
250
M_CLK(pll_periph0_800m_clk,
251
CLK_PLL_PERIPH0_800M, /* id */
252
"pll_periph0_800m", /* name */
253
pll_periph0_800m_parents, /* parents */
254
0x20, /* offset */
255
20, 3, 0, 0, /* m factor */
256
0, 0, /* mux */
257
0, /* gate */
258
0); /* flags */
259
260
/* PLL_PERIPH0(1X) = 24 MHz * N / M / P0 / 2 */
261
static const char *pll_periph0_parents[] = { "pll_periph0_2x" };
262
FIXED_CLK(pll_periph0_clk,
263
CLK_PLL_PERIPH0, /* id */
264
"pll_periph0", /* name */
265
pll_periph0_parents, /* parents */
266
0, /* freq */
267
1, /* mult */
268
2, /* div */
269
0); /* flags */
270
271
/* For child clocks: InputFreq * N / M */
272
static const char *pll_video0_parents[] = { "dcxo" };
273
NP_CLK(pll_video0_clk,
274
CLK_PLL_VIDEO0, /* id */
275
"pll_video0", /* name */
276
pll_video0_parents, /* parents */
277
0x40, /* offset */
278
8, 7, 0, 0, /* n factor */
279
1, 1, 0, 0, /* p factor */
280
27, /* gate */
281
28, 1000, /* lock */
282
AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */
283
284
/* PLL_VIDEO0(4X) = InputFreq * N / M / D */
285
/* D is only for testing */
286
static const char *pll_video0_4x_parents[] = { "pll_video0" };
287
M_CLK(pll_video0_4x_clk,
288
CLK_PLL_VIDEO0_4X, /* id */
289
"pll_video0_4x", /* name */
290
pll_video0_4x_parents, /* parents */
291
0x40, /* offset */
292
0, 1, 0, 0, /* m factor */
293
0, 0, /* mux */
294
0, /* gate */
295
0); /* flags */
296
297
/* PLL_VIDEO0(2X) = InputFreq * N / M / 2 */
298
static const char *pll_video0_2x_parents[] = { "pll_video0" };
299
FIXED_CLK(pll_video0_2x_clk,
300
CLK_PLL_VIDEO0_2X, /* id */
301
"pll_video0_2x", /* name */
302
pll_video0_2x_parents, /* parents */
303
0, /* freq */
304
1, /* mult */
305
2, /* div */
306
0); /* flags */
307
308
/* For child clocks: InputFreq * N / M */
309
static const char *pll_video1_parents[] = { "dcxo" };
310
NP_CLK(pll_video1_clk,
311
CLK_PLL_VIDEO1, /* id */
312
"pll_video1", /* name */
313
pll_video1_parents, /* parents */
314
0x48, /* offset */
315
8, 7, 0, 0, /* n factor */
316
1, 1, 0, 0, /* p factor */
317
27, /* gate */
318
28, 1000, /* lock */
319
AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */
320
321
/* PLL_VIDEO1(4X) = InputFreq * N / M / D */
322
/* D is only for testing */
323
static const char *pll_video1_4x_parents[] = { "pll_video1" };
324
M_CLK(pll_video1_4x_clk,
325
CLK_PLL_VIDEO1_4X, /* id */
326
"pll_video1_4x", /* name */
327
pll_video1_4x_parents, /* parents */
328
0x48, /* offset */
329
0, 1, 0, 0, /* m factor */
330
0, 0, /* mux */
331
0, /* gate */
332
0); /* flags */
333
334
/* PLL_VIDEO1(2X) = InputFreq * N / M / 2 */
335
static const char *pll_video1_2x_parents[] = { "pll_video1" };
336
FIXED_CLK(pll_video1_2x_clk,
337
CLK_PLL_VIDEO1_2X, /* id */
338
"pll_video1_2x", /* name */
339
pll_video1_2x_parents, /* parents */
340
0, /* freq */
341
1, /* mult */
342
2, /* div */
343
0); /* flags */
344
345
static const char *pll_ve_parents[] = { "dcxo" };
346
NMM_CLK(pll_ve_clk,
347
CLK_PLL_VE, /* id */
348
"pll_ve", /* name */
349
pll_ve_parents, /* parents */
350
0x58, /* offset */
351
8, 7, 0, 0, /* n factor */
352
0, 1, 0, 0, /* m0 factor */
353
1, 1, 0, 0, /* m1 factor */
354
27, /* gate */
355
28, 1000, /* lock */
356
AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */
357
358
/* For child clocks: 24MHz * N / M1 / M0 */
359
static const char *pll_audio0_4x_parents[] = { "dcxo" };
360
NMM_CLK(pll_audio0_4x_clk,
361
CLK_PLL_AUDIO0_4X, /* id */
362
"pll_audio0_4x", /* name */
363
pll_audio0_4x_parents, /* parents */
364
0x78, /* offset */
365
8, 7, 0, 0, /* n factor */
366
0, 1, 0, 0, /* m0 factor */
367
1, 1, 0, 0, /* m1 factor */
368
27, /* gate */
369
28, 1000, /* lock */
370
AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */
371
372
/* PLL_AUDIO0(2X) = (24MHz * N / M1 / M0) / P / 2 */
373
static const char *pll_audio0_2x_parents[] = { "pll_audio0_4x" };
374
FIXED_CLK(pll_audio0_2x_clk,
375
CLK_PLL_AUDIO0_2X, /* id */
376
"pll_audio0_2x", /* name */
377
pll_audio0_2x_parents, /* parents */
378
0, /* freq */
379
1, /* mult */
380
2, /* div */
381
0); /* flags */
382
383
/* PLL_AUDIO0(1X) = 24MHz * N / M1 / M0 / P / 2 */
384
static const char *pll_audio0_parents[] = { "pll_audio0_2x" };
385
FIXED_CLK(pll_audio0_clk,
386
CLK_PLL_AUDIO0, /* id */
387
"pll_audio0", /* name */
388
pll_audio0_parents, /* parents */
389
0, /* freq */
390
1, /* mult */
391
2, /* div */
392
0); /* flags */
393
394
/* For child clocks: 24MHz * N / M */
395
static const char *pll_audio1_parents[] = { "dcxo" };
396
NP_CLK(pll_audio1_clk,
397
CLK_PLL_AUDIO1, /* id */
398
"pll_audio1", /* name */
399
pll_audio1_parents, /* parents */
400
0x80, /* offset */
401
8, 7, 0, 0, /* n factor */
402
1, 1, 0, 0, /* p factor */
403
27, /* gate */
404
28, 1000, /* lock */
405
AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */
406
407
/* PLL_AUDIO1(DIV2) = 24MHz * N / M / P0 */
408
static const char *pll_audio1_div2_parents[] = { "pll_audio1" };
409
M_CLK(pll_audio1_div2_clk,
410
CLK_PLL_AUDIO1_DIV2, /* id */
411
"pll_audio1_div2", /* name */
412
pll_audio1_div2_parents, /* parents */
413
0x80, /* offset */
414
16, 3, 0, 0, /* m factor */
415
0, 0, /* mux */
416
0, /* gate */
417
0); /* flags */
418
419
/* PLL_AUDIO1(DIV5) = 24MHz * N / M / P1 */
420
static const char *pll_audio1_div5_parents[] = { "pll_audio1" };
421
M_CLK(pll_audio1_div5_clk,
422
CLK_PLL_AUDIO1_DIV5, /* id */
423
"pll_audio1_div5", /* name */
424
pll_audio1_div5_parents, /* parents */
425
0x80, /* offset */
426
20, 3, 0, 0, /* m factor */
427
0, 0, /* mux */
428
0, /* gate */
429
0); /* flags */
430
431
static const char *cpux_parents[] = { "dcxo", "osc32k", "iosc", "pll_cpux",
432
"pll_periph0", "pll_periph0_2x", "pll_periph0_800m" };
433
M_CLK(cpux_clk,
434
CLK_CPUX, /* id */
435
"cpux", /* name */
436
cpux_parents, /* parents */
437
0x500, /* offset */
438
16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* m factor */
439
24, 3, /* mux */
440
0, /* gate */
441
AW_CLK_HAS_MUX | AW_CLK_SET_PARENT); /* flags */
442
443
static const char *cpux_axi_parents[] = { "cpux" };
444
M_CLK(cpux_axi_clk,
445
CLK_CPUX_AXI, /* id */
446
"cpux_axi", /* name */
447
cpux_axi_parents, /* parents */
448
0x500, /* offset */
449
0, 2, 0, 0, /* m factor */
450
0, 0, /* mux */
451
0, /* gate */
452
0); /* flags */
453
454
static const char *cpux_apb_parents[] = { "cpux" };
455
M_CLK(cpux_apb_clk,
456
CLK_CPUX_APB, /* id */
457
"cpux_apb", /* name */
458
cpux_apb_parents, /* parents */
459
0x500, /* offset */
460
8, 2, 0, 0, /* m factor */
461
0, 0, /* mux */
462
0, /* gate */
463
0); /* flags */
464
465
static const char *psi_ahb_parents[] = { "dcxo", "osc32k", "iosc",
466
"pll_periph0" };
467
NM_CLK(psi_ahb_clk,
468
CLK_PSI_AHB, "psi-ahb", psi_ahb_parents, /* id, name, parents */
469
0x510, /* offset */
470
8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */
471
0, 2, 0, 0, /* m factor */
472
24, 2, /* mux */
473
0, /* gate */
474
AW_CLK_HAS_MUX | AW_CLK_REPARENT); /* flags */
475
476
static const char *apb0_parents[] = { "dcxo", "osc32k", "psi-ahb", "pll_periph0" };
477
NM_CLK(apb0_clk,
478
CLK_APB0, "apb0", apb0_parents, /* id, name, parents */
479
0x520, /* offset */
480
8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */
481
0, 2, 0, 0, /* m factor */
482
24, 2, /* mux */
483
0, /* gate */
484
AW_CLK_HAS_MUX | AW_CLK_REPARENT); /* flags */
485
486
static const char *apb1_parents[] = { "dcxo", "osc32k", "psi-ahb", "pll_periph0" };
487
NM_CLK(apb1_clk,
488
CLK_APB1, "apb1", apb1_parents, /* id, name, parents */
489
0x524, /* offset */
490
8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */
491
0, 2, 0, 0, /* m factor */
492
24, 2, /* mux */
493
0, /* gate */
494
AW_CLK_HAS_MUX | AW_CLK_REPARENT); /* flags */
495
496
static const char *mbus_parents[] = { "dram" };
497
FIXED_CLK(mbus_clk,
498
CLK_MBUS, "mbus", mbus_parents, /* id, name, parents */
499
0, /* freq */
500
1, /* mult */
501
4, /* div */
502
0); /* flags */
503
504
static const char *de_parents[] = { "pll_periph0_2x", "pll_video0_4x",
505
"pll_video1_4x", "pll_audio1_div2" };
506
M_CLK(de_clk,
507
CLK_DE, "de", de_parents, /* id, name, parents */
508
0x600, /* offset */
509
0, 5, 0, 0, /* m factor */
510
24, 3, /* mux */
511
31, /* gate */
512
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
513
AW_CLK_REPARENT); /* flags */
514
515
static const char *di_parents[] = { "pll_periph0_2x", "pll_video0_4x",
516
"pll_video1_4x", "pll_audio1_div2" };
517
M_CLK(di_clk,
518
CLK_DI, "di", di_parents, /* id, name, parents */
519
0x620, /* offset */
520
0, 5, 0, 0, /* m factor */
521
24, 3, /* mux */
522
31, /* gate */
523
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
524
AW_CLK_REPARENT); /* flags */
525
526
static const char *g2d_parents[] = { "pll_periph0_2x", "pll_video0_4x",
527
"pll_video1_4x", "pll_audio1_div2" };
528
M_CLK(g2d_clk,
529
CLK_G2D, "g2d", g2d_parents, /* id, name, parents */
530
0x630, /* offset */
531
0, 5, 0, 0, /* m factor */
532
24, 3, /* mux */
533
31, /* gate */
534
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
535
AW_CLK_REPARENT); /* flags */
536
537
static const char *ce_parents[] = { "dcxo", "pll_periph0_2x", "pll_periph0" };
538
NM_CLK(ce_clk,
539
CLK_CE, "ce", ce_parents, /* id, name, parents */
540
0x680, /* offset */
541
8, 2, 0, 0, /* n factor */
542
0, 4, 0, 0, /* m factor */
543
24, 3, /* mux */
544
31, /* gate */
545
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
546
AW_CLK_REPARENT); /* flags */
547
548
static const char *ve_parents[] = { "pll_ve", "pll_periph0_2x" };
549
M_CLK(ve_clk,
550
CLK_VE, "ve", ve_parents, /* id, name, parents */
551
0x690, /* offset */
552
0, 5, 0, 0, /* m factor */
553
24, 1, /* mux */
554
31, /* gate */
555
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | /* flags */
556
AW_CLK_REPARENT);
557
558
static const char *dram_parents[] = { "pll_ddr0", "pll_audio1_div2",
559
"pll_periph0_2x", "pll_periph0_800m" };
560
NM_CLK(dram_clk,
561
CLK_DRAM, "dram", dram_parents, /* id, name, parents */
562
0x800, /* offset */
563
8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */
564
0, 2, 0, 0, /* m factor */
565
24, 3, /* mux */
566
31, /* gate */
567
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | /* flags */
568
AW_CLK_REPARENT);
569
570
/* SMHC0 */
571
static const char *mmc0_parents[] = { "dcxo", "pll_periph0", "pll_periph0_2x",
572
"pll_audio1_div2" };
573
NM_CLK(mmc0_clk,
574
CLK_MMC0, "mmc0", mmc0_parents, /* id, name, parents */
575
0x830, /* offset */
576
8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */
577
0, 4, 0, 0, /* m factor */
578
24, 3, /* mux */
579
31, /* gate */
580
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
581
AW_CLK_REPARENT); /* flags */
582
583
/* SMHC1 */
584
static const char *mmc1_parents[] = { "dcxo", "pll_periph0", "pll_periph0_2x",
585
"pll_audio1_div2" };
586
NM_CLK(mmc1_clk,
587
CLK_MMC1, "mmc1", mmc1_parents, /* id, name, parents */
588
0x834, /* offset */
589
8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */
590
0, 4, 0, 0, /* m factor */
591
24, 3, /* mux */
592
31, /* gate */
593
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
594
AW_CLK_REPARENT); /* flags */
595
596
/* SMHC2 */
597
static const char *mmc2_parents[] = { "dcxo", "pll_periph0", "pll_periph0_2x",
598
"pll_periph0_800m", "pll_audio1_div2" };
599
NM_CLK(mmc2_clk,
600
CLK_MMC2, "mmc2", mmc2_parents, /* id, name, parents */
601
0x838, /* offset */
602
8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */
603
0, 4, 0, 0, /* m factor */
604
24, 3, /* mux */
605
31, /* gate */
606
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
607
AW_CLK_REPARENT); /* flags */
608
609
static const char *spi0_parents[] = { "dcxo", "pll_periph0", "pll_periph0_2x",
610
"pll_audio1_div2", "pll_audio1_div5" };
611
NM_CLK(spi0_clk,
612
CLK_SPI0, "spi0", spi0_parents, /* id, name, parents */
613
0x940, /* offset */
614
8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */
615
0, 4, 0, 0, /* m factor */
616
24, 3, /* mux */
617
31, /* gate */
618
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
619
AW_CLK_REPARENT); /* flags */
620
621
static const char *spi1_parents[] = { "dcxo", "pll_periph0", "pll_periph0_2x",
622
"pll_audio1_div2", "pll_audio1_div5" };
623
NM_CLK(spi1_clk,
624
CLK_SPI1, "spi1", spi1_parents, /* id, name, parents */
625
0x944, /* offset */
626
8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */
627
0, 4, 0, 0, /* m factor */
628
24, 3, /* mux */
629
31, /* gate */
630
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
631
AW_CLK_REPARENT); /* flags */
632
633
/* Use M_CLK to have gate */
634
static const char *emac_25m_parents[] = { "pll_periph0" };
635
M_CLK(emac_25m_clk,
636
CLK_EMAC_25M, /* id */
637
"emac_25m", /* name */
638
emac_25m_parents, /* parents */
639
0x970, /* offset */
640
0, 0, 24, AW_CLK_FACTOR_FIXED, /* m factor */
641
0, 0, /* mux */
642
31, /* gate */
643
AW_CLK_HAS_GATE | AW_CLK_REPARENT); /* flags */
644
645
static const char *irtx_parents[] = { "dcxo", "pll_periph0" };
646
NM_CLK(irtx_clk,
647
CLK_IR_TX, "irtx", irtx_parents, /* id, name, parents */
648
0x9C0, /* offset */
649
8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */
650
0, 4, 0, 0, /* m factor */
651
24, 3, /* mux */
652
31, /* gate */
653
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
654
AW_CLK_REPARENT); /* flags */
655
656
static const char *i2s0_parents[] = { "pll_audio0", "pll_audio0_4x",
657
"pll_audio1_div2", "pll_audio1_div5" };
658
NM_CLK(i2s0_clk,
659
CLK_I2S0, "i2s0", i2s0_parents, /* id, name, parents */
660
0xA10, /* offset */
661
8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */
662
0, 5, 0, 0, /* m factor */
663
24, 3, /* mux */
664
31, /* gate */
665
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
666
AW_CLK_REPARENT); /* flags */
667
668
static const char *i2s1_parents[] = { "pll_audio0", "pll_audio0_4x",
669
"pll_audio1_div2", "pll_audio1_div5" };
670
NM_CLK(i2s1_clk,
671
CLK_I2S1, "i2s1", i2s1_parents, /* id, name, parents */
672
0xA14, /* offset */
673
8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */
674
0, 5, 0, 0, /* m factor */
675
24, 3, /* mux */
676
31, /* gate */
677
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
678
AW_CLK_REPARENT); /* flags */
679
680
static const char *i2s2_parents[] = { "pll_audio0", "pll_audio0_4x",
681
"pll_audio1_div2", "pll_audio1_div5" };
682
NM_CLK(i2s2_clk,
683
CLK_I2S2, "i2s2", i2s2_parents, /* id, name, parents */
684
0xA18, /* offset */
685
8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */
686
0, 5, 0, 0, /* m factor */
687
24, 3, /* mux */
688
31, /* gate */
689
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
690
AW_CLK_REPARENT); /* flags */
691
692
static const char *i2s2_asrc_parents[] = { "pll_audio0_4x", "pll_periph0",
693
"pll_audio1_div2", "pll_audio1_div5" };
694
NM_CLK(i2s2_asrc_clk,
695
CLK_I2S2_ASRC, /* id */
696
"i2s2_asrc", /* name */
697
i2s2_asrc_parents, /* parents */
698
0xA1C, /* offset */
699
8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */
700
0, 5, 0, 0, /* m factor */
701
24, 3, /* mux */
702
31, /* gate */
703
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
704
AW_CLK_REPARENT); /* flags */
705
706
/* OWA_TX */
707
static const char *spdif_tx_parents[] = { "pll_audio0", "pll_audio0_4x",
708
"pll_audio1_div2", "pll_audio1_div5" };
709
NM_CLK(spdif_tx_clk,
710
CLK_SPDIF_TX, "spdif_tx", spdif_tx_parents, /* id, name, parents */
711
0xA24, /* offset */
712
8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */
713
0, 5, 0, 0, /* m factor */
714
24, 3, /* mux */
715
31, /* gate */
716
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
717
AW_CLK_REPARENT); /* flags */
718
719
/* OWA_RX */
720
static const char *spdif_rx_parents[] = { "pll_periph0", "pll_audio1_div2",
721
"pll_audio1_div5" };
722
NM_CLK(spdif_rx_clk,
723
CLK_SPDIF_RX, "spdif_rx", spdif_rx_parents, /* id, name, parents */
724
0xA28, /* offset */
725
8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */
726
0, 5, 0, 0, /* m factor */
727
24, 3, /* mux */
728
31, /* gate */
729
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
730
AW_CLK_REPARENT); /* flags */
731
732
static const char *dmic_parents[] = { "pll_audio0", "pll_audio1_div2",
733
"pll_audio1_div5" };
734
NM_CLK(dmic_clk,
735
CLK_DMIC, "dmic", dmic_parents, /* id, name, parents */
736
0xA40, /* offset */
737
8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */
738
0, 5, 0, 0, /* m factor */
739
24, 3, /* mux */
740
31, /* gate */
741
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
742
AW_CLK_REPARENT); /* flags */
743
744
static const char *audio_dac_parents[] = { "pll_audio0", "pll_audio1_div2",
745
"pll_audio1_div5" };
746
NM_CLK(audio_dac_clk,
747
CLK_AUDIO_DAC, /* id */
748
"audio_dac", /* name */
749
audio_dac_parents, /* parents */
750
0xA50, /* offset */
751
8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */
752
0, 5, 0, 0, /* m factor */
753
24, 3, /* mux */
754
31, /* gate */
755
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
756
AW_CLK_REPARENT); /* flags */
757
758
static const char *audio_adc_parents[] = { "pll_audio0", "pll_audio1_div2",
759
"pll_audio1_div5" };
760
NM_CLK(audio_adc_clk,
761
CLK_AUDIO_ADC, /* id */
762
"audio_adc", /* name */
763
audio_adc_parents, /* parents */
764
0xA54, /* offset */
765
8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */
766
0, 5, 0, 0, /* m factor */
767
24, 3, /* mux */
768
31, /* gate */
769
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
770
AW_CLK_REPARENT); /* flags */
771
772
/*
773
* XXX: These USB clocks are unusual, and can't be modeled fully with any of
774
* our existing clk classes.
775
*
776
* The clocks have three parents; they output 12M when assigned to the first
777
* two, and the third is direct (32K).
778
*
779
* Thus a divider table like the following would be needed:
780
* struct clk_div_table usb_ohci_div_table[] = {
781
* { .value = 0, .divider = 50 },
782
* { .value = 1, .divider = 2 },
783
* { .value = 2, .divider = 1 },
784
* { },
785
* };
786
*
787
* But we also require a gate.
788
*
789
* To work around this, model the clocks as if they had only one parent.
790
*/
791
static const char *usb_ohci_parents[] = { "pll_periph0",
792
/*"dcxo", "osc32k"*/ };
793
M_CLK(usb_ohci0_clk,
794
CLK_USB_OHCI0, /* id */
795
"usb_ohci0", /* name */
796
usb_ohci_parents, /* parents */
797
0xA70, /* offset */
798
0, 0, 50, AW_CLK_FACTOR_FIXED, /* m factor */
799
24, 2, /* mux */
800
31, /* gate */
801
AW_CLK_HAS_GATE /* | AW_CLK_HAS_MUX */); /* flags */
802
803
M_CLK(usb_ohci1_clk,
804
CLK_USB_OHCI1, /* id */
805
"usb_ohci1", /* name */
806
usb_ohci_parents, /* parents */
807
0xA74, /* offset */
808
0, 0, 50, AW_CLK_FACTOR_FIXED, /* m factor */
809
24, 2, /* mux */
810
31, /* gate */
811
AW_CLK_HAS_GATE /* | AW_CLK_HAS_MUX */); /* flags */
812
813
814
static const char *dsi_parents[] = { "dcxo", "pll_periph0", "pll_video0_2x",
815
"pll_video1_2x", "pll_audio1_div2" };
816
M_CLK(dsi_clk,
817
CLK_MIPI_DSI, "mipi-dsi", dsi_parents, /* id, name, parents */
818
0xB24, /* offset */
819
0, 4, 0, 0, /* m factor */
820
24, 3, /* mux */
821
31, /* gate */
822
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
823
AW_CLK_REPARENT); /* flags */
824
825
static const char *tconlcd_parents[] = { "pll_video0", "pll_video0_4x",
826
"pll_video1", "pll_video1_4x", "pll_periph0_2x", "pll_audio1_div2" };
827
NM_CLK(tconlcd_clk,
828
CLK_TCON_LCD0, "tcon-lcd0", tconlcd_parents, /* id, name, parents */
829
0xB60, /* offset */
830
8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */
831
0, 4, 0, 0, /* m factor */
832
24, 3, /* mux */
833
31, /* gate */
834
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
835
AW_CLK_REPARENT); /* flags */
836
837
static const char *tcontv_parents[] = { "pll_video0", "pll_video0_4x",
838
"pll_video1", "pll_video1_4x", "pll_periph0_2x", "pll_audio1_div2" };
839
NM_CLK(tcontv_clk,
840
CLK_TCON_TV, "tcon-tv", tcontv_parents, /* id, name, parents */
841
0xB80, /* offset */
842
8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */
843
0, 4, 0, 0, /* m factor */
844
24, 3, /* mux */
845
31, /* gate */
846
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
847
AW_CLK_REPARENT); /* flags */
848
849
static const char *tve_parents[] = { "pll_video0", "pll_video0_4x",
850
"pll_video1", "pll_video1_4x", "pll_periph0_2x", "pll_audio1_div2" };
851
NM_CLK(tve_clk,
852
CLK_TVE, "tve", tve_parents, /* id, name, parents */
853
0xBB0, /* offset */
854
8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */
855
0, 4, 0, 0, /* m factor */
856
24, 3, /* mux */
857
31, /* gate */
858
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
859
AW_CLK_REPARENT); /* flags */
860
861
static const char *tvd_parents[] = { "dcxo", "pll_video0", "pll_video1",
862
"pll_periph0" };
863
M_CLK(tvd_clk,
864
CLK_TVD, "tvd", tvd_parents, /* id, name, parents */
865
0xBC0, /* offset */
866
0, 5, 0, 0, /* m factor */
867
24, 3, /* mux */
868
31, /* gate */
869
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
870
AW_CLK_REPARENT); /* flags */
871
872
static const char *ledc_parents[] = { "dcxo", "pll_periph0" };
873
NM_CLK(ledc_clk,
874
CLK_LEDC, "ledc", ledc_parents, /* id, name, parents */
875
0xBF0, /* offset */
876
8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */
877
0, 4, 0, 0, /* m factor */
878
24, 1, /* mux */
879
31, /* gate */
880
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
881
AW_CLK_REPARENT); /* flags */
882
883
static const char *csi_top_parents[] = { "pll_periph0_2x", "pll_video0_2x",
884
"pll_video1_2x" };
885
M_CLK(csi_top_clk,
886
CLK_CSI_TOP, "csi-top", csi_top_parents, /* id, name, parents */
887
0xC04, /* offset */
888
0, 4, 0, 0, /* m factor */
889
24, 3, /* mux */
890
31, /* gate */
891
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
892
AW_CLK_REPARENT); /* flags */
893
894
static const char *csi_mclk_parents[] = { "dcxo", "pll_periph0",
895
"pll_video0", "pll_video1", "pll_audio1_div2", "pll_audio1_div5" };
896
M_CLK(csi_mclk,
897
CLK_CSI_MCLK, /* id */
898
"csi-mclk", /* name */
899
csi_mclk_parents, /* parents */
900
0xC08, /* offset */
901
0, 5, 0, 0, /* m factor */
902
24, 3, /* mux */
903
31, /* gate */
904
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
905
AW_CLK_REPARENT); /* flags */
906
907
/* Use M_CLK to have mux and gate */
908
static const char *tpadc_parents[] = { "dcxo", "pll_audio0" };
909
M_CLK(tpadc_clk,
910
CLK_TPADC, "tpadc", tpadc_parents, /* id, name, parents */
911
0xC50, /* offset */
912
0, 0, 1, AW_CLK_FACTOR_FIXED, /* m factor */
913
24, 2, /* mux */
914
31, /* gate */
915
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
916
AW_CLK_REPARENT); /* flags */
917
918
static const char *dsp_parents[] = { "dcxo", "osc32k", "iosc",
919
"pll_periph0_2x", "pll_audio1_div2" };
920
M_CLK(dsp_clk,
921
CLK_DSP, "dsp", dsp_parents, /* id, name, parents */
922
0xC70, /* offset */
923
0, 5, 0, 0, /* m factor */
924
24, 3, /* mux */
925
31, /* gate */
926
AW_CLK_HAS_GATE | AW_CLK_HAS_MUX |
927
AW_CLK_REPARENT); /* flags */
928
929
static const char *riscv_parents[] = { "dcxo", "osc32k", "iosc",
930
"pll_periph0_800m", "pll_periph0", "pll_cpux", "pll_audio1_div2" };
931
M_CLK(riscv_clk,
932
CLK_RISCV, "riscv", riscv_parents, /* id, name, parents */
933
0xD00, /* offset */
934
0, 5, 0, 0, /* m factor */
935
24, 3, /* mux */
936
0, /* gate */
937
AW_CLK_HAS_MUX | AW_CLK_SET_PARENT); /* flags */
938
939
static const char *riscv_axi_parents[] = { "riscv" };
940
static struct clk_div_table riscv_axi_div_table[] = {
941
{ .value = 1, .divider = 2 },
942
{ .value = 2, .divider = 3 },
943
{ .value = 3, .divider = 4 },
944
{ },
945
};
946
DIV_CLK(riscv_axi_clk,
947
CLK_RISCV_AXI, /* id */
948
"riscv_axi", riscv_axi_parents, /* name, parents */
949
0xD00, /* offset */
950
8, 2, /* shift, width */
951
CLK_DIV_WITH_TABLE, /* flags */
952
riscv_axi_div_table); /* table */
953
954
/* TODO FANOUT */
955
956
static struct aw_ccung_clk ccu_d1_clks[] = {
957
{ .type = AW_CLK_NP, .clk.np = &pll_cpux_clk },
958
{ .type = AW_CLK_NMM, .clk.nmm = &pll_ddr0_clk },
959
{ .type = AW_CLK_NMM, .clk.nmm = &pll_periph0_4x_clk },
960
{ .type = AW_CLK_M, .clk.m = &pll_periph0_2x_clk },
961
{ .type = AW_CLK_M, .clk.m = &pll_periph0_800m_clk },
962
{ .type = AW_CLK_FIXED, .clk.fixed = &pll_periph0_clk },
963
{ .type = AW_CLK_NP, .clk.np = &pll_video0_clk },
964
{ .type = AW_CLK_M, .clk.m = &pll_video0_4x_clk },
965
{ .type = AW_CLK_FIXED, .clk.fixed = &pll_video0_2x_clk },
966
{ .type = AW_CLK_NP, .clk.np = &pll_video1_clk },
967
{ .type = AW_CLK_M, .clk.m = &pll_video1_4x_clk },
968
{ .type = AW_CLK_FIXED, .clk.fixed = &pll_video1_2x_clk },
969
{ .type = AW_CLK_NMM, .clk.nmm = &pll_ve_clk },
970
{ .type = AW_CLK_NMM, .clk.nmm = &pll_audio0_4x_clk },
971
{ .type = AW_CLK_FIXED, .clk.fixed = &pll_audio0_2x_clk },
972
{ .type = AW_CLK_FIXED, .clk.fixed = &pll_audio0_clk },
973
{ .type = AW_CLK_NP, .clk.np = &pll_audio1_clk },
974
{ .type = AW_CLK_M, .clk.m = &pll_audio1_div2_clk },
975
{ .type = AW_CLK_M, .clk.m = &pll_audio1_div5_clk },
976
{ .type = AW_CLK_M, .clk.m = &cpux_clk },
977
{ .type = AW_CLK_M, .clk.m = &cpux_axi_clk },
978
{ .type = AW_CLK_M, .clk.m = &cpux_apb_clk },
979
{ .type = AW_CLK_NM, .clk.nm = &psi_ahb_clk },
980
{ .type = AW_CLK_NM, .clk.nm = &apb0_clk },
981
{ .type = AW_CLK_NM, .clk.nm = &apb1_clk },
982
{ .type = AW_CLK_FIXED, .clk.fixed = &mbus_clk },
983
{ .type = AW_CLK_M, .clk.m = &de_clk },
984
{ .type = AW_CLK_M, .clk.m = &di_clk },
985
{ .type = AW_CLK_M, .clk.m = &g2d_clk },
986
{ .type = AW_CLK_NM, .clk.nm = &ce_clk },
987
{ .type = AW_CLK_M, .clk.m = &ve_clk },
988
{ .type = AW_CLK_NM, .clk.nm = &dram_clk },
989
{ .type = AW_CLK_NM, .clk.nm = &mmc0_clk },
990
{ .type = AW_CLK_NM, .clk.nm = &mmc1_clk },
991
{ .type = AW_CLK_NM, .clk.nm = &mmc2_clk },
992
{ .type = AW_CLK_NM, .clk.nm = &spi0_clk },
993
{ .type = AW_CLK_NM, .clk.nm = &spi1_clk },
994
{ .type = AW_CLK_M, .clk.m = &emac_25m_clk },
995
{ .type = AW_CLK_NM, .clk.nm = &irtx_clk },
996
{ .type = AW_CLK_NM, .clk.nm = &i2s0_clk },
997
{ .type = AW_CLK_NM, .clk.nm = &i2s1_clk },
998
{ .type = AW_CLK_NM, .clk.nm = &i2s2_clk },
999
{ .type = AW_CLK_NM, .clk.nm = &i2s2_asrc_clk },
1000
{ .type = AW_CLK_NM, .clk.nm = &spdif_tx_clk },
1001
{ .type = AW_CLK_NM, .clk.nm = &spdif_rx_clk },
1002
{ .type = AW_CLK_NM, .clk.nm = &dmic_clk },
1003
{ .type = AW_CLK_NM, .clk.nm = &audio_dac_clk },
1004
{ .type = AW_CLK_NM, .clk.nm = &audio_adc_clk },
1005
{ .type = AW_CLK_M, .clk.m = &usb_ohci0_clk },
1006
{ .type = AW_CLK_M, .clk.m = &usb_ohci1_clk },
1007
{ .type = AW_CLK_M, .clk.m = &dsi_clk },
1008
{ .type = AW_CLK_NM, .clk.nm = &tconlcd_clk },
1009
{ .type = AW_CLK_NM, .clk.nm = &tcontv_clk },
1010
{ .type = AW_CLK_NM, .clk.nm = &tve_clk },
1011
{ .type = AW_CLK_M, .clk.m = &tvd_clk },
1012
{ .type = AW_CLK_NM, .clk.nm = &ledc_clk },
1013
{ .type = AW_CLK_M, .clk.m = &csi_top_clk },
1014
{ .type = AW_CLK_M, .clk.m = &csi_mclk },
1015
{ .type = AW_CLK_M, .clk.m = &tpadc_clk },
1016
{ .type = AW_CLK_M, .clk.m = &dsp_clk },
1017
{ .type = AW_CLK_M, .clk.m = &riscv_clk },
1018
{ .type = AW_CLK_DIV, .clk.div = &riscv_axi_clk},
1019
};
1020
1021
static int
1022
ccu_d1_probe(device_t dev)
1023
{
1024
if (!ofw_bus_status_okay(dev))
1025
return (ENXIO);
1026
1027
if (!ofw_bus_is_compatible(dev, "allwinner,sun20i-d1-ccu"))
1028
return (ENXIO);
1029
1030
device_set_desc(dev, "Allwinner D1 Clock Controller Unit");
1031
return (BUS_PROBE_DEFAULT);
1032
}
1033
1034
static int
1035
ccu_d1_attach(device_t dev)
1036
{
1037
struct aw_ccung_softc *sc;
1038
1039
sc = device_get_softc(dev);
1040
1041
sc->resets = ccu_d1_resets;
1042
sc->nresets = nitems(ccu_d1_resets);
1043
sc->gates = ccu_d1_gates;
1044
sc->ngates = nitems(ccu_d1_gates);
1045
sc->clks = ccu_d1_clks;
1046
sc->nclks = nitems(ccu_d1_clks);
1047
1048
return (aw_ccung_attach(dev));
1049
}
1050
1051
static device_method_t ccu_d1_methods[] = {
1052
DEVMETHOD(device_probe, ccu_d1_probe),
1053
DEVMETHOD(device_attach, ccu_d1_attach),
1054
1055
DEVMETHOD_END
1056
};
1057
1058
DEFINE_CLASS_1(ccu_d1, ccu_d1_driver, ccu_d1_methods,
1059
sizeof(struct aw_ccung_softc), aw_ccung_driver);
1060
1061
EARLY_DRIVER_MODULE(ccu_d1, simplebus, ccu_d1_driver, 0, 0,
1062
BUS_PASS_RESOURCE + BUS_PASS_ORDER_MIDDLE);
1063
1064