xref: /linux/drivers/clk/qcom/tcsrcc-x1e80100.c (revision 522ba450b56fff29f868b1552bdc2965f55de7ed)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
4  * Copyright (c) 2023, Linaro Limited
5  */
6 
7 #include <linux/clk-provider.h>
8 #include <linux/mod_devicetable.h>
9 #include <linux/module.h>
10 #include <linux/platform_device.h>
11 #include <linux/regmap.h>
12 
13 #include <dt-bindings/clock/qcom,x1e80100-tcsr.h>
14 
15 #include "clk-branch.h"
16 #include "clk-regmap.h"
17 #include "common.h"
18 #include "reset.h"
19 
20 enum {
21 	DT_BI_TCXO_PAD,
22 };
23 
24 static struct clk_branch tcsr_edp_clkref_en = {
25 	.halt_reg = 0x15130,
26 	.halt_check = BRANCH_HALT_DELAY,
27 	.clkr = {
28 		.enable_reg = 0x15130,
29 		.enable_mask = BIT(0),
30 		.hw.init = &(const struct clk_init_data) {
31 			.name = "tcsr_edp_clkref_en",
32 			.parent_data = &(const struct clk_parent_data){
33 				.index = DT_BI_TCXO_PAD,
34 			},
35 			.num_parents = 1,
36 			.ops = &clk_branch2_ops,
37 		},
38 	},
39 };
40 
41 static struct clk_branch tcsr_pcie_2l_4_clkref_en = {
42 	.halt_reg = 0x15100,
43 	.halt_check = BRANCH_HALT_DELAY,
44 	.clkr = {
45 		.enable_reg = 0x15100,
46 		.enable_mask = BIT(0),
47 		.hw.init = &(struct clk_init_data){
48 			.name = "tcsr_pcie_2l_4_clkref_en",
49 			.parent_data = &(const struct clk_parent_data){
50 				.index = DT_BI_TCXO_PAD,
51 			},
52 			.num_parents = 1,
53 			.ops = &clk_branch2_ops,
54 		},
55 	},
56 };
57 
58 static struct clk_branch tcsr_pcie_2l_5_clkref_en = {
59 	.halt_reg = 0x15104,
60 	.halt_check = BRANCH_HALT_DELAY,
61 	.clkr = {
62 		.enable_reg = 0x15104,
63 		.enable_mask = BIT(0),
64 		.hw.init = &(struct clk_init_data){
65 			.name = "tcsr_pcie_2l_5_clkref_en",
66 			.parent_data = &(const struct clk_parent_data){
67 				.index = DT_BI_TCXO_PAD,
68 			},
69 			.num_parents = 1,
70 			.ops = &clk_branch2_ops,
71 		},
72 	},
73 };
74 
75 static struct clk_branch tcsr_pcie_8l_clkref_en = {
76 	.halt_reg = 0x15108,
77 	.halt_check = BRANCH_HALT_DELAY,
78 	.clkr = {
79 		.enable_reg = 0x15108,
80 		.enable_mask = BIT(0),
81 		.hw.init = &(struct clk_init_data){
82 			.name = "tcsr_pcie_8l_clkref_en",
83 			.parent_data = &(const struct clk_parent_data){
84 				.index = DT_BI_TCXO_PAD,
85 			},
86 			.num_parents = 1,
87 			.ops = &clk_branch2_ops,
88 		},
89 	},
90 };
91 
92 static struct clk_branch tcsr_usb3_mp0_clkref_en = {
93 	.halt_reg = 0x1510c,
94 	.halt_check = BRANCH_HALT_DELAY,
95 	.clkr = {
96 		.enable_reg = 0x1510c,
97 		.enable_mask = BIT(0),
98 		.hw.init = &(struct clk_init_data){
99 			.name = "tcsr_usb3_mp0_clkref_en",
100 			.parent_data = &(const struct clk_parent_data){
101 				.index = DT_BI_TCXO_PAD,
102 			},
103 			.num_parents = 1,
104 			.ops = &clk_branch2_ops,
105 		},
106 	},
107 };
108 
109 static struct clk_branch tcsr_usb3_mp1_clkref_en = {
110 	.halt_reg = 0x15110,
111 	.halt_check = BRANCH_HALT_DELAY,
112 	.clkr = {
113 		.enable_reg = 0x15110,
114 		.enable_mask = BIT(0),
115 		.hw.init = &(struct clk_init_data){
116 			.name = "tcsr_usb3_mp1_clkref_en",
117 			.parent_data = &(const struct clk_parent_data){
118 				.index = DT_BI_TCXO_PAD,
119 			},
120 			.num_parents = 1,
121 			.ops = &clk_branch2_ops,
122 		},
123 	},
124 };
125 
126 static struct clk_branch tcsr_usb2_1_clkref_en = {
127 	.halt_reg = 0x15114,
128 	.halt_check = BRANCH_HALT_DELAY,
129 	.clkr = {
130 		.enable_reg = 0x15114,
131 		.enable_mask = BIT(0),
132 		.hw.init = &(struct clk_init_data){
133 			.name = "tcsr_usb2_1_clkref_en",
134 			.parent_data = &(const struct clk_parent_data){
135 				.index = DT_BI_TCXO_PAD,
136 			},
137 			.num_parents = 1,
138 			.ops = &clk_branch2_ops,
139 		},
140 	},
141 };
142 
143 static struct clk_branch tcsr_ufs_phy_clkref_en = {
144 	.halt_reg = 0x15118,
145 	.halt_check = BRANCH_HALT_DELAY,
146 	.clkr = {
147 		.enable_reg = 0x15118,
148 		.enable_mask = BIT(0),
149 		.hw.init = &(struct clk_init_data){
150 			.name = "tcsr_ufs_phy_clkref_en",
151 			.parent_data = &(const struct clk_parent_data){
152 				.index = DT_BI_TCXO_PAD,
153 			},
154 			.num_parents = 1,
155 			.ops = &clk_branch2_ops,
156 		},
157 	},
158 };
159 
160 static struct clk_branch tcsr_usb4_1_clkref_en = {
161 	.halt_reg = 0x15120,
162 	.halt_check = BRANCH_HALT_DELAY,
163 	.clkr = {
164 		.enable_reg = 0x15120,
165 		.enable_mask = BIT(0),
166 		.hw.init = &(struct clk_init_data){
167 			.name = "tcsr_usb4_1_clkref_en",
168 			.parent_data = &(const struct clk_parent_data){
169 				.index = DT_BI_TCXO_PAD,
170 			},
171 			.num_parents = 1,
172 			.ops = &clk_branch2_ops,
173 		},
174 	},
175 };
176 
177 static struct clk_branch tcsr_usb4_2_clkref_en = {
178 	.halt_reg = 0x15124,
179 	.halt_check = BRANCH_HALT_DELAY,
180 	.clkr = {
181 		.enable_reg = 0x15124,
182 		.enable_mask = BIT(0),
183 		.hw.init = &(struct clk_init_data){
184 			.name = "tcsr_usb4_2_clkref_en",
185 			.parent_data = &(const struct clk_parent_data){
186 				.index = DT_BI_TCXO_PAD,
187 			},
188 			.num_parents = 1,
189 			.ops = &clk_branch2_ops,
190 		},
191 	},
192 };
193 
194 static struct clk_branch tcsr_usb2_2_clkref_en = {
195 	.halt_reg = 0x15128,
196 	.halt_check = BRANCH_HALT_DELAY,
197 	.clkr = {
198 		.enable_reg = 0x15128,
199 		.enable_mask = BIT(0),
200 		.hw.init = &(struct clk_init_data){
201 			.name = "tcsr_usb2_2_clkref_en",
202 			.parent_data = &(const struct clk_parent_data){
203 				.index = DT_BI_TCXO_PAD,
204 			},
205 			.num_parents = 1,
206 			.ops = &clk_branch2_ops,
207 		},
208 	},
209 };
210 
211 static struct clk_branch tcsr_pcie_4l_clkref_en = {
212 	.halt_reg = 0x1512c,
213 	.halt_check = BRANCH_HALT_DELAY,
214 	.clkr = {
215 		.enable_reg = 0x1512c,
216 		.enable_mask = BIT(0),
217 		.hw.init = &(struct clk_init_data){
218 			.name = "tcsr_pcie_4l_clkref_en",
219 			.parent_data = &(const struct clk_parent_data){
220 				.index = DT_BI_TCXO_PAD,
221 			},
222 			.num_parents = 1,
223 			.ops = &clk_branch2_ops,
224 		},
225 	},
226 };
227 
228 static struct clk_regmap *tcsr_cc_x1e80100_clocks[] = {
229 	[TCSR_EDP_CLKREF_EN] = &tcsr_edp_clkref_en.clkr,
230 	[TCSR_PCIE_2L_4_CLKREF_EN] = &tcsr_pcie_2l_4_clkref_en.clkr,
231 	[TCSR_PCIE_2L_5_CLKREF_EN] = &tcsr_pcie_2l_5_clkref_en.clkr,
232 	[TCSR_PCIE_8L_CLKREF_EN] = &tcsr_pcie_8l_clkref_en.clkr,
233 	[TCSR_USB3_MP0_CLKREF_EN] = &tcsr_usb3_mp0_clkref_en.clkr,
234 	[TCSR_USB3_MP1_CLKREF_EN] = &tcsr_usb3_mp1_clkref_en.clkr,
235 	[TCSR_USB2_1_CLKREF_EN] = &tcsr_usb2_1_clkref_en.clkr,
236 	[TCSR_UFS_PHY_CLKREF_EN] = &tcsr_ufs_phy_clkref_en.clkr,
237 	[TCSR_USB4_1_CLKREF_EN] = &tcsr_usb4_1_clkref_en.clkr,
238 	[TCSR_USB4_2_CLKREF_EN] = &tcsr_usb4_2_clkref_en.clkr,
239 	[TCSR_USB2_2_CLKREF_EN] = &tcsr_usb2_2_clkref_en.clkr,
240 	[TCSR_PCIE_4L_CLKREF_EN] = &tcsr_pcie_4l_clkref_en.clkr,
241 };
242 
243 static const struct regmap_config tcsr_cc_x1e80100_regmap_config = {
244 	.reg_bits = 32,
245 	.reg_stride = 4,
246 	.val_bits = 32,
247 	.max_register = 0x2f000,
248 	.fast_io = true,
249 };
250 
251 static const struct qcom_cc_desc tcsr_cc_x1e80100_desc = {
252 	.config = &tcsr_cc_x1e80100_regmap_config,
253 	.clks = tcsr_cc_x1e80100_clocks,
254 	.num_clks = ARRAY_SIZE(tcsr_cc_x1e80100_clocks),
255 };
256 
257 static const struct of_device_id tcsr_cc_x1e80100_match_table[] = {
258 	{ .compatible = "qcom,x1e80100-tcsr" },
259 	{ }
260 };
261 MODULE_DEVICE_TABLE(of, tcsr_cc_x1e80100_match_table);
262 
tcsr_cc_x1e80100_probe(struct platform_device * pdev)263 static int tcsr_cc_x1e80100_probe(struct platform_device *pdev)
264 {
265 	return qcom_cc_probe(pdev, &tcsr_cc_x1e80100_desc);
266 }
267 
268 static struct platform_driver tcsr_cc_x1e80100_driver = {
269 	.probe = tcsr_cc_x1e80100_probe,
270 	.driver = {
271 		.name = "tcsrcc-x1e80100",
272 		.of_match_table = tcsr_cc_x1e80100_match_table,
273 	},
274 };
275 
tcsr_cc_x1e80100_init(void)276 static int __init tcsr_cc_x1e80100_init(void)
277 {
278 	return platform_driver_register(&tcsr_cc_x1e80100_driver);
279 }
280 subsys_initcall(tcsr_cc_x1e80100_init);
281 
tcsr_cc_x1e80100_exit(void)282 static void __exit tcsr_cc_x1e80100_exit(void)
283 {
284 	platform_driver_unregister(&tcsr_cc_x1e80100_driver);
285 }
286 module_exit(tcsr_cc_x1e80100_exit);
287 
288 MODULE_DESCRIPTION("QTI TCSR Clock Controller X1E80100 Driver");
289 MODULE_LICENSE("GPL");
290