1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2018, The Linux Foundation. All rights reserved. 4 */ 5 6 #include <linux/clk-provider.h> 7 #include <linux/platform_device.h> 8 #include <linux/module.h> 9 #include <linux/of_address.h> 10 #include <linux/regmap.h> 11 12 #include <dt-bindings/clock/qcom,lpass-sdm845.h> 13 14 #include "clk-regmap.h" 15 #include "clk-branch.h" 16 #include "common.h" 17 18 static struct clk_branch lpass_q6ss_ahbm_aon_clk = { 19 .halt_reg = 0x12000, 20 .halt_check = BRANCH_VOTED, 21 .clkr = { 22 .enable_reg = 0x12000, 23 .enable_mask = BIT(0), 24 .hw.init = &(struct clk_init_data){ 25 .name = "lpass_q6ss_ahbm_aon_clk", 26 .ops = &clk_branch2_ops, 27 }, 28 }, 29 }; 30 31 static struct clk_branch lpass_q6ss_ahbs_aon_clk = { 32 .halt_reg = 0x1f000, 33 .halt_check = BRANCH_VOTED, 34 .clkr = { 35 .enable_reg = 0x1f000, 36 .enable_mask = BIT(0), 37 .hw.init = &(struct clk_init_data){ 38 .name = "lpass_q6ss_ahbs_aon_clk", 39 .ops = &clk_branch2_ops, 40 }, 41 }, 42 }; 43 44 static struct clk_branch lpass_qdsp6ss_core_clk = { 45 .halt_reg = 0x20, 46 /* CLK_OFF would not toggle until LPASS is out of reset */ 47 .halt_check = BRANCH_HALT_SKIP, 48 .clkr = { 49 .enable_reg = 0x20, 50 .enable_mask = BIT(0), 51 .hw.init = &(struct clk_init_data){ 52 .name = "lpass_qdsp6ss_core_clk", 53 .ops = &clk_branch2_ops, 54 }, 55 }, 56 }; 57 58 static struct clk_branch lpass_qdsp6ss_xo_clk = { 59 .halt_reg = 0x38, 60 /* CLK_OFF would not toggle until LPASS is out of reset */ 61 .halt_check = BRANCH_HALT_SKIP, 62 .clkr = { 63 .enable_reg = 0x38, 64 .enable_mask = BIT(0), 65 .hw.init = &(struct clk_init_data){ 66 .name = "lpass_qdsp6ss_xo_clk", 67 .ops = &clk_branch2_ops, 68 }, 69 }, 70 }; 71 72 static struct clk_branch lpass_qdsp6ss_sleep_clk = { 73 .halt_reg = 0x3c, 74 /* CLK_OFF would not toggle until LPASS is out of reset */ 75 .halt_check = BRANCH_HALT_SKIP, 76 .clkr = { 77 .enable_reg = 0x3c, 78 .enable_mask = BIT(0), 79 .hw.init = &(struct clk_init_data){ 80 .name = "lpass_qdsp6ss_sleep_clk", 81 .ops = &clk_branch2_ops, 82 }, 83 }, 84 }; 85 86 static struct regmap_config lpass_regmap_config = { 87 .reg_bits = 32, 88 .reg_stride = 4, 89 .val_bits = 32, 90 .fast_io = true, 91 }; 92 93 static struct clk_regmap *lpass_cc_sdm845_clocks[] = { 94 [LPASS_Q6SS_AHBM_AON_CLK] = &lpass_q6ss_ahbm_aon_clk.clkr, 95 [LPASS_Q6SS_AHBS_AON_CLK] = &lpass_q6ss_ahbs_aon_clk.clkr, 96 }; 97 98 static const struct qcom_cc_desc lpass_cc_sdm845_desc = { 99 .config = &lpass_regmap_config, 100 .clks = lpass_cc_sdm845_clocks, 101 .num_clks = ARRAY_SIZE(lpass_cc_sdm845_clocks), 102 }; 103 104 static struct clk_regmap *lpass_qdsp6ss_sdm845_clocks[] = { 105 [LPASS_QDSP6SS_XO_CLK] = &lpass_qdsp6ss_xo_clk.clkr, 106 [LPASS_QDSP6SS_SLEEP_CLK] = &lpass_qdsp6ss_sleep_clk.clkr, 107 [LPASS_QDSP6SS_CORE_CLK] = &lpass_qdsp6ss_core_clk.clkr, 108 }; 109 110 static const struct qcom_cc_desc lpass_qdsp6ss_sdm845_desc = { 111 .config = &lpass_regmap_config, 112 .clks = lpass_qdsp6ss_sdm845_clocks, 113 .num_clks = ARRAY_SIZE(lpass_qdsp6ss_sdm845_clocks), 114 }; 115 116 static int lpass_cc_sdm845_probe(struct platform_device *pdev) 117 { 118 const struct qcom_cc_desc *desc; 119 int ret; 120 121 lpass_regmap_config.name = "cc"; 122 desc = &lpass_cc_sdm845_desc; 123 124 ret = qcom_cc_probe_by_index(pdev, 0, desc); 125 if (ret) 126 return ret; 127 128 lpass_regmap_config.name = "qdsp6ss"; 129 desc = &lpass_qdsp6ss_sdm845_desc; 130 131 return qcom_cc_probe_by_index(pdev, 1, desc); 132 } 133 134 static const struct of_device_id lpass_cc_sdm845_match_table[] = { 135 { .compatible = "qcom,sdm845-lpasscc" }, 136 { } 137 }; 138 MODULE_DEVICE_TABLE(of, lpass_cc_sdm845_match_table); 139 140 static struct platform_driver lpass_cc_sdm845_driver = { 141 .probe = lpass_cc_sdm845_probe, 142 .driver = { 143 .name = "sdm845-lpasscc", 144 .of_match_table = lpass_cc_sdm845_match_table, 145 }, 146 }; 147 148 static int __init lpass_cc_sdm845_init(void) 149 { 150 return platform_driver_register(&lpass_cc_sdm845_driver); 151 } 152 subsys_initcall(lpass_cc_sdm845_init); 153 154 static void __exit lpass_cc_sdm845_exit(void) 155 { 156 platform_driver_unregister(&lpass_cc_sdm845_driver); 157 } 158 module_exit(lpass_cc_sdm845_exit); 159 160 MODULE_DESCRIPTION("QTI LPASS_CC SDM845 Driver"); 161 MODULE_LICENSE("GPL v2"); 162