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"); 286