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