Skip to content

Commit 9d13c7b

Browse files
taniyadas20andersson
authored andcommitted
clk: qcom: Add TCSR clock driver for Nord SoC
Add a clock driver for the TCSR clock controller found on Nord SoC, which provides refclks for PCIE, USB, SGMII, UFS subsystems. [Shawn: - Use compatible qcom,nord-tcsrcc - Drop include of <linux/of.h> as the driver doesn't use any OF APIs] Signed-off-by: Taniya Das <[email protected]> Co-developed-by: Shawn Guo <[email protected]> Signed-off-by: Shawn Guo <[email protected]> Signed-off-by: Bartosz Golaszewski <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Bjorn Andersson <[email protected]>
1 parent 06498d5 commit 9d13c7b

3 files changed

Lines changed: 345 additions & 0 deletions

File tree

drivers/clk/qcom/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,13 @@ config QCS_GCC_404
674674
Say Y if you want to use multimedia devices or peripheral
675675
devices such as UART, SPI, I2C, USB, SD/eMMC, PCIe etc.
676676

677+
config CLK_NORD_TCSRCC
678+
tristate "Nord TCSR Clock Controller"
679+
depends on ARM64 || COMPILE_TEST
680+
help
681+
Support for the TCSR clock controller on Nord devices.
682+
Say Y if you want to use peripheral devices such as PCIe, USB, UFS etc.
683+
677684
config SA_CAMCC_8775P
678685
tristate "SA8775P Camera Clock Controller"
679686
depends on ARM64 || COMPILE_TEST

drivers/clk/qcom/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ obj-$(CONFIG_CLK_KAANAPALI_GCC) += gcc-kaanapali.o
3535
obj-$(CONFIG_CLK_KAANAPALI_GPUCC) += gpucc-kaanapali.o gxclkctl-kaanapali.o
3636
obj-$(CONFIG_CLK_KAANAPALI_TCSRCC) += tcsrcc-kaanapali.o
3737
obj-$(CONFIG_CLK_KAANAPALI_VIDEOCC) += videocc-kaanapali.o
38+
obj-$(CONFIG_CLK_NORD_TCSRCC) += tcsrcc-nord.o
3839
obj-$(CONFIG_CLK_X1E80100_CAMCC) += camcc-x1e80100.o
3940
obj-$(CONFIG_CLK_X1E80100_DISPCC) += dispcc-x1e80100.o
4041
obj-$(CONFIG_CLK_X1E80100_GCC) += gcc-x1e80100.o

drivers/clk/qcom/tcsrcc-nord.c

Lines changed: 337 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,337 @@
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");

0 commit comments

Comments
 (0)