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