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

clk: qcom: Add TCSR clock driver for x1e80100

The TCSR clock controller found on X1E80100 provides refclks
for PCIE, USB and UFS. Add clock driver for it.

Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
Link: https://lore.kernel.org/r/20240202-x1e80100-clock-controllers-v4-9-7fb08c861c7c@linaro.org
Signed-off-by: Bjorn Andersson <andersson@kernel.org>

authored by

Abel Vesa and committed by
Bjorn Andersson
06aff116 acddef6e

+294
+8
drivers/clk/qcom/Kconfig
··· 49 49 Say Y if you want to support graphics controller devices and 50 50 functionality such as 3D graphics. 51 51 52 + config CLK_X1E80100_TCSRCC 53 + tristate "X1E80100 TCSR Clock Controller" 54 + depends on ARM64 || COMPILE_TEST 55 + select QCOM_GDSC 56 + help 57 + Support for the TCSR clock controller on X1E80100 devices. 58 + Say Y if you want to use peripheral devices such as SD/UFS. 59 + 52 60 config QCOM_A53PLL 53 61 tristate "MSM8916 A53 PLL" 54 62 help
+1
drivers/clk/qcom/Makefile
··· 24 24 obj-$(CONFIG_CLK_X1E80100_DISPCC) += dispcc-x1e80100.o 25 25 obj-$(CONFIG_CLK_X1E80100_GCC) += gcc-x1e80100.o 26 26 obj-$(CONFIG_CLK_X1E80100_GPUCC) += gpucc-x1e80100.o 27 + obj-$(CONFIG_CLK_X1E80100_TCSRCC) += tcsrcc-x1e80100.o 27 28 obj-$(CONFIG_IPQ_APSS_PLL) += apss-ipq-pll.o 28 29 obj-$(CONFIG_IPQ_APSS_6018) += apss-ipq6018.o 29 30 obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o
+285
drivers/clk/qcom/tcsrcc-x1e80100.c
··· 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 + .ops = &clk_branch2_ops, 33 + }, 34 + }, 35 + }; 36 + 37 + static struct clk_branch tcsr_pcie_2l_4_clkref_en = { 38 + .halt_reg = 0x15100, 39 + .halt_check = BRANCH_HALT_DELAY, 40 + .clkr = { 41 + .enable_reg = 0x15100, 42 + .enable_mask = BIT(0), 43 + .hw.init = &(struct clk_init_data){ 44 + .name = "tcsr_pcie_2l_4_clkref_en", 45 + .parent_data = &(const struct clk_parent_data){ 46 + .index = DT_BI_TCXO_PAD, 47 + }, 48 + .num_parents = 1, 49 + .ops = &clk_branch2_ops, 50 + }, 51 + }, 52 + }; 53 + 54 + static struct clk_branch tcsr_pcie_2l_5_clkref_en = { 55 + .halt_reg = 0x15104, 56 + .halt_check = BRANCH_HALT_DELAY, 57 + .clkr = { 58 + .enable_reg = 0x15104, 59 + .enable_mask = BIT(0), 60 + .hw.init = &(struct clk_init_data){ 61 + .name = "tcsr_pcie_2l_5_clkref_en", 62 + .parent_data = &(const struct clk_parent_data){ 63 + .index = DT_BI_TCXO_PAD, 64 + }, 65 + .num_parents = 1, 66 + .ops = &clk_branch2_ops, 67 + }, 68 + }, 69 + }; 70 + 71 + static struct clk_branch tcsr_pcie_8l_clkref_en = { 72 + .halt_reg = 0x15108, 73 + .halt_check = BRANCH_HALT_DELAY, 74 + .clkr = { 75 + .enable_reg = 0x15108, 76 + .enable_mask = BIT(0), 77 + .hw.init = &(struct clk_init_data){ 78 + .name = "tcsr_pcie_8l_clkref_en", 79 + .parent_data = &(const struct clk_parent_data){ 80 + .index = DT_BI_TCXO_PAD, 81 + }, 82 + .num_parents = 1, 83 + .ops = &clk_branch2_ops, 84 + }, 85 + }, 86 + }; 87 + 88 + static struct clk_branch tcsr_usb3_mp0_clkref_en = { 89 + .halt_reg = 0x1510c, 90 + .halt_check = BRANCH_HALT_DELAY, 91 + .clkr = { 92 + .enable_reg = 0x1510c, 93 + .enable_mask = BIT(0), 94 + .hw.init = &(struct clk_init_data){ 95 + .name = "tcsr_usb3_mp0_clkref_en", 96 + .parent_data = &(const struct clk_parent_data){ 97 + .index = DT_BI_TCXO_PAD, 98 + }, 99 + .num_parents = 1, 100 + .ops = &clk_branch2_ops, 101 + }, 102 + }, 103 + }; 104 + 105 + static struct clk_branch tcsr_usb3_mp1_clkref_en = { 106 + .halt_reg = 0x15110, 107 + .halt_check = BRANCH_HALT_DELAY, 108 + .clkr = { 109 + .enable_reg = 0x15110, 110 + .enable_mask = BIT(0), 111 + .hw.init = &(struct clk_init_data){ 112 + .name = "tcsr_usb3_mp1_clkref_en", 113 + .parent_data = &(const struct clk_parent_data){ 114 + .index = DT_BI_TCXO_PAD, 115 + }, 116 + .num_parents = 1, 117 + .ops = &clk_branch2_ops, 118 + }, 119 + }, 120 + }; 121 + 122 + static struct clk_branch tcsr_usb2_1_clkref_en = { 123 + .halt_reg = 0x15114, 124 + .halt_check = BRANCH_HALT_DELAY, 125 + .clkr = { 126 + .enable_reg = 0x15114, 127 + .enable_mask = BIT(0), 128 + .hw.init = &(struct clk_init_data){ 129 + .name = "tcsr_usb2_1_clkref_en", 130 + .parent_data = &(const struct clk_parent_data){ 131 + .index = DT_BI_TCXO_PAD, 132 + }, 133 + .num_parents = 1, 134 + .ops = &clk_branch2_ops, 135 + }, 136 + }, 137 + }; 138 + 139 + static struct clk_branch tcsr_ufs_phy_clkref_en = { 140 + .halt_reg = 0x15118, 141 + .halt_check = BRANCH_HALT_DELAY, 142 + .clkr = { 143 + .enable_reg = 0x15118, 144 + .enable_mask = BIT(0), 145 + .hw.init = &(struct clk_init_data){ 146 + .name = "tcsr_ufs_phy_clkref_en", 147 + .parent_data = &(const struct clk_parent_data){ 148 + .index = DT_BI_TCXO_PAD, 149 + }, 150 + .num_parents = 1, 151 + .ops = &clk_branch2_ops, 152 + }, 153 + }, 154 + }; 155 + 156 + static struct clk_branch tcsr_usb4_1_clkref_en = { 157 + .halt_reg = 0x15120, 158 + .halt_check = BRANCH_HALT_DELAY, 159 + .clkr = { 160 + .enable_reg = 0x15120, 161 + .enable_mask = BIT(0), 162 + .hw.init = &(struct clk_init_data){ 163 + .name = "tcsr_usb4_1_clkref_en", 164 + .parent_data = &(const struct clk_parent_data){ 165 + .index = DT_BI_TCXO_PAD, 166 + }, 167 + .num_parents = 1, 168 + .ops = &clk_branch2_ops, 169 + }, 170 + }, 171 + }; 172 + 173 + static struct clk_branch tcsr_usb4_2_clkref_en = { 174 + .halt_reg = 0x15124, 175 + .halt_check = BRANCH_HALT_DELAY, 176 + .clkr = { 177 + .enable_reg = 0x15124, 178 + .enable_mask = BIT(0), 179 + .hw.init = &(struct clk_init_data){ 180 + .name = "tcsr_usb4_2_clkref_en", 181 + .parent_data = &(const struct clk_parent_data){ 182 + .index = DT_BI_TCXO_PAD, 183 + }, 184 + .num_parents = 1, 185 + .ops = &clk_branch2_ops, 186 + }, 187 + }, 188 + }; 189 + 190 + static struct clk_branch tcsr_usb2_2_clkref_en = { 191 + .halt_reg = 0x15128, 192 + .halt_check = BRANCH_HALT_DELAY, 193 + .clkr = { 194 + .enable_reg = 0x15128, 195 + .enable_mask = BIT(0), 196 + .hw.init = &(struct clk_init_data){ 197 + .name = "tcsr_usb2_2_clkref_en", 198 + .parent_data = &(const struct clk_parent_data){ 199 + .index = DT_BI_TCXO_PAD, 200 + }, 201 + .num_parents = 1, 202 + .ops = &clk_branch2_ops, 203 + }, 204 + }, 205 + }; 206 + 207 + static struct clk_branch tcsr_pcie_4l_clkref_en = { 208 + .halt_reg = 0x1512c, 209 + .halt_check = BRANCH_HALT_DELAY, 210 + .clkr = { 211 + .enable_reg = 0x1512c, 212 + .enable_mask = BIT(0), 213 + .hw.init = &(struct clk_init_data){ 214 + .name = "tcsr_pcie_4l_clkref_en", 215 + .parent_data = &(const struct clk_parent_data){ 216 + .index = DT_BI_TCXO_PAD, 217 + }, 218 + .num_parents = 1, 219 + .ops = &clk_branch2_ops, 220 + }, 221 + }, 222 + }; 223 + 224 + static struct clk_regmap *tcsr_cc_x1e80100_clocks[] = { 225 + [TCSR_EDP_CLKREF_EN] = &tcsr_edp_clkref_en.clkr, 226 + [TCSR_PCIE_2L_4_CLKREF_EN] = &tcsr_pcie_2l_4_clkref_en.clkr, 227 + [TCSR_PCIE_2L_5_CLKREF_EN] = &tcsr_pcie_2l_5_clkref_en.clkr, 228 + [TCSR_PCIE_8L_CLKREF_EN] = &tcsr_pcie_8l_clkref_en.clkr, 229 + [TCSR_USB3_MP0_CLKREF_EN] = &tcsr_usb3_mp0_clkref_en.clkr, 230 + [TCSR_USB3_MP1_CLKREF_EN] = &tcsr_usb3_mp1_clkref_en.clkr, 231 + [TCSR_USB2_1_CLKREF_EN] = &tcsr_usb2_1_clkref_en.clkr, 232 + [TCSR_UFS_PHY_CLKREF_EN] = &tcsr_ufs_phy_clkref_en.clkr, 233 + [TCSR_USB4_1_CLKREF_EN] = &tcsr_usb4_1_clkref_en.clkr, 234 + [TCSR_USB4_2_CLKREF_EN] = &tcsr_usb4_2_clkref_en.clkr, 235 + [TCSR_USB2_2_CLKREF_EN] = &tcsr_usb2_2_clkref_en.clkr, 236 + [TCSR_PCIE_4L_CLKREF_EN] = &tcsr_pcie_4l_clkref_en.clkr, 237 + }; 238 + 239 + static const struct regmap_config tcsr_cc_x1e80100_regmap_config = { 240 + .reg_bits = 32, 241 + .reg_stride = 4, 242 + .val_bits = 32, 243 + .max_register = 0x2f000, 244 + .fast_io = true, 245 + }; 246 + 247 + static const struct qcom_cc_desc tcsr_cc_x1e80100_desc = { 248 + .config = &tcsr_cc_x1e80100_regmap_config, 249 + .clks = tcsr_cc_x1e80100_clocks, 250 + .num_clks = ARRAY_SIZE(tcsr_cc_x1e80100_clocks), 251 + }; 252 + 253 + static const struct of_device_id tcsr_cc_x1e80100_match_table[] = { 254 + { .compatible = "qcom,x1e80100-tcsr" }, 255 + { } 256 + }; 257 + MODULE_DEVICE_TABLE(of, tcsr_cc_x1e80100_match_table); 258 + 259 + static int tcsr_cc_x1e80100_probe(struct platform_device *pdev) 260 + { 261 + return qcom_cc_probe(pdev, &tcsr_cc_x1e80100_desc); 262 + } 263 + 264 + static struct platform_driver tcsr_cc_x1e80100_driver = { 265 + .probe = tcsr_cc_x1e80100_probe, 266 + .driver = { 267 + .name = "tcsrcc-x1e80100", 268 + .of_match_table = tcsr_cc_x1e80100_match_table, 269 + }, 270 + }; 271 + 272 + static int __init tcsr_cc_x1e80100_init(void) 273 + { 274 + return platform_driver_register(&tcsr_cc_x1e80100_driver); 275 + } 276 + subsys_initcall(tcsr_cc_x1e80100_init); 277 + 278 + static void __exit tcsr_cc_x1e80100_exit(void) 279 + { 280 + platform_driver_unregister(&tcsr_cc_x1e80100_driver); 281 + } 282 + module_exit(tcsr_cc_x1e80100_exit); 283 + 284 + MODULE_DESCRIPTION("QTI TCSR Clock Controller X1E80100 Driver"); 285 + MODULE_LICENSE("GPL");