1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 /* 3 * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. 4 */ 5 6 #include <linux/clk-provider.h> 7 #include <linux/module.h> 8 #include <linux/of.h> 9 #include <linux/platform_device.h> 10 #include <linux/regmap.h> 11 12 #include <dt-bindings/clock/qcom,sm8750-tcsr.h> 13 14 #include "clk-branch.h" 15 #include "clk-regmap.h" 16 #include "clk-regmap-divider.h" 17 #include "clk-regmap-mux.h" 18 #include "common.h" 19 20 enum { 21 DT_BI_TCXO_PAD, 22 }; 23 24 static struct clk_branch tcsr_pcie_0_clkref_en = { 25 .halt_reg = 0x0, 26 .halt_check = BRANCH_HALT_DELAY, 27 .clkr = { 28 .enable_reg = 0x0, 29 .enable_mask = BIT(0), 30 .hw.init = &(const struct clk_init_data) { 31 .name = "tcsr_pcie_0_clkref_en", 32 .ops = &clk_branch2_ops, 33 }, 34 }, 35 }; 36 37 static struct clk_branch tcsr_ufs_clkref_en = { 38 .halt_reg = 0x1000, 39 .halt_check = BRANCH_HALT_DELAY, 40 .clkr = { 41 .enable_reg = 0x1000, 42 .enable_mask = BIT(0), 43 .hw.init = &(const struct clk_init_data) { 44 .name = "tcsr_ufs_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_usb2_clkref_en = { 55 .halt_reg = 0x2000, 56 .halt_check = BRANCH_HALT_DELAY, 57 .clkr = { 58 .enable_reg = 0x2000, 59 .enable_mask = BIT(0), 60 .hw.init = &(const struct clk_init_data) { 61 .name = "tcsr_usb2_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_usb3_clkref_en = { 72 .halt_reg = 0x3000, 73 .halt_check = BRANCH_HALT_DELAY, 74 .clkr = { 75 .enable_reg = 0x3000, 76 .enable_mask = BIT(0), 77 .hw.init = &(const struct clk_init_data) { 78 .name = "tcsr_usb3_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_regmap *tcsr_cc_sm8750_clocks[] = { 89 [TCSR_PCIE_0_CLKREF_EN] = &tcsr_pcie_0_clkref_en.clkr, 90 [TCSR_UFS_CLKREF_EN] = &tcsr_ufs_clkref_en.clkr, 91 [TCSR_USB2_CLKREF_EN] = &tcsr_usb2_clkref_en.clkr, 92 [TCSR_USB3_CLKREF_EN] = &tcsr_usb3_clkref_en.clkr, 93 }; 94 95 static const struct regmap_config tcsr_cc_sm8750_regmap_config = { 96 .reg_bits = 32, 97 .reg_stride = 4, 98 .val_bits = 32, 99 .max_register = 0x3000, 100 .fast_io = true, 101 }; 102 103 static const struct qcom_cc_desc tcsr_cc_sm8750_desc = { 104 .config = &tcsr_cc_sm8750_regmap_config, 105 .clks = tcsr_cc_sm8750_clocks, 106 .num_clks = ARRAY_SIZE(tcsr_cc_sm8750_clocks), 107 }; 108 109 static const struct of_device_id tcsr_cc_sm8750_match_table[] = { 110 { .compatible = "qcom,sm8750-tcsr" }, 111 { } 112 }; 113 MODULE_DEVICE_TABLE(of, tcsr_cc_sm8750_match_table); 114 115 static int tcsr_cc_sm8750_probe(struct platform_device *pdev) 116 { 117 return qcom_cc_probe(pdev, &tcsr_cc_sm8750_desc); 118 } 119 120 static struct platform_driver tcsr_cc_sm8750_driver = { 121 .probe = tcsr_cc_sm8750_probe, 122 .driver = { 123 .name = "tcsr_cc-sm8750", 124 .of_match_table = tcsr_cc_sm8750_match_table, 125 }, 126 }; 127 128 static int __init tcsr_cc_sm8750_init(void) 129 { 130 return platform_driver_register(&tcsr_cc_sm8750_driver); 131 } 132 subsys_initcall(tcsr_cc_sm8750_init); 133 134 static void __exit tcsr_cc_sm8750_exit(void) 135 { 136 platform_driver_unregister(&tcsr_cc_sm8750_driver); 137 } 138 module_exit(tcsr_cc_sm8750_exit); 139 140 MODULE_DESCRIPTION("QTI TCSR_CC SM8750 Driver"); 141 MODULE_LICENSE("GPL"); 142