]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - drivers/clk/qcom/gcc-ipq4019.c
b87297b9923db2b118764461faa03da611cc7fc3
[mirror_ubuntu-bionic-kernel.git] / drivers / clk / qcom / gcc-ipq4019.c
1 /*
2 * Copyright (c) 2015 The Linux Foundation. All rights reserved.
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14 #include <linux/kernel.h>
15 #include <linux/err.h>
16 #include <linux/platform_device.h>
17 #include <linux/module.h>
18 #include <linux/of.h>
19 #include <linux/of_device.h>
20 #include <linux/clk-provider.h>
21 #include <linux/regmap.h>
22 #include <linux/reset-controller.h>
23 #include <linux/math64.h>
24 #include <linux/delay.h>
25
26 #include <dt-bindings/clock/qcom,gcc-ipq4019.h>
27
28 #include "common.h"
29 #include "clk-regmap.h"
30 #include "clk-rcg.h"
31 #include "clk-branch.h"
32 #include "reset.h"
33 #include "clk-regmap-divider.h"
34
35 #define to_clk_regmap_div(_hw) container_of(to_clk_regmap(_hw),\
36 struct clk_regmap_div, clkr)
37
38 #define to_clk_fepll(_hw) container_of(to_clk_regmap_div(_hw),\
39 struct clk_fepll, cdiv)
40
41 enum {
42 P_XO,
43 P_FEPLL200,
44 P_FEPLL500,
45 P_DDRPLL,
46 P_FEPLLWCSS2G,
47 P_FEPLLWCSS5G,
48 P_FEPLL125DLY,
49 P_DDRPLLAPSS,
50 };
51
52 /*
53 * struct clk_fepll_vco - vco feedback divider corresponds for FEPLL clocks
54 * @fdbkdiv_shift: lowest bit for FDBKDIV
55 * @fdbkdiv_width: number of bits in FDBKDIV
56 * @refclkdiv_shift: lowest bit for REFCLKDIV
57 * @refclkdiv_width: number of bits in REFCLKDIV
58 * @reg: PLL_DIV register address
59 */
60 struct clk_fepll_vco {
61 u32 fdbkdiv_shift;
62 u32 fdbkdiv_width;
63 u32 refclkdiv_shift;
64 u32 refclkdiv_width;
65 u32 reg;
66 };
67
68 /*
69 * struct clk_fepll - clk divider corresponds to FEPLL clocks
70 * @fixed_div: fixed divider value if divider is fixed
71 * @parent_map: map from software's parent index to hardware's src_sel field
72 * @cdiv: divider values for PLL_DIV
73 * @pll_vco: vco feedback divider
74 * @div_table: mapping for actual divider value to register divider value
75 * in case of non fixed divider
76 * @freq_tbl: frequency table
77 */
78 struct clk_fepll {
79 u32 fixed_div;
80 const u8 *parent_map;
81 struct clk_regmap_div cdiv;
82 const struct clk_fepll_vco *pll_vco;
83 const struct clk_div_table *div_table;
84 const struct freq_tbl *freq_tbl;
85 };
86
87 static struct parent_map gcc_xo_200_500_map[] = {
88 { P_XO, 0 },
89 { P_FEPLL200, 1 },
90 { P_FEPLL500, 2 },
91 };
92
93 static const char * const gcc_xo_200_500[] = {
94 "xo",
95 "fepll200",
96 "fepll500",
97 };
98
99 static struct parent_map gcc_xo_200_map[] = {
100 { P_XO, 0 },
101 { P_FEPLL200, 1 },
102 };
103
104 static const char * const gcc_xo_200[] = {
105 "xo",
106 "fepll200",
107 };
108
109 static struct parent_map gcc_xo_200_spi_map[] = {
110 { P_XO, 0 },
111 { P_FEPLL200, 2 },
112 };
113
114 static const char * const gcc_xo_200_spi[] = {
115 "xo",
116 "fepll200",
117 };
118
119 static struct parent_map gcc_xo_sdcc1_500_map[] = {
120 { P_XO, 0 },
121 { P_DDRPLL, 1 },
122 { P_FEPLL500, 2 },
123 };
124
125 static const char * const gcc_xo_sdcc1_500[] = {
126 "xo",
127 "ddrpllsdcc",
128 "fepll500",
129 };
130
131 static struct parent_map gcc_xo_wcss2g_map[] = {
132 { P_XO, 0 },
133 { P_FEPLLWCSS2G, 1 },
134 };
135
136 static const char * const gcc_xo_wcss2g[] = {
137 "xo",
138 "fepllwcss2g",
139 };
140
141 static struct parent_map gcc_xo_wcss5g_map[] = {
142 { P_XO, 0 },
143 { P_FEPLLWCSS5G, 1 },
144 };
145
146 static const char * const gcc_xo_wcss5g[] = {
147 "xo",
148 "fepllwcss5g",
149 };
150
151 static struct parent_map gcc_xo_125_dly_map[] = {
152 { P_XO, 0 },
153 { P_FEPLL125DLY, 1 },
154 };
155
156 static const char * const gcc_xo_125_dly[] = {
157 "xo",
158 "fepll125dly",
159 };
160
161 static struct parent_map gcc_xo_ddr_500_200_map[] = {
162 { P_XO, 0 },
163 { P_FEPLL200, 3 },
164 { P_FEPLL500, 2 },
165 { P_DDRPLLAPSS, 1 },
166 };
167
168 static const char * const gcc_xo_ddr_500_200[] = {
169 "xo",
170 "fepll200",
171 "fepll500",
172 "ddrpllapss",
173 };
174
175 #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
176
177 static const struct freq_tbl ftbl_gcc_audio_pwm_clk[] = {
178 F(48000000, P_XO, 1, 0, 0),
179 F(200000000, P_FEPLL200, 1, 0, 0),
180 { }
181 };
182
183 static struct clk_rcg2 audio_clk_src = {
184 .cmd_rcgr = 0x1b000,
185 .hid_width = 5,
186 .parent_map = gcc_xo_200_map,
187 .freq_tbl = ftbl_gcc_audio_pwm_clk,
188 .clkr.hw.init = &(struct clk_init_data){
189 .name = "audio_clk_src",
190 .parent_names = gcc_xo_200,
191 .num_parents = 2,
192 .ops = &clk_rcg2_ops,
193
194 },
195 };
196
197 static struct clk_branch gcc_audio_ahb_clk = {
198 .halt_reg = 0x1b010,
199 .clkr = {
200 .enable_reg = 0x1b010,
201 .enable_mask = BIT(0),
202 .hw.init = &(struct clk_init_data){
203 .name = "gcc_audio_ahb_clk",
204 .parent_names = (const char *[]){
205 "pcnoc_clk_src",
206 },
207 .flags = CLK_SET_RATE_PARENT,
208 .num_parents = 1,
209 .ops = &clk_branch2_ops,
210 },
211 },
212 };
213
214 static struct clk_branch gcc_audio_pwm_clk = {
215 .halt_reg = 0x1b00C,
216 .clkr = {
217 .enable_reg = 0x1b00C,
218 .enable_mask = BIT(0),
219 .hw.init = &(struct clk_init_data){
220 .name = "gcc_audio_pwm_clk",
221 .parent_names = (const char *[]){
222 "audio_clk_src",
223 },
224 .flags = CLK_SET_RATE_PARENT,
225 .num_parents = 1,
226 .ops = &clk_branch2_ops,
227 },
228 },
229 };
230
231 static const struct freq_tbl ftbl_gcc_blsp1_qup1_2_i2c_apps_clk[] = {
232 F(19050000, P_FEPLL200, 10.5, 1, 1),
233 { }
234 };
235
236 static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = {
237 .cmd_rcgr = 0x200c,
238 .hid_width = 5,
239 .parent_map = gcc_xo_200_map,
240 .freq_tbl = ftbl_gcc_blsp1_qup1_2_i2c_apps_clk,
241 .clkr.hw.init = &(struct clk_init_data){
242 .name = "blsp1_qup1_i2c_apps_clk_src",
243 .parent_names = gcc_xo_200,
244 .num_parents = 2,
245 .ops = &clk_rcg2_ops,
246 },
247 };
248
249 static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = {
250 .halt_reg = 0x2008,
251 .clkr = {
252 .enable_reg = 0x2008,
253 .enable_mask = BIT(0),
254 .hw.init = &(struct clk_init_data){
255 .name = "gcc_blsp1_qup1_i2c_apps_clk",
256 .parent_names = (const char *[]){
257 "blsp1_qup1_i2c_apps_clk_src",
258 },
259 .num_parents = 1,
260 .ops = &clk_branch2_ops,
261 .flags = CLK_SET_RATE_PARENT,
262 },
263 },
264 };
265
266 static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = {
267 .cmd_rcgr = 0x3000,
268 .hid_width = 5,
269 .parent_map = gcc_xo_200_map,
270 .freq_tbl = ftbl_gcc_blsp1_qup1_2_i2c_apps_clk,
271 .clkr.hw.init = &(struct clk_init_data){
272 .name = "blsp1_qup2_i2c_apps_clk_src",
273 .parent_names = gcc_xo_200,
274 .num_parents = 2,
275 .ops = &clk_rcg2_ops,
276 },
277 };
278
279 static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = {
280 .halt_reg = 0x3010,
281 .clkr = {
282 .enable_reg = 0x3010,
283 .enable_mask = BIT(0),
284 .hw.init = &(struct clk_init_data){
285 .name = "gcc_blsp1_qup2_i2c_apps_clk",
286 .parent_names = (const char *[]){
287 "blsp1_qup2_i2c_apps_clk_src",
288 },
289 .num_parents = 1,
290 .ops = &clk_branch2_ops,
291 .flags = CLK_SET_RATE_PARENT,
292 },
293 },
294 };
295
296 static const struct freq_tbl ftbl_gcc_blsp1_qup1_2_spi_apps_clk[] = {
297 F(960000, P_XO, 12, 1, 4),
298 F(4800000, P_XO, 1, 1, 10),
299 F(9600000, P_XO, 1, 1, 5),
300 F(15000000, P_XO, 1, 1, 3),
301 F(19200000, P_XO, 1, 2, 5),
302 F(24000000, P_XO, 1, 1, 2),
303 F(48000000, P_XO, 1, 0, 0),
304 { }
305 };
306
307 static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = {
308 .cmd_rcgr = 0x2024,
309 .mnd_width = 8,
310 .hid_width = 5,
311 .parent_map = gcc_xo_200_spi_map,
312 .freq_tbl = ftbl_gcc_blsp1_qup1_2_spi_apps_clk,
313 .clkr.hw.init = &(struct clk_init_data){
314 .name = "blsp1_qup1_spi_apps_clk_src",
315 .parent_names = gcc_xo_200_spi,
316 .num_parents = 2,
317 .ops = &clk_rcg2_ops,
318 },
319 };
320
321 static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = {
322 .halt_reg = 0x2004,
323 .clkr = {
324 .enable_reg = 0x2004,
325 .enable_mask = BIT(0),
326 .hw.init = &(struct clk_init_data){
327 .name = "gcc_blsp1_qup1_spi_apps_clk",
328 .parent_names = (const char *[]){
329 "blsp1_qup1_spi_apps_clk_src",
330 },
331 .num_parents = 1,
332 .ops = &clk_branch2_ops,
333 .flags = CLK_SET_RATE_PARENT,
334 },
335 },
336 };
337
338 static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = {
339 .cmd_rcgr = 0x3014,
340 .mnd_width = 8,
341 .hid_width = 5,
342 .freq_tbl = ftbl_gcc_blsp1_qup1_2_spi_apps_clk,
343 .parent_map = gcc_xo_200_spi_map,
344 .clkr.hw.init = &(struct clk_init_data){
345 .name = "blsp1_qup2_spi_apps_clk_src",
346 .parent_names = gcc_xo_200_spi,
347 .num_parents = 2,
348 .ops = &clk_rcg2_ops,
349 },
350 };
351
352 static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = {
353 .halt_reg = 0x300c,
354 .clkr = {
355 .enable_reg = 0x300c,
356 .enable_mask = BIT(0),
357 .hw.init = &(struct clk_init_data){
358 .name = "gcc_blsp1_qup2_spi_apps_clk",
359 .parent_names = (const char *[]){
360 "blsp1_qup2_spi_apps_clk_src",
361 },
362 .num_parents = 1,
363 .ops = &clk_branch2_ops,
364 .flags = CLK_SET_RATE_PARENT,
365 },
366 },
367 };
368
369 static const struct freq_tbl ftbl_gcc_blsp1_uart1_2_apps_clk[] = {
370 F(1843200, P_FEPLL200, 1, 144, 15625),
371 F(3686400, P_FEPLL200, 1, 288, 15625),
372 F(7372800, P_FEPLL200, 1, 576, 15625),
373 F(14745600, P_FEPLL200, 1, 1152, 15625),
374 F(16000000, P_FEPLL200, 1, 2, 25),
375 F(24000000, P_XO, 1, 1, 2),
376 F(32000000, P_FEPLL200, 1, 4, 25),
377 F(40000000, P_FEPLL200, 1, 1, 5),
378 F(46400000, P_FEPLL200, 1, 29, 125),
379 F(48000000, P_XO, 1, 0, 0),
380 { }
381 };
382
383 static struct clk_rcg2 blsp1_uart1_apps_clk_src = {
384 .cmd_rcgr = 0x2044,
385 .mnd_width = 16,
386 .hid_width = 5,
387 .freq_tbl = ftbl_gcc_blsp1_uart1_2_apps_clk,
388 .parent_map = gcc_xo_200_spi_map,
389 .clkr.hw.init = &(struct clk_init_data){
390 .name = "blsp1_uart1_apps_clk_src",
391 .parent_names = gcc_xo_200_spi,
392 .num_parents = 2,
393 .ops = &clk_rcg2_ops,
394 },
395 };
396
397 static struct clk_branch gcc_blsp1_uart1_apps_clk = {
398 .halt_reg = 0x203c,
399 .clkr = {
400 .enable_reg = 0x203c,
401 .enable_mask = BIT(0),
402 .hw.init = &(struct clk_init_data){
403 .name = "gcc_blsp1_uart1_apps_clk",
404 .parent_names = (const char *[]){
405 "blsp1_uart1_apps_clk_src",
406 },
407 .flags = CLK_SET_RATE_PARENT,
408 .num_parents = 1,
409 .ops = &clk_branch2_ops,
410 },
411 },
412 };
413
414 static struct clk_rcg2 blsp1_uart2_apps_clk_src = {
415 .cmd_rcgr = 0x3034,
416 .mnd_width = 16,
417 .hid_width = 5,
418 .freq_tbl = ftbl_gcc_blsp1_uart1_2_apps_clk,
419 .parent_map = gcc_xo_200_spi_map,
420 .clkr.hw.init = &(struct clk_init_data){
421 .name = "blsp1_uart2_apps_clk_src",
422 .parent_names = gcc_xo_200_spi,
423 .num_parents = 2,
424 .ops = &clk_rcg2_ops,
425 },
426 };
427
428 static struct clk_branch gcc_blsp1_uart2_apps_clk = {
429 .halt_reg = 0x302c,
430 .clkr = {
431 .enable_reg = 0x302c,
432 .enable_mask = BIT(0),
433 .hw.init = &(struct clk_init_data){
434 .name = "gcc_blsp1_uart2_apps_clk",
435 .parent_names = (const char *[]){
436 "blsp1_uart2_apps_clk_src",
437 },
438 .num_parents = 1,
439 .ops = &clk_branch2_ops,
440 .flags = CLK_SET_RATE_PARENT,
441 },
442 },
443 };
444
445 static const struct freq_tbl ftbl_gcc_gp_clk[] = {
446 F(1250000, P_FEPLL200, 1, 16, 0),
447 F(2500000, P_FEPLL200, 1, 8, 0),
448 F(5000000, P_FEPLL200, 1, 4, 0),
449 { }
450 };
451
452 static struct clk_rcg2 gp1_clk_src = {
453 .cmd_rcgr = 0x8004,
454 .mnd_width = 8,
455 .hid_width = 5,
456 .freq_tbl = ftbl_gcc_gp_clk,
457 .parent_map = gcc_xo_200_map,
458 .clkr.hw.init = &(struct clk_init_data){
459 .name = "gp1_clk_src",
460 .parent_names = gcc_xo_200,
461 .num_parents = 2,
462 .ops = &clk_rcg2_ops,
463 },
464 };
465
466 static struct clk_branch gcc_gp1_clk = {
467 .halt_reg = 0x8000,
468 .clkr = {
469 .enable_reg = 0x8000,
470 .enable_mask = BIT(0),
471 .hw.init = &(struct clk_init_data){
472 .name = "gcc_gp1_clk",
473 .parent_names = (const char *[]){
474 "gp1_clk_src",
475 },
476 .num_parents = 1,
477 .ops = &clk_branch2_ops,
478 .flags = CLK_SET_RATE_PARENT,
479 },
480 },
481 };
482
483 static struct clk_rcg2 gp2_clk_src = {
484 .cmd_rcgr = 0x9004,
485 .mnd_width = 8,
486 .hid_width = 5,
487 .freq_tbl = ftbl_gcc_gp_clk,
488 .parent_map = gcc_xo_200_map,
489 .clkr.hw.init = &(struct clk_init_data){
490 .name = "gp2_clk_src",
491 .parent_names = gcc_xo_200,
492 .num_parents = 2,
493 .ops = &clk_rcg2_ops,
494 },
495 };
496
497 static struct clk_branch gcc_gp2_clk = {
498 .halt_reg = 0x9000,
499 .clkr = {
500 .enable_reg = 0x9000,
501 .enable_mask = BIT(0),
502 .hw.init = &(struct clk_init_data){
503 .name = "gcc_gp2_clk",
504 .parent_names = (const char *[]){
505 "gp2_clk_src",
506 },
507 .num_parents = 1,
508 .ops = &clk_branch2_ops,
509 .flags = CLK_SET_RATE_PARENT,
510 },
511 },
512 };
513
514 static struct clk_rcg2 gp3_clk_src = {
515 .cmd_rcgr = 0xa004,
516 .mnd_width = 8,
517 .hid_width = 5,
518 .freq_tbl = ftbl_gcc_gp_clk,
519 .parent_map = gcc_xo_200_map,
520 .clkr.hw.init = &(struct clk_init_data){
521 .name = "gp3_clk_src",
522 .parent_names = gcc_xo_200,
523 .num_parents = 2,
524 .ops = &clk_rcg2_ops,
525 },
526 };
527
528 static struct clk_branch gcc_gp3_clk = {
529 .halt_reg = 0xa000,
530 .clkr = {
531 .enable_reg = 0xa000,
532 .enable_mask = BIT(0),
533 .hw.init = &(struct clk_init_data){
534 .name = "gcc_gp3_clk",
535 .parent_names = (const char *[]){
536 "gp3_clk_src",
537 },
538 .num_parents = 1,
539 .ops = &clk_branch2_ops,
540 .flags = CLK_SET_RATE_PARENT,
541 },
542 },
543 };
544
545 static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk[] = {
546 F(144000, P_XO, 1, 3, 240),
547 F(400000, P_XO, 1, 1, 0),
548 F(20000000, P_FEPLL500, 1, 1, 25),
549 F(25000000, P_FEPLL500, 1, 1, 20),
550 F(50000000, P_FEPLL500, 1, 1, 10),
551 F(100000000, P_FEPLL500, 1, 1, 5),
552 F(192000000, P_DDRPLL, 1, 0, 0),
553 { }
554 };
555
556 static struct clk_rcg2 sdcc1_apps_clk_src = {
557 .cmd_rcgr = 0x18004,
558 .hid_width = 5,
559 .freq_tbl = ftbl_gcc_sdcc1_apps_clk,
560 .parent_map = gcc_xo_sdcc1_500_map,
561 .clkr.hw.init = &(struct clk_init_data){
562 .name = "sdcc1_apps_clk_src",
563 .parent_names = gcc_xo_sdcc1_500,
564 .num_parents = 3,
565 .ops = &clk_rcg2_ops,
566 .flags = CLK_SET_RATE_PARENT,
567 },
568 };
569
570 static const struct freq_tbl ftbl_gcc_apps_clk[] = {
571 F(48000000, P_XO, 1, 0, 0),
572 F(200000000, P_FEPLL200, 1, 0, 0),
573 F(384000000, P_DDRPLLAPSS, 1, 0, 0),
574 F(413000000, P_DDRPLLAPSS, 1, 0, 0),
575 F(448000000, P_DDRPLLAPSS, 1, 0, 0),
576 F(488000000, P_DDRPLLAPSS, 1, 0, 0),
577 F(500000000, P_FEPLL500, 1, 0, 0),
578 F(512000000, P_DDRPLLAPSS, 1, 0, 0),
579 F(537000000, P_DDRPLLAPSS, 1, 0, 0),
580 F(565000000, P_DDRPLLAPSS, 1, 0, 0),
581 F(597000000, P_DDRPLLAPSS, 1, 0, 0),
582 F(632000000, P_DDRPLLAPSS, 1, 0, 0),
583 F(672000000, P_DDRPLLAPSS, 1, 0, 0),
584 F(716000000, P_DDRPLLAPSS, 1, 0, 0),
585 { }
586 };
587
588 static struct clk_rcg2 apps_clk_src = {
589 .cmd_rcgr = 0x1900c,
590 .hid_width = 5,
591 .freq_tbl = ftbl_gcc_apps_clk,
592 .parent_map = gcc_xo_ddr_500_200_map,
593 .clkr.hw.init = &(struct clk_init_data){
594 .name = "apps_clk_src",
595 .parent_names = gcc_xo_ddr_500_200,
596 .num_parents = 4,
597 .ops = &clk_rcg2_ops,
598 .flags = CLK_SET_RATE_PARENT,
599 },
600 };
601
602 static const struct freq_tbl ftbl_gcc_apps_ahb_clk[] = {
603 F(48000000, P_XO, 1, 0, 0),
604 F(100000000, P_FEPLL200, 2, 0, 0),
605 { }
606 };
607
608 static struct clk_rcg2 apps_ahb_clk_src = {
609 .cmd_rcgr = 0x19014,
610 .hid_width = 5,
611 .parent_map = gcc_xo_200_500_map,
612 .freq_tbl = ftbl_gcc_apps_ahb_clk,
613 .clkr.hw.init = &(struct clk_init_data){
614 .name = "apps_ahb_clk_src",
615 .parent_names = gcc_xo_200_500,
616 .num_parents = 3,
617 .ops = &clk_rcg2_ops,
618 },
619 };
620
621 static struct clk_branch gcc_apss_ahb_clk = {
622 .halt_reg = 0x19004,
623 .halt_check = BRANCH_HALT_VOTED,
624 .clkr = {
625 .enable_reg = 0x6000,
626 .enable_mask = BIT(14),
627 .hw.init = &(struct clk_init_data){
628 .name = "gcc_apss_ahb_clk",
629 .parent_names = (const char *[]){
630 "apps_ahb_clk_src",
631 },
632 .num_parents = 1,
633 .ops = &clk_branch2_ops,
634 .flags = CLK_SET_RATE_PARENT,
635 },
636 },
637 };
638
639 static struct clk_branch gcc_blsp1_ahb_clk = {
640 .halt_reg = 0x1008,
641 .halt_check = BRANCH_HALT_VOTED,
642 .clkr = {
643 .enable_reg = 0x6000,
644 .enable_mask = BIT(10),
645 .hw.init = &(struct clk_init_data){
646 .name = "gcc_blsp1_ahb_clk",
647 .parent_names = (const char *[]){
648 "pcnoc_clk_src",
649 },
650 .num_parents = 1,
651 .ops = &clk_branch2_ops,
652 },
653 },
654 };
655
656 static struct clk_branch gcc_dcd_xo_clk = {
657 .halt_reg = 0x2103c,
658 .clkr = {
659 .enable_reg = 0x2103c,
660 .enable_mask = BIT(0),
661 .hw.init = &(struct clk_init_data){
662 .name = "gcc_dcd_xo_clk",
663 .parent_names = (const char *[]){
664 "xo",
665 },
666 .num_parents = 1,
667 .ops = &clk_branch2_ops,
668 },
669 },
670 };
671
672 static struct clk_branch gcc_boot_rom_ahb_clk = {
673 .halt_reg = 0x1300c,
674 .clkr = {
675 .enable_reg = 0x1300c,
676 .enable_mask = BIT(0),
677 .hw.init = &(struct clk_init_data){
678 .name = "gcc_boot_rom_ahb_clk",
679 .parent_names = (const char *[]){
680 "pcnoc_clk_src",
681 },
682 .num_parents = 1,
683 .ops = &clk_branch2_ops,
684 .flags = CLK_SET_RATE_PARENT,
685 },
686 },
687 };
688
689 static struct clk_branch gcc_crypto_ahb_clk = {
690 .halt_reg = 0x16024,
691 .halt_check = BRANCH_HALT_VOTED,
692 .clkr = {
693 .enable_reg = 0x6000,
694 .enable_mask = BIT(0),
695 .hw.init = &(struct clk_init_data){
696 .name = "gcc_crypto_ahb_clk",
697 .parent_names = (const char *[]){
698 "pcnoc_clk_src",
699 },
700 .num_parents = 1,
701 .ops = &clk_branch2_ops,
702 },
703 },
704 };
705
706 static struct clk_branch gcc_crypto_axi_clk = {
707 .halt_reg = 0x16020,
708 .halt_check = BRANCH_HALT_VOTED,
709 .clkr = {
710 .enable_reg = 0x6000,
711 .enable_mask = BIT(1),
712 .hw.init = &(struct clk_init_data){
713 .name = "gcc_crypto_axi_clk",
714 .parent_names = (const char *[]){
715 "fepll125",
716 },
717 .num_parents = 1,
718 .ops = &clk_branch2_ops,
719 },
720 },
721 };
722
723 static struct clk_branch gcc_crypto_clk = {
724 .halt_reg = 0x1601c,
725 .halt_check = BRANCH_HALT_VOTED,
726 .clkr = {
727 .enable_reg = 0x6000,
728 .enable_mask = BIT(2),
729 .hw.init = &(struct clk_init_data){
730 .name = "gcc_crypto_clk",
731 .parent_names = (const char *[]){
732 "fepll125",
733 },
734 .num_parents = 1,
735 .ops = &clk_branch2_ops,
736 },
737 },
738 };
739
740 static struct clk_branch gcc_ess_clk = {
741 .halt_reg = 0x12010,
742 .clkr = {
743 .enable_reg = 0x12010,
744 .enable_mask = BIT(0),
745 .hw.init = &(struct clk_init_data){
746 .name = "gcc_ess_clk",
747 .parent_names = (const char *[]){
748 "fephy_125m_dly_clk_src",
749 },
750 .num_parents = 1,
751 .ops = &clk_branch2_ops,
752 .flags = CLK_SET_RATE_PARENT,
753 },
754 },
755 };
756
757 static struct clk_branch gcc_imem_axi_clk = {
758 .halt_reg = 0xe004,
759 .halt_check = BRANCH_HALT_VOTED,
760 .clkr = {
761 .enable_reg = 0x6000,
762 .enable_mask = BIT(17),
763 .hw.init = &(struct clk_init_data){
764 .name = "gcc_imem_axi_clk",
765 .parent_names = (const char *[]){
766 "fepll200",
767 },
768 .num_parents = 1,
769 .ops = &clk_branch2_ops,
770 },
771 },
772 };
773
774 static struct clk_branch gcc_imem_cfg_ahb_clk = {
775 .halt_reg = 0xe008,
776 .clkr = {
777 .enable_reg = 0xe008,
778 .enable_mask = BIT(0),
779 .hw.init = &(struct clk_init_data){
780 .name = "gcc_imem_cfg_ahb_clk",
781 .parent_names = (const char *[]){
782 "pcnoc_clk_src",
783 },
784 .num_parents = 1,
785 .ops = &clk_branch2_ops,
786 },
787 },
788 };
789
790 static struct clk_branch gcc_pcie_ahb_clk = {
791 .halt_reg = 0x1d00c,
792 .clkr = {
793 .enable_reg = 0x1d00c,
794 .enable_mask = BIT(0),
795 .hw.init = &(struct clk_init_data){
796 .name = "gcc_pcie_ahb_clk",
797 .parent_names = (const char *[]){
798 "pcnoc_clk_src",
799 },
800 .num_parents = 1,
801 .ops = &clk_branch2_ops,
802 },
803 },
804 };
805
806 static struct clk_branch gcc_pcie_axi_m_clk = {
807 .halt_reg = 0x1d004,
808 .clkr = {
809 .enable_reg = 0x1d004,
810 .enable_mask = BIT(0),
811 .hw.init = &(struct clk_init_data){
812 .name = "gcc_pcie_axi_m_clk",
813 .parent_names = (const char *[]){
814 "fepll200",
815 },
816 .num_parents = 1,
817 .ops = &clk_branch2_ops,
818 },
819 },
820 };
821
822 static struct clk_branch gcc_pcie_axi_s_clk = {
823 .halt_reg = 0x1d008,
824 .clkr = {
825 .enable_reg = 0x1d008,
826 .enable_mask = BIT(0),
827 .hw.init = &(struct clk_init_data){
828 .name = "gcc_pcie_axi_s_clk",
829 .parent_names = (const char *[]){
830 "fepll200",
831 },
832 .num_parents = 1,
833 .ops = &clk_branch2_ops,
834 },
835 },
836 };
837
838 static struct clk_branch gcc_prng_ahb_clk = {
839 .halt_reg = 0x13004,
840 .halt_check = BRANCH_HALT_VOTED,
841 .clkr = {
842 .enable_reg = 0x6000,
843 .enable_mask = BIT(8),
844 .hw.init = &(struct clk_init_data){
845 .name = "gcc_prng_ahb_clk",
846 .parent_names = (const char *[]){
847 "pcnoc_clk_src",
848 },
849 .num_parents = 1,
850 .ops = &clk_branch2_ops,
851 },
852 },
853 };
854
855 static struct clk_branch gcc_qpic_ahb_clk = {
856 .halt_reg = 0x1c008,
857 .clkr = {
858 .enable_reg = 0x1c008,
859 .enable_mask = BIT(0),
860 .hw.init = &(struct clk_init_data){
861 .name = "gcc_qpic_ahb_clk",
862 .parent_names = (const char *[]){
863 "pcnoc_clk_src",
864 },
865 .num_parents = 1,
866 .ops = &clk_branch2_ops,
867 },
868 },
869 };
870
871 static struct clk_branch gcc_qpic_clk = {
872 .halt_reg = 0x1c004,
873 .clkr = {
874 .enable_reg = 0x1c004,
875 .enable_mask = BIT(0),
876 .hw.init = &(struct clk_init_data){
877 .name = "gcc_qpic_clk",
878 .parent_names = (const char *[]){
879 "pcnoc_clk_src",
880 },
881 .num_parents = 1,
882 .ops = &clk_branch2_ops,
883 },
884 },
885 };
886
887 static struct clk_branch gcc_sdcc1_ahb_clk = {
888 .halt_reg = 0x18010,
889 .clkr = {
890 .enable_reg = 0x18010,
891 .enable_mask = BIT(0),
892 .hw.init = &(struct clk_init_data){
893 .name = "gcc_sdcc1_ahb_clk",
894 .parent_names = (const char *[]){
895 "pcnoc_clk_src",
896 },
897 .num_parents = 1,
898 .ops = &clk_branch2_ops,
899 },
900 },
901 };
902
903 static struct clk_branch gcc_sdcc1_apps_clk = {
904 .halt_reg = 0x1800c,
905 .clkr = {
906 .enable_reg = 0x1800c,
907 .enable_mask = BIT(0),
908 .hw.init = &(struct clk_init_data){
909 .name = "gcc_sdcc1_apps_clk",
910 .parent_names = (const char *[]){
911 "sdcc1_apps_clk_src",
912 },
913 .num_parents = 1,
914 .ops = &clk_branch2_ops,
915 .flags = CLK_SET_RATE_PARENT,
916 },
917 },
918 };
919
920 static struct clk_branch gcc_tlmm_ahb_clk = {
921 .halt_reg = 0x5004,
922 .halt_check = BRANCH_HALT_VOTED,
923 .clkr = {
924 .enable_reg = 0x6000,
925 .enable_mask = BIT(5),
926 .hw.init = &(struct clk_init_data){
927 .name = "gcc_tlmm_ahb_clk",
928 .parent_names = (const char *[]){
929 "pcnoc_clk_src",
930 },
931 .num_parents = 1,
932 .ops = &clk_branch2_ops,
933 },
934 },
935 };
936
937 static struct clk_branch gcc_usb2_master_clk = {
938 .halt_reg = 0x1e00c,
939 .clkr = {
940 .enable_reg = 0x1e00c,
941 .enable_mask = BIT(0),
942 .hw.init = &(struct clk_init_data){
943 .name = "gcc_usb2_master_clk",
944 .parent_names = (const char *[]){
945 "pcnoc_clk_src",
946 },
947 .num_parents = 1,
948 .ops = &clk_branch2_ops,
949 },
950 },
951 };
952
953 static struct clk_branch gcc_usb2_sleep_clk = {
954 .halt_reg = 0x1e010,
955 .clkr = {
956 .enable_reg = 0x1e010,
957 .enable_mask = BIT(0),
958 .hw.init = &(struct clk_init_data){
959 .name = "gcc_usb2_sleep_clk",
960 .parent_names = (const char *[]){
961 "gcc_sleep_clk_src",
962 },
963 .num_parents = 1,
964 .ops = &clk_branch2_ops,
965 },
966 },
967 };
968
969 static struct clk_branch gcc_usb2_mock_utmi_clk = {
970 .halt_reg = 0x1e014,
971 .clkr = {
972 .enable_reg = 0x1e014,
973 .enable_mask = BIT(0),
974 .hw.init = &(struct clk_init_data){
975 .name = "gcc_usb2_mock_utmi_clk",
976 .parent_names = (const char *[]){
977 "usb30_mock_utmi_clk_src",
978 },
979 .num_parents = 1,
980 .ops = &clk_branch2_ops,
981 .flags = CLK_SET_RATE_PARENT,
982 },
983 },
984 };
985
986 static const struct freq_tbl ftbl_gcc_usb30_mock_utmi_clk[] = {
987 F(2000000, P_FEPLL200, 10, 0, 0),
988 { }
989 };
990
991 static struct clk_rcg2 usb30_mock_utmi_clk_src = {
992 .cmd_rcgr = 0x1e000,
993 .hid_width = 5,
994 .parent_map = gcc_xo_200_map,
995 .freq_tbl = ftbl_gcc_usb30_mock_utmi_clk,
996 .clkr.hw.init = &(struct clk_init_data){
997 .name = "usb30_mock_utmi_clk_src",
998 .parent_names = gcc_xo_200,
999 .num_parents = 2,
1000 .ops = &clk_rcg2_ops,
1001 },
1002 };
1003
1004 static struct clk_branch gcc_usb3_master_clk = {
1005 .halt_reg = 0x1e028,
1006 .clkr = {
1007 .enable_reg = 0x1e028,
1008 .enable_mask = BIT(0),
1009 .hw.init = &(struct clk_init_data){
1010 .name = "gcc_usb3_master_clk",
1011 .parent_names = (const char *[]){
1012 "fepll125",
1013 },
1014 .num_parents = 1,
1015 .ops = &clk_branch2_ops,
1016 },
1017 },
1018 };
1019
1020 static struct clk_branch gcc_usb3_sleep_clk = {
1021 .halt_reg = 0x1e02C,
1022 .clkr = {
1023 .enable_reg = 0x1e02C,
1024 .enable_mask = BIT(0),
1025 .hw.init = &(struct clk_init_data){
1026 .name = "gcc_usb3_sleep_clk",
1027 .parent_names = (const char *[]){
1028 "gcc_sleep_clk_src",
1029 },
1030 .num_parents = 1,
1031 .ops = &clk_branch2_ops,
1032 },
1033 },
1034 };
1035
1036 static struct clk_branch gcc_usb3_mock_utmi_clk = {
1037 .halt_reg = 0x1e030,
1038 .clkr = {
1039 .enable_reg = 0x1e030,
1040 .enable_mask = BIT(0),
1041 .hw.init = &(struct clk_init_data){
1042 .name = "gcc_usb3_mock_utmi_clk",
1043 .parent_names = (const char *[]){
1044 "usb30_mock_utmi_clk_src",
1045 },
1046 .num_parents = 1,
1047 .ops = &clk_branch2_ops,
1048 .flags = CLK_SET_RATE_PARENT,
1049 },
1050 },
1051 };
1052
1053 static const struct freq_tbl ftbl_gcc_fephy_dly_clk[] = {
1054 F(125000000, P_FEPLL125DLY, 1, 0, 0),
1055 { }
1056 };
1057
1058 static struct clk_rcg2 fephy_125m_dly_clk_src = {
1059 .cmd_rcgr = 0x12000,
1060 .hid_width = 5,
1061 .parent_map = gcc_xo_125_dly_map,
1062 .freq_tbl = ftbl_gcc_fephy_dly_clk,
1063 .clkr.hw.init = &(struct clk_init_data){
1064 .name = "fephy_125m_dly_clk_src",
1065 .parent_names = gcc_xo_125_dly,
1066 .num_parents = 2,
1067 .ops = &clk_rcg2_ops,
1068 },
1069 };
1070
1071
1072 static const struct freq_tbl ftbl_gcc_wcss2g_clk[] = {
1073 F(48000000, P_XO, 1, 0, 0),
1074 F(250000000, P_FEPLLWCSS2G, 1, 0, 0),
1075 { }
1076 };
1077
1078 static struct clk_rcg2 wcss2g_clk_src = {
1079 .cmd_rcgr = 0x1f000,
1080 .hid_width = 5,
1081 .freq_tbl = ftbl_gcc_wcss2g_clk,
1082 .parent_map = gcc_xo_wcss2g_map,
1083 .clkr.hw.init = &(struct clk_init_data){
1084 .name = "wcss2g_clk_src",
1085 .parent_names = gcc_xo_wcss2g,
1086 .num_parents = 2,
1087 .ops = &clk_rcg2_ops,
1088 .flags = CLK_SET_RATE_PARENT,
1089 },
1090 };
1091
1092 static struct clk_branch gcc_wcss2g_clk = {
1093 .halt_reg = 0x1f00C,
1094 .clkr = {
1095 .enable_reg = 0x1f00C,
1096 .enable_mask = BIT(0),
1097 .hw.init = &(struct clk_init_data){
1098 .name = "gcc_wcss2g_clk",
1099 .parent_names = (const char *[]){
1100 "wcss2g_clk_src",
1101 },
1102 .num_parents = 1,
1103 .ops = &clk_branch2_ops,
1104 .flags = CLK_SET_RATE_PARENT,
1105 },
1106 },
1107 };
1108
1109 static struct clk_branch gcc_wcss2g_ref_clk = {
1110 .halt_reg = 0x1f00C,
1111 .clkr = {
1112 .enable_reg = 0x1f00C,
1113 .enable_mask = BIT(0),
1114 .hw.init = &(struct clk_init_data){
1115 .name = "gcc_wcss2g_ref_clk",
1116 .parent_names = (const char *[]){
1117 "xo",
1118 },
1119 .num_parents = 1,
1120 .ops = &clk_branch2_ops,
1121 .flags = CLK_SET_RATE_PARENT,
1122 },
1123 },
1124 };
1125
1126 static struct clk_branch gcc_wcss2g_rtc_clk = {
1127 .halt_reg = 0x1f010,
1128 .clkr = {
1129 .enable_reg = 0x1f010,
1130 .enable_mask = BIT(0),
1131 .hw.init = &(struct clk_init_data){
1132 .name = "gcc_wcss2g_rtc_clk",
1133 .parent_names = (const char *[]){
1134 "gcc_sleep_clk_src",
1135 },
1136 .num_parents = 1,
1137 .ops = &clk_branch2_ops,
1138 },
1139 },
1140 };
1141
1142 static const struct freq_tbl ftbl_gcc_wcss5g_clk[] = {
1143 F(48000000, P_XO, 1, 0, 0),
1144 F(250000000, P_FEPLLWCSS5G, 1, 0, 0),
1145 { }
1146 };
1147
1148 static struct clk_rcg2 wcss5g_clk_src = {
1149 .cmd_rcgr = 0x20000,
1150 .hid_width = 5,
1151 .parent_map = gcc_xo_wcss5g_map,
1152 .freq_tbl = ftbl_gcc_wcss5g_clk,
1153 .clkr.hw.init = &(struct clk_init_data){
1154 .name = "wcss5g_clk_src",
1155 .parent_names = gcc_xo_wcss5g,
1156 .num_parents = 2,
1157 .ops = &clk_rcg2_ops,
1158 },
1159 };
1160
1161 static struct clk_branch gcc_wcss5g_clk = {
1162 .halt_reg = 0x2000c,
1163 .clkr = {
1164 .enable_reg = 0x2000c,
1165 .enable_mask = BIT(0),
1166 .hw.init = &(struct clk_init_data){
1167 .name = "gcc_wcss5g_clk",
1168 .parent_names = (const char *[]){
1169 "wcss5g_clk_src",
1170 },
1171 .num_parents = 1,
1172 .ops = &clk_branch2_ops,
1173 .flags = CLK_SET_RATE_PARENT,
1174 },
1175 },
1176 };
1177
1178 static struct clk_branch gcc_wcss5g_ref_clk = {
1179 .halt_reg = 0x2000c,
1180 .clkr = {
1181 .enable_reg = 0x2000c,
1182 .enable_mask = BIT(0),
1183 .hw.init = &(struct clk_init_data){
1184 .name = "gcc_wcss5g_ref_clk",
1185 .parent_names = (const char *[]){
1186 "xo",
1187 },
1188 .num_parents = 1,
1189 .ops = &clk_branch2_ops,
1190 .flags = CLK_SET_RATE_PARENT,
1191 },
1192 },
1193 };
1194
1195 static struct clk_branch gcc_wcss5g_rtc_clk = {
1196 .halt_reg = 0x20010,
1197 .clkr = {
1198 .enable_reg = 0x20010,
1199 .enable_mask = BIT(0),
1200 .hw.init = &(struct clk_init_data){
1201 .name = "gcc_wcss5g_rtc_clk",
1202 .parent_names = (const char *[]){
1203 "gcc_sleep_clk_src",
1204 },
1205 .num_parents = 1,
1206 .ops = &clk_branch2_ops,
1207 .flags = CLK_SET_RATE_PARENT,
1208 },
1209 },
1210 };
1211
1212 /* Calculates the VCO rate for FEPLL. */
1213 static u64 clk_fepll_vco_calc_rate(struct clk_fepll *pll_div,
1214 unsigned long parent_rate)
1215 {
1216 const struct clk_fepll_vco *pll_vco = pll_div->pll_vco;
1217 u32 fdbkdiv, refclkdiv, cdiv;
1218 u64 vco;
1219
1220 regmap_read(pll_div->cdiv.clkr.regmap, pll_vco->reg, &cdiv);
1221 refclkdiv = (cdiv >> pll_vco->refclkdiv_shift) &
1222 (BIT(pll_vco->refclkdiv_width) - 1);
1223 fdbkdiv = (cdiv >> pll_vco->fdbkdiv_shift) &
1224 (BIT(pll_vco->fdbkdiv_width) - 1);
1225
1226 vco = parent_rate / refclkdiv;
1227 vco *= 2;
1228 vco *= fdbkdiv;
1229
1230 return vco;
1231 }
1232
1233 static const struct clk_fepll_vco gcc_apss_ddrpll_vco = {
1234 .fdbkdiv_shift = 16,
1235 .fdbkdiv_width = 8,
1236 .refclkdiv_shift = 24,
1237 .refclkdiv_width = 5,
1238 .reg = 0x2e020,
1239 };
1240
1241 static const struct clk_fepll_vco gcc_fepll_vco = {
1242 .fdbkdiv_shift = 16,
1243 .fdbkdiv_width = 8,
1244 .refclkdiv_shift = 24,
1245 .refclkdiv_width = 5,
1246 .reg = 0x2f020,
1247 };
1248
1249 /*
1250 * Round rate function for APSS CPU PLL Clock divider.
1251 * It looks up the frequency table and returns the next higher frequency
1252 * supported in hardware.
1253 */
1254 static long clk_cpu_div_round_rate(struct clk_hw *hw, unsigned long rate,
1255 unsigned long *p_rate)
1256 {
1257 struct clk_fepll *pll = to_clk_fepll(hw);
1258 struct clk_hw *p_hw;
1259 const struct freq_tbl *f;
1260
1261 f = qcom_find_freq(pll->freq_tbl, rate);
1262 if (!f)
1263 return -EINVAL;
1264
1265 p_hw = clk_hw_get_parent_by_index(hw, f->src);
1266 *p_rate = clk_hw_get_rate(p_hw);
1267
1268 return f->freq;
1269 };
1270
1271 /*
1272 * Clock set rate function for APSS CPU PLL Clock divider.
1273 * It looks up the frequency table and updates the PLL divider to corresponding
1274 * divider value.
1275 */
1276 static int clk_cpu_div_set_rate(struct clk_hw *hw, unsigned long rate,
1277 unsigned long parent_rate)
1278 {
1279 struct clk_fepll *pll = to_clk_fepll(hw);
1280 const struct freq_tbl *f;
1281 u32 mask;
1282 int ret;
1283
1284 f = qcom_find_freq(pll->freq_tbl, rate);
1285 if (!f)
1286 return -EINVAL;
1287
1288 mask = (BIT(pll->cdiv.width) - 1) << pll->cdiv.shift;
1289 ret = regmap_update_bits(pll->cdiv.clkr.regmap,
1290 pll->cdiv.reg, mask,
1291 f->pre_div << pll->cdiv.shift);
1292 /*
1293 * There is no status bit which can be checked for successful CPU
1294 * divider update operation so using delay for the same.
1295 */
1296 udelay(1);
1297
1298 return 0;
1299 };
1300
1301 /*
1302 * Clock frequency calculation function for APSS CPU PLL Clock divider.
1303 * This clock divider is nonlinear so this function calculates the actual
1304 * divider and returns the output frequency by dividing VCO Frequency
1305 * with this actual divider value.
1306 */
1307 static unsigned long
1308 clk_cpu_div_recalc_rate(struct clk_hw *hw,
1309 unsigned long parent_rate)
1310 {
1311 struct clk_fepll *pll = to_clk_fepll(hw);
1312 u32 cdiv, pre_div;
1313 u64 rate;
1314
1315 regmap_read(pll->cdiv.clkr.regmap, pll->cdiv.reg, &cdiv);
1316 cdiv = (cdiv >> pll->cdiv.shift) & (BIT(pll->cdiv.width) - 1);
1317
1318 /*
1319 * Some dividers have value in 0.5 fraction so multiply both VCO
1320 * frequency(parent_rate) and pre_div with 2 to make integer
1321 * calculation.
1322 */
1323 if (cdiv > 10)
1324 pre_div = (cdiv + 1) * 2;
1325 else
1326 pre_div = cdiv + 12;
1327
1328 rate = clk_fepll_vco_calc_rate(pll, parent_rate) * 2;
1329 do_div(rate, pre_div);
1330
1331 return rate;
1332 };
1333
1334 static const struct clk_ops clk_regmap_cpu_div_ops = {
1335 .round_rate = clk_cpu_div_round_rate,
1336 .set_rate = clk_cpu_div_set_rate,
1337 .recalc_rate = clk_cpu_div_recalc_rate,
1338 };
1339
1340 static const struct freq_tbl ftbl_apss_ddr_pll[] = {
1341 { 384000000, P_XO, 0xd, 0, 0 },
1342 { 413000000, P_XO, 0xc, 0, 0 },
1343 { 448000000, P_XO, 0xb, 0, 0 },
1344 { 488000000, P_XO, 0xa, 0, 0 },
1345 { 512000000, P_XO, 0x9, 0, 0 },
1346 { 537000000, P_XO, 0x8, 0, 0 },
1347 { 565000000, P_XO, 0x7, 0, 0 },
1348 { 597000000, P_XO, 0x6, 0, 0 },
1349 { 632000000, P_XO, 0x5, 0, 0 },
1350 { 672000000, P_XO, 0x4, 0, 0 },
1351 { 716000000, P_XO, 0x3, 0, 0 },
1352 { 768000000, P_XO, 0x2, 0, 0 },
1353 { 823000000, P_XO, 0x1, 0, 0 },
1354 { 896000000, P_XO, 0x0, 0, 0 },
1355 { }
1356 };
1357
1358 static struct clk_fepll gcc_apss_cpu_plldiv_clk = {
1359 .cdiv.reg = 0x2e020,
1360 .cdiv.shift = 4,
1361 .cdiv.width = 4,
1362 .cdiv.clkr = {
1363 .enable_reg = 0x2e000,
1364 .enable_mask = BIT(0),
1365 .hw.init = &(struct clk_init_data){
1366 .name = "ddrpllapss",
1367 .parent_names = (const char *[]){
1368 "xo",
1369 },
1370 .num_parents = 1,
1371 .ops = &clk_regmap_cpu_div_ops,
1372 },
1373 },
1374 .freq_tbl = ftbl_apss_ddr_pll,
1375 .pll_vco = &gcc_apss_ddrpll_vco,
1376 };
1377
1378 /* Calculates the rate for PLL divider.
1379 * If the divider value is not fixed then it gets the actual divider value
1380 * from divider table. Then, it calculate the clock rate by dividing the
1381 * parent rate with actual divider value.
1382 */
1383 static unsigned long
1384 clk_regmap_clk_div_recalc_rate(struct clk_hw *hw,
1385 unsigned long parent_rate)
1386 {
1387 struct clk_fepll *pll = to_clk_fepll(hw);
1388 u32 cdiv, pre_div = 1;
1389 u64 rate;
1390 const struct clk_div_table *clkt;
1391
1392 if (pll->fixed_div) {
1393 pre_div = pll->fixed_div;
1394 } else {
1395 regmap_read(pll->cdiv.clkr.regmap, pll->cdiv.reg, &cdiv);
1396 cdiv = (cdiv >> pll->cdiv.shift) & (BIT(pll->cdiv.width) - 1);
1397
1398 for (clkt = pll->div_table; clkt->div; clkt++) {
1399 if (clkt->val == cdiv)
1400 pre_div = clkt->div;
1401 }
1402 }
1403
1404 rate = clk_fepll_vco_calc_rate(pll, parent_rate);
1405 do_div(rate, pre_div);
1406
1407 return rate;
1408 };
1409
1410 static const struct clk_ops clk_fepll_div_ops = {
1411 .recalc_rate = clk_regmap_clk_div_recalc_rate,
1412 };
1413
1414 static struct clk_fepll gcc_apss_sdcc_clk = {
1415 .fixed_div = 28,
1416 .cdiv.clkr = {
1417 .hw.init = &(struct clk_init_data){
1418 .name = "ddrpllsdcc",
1419 .parent_names = (const char *[]){
1420 "xo",
1421 },
1422 .num_parents = 1,
1423 .ops = &clk_fepll_div_ops,
1424 },
1425 },
1426 .pll_vco = &gcc_apss_ddrpll_vco,
1427 };
1428
1429 static struct clk_fepll gcc_fepll125_clk = {
1430 .fixed_div = 32,
1431 .cdiv.clkr = {
1432 .hw.init = &(struct clk_init_data){
1433 .name = "fepll125",
1434 .parent_names = (const char *[]){
1435 "xo",
1436 },
1437 .num_parents = 1,
1438 .ops = &clk_fepll_div_ops,
1439 },
1440 },
1441 .pll_vco = &gcc_fepll_vco,
1442 };
1443
1444 static struct clk_fepll gcc_fepll125dly_clk = {
1445 .fixed_div = 32,
1446 .cdiv.clkr = {
1447 .hw.init = &(struct clk_init_data){
1448 .name = "fepll125dly",
1449 .parent_names = (const char *[]){
1450 "xo",
1451 },
1452 .num_parents = 1,
1453 .ops = &clk_fepll_div_ops,
1454 },
1455 },
1456 .pll_vco = &gcc_fepll_vco,
1457 };
1458
1459 static struct clk_fepll gcc_fepll200_clk = {
1460 .fixed_div = 20,
1461 .cdiv.clkr = {
1462 .hw.init = &(struct clk_init_data){
1463 .name = "fepll200",
1464 .parent_names = (const char *[]){
1465 "xo",
1466 },
1467 .num_parents = 1,
1468 .ops = &clk_fepll_div_ops,
1469 },
1470 },
1471 .pll_vco = &gcc_fepll_vco,
1472 };
1473
1474 static struct clk_fepll gcc_fepll500_clk = {
1475 .fixed_div = 8,
1476 .cdiv.clkr = {
1477 .hw.init = &(struct clk_init_data){
1478 .name = "fepll500",
1479 .parent_names = (const char *[]){
1480 "xo",
1481 },
1482 .num_parents = 1,
1483 .ops = &clk_fepll_div_ops,
1484 },
1485 },
1486 .pll_vco = &gcc_fepll_vco,
1487 };
1488
1489 static const struct clk_div_table fepllwcss_clk_div_table[] = {
1490 { 0, 15 },
1491 { 1, 16 },
1492 { 2, 18 },
1493 { 3, 20 },
1494 { },
1495 };
1496
1497 static struct clk_fepll gcc_fepllwcss2g_clk = {
1498 .cdiv.reg = 0x2f020,
1499 .cdiv.shift = 8,
1500 .cdiv.width = 2,
1501 .cdiv.clkr = {
1502 .hw.init = &(struct clk_init_data){
1503 .name = "fepllwcss2g",
1504 .parent_names = (const char *[]){
1505 "xo",
1506 },
1507 .num_parents = 1,
1508 .ops = &clk_fepll_div_ops,
1509 },
1510 },
1511 .div_table = fepllwcss_clk_div_table,
1512 .pll_vco = &gcc_fepll_vco,
1513 };
1514
1515 static struct clk_fepll gcc_fepllwcss5g_clk = {
1516 .cdiv.reg = 0x2f020,
1517 .cdiv.shift = 12,
1518 .cdiv.width = 2,
1519 .cdiv.clkr = {
1520 .hw.init = &(struct clk_init_data){
1521 .name = "fepllwcss5g",
1522 .parent_names = (const char *[]){
1523 "xo",
1524 },
1525 .num_parents = 1,
1526 .ops = &clk_fepll_div_ops,
1527 },
1528 },
1529 .div_table = fepllwcss_clk_div_table,
1530 .pll_vco = &gcc_fepll_vco,
1531 };
1532
1533 static const struct freq_tbl ftbl_gcc_pcnoc_ahb_clk[] = {
1534 F(48000000, P_XO, 1, 0, 0),
1535 F(100000000, P_FEPLL200, 2, 0, 0),
1536 { }
1537 };
1538
1539 static struct clk_rcg2 gcc_pcnoc_ahb_clk_src = {
1540 .cmd_rcgr = 0x21024,
1541 .hid_width = 5,
1542 .parent_map = gcc_xo_200_500_map,
1543 .freq_tbl = ftbl_gcc_pcnoc_ahb_clk,
1544 .clkr.hw.init = &(struct clk_init_data){
1545 .name = "gcc_pcnoc_ahb_clk_src",
1546 .parent_names = gcc_xo_200_500,
1547 .num_parents = 3,
1548 .ops = &clk_rcg2_ops,
1549 },
1550 };
1551
1552 static struct clk_branch pcnoc_clk_src = {
1553 .halt_reg = 0x21030,
1554 .clkr = {
1555 .enable_reg = 0x21030,
1556 .enable_mask = BIT(0),
1557 .hw.init = &(struct clk_init_data){
1558 .name = "pcnoc_clk_src",
1559 .parent_names = (const char *[]){
1560 "gcc_pcnoc_ahb_clk_src",
1561 },
1562 .num_parents = 1,
1563 .ops = &clk_branch2_ops,
1564 .flags = CLK_SET_RATE_PARENT |
1565 CLK_IS_CRITICAL,
1566 },
1567 },
1568 };
1569
1570 static struct clk_regmap *gcc_ipq4019_clocks[] = {
1571 [AUDIO_CLK_SRC] = &audio_clk_src.clkr,
1572 [BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr,
1573 [BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr,
1574 [BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr,
1575 [BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr,
1576 [BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr,
1577 [BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr,
1578 [GCC_USB3_MOCK_UTMI_CLK_SRC] = &usb30_mock_utmi_clk_src.clkr,
1579 [GCC_APPS_CLK_SRC] = &apps_clk_src.clkr,
1580 [GCC_APPS_AHB_CLK_SRC] = &apps_ahb_clk_src.clkr,
1581 [GP1_CLK_SRC] = &gp1_clk_src.clkr,
1582 [GP2_CLK_SRC] = &gp2_clk_src.clkr,
1583 [GP3_CLK_SRC] = &gp3_clk_src.clkr,
1584 [SDCC1_APPS_CLK_SRC] = &sdcc1_apps_clk_src.clkr,
1585 [FEPHY_125M_DLY_CLK_SRC] = &fephy_125m_dly_clk_src.clkr,
1586 [WCSS2G_CLK_SRC] = &wcss2g_clk_src.clkr,
1587 [WCSS5G_CLK_SRC] = &wcss5g_clk_src.clkr,
1588 [GCC_APSS_AHB_CLK] = &gcc_apss_ahb_clk.clkr,
1589 [GCC_AUDIO_AHB_CLK] = &gcc_audio_ahb_clk.clkr,
1590 [GCC_AUDIO_PWM_CLK] = &gcc_audio_pwm_clk.clkr,
1591 [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr,
1592 [GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr,
1593 [GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr,
1594 [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr,
1595 [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr,
1596 [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr,
1597 [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr,
1598 [GCC_DCD_XO_CLK] = &gcc_dcd_xo_clk.clkr,
1599 [GCC_GP1_CLK] = &gcc_gp1_clk.clkr,
1600 [GCC_GP2_CLK] = &gcc_gp2_clk.clkr,
1601 [GCC_GP3_CLK] = &gcc_gp3_clk.clkr,
1602 [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr,
1603 [GCC_CRYPTO_AHB_CLK] = &gcc_crypto_ahb_clk.clkr,
1604 [GCC_CRYPTO_AXI_CLK] = &gcc_crypto_axi_clk.clkr,
1605 [GCC_CRYPTO_CLK] = &gcc_crypto_clk.clkr,
1606 [GCC_ESS_CLK] = &gcc_ess_clk.clkr,
1607 [GCC_IMEM_AXI_CLK] = &gcc_imem_axi_clk.clkr,
1608 [GCC_IMEM_CFG_AHB_CLK] = &gcc_imem_cfg_ahb_clk.clkr,
1609 [GCC_PCIE_AHB_CLK] = &gcc_pcie_ahb_clk.clkr,
1610 [GCC_PCIE_AXI_M_CLK] = &gcc_pcie_axi_m_clk.clkr,
1611 [GCC_PCIE_AXI_S_CLK] = &gcc_pcie_axi_s_clk.clkr,
1612 [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr,
1613 [GCC_QPIC_AHB_CLK] = &gcc_qpic_ahb_clk.clkr,
1614 [GCC_QPIC_CLK] = &gcc_qpic_clk.clkr,
1615 [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr,
1616 [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr,
1617 [GCC_TLMM_AHB_CLK] = &gcc_tlmm_ahb_clk.clkr,
1618 [GCC_USB2_MASTER_CLK] = &gcc_usb2_master_clk.clkr,
1619 [GCC_USB2_SLEEP_CLK] = &gcc_usb2_sleep_clk.clkr,
1620 [GCC_USB2_MOCK_UTMI_CLK] = &gcc_usb2_mock_utmi_clk.clkr,
1621 [GCC_USB3_MASTER_CLK] = &gcc_usb3_master_clk.clkr,
1622 [GCC_USB3_SLEEP_CLK] = &gcc_usb3_sleep_clk.clkr,
1623 [GCC_USB3_MOCK_UTMI_CLK] = &gcc_usb3_mock_utmi_clk.clkr,
1624 [GCC_WCSS2G_CLK] = &gcc_wcss2g_clk.clkr,
1625 [GCC_WCSS2G_REF_CLK] = &gcc_wcss2g_ref_clk.clkr,
1626 [GCC_WCSS2G_RTC_CLK] = &gcc_wcss2g_rtc_clk.clkr,
1627 [GCC_WCSS5G_CLK] = &gcc_wcss5g_clk.clkr,
1628 [GCC_WCSS5G_REF_CLK] = &gcc_wcss5g_ref_clk.clkr,
1629 [GCC_WCSS5G_RTC_CLK] = &gcc_wcss5g_rtc_clk.clkr,
1630 [GCC_SDCC_PLLDIV_CLK] = &gcc_apss_sdcc_clk.cdiv.clkr,
1631 [GCC_FEPLL125_CLK] = &gcc_fepll125_clk.cdiv.clkr,
1632 [GCC_FEPLL125DLY_CLK] = &gcc_fepll125dly_clk.cdiv.clkr,
1633 [GCC_FEPLL200_CLK] = &gcc_fepll200_clk.cdiv.clkr,
1634 [GCC_FEPLL500_CLK] = &gcc_fepll500_clk.cdiv.clkr,
1635 [GCC_FEPLL_WCSS2G_CLK] = &gcc_fepllwcss2g_clk.cdiv.clkr,
1636 [GCC_FEPLL_WCSS5G_CLK] = &gcc_fepllwcss5g_clk.cdiv.clkr,
1637 [GCC_APSS_CPU_PLLDIV_CLK] = &gcc_apss_cpu_plldiv_clk.cdiv.clkr,
1638 [GCC_PCNOC_AHB_CLK_SRC] = &gcc_pcnoc_ahb_clk_src.clkr,
1639 [GCC_PCNOC_AHB_CLK] = &pcnoc_clk_src.clkr,
1640 };
1641
1642 static const struct qcom_reset_map gcc_ipq4019_resets[] = {
1643 [WIFI0_CPU_INIT_RESET] = { 0x1f008, 5 },
1644 [WIFI0_RADIO_SRIF_RESET] = { 0x1f008, 4 },
1645 [WIFI0_RADIO_WARM_RESET] = { 0x1f008, 3 },
1646 [WIFI0_RADIO_COLD_RESET] = { 0x1f008, 2 },
1647 [WIFI0_CORE_WARM_RESET] = { 0x1f008, 1 },
1648 [WIFI0_CORE_COLD_RESET] = { 0x1f008, 0 },
1649 [WIFI1_CPU_INIT_RESET] = { 0x20008, 5 },
1650 [WIFI1_RADIO_SRIF_RESET] = { 0x20008, 4 },
1651 [WIFI1_RADIO_WARM_RESET] = { 0x20008, 3 },
1652 [WIFI1_RADIO_COLD_RESET] = { 0x20008, 2 },
1653 [WIFI1_CORE_WARM_RESET] = { 0x20008, 1 },
1654 [WIFI1_CORE_COLD_RESET] = { 0x20008, 0 },
1655 [USB3_UNIPHY_PHY_ARES] = { 0x1e038, 5 },
1656 [USB3_HSPHY_POR_ARES] = { 0x1e038, 4 },
1657 [USB3_HSPHY_S_ARES] = { 0x1e038, 2 },
1658 [USB2_HSPHY_POR_ARES] = { 0x1e01c, 4 },
1659 [USB2_HSPHY_S_ARES] = { 0x1e01c, 2 },
1660 [PCIE_PHY_AHB_ARES] = { 0x1d010, 11 },
1661 [PCIE_AHB_ARES] = { 0x1d010, 10 },
1662 [PCIE_PWR_ARES] = { 0x1d010, 9 },
1663 [PCIE_PIPE_STICKY_ARES] = { 0x1d010, 8 },
1664 [PCIE_AXI_M_STICKY_ARES] = { 0x1d010, 7 },
1665 [PCIE_PHY_ARES] = { 0x1d010, 6 },
1666 [PCIE_PARF_XPU_ARES] = { 0x1d010, 5 },
1667 [PCIE_AXI_S_XPU_ARES] = { 0x1d010, 4 },
1668 [PCIE_AXI_M_VMIDMT_ARES] = { 0x1d010, 3 },
1669 [PCIE_PIPE_ARES] = { 0x1d010, 2 },
1670 [PCIE_AXI_S_ARES] = { 0x1d010, 1 },
1671 [PCIE_AXI_M_ARES] = { 0x1d010, 0 },
1672 [ESS_RESET] = { 0x12008, 0},
1673 [GCC_BLSP1_BCR] = {0x01000, 0},
1674 [GCC_BLSP1_QUP1_BCR] = {0x02000, 0},
1675 [GCC_BLSP1_UART1_BCR] = {0x02038, 0},
1676 [GCC_BLSP1_QUP2_BCR] = {0x03008, 0},
1677 [GCC_BLSP1_UART2_BCR] = {0x03028, 0},
1678 [GCC_BIMC_BCR] = {0x04000, 0},
1679 [GCC_TLMM_BCR] = {0x05000, 0},
1680 [GCC_IMEM_BCR] = {0x0E000, 0},
1681 [GCC_ESS_BCR] = {0x12008, 0},
1682 [GCC_PRNG_BCR] = {0x13000, 0},
1683 [GCC_BOOT_ROM_BCR] = {0x13008, 0},
1684 [GCC_CRYPTO_BCR] = {0x16000, 0},
1685 [GCC_SDCC1_BCR] = {0x18000, 0},
1686 [GCC_SEC_CTRL_BCR] = {0x1A000, 0},
1687 [GCC_AUDIO_BCR] = {0x1B008, 0},
1688 [GCC_QPIC_BCR] = {0x1C000, 0},
1689 [GCC_PCIE_BCR] = {0x1D000, 0},
1690 [GCC_USB2_BCR] = {0x1E008, 0},
1691 [GCC_USB2_PHY_BCR] = {0x1E018, 0},
1692 [GCC_USB3_BCR] = {0x1E024, 0},
1693 [GCC_USB3_PHY_BCR] = {0x1E034, 0},
1694 [GCC_SYSTEM_NOC_BCR] = {0x21000, 0},
1695 [GCC_PCNOC_BCR] = {0x2102C, 0},
1696 [GCC_DCD_BCR] = {0x21038, 0},
1697 [GCC_SNOC_BUS_TIMEOUT0_BCR] = {0x21064, 0},
1698 [GCC_SNOC_BUS_TIMEOUT1_BCR] = {0x2106C, 0},
1699 [GCC_SNOC_BUS_TIMEOUT2_BCR] = {0x21074, 0},
1700 [GCC_SNOC_BUS_TIMEOUT3_BCR] = {0x2107C, 0},
1701 [GCC_PCNOC_BUS_TIMEOUT0_BCR] = {0x21084, 0},
1702 [GCC_PCNOC_BUS_TIMEOUT1_BCR] = {0x2108C, 0},
1703 [GCC_PCNOC_BUS_TIMEOUT2_BCR] = {0x21094, 0},
1704 [GCC_PCNOC_BUS_TIMEOUT3_BCR] = {0x2109C, 0},
1705 [GCC_PCNOC_BUS_TIMEOUT4_BCR] = {0x210A4, 0},
1706 [GCC_PCNOC_BUS_TIMEOUT5_BCR] = {0x210AC, 0},
1707 [GCC_PCNOC_BUS_TIMEOUT6_BCR] = {0x210B4, 0},
1708 [GCC_PCNOC_BUS_TIMEOUT7_BCR] = {0x210BC, 0},
1709 [GCC_PCNOC_BUS_TIMEOUT8_BCR] = {0x210C4, 0},
1710 [GCC_PCNOC_BUS_TIMEOUT9_BCR] = {0x210CC, 0},
1711 [GCC_TCSR_BCR] = {0x22000, 0},
1712 [GCC_MPM_BCR] = {0x24000, 0},
1713 [GCC_SPDM_BCR] = {0x25000, 0},
1714 };
1715
1716 static const struct regmap_config gcc_ipq4019_regmap_config = {
1717 .reg_bits = 32,
1718 .reg_stride = 4,
1719 .val_bits = 32,
1720 .max_register = 0x2ffff,
1721 .fast_io = true,
1722 };
1723
1724 static const struct qcom_cc_desc gcc_ipq4019_desc = {
1725 .config = &gcc_ipq4019_regmap_config,
1726 .clks = gcc_ipq4019_clocks,
1727 .num_clks = ARRAY_SIZE(gcc_ipq4019_clocks),
1728 .resets = gcc_ipq4019_resets,
1729 .num_resets = ARRAY_SIZE(gcc_ipq4019_resets),
1730 };
1731
1732 static const struct of_device_id gcc_ipq4019_match_table[] = {
1733 { .compatible = "qcom,gcc-ipq4019" },
1734 { }
1735 };
1736 MODULE_DEVICE_TABLE(of, gcc_ipq4019_match_table);
1737
1738 static int gcc_ipq4019_probe(struct platform_device *pdev)
1739 {
1740 return qcom_cc_probe(pdev, &gcc_ipq4019_desc);
1741 }
1742
1743 static struct platform_driver gcc_ipq4019_driver = {
1744 .probe = gcc_ipq4019_probe,
1745 .driver = {
1746 .name = "qcom,gcc-ipq4019",
1747 .of_match_table = gcc_ipq4019_match_table,
1748 },
1749 };
1750
1751 static int __init gcc_ipq4019_init(void)
1752 {
1753 return platform_driver_register(&gcc_ipq4019_driver);
1754 }
1755 core_initcall(gcc_ipq4019_init);
1756
1757 static void __exit gcc_ipq4019_exit(void)
1758 {
1759 platform_driver_unregister(&gcc_ipq4019_driver);
1760 }
1761 module_exit(gcc_ipq4019_exit);
1762
1763 MODULE_ALIAS("platform:gcc-ipq4019");
1764 MODULE_LICENSE("GPL v2");
1765 MODULE_DESCRIPTION("QCOM GCC IPQ4019 driver");