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,eliza-tcsr.h> 13 14 #include "clk-branch.h" 15 #include "clk-regmap.h" 16 #include "common.h" 17 18 enum { 19 DT_BI_TCXO_PAD, 20 }; 21 22 static struct clk_branch tcsr_hdmi_clkref_en = { 23 .halt_reg = 0x14, 24 .halt_check = BRANCH_HALT_DELAY, 25 .clkr = { 26 .enable_reg = 0x14, 27 .enable_mask = BIT(0), 28 .hw.init = &(const struct clk_init_data) { 29 .name = "tcsr_hdmi_clkref_en", 30 .parent_data = &(const struct clk_parent_data){ 31 .index = DT_BI_TCXO_PAD, 32 }, 33 .num_parents = 1, 34 .ops = &clk_branch2_ops, 35 }, 36 }, 37 }; 38 39 static struct clk_branch tcsr_pcie_0_clkref_en = { 40 .halt_reg = 0x0, 41 .halt_check = BRANCH_HALT_DELAY, 42 .clkr = { 43 .enable_reg = 0x0, 44 .enable_mask = BIT(0), 45 .hw.init = &(const struct clk_init_data) { 46 .name = "tcsr_pcie_0_clkref_en", 47 .parent_data = &(const struct clk_parent_data){ 48 .index = DT_BI_TCXO_PAD, 49 }, 50 .num_parents = 1, 51 .ops = &clk_branch2_ops, 52 }, 53 }, 54 }; 55 56 static struct clk_branch tcsr_pcie_1_clkref_en = { 57 .halt_reg = 0x1c, 58 .halt_check = BRANCH_HALT_DELAY, 59 .clkr = { 60 .enable_reg = 0x1c, 61 .enable_mask = BIT(0), 62 .hw.init = &(const struct clk_init_data) { 63 .name = "tcsr_pcie_1_clkref_en", 64 .parent_data = &(const struct clk_parent_data){ 65 .index = DT_BI_TCXO_PAD, 66 }, 67 .num_parents = 1, 68 .ops = &clk_branch2_ops, 69 }, 70 }, 71 }; 72 73 static struct clk_branch tcsr_ufs_clkref_en = { 74 .halt_reg = 0x8, 75 .halt_check = BRANCH_HALT_DELAY, 76 .clkr = { 77 .enable_reg = 0x8, 78 .enable_mask = BIT(0), 79 .hw.init = &(const struct clk_init_data) { 80 .name = "tcsr_ufs_clkref_en", 81 .parent_data = &(const struct clk_parent_data){ 82 .index = DT_BI_TCXO_PAD, 83 }, 84 .num_parents = 1, 85 .ops = &clk_branch2_ops, 86 }, 87 }, 88 }; 89 90 static struct clk_branch tcsr_usb2_clkref_en = { 91 .halt_reg = 0x4, 92 .halt_check = BRANCH_HALT_DELAY, 93 .clkr = { 94 .enable_reg = 0x4, 95 .enable_mask = BIT(0), 96 .hw.init = &(const struct clk_init_data) { 97 .name = "tcsr_usb2_clkref_en", 98 .parent_data = &(const struct clk_parent_data){ 99 .index = DT_BI_TCXO_PAD, 100 }, 101 .num_parents = 1, 102 .ops = &clk_branch2_ops, 103 }, 104 }, 105 }; 106 107 static struct clk_branch tcsr_usb3_clkref_en = { 108 .halt_reg = 0x10, 109 .halt_check = BRANCH_HALT_DELAY, 110 .clkr = { 111 .enable_reg = 0x10, 112 .enable_mask = BIT(0), 113 .hw.init = &(const struct clk_init_data) { 114 .name = "tcsr_usb3_clkref_en", 115 .parent_data = &(const struct clk_parent_data){ 116 .index = DT_BI_TCXO_PAD, 117 }, 118 .num_parents = 1, 119 .ops = &clk_branch2_ops, 120 }, 121 }, 122 }; 123 124 static struct clk_regmap *tcsr_cc_eliza_clocks[] = { 125 [TCSR_HDMI_CLKREF_EN] = &tcsr_hdmi_clkref_en.clkr, 126 [TCSR_PCIE_0_CLKREF_EN] = &tcsr_pcie_0_clkref_en.clkr, 127 [TCSR_PCIE_1_CLKREF_EN] = &tcsr_pcie_1_clkref_en.clkr, 128 [TCSR_UFS_CLKREF_EN] = &tcsr_ufs_clkref_en.clkr, 129 [TCSR_USB2_CLKREF_EN] = &tcsr_usb2_clkref_en.clkr, 130 [TCSR_USB3_CLKREF_EN] = &tcsr_usb3_clkref_en.clkr, 131 }; 132 133 static const struct regmap_config tcsr_cc_eliza_regmap_config = { 134 .reg_bits = 32, 135 .reg_stride = 4, 136 .val_bits = 32, 137 .max_register = 0x1c, 138 .fast_io = true, 139 }; 140 141 static const struct qcom_cc_desc tcsr_cc_eliza_desc = { 142 .config = &tcsr_cc_eliza_regmap_config, 143 .clks = tcsr_cc_eliza_clocks, 144 .num_clks = ARRAY_SIZE(tcsr_cc_eliza_clocks), 145 }; 146 147 static const struct of_device_id tcsr_cc_eliza_match_table[] = { 148 { .compatible = "qcom,eliza-tcsr" }, 149 { } 150 }; 151 MODULE_DEVICE_TABLE(of, tcsr_cc_eliza_match_table); 152 153 static int tcsr_cc_eliza_probe(struct platform_device *pdev) 154 { 155 return qcom_cc_probe(pdev, &tcsr_cc_eliza_desc); 156 } 157 158 static struct platform_driver tcsr_cc_eliza_driver = { 159 .probe = tcsr_cc_eliza_probe, 160 .driver = { 161 .name = "tcsr_cc-eliza", 162 .of_match_table = tcsr_cc_eliza_match_table, 163 }, 164 }; 165 166 static int __init tcsr_cc_eliza_init(void) 167 { 168 return platform_driver_register(&tcsr_cc_eliza_driver); 169 } 170 subsys_initcall(tcsr_cc_eliza_init); 171 172 static void __exit tcsr_cc_eliza_exit(void) 173 { 174 platform_driver_unregister(&tcsr_cc_eliza_driver); 175 } 176 module_exit(tcsr_cc_eliza_exit); 177 178 MODULE_DESCRIPTION("QTI TCSR_CC Eliza Driver"); 179 MODULE_LICENSE("GPL"); 180