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