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