GNU Linux-libre 4.14.294-gnu1
[releases.git] / drivers / clk / qcom / gcc-ipq4019.c
1 /*
2  * Copyright (c) 2015 The Linux Foundation. All rights reserved.
3  *
4  * This software is licensed under the terms of the GNU General Public
5  * License version 2, as published by the Free Software Foundation, and
6  * may be copied, distributed, and modified under those terms.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  */
13
14 #include <linux/kernel.h>
15 #include <linux/err.h>
16 #include <linux/platform_device.h>
17 #include <linux/module.h>
18 #include <linux/of.h>
19 #include <linux/of_device.h>
20 #include <linux/clk-provider.h>
21 #include <linux/regmap.h>
22 #include <linux/reset-controller.h>
23 #include <linux/math64.h>
24 #include <linux/delay.h>
25 #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");