Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ASoC: mediatek: mt8189: support audio clock control

Add audio clock wrapper and audio tuner control.

Signed-off-by: Cyril Chao <Cyril.Chao@mediatek.com>
Link: https://patch.msgid.link/20251031073216.8662-3-Cyril.Chao@mediatek.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Cyril Chao and committed by
Mark Brown
dc637ffe 81f8f29a

+826
+750
sound/soc/mediatek/mt8189/mt8189-afe-clk.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * mt8189-afe-clk.c -- Mediatek 8189 afe clock ctrl 4 + * 5 + * Copyright (c) 2025 MediaTek Inc. 6 + * Author: Darren Ye <darren.ye@mediatek.com> 7 + */ 8 + 9 + #include <linux/clk.h> 10 + #include <linux/regmap.h> 11 + #include <linux/mfd/syscon.h> 12 + 13 + #include "mt8189-afe-common.h" 14 + #include "mt8189-afe-clk.h" 15 + 16 + /* mck */ 17 + struct mt8189_mck_div { 18 + int m_sel_id; 19 + int div_clk_id; 20 + }; 21 + 22 + static const struct mt8189_mck_div mck_div[MT8189_MCK_NUM] = { 23 + [MT8189_I2SIN0_MCK] = { 24 + .m_sel_id = MT8189_CLK_TOP_I2SIN0_M_SEL, 25 + .div_clk_id = MT8189_CLK_TOP_APLL12_DIV_I2SIN0, 26 + }, 27 + [MT8189_I2SIN1_MCK] = { 28 + .m_sel_id = MT8189_CLK_TOP_I2SIN1_M_SEL, 29 + .div_clk_id = MT8189_CLK_TOP_APLL12_DIV_I2SIN1, 30 + }, 31 + [MT8189_I2SOUT0_MCK] = { 32 + .m_sel_id = MT8189_CLK_TOP_I2SOUT0_M_SEL, 33 + .div_clk_id = MT8189_CLK_TOP_APLL12_DIV_I2SOUT0, 34 + }, 35 + [MT8189_I2SOUT1_MCK] = { 36 + .m_sel_id = MT8189_CLK_TOP_I2SOUT1_M_SEL, 37 + .div_clk_id = MT8189_CLK_TOP_APLL12_DIV_I2SOUT1, 38 + }, 39 + [MT8189_FMI2S_MCK] = { 40 + .m_sel_id = MT8189_CLK_TOP_FMI2S_M_SEL, 41 + .div_clk_id = MT8189_CLK_TOP_APLL12_DIV_FMI2S, 42 + }, 43 + [MT8189_TDMOUT_MCK] = { 44 + .m_sel_id = MT8189_CLK_TOP_TDMOUT_M_SEL, 45 + .div_clk_id = MT8189_CLK_TOP_APLL12_DIV_TDMOUT_M, 46 + }, 47 + [MT8189_TDMOUT_BCK] = { 48 + .m_sel_id = -1, 49 + .div_clk_id = MT8189_CLK_TOP_APLL12_DIV_TDMOUT_B, 50 + }, 51 + }; 52 + 53 + static const char *aud_clks[MT8189_CLK_NUM] = { 54 + [MT8189_CLK_TOP_MUX_AUDIOINTBUS] = "top_aud_intbus", 55 + [MT8189_CLK_TOP_MUX_AUD_ENG1] = "top_aud_eng1", 56 + [MT8189_CLK_TOP_MUX_AUD_ENG2] = "top_aud_eng2", 57 + [MT8189_CLK_TOP_MUX_AUDIO_H] = "top_aud_h", 58 + /* pll */ 59 + [MT8189_CLK_TOP_APLL1_CK] = "apll1", 60 + [MT8189_CLK_TOP_APLL2_CK] = "apll2", 61 + /* divider */ 62 + [MT8189_CLK_TOP_APLL1_D4] = "apll1_d4", 63 + [MT8189_CLK_TOP_APLL2_D4] = "apll2_d4", 64 + [MT8189_CLK_TOP_APLL12_DIV_I2SIN0] = "apll12_div_i2sin0", 65 + [MT8189_CLK_TOP_APLL12_DIV_I2SIN1] = "apll12_div_i2sin1", 66 + [MT8189_CLK_TOP_APLL12_DIV_I2SOUT0] = "apll12_div_i2sout0", 67 + [MT8189_CLK_TOP_APLL12_DIV_I2SOUT1] = "apll12_div_i2sout1", 68 + [MT8189_CLK_TOP_APLL12_DIV_FMI2S] = "apll12_div_fmi2s", 69 + [MT8189_CLK_TOP_APLL12_DIV_TDMOUT_M] = "apll12_div_tdmout_m", 70 + [MT8189_CLK_TOP_APLL12_DIV_TDMOUT_B] = "apll12_div_tdmout_b", 71 + /* mux */ 72 + [MT8189_CLK_TOP_MUX_AUD_1] = "top_apll1", 73 + [MT8189_CLK_TOP_MUX_AUD_2] = "top_apll2", 74 + [MT8189_CLK_TOP_I2SIN0_M_SEL] = "top_i2sin0", 75 + [MT8189_CLK_TOP_I2SIN1_M_SEL] = "top_i2sin1", 76 + [MT8189_CLK_TOP_I2SOUT0_M_SEL] = "top_i2sout0", 77 + [MT8189_CLK_TOP_I2SOUT1_M_SEL] = "top_i2sout1", 78 + [MT8189_CLK_TOP_FMI2S_M_SEL] = "top_fmi2s", 79 + [MT8189_CLK_TOP_TDMOUT_M_SEL] = "top_dptx", 80 + /* top 26m*/ 81 + [MT8189_CLK_TOP_CLK26M] = "clk26m", 82 + /* peri */ 83 + [MT8189_CLK_PERAO_AUDIO_SLV_CK_PERI] = "aud_slv_ck_peri", 84 + [MT8189_CLK_PERAO_AUDIO_MST_CK_PERI] = "aud_mst_ck_peri", 85 + [MT8189_CLK_PERAO_INTBUS_CK_PERI] = "aud_intbus_ck_peri", 86 + }; 87 + 88 + int mt8189_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk) 89 + { 90 + int ret; 91 + 92 + ret = clk_prepare_enable(clk); 93 + if (ret) { 94 + dev_err(afe->dev, "failed to enable clk\n"); 95 + return ret; 96 + } 97 + 98 + return 0; 99 + } 100 + EXPORT_SYMBOL_GPL(mt8189_afe_enable_clk); 101 + 102 + void mt8189_afe_disable_clk(struct mtk_base_afe *afe, struct clk *clk) 103 + { 104 + if (clk) 105 + clk_disable_unprepare(clk); 106 + else 107 + dev_dbg(afe->dev, "NULL clk\n"); 108 + } 109 + EXPORT_SYMBOL_GPL(mt8189_afe_disable_clk); 110 + 111 + static int mt8189_afe_set_clk_rate(struct mtk_base_afe *afe, struct clk *clk, 112 + unsigned int rate) 113 + { 114 + int ret; 115 + 116 + if (clk) { 117 + ret = clk_set_rate(clk, rate); 118 + if (ret) { 119 + dev_err(afe->dev, "failed to set clk rate\n"); 120 + return ret; 121 + } 122 + } 123 + 124 + return 0; 125 + } 126 + 127 + static int mt8189_afe_set_clk_parent(struct mtk_base_afe *afe, struct clk *clk, 128 + struct clk *parent) 129 + { 130 + int ret; 131 + 132 + if (clk && parent) { 133 + ret = clk_set_parent(clk, parent); 134 + if (ret) { 135 + dev_dbg(afe->dev, "failed to set clk parent %d\n", ret); 136 + return ret; 137 + } 138 + } 139 + 140 + return 0; 141 + } 142 + 143 + static unsigned int get_top_cg_reg(unsigned int cg_type) 144 + { 145 + switch (cg_type) { 146 + case MT8189_AUDIO_26M_EN_ON: 147 + case MT8189_AUDIO_F3P25M_EN_ON: 148 + case MT8189_AUDIO_APLL1_EN_ON: 149 + case MT8189_AUDIO_APLL2_EN_ON: 150 + return AUDIO_ENGEN_CON0; 151 + case MT8189_CG_AUDIO_HOPPING_CK: 152 + case MT8189_CG_AUDIO_F26M_CK: 153 + case MT8189_CG_APLL1_CK: 154 + case MT8189_CG_APLL2_CK: 155 + case MT8189_PDN_APLL_TUNER2: 156 + case MT8189_PDN_APLL_TUNER1: 157 + return AUDIO_TOP_CON4; 158 + default: 159 + return 0; 160 + } 161 + } 162 + 163 + static unsigned int get_top_cg_mask(unsigned int cg_type) 164 + { 165 + switch (cg_type) { 166 + case MT8189_AUDIO_26M_EN_ON: 167 + return AUDIO_26M_EN_ON_MASK_SFT; 168 + case MT8189_AUDIO_F3P25M_EN_ON: 169 + return AUDIO_F3P25M_EN_ON_MASK_SFT; 170 + case MT8189_AUDIO_APLL1_EN_ON: 171 + return AUDIO_APLL1_EN_ON_MASK_SFT; 172 + case MT8189_AUDIO_APLL2_EN_ON: 173 + return AUDIO_APLL2_EN_ON_MASK_SFT; 174 + case MT8189_CG_AUDIO_HOPPING_CK: 175 + return CG_AUDIO_HOPPING_CK_MASK_SFT; 176 + case MT8189_CG_AUDIO_F26M_CK: 177 + return CG_AUDIO_F26M_CK_MASK_SFT; 178 + case MT8189_CG_APLL1_CK: 179 + return CG_APLL1_CK_MASK_SFT; 180 + case MT8189_CG_APLL2_CK: 181 + return CG_APLL2_CK_MASK_SFT; 182 + case MT8189_PDN_APLL_TUNER2: 183 + return PDN_APLL_TUNER2_MASK_SFT; 184 + case MT8189_PDN_APLL_TUNER1: 185 + return PDN_APLL_TUNER1_MASK_SFT; 186 + default: 187 + return 0; 188 + } 189 + } 190 + 191 + static unsigned int get_top_cg_on_val(unsigned int cg_type) 192 + { 193 + switch (cg_type) { 194 + case MT8189_AUDIO_26M_EN_ON: 195 + case MT8189_AUDIO_F3P25M_EN_ON: 196 + case MT8189_AUDIO_APLL1_EN_ON: 197 + case MT8189_AUDIO_APLL2_EN_ON: 198 + return get_top_cg_mask(cg_type); 199 + case MT8189_CG_AUDIO_HOPPING_CK: 200 + case MT8189_CG_AUDIO_F26M_CK: 201 + case MT8189_CG_APLL1_CK: 202 + case MT8189_CG_APLL2_CK: 203 + case MT8189_PDN_APLL_TUNER2: 204 + case MT8189_PDN_APLL_TUNER1: 205 + return 0; 206 + default: 207 + return 0; 208 + } 209 + } 210 + 211 + static unsigned int get_top_cg_off_val(unsigned int cg_type) 212 + { 213 + switch (cg_type) { 214 + case MT8189_AUDIO_26M_EN_ON: 215 + case MT8189_AUDIO_F3P25M_EN_ON: 216 + case MT8189_AUDIO_APLL1_EN_ON: 217 + case MT8189_AUDIO_APLL2_EN_ON: 218 + return 0; 219 + case MT8189_CG_AUDIO_HOPPING_CK: 220 + case MT8189_CG_AUDIO_F26M_CK: 221 + case MT8189_CG_APLL1_CK: 222 + case MT8189_CG_APLL2_CK: 223 + case MT8189_PDN_APLL_TUNER2: 224 + case MT8189_PDN_APLL_TUNER1: 225 + return get_top_cg_mask(cg_type); 226 + default: 227 + return get_top_cg_mask(cg_type); 228 + } 229 + } 230 + 231 + static int mt8189_afe_enable_top_cg(struct mtk_base_afe *afe, unsigned int cg_type) 232 + { 233 + unsigned int reg = get_top_cg_reg(cg_type); 234 + unsigned int mask = get_top_cg_mask(cg_type); 235 + unsigned int val = get_top_cg_on_val(cg_type); 236 + 237 + if (!afe->regmap) { 238 + dev_err(afe->dev, "afe regmap is null !!!\n"); 239 + return 0; 240 + } 241 + 242 + dev_dbg(afe->dev, "reg: 0x%x, mask: 0x%x, val: 0x%x\n", reg, mask, val); 243 + 244 + return regmap_update_bits(afe->regmap, reg, mask, val); 245 + } 246 + 247 + static void mt8189_afe_disable_top_cg(struct mtk_base_afe *afe, unsigned int cg_type) 248 + { 249 + unsigned int reg = get_top_cg_reg(cg_type); 250 + unsigned int mask = get_top_cg_mask(cg_type); 251 + unsigned int val = get_top_cg_off_val(cg_type); 252 + 253 + if (!afe->regmap) { 254 + dev_warn(afe->dev, "skip regmap\n"); 255 + return; 256 + } 257 + 258 + dev_dbg(afe->dev, "reg: 0x%x, mask: 0x%x, val: 0x%x\n", reg, mask, val); 259 + regmap_update_bits(afe->regmap, reg, mask, val); 260 + } 261 + 262 + static int apll1_mux_setting(struct mtk_base_afe *afe, bool enable) 263 + { 264 + struct mt8189_afe_private *afe_priv = afe->platform_priv; 265 + int ret; 266 + 267 + dev_dbg(afe->dev, "enable: %d\n", enable); 268 + 269 + if (enable) { 270 + ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1]); 271 + if (ret) 272 + return ret; 273 + 274 + ret = mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1], 275 + afe_priv->clk[MT8189_CLK_TOP_APLL1_CK]); 276 + if (ret) 277 + goto clk_ck_mux_aud1_parent_err; 278 + 279 + /* 180.6336 / 4 = 45.1584MHz */ 280 + ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG1]); 281 + if (ret) 282 + goto clk_ck_mux_eng1_err; 283 + 284 + ret = mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG1], 285 + afe_priv->clk[MT8189_CLK_TOP_APLL1_D4]); 286 + if (ret) 287 + goto clk_ck_mux_eng1_parent_err; 288 + 289 + ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]); 290 + if (ret) 291 + goto clk_ck_mux_audio_h_err; 292 + 293 + ret = mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H], 294 + afe_priv->clk[MT8189_CLK_TOP_APLL1_CK]); 295 + if (ret) 296 + goto clk_ck_mux_audio_h_parent_err; 297 + } else { 298 + mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG1], 299 + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); 300 + 301 + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG1]); 302 + 303 + mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1], 304 + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); 305 + 306 + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1]); 307 + mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H], 308 + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); 309 + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]); 310 + } 311 + 312 + return 0; 313 + 314 + clk_ck_mux_audio_h_parent_err: 315 + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]); 316 + clk_ck_mux_audio_h_err: 317 + mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG1], 318 + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); 319 + clk_ck_mux_eng1_parent_err: 320 + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG1]); 321 + clk_ck_mux_eng1_err: 322 + mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1], 323 + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); 324 + clk_ck_mux_aud1_parent_err: 325 + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1]); 326 + 327 + return ret; 328 + } 329 + 330 + static int apll2_mux_setting(struct mtk_base_afe *afe, bool enable) 331 + { 332 + struct mt8189_afe_private *afe_priv = afe->platform_priv; 333 + int ret; 334 + 335 + dev_dbg(afe->dev, "enable: %d\n", enable); 336 + 337 + if (enable) { 338 + ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2]); 339 + if (ret) 340 + return ret; 341 + 342 + ret = mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2], 343 + afe_priv->clk[MT8189_CLK_TOP_APLL2_CK]); 344 + if (ret) 345 + goto clk_ck_mux_aud2_parent_err; 346 + 347 + /* 196.608 / 4 = 49.152MHz */ 348 + ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG2]); 349 + if (ret) 350 + goto clk_ck_mux_eng2_err; 351 + 352 + ret = mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG2], 353 + afe_priv->clk[MT8189_CLK_TOP_APLL2_D4]); 354 + if (ret) 355 + goto clk_ck_mux_eng2_parent_err; 356 + 357 + ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]); 358 + if (ret) 359 + goto clk_ck_mux_audio_h_err; 360 + 361 + ret = mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H], 362 + afe_priv->clk[MT8189_CLK_TOP_APLL2_CK]); 363 + if (ret) 364 + goto clk_ck_mux_audio_h_parent_err; 365 + } else { 366 + mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG2], 367 + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); 368 + 369 + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG2]); 370 + 371 + mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2], 372 + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); 373 + 374 + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2]); 375 + mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H], 376 + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); 377 + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]); 378 + } 379 + 380 + return 0; 381 + 382 + clk_ck_mux_audio_h_parent_err: 383 + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]); 384 + clk_ck_mux_audio_h_err: 385 + mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG2], 386 + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); 387 + clk_ck_mux_eng2_parent_err: 388 + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG2]); 389 + clk_ck_mux_eng2_err: 390 + mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2], 391 + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); 392 + clk_ck_mux_aud2_parent_err: 393 + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2]); 394 + 395 + return ret; 396 + } 397 + 398 + static int mt8189_afe_disable_apll(struct mtk_base_afe *afe) 399 + { 400 + struct mt8189_afe_private *afe_priv = afe->platform_priv; 401 + int ret; 402 + 403 + ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]); 404 + if (ret) 405 + return ret; 406 + 407 + ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1]); 408 + if (ret) 409 + goto clk_ck_mux_aud1_err; 410 + 411 + ret = mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1], 412 + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); 413 + if (ret) 414 + goto clk_ck_mux_aud1_parent_err; 415 + 416 + ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2]); 417 + if (ret) 418 + goto clk_ck_mux_aud2_err; 419 + 420 + ret = mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2], 421 + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); 422 + if (ret) 423 + goto clk_ck_mux_aud2_parent_err; 424 + 425 + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1]); 426 + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2]); 427 + mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H], 428 + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); 429 + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]); 430 + 431 + return 0; 432 + 433 + clk_ck_mux_aud2_parent_err: 434 + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2]); 435 + clk_ck_mux_aud2_err: 436 + mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1], 437 + afe_priv->clk[MT8189_CLK_TOP_APLL1_CK]); 438 + clk_ck_mux_aud1_parent_err: 439 + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1]); 440 + clk_ck_mux_aud1_err: 441 + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]); 442 + 443 + return ret; 444 + } 445 + 446 + int mt8189_apll1_enable(struct mtk_base_afe *afe) 447 + { 448 + int ret; 449 + 450 + /* setting for APLL */ 451 + ret = apll1_mux_setting(afe, true); 452 + if (ret) 453 + return ret; 454 + 455 + ret = mt8189_afe_enable_top_cg(afe, MT8189_CG_APLL1_CK); 456 + if (ret) 457 + return ret; 458 + 459 + ret = mt8189_afe_enable_top_cg(afe, MT8189_PDN_APLL_TUNER1); 460 + if (ret) 461 + return ret; 462 + 463 + /* sel 44.1kHz:1, apll_div:7, upper bound:3 */ 464 + regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG, 465 + XTAL_EN_128FS_SEL_MASK_SFT | APLL_DIV_MASK_SFT | 466 + UPPER_BOUND_MASK_SFT, 467 + (0x1 << XTAL_EN_128FS_SEL_SFT) | (7 << APLL_DIV_SFT) | 468 + (3 << UPPER_BOUND_SFT)); 469 + 470 + /* apll1 freq tuner enable */ 471 + regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG, 472 + FREQ_TUNER_EN_MASK_SFT, 473 + 0x1 << FREQ_TUNER_EN_SFT); 474 + 475 + /* audio apll1 on */ 476 + ret = mt8189_afe_enable_top_cg(afe, MT8189_AUDIO_APLL1_EN_ON); 477 + if (ret) 478 + return ret; 479 + 480 + return 0; 481 + } 482 + 483 + void mt8189_apll1_disable(struct mtk_base_afe *afe) 484 + { 485 + /* audio apll1 off */ 486 + mt8189_afe_disable_top_cg(afe, MT8189_AUDIO_APLL1_EN_ON); 487 + 488 + /* apll1 freq tuner disable */ 489 + regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG, 490 + FREQ_TUNER_EN_MASK_SFT, 491 + 0x0); 492 + 493 + mt8189_afe_disable_top_cg(afe, MT8189_PDN_APLL_TUNER1); 494 + mt8189_afe_disable_top_cg(afe, MT8189_CG_APLL1_CK); 495 + apll1_mux_setting(afe, false); 496 + } 497 + 498 + int mt8189_apll2_enable(struct mtk_base_afe *afe) 499 + { 500 + int ret; 501 + 502 + /* setting for APLL */ 503 + ret = apll2_mux_setting(afe, true); 504 + if (ret) 505 + return ret; 506 + 507 + ret = mt8189_afe_enable_top_cg(afe, MT8189_CG_APLL2_CK); 508 + if (ret) 509 + return ret; 510 + 511 + ret = mt8189_afe_enable_top_cg(afe, MT8189_PDN_APLL_TUNER2); 512 + if (ret) 513 + return ret; 514 + 515 + /* sel 48kHz: 2, apll_div: 7, upper bound: 3*/ 516 + regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG, 517 + XTAL_EN_128FS_SEL_MASK_SFT | APLL_DIV_MASK_SFT | 518 + UPPER_BOUND_MASK_SFT, 519 + (0x2 << XTAL_EN_128FS_SEL_SFT) | (7 << APLL_DIV_SFT) | 520 + (3 << UPPER_BOUND_SFT)); 521 + 522 + /* apll2 freq tuner enable */ 523 + regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG, 524 + FREQ_TUNER_EN_MASK_SFT, 525 + 0x1 << FREQ_TUNER_EN_SFT); 526 + 527 + /* audio apll2 on */ 528 + ret = mt8189_afe_enable_top_cg(afe, MT8189_AUDIO_APLL2_EN_ON); 529 + if (ret) 530 + return ret; 531 + 532 + return 0; 533 + } 534 + 535 + void mt8189_apll2_disable(struct mtk_base_afe *afe) 536 + { 537 + /* audio apll2 off */ 538 + mt8189_afe_disable_top_cg(afe, MT8189_AUDIO_APLL2_EN_ON); 539 + 540 + /* apll2 freq tuner disable */ 541 + regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG, 542 + FREQ_TUNER_EN_MASK_SFT, 543 + 0x0); 544 + 545 + mt8189_afe_disable_top_cg(afe, MT8189_PDN_APLL_TUNER2); 546 + mt8189_afe_disable_top_cg(afe, MT8189_CG_APLL2_CK); 547 + apll2_mux_setting(afe, false); 548 + } 549 + 550 + int mt8189_get_apll_rate(struct mtk_base_afe *afe, int apll) 551 + { 552 + struct mt8189_afe_private *afe_priv = afe->platform_priv; 553 + int clk_id; 554 + 555 + if (apll < MT8189_APLL1 || apll > MT8189_APLL2) { 556 + dev_warn(afe->dev, "invalid clk id %d\n", apll); 557 + return 0; 558 + } 559 + 560 + if (apll == MT8189_APLL1) 561 + clk_id = MT8189_CLK_TOP_APLL1_CK; 562 + else 563 + clk_id = MT8189_CLK_TOP_APLL2_CK; 564 + 565 + return clk_get_rate(afe_priv->clk[clk_id]); 566 + } 567 + 568 + int mt8189_get_apll_by_rate(struct mtk_base_afe *afe, int rate) 569 + { 570 + return (rate % 8000) ? MT8189_APLL1 : MT8189_APLL2; 571 + } 572 + 573 + int mt8189_get_apll_by_name(struct mtk_base_afe *afe, const char *name) 574 + { 575 + if (strcmp(name, APLL1_W_NAME) == 0) 576 + return MT8189_APLL1; 577 + 578 + return MT8189_APLL2; 579 + } 580 + 581 + int mt8189_mck_enable(struct mtk_base_afe *afe, int mck_id, int rate) 582 + { 583 + struct mt8189_afe_private *afe_priv = afe->platform_priv; 584 + int apll = mt8189_get_apll_by_rate(afe, rate); 585 + int apll_clk_id = apll == MT8189_APLL1 ? 586 + MT8189_CLK_TOP_MUX_AUD_1 : MT8189_CLK_TOP_MUX_AUD_2; 587 + int m_sel_id; 588 + int div_clk_id; 589 + int ret; 590 + 591 + dev_dbg(afe->dev, "mck_id: %d, rate: %d\n", mck_id, rate); 592 + 593 + if (mck_id >= MT8189_MCK_NUM || mck_id < 0) 594 + return -EINVAL; 595 + 596 + m_sel_id = mck_div[mck_id].m_sel_id; 597 + div_clk_id = mck_div[mck_id].div_clk_id; 598 + 599 + /* select apll */ 600 + if (m_sel_id >= 0) { 601 + ret = mt8189_afe_enable_clk(afe, afe_priv->clk[m_sel_id]); 602 + if (ret) 603 + return ret; 604 + 605 + ret = mt8189_afe_set_clk_parent(afe, afe_priv->clk[m_sel_id], 606 + afe_priv->clk[apll_clk_id]); 607 + if (ret) 608 + return ret; 609 + } 610 + 611 + /* enable div, set rate */ 612 + if (div_clk_id < 0) { 613 + dev_err(afe->dev, "invalid div_clk_id %d\n", div_clk_id); 614 + return -EINVAL; 615 + } 616 + 617 + ret = mt8189_afe_enable_clk(afe, afe_priv->clk[div_clk_id]); 618 + if (ret) 619 + return ret; 620 + 621 + ret = mt8189_afe_set_clk_rate(afe, afe_priv->clk[div_clk_id], rate); 622 + if (ret) 623 + return ret; 624 + 625 + return 0; 626 + } 627 + 628 + int mt8189_mck_disable(struct mtk_base_afe *afe, int mck_id) 629 + { 630 + struct mt8189_afe_private *afe_priv = afe->platform_priv; 631 + int m_sel_id; 632 + int div_clk_id; 633 + 634 + dev_dbg(afe->dev, "mck_id: %d.\n", mck_id); 635 + 636 + if (mck_id < 0) { 637 + dev_err(afe->dev, "mck_id = %d < 0\n", mck_id); 638 + return -EINVAL; 639 + } 640 + 641 + m_sel_id = mck_div[mck_id].m_sel_id; 642 + div_clk_id = mck_div[mck_id].div_clk_id; 643 + 644 + if (div_clk_id < 0) { 645 + dev_err(afe->dev, "div_clk_id = %d < 0\n", 646 + div_clk_id); 647 + return -EINVAL; 648 + } 649 + 650 + mt8189_afe_disable_clk(afe, afe_priv->clk[div_clk_id]); 651 + 652 + if (m_sel_id >= 0) 653 + mt8189_afe_disable_clk(afe, afe_priv->clk[m_sel_id]); 654 + 655 + return 0; 656 + } 657 + 658 + int mt8189_afe_enable_reg_rw_clk(struct mtk_base_afe *afe) 659 + { 660 + struct mt8189_afe_private *afe_priv = afe->platform_priv; 661 + 662 + /* bus clock for AFE internal access, like AFE SRAM */ 663 + mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIOINTBUS]); 664 + mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIOINTBUS], 665 + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); 666 + /* enable audio clock source */ 667 + mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]); 668 + mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H], 669 + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); 670 + 671 + return 0; 672 + } 673 + 674 + int mt8189_afe_disable_reg_rw_clk(struct mtk_base_afe *afe) 675 + { 676 + struct mt8189_afe_private *afe_priv = afe->platform_priv; 677 + 678 + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]); 679 + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIOINTBUS]); 680 + 681 + return 0; 682 + } 683 + 684 + int mt8189_afe_enable_main_clock(struct mtk_base_afe *afe) 685 + { 686 + return mt8189_afe_enable_top_cg(afe, MT8189_AUDIO_26M_EN_ON); 687 + } 688 + 689 + void mt8189_afe_disable_main_clock(struct mtk_base_afe *afe) 690 + { 691 + mt8189_afe_disable_top_cg(afe, MT8189_AUDIO_26M_EN_ON); 692 + } 693 + 694 + static int mt8189_afe_enable_ao_clock(struct mtk_base_afe *afe) 695 + { 696 + struct mt8189_afe_private *afe_priv = afe->platform_priv; 697 + int ret; 698 + 699 + /* Peri clock AO enable */ 700 + ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_PERAO_INTBUS_CK_PERI]); 701 + if (ret) 702 + return ret; 703 + 704 + ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_PERAO_AUDIO_SLV_CK_PERI]); 705 + if (ret) 706 + goto err_clk_perao_slv; 707 + 708 + ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_PERAO_AUDIO_MST_CK_PERI]); 709 + if (ret) 710 + goto err_clk_perao_mst; 711 + 712 + return 0; 713 + 714 + err_clk_perao_mst: 715 + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_PERAO_AUDIO_SLV_CK_PERI]); 716 + err_clk_perao_slv: 717 + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_PERAO_INTBUS_CK_PERI]); 718 + 719 + return ret; 720 + } 721 + 722 + int mt8189_init_clock(struct mtk_base_afe *afe) 723 + { 724 + struct mt8189_afe_private *afe_priv = afe->platform_priv; 725 + int ret; 726 + int i; 727 + 728 + afe_priv->clk = devm_kcalloc(afe->dev, MT8189_CLK_NUM, sizeof(*afe_priv->clk), 729 + GFP_KERNEL); 730 + if (!afe_priv->clk) 731 + return -ENOMEM; 732 + 733 + for (i = 0; i < MT8189_CLK_NUM; i++) { 734 + afe_priv->clk[i] = devm_clk_get(afe->dev, aud_clks[i]); 735 + if (IS_ERR(afe_priv->clk[i])) { 736 + dev_err(afe->dev, "devm_clk_get %s fail\n", aud_clks[i]); 737 + return PTR_ERR(afe_priv->clk[i]); 738 + } 739 + } 740 + 741 + ret = mt8189_afe_disable_apll(afe); 742 + if (ret) 743 + return ret; 744 + 745 + ret = mt8189_afe_enable_ao_clock(afe); 746 + if (ret) 747 + return ret; 748 + 749 + return 0; 750 + }
+76
sound/soc/mediatek/mt8189/mt8189-afe-clk.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * mt8189-afe-clk.h -- Mediatek 8189 afe clock ctrl definition 4 + * 5 + * Copyright (c) 2025 MediaTek Inc. 6 + * Author: Darren Ye <darren.ye@mediatek.com> 7 + */ 8 + 9 + #ifndef _MT8189_AFE_CLOCK_CTRL_H_ 10 + #define _MT8189_AFE_CLOCK_CTRL_H_ 11 + 12 + /* APLL */ 13 + #define APLL1_W_NAME "APLL1" 14 + #define APLL2_W_NAME "APLL2" 15 + 16 + enum { 17 + MT8189_APLL1, 18 + MT8189_APLL2, 19 + }; 20 + 21 + enum { 22 + MT8189_CLK_TOP_MUX_AUDIOINTBUS, 23 + MT8189_CLK_TOP_MUX_AUD_ENG1, 24 + MT8189_CLK_TOP_MUX_AUD_ENG2, 25 + MT8189_CLK_TOP_MUX_AUDIO_H, 26 + /* pll */ 27 + MT8189_CLK_TOP_APLL1_CK, 28 + MT8189_CLK_TOP_APLL2_CK, 29 + /* divider */ 30 + MT8189_CLK_TOP_APLL1_D4, 31 + MT8189_CLK_TOP_APLL2_D4, 32 + MT8189_CLK_TOP_APLL12_DIV_I2SIN0, 33 + MT8189_CLK_TOP_APLL12_DIV_I2SIN1, 34 + MT8189_CLK_TOP_APLL12_DIV_I2SOUT0, 35 + MT8189_CLK_TOP_APLL12_DIV_I2SOUT1, 36 + MT8189_CLK_TOP_APLL12_DIV_FMI2S, 37 + MT8189_CLK_TOP_APLL12_DIV_TDMOUT_M, 38 + MT8189_CLK_TOP_APLL12_DIV_TDMOUT_B, 39 + /* mux */ 40 + MT8189_CLK_TOP_MUX_AUD_1, 41 + MT8189_CLK_TOP_MUX_AUD_2, 42 + MT8189_CLK_TOP_I2SIN0_M_SEL, 43 + MT8189_CLK_TOP_I2SIN1_M_SEL, 44 + MT8189_CLK_TOP_I2SOUT0_M_SEL, 45 + MT8189_CLK_TOP_I2SOUT1_M_SEL, 46 + MT8189_CLK_TOP_FMI2S_M_SEL, 47 + MT8189_CLK_TOP_TDMOUT_M_SEL, 48 + /* top 26m */ 49 + MT8189_CLK_TOP_CLK26M, 50 + /* peri */ 51 + MT8189_CLK_PERAO_AUDIO_SLV_CK_PERI, 52 + MT8189_CLK_PERAO_AUDIO_MST_CK_PERI, 53 + MT8189_CLK_PERAO_INTBUS_CK_PERI, 54 + MT8189_CLK_NUM, 55 + }; 56 + 57 + struct mtk_base_afe; 58 + 59 + int mt8189_mck_enable(struct mtk_base_afe *afe, int mck_id, int rate); 60 + int mt8189_mck_disable(struct mtk_base_afe *afe, int mck_id); 61 + int mt8189_get_apll_rate(struct mtk_base_afe *afe, int apll); 62 + int mt8189_get_apll_by_rate(struct mtk_base_afe *afe, int rate); 63 + int mt8189_get_apll_by_name(struct mtk_base_afe *afe, const char *name); 64 + int mt8189_init_clock(struct mtk_base_afe *afe); 65 + int mt8189_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk); 66 + void mt8189_afe_disable_clk(struct mtk_base_afe *afe, struct clk *clk); 67 + int mt8189_apll1_enable(struct mtk_base_afe *afe); 68 + void mt8189_apll1_disable(struct mtk_base_afe *afe); 69 + int mt8189_apll2_enable(struct mtk_base_afe *afe); 70 + void mt8189_apll2_disable(struct mtk_base_afe *afe); 71 + int mt8189_afe_enable_main_clock(struct mtk_base_afe *afe); 72 + void mt8189_afe_disable_main_clock(struct mtk_base_afe *afe); 73 + int mt8189_afe_enable_reg_rw_clk(struct mtk_base_afe *afe); 74 + int mt8189_afe_disable_reg_rw_clk(struct mtk_base_afe *afe); 75 + 76 + #endif