Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <taniya.das@oss.qualcomm.com>
Co-developed-by: Shawn Guo <shengchao.guo@oss.qualcomm.com>
Signed-off-by: Shawn Guo <shengchao.guo@oss.qualcomm.com>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20260403-nord-clks-v1-4-018af14979fd@oss.qualcomm.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>

authored by

Taniya Das and committed by
Bjorn Andersson
9d13c7bb 06498d59

+345
+7
drivers/clk/qcom/Kconfig
··· 674 674 Say Y if you want to use multimedia devices or peripheral 675 675 devices such as UART, SPI, I2C, USB, SD/eMMC, PCIe etc. 676 676 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 + 677 684 config SA_CAMCC_8775P 678 685 tristate "SA8775P Camera Clock Controller" 679 686 depends on ARM64 || COMPILE_TEST
+1
drivers/clk/qcom/Makefile
··· 35 35 obj-$(CONFIG_CLK_KAANAPALI_GPUCC) += gpucc-kaanapali.o gxclkctl-kaanapali.o 36 36 obj-$(CONFIG_CLK_KAANAPALI_TCSRCC) += tcsrcc-kaanapali.o 37 37 obj-$(CONFIG_CLK_KAANAPALI_VIDEOCC) += videocc-kaanapali.o 38 + obj-$(CONFIG_CLK_NORD_TCSRCC) += tcsrcc-nord.o 38 39 obj-$(CONFIG_CLK_X1E80100_CAMCC) += camcc-x1e80100.o 39 40 obj-$(CONFIG_CLK_X1E80100_DISPCC) += dispcc-x1e80100.o 40 41 obj-$(CONFIG_CLK_X1E80100_GCC) += gcc-x1e80100.o
+337
drivers/clk/qcom/tcsrcc-nord.c
··· 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");