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 } 751