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