xref: /linux/drivers/clk/qcom/tcsrcc-glymur.c (revision 522ba450b56fff29f868b1552bdc2965f55de7ed)
1*2c1d6ce4STaniya Das // SPDX-License-Identifier: GPL-2.0-only
2*2c1d6ce4STaniya Das /*
3*2c1d6ce4STaniya Das  * Copyright (c) 2025, Qualcomm Technologies, Inc. and/or its subsidiaries.
4*2c1d6ce4STaniya Das  */
5*2c1d6ce4STaniya Das 
6*2c1d6ce4STaniya Das #include <linux/clk-provider.h>
7*2c1d6ce4STaniya Das #include <linux/mod_devicetable.h>
8*2c1d6ce4STaniya Das #include <linux/module.h>
9*2c1d6ce4STaniya Das #include <linux/of.h>
10*2c1d6ce4STaniya Das #include <linux/platform_device.h>
11*2c1d6ce4STaniya Das #include <linux/regmap.h>
12*2c1d6ce4STaniya Das 
13*2c1d6ce4STaniya Das #include <dt-bindings/clock/qcom,glymur-tcsr.h>
14*2c1d6ce4STaniya Das 
15*2c1d6ce4STaniya Das #include "clk-alpha-pll.h"
16*2c1d6ce4STaniya Das #include "clk-branch.h"
17*2c1d6ce4STaniya Das #include "clk-pll.h"
18*2c1d6ce4STaniya Das #include "clk-rcg.h"
19*2c1d6ce4STaniya Das #include "clk-regmap.h"
20*2c1d6ce4STaniya Das #include "clk-regmap-divider.h"
21*2c1d6ce4STaniya Das #include "clk-regmap-mux.h"
22*2c1d6ce4STaniya Das #include "common.h"
23*2c1d6ce4STaniya Das #include "gdsc.h"
24*2c1d6ce4STaniya Das #include "reset.h"
25*2c1d6ce4STaniya Das 
26*2c1d6ce4STaniya Das enum {
27*2c1d6ce4STaniya Das 	DT_BI_TCXO_PAD,
28*2c1d6ce4STaniya Das };
29*2c1d6ce4STaniya Das 
30*2c1d6ce4STaniya Das static struct clk_branch tcsr_edp_clkref_en = {
31*2c1d6ce4STaniya Das 	.halt_reg = 0x1c,
32*2c1d6ce4STaniya Das 	.halt_check = BRANCH_HALT_DELAY,
33*2c1d6ce4STaniya Das 	.clkr = {
34*2c1d6ce4STaniya Das 		.enable_reg = 0x1c,
35*2c1d6ce4STaniya Das 		.enable_mask = BIT(0),
36*2c1d6ce4STaniya Das 		.hw.init = &(const struct clk_init_data) {
37*2c1d6ce4STaniya Das 			.name = "tcsr_edp_clkref_en",
38*2c1d6ce4STaniya Das 			.parent_data = &(const struct clk_parent_data){
39*2c1d6ce4STaniya Das 				.index = DT_BI_TCXO_PAD,
40*2c1d6ce4STaniya Das 			},
41*2c1d6ce4STaniya Das 			.num_parents = 1,
42*2c1d6ce4STaniya Das 			.ops = &clk_branch2_ops,
43*2c1d6ce4STaniya Das 		},
44*2c1d6ce4STaniya Das 	},
45*2c1d6ce4STaniya Das };
46*2c1d6ce4STaniya Das 
47*2c1d6ce4STaniya Das static struct clk_branch tcsr_pcie_1_clkref_en = {
48*2c1d6ce4STaniya Das 	.halt_reg = 0x4,
49*2c1d6ce4STaniya Das 	.halt_check = BRANCH_HALT_DELAY,
50*2c1d6ce4STaniya Das 	.clkr = {
51*2c1d6ce4STaniya Das 		.enable_reg = 0x4,
52*2c1d6ce4STaniya Das 		.enable_mask = BIT(0),
53*2c1d6ce4STaniya Das 		.hw.init = &(const struct clk_init_data) {
54*2c1d6ce4STaniya Das 			.name = "tcsr_pcie_1_clkref_en",
55*2c1d6ce4STaniya Das 			.parent_data = &(const struct clk_parent_data){
56*2c1d6ce4STaniya Das 				.index = DT_BI_TCXO_PAD,
57*2c1d6ce4STaniya Das 			},
58*2c1d6ce4STaniya Das 			.num_parents = 1,
59*2c1d6ce4STaniya Das 			.ops = &clk_branch2_ops,
60*2c1d6ce4STaniya Das 		},
61*2c1d6ce4STaniya Das 	},
62*2c1d6ce4STaniya Das };
63*2c1d6ce4STaniya Das 
64*2c1d6ce4STaniya Das static struct clk_branch tcsr_pcie_2_clkref_en = {
65*2c1d6ce4STaniya Das 	.halt_reg = 0x8,
66*2c1d6ce4STaniya Das 	.halt_check = BRANCH_HALT_DELAY,
67*2c1d6ce4STaniya Das 	.clkr = {
68*2c1d6ce4STaniya Das 		.enable_reg = 0x8,
69*2c1d6ce4STaniya Das 		.enable_mask = BIT(0),
70*2c1d6ce4STaniya Das 		.hw.init = &(const struct clk_init_data) {
71*2c1d6ce4STaniya Das 			.name = "tcsr_pcie_2_clkref_en",
72*2c1d6ce4STaniya Das 			.parent_data = &(const struct clk_parent_data){
73*2c1d6ce4STaniya Das 				.index = DT_BI_TCXO_PAD,
74*2c1d6ce4STaniya Das 			},
75*2c1d6ce4STaniya Das 			.num_parents = 1,
76*2c1d6ce4STaniya Das 			.ops = &clk_branch2_ops,
77*2c1d6ce4STaniya Das 		},
78*2c1d6ce4STaniya Das 	},
79*2c1d6ce4STaniya Das };
80*2c1d6ce4STaniya Das 
81*2c1d6ce4STaniya Das static struct clk_branch tcsr_pcie_3_clkref_en = {
82*2c1d6ce4STaniya Das 	.halt_reg = 0x10,
83*2c1d6ce4STaniya Das 	.halt_check = BRANCH_HALT_DELAY,
84*2c1d6ce4STaniya Das 	.clkr = {
85*2c1d6ce4STaniya Das 		.enable_reg = 0x10,
86*2c1d6ce4STaniya Das 		.enable_mask = BIT(0),
87*2c1d6ce4STaniya Das 		.hw.init = &(const struct clk_init_data) {
88*2c1d6ce4STaniya Das 			.name = "tcsr_pcie_3_clkref_en",
89*2c1d6ce4STaniya Das 			.parent_data = &(const struct clk_parent_data){
90*2c1d6ce4STaniya Das 				.index = DT_BI_TCXO_PAD,
91*2c1d6ce4STaniya Das 			},
92*2c1d6ce4STaniya Das 			.num_parents = 1,
93*2c1d6ce4STaniya Das 			.ops = &clk_branch2_ops,
94*2c1d6ce4STaniya Das 		},
95*2c1d6ce4STaniya Das 	},
96*2c1d6ce4STaniya Das };
97*2c1d6ce4STaniya Das 
98*2c1d6ce4STaniya Das static struct clk_branch tcsr_pcie_4_clkref_en = {
99*2c1d6ce4STaniya Das 	.halt_reg = 0x14,
100*2c1d6ce4STaniya Das 	.halt_check = BRANCH_HALT_DELAY,
101*2c1d6ce4STaniya Das 	.clkr = {
102*2c1d6ce4STaniya Das 		.enable_reg = 0x14,
103*2c1d6ce4STaniya Das 		.enable_mask = BIT(0),
104*2c1d6ce4STaniya Das 		.hw.init = &(const struct clk_init_data) {
105*2c1d6ce4STaniya Das 			.name = "tcsr_pcie_4_clkref_en",
106*2c1d6ce4STaniya Das 			.parent_data = &(const struct clk_parent_data){
107*2c1d6ce4STaniya Das 				.index = DT_BI_TCXO_PAD,
108*2c1d6ce4STaniya Das 			},
109*2c1d6ce4STaniya Das 			.num_parents = 1,
110*2c1d6ce4STaniya Das 			.ops = &clk_branch2_ops,
111*2c1d6ce4STaniya Das 		},
112*2c1d6ce4STaniya Das 	},
113*2c1d6ce4STaniya Das };
114*2c1d6ce4STaniya Das 
115*2c1d6ce4STaniya Das static struct clk_branch tcsr_usb2_1_clkref_en = {
116*2c1d6ce4STaniya Das 	.halt_reg = 0x28,
117*2c1d6ce4STaniya Das 	.halt_check = BRANCH_HALT_DELAY,
118*2c1d6ce4STaniya Das 	.clkr = {
119*2c1d6ce4STaniya Das 		.enable_reg = 0x28,
120*2c1d6ce4STaniya Das 		.enable_mask = BIT(0),
121*2c1d6ce4STaniya Das 		.hw.init = &(const struct clk_init_data) {
122*2c1d6ce4STaniya Das 			.name = "tcsr_usb2_1_clkref_en",
123*2c1d6ce4STaniya Das 			.parent_data = &(const struct clk_parent_data){
124*2c1d6ce4STaniya Das 				.index = DT_BI_TCXO_PAD,
125*2c1d6ce4STaniya Das 			},
126*2c1d6ce4STaniya Das 			.num_parents = 1,
127*2c1d6ce4STaniya Das 			.ops = &clk_branch2_ops,
128*2c1d6ce4STaniya Das 		},
129*2c1d6ce4STaniya Das 	},
130*2c1d6ce4STaniya Das };
131*2c1d6ce4STaniya Das 
132*2c1d6ce4STaniya Das static struct clk_branch tcsr_usb2_2_clkref_en = {
133*2c1d6ce4STaniya Das 	.halt_reg = 0x2c,
134*2c1d6ce4STaniya Das 	.halt_check = BRANCH_HALT_DELAY,
135*2c1d6ce4STaniya Das 	.clkr = {
136*2c1d6ce4STaniya Das 		.enable_reg = 0x2c,
137*2c1d6ce4STaniya Das 		.enable_mask = BIT(0),
138*2c1d6ce4STaniya Das 		.hw.init = &(const struct clk_init_data) {
139*2c1d6ce4STaniya Das 			.name = "tcsr_usb2_2_clkref_en",
140*2c1d6ce4STaniya Das 			.parent_data = &(const struct clk_parent_data){
141*2c1d6ce4STaniya Das 				.index = DT_BI_TCXO_PAD,
142*2c1d6ce4STaniya Das 			},
143*2c1d6ce4STaniya Das 			.num_parents = 1,
144*2c1d6ce4STaniya Das 			.ops = &clk_branch2_ops,
145*2c1d6ce4STaniya Das 		},
146*2c1d6ce4STaniya Das 	},
147*2c1d6ce4STaniya Das };
148*2c1d6ce4STaniya Das 
149*2c1d6ce4STaniya Das static struct clk_branch tcsr_usb2_3_clkref_en = {
150*2c1d6ce4STaniya Das 	.halt_reg = 0x30,
151*2c1d6ce4STaniya Das 	.halt_check = BRANCH_HALT_DELAY,
152*2c1d6ce4STaniya Das 	.clkr = {
153*2c1d6ce4STaniya Das 		.enable_reg = 0x30,
154*2c1d6ce4STaniya Das 		.enable_mask = BIT(0),
155*2c1d6ce4STaniya Das 		.hw.init = &(const struct clk_init_data) {
156*2c1d6ce4STaniya Das 			.name = "tcsr_usb2_3_clkref_en",
157*2c1d6ce4STaniya Das 			.parent_data = &(const struct clk_parent_data){
158*2c1d6ce4STaniya Das 				.index = DT_BI_TCXO_PAD,
159*2c1d6ce4STaniya Das 			},
160*2c1d6ce4STaniya Das 			.num_parents = 1,
161*2c1d6ce4STaniya Das 			.ops = &clk_branch2_ops,
162*2c1d6ce4STaniya Das 		},
163*2c1d6ce4STaniya Das 	},
164*2c1d6ce4STaniya Das };
165*2c1d6ce4STaniya Das 
166*2c1d6ce4STaniya Das static struct clk_branch tcsr_usb2_4_clkref_en = {
167*2c1d6ce4STaniya Das 	.halt_reg = 0x44,
168*2c1d6ce4STaniya Das 	.halt_check = BRANCH_HALT_DELAY,
169*2c1d6ce4STaniya Das 	.clkr = {
170*2c1d6ce4STaniya Das 		.enable_reg = 0x44,
171*2c1d6ce4STaniya Das 		.enable_mask = BIT(0),
172*2c1d6ce4STaniya Das 		.hw.init = &(const struct clk_init_data) {
173*2c1d6ce4STaniya Das 			.name = "tcsr_usb2_4_clkref_en",
174*2c1d6ce4STaniya Das 			.parent_data = &(const struct clk_parent_data){
175*2c1d6ce4STaniya Das 				.index = DT_BI_TCXO_PAD,
176*2c1d6ce4STaniya Das 			},
177*2c1d6ce4STaniya Das 			.num_parents = 1,
178*2c1d6ce4STaniya Das 			.ops = &clk_branch2_ops,
179*2c1d6ce4STaniya Das 		},
180*2c1d6ce4STaniya Das 	},
181*2c1d6ce4STaniya Das };
182*2c1d6ce4STaniya Das 
183*2c1d6ce4STaniya Das static struct clk_branch tcsr_usb3_0_clkref_en = {
184*2c1d6ce4STaniya Das 	.halt_reg = 0x20,
185*2c1d6ce4STaniya Das 	.halt_check = BRANCH_HALT_DELAY,
186*2c1d6ce4STaniya Das 	.clkr = {
187*2c1d6ce4STaniya Das 		.enable_reg = 0x20,
188*2c1d6ce4STaniya Das 		.enable_mask = BIT(0),
189*2c1d6ce4STaniya Das 		.hw.init = &(const struct clk_init_data) {
190*2c1d6ce4STaniya Das 			.name = "tcsr_usb3_0_clkref_en",
191*2c1d6ce4STaniya Das 			.parent_data = &(const struct clk_parent_data){
192*2c1d6ce4STaniya Das 				.index = DT_BI_TCXO_PAD,
193*2c1d6ce4STaniya Das 			},
194*2c1d6ce4STaniya Das 			.num_parents = 1,
195*2c1d6ce4STaniya Das 			.ops = &clk_branch2_ops,
196*2c1d6ce4STaniya Das 		},
197*2c1d6ce4STaniya Das 	},
198*2c1d6ce4STaniya Das };
199*2c1d6ce4STaniya Das 
200*2c1d6ce4STaniya Das static struct clk_branch tcsr_usb3_1_clkref_en = {
201*2c1d6ce4STaniya Das 	.halt_reg = 0x24,
202*2c1d6ce4STaniya Das 	.halt_check = BRANCH_HALT_DELAY,
203*2c1d6ce4STaniya Das 	.clkr = {
204*2c1d6ce4STaniya Das 		.enable_reg = 0x24,
205*2c1d6ce4STaniya Das 		.enable_mask = BIT(0),
206*2c1d6ce4STaniya Das 		.hw.init = &(const struct clk_init_data) {
207*2c1d6ce4STaniya Das 			.name = "tcsr_usb3_1_clkref_en",
208*2c1d6ce4STaniya Das 			.parent_data = &(const struct clk_parent_data){
209*2c1d6ce4STaniya Das 				.index = DT_BI_TCXO_PAD,
210*2c1d6ce4STaniya Das 			},
211*2c1d6ce4STaniya Das 			.num_parents = 1,
212*2c1d6ce4STaniya Das 			.ops = &clk_branch2_ops,
213*2c1d6ce4STaniya Das 		},
214*2c1d6ce4STaniya Das 	},
215*2c1d6ce4STaniya Das };
216*2c1d6ce4STaniya Das 
217*2c1d6ce4STaniya Das static struct clk_branch tcsr_usb4_1_clkref_en = {
218*2c1d6ce4STaniya Das 	.halt_reg = 0x0,
219*2c1d6ce4STaniya Das 	.halt_check = BRANCH_HALT_DELAY,
220*2c1d6ce4STaniya Das 	.clkr = {
221*2c1d6ce4STaniya Das 		.enable_reg = 0x0,
222*2c1d6ce4STaniya Das 		.enable_mask = BIT(0),
223*2c1d6ce4STaniya Das 		.hw.init = &(const struct clk_init_data) {
224*2c1d6ce4STaniya Das 			.name = "tcsr_usb4_1_clkref_en",
225*2c1d6ce4STaniya Das 			.parent_data = &(const struct clk_parent_data){
226*2c1d6ce4STaniya Das 				.index = DT_BI_TCXO_PAD,
227*2c1d6ce4STaniya Das 			},
228*2c1d6ce4STaniya Das 			.num_parents = 1,
229*2c1d6ce4STaniya Das 			.ops = &clk_branch2_ops,
230*2c1d6ce4STaniya Das 		},
231*2c1d6ce4STaniya Das 	},
232*2c1d6ce4STaniya Das };
233*2c1d6ce4STaniya Das 
234*2c1d6ce4STaniya Das static struct clk_branch tcsr_usb4_2_clkref_en = {
235*2c1d6ce4STaniya Das 	.halt_reg = 0x18,
236*2c1d6ce4STaniya Das 	.halt_check = BRANCH_HALT_DELAY,
237*2c1d6ce4STaniya Das 	.clkr = {
238*2c1d6ce4STaniya Das 		.enable_reg = 0x18,
239*2c1d6ce4STaniya Das 		.enable_mask = BIT(0),
240*2c1d6ce4STaniya Das 		.hw.init = &(const struct clk_init_data) {
241*2c1d6ce4STaniya Das 			.name = "tcsr_usb4_2_clkref_en",
242*2c1d6ce4STaniya Das 			.parent_data = &(const struct clk_parent_data){
243*2c1d6ce4STaniya Das 				.index = DT_BI_TCXO_PAD,
244*2c1d6ce4STaniya Das 			},
245*2c1d6ce4STaniya Das 			.num_parents = 1,
246*2c1d6ce4STaniya Das 			.ops = &clk_branch2_ops,
247*2c1d6ce4STaniya Das 		},
248*2c1d6ce4STaniya Das 	},
249*2c1d6ce4STaniya Das };
250*2c1d6ce4STaniya Das 
251*2c1d6ce4STaniya Das static struct clk_regmap *tcsr_cc_glymur_clocks[] = {
252*2c1d6ce4STaniya Das 	[TCSR_EDP_CLKREF_EN] = &tcsr_edp_clkref_en.clkr,
253*2c1d6ce4STaniya Das 	[TCSR_PCIE_1_CLKREF_EN] = &tcsr_pcie_1_clkref_en.clkr,
254*2c1d6ce4STaniya Das 	[TCSR_PCIE_2_CLKREF_EN] = &tcsr_pcie_2_clkref_en.clkr,
255*2c1d6ce4STaniya Das 	[TCSR_PCIE_3_CLKREF_EN] = &tcsr_pcie_3_clkref_en.clkr,
256*2c1d6ce4STaniya Das 	[TCSR_PCIE_4_CLKREF_EN] = &tcsr_pcie_4_clkref_en.clkr,
257*2c1d6ce4STaniya Das 	[TCSR_USB2_1_CLKREF_EN] = &tcsr_usb2_1_clkref_en.clkr,
258*2c1d6ce4STaniya Das 	[TCSR_USB2_2_CLKREF_EN] = &tcsr_usb2_2_clkref_en.clkr,
259*2c1d6ce4STaniya Das 	[TCSR_USB2_3_CLKREF_EN] = &tcsr_usb2_3_clkref_en.clkr,
260*2c1d6ce4STaniya Das 	[TCSR_USB2_4_CLKREF_EN] = &tcsr_usb2_4_clkref_en.clkr,
261*2c1d6ce4STaniya Das 	[TCSR_USB3_0_CLKREF_EN] = &tcsr_usb3_0_clkref_en.clkr,
262*2c1d6ce4STaniya Das 	[TCSR_USB3_1_CLKREF_EN] = &tcsr_usb3_1_clkref_en.clkr,
263*2c1d6ce4STaniya Das 	[TCSR_USB4_1_CLKREF_EN] = &tcsr_usb4_1_clkref_en.clkr,
264*2c1d6ce4STaniya Das 	[TCSR_USB4_2_CLKREF_EN] = &tcsr_usb4_2_clkref_en.clkr,
265*2c1d6ce4STaniya Das };
266*2c1d6ce4STaniya Das 
267*2c1d6ce4STaniya Das static const struct regmap_config tcsr_cc_glymur_regmap_config = {
268*2c1d6ce4STaniya Das 	.reg_bits = 32,
269*2c1d6ce4STaniya Das 	.reg_stride = 4,
270*2c1d6ce4STaniya Das 	.val_bits = 32,
271*2c1d6ce4STaniya Das 	.max_register = 0x44,
272*2c1d6ce4STaniya Das 	.fast_io = true,
273*2c1d6ce4STaniya Das };
274*2c1d6ce4STaniya Das 
275*2c1d6ce4STaniya Das static const struct qcom_cc_desc tcsr_cc_glymur_desc = {
276*2c1d6ce4STaniya Das 	.config = &tcsr_cc_glymur_regmap_config,
277*2c1d6ce4STaniya Das 	.clks = tcsr_cc_glymur_clocks,
278*2c1d6ce4STaniya Das 	.num_clks = ARRAY_SIZE(tcsr_cc_glymur_clocks),
279*2c1d6ce4STaniya Das };
280*2c1d6ce4STaniya Das 
281*2c1d6ce4STaniya Das static const struct of_device_id tcsr_cc_glymur_match_table[] = {
282*2c1d6ce4STaniya Das 	{ .compatible = "qcom,glymur-tcsr" },
283*2c1d6ce4STaniya Das 	{ }
284*2c1d6ce4STaniya Das };
285*2c1d6ce4STaniya Das MODULE_DEVICE_TABLE(of, tcsr_cc_glymur_match_table);
286*2c1d6ce4STaniya Das 
tcsr_cc_glymur_probe(struct platform_device * pdev)287*2c1d6ce4STaniya Das static int tcsr_cc_glymur_probe(struct platform_device *pdev)
288*2c1d6ce4STaniya Das {
289*2c1d6ce4STaniya Das 	return qcom_cc_probe(pdev, &tcsr_cc_glymur_desc);
290*2c1d6ce4STaniya Das }
291*2c1d6ce4STaniya Das 
292*2c1d6ce4STaniya Das static struct platform_driver tcsr_cc_glymur_driver = {
293*2c1d6ce4STaniya Das 	.probe = tcsr_cc_glymur_probe,
294*2c1d6ce4STaniya Das 	.driver = {
295*2c1d6ce4STaniya Das 		.name = "tcsrcc-glymur",
296*2c1d6ce4STaniya Das 		.of_match_table = tcsr_cc_glymur_match_table,
297*2c1d6ce4STaniya Das 	},
298*2c1d6ce4STaniya Das };
299*2c1d6ce4STaniya Das 
tcsr_cc_glymur_init(void)300*2c1d6ce4STaniya Das static int __init tcsr_cc_glymur_init(void)
301*2c1d6ce4STaniya Das {
302*2c1d6ce4STaniya Das 	return platform_driver_register(&tcsr_cc_glymur_driver);
303*2c1d6ce4STaniya Das }
304*2c1d6ce4STaniya Das subsys_initcall(tcsr_cc_glymur_init);
305*2c1d6ce4STaniya Das 
tcsr_cc_glymur_exit(void)306*2c1d6ce4STaniya Das static void __exit tcsr_cc_glymur_exit(void)
307*2c1d6ce4STaniya Das {
308*2c1d6ce4STaniya Das 	platform_driver_unregister(&tcsr_cc_glymur_driver);
309*2c1d6ce4STaniya Das }
310*2c1d6ce4STaniya Das module_exit(tcsr_cc_glymur_exit);
311*2c1d6ce4STaniya Das 
312*2c1d6ce4STaniya Das MODULE_DESCRIPTION("QTI TCSRCC GLYMUR Driver");
313*2c1d6ce4STaniya Das MODULE_LICENSE("GPL");
314