1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (c) 2020, Linaro Limited 3 4 #include <linux/err.h> 5 #include <linux/init.h> 6 #include <linux/clk-provider.h> 7 #include <linux/module.h> 8 #include <linux/device.h> 9 #include <linux/platform_device.h> 10 #include <linux/of.h> 11 #include <linux/slab.h> 12 #include "q6afe.h" 13 14 #define Q6AFE_CLK(id) &(struct q6afe_clk) { \ 15 .clk_id = id, \ 16 .afe_clk_id = Q6AFE_##id, \ 17 .name = #id, \ 18 .attributes = LPASS_CLK_ATTRIBUTE_COUPLE_NO, \ 19 .hw.init = &(struct clk_init_data) { \ 20 .ops = &clk_q6afe_ops, \ 21 .name = #id, \ 22 }, \ 23 } 24 25 #define Q6AFE_VOTE_CLK(id, blkid, n) &(struct q6afe_clk) { \ 26 .clk_id = id, \ 27 .afe_clk_id = blkid, \ 28 .name = #n, \ 29 .hw.init = &(struct clk_init_data) { \ 30 .ops = &clk_vote_q6afe_ops, \ 31 .name = #id, \ 32 }, \ 33 } 34 35 struct q6afe_clk { 36 struct device *dev; 37 int clk_id; 38 int afe_clk_id; 39 char *name; 40 int attributes; 41 int rate; 42 uint32_t handle; 43 struct clk_hw hw; 44 }; 45 46 #define to_q6afe_clk(_hw) container_of(_hw, struct q6afe_clk, hw) 47 48 struct q6afe_cc { 49 struct device *dev; 50 struct q6afe_clk **clks; 51 int num_clks; 52 }; 53 54 static int clk_q6afe_prepare(struct clk_hw *hw) 55 { 56 struct q6afe_clk *clk = to_q6afe_clk(hw); 57 58 return q6afe_set_lpass_clock(clk->dev, clk->afe_clk_id, clk->attributes, 59 Q6AFE_LPASS_CLK_ROOT_DEFAULT, clk->rate); 60 } 61 62 static void clk_q6afe_unprepare(struct clk_hw *hw) 63 { 64 struct q6afe_clk *clk = to_q6afe_clk(hw); 65 66 q6afe_set_lpass_clock(clk->dev, clk->afe_clk_id, clk->attributes, 67 Q6AFE_LPASS_CLK_ROOT_DEFAULT, 0); 68 } 69 70 static int clk_q6afe_set_rate(struct clk_hw *hw, unsigned long rate, 71 unsigned long parent_rate) 72 { 73 struct q6afe_clk *clk = to_q6afe_clk(hw); 74 75 clk->rate = rate; 76 77 return 0; 78 } 79 80 static unsigned long clk_q6afe_recalc_rate(struct clk_hw *hw, 81 unsigned long parent_rate) 82 { 83 struct q6afe_clk *clk = to_q6afe_clk(hw); 84 85 return clk->rate; 86 } 87 88 static long clk_q6afe_round_rate(struct clk_hw *hw, unsigned long rate, 89 unsigned long *parent_rate) 90 { 91 return rate; 92 } 93 94 static const struct clk_ops clk_q6afe_ops = { 95 .prepare = clk_q6afe_prepare, 96 .unprepare = clk_q6afe_unprepare, 97 .set_rate = clk_q6afe_set_rate, 98 .round_rate = clk_q6afe_round_rate, 99 .recalc_rate = clk_q6afe_recalc_rate, 100 }; 101 102 static int clk_vote_q6afe_block(struct clk_hw *hw) 103 { 104 struct q6afe_clk *clk = to_q6afe_clk(hw); 105 106 return q6afe_vote_lpass_core_hw(clk->dev, clk->afe_clk_id, 107 clk->name, &clk->handle); 108 } 109 110 static void clk_unvote_q6afe_block(struct clk_hw *hw) 111 { 112 struct q6afe_clk *clk = to_q6afe_clk(hw); 113 114 q6afe_unvote_lpass_core_hw(clk->dev, clk->afe_clk_id, clk->handle); 115 } 116 117 static const struct clk_ops clk_vote_q6afe_ops = { 118 .prepare = clk_vote_q6afe_block, 119 .unprepare = clk_unvote_q6afe_block, 120 }; 121 122 struct q6afe_clk *q6afe_clks[Q6AFE_MAX_CLK_ID] = { 123 [LPASS_CLK_ID_PRI_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_PRI_MI2S_IBIT), 124 [LPASS_CLK_ID_PRI_MI2S_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_PRI_MI2S_EBIT), 125 [LPASS_CLK_ID_SEC_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEC_MI2S_IBIT), 126 [LPASS_CLK_ID_SEC_MI2S_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEC_MI2S_EBIT), 127 [LPASS_CLK_ID_TER_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_TER_MI2S_IBIT), 128 [LPASS_CLK_ID_TER_MI2S_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_TER_MI2S_EBIT), 129 [LPASS_CLK_ID_QUAD_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUAD_MI2S_IBIT), 130 [LPASS_CLK_ID_QUAD_MI2S_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUAD_MI2S_EBIT), 131 [LPASS_CLK_ID_SPEAKER_I2S_IBIT] = 132 Q6AFE_CLK(LPASS_CLK_ID_SPEAKER_I2S_IBIT), 133 [LPASS_CLK_ID_SPEAKER_I2S_EBIT] = 134 Q6AFE_CLK(LPASS_CLK_ID_SPEAKER_I2S_EBIT), 135 [LPASS_CLK_ID_SPEAKER_I2S_OSR] = 136 Q6AFE_CLK(LPASS_CLK_ID_SPEAKER_I2S_OSR), 137 [LPASS_CLK_ID_QUI_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUI_MI2S_IBIT), 138 [LPASS_CLK_ID_QUI_MI2S_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUI_MI2S_EBIT), 139 [LPASS_CLK_ID_SEN_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEN_MI2S_IBIT), 140 [LPASS_CLK_ID_SEN_MI2S_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEN_MI2S_EBIT), 141 [LPASS_CLK_ID_INT0_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_INT0_MI2S_IBIT), 142 [LPASS_CLK_ID_INT1_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_INT1_MI2S_IBIT), 143 [LPASS_CLK_ID_INT2_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_INT2_MI2S_IBIT), 144 [LPASS_CLK_ID_INT3_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_INT3_MI2S_IBIT), 145 [LPASS_CLK_ID_INT4_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_INT4_MI2S_IBIT), 146 [LPASS_CLK_ID_INT5_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_INT5_MI2S_IBIT), 147 [LPASS_CLK_ID_INT6_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_INT6_MI2S_IBIT), 148 [LPASS_CLK_ID_QUI_MI2S_OSR] = Q6AFE_CLK(LPASS_CLK_ID_QUI_MI2S_OSR), 149 [LPASS_CLK_ID_PRI_PCM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_PRI_PCM_IBIT), 150 [LPASS_CLK_ID_PRI_PCM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_PRI_PCM_EBIT), 151 [LPASS_CLK_ID_SEC_PCM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEC_PCM_IBIT), 152 [LPASS_CLK_ID_SEC_PCM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEC_PCM_EBIT), 153 [LPASS_CLK_ID_TER_PCM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_TER_PCM_IBIT), 154 [LPASS_CLK_ID_TER_PCM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_TER_PCM_EBIT), 155 [LPASS_CLK_ID_QUAD_PCM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUAD_PCM_IBIT), 156 [LPASS_CLK_ID_QUAD_PCM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUAD_PCM_EBIT), 157 [LPASS_CLK_ID_QUIN_PCM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUIN_PCM_IBIT), 158 [LPASS_CLK_ID_QUIN_PCM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUIN_PCM_EBIT), 159 [LPASS_CLK_ID_QUI_PCM_OSR] = Q6AFE_CLK(LPASS_CLK_ID_QUI_PCM_OSR), 160 [LPASS_CLK_ID_PRI_TDM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_PRI_TDM_IBIT), 161 [LPASS_CLK_ID_PRI_TDM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_PRI_TDM_EBIT), 162 [LPASS_CLK_ID_SEC_TDM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEC_TDM_IBIT), 163 [LPASS_CLK_ID_SEC_TDM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEC_TDM_EBIT), 164 [LPASS_CLK_ID_TER_TDM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_TER_TDM_IBIT), 165 [LPASS_CLK_ID_TER_TDM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_TER_TDM_EBIT), 166 [LPASS_CLK_ID_QUAD_TDM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUAD_TDM_IBIT), 167 [LPASS_CLK_ID_QUAD_TDM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUAD_TDM_EBIT), 168 [LPASS_CLK_ID_QUIN_TDM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUIN_TDM_IBIT), 169 [LPASS_CLK_ID_QUIN_TDM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUIN_TDM_EBIT), 170 [LPASS_CLK_ID_QUIN_TDM_OSR] = Q6AFE_CLK(LPASS_CLK_ID_QUIN_TDM_OSR), 171 [LPASS_CLK_ID_MCLK_1] = Q6AFE_CLK(LPASS_CLK_ID_MCLK_1), 172 [LPASS_CLK_ID_MCLK_2] = Q6AFE_CLK(LPASS_CLK_ID_MCLK_2), 173 [LPASS_CLK_ID_MCLK_3] = Q6AFE_CLK(LPASS_CLK_ID_MCLK_3), 174 [LPASS_CLK_ID_MCLK_4] = Q6AFE_CLK(LPASS_CLK_ID_MCLK_4), 175 [LPASS_CLK_ID_INTERNAL_DIGITAL_CODEC_CORE] = 176 Q6AFE_CLK(LPASS_CLK_ID_INTERNAL_DIGITAL_CODEC_CORE), 177 [LPASS_CLK_ID_INT_MCLK_0] = Q6AFE_CLK(LPASS_CLK_ID_INT_MCLK_0), 178 [LPASS_CLK_ID_INT_MCLK_1] = Q6AFE_CLK(LPASS_CLK_ID_INT_MCLK_1), 179 [LPASS_CLK_ID_WSA_CORE_MCLK] = Q6AFE_CLK(LPASS_CLK_ID_WSA_CORE_MCLK), 180 [LPASS_CLK_ID_WSA_CORE_NPL_MCLK] = 181 Q6AFE_CLK(LPASS_CLK_ID_WSA_CORE_NPL_MCLK), 182 [LPASS_CLK_ID_VA_CORE_MCLK] = Q6AFE_CLK(LPASS_CLK_ID_VA_CORE_MCLK), 183 [LPASS_CLK_ID_TX_CORE_MCLK] = Q6AFE_CLK(LPASS_CLK_ID_TX_CORE_MCLK), 184 [LPASS_CLK_ID_TX_CORE_NPL_MCLK] = 185 Q6AFE_CLK(LPASS_CLK_ID_TX_CORE_NPL_MCLK), 186 [LPASS_CLK_ID_RX_CORE_MCLK] = Q6AFE_CLK(LPASS_CLK_ID_RX_CORE_MCLK), 187 [LPASS_CLK_ID_RX_CORE_NPL_MCLK] = 188 Q6AFE_CLK(LPASS_CLK_ID_RX_CORE_NPL_MCLK), 189 [LPASS_CLK_ID_VA_CORE_2X_MCLK] = 190 Q6AFE_CLK(LPASS_CLK_ID_VA_CORE_2X_MCLK), 191 [LPASS_HW_AVTIMER_VOTE] = Q6AFE_VOTE_CLK(LPASS_HW_AVTIMER_VOTE, 192 Q6AFE_LPASS_CORE_AVTIMER_BLOCK, 193 "LPASS_AVTIMER_MACRO"), 194 [LPASS_HW_MACRO_VOTE] = Q6AFE_VOTE_CLK(LPASS_HW_MACRO_VOTE, 195 Q6AFE_LPASS_CORE_HW_MACRO_BLOCK, 196 "LPASS_HW_MACRO"), 197 [LPASS_HW_DCODEC_VOTE] = Q6AFE_VOTE_CLK(LPASS_HW_DCODEC_VOTE, 198 Q6AFE_LPASS_CORE_HW_DCODEC_BLOCK, 199 "LPASS_HW_DCODEC"), 200 }; 201 202 static struct clk_hw *q6afe_of_clk_hw_get(struct of_phandle_args *clkspec, 203 void *data) 204 { 205 struct q6afe_cc *cc = data; 206 unsigned int idx = clkspec->args[0]; 207 unsigned int attr = clkspec->args[1]; 208 209 if (idx >= cc->num_clks || attr > LPASS_CLK_ATTRIBUTE_COUPLE_DIVISOR) { 210 dev_err(cc->dev, "Invalid clk specifier (%d, %d)\n", idx, attr); 211 return ERR_PTR(-EINVAL); 212 } 213 214 if (cc->clks[idx]) { 215 cc->clks[idx]->attributes = attr; 216 return &cc->clks[idx]->hw; 217 } 218 219 return ERR_PTR(-ENOENT); 220 } 221 222 static int q6afe_clock_dev_probe(struct platform_device *pdev) 223 { 224 struct q6afe_cc *cc; 225 struct device *dev = &pdev->dev; 226 int i, ret; 227 228 cc = devm_kzalloc(dev, sizeof(*cc), GFP_KERNEL); 229 if (!cc) 230 return -ENOMEM; 231 232 cc->clks = &q6afe_clks[0]; 233 cc->num_clks = ARRAY_SIZE(q6afe_clks); 234 for (i = 0; i < ARRAY_SIZE(q6afe_clks); i++) { 235 if (!q6afe_clks[i]) 236 continue; 237 238 q6afe_clks[i]->dev = dev; 239 240 ret = devm_clk_hw_register(dev, &q6afe_clks[i]->hw); 241 if (ret) 242 return ret; 243 } 244 245 ret = of_clk_add_hw_provider(dev->of_node, q6afe_of_clk_hw_get, cc); 246 if (ret) 247 return ret; 248 249 dev_set_drvdata(dev, cc); 250 251 return 0; 252 } 253 254 #ifdef CONFIG_OF 255 static const struct of_device_id q6afe_clock_device_id[] = { 256 { .compatible = "qcom,q6afe-clocks" }, 257 {}, 258 }; 259 MODULE_DEVICE_TABLE(of, q6afe_clock_device_id); 260 #endif 261 262 static struct platform_driver q6afe_clock_platform_driver = { 263 .driver = { 264 .name = "q6afe-clock", 265 .of_match_table = of_match_ptr(q6afe_clock_device_id), 266 }, 267 .probe = q6afe_clock_dev_probe, 268 }; 269 module_platform_driver(q6afe_clock_platform_driver); 270 271 MODULE_DESCRIPTION("Q6 Audio Frontend clock driver"); 272 MODULE_LICENSE("GPL v2"); 273