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