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