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