xref: /linux/drivers/clk/qcom/tcsrcc-nord.c (revision 0fc8f6200d2313278fbf4539bbab74677c685531)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
4  */
5 
6 #include <linux/clk-provider.h>
7 #include <linux/mod_devicetable.h>
8 #include <linux/module.h>
9 #include <linux/platform_device.h>
10 #include <linux/regmap.h>
11 
12 #include <dt-bindings/clock/qcom,nord-tcsrcc.h>
13 
14 #include "clk-alpha-pll.h"
15 #include "clk-branch.h"
16 #include "clk-pll.h"
17 #include "clk-rcg.h"
18 #include "clk-regmap.h"
19 #include "clk-regmap-divider.h"
20 #include "clk-regmap-mux.h"
21 #include "common.h"
22 #include "reset.h"
23 
24 enum {
25 	DT_BI_TCXO_PAD,
26 };
27 
28 static struct clk_branch tcsr_dp_rx_0_clkref_en = {
29 	.halt_reg = 0xa008,
30 	.halt_check = BRANCH_HALT_DELAY,
31 	.clkr = {
32 		.enable_reg = 0xa008,
33 		.enable_mask = BIT(0),
34 		.hw.init = &(const struct clk_init_data) {
35 			.name = "tcsr_dp_rx_0_clkref_en",
36 			.parent_data = &(const struct clk_parent_data){
37 				.index = DT_BI_TCXO_PAD,
38 			},
39 			.num_parents = 1,
40 			.ops = &clk_branch2_ops,
41 		},
42 	},
43 };
44 
45 static struct clk_branch tcsr_dp_rx_1_clkref_en = {
46 	.halt_reg = 0xb008,
47 	.halt_check = BRANCH_HALT_DELAY,
48 	.clkr = {
49 		.enable_reg = 0xb008,
50 		.enable_mask = BIT(0),
51 		.hw.init = &(const struct clk_init_data) {
52 			.name = "tcsr_dp_rx_1_clkref_en",
53 			.parent_data = &(const struct clk_parent_data){
54 				.index = DT_BI_TCXO_PAD,
55 			},
56 			.num_parents = 1,
57 			.ops = &clk_branch2_ops,
58 		},
59 	},
60 };
61 
62 static struct clk_branch tcsr_dp_tx_0_clkref_en = {
63 	.halt_reg = 0xc008,
64 	.halt_check = BRANCH_HALT_DELAY,
65 	.clkr = {
66 		.enable_reg = 0xc008,
67 		.enable_mask = BIT(0),
68 		.hw.init = &(const struct clk_init_data) {
69 			.name = "tcsr_dp_tx_0_clkref_en",
70 			.parent_data = &(const struct clk_parent_data){
71 				.index = DT_BI_TCXO_PAD,
72 			},
73 			.num_parents = 1,
74 			.ops = &clk_branch2_ops,
75 		},
76 	},
77 };
78 
79 static struct clk_branch tcsr_dp_tx_1_clkref_en = {
80 	.halt_reg = 0xd008,
81 	.halt_check = BRANCH_HALT_DELAY,
82 	.clkr = {
83 		.enable_reg = 0xd008,
84 		.enable_mask = BIT(0),
85 		.hw.init = &(const struct clk_init_data) {
86 			.name = "tcsr_dp_tx_1_clkref_en",
87 			.parent_data = &(const struct clk_parent_data){
88 				.index = DT_BI_TCXO_PAD,
89 			},
90 			.num_parents = 1,
91 			.ops = &clk_branch2_ops,
92 		},
93 	},
94 };
95 
96 static struct clk_branch tcsr_dp_tx_2_clkref_en = {
97 	.halt_reg = 0xe008,
98 	.halt_check = BRANCH_HALT_DELAY,
99 	.clkr = {
100 		.enable_reg = 0xe008,
101 		.enable_mask = BIT(0),
102 		.hw.init = &(const struct clk_init_data) {
103 			.name = "tcsr_dp_tx_2_clkref_en",
104 			.parent_data = &(const struct clk_parent_data){
105 				.index = DT_BI_TCXO_PAD,
106 			},
107 			.num_parents = 1,
108 			.ops = &clk_branch2_ops,
109 		},
110 	},
111 };
112 
113 static struct clk_branch tcsr_dp_tx_3_clkref_en = {
114 	.halt_reg = 0xf008,
115 	.halt_check = BRANCH_HALT_DELAY,
116 	.clkr = {
117 		.enable_reg = 0xf008,
118 		.enable_mask = BIT(0),
119 		.hw.init = &(const struct clk_init_data) {
120 			.name = "tcsr_dp_tx_3_clkref_en",
121 			.parent_data = &(const struct clk_parent_data){
122 				.index = DT_BI_TCXO_PAD,
123 			},
124 			.num_parents = 1,
125 			.ops = &clk_branch2_ops,
126 		},
127 	},
128 };
129 
130 static struct clk_branch tcsr_pcie_clkref_en = {
131 	.halt_reg = 0x8,
132 	.halt_check = BRANCH_HALT_DELAY,
133 	.clkr = {
134 		.enable_reg = 0x8,
135 		.enable_mask = BIT(0),
136 		.hw.init = &(const struct clk_init_data) {
137 			.name = "tcsr_pcie_clkref_en",
138 			.parent_data = &(const struct clk_parent_data){
139 				.index = DT_BI_TCXO_PAD,
140 			},
141 			.num_parents = 1,
142 			.ops = &clk_branch2_ops,
143 		},
144 	},
145 };
146 
147 static struct clk_branch tcsr_ufs_clkref_en = {
148 	.halt_reg = 0x3008,
149 	.halt_check = BRANCH_HALT_DELAY,
150 	.clkr = {
151 		.enable_reg = 0x3008,
152 		.enable_mask = BIT(0),
153 		.hw.init = &(const struct clk_init_data) {
154 			.name = "tcsr_ufs_clkref_en",
155 			.parent_data = &(const struct clk_parent_data){
156 				.index = DT_BI_TCXO_PAD,
157 			},
158 			.num_parents = 1,
159 			.ops = &clk_branch2_ops,
160 		},
161 	},
162 };
163 
164 static struct clk_branch tcsr_usb2_0_clkref_en = {
165 	.halt_reg = 0x4008,
166 	.halt_check = BRANCH_HALT_DELAY,
167 	.clkr = {
168 		.enable_reg = 0x4008,
169 		.enable_mask = BIT(0),
170 		.hw.init = &(const struct clk_init_data) {
171 			.name = "tcsr_usb2_0_clkref_en",
172 			.parent_data = &(const struct clk_parent_data){
173 				.index = DT_BI_TCXO_PAD,
174 			},
175 			.num_parents = 1,
176 			.ops = &clk_branch2_ops,
177 		},
178 	},
179 };
180 
181 static struct clk_branch tcsr_usb2_1_clkref_en = {
182 	.halt_reg = 0x5008,
183 	.halt_check = BRANCH_HALT_DELAY,
184 	.clkr = {
185 		.enable_reg = 0x5008,
186 		.enable_mask = BIT(0),
187 		.hw.init = &(const struct clk_init_data) {
188 			.name = "tcsr_usb2_1_clkref_en",
189 			.parent_data = &(const struct clk_parent_data){
190 				.index = DT_BI_TCXO_PAD,
191 			},
192 			.num_parents = 1,
193 			.ops = &clk_branch2_ops,
194 		},
195 	},
196 };
197 
198 static struct clk_branch tcsr_usb2_2_clkref_en = {
199 	.halt_reg = 0x6008,
200 	.halt_check = BRANCH_HALT_DELAY,
201 	.clkr = {
202 		.enable_reg = 0x6008,
203 		.enable_mask = BIT(0),
204 		.hw.init = &(const struct clk_init_data) {
205 			.name = "tcsr_usb2_2_clkref_en",
206 			.parent_data = &(const struct clk_parent_data){
207 				.index = DT_BI_TCXO_PAD,
208 			},
209 			.num_parents = 1,
210 			.ops = &clk_branch2_ops,
211 		},
212 	},
213 };
214 
215 static struct clk_branch tcsr_usb3_0_clkref_en = {
216 	.halt_reg = 0x8008,
217 	.halt_check = BRANCH_HALT_DELAY,
218 	.clkr = {
219 		.enable_reg = 0x8008,
220 		.enable_mask = BIT(0),
221 		.hw.init = &(const struct clk_init_data) {
222 			.name = "tcsr_usb3_0_clkref_en",
223 			.parent_data = &(const struct clk_parent_data){
224 				.index = DT_BI_TCXO_PAD,
225 			},
226 			.num_parents = 1,
227 			.ops = &clk_branch2_ops,
228 		},
229 	},
230 };
231 
232 static struct clk_branch tcsr_usb3_1_clkref_en = {
233 	.halt_reg = 0x7008,
234 	.halt_check = BRANCH_HALT_DELAY,
235 	.clkr = {
236 		.enable_reg = 0x7008,
237 		.enable_mask = BIT(0),
238 		.hw.init = &(const struct clk_init_data) {
239 			.name = "tcsr_usb3_1_clkref_en",
240 			.parent_data = &(const struct clk_parent_data){
241 				.index = DT_BI_TCXO_PAD,
242 			},
243 			.num_parents = 1,
244 			.ops = &clk_branch2_ops,
245 		},
246 	},
247 };
248 
249 static struct clk_branch tcsr_ux_sgmii_0_clkref_en = {
250 	.halt_reg = 0x1008,
251 	.halt_check = BRANCH_HALT_DELAY,
252 	.clkr = {
253 		.enable_reg = 0x1008,
254 		.enable_mask = BIT(0),
255 		.hw.init = &(const struct clk_init_data) {
256 			.name = "tcsr_ux_sgmii_0_clkref_en",
257 			.parent_data = &(const struct clk_parent_data){
258 				.index = DT_BI_TCXO_PAD,
259 			},
260 			.num_parents = 1,
261 			.ops = &clk_branch2_ops,
262 		},
263 	},
264 };
265 
266 static struct clk_branch tcsr_ux_sgmii_1_clkref_en = {
267 	.halt_reg = 0x2008,
268 	.halt_check = BRANCH_HALT_DELAY,
269 	.clkr = {
270 		.enable_reg = 0x2008,
271 		.enable_mask = BIT(0),
272 		.hw.init = &(const struct clk_init_data) {
273 			.name = "tcsr_ux_sgmii_1_clkref_en",
274 			.parent_data = &(const struct clk_parent_data){
275 				.index = DT_BI_TCXO_PAD,
276 			},
277 			.num_parents = 1,
278 			.ops = &clk_branch2_ops,
279 		},
280 	},
281 };
282 
283 static struct clk_regmap *tcsr_cc_nord_clocks[] = {
284 	[TCSR_DP_RX_0_CLKREF_EN] = &tcsr_dp_rx_0_clkref_en.clkr,
285 	[TCSR_DP_RX_1_CLKREF_EN] = &tcsr_dp_rx_1_clkref_en.clkr,
286 	[TCSR_DP_TX_0_CLKREF_EN] = &tcsr_dp_tx_0_clkref_en.clkr,
287 	[TCSR_DP_TX_1_CLKREF_EN] = &tcsr_dp_tx_1_clkref_en.clkr,
288 	[TCSR_DP_TX_2_CLKREF_EN] = &tcsr_dp_tx_2_clkref_en.clkr,
289 	[TCSR_DP_TX_3_CLKREF_EN] = &tcsr_dp_tx_3_clkref_en.clkr,
290 	[TCSR_PCIE_CLKREF_EN] = &tcsr_pcie_clkref_en.clkr,
291 	[TCSR_UFS_CLKREF_EN] = &tcsr_ufs_clkref_en.clkr,
292 	[TCSR_USB2_0_CLKREF_EN] = &tcsr_usb2_0_clkref_en.clkr,
293 	[TCSR_USB2_1_CLKREF_EN] = &tcsr_usb2_1_clkref_en.clkr,
294 	[TCSR_USB2_2_CLKREF_EN] = &tcsr_usb2_2_clkref_en.clkr,
295 	[TCSR_USB3_0_CLKREF_EN] = &tcsr_usb3_0_clkref_en.clkr,
296 	[TCSR_USB3_1_CLKREF_EN] = &tcsr_usb3_1_clkref_en.clkr,
297 	[TCSR_UX_SGMII_0_CLKREF_EN] = &tcsr_ux_sgmii_0_clkref_en.clkr,
298 	[TCSR_UX_SGMII_1_CLKREF_EN] = &tcsr_ux_sgmii_1_clkref_en.clkr,
299 };
300 
301 static const struct regmap_config tcsr_cc_nord_regmap_config = {
302 	.reg_bits = 32,
303 	.reg_stride = 4,
304 	.val_bits = 32,
305 	.max_register = 0xf008,
306 	.fast_io = true,
307 };
308 
309 static const struct qcom_cc_desc tcsr_cc_nord_desc = {
310 	.config = &tcsr_cc_nord_regmap_config,
311 	.clks = tcsr_cc_nord_clocks,
312 	.num_clks = ARRAY_SIZE(tcsr_cc_nord_clocks),
313 };
314 
315 static const struct of_device_id tcsr_cc_nord_match_table[] = {
316 	{ .compatible = "qcom,nord-tcsrcc" },
317 	{ }
318 };
319 MODULE_DEVICE_TABLE(of, tcsr_cc_nord_match_table);
320 
321 static int tcsr_cc_nord_probe(struct platform_device *pdev)
322 {
323 	return qcom_cc_probe(pdev, &tcsr_cc_nord_desc);
324 }
325 
326 static struct platform_driver tcsr_cc_nord_driver = {
327 	.probe = tcsr_cc_nord_probe,
328 	.driver = {
329 		.name = "tcsrcc-nord",
330 		.of_match_table = tcsr_cc_nord_match_table,
331 	},
332 };
333 
334 module_platform_driver(tcsr_cc_nord_driver);
335 
336 MODULE_DESCRIPTION("QTI TCSRCC NORD Driver");
337 MODULE_LICENSE("GPL");
338