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