645 lines · c
1// SPDX-License-Identifier: GPL-2.02//3// mt8186-afe-clk.c -- Mediatek 8186 afe clock ctrl4//5// Copyright (c) 2022 MediaTek Inc.6// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>7 8#include <linux/clk.h>9#include <linux/regmap.h>10#include <linux/mfd/syscon.h>11 12#include "mt8186-afe-common.h"13#include "mt8186-afe-clk.h"14#include "mt8186-audsys-clk.h"15 16static const char *aud_clks[CLK_NUM] = {17 [CLK_AFE] = "aud_afe_clk",18 [CLK_DAC] = "aud_dac_clk",19 [CLK_DAC_PREDIS] = "aud_dac_predis_clk",20 [CLK_ADC] = "aud_adc_clk",21 [CLK_TML] = "aud_tml_clk",22 [CLK_APLL22M] = "aud_apll22m_clk",23 [CLK_APLL24M] = "aud_apll24m_clk",24 [CLK_APLL1_TUNER] = "aud_apll_tuner_clk",25 [CLK_APLL2_TUNER] = "aud_apll2_tuner_clk",26 [CLK_TDM] = "aud_tdm_clk",27 [CLK_NLE] = "aud_nle_clk",28 [CLK_DAC_HIRES] = "aud_dac_hires_clk",29 [CLK_ADC_HIRES] = "aud_adc_hires_clk",30 [CLK_I2S1_BCLK] = "aud_i2s1_bclk",31 [CLK_I2S2_BCLK] = "aud_i2s2_bclk",32 [CLK_I2S3_BCLK] = "aud_i2s3_bclk",33 [CLK_I2S4_BCLK] = "aud_i2s4_bclk",34 [CLK_CONNSYS_I2S_ASRC] = "aud_connsys_i2s_asrc",35 [CLK_GENERAL1_ASRC] = "aud_general1_asrc",36 [CLK_GENERAL2_ASRC] = "aud_general2_asrc",37 [CLK_ADC_HIRES_TML] = "aud_adc_hires_tml",38 [CLK_ADDA6_ADC] = "aud_adda6_adc",39 [CLK_ADDA6_ADC_HIRES] = "aud_adda6_adc_hires",40 [CLK_3RD_DAC] = "aud_3rd_dac",41 [CLK_3RD_DAC_PREDIS] = "aud_3rd_dac_predis",42 [CLK_3RD_DAC_TML] = "aud_3rd_dac_tml",43 [CLK_3RD_DAC_HIRES] = "aud_3rd_dac_hires",44 [CLK_ETDM_IN1_BCLK] = "aud_etdm_in1_bclk",45 [CLK_ETDM_OUT1_BCLK] = "aud_etdm_out1_bclk",46 [CLK_INFRA_SYS_AUDIO] = "aud_infra_clk",47 [CLK_INFRA_AUDIO_26M] = "mtkaif_26m_clk",48 [CLK_MUX_AUDIO] = "top_mux_audio",49 [CLK_MUX_AUDIOINTBUS] = "top_mux_audio_int",50 [CLK_TOP_MAINPLL_D2_D4] = "top_mainpll_d2_d4",51 [CLK_TOP_MUX_AUD_1] = "top_mux_aud_1",52 [CLK_TOP_APLL1_CK] = "top_apll1_ck",53 [CLK_TOP_MUX_AUD_2] = "top_mux_aud_2",54 [CLK_TOP_APLL2_CK] = "top_apll2_ck",55 [CLK_TOP_MUX_AUD_ENG1] = "top_mux_aud_eng1",56 [CLK_TOP_APLL1_D8] = "top_apll1_d8",57 [CLK_TOP_MUX_AUD_ENG2] = "top_mux_aud_eng2",58 [CLK_TOP_APLL2_D8] = "top_apll2_d8",59 [CLK_TOP_MUX_AUDIO_H] = "top_mux_audio_h",60 [CLK_TOP_I2S0_M_SEL] = "top_i2s0_m_sel",61 [CLK_TOP_I2S1_M_SEL] = "top_i2s1_m_sel",62 [CLK_TOP_I2S2_M_SEL] = "top_i2s2_m_sel",63 [CLK_TOP_I2S4_M_SEL] = "top_i2s4_m_sel",64 [CLK_TOP_TDM_M_SEL] = "top_tdm_m_sel",65 [CLK_TOP_APLL12_DIV0] = "top_apll12_div0",66 [CLK_TOP_APLL12_DIV1] = "top_apll12_div1",67 [CLK_TOP_APLL12_DIV2] = "top_apll12_div2",68 [CLK_TOP_APLL12_DIV4] = "top_apll12_div4",69 [CLK_TOP_APLL12_DIV_TDM] = "top_apll12_div_tdm",70 [CLK_CLK26M] = "top_clk26m_clk",71};72 73int mt8186_set_audio_int_bus_parent(struct mtk_base_afe *afe,74 int clk_id)75{76 struct mt8186_afe_private *afe_priv = afe->platform_priv;77 int ret;78 79 ret = clk_set_parent(afe_priv->clk[CLK_MUX_AUDIOINTBUS],80 afe_priv->clk[clk_id]);81 if (ret) {82 dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",83 __func__, aud_clks[CLK_MUX_AUDIOINTBUS],84 aud_clks[clk_id], ret);85 return ret;86 }87 88 return 0;89}90 91static int apll1_mux_setting(struct mtk_base_afe *afe, bool enable)92{93 struct mt8186_afe_private *afe_priv = afe->platform_priv;94 int ret;95 96 if (enable) {97 ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD_1]);98 if (ret) {99 dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",100 __func__, aud_clks[CLK_TOP_MUX_AUD_1], ret);101 return ret;102 }103 ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_1],104 afe_priv->clk[CLK_TOP_APLL1_CK]);105 if (ret) {106 dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",107 __func__, aud_clks[CLK_TOP_MUX_AUD_1],108 aud_clks[CLK_TOP_APLL1_CK], ret);109 return ret;110 }111 112 /* 180.6336 / 8 = 22.5792MHz */113 ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD_ENG1]);114 if (ret) {115 dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",116 __func__, aud_clks[CLK_TOP_MUX_AUD_ENG1], ret);117 return ret;118 }119 ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_ENG1],120 afe_priv->clk[CLK_TOP_APLL1_D8]);121 if (ret) {122 dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",123 __func__, aud_clks[CLK_TOP_MUX_AUD_ENG1],124 aud_clks[CLK_TOP_APLL1_D8], ret);125 return ret;126 }127 } else {128 ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_ENG1],129 afe_priv->clk[CLK_CLK26M]);130 if (ret) {131 dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",132 __func__, aud_clks[CLK_TOP_MUX_AUD_ENG1],133 aud_clks[CLK_CLK26M], ret);134 return ret;135 }136 clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_ENG1]);137 138 ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_1],139 afe_priv->clk[CLK_CLK26M]);140 if (ret) {141 dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",142 __func__, aud_clks[CLK_TOP_MUX_AUD_1],143 aud_clks[CLK_CLK26M], ret);144 return ret;145 }146 clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_1]);147 }148 149 return 0;150}151 152static int apll2_mux_setting(struct mtk_base_afe *afe, bool enable)153{154 struct mt8186_afe_private *afe_priv = afe->platform_priv;155 int ret;156 157 if (enable) {158 ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD_2]);159 if (ret) {160 dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",161 __func__, aud_clks[CLK_TOP_MUX_AUD_2], ret);162 return ret;163 }164 ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_2],165 afe_priv->clk[CLK_TOP_APLL2_CK]);166 if (ret) {167 dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",168 __func__, aud_clks[CLK_TOP_MUX_AUD_2],169 aud_clks[CLK_TOP_APLL2_CK], ret);170 return ret;171 }172 173 /* 196.608 / 8 = 24.576MHz */174 ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD_ENG2]);175 if (ret) {176 dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",177 __func__, aud_clks[CLK_TOP_MUX_AUD_ENG2], ret);178 return ret;179 }180 ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_ENG2],181 afe_priv->clk[CLK_TOP_APLL2_D8]);182 if (ret) {183 dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",184 __func__, aud_clks[CLK_TOP_MUX_AUD_ENG2],185 aud_clks[CLK_TOP_APLL2_D8], ret);186 return ret;187 }188 } else {189 ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_ENG2],190 afe_priv->clk[CLK_CLK26M]);191 if (ret) {192 dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",193 __func__, aud_clks[CLK_TOP_MUX_AUD_ENG2],194 aud_clks[CLK_CLK26M], ret);195 return ret;196 }197 clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_ENG2]);198 199 ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_2],200 afe_priv->clk[CLK_CLK26M]);201 if (ret) {202 dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",203 __func__, aud_clks[CLK_TOP_MUX_AUD_2],204 aud_clks[CLK_CLK26M], ret);205 return ret;206 }207 clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_2]);208 }209 210 return 0;211}212 213int mt8186_afe_enable_cgs(struct mtk_base_afe *afe)214{215 struct mt8186_afe_private *afe_priv = afe->platform_priv;216 int ret = 0;217 int i;218 219 for (i = CLK_I2S1_BCLK; i <= CLK_ETDM_OUT1_BCLK; i++) {220 ret = clk_prepare_enable(afe_priv->clk[i]);221 if (ret) {222 dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",223 __func__, aud_clks[i], ret);224 return ret;225 }226 }227 228 return 0;229}230 231void mt8186_afe_disable_cgs(struct mtk_base_afe *afe)232{233 struct mt8186_afe_private *afe_priv = afe->platform_priv;234 int i;235 236 for (i = CLK_I2S1_BCLK; i <= CLK_ETDM_OUT1_BCLK; i++)237 clk_disable_unprepare(afe_priv->clk[i]);238}239 240int mt8186_afe_enable_clock(struct mtk_base_afe *afe)241{242 struct mt8186_afe_private *afe_priv = afe->platform_priv;243 int ret = 0;244 245 ret = clk_prepare_enable(afe_priv->clk[CLK_INFRA_SYS_AUDIO]);246 if (ret) {247 dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",248 __func__, aud_clks[CLK_INFRA_SYS_AUDIO], ret);249 goto clk_infra_sys_audio_err;250 }251 252 ret = clk_prepare_enable(afe_priv->clk[CLK_INFRA_AUDIO_26M]);253 if (ret) {254 dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",255 __func__, aud_clks[CLK_INFRA_AUDIO_26M], ret);256 goto clk_infra_audio_26m_err;257 }258 259 ret = clk_prepare_enable(afe_priv->clk[CLK_MUX_AUDIO]);260 if (ret) {261 dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",262 __func__, aud_clks[CLK_MUX_AUDIO], ret);263 goto clk_mux_audio_err;264 }265 ret = clk_set_parent(afe_priv->clk[CLK_MUX_AUDIO],266 afe_priv->clk[CLK_CLK26M]);267 if (ret) {268 dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",269 __func__, aud_clks[CLK_MUX_AUDIO],270 aud_clks[CLK_CLK26M], ret);271 goto clk_mux_audio_err;272 }273 274 ret = clk_prepare_enable(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);275 if (ret) {276 dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",277 __func__, aud_clks[CLK_MUX_AUDIOINTBUS], ret);278 goto clk_mux_audio_intbus_err;279 }280 ret = mt8186_set_audio_int_bus_parent(afe,281 CLK_TOP_MAINPLL_D2_D4);282 if (ret)283 goto clk_mux_audio_intbus_parent_err;284 285 ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUDIO_H],286 afe_priv->clk[CLK_TOP_APLL2_CK]);287 if (ret) {288 dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",289 __func__, aud_clks[CLK_TOP_MUX_AUDIO_H],290 aud_clks[CLK_TOP_APLL2_CK], ret);291 goto clk_mux_audio_h_parent_err;292 }293 294 ret = clk_prepare_enable(afe_priv->clk[CLK_AFE]);295 if (ret) {296 dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",297 __func__, aud_clks[CLK_AFE], ret);298 goto clk_afe_err;299 }300 301 return 0;302 303clk_afe_err:304 clk_disable_unprepare(afe_priv->clk[CLK_AFE]);305clk_mux_audio_h_parent_err:306clk_mux_audio_intbus_parent_err:307 mt8186_set_audio_int_bus_parent(afe, CLK_CLK26M);308clk_mux_audio_intbus_err:309 clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);310clk_mux_audio_err:311 clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIO]);312clk_infra_sys_audio_err:313 clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUDIO]);314clk_infra_audio_26m_err:315 clk_disable_unprepare(afe_priv->clk[CLK_INFRA_AUDIO_26M]);316 317 return ret;318}319 320void mt8186_afe_disable_clock(struct mtk_base_afe *afe)321{322 struct mt8186_afe_private *afe_priv = afe->platform_priv;323 324 clk_disable_unprepare(afe_priv->clk[CLK_AFE]);325 mt8186_set_audio_int_bus_parent(afe, CLK_CLK26M);326 clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);327 clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIO]);328 clk_disable_unprepare(afe_priv->clk[CLK_INFRA_AUDIO_26M]);329 clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUDIO]);330}331 332int mt8186_afe_suspend_clock(struct mtk_base_afe *afe)333{334 struct mt8186_afe_private *afe_priv = afe->platform_priv;335 int ret;336 337 /* set audio int bus to 26M */338 ret = clk_prepare_enable(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);339 if (ret) {340 dev_info(afe->dev, "%s clk_prepare_enable %s fail %d\n",341 __func__, aud_clks[CLK_MUX_AUDIOINTBUS], ret);342 goto clk_mux_audio_intbus_err;343 }344 ret = mt8186_set_audio_int_bus_parent(afe, CLK_CLK26M);345 if (ret)346 goto clk_mux_audio_intbus_parent_err;347 348 clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);349 350 return 0;351 352clk_mux_audio_intbus_parent_err:353 mt8186_set_audio_int_bus_parent(afe, CLK_TOP_MAINPLL_D2_D4);354clk_mux_audio_intbus_err:355 clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);356 return ret;357}358 359int mt8186_afe_resume_clock(struct mtk_base_afe *afe)360{361 struct mt8186_afe_private *afe_priv = afe->platform_priv;362 int ret;363 364 /* set audio int bus to normal working clock */365 ret = clk_prepare_enable(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);366 if (ret) {367 dev_info(afe->dev, "%s clk_prepare_enable %s fail %d\n",368 __func__, aud_clks[CLK_MUX_AUDIOINTBUS], ret);369 goto clk_mux_audio_intbus_err;370 }371 ret = mt8186_set_audio_int_bus_parent(afe,372 CLK_TOP_MAINPLL_D2_D4);373 if (ret)374 goto clk_mux_audio_intbus_parent_err;375 376 clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);377 378 return 0;379 380clk_mux_audio_intbus_parent_err:381 mt8186_set_audio_int_bus_parent(afe, CLK_CLK26M);382clk_mux_audio_intbus_err:383 clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);384 return ret;385}386 387int mt8186_apll1_enable(struct mtk_base_afe *afe)388{389 struct mt8186_afe_private *afe_priv = afe->platform_priv;390 int ret;391 392 /* setting for APLL */393 apll1_mux_setting(afe, true);394 395 ret = clk_prepare_enable(afe_priv->clk[CLK_APLL22M]);396 if (ret) {397 dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",398 __func__, aud_clks[CLK_APLL22M], ret);399 goto err_clk_apll22m;400 }401 402 ret = clk_prepare_enable(afe_priv->clk[CLK_APLL1_TUNER]);403 if (ret) {404 dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",405 __func__, aud_clks[CLK_APLL1_TUNER], ret);406 goto err_clk_apll1_tuner;407 }408 409 regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG, 0xfff7, 0x832);410 regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG, 0x1, 0x1);411 412 regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,413 AFE_22M_ON_MASK_SFT, BIT(AFE_22M_ON_SFT));414 415 return 0;416 417err_clk_apll1_tuner:418 clk_disable_unprepare(afe_priv->clk[CLK_APLL1_TUNER]);419err_clk_apll22m:420 clk_disable_unprepare(afe_priv->clk[CLK_APLL22M]);421 422 return ret;423}424 425void mt8186_apll1_disable(struct mtk_base_afe *afe)426{427 struct mt8186_afe_private *afe_priv = afe->platform_priv;428 429 regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,430 AFE_22M_ON_MASK_SFT, 0);431 432 regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG, 0x1, 0);433 434 clk_disable_unprepare(afe_priv->clk[CLK_APLL1_TUNER]);435 clk_disable_unprepare(afe_priv->clk[CLK_APLL22M]);436 437 apll1_mux_setting(afe, false);438}439 440int mt8186_apll2_enable(struct mtk_base_afe *afe)441{442 struct mt8186_afe_private *afe_priv = afe->platform_priv;443 int ret;444 445 /* setting for APLL */446 apll2_mux_setting(afe, true);447 448 ret = clk_prepare_enable(afe_priv->clk[CLK_APLL24M]);449 if (ret) {450 dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",451 __func__, aud_clks[CLK_APLL24M], ret);452 goto err_clk_apll24m;453 }454 455 ret = clk_prepare_enable(afe_priv->clk[CLK_APLL2_TUNER]);456 if (ret) {457 dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",458 __func__, aud_clks[CLK_APLL2_TUNER], ret);459 goto err_clk_apll2_tuner;460 }461 462 regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG, 0xfff7, 0x634);463 regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG, 0x1, 0x1);464 465 regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,466 AFE_24M_ON_MASK_SFT, BIT(AFE_24M_ON_SFT));467 468 return 0;469 470err_clk_apll2_tuner:471 clk_disable_unprepare(afe_priv->clk[CLK_APLL2_TUNER]);472err_clk_apll24m:473 clk_disable_unprepare(afe_priv->clk[CLK_APLL24M]);474 475 return ret;476}477 478void mt8186_apll2_disable(struct mtk_base_afe *afe)479{480 struct mt8186_afe_private *afe_priv = afe->platform_priv;481 482 regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,483 AFE_24M_ON_MASK_SFT, 0);484 485 regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG, 0x1, 0);486 487 clk_disable_unprepare(afe_priv->clk[CLK_APLL2_TUNER]);488 clk_disable_unprepare(afe_priv->clk[CLK_APLL24M]);489 490 apll2_mux_setting(afe, false);491}492 493int mt8186_get_apll_rate(struct mtk_base_afe *afe, int apll)494{495 return (apll == MT8186_APLL1) ? 180633600 : 196608000;496}497 498int mt8186_get_apll_by_rate(struct mtk_base_afe *afe, int rate)499{500 return ((rate % 8000) == 0) ? MT8186_APLL2 : MT8186_APLL1;501}502 503int mt8186_get_apll_by_name(struct mtk_base_afe *afe, const char *name)504{505 if (strcmp(name, APLL1_W_NAME) == 0)506 return MT8186_APLL1;507 508 return MT8186_APLL2;509}510 511/* mck */512struct mt8186_mck_div {513 u32 m_sel_id;514 u32 div_clk_id;515};516 517static const struct mt8186_mck_div mck_div[MT8186_MCK_NUM] = {518 [MT8186_I2S0_MCK] = {519 .m_sel_id = CLK_TOP_I2S0_M_SEL,520 .div_clk_id = CLK_TOP_APLL12_DIV0,521 },522 [MT8186_I2S1_MCK] = {523 .m_sel_id = CLK_TOP_I2S1_M_SEL,524 .div_clk_id = CLK_TOP_APLL12_DIV1,525 },526 [MT8186_I2S2_MCK] = {527 .m_sel_id = CLK_TOP_I2S2_M_SEL,528 .div_clk_id = CLK_TOP_APLL12_DIV2,529 },530 [MT8186_I2S4_MCK] = {531 .m_sel_id = CLK_TOP_I2S4_M_SEL,532 .div_clk_id = CLK_TOP_APLL12_DIV4,533 },534 [MT8186_TDM_MCK] = {535 .m_sel_id = CLK_TOP_TDM_M_SEL,536 .div_clk_id = CLK_TOP_APLL12_DIV_TDM,537 },538};539 540int mt8186_mck_enable(struct mtk_base_afe *afe, int mck_id, int rate)541{542 struct mt8186_afe_private *afe_priv = afe->platform_priv;543 int apll = mt8186_get_apll_by_rate(afe, rate);544 int apll_clk_id = apll == MT8186_APLL1 ?545 CLK_TOP_MUX_AUD_1 : CLK_TOP_MUX_AUD_2;546 int m_sel_id = mck_div[mck_id].m_sel_id;547 int div_clk_id = mck_div[mck_id].div_clk_id;548 int ret;549 550 /* select apll */551 if (m_sel_id >= 0) {552 ret = clk_prepare_enable(afe_priv->clk[m_sel_id]);553 if (ret) {554 dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",555 __func__, aud_clks[m_sel_id], ret);556 return ret;557 }558 ret = clk_set_parent(afe_priv->clk[m_sel_id],559 afe_priv->clk[apll_clk_id]);560 if (ret) {561 dev_err(afe->dev, "%s(), clk_set_parent %s-%s fail %d\n",562 __func__, aud_clks[m_sel_id],563 aud_clks[apll_clk_id], ret);564 return ret;565 }566 }567 568 /* enable div, set rate */569 ret = clk_prepare_enable(afe_priv->clk[div_clk_id]);570 if (ret) {571 dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",572 __func__, aud_clks[div_clk_id], ret);573 return ret;574 }575 ret = clk_set_rate(afe_priv->clk[div_clk_id], rate);576 if (ret) {577 dev_err(afe->dev, "%s(), clk_set_rate %s, rate %d, fail %d\n",578 __func__, aud_clks[div_clk_id], rate, ret);579 return ret;580 }581 582 return 0;583}584 585void mt8186_mck_disable(struct mtk_base_afe *afe, int mck_id)586{587 struct mt8186_afe_private *afe_priv = afe->platform_priv;588 int m_sel_id = mck_div[mck_id].m_sel_id;589 int div_clk_id = mck_div[mck_id].div_clk_id;590 591 clk_disable_unprepare(afe_priv->clk[div_clk_id]);592 if (m_sel_id >= 0)593 clk_disable_unprepare(afe_priv->clk[m_sel_id]);594}595 596int mt8186_init_clock(struct mtk_base_afe *afe)597{598 struct mt8186_afe_private *afe_priv = afe->platform_priv;599 struct device_node *of_node = afe->dev->of_node;600 int i = 0;601 602 mt8186_audsys_clk_register(afe);603 604 afe_priv->clk = devm_kcalloc(afe->dev, CLK_NUM, sizeof(*afe_priv->clk),605 GFP_KERNEL);606 if (!afe_priv->clk)607 return -ENOMEM;608 609 for (i = 0; i < CLK_NUM; i++) {610 afe_priv->clk[i] = devm_clk_get(afe->dev, aud_clks[i]);611 if (IS_ERR(afe_priv->clk[i])) {612 dev_err(afe->dev, "%s devm_clk_get %s fail, ret %ld\n",613 __func__,614 aud_clks[i], PTR_ERR(afe_priv->clk[i]));615 afe_priv->clk[i] = NULL;616 }617 }618 619 afe_priv->apmixedsys = syscon_regmap_lookup_by_phandle(of_node,620 "mediatek,apmixedsys");621 if (IS_ERR(afe_priv->apmixedsys)) {622 dev_err(afe->dev, "%s() Cannot find apmixedsys controller: %ld\n",623 __func__, PTR_ERR(afe_priv->apmixedsys));624 return PTR_ERR(afe_priv->apmixedsys);625 }626 627 afe_priv->topckgen = syscon_regmap_lookup_by_phandle(of_node,628 "mediatek,topckgen");629 if (IS_ERR(afe_priv->topckgen)) {630 dev_err(afe->dev, "%s() Cannot find topckgen controller: %ld\n",631 __func__, PTR_ERR(afe_priv->topckgen));632 return PTR_ERR(afe_priv->topckgen);633 }634 635 afe_priv->infracfg = syscon_regmap_lookup_by_phandle(of_node,636 "mediatek,infracfg");637 if (IS_ERR(afe_priv->infracfg)) {638 dev_err(afe->dev, "%s() Cannot find infracfg: %ld\n",639 __func__, PTR_ERR(afe_priv->infracfg));640 return PTR_ERR(afe_priv->infracfg);641 }642 643 return 0;644}645