blob: 13fc0006f63d82f4de17a376ecafe9344907e93f [file] [log] [blame]
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * AmLogic Meson-AXG Clock Controller Driver
4 *
5 * Copyright (c) 2016 Baylibre SAS.
6 * Author: Michael Turquette <mturquette@baylibre.com>
7 *
8 * Copyright (c) 2017 Amlogic, inc.
9 * Author: Qiufang Dai <qiufang.dai@amlogic.com>
10 */
11
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000012#include <linux/clk-provider.h>
13#include <linux/init.h>
14#include <linux/of_device.h>
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000015#include <linux/platform_device.h>
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000016
David Brazdil0f672f62019-12-10 10:32:29 +000017#include "clk-regmap.h"
18#include "clk-pll.h"
19#include "clk-mpll.h"
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000020#include "axg.h"
David Brazdil0f672f62019-12-10 10:32:29 +000021#include "meson-eeclk.h"
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000022
23static DEFINE_SPINLOCK(meson_clk_lock);
24
David Brazdil0f672f62019-12-10 10:32:29 +000025static struct clk_regmap axg_fixed_pll_dco = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000026 .data = &(struct meson_clk_pll_data){
David Brazdil0f672f62019-12-10 10:32:29 +000027 .en = {
28 .reg_off = HHI_MPLL_CNTL,
29 .shift = 30,
30 .width = 1,
31 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000032 .m = {
33 .reg_off = HHI_MPLL_CNTL,
34 .shift = 0,
35 .width = 9,
36 },
37 .n = {
38 .reg_off = HHI_MPLL_CNTL,
39 .shift = 9,
40 .width = 5,
41 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000042 .frac = {
43 .reg_off = HHI_MPLL_CNTL2,
44 .shift = 0,
45 .width = 12,
46 },
47 .l = {
48 .reg_off = HHI_MPLL_CNTL,
49 .shift = 31,
50 .width = 1,
51 },
52 .rst = {
53 .reg_off = HHI_MPLL_CNTL,
54 .shift = 29,
55 .width = 1,
56 },
57 },
58 .hw.init = &(struct clk_init_data){
David Brazdil0f672f62019-12-10 10:32:29 +000059 .name = "fixed_pll_dco",
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000060 .ops = &meson_clk_pll_ro_ops,
David Brazdil0f672f62019-12-10 10:32:29 +000061 .parent_data = &(const struct clk_parent_data) {
62 .fw_name = "xtal",
63 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000064 .num_parents = 1,
65 },
66};
67
David Brazdil0f672f62019-12-10 10:32:29 +000068static struct clk_regmap axg_fixed_pll = {
69 .data = &(struct clk_regmap_div_data){
70 .offset = HHI_MPLL_CNTL,
71 .shift = 16,
72 .width = 2,
73 .flags = CLK_DIVIDER_POWER_OF_TWO,
74 },
75 .hw.init = &(struct clk_init_data){
76 .name = "fixed_pll",
77 .ops = &clk_regmap_divider_ro_ops,
78 .parent_hws = (const struct clk_hw *[]) {
79 &axg_fixed_pll_dco.hw
80 },
81 .num_parents = 1,
82 /*
83 * This clock won't ever change at runtime so
84 * CLK_SET_RATE_PARENT is not required
85 */
86 },
87};
88
89static struct clk_regmap axg_sys_pll_dco = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000090 .data = &(struct meson_clk_pll_data){
David Brazdil0f672f62019-12-10 10:32:29 +000091 .en = {
92 .reg_off = HHI_SYS_PLL_CNTL,
93 .shift = 30,
94 .width = 1,
95 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000096 .m = {
97 .reg_off = HHI_SYS_PLL_CNTL,
98 .shift = 0,
99 .width = 9,
100 },
101 .n = {
102 .reg_off = HHI_SYS_PLL_CNTL,
103 .shift = 9,
104 .width = 5,
105 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000106 .l = {
107 .reg_off = HHI_SYS_PLL_CNTL,
108 .shift = 31,
109 .width = 1,
110 },
111 .rst = {
112 .reg_off = HHI_SYS_PLL_CNTL,
113 .shift = 29,
114 .width = 1,
115 },
116 },
117 .hw.init = &(struct clk_init_data){
David Brazdil0f672f62019-12-10 10:32:29 +0000118 .name = "sys_pll_dco",
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000119 .ops = &meson_clk_pll_ro_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000120 .parent_data = &(const struct clk_parent_data) {
121 .fw_name = "xtal",
122 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000123 .num_parents = 1,
124 },
125};
126
David Brazdil0f672f62019-12-10 10:32:29 +0000127static struct clk_regmap axg_sys_pll = {
128 .data = &(struct clk_regmap_div_data){
129 .offset = HHI_SYS_PLL_CNTL,
130 .shift = 16,
131 .width = 2,
132 .flags = CLK_DIVIDER_POWER_OF_TWO,
133 },
134 .hw.init = &(struct clk_init_data){
135 .name = "sys_pll",
136 .ops = &clk_regmap_divider_ro_ops,
137 .parent_hws = (const struct clk_hw *[]) {
138 &axg_sys_pll_dco.hw
139 },
140 .num_parents = 1,
141 .flags = CLK_SET_RATE_PARENT,
142 },
143};
144
145static const struct pll_params_table axg_gp0_pll_params_table[] = {
146 PLL_PARAMS(40, 1),
147 PLL_PARAMS(41, 1),
148 PLL_PARAMS(42, 1),
149 PLL_PARAMS(43, 1),
150 PLL_PARAMS(44, 1),
151 PLL_PARAMS(45, 1),
152 PLL_PARAMS(46, 1),
153 PLL_PARAMS(47, 1),
154 PLL_PARAMS(48, 1),
155 PLL_PARAMS(49, 1),
156 PLL_PARAMS(50, 1),
157 PLL_PARAMS(51, 1),
158 PLL_PARAMS(52, 1),
159 PLL_PARAMS(53, 1),
160 PLL_PARAMS(54, 1),
161 PLL_PARAMS(55, 1),
162 PLL_PARAMS(56, 1),
163 PLL_PARAMS(57, 1),
164 PLL_PARAMS(58, 1),
165 PLL_PARAMS(59, 1),
166 PLL_PARAMS(60, 1),
167 PLL_PARAMS(61, 1),
168 PLL_PARAMS(62, 1),
169 PLL_PARAMS(63, 1),
170 PLL_PARAMS(64, 1),
171 PLL_PARAMS(65, 1),
172 PLL_PARAMS(66, 1),
173 PLL_PARAMS(67, 1),
174 PLL_PARAMS(68, 1),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000175 { /* sentinel */ },
176};
177
178static const struct reg_sequence axg_gp0_init_regs[] = {
179 { .reg = HHI_GP0_PLL_CNTL1, .def = 0xc084b000 },
180 { .reg = HHI_GP0_PLL_CNTL2, .def = 0xb75020be },
181 { .reg = HHI_GP0_PLL_CNTL3, .def = 0x0a59a288 },
182 { .reg = HHI_GP0_PLL_CNTL4, .def = 0xc000004d },
183 { .reg = HHI_GP0_PLL_CNTL5, .def = 0x00078000 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000184};
185
David Brazdil0f672f62019-12-10 10:32:29 +0000186static struct clk_regmap axg_gp0_pll_dco = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000187 .data = &(struct meson_clk_pll_data){
David Brazdil0f672f62019-12-10 10:32:29 +0000188 .en = {
189 .reg_off = HHI_GP0_PLL_CNTL,
190 .shift = 30,
191 .width = 1,
192 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000193 .m = {
194 .reg_off = HHI_GP0_PLL_CNTL,
195 .shift = 0,
196 .width = 9,
197 },
198 .n = {
199 .reg_off = HHI_GP0_PLL_CNTL,
200 .shift = 9,
201 .width = 5,
202 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000203 .frac = {
204 .reg_off = HHI_GP0_PLL_CNTL1,
205 .shift = 0,
206 .width = 10,
207 },
208 .l = {
209 .reg_off = HHI_GP0_PLL_CNTL,
210 .shift = 31,
211 .width = 1,
212 },
213 .rst = {
214 .reg_off = HHI_GP0_PLL_CNTL,
215 .shift = 29,
216 .width = 1,
217 },
David Brazdil0f672f62019-12-10 10:32:29 +0000218 .table = axg_gp0_pll_params_table,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000219 .init_regs = axg_gp0_init_regs,
220 .init_count = ARRAY_SIZE(axg_gp0_init_regs),
221 },
222 .hw.init = &(struct clk_init_data){
David Brazdil0f672f62019-12-10 10:32:29 +0000223 .name = "gp0_pll_dco",
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000224 .ops = &meson_clk_pll_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000225 .parent_data = &(const struct clk_parent_data) {
226 .fw_name = "xtal",
227 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000228 .num_parents = 1,
229 },
230};
231
David Brazdil0f672f62019-12-10 10:32:29 +0000232static struct clk_regmap axg_gp0_pll = {
233 .data = &(struct clk_regmap_div_data){
234 .offset = HHI_GP0_PLL_CNTL,
235 .shift = 16,
236 .width = 2,
237 .flags = CLK_DIVIDER_POWER_OF_TWO,
238 },
239 .hw.init = &(struct clk_init_data){
240 .name = "gp0_pll",
241 .ops = &clk_regmap_divider_ops,
242 .parent_hws = (const struct clk_hw *[]) {
243 &axg_gp0_pll_dco.hw
244 },
245 .num_parents = 1,
246 .flags = CLK_SET_RATE_PARENT,
247 },
248};
249
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000250static const struct reg_sequence axg_hifi_init_regs[] = {
251 { .reg = HHI_HIFI_PLL_CNTL1, .def = 0xc084b000 },
252 { .reg = HHI_HIFI_PLL_CNTL2, .def = 0xb75020be },
253 { .reg = HHI_HIFI_PLL_CNTL3, .def = 0x0a6a3a88 },
254 { .reg = HHI_HIFI_PLL_CNTL4, .def = 0xc000004d },
255 { .reg = HHI_HIFI_PLL_CNTL5, .def = 0x00058000 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000256};
257
David Brazdil0f672f62019-12-10 10:32:29 +0000258static struct clk_regmap axg_hifi_pll_dco = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000259 .data = &(struct meson_clk_pll_data){
David Brazdil0f672f62019-12-10 10:32:29 +0000260 .en = {
261 .reg_off = HHI_HIFI_PLL_CNTL,
262 .shift = 30,
263 .width = 1,
264 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000265 .m = {
266 .reg_off = HHI_HIFI_PLL_CNTL,
267 .shift = 0,
268 .width = 9,
269 },
270 .n = {
271 .reg_off = HHI_HIFI_PLL_CNTL,
272 .shift = 9,
273 .width = 5,
274 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000275 .frac = {
276 .reg_off = HHI_HIFI_PLL_CNTL5,
277 .shift = 0,
278 .width = 13,
279 },
280 .l = {
281 .reg_off = HHI_HIFI_PLL_CNTL,
282 .shift = 31,
283 .width = 1,
284 },
285 .rst = {
286 .reg_off = HHI_HIFI_PLL_CNTL,
287 .shift = 29,
288 .width = 1,
289 },
David Brazdil0f672f62019-12-10 10:32:29 +0000290 .table = axg_gp0_pll_params_table,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000291 .init_regs = axg_hifi_init_regs,
292 .init_count = ARRAY_SIZE(axg_hifi_init_regs),
293 .flags = CLK_MESON_PLL_ROUND_CLOSEST,
294 },
295 .hw.init = &(struct clk_init_data){
David Brazdil0f672f62019-12-10 10:32:29 +0000296 .name = "hifi_pll_dco",
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000297 .ops = &meson_clk_pll_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000298 .parent_data = &(const struct clk_parent_data) {
299 .fw_name = "xtal",
300 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000301 .num_parents = 1,
302 },
303};
304
David Brazdil0f672f62019-12-10 10:32:29 +0000305static struct clk_regmap axg_hifi_pll = {
306 .data = &(struct clk_regmap_div_data){
307 .offset = HHI_HIFI_PLL_CNTL,
308 .shift = 16,
309 .width = 2,
310 .flags = CLK_DIVIDER_POWER_OF_TWO,
311 },
312 .hw.init = &(struct clk_init_data){
313 .name = "hifi_pll",
314 .ops = &clk_regmap_divider_ops,
315 .parent_hws = (const struct clk_hw *[]) {
316 &axg_hifi_pll_dco.hw
317 },
318 .num_parents = 1,
319 .flags = CLK_SET_RATE_PARENT,
320 },
321};
322
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000323static struct clk_fixed_factor axg_fclk_div2_div = {
324 .mult = 1,
325 .div = 2,
326 .hw.init = &(struct clk_init_data){
327 .name = "fclk_div2_div",
328 .ops = &clk_fixed_factor_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000329 .parent_hws = (const struct clk_hw *[]) { &axg_fixed_pll.hw },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000330 .num_parents = 1,
331 },
332};
333
334static struct clk_regmap axg_fclk_div2 = {
335 .data = &(struct clk_regmap_gate_data){
336 .offset = HHI_MPLL_CNTL6,
337 .bit_idx = 27,
338 },
339 .hw.init = &(struct clk_init_data){
340 .name = "fclk_div2",
341 .ops = &clk_regmap_gate_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000342 .parent_hws = (const struct clk_hw *[]) {
343 &axg_fclk_div2_div.hw
344 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000345 .num_parents = 1,
346 .flags = CLK_IS_CRITICAL,
347 },
348};
349
350static struct clk_fixed_factor axg_fclk_div3_div = {
351 .mult = 1,
352 .div = 3,
353 .hw.init = &(struct clk_init_data){
354 .name = "fclk_div3_div",
355 .ops = &clk_fixed_factor_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000356 .parent_hws = (const struct clk_hw *[]) { &axg_fixed_pll.hw },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000357 .num_parents = 1,
358 },
359};
360
361static struct clk_regmap axg_fclk_div3 = {
362 .data = &(struct clk_regmap_gate_data){
363 .offset = HHI_MPLL_CNTL6,
364 .bit_idx = 28,
365 },
366 .hw.init = &(struct clk_init_data){
367 .name = "fclk_div3",
368 .ops = &clk_regmap_gate_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000369 .parent_hws = (const struct clk_hw *[]) {
370 &axg_fclk_div3_div.hw
371 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000372 .num_parents = 1,
373 /*
374 * FIXME:
375 * This clock, as fdiv2, is used by the SCPI FW and is required
376 * by the platform to operate correctly.
377 * Until the following condition are met, we need this clock to
378 * be marked as critical:
379 * a) The SCPI generic driver claims and enable all the clocks
380 * it needs
381 * b) CCF has a clock hand-off mechanism to make the sure the
382 * clock stays on until the proper driver comes along
383 */
384 .flags = CLK_IS_CRITICAL,
385 },
386};
387
388static struct clk_fixed_factor axg_fclk_div4_div = {
389 .mult = 1,
390 .div = 4,
391 .hw.init = &(struct clk_init_data){
392 .name = "fclk_div4_div",
393 .ops = &clk_fixed_factor_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000394 .parent_hws = (const struct clk_hw *[]) { &axg_fixed_pll.hw },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000395 .num_parents = 1,
396 },
397};
398
399static struct clk_regmap axg_fclk_div4 = {
400 .data = &(struct clk_regmap_gate_data){
401 .offset = HHI_MPLL_CNTL6,
402 .bit_idx = 29,
403 },
404 .hw.init = &(struct clk_init_data){
405 .name = "fclk_div4",
406 .ops = &clk_regmap_gate_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000407 .parent_hws = (const struct clk_hw *[]) {
408 &axg_fclk_div4_div.hw
409 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000410 .num_parents = 1,
411 },
412};
413
414static struct clk_fixed_factor axg_fclk_div5_div = {
415 .mult = 1,
416 .div = 5,
417 .hw.init = &(struct clk_init_data){
418 .name = "fclk_div5_div",
419 .ops = &clk_fixed_factor_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000420 .parent_hws = (const struct clk_hw *[]) { &axg_fixed_pll.hw },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000421 .num_parents = 1,
422 },
423};
424
425static struct clk_regmap axg_fclk_div5 = {
426 .data = &(struct clk_regmap_gate_data){
427 .offset = HHI_MPLL_CNTL6,
428 .bit_idx = 30,
429 },
430 .hw.init = &(struct clk_init_data){
431 .name = "fclk_div5",
432 .ops = &clk_regmap_gate_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000433 .parent_hws = (const struct clk_hw *[]) {
434 &axg_fclk_div5_div.hw
435 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000436 .num_parents = 1,
437 },
438};
439
440static struct clk_fixed_factor axg_fclk_div7_div = {
441 .mult = 1,
442 .div = 7,
443 .hw.init = &(struct clk_init_data){
444 .name = "fclk_div7_div",
445 .ops = &clk_fixed_factor_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000446 .parent_hws = (const struct clk_hw *[]) {
447 &axg_fixed_pll.hw
448 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000449 .num_parents = 1,
450 },
451};
452
453static struct clk_regmap axg_fclk_div7 = {
454 .data = &(struct clk_regmap_gate_data){
455 .offset = HHI_MPLL_CNTL6,
456 .bit_idx = 31,
457 },
458 .hw.init = &(struct clk_init_data){
459 .name = "fclk_div7",
460 .ops = &clk_regmap_gate_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000461 .parent_hws = (const struct clk_hw *[]) {
462 &axg_fclk_div7_div.hw
463 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000464 .num_parents = 1,
465 },
466};
467
468static struct clk_regmap axg_mpll_prediv = {
469 .data = &(struct clk_regmap_div_data){
470 .offset = HHI_MPLL_CNTL5,
471 .shift = 12,
472 .width = 1,
473 },
474 .hw.init = &(struct clk_init_data){
475 .name = "mpll_prediv",
476 .ops = &clk_regmap_divider_ro_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000477 .parent_hws = (const struct clk_hw *[]) {
478 &axg_fixed_pll.hw
479 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000480 .num_parents = 1,
481 },
482};
483
484static struct clk_regmap axg_mpll0_div = {
485 .data = &(struct meson_clk_mpll_data){
486 .sdm = {
487 .reg_off = HHI_MPLL_CNTL7,
488 .shift = 0,
489 .width = 14,
490 },
491 .sdm_en = {
492 .reg_off = HHI_MPLL_CNTL7,
493 .shift = 15,
494 .width = 1,
495 },
496 .n2 = {
497 .reg_off = HHI_MPLL_CNTL7,
498 .shift = 16,
499 .width = 9,
500 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000501 .misc = {
502 .reg_off = HHI_PLL_TOP_MISC,
503 .shift = 0,
504 .width = 1,
505 },
506 .lock = &meson_clk_lock,
507 .flags = CLK_MESON_MPLL_ROUND_CLOSEST,
508 },
509 .hw.init = &(struct clk_init_data){
510 .name = "mpll0_div",
511 .ops = &meson_clk_mpll_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000512 .parent_hws = (const struct clk_hw *[]) {
513 &axg_mpll_prediv.hw
514 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000515 .num_parents = 1,
516 },
517};
518
519static struct clk_regmap axg_mpll0 = {
520 .data = &(struct clk_regmap_gate_data){
521 .offset = HHI_MPLL_CNTL7,
522 .bit_idx = 14,
523 },
524 .hw.init = &(struct clk_init_data){
525 .name = "mpll0",
526 .ops = &clk_regmap_gate_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000527 .parent_hws = (const struct clk_hw *[]) {
528 &axg_mpll0_div.hw
529 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000530 .num_parents = 1,
531 .flags = CLK_SET_RATE_PARENT,
532 },
533};
534
535static struct clk_regmap axg_mpll1_div = {
536 .data = &(struct meson_clk_mpll_data){
537 .sdm = {
538 .reg_off = HHI_MPLL_CNTL8,
539 .shift = 0,
540 .width = 14,
541 },
542 .sdm_en = {
543 .reg_off = HHI_MPLL_CNTL8,
544 .shift = 15,
545 .width = 1,
546 },
547 .n2 = {
548 .reg_off = HHI_MPLL_CNTL8,
549 .shift = 16,
550 .width = 9,
551 },
552 .misc = {
553 .reg_off = HHI_PLL_TOP_MISC,
554 .shift = 1,
555 .width = 1,
556 },
557 .lock = &meson_clk_lock,
558 .flags = CLK_MESON_MPLL_ROUND_CLOSEST,
559 },
560 .hw.init = &(struct clk_init_data){
561 .name = "mpll1_div",
562 .ops = &meson_clk_mpll_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000563 .parent_hws = (const struct clk_hw *[]) {
564 &axg_mpll_prediv.hw
565 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000566 .num_parents = 1,
567 },
568};
569
570static struct clk_regmap axg_mpll1 = {
571 .data = &(struct clk_regmap_gate_data){
572 .offset = HHI_MPLL_CNTL8,
573 .bit_idx = 14,
574 },
575 .hw.init = &(struct clk_init_data){
576 .name = "mpll1",
577 .ops = &clk_regmap_gate_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000578 .parent_hws = (const struct clk_hw *[]) {
579 &axg_mpll1_div.hw
580 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000581 .num_parents = 1,
582 .flags = CLK_SET_RATE_PARENT,
583 },
584};
585
586static struct clk_regmap axg_mpll2_div = {
587 .data = &(struct meson_clk_mpll_data){
588 .sdm = {
589 .reg_off = HHI_MPLL_CNTL9,
590 .shift = 0,
591 .width = 14,
592 },
593 .sdm_en = {
594 .reg_off = HHI_MPLL_CNTL9,
595 .shift = 15,
596 .width = 1,
597 },
598 .n2 = {
599 .reg_off = HHI_MPLL_CNTL9,
600 .shift = 16,
601 .width = 9,
602 },
David Brazdil0f672f62019-12-10 10:32:29 +0000603 .ssen = {
604 .reg_off = HHI_MPLL_CNTL,
605 .shift = 25,
606 .width = 1,
607 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000608 .misc = {
609 .reg_off = HHI_PLL_TOP_MISC,
610 .shift = 2,
611 .width = 1,
612 },
613 .lock = &meson_clk_lock,
614 .flags = CLK_MESON_MPLL_ROUND_CLOSEST,
615 },
616 .hw.init = &(struct clk_init_data){
617 .name = "mpll2_div",
618 .ops = &meson_clk_mpll_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000619 .parent_hws = (const struct clk_hw *[]) {
620 &axg_mpll_prediv.hw
621 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000622 .num_parents = 1,
623 },
624};
625
626static struct clk_regmap axg_mpll2 = {
627 .data = &(struct clk_regmap_gate_data){
628 .offset = HHI_MPLL_CNTL9,
629 .bit_idx = 14,
630 },
631 .hw.init = &(struct clk_init_data){
632 .name = "mpll2",
633 .ops = &clk_regmap_gate_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000634 .parent_hws = (const struct clk_hw *[]) {
635 &axg_mpll2_div.hw
636 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000637 .num_parents = 1,
638 .flags = CLK_SET_RATE_PARENT,
639 },
640};
641
642static struct clk_regmap axg_mpll3_div = {
643 .data = &(struct meson_clk_mpll_data){
644 .sdm = {
645 .reg_off = HHI_MPLL3_CNTL0,
646 .shift = 12,
647 .width = 14,
648 },
649 .sdm_en = {
650 .reg_off = HHI_MPLL3_CNTL0,
651 .shift = 11,
652 .width = 1,
653 },
654 .n2 = {
655 .reg_off = HHI_MPLL3_CNTL0,
656 .shift = 2,
657 .width = 9,
658 },
659 .misc = {
660 .reg_off = HHI_PLL_TOP_MISC,
661 .shift = 3,
662 .width = 1,
663 },
664 .lock = &meson_clk_lock,
665 .flags = CLK_MESON_MPLL_ROUND_CLOSEST,
666 },
667 .hw.init = &(struct clk_init_data){
668 .name = "mpll3_div",
669 .ops = &meson_clk_mpll_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000670 .parent_hws = (const struct clk_hw *[]) {
671 &axg_mpll_prediv.hw
672 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000673 .num_parents = 1,
674 },
675};
676
677static struct clk_regmap axg_mpll3 = {
678 .data = &(struct clk_regmap_gate_data){
679 .offset = HHI_MPLL3_CNTL0,
680 .bit_idx = 0,
681 },
682 .hw.init = &(struct clk_init_data){
683 .name = "mpll3",
684 .ops = &clk_regmap_gate_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000685 .parent_hws = (const struct clk_hw *[]) {
686 &axg_mpll3_div.hw
687 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000688 .num_parents = 1,
689 .flags = CLK_SET_RATE_PARENT,
690 },
691};
692
David Brazdil0f672f62019-12-10 10:32:29 +0000693static const struct pll_params_table axg_pcie_pll_params_table[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000694 {
David Brazdil0f672f62019-12-10 10:32:29 +0000695 .m = 200,
696 .n = 3,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000697 },
698 { /* sentinel */ },
699};
700
701static const struct reg_sequence axg_pcie_init_regs[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000702 { .reg = HHI_PCIE_PLL_CNTL1, .def = 0x0084a2aa },
703 { .reg = HHI_PCIE_PLL_CNTL2, .def = 0xb75020be },
704 { .reg = HHI_PCIE_PLL_CNTL3, .def = 0x0a47488e },
705 { .reg = HHI_PCIE_PLL_CNTL4, .def = 0xc000004d },
706 { .reg = HHI_PCIE_PLL_CNTL5, .def = 0x00078000 },
707 { .reg = HHI_PCIE_PLL_CNTL6, .def = 0x002323c6 },
David Brazdil0f672f62019-12-10 10:32:29 +0000708 { .reg = HHI_PCIE_PLL_CNTL, .def = 0x400106c8 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000709};
710
David Brazdil0f672f62019-12-10 10:32:29 +0000711static struct clk_regmap axg_pcie_pll_dco = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000712 .data = &(struct meson_clk_pll_data){
David Brazdil0f672f62019-12-10 10:32:29 +0000713 .en = {
714 .reg_off = HHI_PCIE_PLL_CNTL,
715 .shift = 30,
716 .width = 1,
717 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000718 .m = {
719 .reg_off = HHI_PCIE_PLL_CNTL,
720 .shift = 0,
721 .width = 9,
722 },
723 .n = {
724 .reg_off = HHI_PCIE_PLL_CNTL,
725 .shift = 9,
726 .width = 5,
727 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000728 .frac = {
729 .reg_off = HHI_PCIE_PLL_CNTL1,
730 .shift = 0,
731 .width = 12,
732 },
733 .l = {
734 .reg_off = HHI_PCIE_PLL_CNTL,
735 .shift = 31,
736 .width = 1,
737 },
738 .rst = {
739 .reg_off = HHI_PCIE_PLL_CNTL,
740 .shift = 29,
741 .width = 1,
742 },
David Brazdil0f672f62019-12-10 10:32:29 +0000743 .table = axg_pcie_pll_params_table,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000744 .init_regs = axg_pcie_init_regs,
745 .init_count = ARRAY_SIZE(axg_pcie_init_regs),
746 },
747 .hw.init = &(struct clk_init_data){
David Brazdil0f672f62019-12-10 10:32:29 +0000748 .name = "pcie_pll_dco",
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000749 .ops = &meson_clk_pll_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000750 .parent_data = &(const struct clk_parent_data) {
751 .fw_name = "xtal",
752 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000753 .num_parents = 1,
754 },
755};
756
David Brazdil0f672f62019-12-10 10:32:29 +0000757static struct clk_regmap axg_pcie_pll_od = {
758 .data = &(struct clk_regmap_div_data){
759 .offset = HHI_PCIE_PLL_CNTL,
760 .shift = 16,
761 .width = 2,
762 .flags = CLK_DIVIDER_POWER_OF_TWO,
763 },
764 .hw.init = &(struct clk_init_data){
765 .name = "pcie_pll_od",
766 .ops = &clk_regmap_divider_ops,
767 .parent_hws = (const struct clk_hw *[]) {
768 &axg_pcie_pll_dco.hw
769 },
770 .num_parents = 1,
771 .flags = CLK_SET_RATE_PARENT,
772 },
773};
774
775static struct clk_regmap axg_pcie_pll = {
776 .data = &(struct clk_regmap_div_data){
777 .offset = HHI_PCIE_PLL_CNTL6,
778 .shift = 6,
779 .width = 2,
780 .flags = CLK_DIVIDER_POWER_OF_TWO,
781 },
782 .hw.init = &(struct clk_init_data){
783 .name = "pcie_pll",
784 .ops = &clk_regmap_divider_ops,
785 .parent_hws = (const struct clk_hw *[]) {
786 &axg_pcie_pll_od.hw
787 },
788 .num_parents = 1,
789 .flags = CLK_SET_RATE_PARENT,
790 },
791};
792
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000793static struct clk_regmap axg_pcie_mux = {
794 .data = &(struct clk_regmap_mux_data){
795 .offset = HHI_PCIE_PLL_CNTL6,
796 .mask = 0x1,
797 .shift = 2,
798 /* skip the parent mpll3, reserved for debug */
799 .table = (u32[]){ 1 },
800 },
801 .hw.init = &(struct clk_init_data){
802 .name = "pcie_mux",
803 .ops = &clk_regmap_mux_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000804 .parent_hws = (const struct clk_hw *[]) { &axg_pcie_pll.hw },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000805 .num_parents = 1,
806 .flags = CLK_SET_RATE_PARENT,
807 },
808};
809
810static struct clk_regmap axg_pcie_ref = {
811 .data = &(struct clk_regmap_mux_data){
812 .offset = HHI_PCIE_PLL_CNTL6,
813 .mask = 0x1,
814 .shift = 1,
815 /* skip the parent 0, reserved for debug */
816 .table = (u32[]){ 1 },
817 },
818 .hw.init = &(struct clk_init_data){
819 .name = "pcie_ref",
820 .ops = &clk_regmap_mux_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000821 .parent_hws = (const struct clk_hw *[]) { &axg_pcie_mux.hw },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000822 .num_parents = 1,
823 .flags = CLK_SET_RATE_PARENT,
824 },
825};
826
827static struct clk_regmap axg_pcie_cml_en0 = {
828 .data = &(struct clk_regmap_gate_data){
829 .offset = HHI_PCIE_PLL_CNTL6,
830 .bit_idx = 4,
831 },
832 .hw.init = &(struct clk_init_data) {
833 .name = "pcie_cml_en0",
834 .ops = &clk_regmap_gate_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000835 .parent_hws = (const struct clk_hw *[]) { &axg_pcie_ref.hw },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000836 .num_parents = 1,
837 .flags = CLK_SET_RATE_PARENT,
838
839 },
840};
841
842static struct clk_regmap axg_pcie_cml_en1 = {
843 .data = &(struct clk_regmap_gate_data){
844 .offset = HHI_PCIE_PLL_CNTL6,
845 .bit_idx = 3,
846 },
847 .hw.init = &(struct clk_init_data) {
848 .name = "pcie_cml_en1",
849 .ops = &clk_regmap_gate_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000850 .parent_hws = (const struct clk_hw *[]) { &axg_pcie_ref.hw },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000851 .num_parents = 1,
852 .flags = CLK_SET_RATE_PARENT,
853 },
854};
855
856static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 };
David Brazdil0f672f62019-12-10 10:32:29 +0000857static const struct clk_parent_data clk81_parent_data[] = {
858 { .fw_name = "xtal", },
859 { .hw = &axg_fclk_div7.hw },
860 { .hw = &axg_mpll1.hw },
861 { .hw = &axg_mpll2.hw },
862 { .hw = &axg_fclk_div4.hw },
863 { .hw = &axg_fclk_div3.hw },
864 { .hw = &axg_fclk_div5.hw },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000865};
866
867static struct clk_regmap axg_mpeg_clk_sel = {
868 .data = &(struct clk_regmap_mux_data){
869 .offset = HHI_MPEG_CLK_CNTL,
870 .mask = 0x7,
871 .shift = 12,
872 .table = mux_table_clk81,
873 },
874 .hw.init = &(struct clk_init_data){
875 .name = "mpeg_clk_sel",
876 .ops = &clk_regmap_mux_ro_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000877 .parent_data = clk81_parent_data,
878 .num_parents = ARRAY_SIZE(clk81_parent_data),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000879 },
880};
881
882static struct clk_regmap axg_mpeg_clk_div = {
883 .data = &(struct clk_regmap_div_data){
884 .offset = HHI_MPEG_CLK_CNTL,
885 .shift = 0,
886 .width = 7,
887 },
888 .hw.init = &(struct clk_init_data){
889 .name = "mpeg_clk_div",
890 .ops = &clk_regmap_divider_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000891 .parent_hws = (const struct clk_hw *[]) {
892 &axg_mpeg_clk_sel.hw
893 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000894 .num_parents = 1,
895 .flags = CLK_SET_RATE_PARENT,
896 },
897};
898
899static struct clk_regmap axg_clk81 = {
900 .data = &(struct clk_regmap_gate_data){
901 .offset = HHI_MPEG_CLK_CNTL,
902 .bit_idx = 7,
903 },
904 .hw.init = &(struct clk_init_data){
905 .name = "clk81",
906 .ops = &clk_regmap_gate_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000907 .parent_hws = (const struct clk_hw *[]) {
908 &axg_mpeg_clk_div.hw
909 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000910 .num_parents = 1,
911 .flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL),
912 },
913};
914
David Brazdil0f672f62019-12-10 10:32:29 +0000915static const struct clk_parent_data axg_sd_emmc_clk0_parent_data[] = {
916 { .fw_name = "xtal", },
917 { .hw = &axg_fclk_div2.hw },
918 { .hw = &axg_fclk_div3.hw },
919 { .hw = &axg_fclk_div5.hw },
920 { .hw = &axg_fclk_div7.hw },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000921 /*
922 * Following these parent clocks, we should also have had mpll2, mpll3
923 * and gp0_pll but these clocks are too precious to be used here. All
924 * the necessary rates for MMC and NAND operation can be acheived using
925 * xtal or fclk_div clocks
926 */
927};
928
929/* SDcard clock */
930static struct clk_regmap axg_sd_emmc_b_clk0_sel = {
931 .data = &(struct clk_regmap_mux_data){
932 .offset = HHI_SD_EMMC_CLK_CNTL,
933 .mask = 0x7,
934 .shift = 25,
935 },
936 .hw.init = &(struct clk_init_data) {
937 .name = "sd_emmc_b_clk0_sel",
938 .ops = &clk_regmap_mux_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000939 .parent_data = axg_sd_emmc_clk0_parent_data,
940 .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_data),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000941 .flags = CLK_SET_RATE_PARENT,
942 },
943};
944
945static struct clk_regmap axg_sd_emmc_b_clk0_div = {
946 .data = &(struct clk_regmap_div_data){
947 .offset = HHI_SD_EMMC_CLK_CNTL,
948 .shift = 16,
949 .width = 7,
950 .flags = CLK_DIVIDER_ROUND_CLOSEST,
951 },
952 .hw.init = &(struct clk_init_data) {
953 .name = "sd_emmc_b_clk0_div",
954 .ops = &clk_regmap_divider_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000955 .parent_hws = (const struct clk_hw *[]) {
956 &axg_sd_emmc_b_clk0_sel.hw
957 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000958 .num_parents = 1,
959 .flags = CLK_SET_RATE_PARENT,
960 },
961};
962
963static struct clk_regmap axg_sd_emmc_b_clk0 = {
964 .data = &(struct clk_regmap_gate_data){
965 .offset = HHI_SD_EMMC_CLK_CNTL,
966 .bit_idx = 23,
967 },
968 .hw.init = &(struct clk_init_data){
969 .name = "sd_emmc_b_clk0",
970 .ops = &clk_regmap_gate_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000971 .parent_hws = (const struct clk_hw *[]) {
972 &axg_sd_emmc_b_clk0_div.hw
973 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000974 .num_parents = 1,
975 .flags = CLK_SET_RATE_PARENT,
976 },
977};
978
979/* EMMC/NAND clock */
980static struct clk_regmap axg_sd_emmc_c_clk0_sel = {
981 .data = &(struct clk_regmap_mux_data){
982 .offset = HHI_NAND_CLK_CNTL,
983 .mask = 0x7,
984 .shift = 9,
985 },
986 .hw.init = &(struct clk_init_data) {
987 .name = "sd_emmc_c_clk0_sel",
988 .ops = &clk_regmap_mux_ops,
David Brazdil0f672f62019-12-10 10:32:29 +0000989 .parent_data = axg_sd_emmc_clk0_parent_data,
990 .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_data),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000991 .flags = CLK_SET_RATE_PARENT,
992 },
993};
994
995static struct clk_regmap axg_sd_emmc_c_clk0_div = {
996 .data = &(struct clk_regmap_div_data){
997 .offset = HHI_NAND_CLK_CNTL,
998 .shift = 0,
999 .width = 7,
1000 .flags = CLK_DIVIDER_ROUND_CLOSEST,
1001 },
1002 .hw.init = &(struct clk_init_data) {
1003 .name = "sd_emmc_c_clk0_div",
1004 .ops = &clk_regmap_divider_ops,
David Brazdil0f672f62019-12-10 10:32:29 +00001005 .parent_hws = (const struct clk_hw *[]) {
1006 &axg_sd_emmc_c_clk0_sel.hw
1007 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001008 .num_parents = 1,
1009 .flags = CLK_SET_RATE_PARENT,
1010 },
1011};
1012
1013static struct clk_regmap axg_sd_emmc_c_clk0 = {
1014 .data = &(struct clk_regmap_gate_data){
1015 .offset = HHI_NAND_CLK_CNTL,
1016 .bit_idx = 7,
1017 },
1018 .hw.init = &(struct clk_init_data){
1019 .name = "sd_emmc_c_clk0",
1020 .ops = &clk_regmap_gate_ops,
David Brazdil0f672f62019-12-10 10:32:29 +00001021 .parent_hws = (const struct clk_hw *[]) {
1022 &axg_sd_emmc_c_clk0_div.hw
1023 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001024 .num_parents = 1,
1025 .flags = CLK_SET_RATE_PARENT,
1026 },
1027};
1028
1029static u32 mux_table_gen_clk[] = { 0, 4, 5, 6, 7, 8,
1030 9, 10, 11, 13, 14, };
David Brazdil0f672f62019-12-10 10:32:29 +00001031static const struct clk_parent_data gen_clk_parent_data[] = {
1032 { .fw_name = "xtal", },
1033 { .hw = &axg_hifi_pll.hw },
1034 { .hw = &axg_mpll0.hw },
1035 { .hw = &axg_mpll1.hw },
1036 { .hw = &axg_mpll2.hw },
1037 { .hw = &axg_mpll3.hw },
1038 { .hw = &axg_fclk_div4.hw },
1039 { .hw = &axg_fclk_div3.hw },
1040 { .hw = &axg_fclk_div5.hw },
1041 { .hw = &axg_fclk_div7.hw },
1042 { .hw = &axg_gp0_pll.hw },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001043};
1044
1045static struct clk_regmap axg_gen_clk_sel = {
1046 .data = &(struct clk_regmap_mux_data){
1047 .offset = HHI_GEN_CLK_CNTL,
1048 .mask = 0xf,
1049 .shift = 12,
1050 .table = mux_table_gen_clk,
1051 },
1052 .hw.init = &(struct clk_init_data){
1053 .name = "gen_clk_sel",
1054 .ops = &clk_regmap_mux_ops,
1055 /*
1056 * bits 15:12 selects from 14 possible parents:
1057 * xtal, [rtc_oscin_i], [sys_cpu_div16], [ddr_dpll_pt],
1058 * hifi_pll, mpll0, mpll1, mpll2, mpll3, fdiv4,
1059 * fdiv3, fdiv5, [cts_msr_clk], fdiv7, gp0_pll
1060 */
David Brazdil0f672f62019-12-10 10:32:29 +00001061 .parent_data = gen_clk_parent_data,
1062 .num_parents = ARRAY_SIZE(gen_clk_parent_data),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001063 },
1064};
1065
1066static struct clk_regmap axg_gen_clk_div = {
1067 .data = &(struct clk_regmap_div_data){
1068 .offset = HHI_GEN_CLK_CNTL,
1069 .shift = 0,
1070 .width = 11,
1071 },
1072 .hw.init = &(struct clk_init_data){
1073 .name = "gen_clk_div",
1074 .ops = &clk_regmap_divider_ops,
David Brazdil0f672f62019-12-10 10:32:29 +00001075 .parent_hws = (const struct clk_hw *[]) {
1076 &axg_gen_clk_sel.hw
1077 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001078 .num_parents = 1,
1079 .flags = CLK_SET_RATE_PARENT,
1080 },
1081};
1082
1083static struct clk_regmap axg_gen_clk = {
1084 .data = &(struct clk_regmap_gate_data){
1085 .offset = HHI_GEN_CLK_CNTL,
1086 .bit_idx = 7,
1087 },
1088 .hw.init = &(struct clk_init_data){
1089 .name = "gen_clk",
1090 .ops = &clk_regmap_gate_ops,
David Brazdil0f672f62019-12-10 10:32:29 +00001091 .parent_hws = (const struct clk_hw *[]) {
1092 &axg_gen_clk_div.hw
1093 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001094 .num_parents = 1,
1095 .flags = CLK_SET_RATE_PARENT,
1096 },
1097};
1098
David Brazdil0f672f62019-12-10 10:32:29 +00001099#define MESON_GATE(_name, _reg, _bit) \
1100 MESON_PCLK(_name, _reg, _bit, &axg_clk81.hw)
1101
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001102/* Everything Else (EE) domain gates */
1103static MESON_GATE(axg_ddr, HHI_GCLK_MPEG0, 0);
1104static MESON_GATE(axg_audio_locker, HHI_GCLK_MPEG0, 2);
1105static MESON_GATE(axg_mipi_dsi_host, HHI_GCLK_MPEG0, 3);
1106static MESON_GATE(axg_isa, HHI_GCLK_MPEG0, 5);
1107static MESON_GATE(axg_pl301, HHI_GCLK_MPEG0, 6);
1108static MESON_GATE(axg_periphs, HHI_GCLK_MPEG0, 7);
1109static MESON_GATE(axg_spicc_0, HHI_GCLK_MPEG0, 8);
1110static MESON_GATE(axg_i2c, HHI_GCLK_MPEG0, 9);
1111static MESON_GATE(axg_rng0, HHI_GCLK_MPEG0, 12);
1112static MESON_GATE(axg_uart0, HHI_GCLK_MPEG0, 13);
1113static MESON_GATE(axg_mipi_dsi_phy, HHI_GCLK_MPEG0, 14);
1114static MESON_GATE(axg_spicc_1, HHI_GCLK_MPEG0, 15);
1115static MESON_GATE(axg_pcie_a, HHI_GCLK_MPEG0, 16);
1116static MESON_GATE(axg_pcie_b, HHI_GCLK_MPEG0, 17);
1117static MESON_GATE(axg_hiu_reg, HHI_GCLK_MPEG0, 19);
1118static MESON_GATE(axg_assist_misc, HHI_GCLK_MPEG0, 23);
1119static MESON_GATE(axg_emmc_b, HHI_GCLK_MPEG0, 25);
1120static MESON_GATE(axg_emmc_c, HHI_GCLK_MPEG0, 26);
1121static MESON_GATE(axg_dma, HHI_GCLK_MPEG0, 27);
1122static MESON_GATE(axg_spi, HHI_GCLK_MPEG0, 30);
1123
1124static MESON_GATE(axg_audio, HHI_GCLK_MPEG1, 0);
1125static MESON_GATE(axg_eth_core, HHI_GCLK_MPEG1, 3);
1126static MESON_GATE(axg_uart1, HHI_GCLK_MPEG1, 16);
1127static MESON_GATE(axg_g2d, HHI_GCLK_MPEG1, 20);
1128static MESON_GATE(axg_usb0, HHI_GCLK_MPEG1, 21);
1129static MESON_GATE(axg_usb1, HHI_GCLK_MPEG1, 22);
1130static MESON_GATE(axg_reset, HHI_GCLK_MPEG1, 23);
1131static MESON_GATE(axg_usb_general, HHI_GCLK_MPEG1, 26);
1132static MESON_GATE(axg_ahb_arb0, HHI_GCLK_MPEG1, 29);
1133static MESON_GATE(axg_efuse, HHI_GCLK_MPEG1, 30);
1134static MESON_GATE(axg_boot_rom, HHI_GCLK_MPEG1, 31);
1135
1136static MESON_GATE(axg_ahb_data_bus, HHI_GCLK_MPEG2, 1);
1137static MESON_GATE(axg_ahb_ctrl_bus, HHI_GCLK_MPEG2, 2);
1138static MESON_GATE(axg_usb1_to_ddr, HHI_GCLK_MPEG2, 8);
1139static MESON_GATE(axg_usb0_to_ddr, HHI_GCLK_MPEG2, 9);
1140static MESON_GATE(axg_mmc_pclk, HHI_GCLK_MPEG2, 11);
1141static MESON_GATE(axg_vpu_intr, HHI_GCLK_MPEG2, 25);
1142static MESON_GATE(axg_sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26);
1143static MESON_GATE(axg_gic, HHI_GCLK_MPEG2, 30);
1144static MESON_GATE(axg_mipi_enable, HHI_MIPI_CNTL0, 29);
1145
1146/* Always On (AO) domain gates */
1147
1148static MESON_GATE(axg_ao_media_cpu, HHI_GCLK_AO, 0);
1149static MESON_GATE(axg_ao_ahb_sram, HHI_GCLK_AO, 1);
1150static MESON_GATE(axg_ao_ahb_bus, HHI_GCLK_AO, 2);
1151static MESON_GATE(axg_ao_iface, HHI_GCLK_AO, 3);
1152static MESON_GATE(axg_ao_i2c, HHI_GCLK_AO, 4);
1153
1154/* Array of all clocks provided by this provider */
1155
1156static struct clk_hw_onecell_data axg_hw_onecell_data = {
1157 .hws = {
1158 [CLKID_SYS_PLL] = &axg_sys_pll.hw,
1159 [CLKID_FIXED_PLL] = &axg_fixed_pll.hw,
1160 [CLKID_FCLK_DIV2] = &axg_fclk_div2.hw,
1161 [CLKID_FCLK_DIV3] = &axg_fclk_div3.hw,
1162 [CLKID_FCLK_DIV4] = &axg_fclk_div4.hw,
1163 [CLKID_FCLK_DIV5] = &axg_fclk_div5.hw,
1164 [CLKID_FCLK_DIV7] = &axg_fclk_div7.hw,
1165 [CLKID_GP0_PLL] = &axg_gp0_pll.hw,
1166 [CLKID_MPEG_SEL] = &axg_mpeg_clk_sel.hw,
1167 [CLKID_MPEG_DIV] = &axg_mpeg_clk_div.hw,
1168 [CLKID_CLK81] = &axg_clk81.hw,
1169 [CLKID_MPLL0] = &axg_mpll0.hw,
1170 [CLKID_MPLL1] = &axg_mpll1.hw,
1171 [CLKID_MPLL2] = &axg_mpll2.hw,
1172 [CLKID_MPLL3] = &axg_mpll3.hw,
1173 [CLKID_DDR] = &axg_ddr.hw,
1174 [CLKID_AUDIO_LOCKER] = &axg_audio_locker.hw,
1175 [CLKID_MIPI_DSI_HOST] = &axg_mipi_dsi_host.hw,
1176 [CLKID_ISA] = &axg_isa.hw,
1177 [CLKID_PL301] = &axg_pl301.hw,
1178 [CLKID_PERIPHS] = &axg_periphs.hw,
1179 [CLKID_SPICC0] = &axg_spicc_0.hw,
1180 [CLKID_I2C] = &axg_i2c.hw,
1181 [CLKID_RNG0] = &axg_rng0.hw,
1182 [CLKID_UART0] = &axg_uart0.hw,
1183 [CLKID_MIPI_DSI_PHY] = &axg_mipi_dsi_phy.hw,
1184 [CLKID_SPICC1] = &axg_spicc_1.hw,
1185 [CLKID_PCIE_A] = &axg_pcie_a.hw,
1186 [CLKID_PCIE_B] = &axg_pcie_b.hw,
1187 [CLKID_HIU_IFACE] = &axg_hiu_reg.hw,
1188 [CLKID_ASSIST_MISC] = &axg_assist_misc.hw,
1189 [CLKID_SD_EMMC_B] = &axg_emmc_b.hw,
1190 [CLKID_SD_EMMC_C] = &axg_emmc_c.hw,
1191 [CLKID_DMA] = &axg_dma.hw,
1192 [CLKID_SPI] = &axg_spi.hw,
1193 [CLKID_AUDIO] = &axg_audio.hw,
1194 [CLKID_ETH] = &axg_eth_core.hw,
1195 [CLKID_UART1] = &axg_uart1.hw,
1196 [CLKID_G2D] = &axg_g2d.hw,
1197 [CLKID_USB0] = &axg_usb0.hw,
1198 [CLKID_USB1] = &axg_usb1.hw,
1199 [CLKID_RESET] = &axg_reset.hw,
1200 [CLKID_USB] = &axg_usb_general.hw,
1201 [CLKID_AHB_ARB0] = &axg_ahb_arb0.hw,
1202 [CLKID_EFUSE] = &axg_efuse.hw,
1203 [CLKID_BOOT_ROM] = &axg_boot_rom.hw,
1204 [CLKID_AHB_DATA_BUS] = &axg_ahb_data_bus.hw,
1205 [CLKID_AHB_CTRL_BUS] = &axg_ahb_ctrl_bus.hw,
1206 [CLKID_USB1_DDR_BRIDGE] = &axg_usb1_to_ddr.hw,
1207 [CLKID_USB0_DDR_BRIDGE] = &axg_usb0_to_ddr.hw,
1208 [CLKID_MMC_PCLK] = &axg_mmc_pclk.hw,
1209 [CLKID_VPU_INTR] = &axg_vpu_intr.hw,
1210 [CLKID_SEC_AHB_AHB3_BRIDGE] = &axg_sec_ahb_ahb3_bridge.hw,
1211 [CLKID_GIC] = &axg_gic.hw,
1212 [CLKID_AO_MEDIA_CPU] = &axg_ao_media_cpu.hw,
1213 [CLKID_AO_AHB_SRAM] = &axg_ao_ahb_sram.hw,
1214 [CLKID_AO_AHB_BUS] = &axg_ao_ahb_bus.hw,
1215 [CLKID_AO_IFACE] = &axg_ao_iface.hw,
1216 [CLKID_AO_I2C] = &axg_ao_i2c.hw,
1217 [CLKID_SD_EMMC_B_CLK0_SEL] = &axg_sd_emmc_b_clk0_sel.hw,
1218 [CLKID_SD_EMMC_B_CLK0_DIV] = &axg_sd_emmc_b_clk0_div.hw,
1219 [CLKID_SD_EMMC_B_CLK0] = &axg_sd_emmc_b_clk0.hw,
1220 [CLKID_SD_EMMC_C_CLK0_SEL] = &axg_sd_emmc_c_clk0_sel.hw,
1221 [CLKID_SD_EMMC_C_CLK0_DIV] = &axg_sd_emmc_c_clk0_div.hw,
1222 [CLKID_SD_EMMC_C_CLK0] = &axg_sd_emmc_c_clk0.hw,
1223 [CLKID_MPLL0_DIV] = &axg_mpll0_div.hw,
1224 [CLKID_MPLL1_DIV] = &axg_mpll1_div.hw,
1225 [CLKID_MPLL2_DIV] = &axg_mpll2_div.hw,
1226 [CLKID_MPLL3_DIV] = &axg_mpll3_div.hw,
1227 [CLKID_HIFI_PLL] = &axg_hifi_pll.hw,
1228 [CLKID_MPLL_PREDIV] = &axg_mpll_prediv.hw,
1229 [CLKID_FCLK_DIV2_DIV] = &axg_fclk_div2_div.hw,
1230 [CLKID_FCLK_DIV3_DIV] = &axg_fclk_div3_div.hw,
1231 [CLKID_FCLK_DIV4_DIV] = &axg_fclk_div4_div.hw,
1232 [CLKID_FCLK_DIV5_DIV] = &axg_fclk_div5_div.hw,
1233 [CLKID_FCLK_DIV7_DIV] = &axg_fclk_div7_div.hw,
1234 [CLKID_PCIE_PLL] = &axg_pcie_pll.hw,
1235 [CLKID_PCIE_MUX] = &axg_pcie_mux.hw,
1236 [CLKID_PCIE_REF] = &axg_pcie_ref.hw,
1237 [CLKID_PCIE_CML_EN0] = &axg_pcie_cml_en0.hw,
1238 [CLKID_PCIE_CML_EN1] = &axg_pcie_cml_en1.hw,
1239 [CLKID_MIPI_ENABLE] = &axg_mipi_enable.hw,
1240 [CLKID_GEN_CLK_SEL] = &axg_gen_clk_sel.hw,
1241 [CLKID_GEN_CLK_DIV] = &axg_gen_clk_div.hw,
1242 [CLKID_GEN_CLK] = &axg_gen_clk.hw,
David Brazdil0f672f62019-12-10 10:32:29 +00001243 [CLKID_SYS_PLL_DCO] = &axg_sys_pll_dco.hw,
1244 [CLKID_FIXED_PLL_DCO] = &axg_fixed_pll_dco.hw,
1245 [CLKID_GP0_PLL_DCO] = &axg_gp0_pll_dco.hw,
1246 [CLKID_HIFI_PLL_DCO] = &axg_hifi_pll_dco.hw,
1247 [CLKID_PCIE_PLL_DCO] = &axg_pcie_pll_dco.hw,
1248 [CLKID_PCIE_PLL_OD] = &axg_pcie_pll_od.hw,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001249 [NR_CLKS] = NULL,
1250 },
1251 .num = NR_CLKS,
1252};
1253
1254/* Convenience table to populate regmap in .probe */
1255static struct clk_regmap *const axg_clk_regmaps[] = {
1256 &axg_clk81,
1257 &axg_ddr,
1258 &axg_audio_locker,
1259 &axg_mipi_dsi_host,
1260 &axg_isa,
1261 &axg_pl301,
1262 &axg_periphs,
1263 &axg_spicc_0,
1264 &axg_i2c,
1265 &axg_rng0,
1266 &axg_uart0,
1267 &axg_mipi_dsi_phy,
1268 &axg_spicc_1,
1269 &axg_pcie_a,
1270 &axg_pcie_b,
1271 &axg_hiu_reg,
1272 &axg_assist_misc,
1273 &axg_emmc_b,
1274 &axg_emmc_c,
1275 &axg_dma,
1276 &axg_spi,
1277 &axg_audio,
1278 &axg_eth_core,
1279 &axg_uart1,
1280 &axg_g2d,
1281 &axg_usb0,
1282 &axg_usb1,
1283 &axg_reset,
1284 &axg_usb_general,
1285 &axg_ahb_arb0,
1286 &axg_efuse,
1287 &axg_boot_rom,
1288 &axg_ahb_data_bus,
1289 &axg_ahb_ctrl_bus,
1290 &axg_usb1_to_ddr,
1291 &axg_usb0_to_ddr,
1292 &axg_mmc_pclk,
1293 &axg_vpu_intr,
1294 &axg_sec_ahb_ahb3_bridge,
1295 &axg_gic,
1296 &axg_ao_media_cpu,
1297 &axg_ao_ahb_sram,
1298 &axg_ao_ahb_bus,
1299 &axg_ao_iface,
1300 &axg_ao_i2c,
1301 &axg_sd_emmc_b_clk0,
1302 &axg_sd_emmc_c_clk0,
1303 &axg_mpeg_clk_div,
1304 &axg_sd_emmc_b_clk0_div,
1305 &axg_sd_emmc_c_clk0_div,
1306 &axg_mpeg_clk_sel,
1307 &axg_sd_emmc_b_clk0_sel,
1308 &axg_sd_emmc_c_clk0_sel,
1309 &axg_mpll0,
1310 &axg_mpll1,
1311 &axg_mpll2,
1312 &axg_mpll3,
1313 &axg_mpll0_div,
1314 &axg_mpll1_div,
1315 &axg_mpll2_div,
1316 &axg_mpll3_div,
1317 &axg_fixed_pll,
1318 &axg_sys_pll,
1319 &axg_gp0_pll,
1320 &axg_hifi_pll,
1321 &axg_mpll_prediv,
1322 &axg_fclk_div2,
1323 &axg_fclk_div3,
1324 &axg_fclk_div4,
1325 &axg_fclk_div5,
1326 &axg_fclk_div7,
David Brazdil0f672f62019-12-10 10:32:29 +00001327 &axg_pcie_pll_dco,
1328 &axg_pcie_pll_od,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001329 &axg_pcie_pll,
1330 &axg_pcie_mux,
1331 &axg_pcie_ref,
1332 &axg_pcie_cml_en0,
1333 &axg_pcie_cml_en1,
1334 &axg_mipi_enable,
1335 &axg_gen_clk_sel,
1336 &axg_gen_clk_div,
1337 &axg_gen_clk,
David Brazdil0f672f62019-12-10 10:32:29 +00001338 &axg_fixed_pll_dco,
1339 &axg_sys_pll_dco,
1340 &axg_gp0_pll_dco,
1341 &axg_hifi_pll_dco,
1342 &axg_pcie_pll_dco,
1343 &axg_pcie_pll_od,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001344};
1345
David Brazdil0f672f62019-12-10 10:32:29 +00001346static const struct meson_eeclkc_data axg_clkc_data = {
1347 .regmap_clks = axg_clk_regmaps,
1348 .regmap_clk_num = ARRAY_SIZE(axg_clk_regmaps),
1349 .hw_onecell_data = &axg_hw_onecell_data,
1350};
1351
1352
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001353static const struct of_device_id clkc_match_table[] = {
David Brazdil0f672f62019-12-10 10:32:29 +00001354 { .compatible = "amlogic,axg-clkc", .data = &axg_clkc_data },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001355 {}
1356};
1357
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001358static struct platform_driver axg_driver = {
David Brazdil0f672f62019-12-10 10:32:29 +00001359 .probe = meson_eeclkc_probe,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001360 .driver = {
1361 .name = "axg-clkc",
1362 .of_match_table = clkc_match_table,
1363 },
1364};
1365
1366builtin_platform_driver(axg_driver);