aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/meson/axg.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/meson/axg.c')
-rw-r--r--drivers/clk/meson/axg.c955
1 files changed, 542 insertions, 413 deletions
diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
index 1294f3ad7cd5..5f5d468c1efe 100644
--- a/drivers/clk/meson/axg.c
+++ b/drivers/clk/meson/axg.c
@@ -11,125 +11,51 @@
11 11
12#include <linux/clk.h> 12#include <linux/clk.h>
13#include <linux/clk-provider.h> 13#include <linux/clk-provider.h>
14#include <linux/init.h>
14#include <linux/of_address.h> 15#include <linux/of_address.h>
15#include <linux/of_device.h> 16#include <linux/of_device.h>
17#include <linux/mfd/syscon.h>
16#include <linux/platform_device.h> 18#include <linux/platform_device.h>
17#include <linux/init.h> 19#include <linux/regmap.h>
18 20
19#include "clkc.h" 21#include "clkc.h"
20#include "axg.h" 22#include "axg.h"
21 23
22static DEFINE_SPINLOCK(meson_clk_lock); 24static DEFINE_SPINLOCK(meson_clk_lock);
23 25
24static const struct pll_rate_table sys_pll_rate_table[] = { 26static struct clk_regmap axg_fixed_pll = {
25 PLL_RATE(24000000, 56, 1, 2), 27 .data = &(struct meson_clk_pll_data){
26 PLL_RATE(48000000, 64, 1, 2), 28 .m = {
27 PLL_RATE(72000000, 72, 1, 2), 29 .reg_off = HHI_MPLL_CNTL,
28 PLL_RATE(96000000, 64, 1, 2), 30 .shift = 0,
29 PLL_RATE(120000000, 80, 1, 2), 31 .width = 9,
30 PLL_RATE(144000000, 96, 1, 2), 32 },
31 PLL_RATE(168000000, 56, 1, 1), 33 .n = {
32 PLL_RATE(192000000, 64, 1, 1), 34 .reg_off = HHI_MPLL_CNTL,
33 PLL_RATE(216000000, 72, 1, 1), 35 .shift = 9,
34 PLL_RATE(240000000, 80, 1, 1), 36 .width = 5,
35 PLL_RATE(264000000, 88, 1, 1), 37 },
36 PLL_RATE(288000000, 96, 1, 1), 38 .od = {
37 PLL_RATE(312000000, 52, 1, 2), 39 .reg_off = HHI_MPLL_CNTL,
38 PLL_RATE(336000000, 56, 1, 2), 40 .shift = 16,
39 PLL_RATE(360000000, 60, 1, 2), 41 .width = 2,
40 PLL_RATE(384000000, 64, 1, 2), 42 },
41 PLL_RATE(408000000, 68, 1, 2), 43 .frac = {
42 PLL_RATE(432000000, 72, 1, 2), 44 .reg_off = HHI_MPLL_CNTL2,
43 PLL_RATE(456000000, 76, 1, 2), 45 .shift = 0,
44 PLL_RATE(480000000, 80, 1, 2), 46 .width = 12,
45 PLL_RATE(504000000, 84, 1, 2), 47 },
46 PLL_RATE(528000000, 88, 1, 2), 48 .l = {
47 PLL_RATE(552000000, 92, 1, 2), 49 .reg_off = HHI_MPLL_CNTL,
48 PLL_RATE(576000000, 96, 1, 2), 50 .shift = 31,
49 PLL_RATE(600000000, 50, 1, 1), 51 .width = 1,
50 PLL_RATE(624000000, 52, 1, 1), 52 },
51 PLL_RATE(648000000, 54, 1, 1), 53 .rst = {
52 PLL_RATE(672000000, 56, 1, 1), 54 .reg_off = HHI_MPLL_CNTL,
53 PLL_RATE(696000000, 58, 1, 1), 55 .shift = 29,
54 PLL_RATE(720000000, 60, 1, 1), 56 .width = 1,
55 PLL_RATE(744000000, 62, 1, 1), 57 },
56 PLL_RATE(768000000, 64, 1, 1),
57 PLL_RATE(792000000, 66, 1, 1),
58 PLL_RATE(816000000, 68, 1, 1),
59 PLL_RATE(840000000, 70, 1, 1),
60 PLL_RATE(864000000, 72, 1, 1),
61 PLL_RATE(888000000, 74, 1, 1),
62 PLL_RATE(912000000, 76, 1, 1),
63 PLL_RATE(936000000, 78, 1, 1),
64 PLL_RATE(960000000, 80, 1, 1),
65 PLL_RATE(984000000, 82, 1, 1),
66 PLL_RATE(1008000000, 84, 1, 1),
67 PLL_RATE(1032000000, 86, 1, 1),
68 PLL_RATE(1056000000, 88, 1, 1),
69 PLL_RATE(1080000000, 90, 1, 1),
70 PLL_RATE(1104000000, 92, 1, 1),
71 PLL_RATE(1128000000, 94, 1, 1),
72 PLL_RATE(1152000000, 96, 1, 1),
73 PLL_RATE(1176000000, 98, 1, 1),
74 PLL_RATE(1200000000, 50, 1, 0),
75 PLL_RATE(1224000000, 51, 1, 0),
76 PLL_RATE(1248000000, 52, 1, 0),
77 PLL_RATE(1272000000, 53, 1, 0),
78 PLL_RATE(1296000000, 54, 1, 0),
79 PLL_RATE(1320000000, 55, 1, 0),
80 PLL_RATE(1344000000, 56, 1, 0),
81 PLL_RATE(1368000000, 57, 1, 0),
82 PLL_RATE(1392000000, 58, 1, 0),
83 PLL_RATE(1416000000, 59, 1, 0),
84 PLL_RATE(1440000000, 60, 1, 0),
85 PLL_RATE(1464000000, 61, 1, 0),
86 PLL_RATE(1488000000, 62, 1, 0),
87 PLL_RATE(1512000000, 63, 1, 0),
88 PLL_RATE(1536000000, 64, 1, 0),
89 PLL_RATE(1560000000, 65, 1, 0),
90 PLL_RATE(1584000000, 66, 1, 0),
91 PLL_RATE(1608000000, 67, 1, 0),
92 PLL_RATE(1632000000, 68, 1, 0),
93 PLL_RATE(1656000000, 68, 1, 0),
94 PLL_RATE(1680000000, 68, 1, 0),
95 PLL_RATE(1704000000, 68, 1, 0),
96 PLL_RATE(1728000000, 69, 1, 0),
97 PLL_RATE(1752000000, 69, 1, 0),
98 PLL_RATE(1776000000, 69, 1, 0),
99 PLL_RATE(1800000000, 69, 1, 0),
100 PLL_RATE(1824000000, 70, 1, 0),
101 PLL_RATE(1848000000, 70, 1, 0),
102 PLL_RATE(1872000000, 70, 1, 0),
103 PLL_RATE(1896000000, 70, 1, 0),
104 PLL_RATE(1920000000, 71, 1, 0),
105 PLL_RATE(1944000000, 71, 1, 0),
106 PLL_RATE(1968000000, 71, 1, 0),
107 PLL_RATE(1992000000, 71, 1, 0),
108 PLL_RATE(2016000000, 72, 1, 0),
109 PLL_RATE(2040000000, 72, 1, 0),
110 PLL_RATE(2064000000, 72, 1, 0),
111 PLL_RATE(2088000000, 72, 1, 0),
112 PLL_RATE(2112000000, 73, 1, 0),
113 { /* sentinel */ },
114};
115
116static struct meson_clk_pll axg_fixed_pll = {
117 .m = {
118 .reg_off = HHI_MPLL_CNTL,
119 .shift = 0,
120 .width = 9,
121 },
122 .n = {
123 .reg_off = HHI_MPLL_CNTL,
124 .shift = 9,
125 .width = 5,
126 },
127 .od = {
128 .reg_off = HHI_MPLL_CNTL,
129 .shift = 16,
130 .width = 2,
131 }, 58 },
132 .lock = &meson_clk_lock,
133 .hw.init = &(struct clk_init_data){ 59 .hw.init = &(struct clk_init_data){
134 .name = "fixed_pll", 60 .name = "fixed_pll",
135 .ops = &meson_clk_pll_ro_ops, 61 .ops = &meson_clk_pll_ro_ops,
@@ -138,25 +64,34 @@ static struct meson_clk_pll axg_fixed_pll = {
138 }, 64 },
139}; 65};
140 66
141static struct meson_clk_pll axg_sys_pll = { 67static struct clk_regmap axg_sys_pll = {
142 .m = { 68 .data = &(struct meson_clk_pll_data){
143 .reg_off = HHI_SYS_PLL_CNTL, 69 .m = {
144 .shift = 0, 70 .reg_off = HHI_SYS_PLL_CNTL,
145 .width = 9, 71 .shift = 0,
72 .width = 9,
73 },
74 .n = {
75 .reg_off = HHI_SYS_PLL_CNTL,
76 .shift = 9,
77 .width = 5,
78 },
79 .od = {
80 .reg_off = HHI_SYS_PLL_CNTL,
81 .shift = 16,
82 .width = 2,
83 },
84 .l = {
85 .reg_off = HHI_SYS_PLL_CNTL,
86 .shift = 31,
87 .width = 1,
88 },
89 .rst = {
90 .reg_off = HHI_SYS_PLL_CNTL,
91 .shift = 29,
92 .width = 1,
93 },
146 }, 94 },
147 .n = {
148 .reg_off = HHI_SYS_PLL_CNTL,
149 .shift = 9,
150 .width = 5,
151 },
152 .od = {
153 .reg_off = HHI_SYS_PLL_CNTL,
154 .shift = 10,
155 .width = 2,
156 },
157 .rate_table = sys_pll_rate_table,
158 .rate_count = ARRAY_SIZE(sys_pll_rate_table),
159 .lock = &meson_clk_lock,
160 .hw.init = &(struct clk_init_data){ 95 .hw.init = &(struct clk_init_data){
161 .name = "sys_pll", 96 .name = "sys_pll",
162 .ops = &meson_clk_pll_ro_ops, 97 .ops = &meson_clk_pll_ro_ops,
@@ -257,40 +192,51 @@ static const struct pll_rate_table axg_gp0_pll_rate_table[] = {
257 { /* sentinel */ }, 192 { /* sentinel */ },
258}; 193};
259 194
260static struct pll_params_table axg_gp0_params_table[] = { 195static const struct reg_sequence axg_gp0_init_regs[] = {
261 PLL_PARAM(HHI_GP0_PLL_CNTL, 0x40010250), 196 { .reg = HHI_GP0_PLL_CNTL1, .def = 0xc084b000 },
262 PLL_PARAM(HHI_GP0_PLL_CNTL1, 0xc084a000), 197 { .reg = HHI_GP0_PLL_CNTL2, .def = 0xb75020be },
263 PLL_PARAM(HHI_GP0_PLL_CNTL2, 0xb75020be), 198 { .reg = HHI_GP0_PLL_CNTL3, .def = 0x0a59a288 },
264 PLL_PARAM(HHI_GP0_PLL_CNTL3, 0x0a59a288), 199 { .reg = HHI_GP0_PLL_CNTL4, .def = 0xc000004d },
265 PLL_PARAM(HHI_GP0_PLL_CNTL4, 0xc000004d), 200 { .reg = HHI_GP0_PLL_CNTL5, .def = 0x00078000 },
266 PLL_PARAM(HHI_GP0_PLL_CNTL5, 0x00078000), 201 { .reg = HHI_GP0_PLL_CNTL, .def = 0x40010250 },
267}; 202};
268 203
269static struct meson_clk_pll axg_gp0_pll = { 204static struct clk_regmap axg_gp0_pll = {
270 .m = { 205 .data = &(struct meson_clk_pll_data){
271 .reg_off = HHI_GP0_PLL_CNTL, 206 .m = {
272 .shift = 0, 207 .reg_off = HHI_GP0_PLL_CNTL,
273 .width = 9, 208 .shift = 0,
274 }, 209 .width = 9,
275 .n = { 210 },
276 .reg_off = HHI_GP0_PLL_CNTL, 211 .n = {
277 .shift = 9, 212 .reg_off = HHI_GP0_PLL_CNTL,
278 .width = 5, 213 .shift = 9,
279 }, 214 .width = 5,
280 .od = { 215 },
281 .reg_off = HHI_GP0_PLL_CNTL, 216 .od = {
282 .shift = 16, 217 .reg_off = HHI_GP0_PLL_CNTL,
283 .width = 2, 218 .shift = 16,
284 }, 219 .width = 2,
285 .params = { 220 },
286 .params_table = axg_gp0_params_table, 221 .frac = {
287 .params_count = ARRAY_SIZE(axg_gp0_params_table), 222 .reg_off = HHI_GP0_PLL_CNTL1,
288 .no_init_reset = true, 223 .shift = 0,
289 .reset_lock_loop = true, 224 .width = 10,
290 }, 225 },
291 .rate_table = axg_gp0_pll_rate_table, 226 .l = {
292 .rate_count = ARRAY_SIZE(axg_gp0_pll_rate_table), 227 .reg_off = HHI_GP0_PLL_CNTL,
293 .lock = &meson_clk_lock, 228 .shift = 31,
229 .width = 1,
230 },
231 .rst = {
232 .reg_off = HHI_GP0_PLL_CNTL,
233 .shift = 29,
234 .width = 1,
235 },
236 .table = axg_gp0_pll_rate_table,
237 .init_regs = axg_gp0_init_regs,
238 .init_count = ARRAY_SIZE(axg_gp0_init_regs),
239 },
294 .hw.init = &(struct clk_init_data){ 240 .hw.init = &(struct clk_init_data){
295 .name = "gp0_pll", 241 .name = "gp0_pll",
296 .ops = &meson_clk_pll_ops, 242 .ops = &meson_clk_pll_ops,
@@ -299,234 +245,427 @@ static struct meson_clk_pll axg_gp0_pll = {
299 }, 245 },
300}; 246};
301 247
248static const struct reg_sequence axg_hifi_init_regs[] = {
249 { .reg = HHI_HIFI_PLL_CNTL1, .def = 0xc084b000 },
250 { .reg = HHI_HIFI_PLL_CNTL2, .def = 0xb75020be },
251 { .reg = HHI_HIFI_PLL_CNTL3, .def = 0x0a6a3a88 },
252 { .reg = HHI_HIFI_PLL_CNTL4, .def = 0xc000004d },
253 { .reg = HHI_HIFI_PLL_CNTL5, .def = 0x00058000 },
254 { .reg = HHI_HIFI_PLL_CNTL, .def = 0x40010250 },
255};
256
257static struct clk_regmap axg_hifi_pll = {
258 .data = &(struct meson_clk_pll_data){
259 .m = {
260 .reg_off = HHI_HIFI_PLL_CNTL,
261 .shift = 0,
262 .width = 9,
263 },
264 .n = {
265 .reg_off = HHI_HIFI_PLL_CNTL,
266 .shift = 9,
267 .width = 5,
268 },
269 .od = {
270 .reg_off = HHI_HIFI_PLL_CNTL,
271 .shift = 16,
272 .width = 2,
273 },
274 .frac = {
275 .reg_off = HHI_HIFI_PLL_CNTL5,
276 .shift = 0,
277 .width = 13,
278 },
279 .l = {
280 .reg_off = HHI_HIFI_PLL_CNTL,
281 .shift = 31,
282 .width = 1,
283 },
284 .rst = {
285 .reg_off = HHI_HIFI_PLL_CNTL,
286 .shift = 29,
287 .width = 1,
288 },
289 .table = axg_gp0_pll_rate_table,
290 .init_regs = axg_hifi_init_regs,
291 .init_count = ARRAY_SIZE(axg_hifi_init_regs),
292 .flags = CLK_MESON_PLL_ROUND_CLOSEST,
293 },
294 .hw.init = &(struct clk_init_data){
295 .name = "hifi_pll",
296 .ops = &meson_clk_pll_ops,
297 .parent_names = (const char *[]){ "xtal" },
298 .num_parents = 1,
299 },
300};
302 301
303static struct clk_fixed_factor axg_fclk_div2 = { 302static struct clk_fixed_factor axg_fclk_div2_div = {
304 .mult = 1, 303 .mult = 1,
305 .div = 2, 304 .div = 2,
306 .hw.init = &(struct clk_init_data){ 305 .hw.init = &(struct clk_init_data){
307 .name = "fclk_div2", 306 .name = "fclk_div2_div",
308 .ops = &clk_fixed_factor_ops, 307 .ops = &clk_fixed_factor_ops,
309 .parent_names = (const char *[]){ "fixed_pll" }, 308 .parent_names = (const char *[]){ "fixed_pll" },
310 .num_parents = 1, 309 .num_parents = 1,
311 }, 310 },
312}; 311};
313 312
314static struct clk_fixed_factor axg_fclk_div3 = { 313static struct clk_regmap axg_fclk_div2 = {
314 .data = &(struct clk_regmap_gate_data){
315 .offset = HHI_MPLL_CNTL6,
316 .bit_idx = 27,
317 },
318 .hw.init = &(struct clk_init_data){
319 .name = "fclk_div2",
320 .ops = &clk_regmap_gate_ops,
321 .parent_names = (const char *[]){ "fclk_div2_div" },
322 .num_parents = 1,
323 },
324};
325
326static struct clk_fixed_factor axg_fclk_div3_div = {
315 .mult = 1, 327 .mult = 1,
316 .div = 3, 328 .div = 3,
317 .hw.init = &(struct clk_init_data){ 329 .hw.init = &(struct clk_init_data){
318 .name = "fclk_div3", 330 .name = "fclk_div3_div",
319 .ops = &clk_fixed_factor_ops, 331 .ops = &clk_fixed_factor_ops,
320 .parent_names = (const char *[]){ "fixed_pll" }, 332 .parent_names = (const char *[]){ "fixed_pll" },
321 .num_parents = 1, 333 .num_parents = 1,
322 }, 334 },
323}; 335};
324 336
325static struct clk_fixed_factor axg_fclk_div4 = { 337static struct clk_regmap axg_fclk_div3 = {
338 .data = &(struct clk_regmap_gate_data){
339 .offset = HHI_MPLL_CNTL6,
340 .bit_idx = 28,
341 },
342 .hw.init = &(struct clk_init_data){
343 .name = "fclk_div3",
344 .ops = &clk_regmap_gate_ops,
345 .parent_names = (const char *[]){ "fclk_div3_div" },
346 .num_parents = 1,
347 },
348};
349
350static struct clk_fixed_factor axg_fclk_div4_div = {
326 .mult = 1, 351 .mult = 1,
327 .div = 4, 352 .div = 4,
328 .hw.init = &(struct clk_init_data){ 353 .hw.init = &(struct clk_init_data){
329 .name = "fclk_div4", 354 .name = "fclk_div4_div",
330 .ops = &clk_fixed_factor_ops, 355 .ops = &clk_fixed_factor_ops,
331 .parent_names = (const char *[]){ "fixed_pll" }, 356 .parent_names = (const char *[]){ "fixed_pll" },
332 .num_parents = 1, 357 .num_parents = 1,
333 }, 358 },
334}; 359};
335 360
336static struct clk_fixed_factor axg_fclk_div5 = { 361static struct clk_regmap axg_fclk_div4 = {
362 .data = &(struct clk_regmap_gate_data){
363 .offset = HHI_MPLL_CNTL6,
364 .bit_idx = 29,
365 },
366 .hw.init = &(struct clk_init_data){
367 .name = "fclk_div4",
368 .ops = &clk_regmap_gate_ops,
369 .parent_names = (const char *[]){ "fclk_div4_div" },
370 .num_parents = 1,
371 },
372};
373
374static struct clk_fixed_factor axg_fclk_div5_div = {
337 .mult = 1, 375 .mult = 1,
338 .div = 5, 376 .div = 5,
339 .hw.init = &(struct clk_init_data){ 377 .hw.init = &(struct clk_init_data){
340 .name = "fclk_div5", 378 .name = "fclk_div5_div",
341 .ops = &clk_fixed_factor_ops, 379 .ops = &clk_fixed_factor_ops,
342 .parent_names = (const char *[]){ "fixed_pll" }, 380 .parent_names = (const char *[]){ "fixed_pll" },
343 .num_parents = 1, 381 .num_parents = 1,
344 }, 382 },
345}; 383};
346 384
347static struct clk_fixed_factor axg_fclk_div7 = { 385static struct clk_regmap axg_fclk_div5 = {
386 .data = &(struct clk_regmap_gate_data){
387 .offset = HHI_MPLL_CNTL6,
388 .bit_idx = 30,
389 },
390 .hw.init = &(struct clk_init_data){
391 .name = "fclk_div5",
392 .ops = &clk_regmap_gate_ops,
393 .parent_names = (const char *[]){ "fclk_div5_div" },
394 .num_parents = 1,
395 },
396};
397
398static struct clk_fixed_factor axg_fclk_div7_div = {
348 .mult = 1, 399 .mult = 1,
349 .div = 7, 400 .div = 7,
350 .hw.init = &(struct clk_init_data){ 401 .hw.init = &(struct clk_init_data){
351 .name = "fclk_div7", 402 .name = "fclk_div7_div",
352 .ops = &clk_fixed_factor_ops, 403 .ops = &clk_fixed_factor_ops,
353 .parent_names = (const char *[]){ "fixed_pll" }, 404 .parent_names = (const char *[]){ "fixed_pll" },
354 .num_parents = 1, 405 .num_parents = 1,
355 }, 406 },
356}; 407};
357 408
358static struct meson_clk_mpll axg_mpll0 = { 409static struct clk_regmap axg_fclk_div7 = {
359 .sdm = { 410 .data = &(struct clk_regmap_gate_data){
360 .reg_off = HHI_MPLL_CNTL7, 411 .offset = HHI_MPLL_CNTL6,
361 .shift = 0, 412 .bit_idx = 31,
362 .width = 14,
363 }, 413 },
364 .sdm_en = { 414 .hw.init = &(struct clk_init_data){
365 .reg_off = HHI_MPLL_CNTL7, 415 .name = "fclk_div7",
366 .shift = 15, 416 .ops = &clk_regmap_gate_ops,
367 .width = 1, 417 .parent_names = (const char *[]){ "fclk_div7_div" },
418 .num_parents = 1,
368 }, 419 },
369 .n2 = { 420};
370 .reg_off = HHI_MPLL_CNTL7, 421
371 .shift = 16, 422static struct clk_regmap axg_mpll_prediv = {
372 .width = 9, 423 .data = &(struct clk_regmap_div_data){
424 .offset = HHI_MPLL_CNTL5,
425 .shift = 12,
426 .width = 1,
373 }, 427 },
374 .en = { 428 .hw.init = &(struct clk_init_data){
375 .reg_off = HHI_MPLL_CNTL7, 429 .name = "mpll_prediv",
376 .shift = 14, 430 .ops = &clk_regmap_divider_ro_ops,
377 .width = 1, 431 .parent_names = (const char *[]){ "fixed_pll" },
432 .num_parents = 1,
378 }, 433 },
379 .ssen = { 434};
380 .reg_off = HHI_MPLL_CNTL, 435
381 .shift = 25, 436static struct clk_regmap axg_mpll0_div = {
382 .width = 1, 437 .data = &(struct meson_clk_mpll_data){
438 .sdm = {
439 .reg_off = HHI_MPLL_CNTL7,
440 .shift = 0,
441 .width = 14,
442 },
443 .sdm_en = {
444 .reg_off = HHI_MPLL_CNTL7,
445 .shift = 15,
446 .width = 1,
447 },
448 .n2 = {
449 .reg_off = HHI_MPLL_CNTL7,
450 .shift = 16,
451 .width = 9,
452 },
453 .ssen = {
454 .reg_off = HHI_MPLL_CNTL,
455 .shift = 25,
456 .width = 1,
457 },
458 .misc = {
459 .reg_off = HHI_PLL_TOP_MISC,
460 .shift = 0,
461 .width = 1,
462 },
463 .lock = &meson_clk_lock,
383 }, 464 },
384 .lock = &meson_clk_lock,
385 .hw.init = &(struct clk_init_data){ 465 .hw.init = &(struct clk_init_data){
386 .name = "mpll0", 466 .name = "mpll0_div",
387 .ops = &meson_clk_mpll_ops, 467 .ops = &meson_clk_mpll_ops,
388 .parent_names = (const char *[]){ "fixed_pll" }, 468 .parent_names = (const char *[]){ "mpll_prediv" },
389 .num_parents = 1, 469 .num_parents = 1,
390 }, 470 },
391}; 471};
392 472
393static struct meson_clk_mpll axg_mpll1 = { 473static struct clk_regmap axg_mpll0 = {
394 .sdm = { 474 .data = &(struct clk_regmap_gate_data){
395 .reg_off = HHI_MPLL_CNTL8, 475 .offset = HHI_MPLL_CNTL7,
396 .shift = 0, 476 .bit_idx = 14,
397 .width = 14,
398 }, 477 },
399 .sdm_en = { 478 .hw.init = &(struct clk_init_data){
400 .reg_off = HHI_MPLL_CNTL8, 479 .name = "mpll0",
401 .shift = 15, 480 .ops = &clk_regmap_gate_ops,
402 .width = 1, 481 .parent_names = (const char *[]){ "mpll0_div" },
403 }, 482 .num_parents = 1,
404 .n2 = { 483 .flags = CLK_SET_RATE_PARENT,
405 .reg_off = HHI_MPLL_CNTL8,
406 .shift = 16,
407 .width = 9,
408 }, 484 },
409 .en = { 485};
410 .reg_off = HHI_MPLL_CNTL8, 486
411 .shift = 14, 487static struct clk_regmap axg_mpll1_div = {
412 .width = 1, 488 .data = &(struct meson_clk_mpll_data){
489 .sdm = {
490 .reg_off = HHI_MPLL_CNTL8,
491 .shift = 0,
492 .width = 14,
493 },
494 .sdm_en = {
495 .reg_off = HHI_MPLL_CNTL8,
496 .shift = 15,
497 .width = 1,
498 },
499 .n2 = {
500 .reg_off = HHI_MPLL_CNTL8,
501 .shift = 16,
502 .width = 9,
503 },
504 .misc = {
505 .reg_off = HHI_PLL_TOP_MISC,
506 .shift = 1,
507 .width = 1,
508 },
509 .lock = &meson_clk_lock,
413 }, 510 },
414 .lock = &meson_clk_lock,
415 .hw.init = &(struct clk_init_data){ 511 .hw.init = &(struct clk_init_data){
416 .name = "mpll1", 512 .name = "mpll1_div",
417 .ops = &meson_clk_mpll_ops, 513 .ops = &meson_clk_mpll_ops,
418 .parent_names = (const char *[]){ "fixed_pll" }, 514 .parent_names = (const char *[]){ "mpll_prediv" },
419 .num_parents = 1, 515 .num_parents = 1,
420 }, 516 },
421}; 517};
422 518
423static struct meson_clk_mpll axg_mpll2 = { 519static struct clk_regmap axg_mpll1 = {
424 .sdm = { 520 .data = &(struct clk_regmap_gate_data){
425 .reg_off = HHI_MPLL_CNTL9, 521 .offset = HHI_MPLL_CNTL8,
426 .shift = 0, 522 .bit_idx = 14,
427 .width = 14,
428 }, 523 },
429 .sdm_en = { 524 .hw.init = &(struct clk_init_data){
430 .reg_off = HHI_MPLL_CNTL9, 525 .name = "mpll1",
431 .shift = 15, 526 .ops = &clk_regmap_gate_ops,
432 .width = 1, 527 .parent_names = (const char *[]){ "mpll1_div" },
433 }, 528 .num_parents = 1,
434 .n2 = { 529 .flags = CLK_SET_RATE_PARENT,
435 .reg_off = HHI_MPLL_CNTL9,
436 .shift = 16,
437 .width = 9,
438 }, 530 },
439 .en = { 531};
440 .reg_off = HHI_MPLL_CNTL9, 532
441 .shift = 14, 533static struct clk_regmap axg_mpll2_div = {
442 .width = 1, 534 .data = &(struct meson_clk_mpll_data){
535 .sdm = {
536 .reg_off = HHI_MPLL_CNTL9,
537 .shift = 0,
538 .width = 14,
539 },
540 .sdm_en = {
541 .reg_off = HHI_MPLL_CNTL9,
542 .shift = 15,
543 .width = 1,
544 },
545 .n2 = {
546 .reg_off = HHI_MPLL_CNTL9,
547 .shift = 16,
548 .width = 9,
549 },
550 .misc = {
551 .reg_off = HHI_PLL_TOP_MISC,
552 .shift = 2,
553 .width = 1,
554 },
555 .lock = &meson_clk_lock,
443 }, 556 },
444 .lock = &meson_clk_lock,
445 .hw.init = &(struct clk_init_data){ 557 .hw.init = &(struct clk_init_data){
446 .name = "mpll2", 558 .name = "mpll2_div",
447 .ops = &meson_clk_mpll_ops, 559 .ops = &meson_clk_mpll_ops,
448 .parent_names = (const char *[]){ "fixed_pll" }, 560 .parent_names = (const char *[]){ "mpll_prediv" },
449 .num_parents = 1, 561 .num_parents = 1,
450 }, 562 },
451}; 563};
452 564
453static struct meson_clk_mpll axg_mpll3 = { 565static struct clk_regmap axg_mpll2 = {
454 .sdm = { 566 .data = &(struct clk_regmap_gate_data){
455 .reg_off = HHI_MPLL3_CNTL0, 567 .offset = HHI_MPLL_CNTL9,
456 .shift = 12, 568 .bit_idx = 14,
457 .width = 14,
458 }, 569 },
459 .sdm_en = { 570 .hw.init = &(struct clk_init_data){
460 .reg_off = HHI_MPLL3_CNTL0, 571 .name = "mpll2",
461 .shift = 11, 572 .ops = &clk_regmap_gate_ops,
462 .width = 1, 573 .parent_names = (const char *[]){ "mpll2_div" },
574 .num_parents = 1,
575 .flags = CLK_SET_RATE_PARENT,
576 },
577};
578
579static struct clk_regmap axg_mpll3_div = {
580 .data = &(struct meson_clk_mpll_data){
581 .sdm = {
582 .reg_off = HHI_MPLL3_CNTL0,
583 .shift = 12,
584 .width = 14,
585 },
586 .sdm_en = {
587 .reg_off = HHI_MPLL3_CNTL0,
588 .shift = 11,
589 .width = 1,
590 },
591 .n2 = {
592 .reg_off = HHI_MPLL3_CNTL0,
593 .shift = 2,
594 .width = 9,
595 },
596 .misc = {
597 .reg_off = HHI_PLL_TOP_MISC,
598 .shift = 3,
599 .width = 1,
600 },
601 .lock = &meson_clk_lock,
463 }, 602 },
464 .n2 = { 603 .hw.init = &(struct clk_init_data){
465 .reg_off = HHI_MPLL3_CNTL0, 604 .name = "mpll3_div",
466 .shift = 2, 605 .ops = &meson_clk_mpll_ops,
467 .width = 9, 606 .parent_names = (const char *[]){ "mpll_prediv" },
607 .num_parents = 1,
468 }, 608 },
469 .en = { 609};
470 .reg_off = HHI_MPLL3_CNTL0, 610
471 .shift = 0, 611static struct clk_regmap axg_mpll3 = {
472 .width = 1, 612 .data = &(struct clk_regmap_gate_data){
613 .offset = HHI_MPLL3_CNTL0,
614 .bit_idx = 0,
473 }, 615 },
474 .lock = &meson_clk_lock,
475 .hw.init = &(struct clk_init_data){ 616 .hw.init = &(struct clk_init_data){
476 .name = "mpll3", 617 .name = "mpll3",
477 .ops = &meson_clk_mpll_ops, 618 .ops = &clk_regmap_gate_ops,
478 .parent_names = (const char *[]){ "fixed_pll" }, 619 .parent_names = (const char *[]){ "mpll3_div" },
479 .num_parents = 1, 620 .num_parents = 1,
621 .flags = CLK_SET_RATE_PARENT,
480 }, 622 },
481}; 623};
482 624
483/*
484 * FIXME The legacy composite clocks (e.g. clk81) are both PLL post-dividers
485 * and should be modeled with their respective PLLs via the forthcoming
486 * coordinated clock rates feature
487 */
488static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; 625static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 };
489static const char * const clk81_parent_names[] = { 626static const char * const clk81_parent_names[] = {
490 "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4", 627 "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4",
491 "fclk_div3", "fclk_div5" 628 "fclk_div3", "fclk_div5"
492}; 629};
493 630
494static struct clk_mux axg_mpeg_clk_sel = { 631static struct clk_regmap axg_mpeg_clk_sel = {
495 .reg = (void *)HHI_MPEG_CLK_CNTL, 632 .data = &(struct clk_regmap_mux_data){
496 .mask = 0x7, 633 .offset = HHI_MPEG_CLK_CNTL,
497 .shift = 12, 634 .mask = 0x7,
498 .flags = CLK_MUX_READ_ONLY, 635 .shift = 12,
499 .table = mux_table_clk81, 636 .table = mux_table_clk81,
500 .lock = &meson_clk_lock, 637 },
501 .hw.init = &(struct clk_init_data){ 638 .hw.init = &(struct clk_init_data){
502 .name = "mpeg_clk_sel", 639 .name = "mpeg_clk_sel",
503 .ops = &clk_mux_ro_ops, 640 .ops = &clk_regmap_mux_ro_ops,
504 .parent_names = clk81_parent_names, 641 .parent_names = clk81_parent_names,
505 .num_parents = ARRAY_SIZE(clk81_parent_names), 642 .num_parents = ARRAY_SIZE(clk81_parent_names),
506 }, 643 },
507}; 644};
508 645
509static struct clk_divider axg_mpeg_clk_div = { 646static struct clk_regmap axg_mpeg_clk_div = {
510 .reg = (void *)HHI_MPEG_CLK_CNTL, 647 .data = &(struct clk_regmap_div_data){
511 .shift = 0, 648 .offset = HHI_MPEG_CLK_CNTL,
512 .width = 7, 649 .shift = 0,
513 .lock = &meson_clk_lock, 650 .width = 7,
651 },
514 .hw.init = &(struct clk_init_data){ 652 .hw.init = &(struct clk_init_data){
515 .name = "mpeg_clk_div", 653 .name = "mpeg_clk_div",
516 .ops = &clk_divider_ops, 654 .ops = &clk_regmap_divider_ops,
517 .parent_names = (const char *[]){ "mpeg_clk_sel" }, 655 .parent_names = (const char *[]){ "mpeg_clk_sel" },
518 .num_parents = 1, 656 .num_parents = 1,
519 .flags = CLK_SET_RATE_PARENT, 657 .flags = CLK_SET_RATE_PARENT,
520 }, 658 },
521}; 659};
522 660
523static struct clk_gate axg_clk81 = { 661static struct clk_regmap axg_clk81 = {
524 .reg = (void *)HHI_MPEG_CLK_CNTL, 662 .data = &(struct clk_regmap_gate_data){
525 .bit_idx = 7, 663 .offset = HHI_MPEG_CLK_CNTL,
526 .lock = &meson_clk_lock, 664 .bit_idx = 7,
665 },
527 .hw.init = &(struct clk_init_data){ 666 .hw.init = &(struct clk_init_data){
528 .name = "clk81", 667 .name = "clk81",
529 .ops = &clk_gate_ops, 668 .ops = &clk_regmap_gate_ops,
530 .parent_names = (const char *[]){ "mpeg_clk_div" }, 669 .parent_names = (const char *[]){ "mpeg_clk_div" },
531 .num_parents = 1, 670 .num_parents = 1,
532 .flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL), 671 .flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL),
@@ -545,42 +684,45 @@ static const char * const axg_sd_emmc_clk0_parent_names[] = {
545}; 684};
546 685
547/* SDcard clock */ 686/* SDcard clock */
548static struct clk_mux axg_sd_emmc_b_clk0_sel = { 687static struct clk_regmap axg_sd_emmc_b_clk0_sel = {
549 .reg = (void *)HHI_SD_EMMC_CLK_CNTL, 688 .data = &(struct clk_regmap_mux_data){
550 .mask = 0x7, 689 .offset = HHI_SD_EMMC_CLK_CNTL,
551 .shift = 25, 690 .mask = 0x7,
552 .lock = &meson_clk_lock, 691 .shift = 25,
692 },
553 .hw.init = &(struct clk_init_data) { 693 .hw.init = &(struct clk_init_data) {
554 .name = "sd_emmc_b_clk0_sel", 694 .name = "sd_emmc_b_clk0_sel",
555 .ops = &clk_mux_ops, 695 .ops = &clk_regmap_mux_ops,
556 .parent_names = axg_sd_emmc_clk0_parent_names, 696 .parent_names = axg_sd_emmc_clk0_parent_names,
557 .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_names), 697 .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_names),
558 .flags = CLK_SET_RATE_PARENT, 698 .flags = CLK_SET_RATE_PARENT,
559 }, 699 },
560}; 700};
561 701
562static struct clk_divider axg_sd_emmc_b_clk0_div = { 702static struct clk_regmap axg_sd_emmc_b_clk0_div = {
563 .reg = (void *)HHI_SD_EMMC_CLK_CNTL, 703 .data = &(struct clk_regmap_div_data){
564 .shift = 16, 704 .offset = HHI_SD_EMMC_CLK_CNTL,
565 .width = 7, 705 .shift = 16,
566 .lock = &meson_clk_lock, 706 .width = 7,
567 .flags = CLK_DIVIDER_ROUND_CLOSEST, 707 .flags = CLK_DIVIDER_ROUND_CLOSEST,
708 },
568 .hw.init = &(struct clk_init_data) { 709 .hw.init = &(struct clk_init_data) {
569 .name = "sd_emmc_b_clk0_div", 710 .name = "sd_emmc_b_clk0_div",
570 .ops = &clk_divider_ops, 711 .ops = &clk_regmap_divider_ops,
571 .parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" }, 712 .parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" },
572 .num_parents = 1, 713 .num_parents = 1,
573 .flags = CLK_SET_RATE_PARENT, 714 .flags = CLK_SET_RATE_PARENT,
574 }, 715 },
575}; 716};
576 717
577static struct clk_gate axg_sd_emmc_b_clk0 = { 718static struct clk_regmap axg_sd_emmc_b_clk0 = {
578 .reg = (void *)HHI_SD_EMMC_CLK_CNTL, 719 .data = &(struct clk_regmap_gate_data){
579 .bit_idx = 23, 720 .offset = HHI_SD_EMMC_CLK_CNTL,
580 .lock = &meson_clk_lock, 721 .bit_idx = 23,
722 },
581 .hw.init = &(struct clk_init_data){ 723 .hw.init = &(struct clk_init_data){
582 .name = "sd_emmc_b_clk0", 724 .name = "sd_emmc_b_clk0",
583 .ops = &clk_gate_ops, 725 .ops = &clk_regmap_gate_ops,
584 .parent_names = (const char *[]){ "sd_emmc_b_clk0_div" }, 726 .parent_names = (const char *[]){ "sd_emmc_b_clk0_div" },
585 .num_parents = 1, 727 .num_parents = 1,
586 .flags = CLK_SET_RATE_PARENT, 728 .flags = CLK_SET_RATE_PARENT,
@@ -588,42 +730,45 @@ static struct clk_gate axg_sd_emmc_b_clk0 = {
588}; 730};
589 731
590/* EMMC/NAND clock */ 732/* EMMC/NAND clock */
591static struct clk_mux axg_sd_emmc_c_clk0_sel = { 733static struct clk_regmap axg_sd_emmc_c_clk0_sel = {
592 .reg = (void *)HHI_NAND_CLK_CNTL, 734 .data = &(struct clk_regmap_mux_data){
593 .mask = 0x7, 735 .offset = HHI_NAND_CLK_CNTL,
594 .shift = 9, 736 .mask = 0x7,
595 .lock = &meson_clk_lock, 737 .shift = 9,
738 },
596 .hw.init = &(struct clk_init_data) { 739 .hw.init = &(struct clk_init_data) {
597 .name = "sd_emmc_c_clk0_sel", 740 .name = "sd_emmc_c_clk0_sel",
598 .ops = &clk_mux_ops, 741 .ops = &clk_regmap_mux_ops,
599 .parent_names = axg_sd_emmc_clk0_parent_names, 742 .parent_names = axg_sd_emmc_clk0_parent_names,
600 .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_names), 743 .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_names),
601 .flags = CLK_SET_RATE_PARENT, 744 .flags = CLK_SET_RATE_PARENT,
602 }, 745 },
603}; 746};
604 747
605static struct clk_divider axg_sd_emmc_c_clk0_div = { 748static struct clk_regmap axg_sd_emmc_c_clk0_div = {
606 .reg = (void *)HHI_NAND_CLK_CNTL, 749 .data = &(struct clk_regmap_div_data){
607 .shift = 0, 750 .offset = HHI_NAND_CLK_CNTL,
608 .width = 7, 751 .shift = 0,
609 .lock = &meson_clk_lock, 752 .width = 7,
610 .flags = CLK_DIVIDER_ROUND_CLOSEST, 753 .flags = CLK_DIVIDER_ROUND_CLOSEST,
754 },
611 .hw.init = &(struct clk_init_data) { 755 .hw.init = &(struct clk_init_data) {
612 .name = "sd_emmc_c_clk0_div", 756 .name = "sd_emmc_c_clk0_div",
613 .ops = &clk_divider_ops, 757 .ops = &clk_regmap_divider_ops,
614 .parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" }, 758 .parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" },
615 .num_parents = 1, 759 .num_parents = 1,
616 .flags = CLK_SET_RATE_PARENT, 760 .flags = CLK_SET_RATE_PARENT,
617 }, 761 },
618}; 762};
619 763
620static struct clk_gate axg_sd_emmc_c_clk0 = { 764static struct clk_regmap axg_sd_emmc_c_clk0 = {
621 .reg = (void *)HHI_NAND_CLK_CNTL, 765 .data = &(struct clk_regmap_gate_data){
622 .bit_idx = 7, 766 .offset = HHI_NAND_CLK_CNTL,
623 .lock = &meson_clk_lock, 767 .bit_idx = 7,
768 },
624 .hw.init = &(struct clk_init_data){ 769 .hw.init = &(struct clk_init_data){
625 .name = "sd_emmc_c_clk0", 770 .name = "sd_emmc_c_clk0",
626 .ops = &clk_gate_ops, 771 .ops = &clk_regmap_gate_ops,
627 .parent_names = (const char *[]){ "sd_emmc_c_clk0_div" }, 772 .parent_names = (const char *[]){ "sd_emmc_c_clk0_div" },
628 .num_parents = 1, 773 .num_parents = 1,
629 .flags = CLK_SET_RATE_PARENT, 774 .flags = CLK_SET_RATE_PARENT,
@@ -750,27 +895,24 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = {
750 [CLKID_SD_EMMC_C_CLK0_SEL] = &axg_sd_emmc_c_clk0_sel.hw, 895 [CLKID_SD_EMMC_C_CLK0_SEL] = &axg_sd_emmc_c_clk0_sel.hw,
751 [CLKID_SD_EMMC_C_CLK0_DIV] = &axg_sd_emmc_c_clk0_div.hw, 896 [CLKID_SD_EMMC_C_CLK0_DIV] = &axg_sd_emmc_c_clk0_div.hw,
752 [CLKID_SD_EMMC_C_CLK0] = &axg_sd_emmc_c_clk0.hw, 897 [CLKID_SD_EMMC_C_CLK0] = &axg_sd_emmc_c_clk0.hw,
898 [CLKID_MPLL0_DIV] = &axg_mpll0_div.hw,
899 [CLKID_MPLL1_DIV] = &axg_mpll1_div.hw,
900 [CLKID_MPLL2_DIV] = &axg_mpll2_div.hw,
901 [CLKID_MPLL3_DIV] = &axg_mpll3_div.hw,
902 [CLKID_HIFI_PLL] = &axg_hifi_pll.hw,
903 [CLKID_MPLL_PREDIV] = &axg_mpll_prediv.hw,
904 [CLKID_FCLK_DIV2_DIV] = &axg_fclk_div2_div.hw,
905 [CLKID_FCLK_DIV3_DIV] = &axg_fclk_div3_div.hw,
906 [CLKID_FCLK_DIV4_DIV] = &axg_fclk_div4_div.hw,
907 [CLKID_FCLK_DIV5_DIV] = &axg_fclk_div5_div.hw,
908 [CLKID_FCLK_DIV7_DIV] = &axg_fclk_div7_div.hw,
753 [NR_CLKS] = NULL, 909 [NR_CLKS] = NULL,
754 }, 910 },
755 .num = NR_CLKS, 911 .num = NR_CLKS,
756}; 912};
757 913
758/* Convenience tables to populate base addresses in .probe */ 914/* Convenience table to populate regmap in .probe */
759 915static struct clk_regmap *const axg_clk_regmaps[] = {
760static struct meson_clk_pll *const axg_clk_plls[] = {
761 &axg_fixed_pll,
762 &axg_sys_pll,
763 &axg_gp0_pll,
764};
765
766static struct meson_clk_mpll *const axg_clk_mplls[] = {
767 &axg_mpll0,
768 &axg_mpll1,
769 &axg_mpll2,
770 &axg_mpll3,
771};
772
773static struct clk_gate *const axg_clk_gates[] = {
774 &axg_clk81, 916 &axg_clk81,
775 &axg_ddr, 917 &axg_ddr,
776 &axg_audio_locker, 918 &axg_audio_locker,
@@ -818,113 +960,100 @@ static struct clk_gate *const axg_clk_gates[] = {
818 &axg_ao_i2c, 960 &axg_ao_i2c,
819 &axg_sd_emmc_b_clk0, 961 &axg_sd_emmc_b_clk0,
820 &axg_sd_emmc_c_clk0, 962 &axg_sd_emmc_c_clk0,
821};
822
823static struct clk_mux *const axg_clk_muxes[] = {
824 &axg_mpeg_clk_sel,
825 &axg_sd_emmc_b_clk0_sel,
826 &axg_sd_emmc_c_clk0_sel,
827};
828
829static struct clk_divider *const axg_clk_dividers[] = {
830 &axg_mpeg_clk_div, 963 &axg_mpeg_clk_div,
831 &axg_sd_emmc_b_clk0_div, 964 &axg_sd_emmc_b_clk0_div,
832 &axg_sd_emmc_c_clk0_div, 965 &axg_sd_emmc_c_clk0_div,
833}; 966 &axg_mpeg_clk_sel,
834 967 &axg_sd_emmc_b_clk0_sel,
835struct clkc_data { 968 &axg_sd_emmc_c_clk0_sel,
836 struct clk_gate *const *clk_gates; 969 &axg_mpll0,
837 unsigned int clk_gates_count; 970 &axg_mpll1,
838 struct meson_clk_mpll *const *clk_mplls; 971 &axg_mpll2,
839 unsigned int clk_mplls_count; 972 &axg_mpll3,
840 struct meson_clk_pll *const *clk_plls; 973 &axg_mpll0_div,
841 unsigned int clk_plls_count; 974 &axg_mpll1_div,
842 struct clk_mux *const *clk_muxes; 975 &axg_mpll2_div,
843 unsigned int clk_muxes_count; 976 &axg_mpll3_div,
844 struct clk_divider *const *clk_dividers; 977 &axg_fixed_pll,
845 unsigned int clk_dividers_count; 978 &axg_sys_pll,
846 struct clk_hw_onecell_data *hw_onecell_data; 979 &axg_gp0_pll,
847}; 980 &axg_hifi_pll,
848 981 &axg_mpll_prediv,
849static const struct clkc_data axg_clkc_data = { 982 &axg_fclk_div2,
850 .clk_gates = axg_clk_gates, 983 &axg_fclk_div3,
851 .clk_gates_count = ARRAY_SIZE(axg_clk_gates), 984 &axg_fclk_div4,
852 .clk_mplls = axg_clk_mplls, 985 &axg_fclk_div5,
853 .clk_mplls_count = ARRAY_SIZE(axg_clk_mplls), 986 &axg_fclk_div7,
854 .clk_plls = axg_clk_plls,
855 .clk_plls_count = ARRAY_SIZE(axg_clk_plls),
856 .clk_muxes = axg_clk_muxes,
857 .clk_muxes_count = ARRAY_SIZE(axg_clk_muxes),
858 .clk_dividers = axg_clk_dividers,
859 .clk_dividers_count = ARRAY_SIZE(axg_clk_dividers),
860 .hw_onecell_data = &axg_hw_onecell_data,
861}; 987};
862 988
863static const struct of_device_id clkc_match_table[] = { 989static const struct of_device_id clkc_match_table[] = {
864 { .compatible = "amlogic,axg-clkc", .data = &axg_clkc_data }, 990 { .compatible = "amlogic,axg-clkc" },
865 {} 991 {}
866}; 992};
867 993
994static const struct regmap_config clkc_regmap_config = {
995 .reg_bits = 32,
996 .val_bits = 32,
997 .reg_stride = 4,
998};
999
868static int axg_clkc_probe(struct platform_device *pdev) 1000static int axg_clkc_probe(struct platform_device *pdev)
869{ 1001{
870 struct device *dev = &pdev->dev; 1002 struct device *dev = &pdev->dev;
871 const struct clkc_data *clkc_data;
872 struct resource *res; 1003 struct resource *res;
873 void __iomem *clk_base; 1004 void __iomem *clk_base = NULL;
874 int ret, clkid, i; 1005 struct regmap *map;
875 1006 int ret, i;
876 clkc_data = of_device_get_match_data(&pdev->dev);
877 if (!clkc_data)
878 return -EINVAL;
879
880 /* Generic clocks and PLLs */
881 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
882 if (!res)
883 return -EINVAL;
884 clk_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
885 if (!clk_base) {
886 dev_err(&pdev->dev, "Unable to map clk base\n");
887 return -ENXIO;
888 }
889 1007
890 /* Populate base address for PLLs */ 1008 /* Get the hhi system controller node if available */
891 for (i = 0; i < clkc_data->clk_plls_count; i++) 1009 map = syscon_node_to_regmap(of_get_parent(dev->of_node));
892 clkc_data->clk_plls[i]->base = clk_base; 1010 if (IS_ERR(map)) {
1011 dev_err(dev,
1012 "failed to get HHI regmap - Trying obsolete regs\n");
893 1013
894 /* Populate base address for MPLLs */ 1014 /*
895 for (i = 0; i < clkc_data->clk_mplls_count; i++) 1015 * FIXME: HHI registers should be accessed through
896 clkc_data->clk_mplls[i]->base = clk_base; 1016 * the appropriate system controller. This is required because
1017 * there is more than just clocks in this register space
1018 *
1019 * This fallback method is only provided temporarily until
1020 * all the platform DTs are properly using the syscon node
1021 */
1022 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1023 if (!res)
1024 return -EINVAL;
897 1025
898 /* Populate base address for gates */
899 for (i = 0; i < clkc_data->clk_gates_count; i++)
900 clkc_data->clk_gates[i]->reg = clk_base +
901 (u64)clkc_data->clk_gates[i]->reg;
902 1026
903 /* Populate base address for muxes */ 1027 clk_base = devm_ioremap(dev, res->start, resource_size(res));
904 for (i = 0; i < clkc_data->clk_muxes_count; i++) 1028 if (!clk_base) {
905 clkc_data->clk_muxes[i]->reg = clk_base + 1029 dev_err(dev, "Unable to map clk base\n");
906 (u64)clkc_data->clk_muxes[i]->reg; 1030 return -ENXIO;
1031 }
1032
1033 map = devm_regmap_init_mmio(dev, clk_base,
1034 &clkc_regmap_config);
1035 if (IS_ERR(map))
1036 return PTR_ERR(map);
1037 }
907 1038
908 /* Populate base address for dividers */ 1039 /* Populate regmap for the regmap backed clocks */
909 for (i = 0; i < clkc_data->clk_dividers_count; i++) 1040 for (i = 0; i < ARRAY_SIZE(axg_clk_regmaps); i++)
910 clkc_data->clk_dividers[i]->reg = clk_base + 1041 axg_clk_regmaps[i]->map = map;
911 (u64)clkc_data->clk_dividers[i]->reg;
912 1042
913 for (clkid = 0; clkid < clkc_data->hw_onecell_data->num; clkid++) { 1043 for (i = 0; i < axg_hw_onecell_data.num; i++) {
914 /* array might be sparse */ 1044 /* array might be sparse */
915 if (!clkc_data->hw_onecell_data->hws[clkid]) 1045 if (!axg_hw_onecell_data.hws[i])
916 continue; 1046 continue;
917 1047
918 ret = devm_clk_hw_register(dev, 1048 ret = devm_clk_hw_register(dev, axg_hw_onecell_data.hws[i]);
919 clkc_data->hw_onecell_data->hws[clkid]);
920 if (ret) { 1049 if (ret) {
921 dev_err(&pdev->dev, "Clock registration failed\n"); 1050 dev_err(dev, "Clock registration failed\n");
922 return ret; 1051 return ret;
923 } 1052 }
924 } 1053 }
925 1054
926 return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, 1055 return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
927 clkc_data->hw_onecell_data); 1056 &axg_hw_onecell_data);
928} 1057}
929 1058
930static struct platform_driver axg_driver = { 1059static struct platform_driver axg_driver = {